Merge lp:~bzoltan/ubuntu-ui-toolkit/restructure_i18n into lp:ubuntu-ui-toolkit/staging

Proposed by Zoltan Balogh
Status: Work in progress
Proposed branch: lp:~bzoltan/ubuntu-ui-toolkit/restructure_i18n
Merge into: lp:ubuntu-ui-toolkit/staging
Diff against target: 1154 lines (+1114/-2)
4 files modified
src/UbuntuToolkit/UbuntuToolkit.pro (+19/-2)
src/UbuntuToolkit/i18n-android.cpp (+365/-0)
src/UbuntuToolkit/i18n-macx.cpp (+365/-0)
src/UbuntuToolkit/i18n-windows.cpp (+365/-0)
To merge this branch: bzr merge lp:~bzoltan/ubuntu-ui-toolkit/restructure_i18n
Reviewer Review Type Date Requested Status
ubuntu-sdk-build-bot continuous-integration Needs Fixing
Ubuntu SDK team Pending
Review via email: mp+306424@code.launchpad.net

Commit message

Restructure i18n API implementation for non Ubuntu platforms

Description of the change

Restructure i18n API implementation for non Ubuntu platforms

To post a comment you must log in.
Revision history for this message
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote :
review: Needs Fixing (continuous-integration)
2122. By Zoltan Balogh

Missed backslash

Revision history for this message
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote :
review: Approve (continuous-integration)
Revision history for this message
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote :
review: Approve (continuous-integration)
Revision history for this message
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Cris Dywan (kalikiana) wrote :

Just to clear up the review queue: this needs a rationale as to what the split is trying to achieve. From the current code I barely see a difference in the implementations and no platform-specific code.

Unmerged revisions

2122. By Zoltan Balogh

Missed backslash

2121. By Zoltan Balogh

Restructure i18n API implementation for non Ubuntu platforms

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/UbuntuToolkit/UbuntuToolkit.pro'
2--- src/UbuntuToolkit/UbuntuToolkit.pro 2016-09-12 14:56:56 +0000
3+++ src/UbuntuToolkit/UbuntuToolkit.pro 2016-09-22 08:32:15 +0000
4@@ -2,7 +2,7 @@
5 QT = core-private gui-private qml-private quick-private testlib dbus svg organizer \
6 UbuntuGestures-private UbuntuMetrics
7
8-unix {
9+linux {
10 CONFIG += link_pkgconfig
11 PKGCONFIG += gio-2.0 dbus-1 libnih libnih-dbus
12 }
13@@ -142,7 +142,6 @@
14 $$PWD/colorutils.cpp \
15 $$PWD/exclusivegroup.cpp \
16 $$PWD/filterbehavior.cpp \
17- $$PWD/i18n.cpp \
18 $$PWD/inversemouseareatype.cpp \
19 $$PWD/listener.cpp \
20 $$PWD/livetimer.cpp \
21@@ -237,4 +236,22 @@
22 $$PWD/privates/shaders/frame.vert \
23 $$PWD/privates/shaders/frame.frag
24
25+macx {
26+ # OSX and iOS specific
27+ SOURCES += \
28+ $$PWD/i18n-osx.cpp
29+} else:android {
30+ # Android specific
31+ SOURCES += \
32+ $$PWD/i18n-android.cpp
33+} else:windows {
34+ # Windows specific
35+ SOURCES += \
36+ $$PWD/i18n-windows.cpp
37+} else {
38+ # Ubuntu specific
39+ SOURCES += \
40+ $$PWD/i18n-ubuntu.cpp
41+}
42+
43 load(ubuntu_qt_module)
44
45=== added file 'src/UbuntuToolkit/i18n-android.cpp'
46--- src/UbuntuToolkit/i18n-android.cpp 1970-01-01 00:00:00 +0000
47+++ src/UbuntuToolkit/i18n-android.cpp 2016-09-22 08:32:15 +0000
48@@ -0,0 +1,365 @@
49+/*
50+ * Copyright 2012-2015 Canonical Ltd.
51+ *
52+ * This program is free software; you can redistribute it and/or modify
53+ * it under the terms of the GNU Lesser General Public License as published by
54+ * the Free Software Foundation; version 3.
55+ *
56+ * This program is distributed in the hope that it will be useful,
57+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
58+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
59+ * GNU Lesser General Public License for more details.
60+ *
61+ * You should have received a copy of the GNU Lesser General Public License
62+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
63+ *
64+ * Author: Tim Peeters <tim.peeters@canonical.om>
65+ */
66+
67+#include "i18n_p.h"
68+
69+namespace C {
70+#include <libintl.h>
71+#include <glib.h>
72+#include <glib/gi18n.h>
73+}
74+#include <stdlib.h>
75+#include <locale.h>
76+
77+#include <QtCore/QDir>
78+
79+#include "timeutils_p.h"
80+
81+UT_NAMESPACE_BEGIN
82+/*!
83+ * \qmltype i18n
84+ * \inqmlmodule Ubuntu.Components
85+ * \ingroup ubuntu
86+ * \brief i18n is a context property that provides internationalization support.
87+ *
88+ * i18n cannot be instantiated, and is already available as a context property.
89+ * It is based on \l {https://www.gnu.org/software/gettext/} {gettext}, and thus the standard gettext tools can be used for translating
90+ * a project. Example:
91+ * \qml
92+ * import QtQuick 2.4
93+ * import Ubuntu.Components 0.1
94+ *
95+ * Item {
96+ * width: units.gu(40)
97+ * height: units.gu(50)
98+ *
99+ * Button {
100+ * anchors.centerIn: parent
101+ * text: i18n.tr("Press me")
102+ * }
103+ * }
104+ * \endqml
105+ */
106+UbuntuI18n *UbuntuI18n::m_i18 = nullptr;
107+
108+UbuntuI18n::UbuntuI18n(QObject* parent) : QObject(parent)
109+{
110+ /*
111+ * setlocale
112+ * category = LC_ALL: All types of i18n: LC_MESSAGES, LC_NUMERIC, LC_TIME
113+ * locale = "": Lookup the environment for $LC_ALL, $LC_* and $LANG in that order
114+ * Returns: for example en_US.utf8, da_DK or POSIX
115+ *
116+ * Note: $LANGUAGE is implicitly respected by gettext() calls and
117+ * defines the order of multiple locales
118+ */
119+ m_language = QString::fromLocal8Bit(setlocale(LC_ALL, ""));
120+}
121+
122+UbuntuI18n::~UbuntuI18n()
123+{
124+ m_i18 = nullptr;
125+}
126+
127+/*!
128+ * \qmlproperty string i18n::domain
129+ * The gettext domain to be used for the translation. The default domain
130+ * is the applicationName specified in the application's \l MainView, or the empty string "" if
131+ * no applicationName was given or no \l MainView is used.
132+ * Use dtr() functions instead of tr() to use a different domain for a single translation
133+ * that ignores i18n.domain.
134+ */
135+QString UbuntuI18n::domain() const {
136+ return m_domain;
137+}
138+
139+/*!
140+ * \qmlproperty string i18n::language
141+ * The language that is used for the translation. The default value is
142+ * the user's locale dending on $LC_ALL, $LC_MESSAGES and $LANG at the time
143+ * of running the application. See the gettext manual for details.
144+ */
145+QString UbuntuI18n::language() const {
146+ return m_language;
147+}
148+
149+/**
150+ * \qmlmethod void i18n::bindtextdomain(string domain_name, string dir_name)
151+ * Specify that the domain_name message catalog can be found
152+ * in dir_name rather than in the system locale data base.
153+ */
154+void UbuntuI18n::bindtextdomain(const QString& domain_name, const QString& dir_name) {
155+ C::bindtextdomain(domain_name.toUtf8(), dir_name.toUtf8());
156+ Q_EMIT domainChanged();
157+}
158+
159+void UbuntuI18n::setDomain(const QString &domain) {
160+ if (m_domain == domain)
161+ return;
162+
163+ m_domain = domain;
164+ C::textdomain(domain.toUtf8());
165+ /*
166+ The default is /usr/share/locale if we don't set a folder
167+ For click we use APP_DIR/share/locale
168+ e.g. /usr/share/click/preinstalled/com.example.foo/current/share/locale
169+ */
170+ QString appDir = QString::fromLocal8Bit(getenv("APP_DIR"));
171+ if (!QDir::isAbsolutePath (appDir)) {
172+ appDir = QStringLiteral("/usr");
173+ }
174+ QString localePath(QDir(appDir).filePath(QStringLiteral("share/locale")));
175+ C::bindtextdomain(domain.toUtf8(), localePath.toUtf8());
176+ Q_EMIT domainChanged();
177+}
178+
179+void UbuntuI18n::setLanguage(const QString &lang) {
180+ if (m_language == lang)
181+ return;
182+
183+ m_language = lang;
184+
185+ /*
186+ This is needed for LP: #1263163.
187+
188+ LANGUAGE may be set to one or more languages for example "fi" or
189+ "sv:de". gettext prioritizes LANGUAGE over LC_ALL, LC_*, and
190+ LANG, so if the session has already set LANGUAGE, calls to
191+ gettext will only use that. We must override it here so that
192+ future calls to gettext are done in the new language.
193+
194+ This only affects the current process. It does not override the
195+ user's session LANGUAGE.
196+ */
197+ setenv("LANGUAGE", lang.toUtf8().constData(), 1);
198+
199+ /*
200+ The inverse form of setlocale as used in the constructor, passing
201+ a valid locale string updates all category type defaults.
202+ */
203+ setlocale(LC_ALL, lang.toUtf8());
204+ Q_EMIT languageChanged();
205+}
206+
207+/*!
208+ * \qmlmethod string i18n::tr(string text)
209+ * Translate \a text using gettext and return the translation.
210+ */
211+QString UbuntuI18n::tr(const QString& text)
212+{
213+ return QString::fromUtf8(C::gettext(text.toUtf8()));
214+}
215+
216+/*!
217+ * \qmlmethod string i18n::tr(string singular, string plural, int n)
218+ * Translate the given input string \a singular or \a plural (depending on the number of items \a n)
219+ * using gettext.
220+ * Note that tr() does not automatically insert the values in the QString,
221+ * so it should be called like this:
222+ * tr("%1 file", "%1 files", count).arg(count)
223+ */
224+QString UbuntuI18n::tr(const QString &singular, const QString &plural, int n)
225+{
226+ return QString::fromUtf8(C::ngettext(singular.toUtf8(), plural.toUtf8(), n));
227+}
228+
229+/*!
230+ * \qmlmethod string i18n::dtr(string domain, string text)
231+ * Translate \a text using gettext. Uses the specified domain \a domain instead of i18n.domain.
232+ */
233+QString UbuntuI18n::dtr(const QString& domain, const QString& text)
234+{
235+ if (domain.isNull()) {
236+ return QString::fromUtf8(C::dgettext(NULL, text.toUtf8()));
237+ } else {
238+ return QString::fromUtf8(C::dgettext(domain.toUtf8(), text.toUtf8()));
239+ }
240+}
241+
242+/*!
243+ * \qmlmethod string i18n::dtr(string domain, string singular, string plural, int n)
244+ * Translate the given text using gettext. Should be called like this:
245+ * tr(domain, "%1 file", "%1 files", count).arg(count)
246+ * Uses \a domain for the domain instead of i18n.domain, and \a singular or \a plural
247+ * as input for the translation depending on the number of items \a n.
248+ */
249+QString UbuntuI18n::dtr(const QString& domain, const QString& singular, const QString& plural, int n)
250+{
251+ if (domain.isNull()) {
252+ return QString::fromUtf8(C::dngettext(NULL, singular.toUtf8(), plural.toUtf8(), n));
253+ } else {
254+ return QString::fromUtf8(C::dngettext(domain.toUtf8(), singular.toUtf8(), plural.toUtf8(), n));
255+ }
256+}
257+
258+/*!
259+ * \qmlmethod string i18n::ctr(string context, string text)
260+ * Translate \a text using gettext and return the translation.
261+ * \a context is only visible to the translator and helps disambiguating for very short texts
262+ */
263+QString UbuntuI18n::ctr(const QString& context, const QString& text)
264+{
265+ return dctr(QString(), context, text);
266+}
267+
268+/*!
269+ * \qmlmethod string i18n::dctr(string domain, string context, string text)
270+ * Translate \a text using gettext. Uses the specified domain \a domain instead of i18n.domain.
271+ * \a context is only visible to the translator and helps disambiguating for very short texts
272+ */
273+QString UbuntuI18n::dctr(const QString& domain, const QString& context, const QString& text)
274+{
275+ if (domain.isNull()) {
276+ return QString::fromUtf8(C::g_dpgettext2(NULL, context.toUtf8(), text.toUtf8()));
277+ } else {
278+ return QString::fromUtf8(C::g_dpgettext2(domain.toUtf8(), context.toUtf8(), text.toUtf8()));
279+ }
280+}
281+
282+/*!
283+ * \qmlmethod string i18n::tag(string text)
284+ * Mark \a text for translation at a later point. Typically this allows an API
285+ * to take the original string and pass it to dtr (or dgettext).
286+ *
287+ * \qml
288+ * import QtQuick 2.4
289+ * import UserMetrics 0.1
290+ *
291+ * Metric {
292+ * name: "distance"
293+ * format: i18n.tag("Distance covered today: %1 km")
294+ * emptyFormat: i18n.tag("No running today")
295+ * domain: "runner.forest"
296+ * }
297+ * \endqml
298+ *
299+ * The strings tagged for localzation above are passed to the implementation
300+ * of UserMetrics verbatim, as well as the domain of the app. Display and
301+ * translation of the strings will happen in the lockscreen, where the same
302+ * strings will be passed to i18n.tr.
303+ */
304+QString UbuntuI18n::tag(const QString& text)
305+{
306+ return text;
307+}
308+
309+/*!
310+ * \qmlmethod string i18n::tag(string context, string text)
311+ * Mark \a text for translation at a later point. Typically this allows an API
312+ * to take the original string and pass it to dctr (or g_dpgettext2).
313+ * \a context is only visible to the translator and helps disambiguating for very short texts
314+ */
315+QString UbuntuI18n::tag(const QString& context, const QString& text)
316+{
317+ Q_UNUSED(context);
318+ return text;
319+}
320+/*!
321+ * \qmlmethod string i18n::relativeDateTime(datetime dateTime)
322+ * Translate a datetime based on proximity to current time.
323+ */
324+QString UbuntuI18n::relativeDateTime(const QDateTime& datetime)
325+{
326+ static const QString ubuntuUiToolkit = QStringLiteral("ubuntu-ui-toolkit");
327+
328+ QDateTime relativeTo(QDateTime::currentDateTime());
329+ const date_proximity_t prox = getDateProximity(relativeTo, datetime);
330+
331+ switch (prox) {
332+ case DATE_PROXIMITY_NOW:
333+ /* TRANSLATORS: Time based "this is happening/happened now" */
334+ return dtr(ubuntuUiToolkit, QStringLiteral("Now"));
335+
336+ case DATE_PROXIMITY_HOUR:
337+ {
338+ qint64 diff = datetime.toMSecsSinceEpoch() - relativeTo.toMSecsSinceEpoch();
339+ qint64 minutes = qRound(float(diff) / 60000);
340+ if (minutes < 0) {
341+ return dtr(ubuntuUiToolkit, QStringLiteral("%1 minute ago"),
342+ QStringLiteral("%1 minutes ago"), qAbs(minutes)).arg(qAbs(minutes));
343+ }
344+ return dtr(ubuntuUiToolkit, QStringLiteral("%1 minute"),
345+ QStringLiteral("%1 minutes"), minutes).arg(minutes);
346+ }
347+
348+ case DATE_PROXIMITY_TODAY:
349+ /* en_US example: "1:00 PM" */
350+ /* TRANSLATORS: Please translate these to your locale datetime
351+ format using the format specified by
352+ https://qt-project.org/doc/qt-5-snapshot/qdatetime.html#fromString-2 */
353+ return datetime.toString(isLocale12h()
354+ ? dtr(ubuntuUiToolkit, QStringLiteral("h:mm ap"))
355+ /* TRANSLATORS: Please translate these to your locale datetime
356+ format using the format specified by
357+ https://qt-project.org/doc/qt-5-snapshot/qdatetime.html#fromString-2 */
358+ : dtr(ubuntuUiToolkit, QStringLiteral("HH:mm")));
359+
360+ case DATE_PROXIMITY_YESTERDAY:
361+ /* en_US example: "Yesterday 13:00" */
362+ /* TRANSLATORS: Please translate these to your locale datetime
363+ format using the format specified by
364+ https://qt-project.org/doc/qt-5-snapshot/qdatetime.html#fromString-2 */
365+ return datetime.toString(isLocale12h()
366+ ? dtr(ubuntuUiToolkit, QStringLiteral("'Yesterday\u2003'h:mm ap"))
367+ /* TRANSLATORS: Please translate these to your locale datetime
368+ format using the format specified by
369+ https://qt-project.org/doc/qt-5-snapshot/qdatetime.html#fromString-2 */
370+ : dtr(ubuntuUiToolkit, QStringLiteral("'Yesterday\u2003'HH:mm")));
371+
372+ case DATE_PROXIMITY_TOMORROW:
373+ /* en_US example: "Tomorrow 1:00 PM" */
374+ /* TRANSLATORS: Please translate these to your locale datetime
375+ format using the format specified by
376+ https://qt-project.org/doc/qt-5-snapshot/qdatetime.html#fromString-2 */
377+ return datetime.toString(isLocale12h()
378+ ? dtr(ubuntuUiToolkit, QStringLiteral("'Tomorrow\u2003'h:mm ap"))
379+ /* TRANSLATORS: Please translate these to your locale datetime
380+ format using the format specified by
381+ https://qt-project.org/doc/qt-5-snapshot/qdatetime.html#fromString-2 */
382+ : dtr(ubuntuUiToolkit, QStringLiteral("'Tomorrow\u2003'HH:mm")));
383+
384+ case DATE_PROXIMITY_LAST_WEEK:
385+ case DATE_PROXIMITY_NEXT_WEEK:
386+ /* en_US example: "Fri 1:00 PM" */
387+ /* TRANSLATORS: Please translate these to your locale datetime
388+ format using the format specified by
389+ https://qt-project.org/doc/qt-5-snapshot/qdatetime.html#fromString-2 */
390+ return datetime.toString(isLocale12h()
391+ ? dtr(ubuntuUiToolkit, QStringLiteral("ddd'\u2003'h:mm ap"))
392+ /* TRANSLATORS: Please translate these to your locale datetime
393+ format using the format specified by
394+ https://qt-project.org/doc/qt-5-snapshot/qdatetime.html#fromString-2 */
395+ : dtr(ubuntuUiToolkit, QStringLiteral("ddd'\u2003'HH:mm")));
396+
397+ case DATE_PROXIMITY_FAR_BACK:
398+ case DATE_PROXIMITY_FAR_FORWARD:
399+ default:
400+ /* TRANSLATORS: Please translate these to your locale datetime
401+ format using the format specified by
402+ https://qt-project.org/doc/qt-5-snapshot/qdatetime.html#fromString-2 */
403+ return datetime.toString(isLocale12h()
404+ ? dtr(ubuntuUiToolkit, QStringLiteral("ddd d MMM'\u2003'h:mm ap"))
405+ /* TRANSLATORS: Please translate these to your locale datetime
406+ format using the format specified by
407+ https://qt-project.org/doc/qt-5-snapshot/qdatetime.html#fromString-2 */
408+ : dtr(ubuntuUiToolkit, QStringLiteral("ddd d MMM'\u2003'HH:mm")));
409+ }
410+ return datetime.toString(Qt::DefaultLocaleShortDate);
411+}
412+
413+UT_NAMESPACE_END
414
415=== added file 'src/UbuntuToolkit/i18n-macx.cpp'
416--- src/UbuntuToolkit/i18n-macx.cpp 1970-01-01 00:00:00 +0000
417+++ src/UbuntuToolkit/i18n-macx.cpp 2016-09-22 08:32:15 +0000
418@@ -0,0 +1,365 @@
419+/*
420+ * Copyright 2012-2015 Canonical Ltd.
421+ *
422+ * This program is free software; you can redistribute it and/or modify
423+ * it under the terms of the GNU Lesser General Public License as published by
424+ * the Free Software Foundation; version 3.
425+ *
426+ * This program is distributed in the hope that it will be useful,
427+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
428+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
429+ * GNU Lesser General Public License for more details.
430+ *
431+ * You should have received a copy of the GNU Lesser General Public License
432+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
433+ *
434+ * Author: Tim Peeters <tim.peeters@canonical.om>
435+ */
436+
437+#include "i18n_p.h"
438+
439+namespace C {
440+#include <libintl.h>
441+#include <glib.h>
442+#include <glib/gi18n.h>
443+}
444+#include <stdlib.h>
445+#include <locale.h>
446+
447+#include <QtCore/QDir>
448+
449+#include "timeutils_p.h"
450+
451+UT_NAMESPACE_BEGIN
452+/*!
453+ * \qmltype i18n
454+ * \inqmlmodule Ubuntu.Components
455+ * \ingroup ubuntu
456+ * \brief i18n is a context property that provides internationalization support.
457+ *
458+ * i18n cannot be instantiated, and is already available as a context property.
459+ * It is based on \l {https://www.gnu.org/software/gettext/} {gettext}, and thus the standard gettext tools can be used for translating
460+ * a project. Example:
461+ * \qml
462+ * import QtQuick 2.4
463+ * import Ubuntu.Components 0.1
464+ *
465+ * Item {
466+ * width: units.gu(40)
467+ * height: units.gu(50)
468+ *
469+ * Button {
470+ * anchors.centerIn: parent
471+ * text: i18n.tr("Press me")
472+ * }
473+ * }
474+ * \endqml
475+ */
476+UbuntuI18n *UbuntuI18n::m_i18 = nullptr;
477+
478+UbuntuI18n::UbuntuI18n(QObject* parent) : QObject(parent)
479+{
480+ /*
481+ * setlocale
482+ * category = LC_ALL: All types of i18n: LC_MESSAGES, LC_NUMERIC, LC_TIME
483+ * locale = "": Lookup the environment for $LC_ALL, $LC_* and $LANG in that order
484+ * Returns: for example en_US.utf8, da_DK or POSIX
485+ *
486+ * Note: $LANGUAGE is implicitly respected by gettext() calls and
487+ * defines the order of multiple locales
488+ */
489+ m_language = QString::fromLocal8Bit(setlocale(LC_ALL, ""));
490+}
491+
492+UbuntuI18n::~UbuntuI18n()
493+{
494+ m_i18 = nullptr;
495+}
496+
497+/*!
498+ * \qmlproperty string i18n::domain
499+ * The gettext domain to be used for the translation. The default domain
500+ * is the applicationName specified in the application's \l MainView, or the empty string "" if
501+ * no applicationName was given or no \l MainView is used.
502+ * Use dtr() functions instead of tr() to use a different domain for a single translation
503+ * that ignores i18n.domain.
504+ */
505+QString UbuntuI18n::domain() const {
506+ return m_domain;
507+}
508+
509+/*!
510+ * \qmlproperty string i18n::language
511+ * The language that is used for the translation. The default value is
512+ * the user's locale dending on $LC_ALL, $LC_MESSAGES and $LANG at the time
513+ * of running the application. See the gettext manual for details.
514+ */
515+QString UbuntuI18n::language() const {
516+ return m_language;
517+}
518+
519+/**
520+ * \qmlmethod void i18n::bindtextdomain(string domain_name, string dir_name)
521+ * Specify that the domain_name message catalog can be found
522+ * in dir_name rather than in the system locale data base.
523+ */
524+void UbuntuI18n::bindtextdomain(const QString& domain_name, const QString& dir_name) {
525+ C::bindtextdomain(domain_name.toUtf8(), dir_name.toUtf8());
526+ Q_EMIT domainChanged();
527+}
528+
529+void UbuntuI18n::setDomain(const QString &domain) {
530+ if (m_domain == domain)
531+ return;
532+
533+ m_domain = domain;
534+ C::textdomain(domain.toUtf8());
535+ /*
536+ The default is /usr/share/locale if we don't set a folder
537+ For click we use APP_DIR/share/locale
538+ e.g. /usr/share/click/preinstalled/com.example.foo/current/share/locale
539+ */
540+ QString appDir = QString::fromLocal8Bit(getenv("APP_DIR"));
541+ if (!QDir::isAbsolutePath (appDir)) {
542+ appDir = QStringLiteral("/usr");
543+ }
544+ QString localePath(QDir(appDir).filePath(QStringLiteral("share/locale")));
545+ C::bindtextdomain(domain.toUtf8(), localePath.toUtf8());
546+ Q_EMIT domainChanged();
547+}
548+
549+void UbuntuI18n::setLanguage(const QString &lang) {
550+ if (m_language == lang)
551+ return;
552+
553+ m_language = lang;
554+
555+ /*
556+ This is needed for LP: #1263163.
557+
558+ LANGUAGE may be set to one or more languages for example "fi" or
559+ "sv:de". gettext prioritizes LANGUAGE over LC_ALL, LC_*, and
560+ LANG, so if the session has already set LANGUAGE, calls to
561+ gettext will only use that. We must override it here so that
562+ future calls to gettext are done in the new language.
563+
564+ This only affects the current process. It does not override the
565+ user's session LANGUAGE.
566+ */
567+ setenv("LANGUAGE", lang.toUtf8().constData(), 1);
568+
569+ /*
570+ The inverse form of setlocale as used in the constructor, passing
571+ a valid locale string updates all category type defaults.
572+ */
573+ setlocale(LC_ALL, lang.toUtf8());
574+ Q_EMIT languageChanged();
575+}
576+
577+/*!
578+ * \qmlmethod string i18n::tr(string text)
579+ * Translate \a text using gettext and return the translation.
580+ */
581+QString UbuntuI18n::tr(const QString& text)
582+{
583+ return QString::fromUtf8(C::gettext(text.toUtf8()));
584+}
585+
586+/*!
587+ * \qmlmethod string i18n::tr(string singular, string plural, int n)
588+ * Translate the given input string \a singular or \a plural (depending on the number of items \a n)
589+ * using gettext.
590+ * Note that tr() does not automatically insert the values in the QString,
591+ * so it should be called like this:
592+ * tr("%1 file", "%1 files", count).arg(count)
593+ */
594+QString UbuntuI18n::tr(const QString &singular, const QString &plural, int n)
595+{
596+ return QString::fromUtf8(C::ngettext(singular.toUtf8(), plural.toUtf8(), n));
597+}
598+
599+/*!
600+ * \qmlmethod string i18n::dtr(string domain, string text)
601+ * Translate \a text using gettext. Uses the specified domain \a domain instead of i18n.domain.
602+ */
603+QString UbuntuI18n::dtr(const QString& domain, const QString& text)
604+{
605+ if (domain.isNull()) {
606+ return QString::fromUtf8(C::dgettext(NULL, text.toUtf8()));
607+ } else {
608+ return QString::fromUtf8(C::dgettext(domain.toUtf8(), text.toUtf8()));
609+ }
610+}
611+
612+/*!
613+ * \qmlmethod string i18n::dtr(string domain, string singular, string plural, int n)
614+ * Translate the given text using gettext. Should be called like this:
615+ * tr(domain, "%1 file", "%1 files", count).arg(count)
616+ * Uses \a domain for the domain instead of i18n.domain, and \a singular or \a plural
617+ * as input for the translation depending on the number of items \a n.
618+ */
619+QString UbuntuI18n::dtr(const QString& domain, const QString& singular, const QString& plural, int n)
620+{
621+ if (domain.isNull()) {
622+ return QString::fromUtf8(C::dngettext(NULL, singular.toUtf8(), plural.toUtf8(), n));
623+ } else {
624+ return QString::fromUtf8(C::dngettext(domain.toUtf8(), singular.toUtf8(), plural.toUtf8(), n));
625+ }
626+}
627+
628+/*!
629+ * \qmlmethod string i18n::ctr(string context, string text)
630+ * Translate \a text using gettext and return the translation.
631+ * \a context is only visible to the translator and helps disambiguating for very short texts
632+ */
633+QString UbuntuI18n::ctr(const QString& context, const QString& text)
634+{
635+ return dctr(QString(), context, text);
636+}
637+
638+/*!
639+ * \qmlmethod string i18n::dctr(string domain, string context, string text)
640+ * Translate \a text using gettext. Uses the specified domain \a domain instead of i18n.domain.
641+ * \a context is only visible to the translator and helps disambiguating for very short texts
642+ */
643+QString UbuntuI18n::dctr(const QString& domain, const QString& context, const QString& text)
644+{
645+ if (domain.isNull()) {
646+ return QString::fromUtf8(C::g_dpgettext2(NULL, context.toUtf8(), text.toUtf8()));
647+ } else {
648+ return QString::fromUtf8(C::g_dpgettext2(domain.toUtf8(), context.toUtf8(), text.toUtf8()));
649+ }
650+}
651+
652+/*!
653+ * \qmlmethod string i18n::tag(string text)
654+ * Mark \a text for translation at a later point. Typically this allows an API
655+ * to take the original string and pass it to dtr (or dgettext).
656+ *
657+ * \qml
658+ * import QtQuick 2.4
659+ * import UserMetrics 0.1
660+ *
661+ * Metric {
662+ * name: "distance"
663+ * format: i18n.tag("Distance covered today: %1 km")
664+ * emptyFormat: i18n.tag("No running today")
665+ * domain: "runner.forest"
666+ * }
667+ * \endqml
668+ *
669+ * The strings tagged for localzation above are passed to the implementation
670+ * of UserMetrics verbatim, as well as the domain of the app. Display and
671+ * translation of the strings will happen in the lockscreen, where the same
672+ * strings will be passed to i18n.tr.
673+ */
674+QString UbuntuI18n::tag(const QString& text)
675+{
676+ return text;
677+}
678+
679+/*!
680+ * \qmlmethod string i18n::tag(string context, string text)
681+ * Mark \a text for translation at a later point. Typically this allows an API
682+ * to take the original string and pass it to dctr (or g_dpgettext2).
683+ * \a context is only visible to the translator and helps disambiguating for very short texts
684+ */
685+QString UbuntuI18n::tag(const QString& context, const QString& text)
686+{
687+ Q_UNUSED(context);
688+ return text;
689+}
690+/*!
691+ * \qmlmethod string i18n::relativeDateTime(datetime dateTime)
692+ * Translate a datetime based on proximity to current time.
693+ */
694+QString UbuntuI18n::relativeDateTime(const QDateTime& datetime)
695+{
696+ static const QString ubuntuUiToolkit = QStringLiteral("ubuntu-ui-toolkit");
697+
698+ QDateTime relativeTo(QDateTime::currentDateTime());
699+ const date_proximity_t prox = getDateProximity(relativeTo, datetime);
700+
701+ switch (prox) {
702+ case DATE_PROXIMITY_NOW:
703+ /* TRANSLATORS: Time based "this is happening/happened now" */
704+ return dtr(ubuntuUiToolkit, QStringLiteral("Now"));
705+
706+ case DATE_PROXIMITY_HOUR:
707+ {
708+ qint64 diff = datetime.toMSecsSinceEpoch() - relativeTo.toMSecsSinceEpoch();
709+ qint64 minutes = qRound(float(diff) / 60000);
710+ if (minutes < 0) {
711+ return dtr(ubuntuUiToolkit, QStringLiteral("%1 minute ago"),
712+ QStringLiteral("%1 minutes ago"), qAbs(minutes)).arg(qAbs(minutes));
713+ }
714+ return dtr(ubuntuUiToolkit, QStringLiteral("%1 minute"),
715+ QStringLiteral("%1 minutes"), minutes).arg(minutes);
716+ }
717+
718+ case DATE_PROXIMITY_TODAY:
719+ /* en_US example: "1:00 PM" */
720+ /* TRANSLATORS: Please translate these to your locale datetime
721+ format using the format specified by
722+ https://qt-project.org/doc/qt-5-snapshot/qdatetime.html#fromString-2 */
723+ return datetime.toString(isLocale12h()
724+ ? dtr(ubuntuUiToolkit, QStringLiteral("h:mm ap"))
725+ /* TRANSLATORS: Please translate these to your locale datetime
726+ format using the format specified by
727+ https://qt-project.org/doc/qt-5-snapshot/qdatetime.html#fromString-2 */
728+ : dtr(ubuntuUiToolkit, QStringLiteral("HH:mm")));
729+
730+ case DATE_PROXIMITY_YESTERDAY:
731+ /* en_US example: "Yesterday 13:00" */
732+ /* TRANSLATORS: Please translate these to your locale datetime
733+ format using the format specified by
734+ https://qt-project.org/doc/qt-5-snapshot/qdatetime.html#fromString-2 */
735+ return datetime.toString(isLocale12h()
736+ ? dtr(ubuntuUiToolkit, QStringLiteral("'Yesterday\u2003'h:mm ap"))
737+ /* TRANSLATORS: Please translate these to your locale datetime
738+ format using the format specified by
739+ https://qt-project.org/doc/qt-5-snapshot/qdatetime.html#fromString-2 */
740+ : dtr(ubuntuUiToolkit, QStringLiteral("'Yesterday\u2003'HH:mm")));
741+
742+ case DATE_PROXIMITY_TOMORROW:
743+ /* en_US example: "Tomorrow 1:00 PM" */
744+ /* TRANSLATORS: Please translate these to your locale datetime
745+ format using the format specified by
746+ https://qt-project.org/doc/qt-5-snapshot/qdatetime.html#fromString-2 */
747+ return datetime.toString(isLocale12h()
748+ ? dtr(ubuntuUiToolkit, QStringLiteral("'Tomorrow\u2003'h:mm ap"))
749+ /* TRANSLATORS: Please translate these to your locale datetime
750+ format using the format specified by
751+ https://qt-project.org/doc/qt-5-snapshot/qdatetime.html#fromString-2 */
752+ : dtr(ubuntuUiToolkit, QStringLiteral("'Tomorrow\u2003'HH:mm")));
753+
754+ case DATE_PROXIMITY_LAST_WEEK:
755+ case DATE_PROXIMITY_NEXT_WEEK:
756+ /* en_US example: "Fri 1:00 PM" */
757+ /* TRANSLATORS: Please translate these to your locale datetime
758+ format using the format specified by
759+ https://qt-project.org/doc/qt-5-snapshot/qdatetime.html#fromString-2 */
760+ return datetime.toString(isLocale12h()
761+ ? dtr(ubuntuUiToolkit, QStringLiteral("ddd'\u2003'h:mm ap"))
762+ /* TRANSLATORS: Please translate these to your locale datetime
763+ format using the format specified by
764+ https://qt-project.org/doc/qt-5-snapshot/qdatetime.html#fromString-2 */
765+ : dtr(ubuntuUiToolkit, QStringLiteral("ddd'\u2003'HH:mm")));
766+
767+ case DATE_PROXIMITY_FAR_BACK:
768+ case DATE_PROXIMITY_FAR_FORWARD:
769+ default:
770+ /* TRANSLATORS: Please translate these to your locale datetime
771+ format using the format specified by
772+ https://qt-project.org/doc/qt-5-snapshot/qdatetime.html#fromString-2 */
773+ return datetime.toString(isLocale12h()
774+ ? dtr(ubuntuUiToolkit, QStringLiteral("ddd d MMM'\u2003'h:mm ap"))
775+ /* TRANSLATORS: Please translate these to your locale datetime
776+ format using the format specified by
777+ https://qt-project.org/doc/qt-5-snapshot/qdatetime.html#fromString-2 */
778+ : dtr(ubuntuUiToolkit, QStringLiteral("ddd d MMM'\u2003'HH:mm")));
779+ }
780+ return datetime.toString(Qt::DefaultLocaleShortDate);
781+}
782+
783+UT_NAMESPACE_END
784
785=== renamed file 'src/UbuntuToolkit/i18n.cpp' => 'src/UbuntuToolkit/i18n-ubuntu.cpp'
786=== added file 'src/UbuntuToolkit/i18n-windows.cpp'
787--- src/UbuntuToolkit/i18n-windows.cpp 1970-01-01 00:00:00 +0000
788+++ src/UbuntuToolkit/i18n-windows.cpp 2016-09-22 08:32:15 +0000
789@@ -0,0 +1,365 @@
790+/*
791+ * Copyright 2012-2015 Canonical Ltd.
792+ *
793+ * This program is free software; you can redistribute it and/or modify
794+ * it under the terms of the GNU Lesser General Public License as published by
795+ * the Free Software Foundation; version 3.
796+ *
797+ * This program is distributed in the hope that it will be useful,
798+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
799+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
800+ * GNU Lesser General Public License for more details.
801+ *
802+ * You should have received a copy of the GNU Lesser General Public License
803+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
804+ *
805+ * Author: Tim Peeters <tim.peeters@canonical.om>
806+ */
807+
808+#include "i18n_p.h"
809+
810+namespace C {
811+#include <libintl.h>
812+#include <glib.h>
813+#include <glib/gi18n.h>
814+}
815+#include <stdlib.h>
816+#include <locale.h>
817+
818+#include <QtCore/QDir>
819+
820+#include "timeutils_p.h"
821+
822+UT_NAMESPACE_BEGIN
823+/*!
824+ * \qmltype i18n
825+ * \inqmlmodule Ubuntu.Components
826+ * \ingroup ubuntu
827+ * \brief i18n is a context property that provides internationalization support.
828+ *
829+ * i18n cannot be instantiated, and is already available as a context property.
830+ * It is based on \l {https://www.gnu.org/software/gettext/} {gettext}, and thus the standard gettext tools can be used for translating
831+ * a project. Example:
832+ * \qml
833+ * import QtQuick 2.4
834+ * import Ubuntu.Components 0.1
835+ *
836+ * Item {
837+ * width: units.gu(40)
838+ * height: units.gu(50)
839+ *
840+ * Button {
841+ * anchors.centerIn: parent
842+ * text: i18n.tr("Press me")
843+ * }
844+ * }
845+ * \endqml
846+ */
847+UbuntuI18n *UbuntuI18n::m_i18 = nullptr;
848+
849+UbuntuI18n::UbuntuI18n(QObject* parent) : QObject(parent)
850+{
851+ /*
852+ * setlocale
853+ * category = LC_ALL: All types of i18n: LC_MESSAGES, LC_NUMERIC, LC_TIME
854+ * locale = "": Lookup the environment for $LC_ALL, $LC_* and $LANG in that order
855+ * Returns: for example en_US.utf8, da_DK or POSIX
856+ *
857+ * Note: $LANGUAGE is implicitly respected by gettext() calls and
858+ * defines the order of multiple locales
859+ */
860+ m_language = QString::fromLocal8Bit(setlocale(LC_ALL, ""));
861+}
862+
863+UbuntuI18n::~UbuntuI18n()
864+{
865+ m_i18 = nullptr;
866+}
867+
868+/*!
869+ * \qmlproperty string i18n::domain
870+ * The gettext domain to be used for the translation. The default domain
871+ * is the applicationName specified in the application's \l MainView, or the empty string "" if
872+ * no applicationName was given or no \l MainView is used.
873+ * Use dtr() functions instead of tr() to use a different domain for a single translation
874+ * that ignores i18n.domain.
875+ */
876+QString UbuntuI18n::domain() const {
877+ return m_domain;
878+}
879+
880+/*!
881+ * \qmlproperty string i18n::language
882+ * The language that is used for the translation. The default value is
883+ * the user's locale dending on $LC_ALL, $LC_MESSAGES and $LANG at the time
884+ * of running the application. See the gettext manual for details.
885+ */
886+QString UbuntuI18n::language() const {
887+ return m_language;
888+}
889+
890+/**
891+ * \qmlmethod void i18n::bindtextdomain(string domain_name, string dir_name)
892+ * Specify that the domain_name message catalog can be found
893+ * in dir_name rather than in the system locale data base.
894+ */
895+void UbuntuI18n::bindtextdomain(const QString& domain_name, const QString& dir_name) {
896+ C::bindtextdomain(domain_name.toUtf8(), dir_name.toUtf8());
897+ Q_EMIT domainChanged();
898+}
899+
900+void UbuntuI18n::setDomain(const QString &domain) {
901+ if (m_domain == domain)
902+ return;
903+
904+ m_domain = domain;
905+ C::textdomain(domain.toUtf8());
906+ /*
907+ The default is /usr/share/locale if we don't set a folder
908+ For click we use APP_DIR/share/locale
909+ e.g. /usr/share/click/preinstalled/com.example.foo/current/share/locale
910+ */
911+ QString appDir = QString::fromLocal8Bit(getenv("APP_DIR"));
912+ if (!QDir::isAbsolutePath (appDir)) {
913+ appDir = QStringLiteral("/usr");
914+ }
915+ QString localePath(QDir(appDir).filePath(QStringLiteral("share/locale")));
916+ C::bindtextdomain(domain.toUtf8(), localePath.toUtf8());
917+ Q_EMIT domainChanged();
918+}
919+
920+void UbuntuI18n::setLanguage(const QString &lang) {
921+ if (m_language == lang)
922+ return;
923+
924+ m_language = lang;
925+
926+ /*
927+ This is needed for LP: #1263163.
928+
929+ LANGUAGE may be set to one or more languages for example "fi" or
930+ "sv:de". gettext prioritizes LANGUAGE over LC_ALL, LC_*, and
931+ LANG, so if the session has already set LANGUAGE, calls to
932+ gettext will only use that. We must override it here so that
933+ future calls to gettext are done in the new language.
934+
935+ This only affects the current process. It does not override the
936+ user's session LANGUAGE.
937+ */
938+ setenv("LANGUAGE", lang.toUtf8().constData(), 1);
939+
940+ /*
941+ The inverse form of setlocale as used in the constructor, passing
942+ a valid locale string updates all category type defaults.
943+ */
944+ setlocale(LC_ALL, lang.toUtf8());
945+ Q_EMIT languageChanged();
946+}
947+
948+/*!
949+ * \qmlmethod string i18n::tr(string text)
950+ * Translate \a text using gettext and return the translation.
951+ */
952+QString UbuntuI18n::tr(const QString& text)
953+{
954+ return QString::fromUtf8(C::gettext(text.toUtf8()));
955+}
956+
957+/*!
958+ * \qmlmethod string i18n::tr(string singular, string plural, int n)
959+ * Translate the given input string \a singular or \a plural (depending on the number of items \a n)
960+ * using gettext.
961+ * Note that tr() does not automatically insert the values in the QString,
962+ * so it should be called like this:
963+ * tr("%1 file", "%1 files", count).arg(count)
964+ */
965+QString UbuntuI18n::tr(const QString &singular, const QString &plural, int n)
966+{
967+ return QString::fromUtf8(C::ngettext(singular.toUtf8(), plural.toUtf8(), n));
968+}
969+
970+/*!
971+ * \qmlmethod string i18n::dtr(string domain, string text)
972+ * Translate \a text using gettext. Uses the specified domain \a domain instead of i18n.domain.
973+ */
974+QString UbuntuI18n::dtr(const QString& domain, const QString& text)
975+{
976+ if (domain.isNull()) {
977+ return QString::fromUtf8(C::dgettext(NULL, text.toUtf8()));
978+ } else {
979+ return QString::fromUtf8(C::dgettext(domain.toUtf8(), text.toUtf8()));
980+ }
981+}
982+
983+/*!
984+ * \qmlmethod string i18n::dtr(string domain, string singular, string plural, int n)
985+ * Translate the given text using gettext. Should be called like this:
986+ * tr(domain, "%1 file", "%1 files", count).arg(count)
987+ * Uses \a domain for the domain instead of i18n.domain, and \a singular or \a plural
988+ * as input for the translation depending on the number of items \a n.
989+ */
990+QString UbuntuI18n::dtr(const QString& domain, const QString& singular, const QString& plural, int n)
991+{
992+ if (domain.isNull()) {
993+ return QString::fromUtf8(C::dngettext(NULL, singular.toUtf8(), plural.toUtf8(), n));
994+ } else {
995+ return QString::fromUtf8(C::dngettext(domain.toUtf8(), singular.toUtf8(), plural.toUtf8(), n));
996+ }
997+}
998+
999+/*!
1000+ * \qmlmethod string i18n::ctr(string context, string text)
1001+ * Translate \a text using gettext and return the translation.
1002+ * \a context is only visible to the translator and helps disambiguating for very short texts
1003+ */
1004+QString UbuntuI18n::ctr(const QString& context, const QString& text)
1005+{
1006+ return dctr(QString(), context, text);
1007+}
1008+
1009+/*!
1010+ * \qmlmethod string i18n::dctr(string domain, string context, string text)
1011+ * Translate \a text using gettext. Uses the specified domain \a domain instead of i18n.domain.
1012+ * \a context is only visible to the translator and helps disambiguating for very short texts
1013+ */
1014+QString UbuntuI18n::dctr(const QString& domain, const QString& context, const QString& text)
1015+{
1016+ if (domain.isNull()) {
1017+ return QString::fromUtf8(C::g_dpgettext2(NULL, context.toUtf8(), text.toUtf8()));
1018+ } else {
1019+ return QString::fromUtf8(C::g_dpgettext2(domain.toUtf8(), context.toUtf8(), text.toUtf8()));
1020+ }
1021+}
1022+
1023+/*!
1024+ * \qmlmethod string i18n::tag(string text)
1025+ * Mark \a text for translation at a later point. Typically this allows an API
1026+ * to take the original string and pass it to dtr (or dgettext).
1027+ *
1028+ * \qml
1029+ * import QtQuick 2.4
1030+ * import UserMetrics 0.1
1031+ *
1032+ * Metric {
1033+ * name: "distance"
1034+ * format: i18n.tag("Distance covered today: %1 km")
1035+ * emptyFormat: i18n.tag("No running today")
1036+ * domain: "runner.forest"
1037+ * }
1038+ * \endqml
1039+ *
1040+ * The strings tagged for localzation above are passed to the implementation
1041+ * of UserMetrics verbatim, as well as the domain of the app. Display and
1042+ * translation of the strings will happen in the lockscreen, where the same
1043+ * strings will be passed to i18n.tr.
1044+ */
1045+QString UbuntuI18n::tag(const QString& text)
1046+{
1047+ return text;
1048+}
1049+
1050+/*!
1051+ * \qmlmethod string i18n::tag(string context, string text)
1052+ * Mark \a text for translation at a later point. Typically this allows an API
1053+ * to take the original string and pass it to dctr (or g_dpgettext2).
1054+ * \a context is only visible to the translator and helps disambiguating for very short texts
1055+ */
1056+QString UbuntuI18n::tag(const QString& context, const QString& text)
1057+{
1058+ Q_UNUSED(context);
1059+ return text;
1060+}
1061+/*!
1062+ * \qmlmethod string i18n::relativeDateTime(datetime dateTime)
1063+ * Translate a datetime based on proximity to current time.
1064+ */
1065+QString UbuntuI18n::relativeDateTime(const QDateTime& datetime)
1066+{
1067+ static const QString ubuntuUiToolkit = QStringLiteral("ubuntu-ui-toolkit");
1068+
1069+ QDateTime relativeTo(QDateTime::currentDateTime());
1070+ const date_proximity_t prox = getDateProximity(relativeTo, datetime);
1071+
1072+ switch (prox) {
1073+ case DATE_PROXIMITY_NOW:
1074+ /* TRANSLATORS: Time based "this is happening/happened now" */
1075+ return dtr(ubuntuUiToolkit, QStringLiteral("Now"));
1076+
1077+ case DATE_PROXIMITY_HOUR:
1078+ {
1079+ qint64 diff = datetime.toMSecsSinceEpoch() - relativeTo.toMSecsSinceEpoch();
1080+ qint64 minutes = qRound(float(diff) / 60000);
1081+ if (minutes < 0) {
1082+ return dtr(ubuntuUiToolkit, QStringLiteral("%1 minute ago"),
1083+ QStringLiteral("%1 minutes ago"), qAbs(minutes)).arg(qAbs(minutes));
1084+ }
1085+ return dtr(ubuntuUiToolkit, QStringLiteral("%1 minute"),
1086+ QStringLiteral("%1 minutes"), minutes).arg(minutes);
1087+ }
1088+
1089+ case DATE_PROXIMITY_TODAY:
1090+ /* en_US example: "1:00 PM" */
1091+ /* TRANSLATORS: Please translate these to your locale datetime
1092+ format using the format specified by
1093+ https://qt-project.org/doc/qt-5-snapshot/qdatetime.html#fromString-2 */
1094+ return datetime.toString(isLocale12h()
1095+ ? dtr(ubuntuUiToolkit, QStringLiteral("h:mm ap"))
1096+ /* TRANSLATORS: Please translate these to your locale datetime
1097+ format using the format specified by
1098+ https://qt-project.org/doc/qt-5-snapshot/qdatetime.html#fromString-2 */
1099+ : dtr(ubuntuUiToolkit, QStringLiteral("HH:mm")));
1100+
1101+ case DATE_PROXIMITY_YESTERDAY:
1102+ /* en_US example: "Yesterday 13:00" */
1103+ /* TRANSLATORS: Please translate these to your locale datetime
1104+ format using the format specified by
1105+ https://qt-project.org/doc/qt-5-snapshot/qdatetime.html#fromString-2 */
1106+ return datetime.toString(isLocale12h()
1107+ ? dtr(ubuntuUiToolkit, QStringLiteral("'Yesterday\u2003'h:mm ap"))
1108+ /* TRANSLATORS: Please translate these to your locale datetime
1109+ format using the format specified by
1110+ https://qt-project.org/doc/qt-5-snapshot/qdatetime.html#fromString-2 */
1111+ : dtr(ubuntuUiToolkit, QStringLiteral("'Yesterday\u2003'HH:mm")));
1112+
1113+ case DATE_PROXIMITY_TOMORROW:
1114+ /* en_US example: "Tomorrow 1:00 PM" */
1115+ /* TRANSLATORS: Please translate these to your locale datetime
1116+ format using the format specified by
1117+ https://qt-project.org/doc/qt-5-snapshot/qdatetime.html#fromString-2 */
1118+ return datetime.toString(isLocale12h()
1119+ ? dtr(ubuntuUiToolkit, QStringLiteral("'Tomorrow\u2003'h:mm ap"))
1120+ /* TRANSLATORS: Please translate these to your locale datetime
1121+ format using the format specified by
1122+ https://qt-project.org/doc/qt-5-snapshot/qdatetime.html#fromString-2 */
1123+ : dtr(ubuntuUiToolkit, QStringLiteral("'Tomorrow\u2003'HH:mm")));
1124+
1125+ case DATE_PROXIMITY_LAST_WEEK:
1126+ case DATE_PROXIMITY_NEXT_WEEK:
1127+ /* en_US example: "Fri 1:00 PM" */
1128+ /* TRANSLATORS: Please translate these to your locale datetime
1129+ format using the format specified by
1130+ https://qt-project.org/doc/qt-5-snapshot/qdatetime.html#fromString-2 */
1131+ return datetime.toString(isLocale12h()
1132+ ? dtr(ubuntuUiToolkit, QStringLiteral("ddd'\u2003'h:mm ap"))
1133+ /* TRANSLATORS: Please translate these to your locale datetime
1134+ format using the format specified by
1135+ https://qt-project.org/doc/qt-5-snapshot/qdatetime.html#fromString-2 */
1136+ : dtr(ubuntuUiToolkit, QStringLiteral("ddd'\u2003'HH:mm")));
1137+
1138+ case DATE_PROXIMITY_FAR_BACK:
1139+ case DATE_PROXIMITY_FAR_FORWARD:
1140+ default:
1141+ /* TRANSLATORS: Please translate these to your locale datetime
1142+ format using the format specified by
1143+ https://qt-project.org/doc/qt-5-snapshot/qdatetime.html#fromString-2 */
1144+ return datetime.toString(isLocale12h()
1145+ ? dtr(ubuntuUiToolkit, QStringLiteral("ddd d MMM'\u2003'h:mm ap"))
1146+ /* TRANSLATORS: Please translate these to your locale datetime
1147+ format using the format specified by
1148+ https://qt-project.org/doc/qt-5-snapshot/qdatetime.html#fromString-2 */
1149+ : dtr(ubuntuUiToolkit, QStringLiteral("ddd d MMM'\u2003'HH:mm")));
1150+ }
1151+ return datetime.toString(Qt::DefaultLocaleShortDate);
1152+}
1153+
1154+UT_NAMESPACE_END

Subscribers

People subscribed via source and target branches