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
=== modified file 'src/UbuntuToolkit/UbuntuToolkit.pro'
--- src/UbuntuToolkit/UbuntuToolkit.pro 2016-09-12 14:56:56 +0000
+++ src/UbuntuToolkit/UbuntuToolkit.pro 2016-09-22 08:32:15 +0000
@@ -2,7 +2,7 @@
2QT = core-private gui-private qml-private quick-private testlib dbus svg organizer \2QT = core-private gui-private qml-private quick-private testlib dbus svg organizer \
3 UbuntuGestures-private UbuntuMetrics3 UbuntuGestures-private UbuntuMetrics
44
5unix {5linux {
6 CONFIG += link_pkgconfig6 CONFIG += link_pkgconfig
7 PKGCONFIG += gio-2.0 dbus-1 libnih libnih-dbus7 PKGCONFIG += gio-2.0 dbus-1 libnih libnih-dbus
8}8}
@@ -142,7 +142,6 @@
142 $$PWD/colorutils.cpp \142 $$PWD/colorutils.cpp \
143 $$PWD/exclusivegroup.cpp \143 $$PWD/exclusivegroup.cpp \
144 $$PWD/filterbehavior.cpp \144 $$PWD/filterbehavior.cpp \
145 $$PWD/i18n.cpp \
146 $$PWD/inversemouseareatype.cpp \145 $$PWD/inversemouseareatype.cpp \
147 $$PWD/listener.cpp \146 $$PWD/listener.cpp \
148 $$PWD/livetimer.cpp \147 $$PWD/livetimer.cpp \
@@ -237,4 +236,22 @@
237 $$PWD/privates/shaders/frame.vert \236 $$PWD/privates/shaders/frame.vert \
238 $$PWD/privates/shaders/frame.frag237 $$PWD/privates/shaders/frame.frag
239238
239macx {
240 # OSX and iOS specific
241 SOURCES += \
242 $$PWD/i18n-osx.cpp
243} else:android {
244 # Android specific
245 SOURCES += \
246 $$PWD/i18n-android.cpp
247} else:windows {
248 # Windows specific
249 SOURCES += \
250 $$PWD/i18n-windows.cpp
251} else {
252 # Ubuntu specific
253 SOURCES += \
254 $$PWD/i18n-ubuntu.cpp
255}
256
240load(ubuntu_qt_module)257load(ubuntu_qt_module)
241258
=== added file 'src/UbuntuToolkit/i18n-android.cpp'
--- src/UbuntuToolkit/i18n-android.cpp 1970-01-01 00:00:00 +0000
+++ src/UbuntuToolkit/i18n-android.cpp 2016-09-22 08:32:15 +0000
@@ -0,0 +1,365 @@
1/*
2 * Copyright 2012-2015 Canonical Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published by
6 * the Free Software Foundation; version 3.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Author: Tim Peeters <tim.peeters@canonical.om>
17 */
18
19#include "i18n_p.h"
20
21namespace C {
22#include <libintl.h>
23#include <glib.h>
24#include <glib/gi18n.h>
25}
26#include <stdlib.h>
27#include <locale.h>
28
29#include <QtCore/QDir>
30
31#include "timeutils_p.h"
32
33UT_NAMESPACE_BEGIN
34/*!
35 * \qmltype i18n
36 * \inqmlmodule Ubuntu.Components
37 * \ingroup ubuntu
38 * \brief i18n is a context property that provides internationalization support.
39 *
40 * i18n cannot be instantiated, and is already available as a context property.
41 * It is based on \l {https://www.gnu.org/software/gettext/} {gettext}, and thus the standard gettext tools can be used for translating
42 * a project. Example:
43 * \qml
44 * import QtQuick 2.4
45 * import Ubuntu.Components 0.1
46 *
47 * Item {
48 * width: units.gu(40)
49 * height: units.gu(50)
50 *
51 * Button {
52 * anchors.centerIn: parent
53 * text: i18n.tr("Press me")
54 * }
55 * }
56 * \endqml
57 */
58UbuntuI18n *UbuntuI18n::m_i18 = nullptr;
59
60UbuntuI18n::UbuntuI18n(QObject* parent) : QObject(parent)
61{
62 /*
63 * setlocale
64 * category = LC_ALL: All types of i18n: LC_MESSAGES, LC_NUMERIC, LC_TIME
65 * locale = "": Lookup the environment for $LC_ALL, $LC_* and $LANG in that order
66 * Returns: for example en_US.utf8, da_DK or POSIX
67 *
68 * Note: $LANGUAGE is implicitly respected by gettext() calls and
69 * defines the order of multiple locales
70 */
71 m_language = QString::fromLocal8Bit(setlocale(LC_ALL, ""));
72}
73
74UbuntuI18n::~UbuntuI18n()
75{
76 m_i18 = nullptr;
77}
78
79/*!
80 * \qmlproperty string i18n::domain
81 * The gettext domain to be used for the translation. The default domain
82 * is the applicationName specified in the application's \l MainView, or the empty string "" if
83 * no applicationName was given or no \l MainView is used.
84 * Use dtr() functions instead of tr() to use a different domain for a single translation
85 * that ignores i18n.domain.
86 */
87QString UbuntuI18n::domain() const {
88 return m_domain;
89}
90
91/*!
92 * \qmlproperty string i18n::language
93 * The language that is used for the translation. The default value is
94 * the user's locale dending on $LC_ALL, $LC_MESSAGES and $LANG at the time
95 * of running the application. See the gettext manual for details.
96 */
97QString UbuntuI18n::language() const {
98 return m_language;
99}
100
101/**
102 * \qmlmethod void i18n::bindtextdomain(string domain_name, string dir_name)
103 * Specify that the domain_name message catalog can be found
104 * in dir_name rather than in the system locale data base.
105 */
106void UbuntuI18n::bindtextdomain(const QString& domain_name, const QString& dir_name) {
107 C::bindtextdomain(domain_name.toUtf8(), dir_name.toUtf8());
108 Q_EMIT domainChanged();
109}
110
111void UbuntuI18n::setDomain(const QString &domain) {
112 if (m_domain == domain)
113 return;
114
115 m_domain = domain;
116 C::textdomain(domain.toUtf8());
117 /*
118 The default is /usr/share/locale if we don't set a folder
119 For click we use APP_DIR/share/locale
120 e.g. /usr/share/click/preinstalled/com.example.foo/current/share/locale
121 */
122 QString appDir = QString::fromLocal8Bit(getenv("APP_DIR"));
123 if (!QDir::isAbsolutePath (appDir)) {
124 appDir = QStringLiteral("/usr");
125 }
126 QString localePath(QDir(appDir).filePath(QStringLiteral("share/locale")));
127 C::bindtextdomain(domain.toUtf8(), localePath.toUtf8());
128 Q_EMIT domainChanged();
129}
130
131void UbuntuI18n::setLanguage(const QString &lang) {
132 if (m_language == lang)
133 return;
134
135 m_language = lang;
136
137 /*
138 This is needed for LP: #1263163.
139
140 LANGUAGE may be set to one or more languages for example "fi" or
141 "sv:de". gettext prioritizes LANGUAGE over LC_ALL, LC_*, and
142 LANG, so if the session has already set LANGUAGE, calls to
143 gettext will only use that. We must override it here so that
144 future calls to gettext are done in the new language.
145
146 This only affects the current process. It does not override the
147 user's session LANGUAGE.
148 */
149 setenv("LANGUAGE", lang.toUtf8().constData(), 1);
150
151 /*
152 The inverse form of setlocale as used in the constructor, passing
153 a valid locale string updates all category type defaults.
154 */
155 setlocale(LC_ALL, lang.toUtf8());
156 Q_EMIT languageChanged();
157}
158
159/*!
160 * \qmlmethod string i18n::tr(string text)
161 * Translate \a text using gettext and return the translation.
162 */
163QString UbuntuI18n::tr(const QString& text)
164{
165 return QString::fromUtf8(C::gettext(text.toUtf8()));
166}
167
168/*!
169 * \qmlmethod string i18n::tr(string singular, string plural, int n)
170 * Translate the given input string \a singular or \a plural (depending on the number of items \a n)
171 * using gettext.
172 * Note that tr() does not automatically insert the values in the QString,
173 * so it should be called like this:
174 * tr("%1 file", "%1 files", count).arg(count)
175 */
176QString UbuntuI18n::tr(const QString &singular, const QString &plural, int n)
177{
178 return QString::fromUtf8(C::ngettext(singular.toUtf8(), plural.toUtf8(), n));
179}
180
181/*!
182 * \qmlmethod string i18n::dtr(string domain, string text)
183 * Translate \a text using gettext. Uses the specified domain \a domain instead of i18n.domain.
184 */
185QString UbuntuI18n::dtr(const QString& domain, const QString& text)
186{
187 if (domain.isNull()) {
188 return QString::fromUtf8(C::dgettext(NULL, text.toUtf8()));
189 } else {
190 return QString::fromUtf8(C::dgettext(domain.toUtf8(), text.toUtf8()));
191 }
192}
193
194/*!
195 * \qmlmethod string i18n::dtr(string domain, string singular, string plural, int n)
196 * Translate the given text using gettext. Should be called like this:
197 * tr(domain, "%1 file", "%1 files", count).arg(count)
198 * Uses \a domain for the domain instead of i18n.domain, and \a singular or \a plural
199 * as input for the translation depending on the number of items \a n.
200 */
201QString UbuntuI18n::dtr(const QString& domain, const QString& singular, const QString& plural, int n)
202{
203 if (domain.isNull()) {
204 return QString::fromUtf8(C::dngettext(NULL, singular.toUtf8(), plural.toUtf8(), n));
205 } else {
206 return QString::fromUtf8(C::dngettext(domain.toUtf8(), singular.toUtf8(), plural.toUtf8(), n));
207 }
208}
209
210/*!
211 * \qmlmethod string i18n::ctr(string context, string text)
212 * Translate \a text using gettext and return the translation.
213 * \a context is only visible to the translator and helps disambiguating for very short texts
214 */
215QString UbuntuI18n::ctr(const QString& context, const QString& text)
216{
217 return dctr(QString(), context, text);
218}
219
220/*!
221 * \qmlmethod string i18n::dctr(string domain, string context, string text)
222 * Translate \a text using gettext. Uses the specified domain \a domain instead of i18n.domain.
223 * \a context is only visible to the translator and helps disambiguating for very short texts
224 */
225QString UbuntuI18n::dctr(const QString& domain, const QString& context, const QString& text)
226{
227 if (domain.isNull()) {
228 return QString::fromUtf8(C::g_dpgettext2(NULL, context.toUtf8(), text.toUtf8()));
229 } else {
230 return QString::fromUtf8(C::g_dpgettext2(domain.toUtf8(), context.toUtf8(), text.toUtf8()));
231 }
232}
233
234/*!
235 * \qmlmethod string i18n::tag(string text)
236 * Mark \a text for translation at a later point. Typically this allows an API
237 * to take the original string and pass it to dtr (or dgettext).
238 *
239 * \qml
240 * import QtQuick 2.4
241 * import UserMetrics 0.1
242 *
243 * Metric {
244 * name: "distance"
245 * format: i18n.tag("Distance covered today: %1 km")
246 * emptyFormat: i18n.tag("No running today")
247 * domain: "runner.forest"
248 * }
249 * \endqml
250 *
251 * The strings tagged for localzation above are passed to the implementation
252 * of UserMetrics verbatim, as well as the domain of the app. Display and
253 * translation of the strings will happen in the lockscreen, where the same
254 * strings will be passed to i18n.tr.
255 */
256QString UbuntuI18n::tag(const QString& text)
257{
258 return text;
259}
260
261/*!
262 * \qmlmethod string i18n::tag(string context, string text)
263 * Mark \a text for translation at a later point. Typically this allows an API
264 * to take the original string and pass it to dctr (or g_dpgettext2).
265 * \a context is only visible to the translator and helps disambiguating for very short texts
266 */
267QString UbuntuI18n::tag(const QString& context, const QString& text)
268{
269 Q_UNUSED(context);
270 return text;
271}
272/*!
273 * \qmlmethod string i18n::relativeDateTime(datetime dateTime)
274 * Translate a datetime based on proximity to current time.
275 */
276QString UbuntuI18n::relativeDateTime(const QDateTime& datetime)
277{
278 static const QString ubuntuUiToolkit = QStringLiteral("ubuntu-ui-toolkit");
279
280 QDateTime relativeTo(QDateTime::currentDateTime());
281 const date_proximity_t prox = getDateProximity(relativeTo, datetime);
282
283 switch (prox) {
284 case DATE_PROXIMITY_NOW:
285 /* TRANSLATORS: Time based "this is happening/happened now" */
286 return dtr(ubuntuUiToolkit, QStringLiteral("Now"));
287
288 case DATE_PROXIMITY_HOUR:
289 {
290 qint64 diff = datetime.toMSecsSinceEpoch() - relativeTo.toMSecsSinceEpoch();
291 qint64 minutes = qRound(float(diff) / 60000);
292 if (minutes < 0) {
293 return dtr(ubuntuUiToolkit, QStringLiteral("%1 minute ago"),
294 QStringLiteral("%1 minutes ago"), qAbs(minutes)).arg(qAbs(minutes));
295 }
296 return dtr(ubuntuUiToolkit, QStringLiteral("%1 minute"),
297 QStringLiteral("%1 minutes"), minutes).arg(minutes);
298 }
299
300 case DATE_PROXIMITY_TODAY:
301 /* en_US example: "1:00 PM" */
302 /* TRANSLATORS: Please translate these to your locale datetime
303 format using the format specified by
304 https://qt-project.org/doc/qt-5-snapshot/qdatetime.html#fromString-2 */
305 return datetime.toString(isLocale12h()
306 ? dtr(ubuntuUiToolkit, QStringLiteral("h:mm ap"))
307 /* TRANSLATORS: Please translate these to your locale datetime
308 format using the format specified by
309 https://qt-project.org/doc/qt-5-snapshot/qdatetime.html#fromString-2 */
310 : dtr(ubuntuUiToolkit, QStringLiteral("HH:mm")));
311
312 case DATE_PROXIMITY_YESTERDAY:
313 /* en_US example: "Yesterday 13:00" */
314 /* TRANSLATORS: Please translate these to your locale datetime
315 format using the format specified by
316 https://qt-project.org/doc/qt-5-snapshot/qdatetime.html#fromString-2 */
317 return datetime.toString(isLocale12h()
318 ? dtr(ubuntuUiToolkit, QStringLiteral("'Yesterday\u2003'h:mm ap"))
319 /* TRANSLATORS: Please translate these to your locale datetime
320 format using the format specified by
321 https://qt-project.org/doc/qt-5-snapshot/qdatetime.html#fromString-2 */
322 : dtr(ubuntuUiToolkit, QStringLiteral("'Yesterday\u2003'HH:mm")));
323
324 case DATE_PROXIMITY_TOMORROW:
325 /* en_US example: "Tomorrow 1:00 PM" */
326 /* TRANSLATORS: Please translate these to your locale datetime
327 format using the format specified by
328 https://qt-project.org/doc/qt-5-snapshot/qdatetime.html#fromString-2 */
329 return datetime.toString(isLocale12h()
330 ? dtr(ubuntuUiToolkit, QStringLiteral("'Tomorrow\u2003'h:mm ap"))
331 /* TRANSLATORS: Please translate these to your locale datetime
332 format using the format specified by
333 https://qt-project.org/doc/qt-5-snapshot/qdatetime.html#fromString-2 */
334 : dtr(ubuntuUiToolkit, QStringLiteral("'Tomorrow\u2003'HH:mm")));
335
336 case DATE_PROXIMITY_LAST_WEEK:
337 case DATE_PROXIMITY_NEXT_WEEK:
338 /* en_US example: "Fri 1:00 PM" */
339 /* TRANSLATORS: Please translate these to your locale datetime
340 format using the format specified by
341 https://qt-project.org/doc/qt-5-snapshot/qdatetime.html#fromString-2 */
342 return datetime.toString(isLocale12h()
343 ? dtr(ubuntuUiToolkit, QStringLiteral("ddd'\u2003'h:mm ap"))
344 /* TRANSLATORS: Please translate these to your locale datetime
345 format using the format specified by
346 https://qt-project.org/doc/qt-5-snapshot/qdatetime.html#fromString-2 */
347 : dtr(ubuntuUiToolkit, QStringLiteral("ddd'\u2003'HH:mm")));
348
349 case DATE_PROXIMITY_FAR_BACK:
350 case DATE_PROXIMITY_FAR_FORWARD:
351 default:
352 /* TRANSLATORS: Please translate these to your locale datetime
353 format using the format specified by
354 https://qt-project.org/doc/qt-5-snapshot/qdatetime.html#fromString-2 */
355 return datetime.toString(isLocale12h()
356 ? dtr(ubuntuUiToolkit, QStringLiteral("ddd d MMM'\u2003'h:mm ap"))
357 /* TRANSLATORS: Please translate these to your locale datetime
358 format using the format specified by
359 https://qt-project.org/doc/qt-5-snapshot/qdatetime.html#fromString-2 */
360 : dtr(ubuntuUiToolkit, QStringLiteral("ddd d MMM'\u2003'HH:mm")));
361 }
362 return datetime.toString(Qt::DefaultLocaleShortDate);
363}
364
365UT_NAMESPACE_END
0366
=== added file 'src/UbuntuToolkit/i18n-macx.cpp'
--- src/UbuntuToolkit/i18n-macx.cpp 1970-01-01 00:00:00 +0000
+++ src/UbuntuToolkit/i18n-macx.cpp 2016-09-22 08:32:15 +0000
@@ -0,0 +1,365 @@
1/*
2 * Copyright 2012-2015 Canonical Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published by
6 * the Free Software Foundation; version 3.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Author: Tim Peeters <tim.peeters@canonical.om>
17 */
18
19#include "i18n_p.h"
20
21namespace C {
22#include <libintl.h>
23#include <glib.h>
24#include <glib/gi18n.h>
25}
26#include <stdlib.h>
27#include <locale.h>
28
29#include <QtCore/QDir>
30
31#include "timeutils_p.h"
32
33UT_NAMESPACE_BEGIN
34/*!
35 * \qmltype i18n
36 * \inqmlmodule Ubuntu.Components
37 * \ingroup ubuntu
38 * \brief i18n is a context property that provides internationalization support.
39 *
40 * i18n cannot be instantiated, and is already available as a context property.
41 * It is based on \l {https://www.gnu.org/software/gettext/} {gettext}, and thus the standard gettext tools can be used for translating
42 * a project. Example:
43 * \qml
44 * import QtQuick 2.4
45 * import Ubuntu.Components 0.1
46 *
47 * Item {
48 * width: units.gu(40)
49 * height: units.gu(50)
50 *
51 * Button {
52 * anchors.centerIn: parent
53 * text: i18n.tr("Press me")
54 * }
55 * }
56 * \endqml
57 */
58UbuntuI18n *UbuntuI18n::m_i18 = nullptr;
59
60UbuntuI18n::UbuntuI18n(QObject* parent) : QObject(parent)
61{
62 /*
63 * setlocale
64 * category = LC_ALL: All types of i18n: LC_MESSAGES, LC_NUMERIC, LC_TIME
65 * locale = "": Lookup the environment for $LC_ALL, $LC_* and $LANG in that order
66 * Returns: for example en_US.utf8, da_DK or POSIX
67 *
68 * Note: $LANGUAGE is implicitly respected by gettext() calls and
69 * defines the order of multiple locales
70 */
71 m_language = QString::fromLocal8Bit(setlocale(LC_ALL, ""));
72}
73
74UbuntuI18n::~UbuntuI18n()
75{
76 m_i18 = nullptr;
77}
78
79/*!
80 * \qmlproperty string i18n::domain
81 * The gettext domain to be used for the translation. The default domain
82 * is the applicationName specified in the application's \l MainView, or the empty string "" if
83 * no applicationName was given or no \l MainView is used.
84 * Use dtr() functions instead of tr() to use a different domain for a single translation
85 * that ignores i18n.domain.
86 */
87QString UbuntuI18n::domain() const {
88 return m_domain;
89}
90
91/*!
92 * \qmlproperty string i18n::language
93 * The language that is used for the translation. The default value is
94 * the user's locale dending on $LC_ALL, $LC_MESSAGES and $LANG at the time
95 * of running the application. See the gettext manual for details.
96 */
97QString UbuntuI18n::language() const {
98 return m_language;
99}
100
101/**
102 * \qmlmethod void i18n::bindtextdomain(string domain_name, string dir_name)
103 * Specify that the domain_name message catalog can be found
104 * in dir_name rather than in the system locale data base.
105 */
106void UbuntuI18n::bindtextdomain(const QString& domain_name, const QString& dir_name) {
107 C::bindtextdomain(domain_name.toUtf8(), dir_name.toUtf8());
108 Q_EMIT domainChanged();
109}
110
111void UbuntuI18n::setDomain(const QString &domain) {
112 if (m_domain == domain)
113 return;
114
115 m_domain = domain;
116 C::textdomain(domain.toUtf8());
117 /*
118 The default is /usr/share/locale if we don't set a folder
119 For click we use APP_DIR/share/locale
120 e.g. /usr/share/click/preinstalled/com.example.foo/current/share/locale
121 */
122 QString appDir = QString::fromLocal8Bit(getenv("APP_DIR"));
123 if (!QDir::isAbsolutePath (appDir)) {
124 appDir = QStringLiteral("/usr");
125 }
126 QString localePath(QDir(appDir).filePath(QStringLiteral("share/locale")));
127 C::bindtextdomain(domain.toUtf8(), localePath.toUtf8());
128 Q_EMIT domainChanged();
129}
130
131void UbuntuI18n::setLanguage(const QString &lang) {
132 if (m_language == lang)
133 return;
134
135 m_language = lang;
136
137 /*
138 This is needed for LP: #1263163.
139
140 LANGUAGE may be set to one or more languages for example "fi" or
141 "sv:de". gettext prioritizes LANGUAGE over LC_ALL, LC_*, and
142 LANG, so if the session has already set LANGUAGE, calls to
143 gettext will only use that. We must override it here so that
144 future calls to gettext are done in the new language.
145
146 This only affects the current process. It does not override the
147 user's session LANGUAGE.
148 */
149 setenv("LANGUAGE", lang.toUtf8().constData(), 1);
150
151 /*
152 The inverse form of setlocale as used in the constructor, passing
153 a valid locale string updates all category type defaults.
154 */
155 setlocale(LC_ALL, lang.toUtf8());
156 Q_EMIT languageChanged();
157}
158
159/*!
160 * \qmlmethod string i18n::tr(string text)
161 * Translate \a text using gettext and return the translation.
162 */
163QString UbuntuI18n::tr(const QString& text)
164{
165 return QString::fromUtf8(C::gettext(text.toUtf8()));
166}
167
168/*!
169 * \qmlmethod string i18n::tr(string singular, string plural, int n)
170 * Translate the given input string \a singular or \a plural (depending on the number of items \a n)
171 * using gettext.
172 * Note that tr() does not automatically insert the values in the QString,
173 * so it should be called like this:
174 * tr("%1 file", "%1 files", count).arg(count)
175 */
176QString UbuntuI18n::tr(const QString &singular, const QString &plural, int n)
177{
178 return QString::fromUtf8(C::ngettext(singular.toUtf8(), plural.toUtf8(), n));
179}
180
181/*!
182 * \qmlmethod string i18n::dtr(string domain, string text)
183 * Translate \a text using gettext. Uses the specified domain \a domain instead of i18n.domain.
184 */
185QString UbuntuI18n::dtr(const QString& domain, const QString& text)
186{
187 if (domain.isNull()) {
188 return QString::fromUtf8(C::dgettext(NULL, text.toUtf8()));
189 } else {
190 return QString::fromUtf8(C::dgettext(domain.toUtf8(), text.toUtf8()));
191 }
192}
193
194/*!
195 * \qmlmethod string i18n::dtr(string domain, string singular, string plural, int n)
196 * Translate the given text using gettext. Should be called like this:
197 * tr(domain, "%1 file", "%1 files", count).arg(count)
198 * Uses \a domain for the domain instead of i18n.domain, and \a singular or \a plural
199 * as input for the translation depending on the number of items \a n.
200 */
201QString UbuntuI18n::dtr(const QString& domain, const QString& singular, const QString& plural, int n)
202{
203 if (domain.isNull()) {
204 return QString::fromUtf8(C::dngettext(NULL, singular.toUtf8(), plural.toUtf8(), n));
205 } else {
206 return QString::fromUtf8(C::dngettext(domain.toUtf8(), singular.toUtf8(), plural.toUtf8(), n));
207 }
208}
209
210/*!
211 * \qmlmethod string i18n::ctr(string context, string text)
212 * Translate \a text using gettext and return the translation.
213 * \a context is only visible to the translator and helps disambiguating for very short texts
214 */
215QString UbuntuI18n::ctr(const QString& context, const QString& text)
216{
217 return dctr(QString(), context, text);
218}
219
220/*!
221 * \qmlmethod string i18n::dctr(string domain, string context, string text)
222 * Translate \a text using gettext. Uses the specified domain \a domain instead of i18n.domain.
223 * \a context is only visible to the translator and helps disambiguating for very short texts
224 */
225QString UbuntuI18n::dctr(const QString& domain, const QString& context, const QString& text)
226{
227 if (domain.isNull()) {
228 return QString::fromUtf8(C::g_dpgettext2(NULL, context.toUtf8(), text.toUtf8()));
229 } else {
230 return QString::fromUtf8(C::g_dpgettext2(domain.toUtf8(), context.toUtf8(), text.toUtf8()));
231 }
232}
233
234/*!
235 * \qmlmethod string i18n::tag(string text)
236 * Mark \a text for translation at a later point. Typically this allows an API
237 * to take the original string and pass it to dtr (or dgettext).
238 *
239 * \qml
240 * import QtQuick 2.4
241 * import UserMetrics 0.1
242 *
243 * Metric {
244 * name: "distance"
245 * format: i18n.tag("Distance covered today: %1 km")
246 * emptyFormat: i18n.tag("No running today")
247 * domain: "runner.forest"
248 * }
249 * \endqml
250 *
251 * The strings tagged for localzation above are passed to the implementation
252 * of UserMetrics verbatim, as well as the domain of the app. Display and
253 * translation of the strings will happen in the lockscreen, where the same
254 * strings will be passed to i18n.tr.
255 */
256QString UbuntuI18n::tag(const QString& text)
257{
258 return text;
259}
260
261/*!
262 * \qmlmethod string i18n::tag(string context, string text)
263 * Mark \a text for translation at a later point. Typically this allows an API
264 * to take the original string and pass it to dctr (or g_dpgettext2).
265 * \a context is only visible to the translator and helps disambiguating for very short texts
266 */
267QString UbuntuI18n::tag(const QString& context, const QString& text)
268{
269 Q_UNUSED(context);
270 return text;
271}
272/*!
273 * \qmlmethod string i18n::relativeDateTime(datetime dateTime)
274 * Translate a datetime based on proximity to current time.
275 */
276QString UbuntuI18n::relativeDateTime(const QDateTime& datetime)
277{
278 static const QString ubuntuUiToolkit = QStringLiteral("ubuntu-ui-toolkit");
279
280 QDateTime relativeTo(QDateTime::currentDateTime());
281 const date_proximity_t prox = getDateProximity(relativeTo, datetime);
282
283 switch (prox) {
284 case DATE_PROXIMITY_NOW:
285 /* TRANSLATORS: Time based "this is happening/happened now" */
286 return dtr(ubuntuUiToolkit, QStringLiteral("Now"));
287
288 case DATE_PROXIMITY_HOUR:
289 {
290 qint64 diff = datetime.toMSecsSinceEpoch() - relativeTo.toMSecsSinceEpoch();
291 qint64 minutes = qRound(float(diff) / 60000);
292 if (minutes < 0) {
293 return dtr(ubuntuUiToolkit, QStringLiteral("%1 minute ago"),
294 QStringLiteral("%1 minutes ago"), qAbs(minutes)).arg(qAbs(minutes));
295 }
296 return dtr(ubuntuUiToolkit, QStringLiteral("%1 minute"),
297 QStringLiteral("%1 minutes"), minutes).arg(minutes);
298 }
299
300 case DATE_PROXIMITY_TODAY:
301 /* en_US example: "1:00 PM" */
302 /* TRANSLATORS: Please translate these to your locale datetime
303 format using the format specified by
304 https://qt-project.org/doc/qt-5-snapshot/qdatetime.html#fromString-2 */
305 return datetime.toString(isLocale12h()
306 ? dtr(ubuntuUiToolkit, QStringLiteral("h:mm ap"))
307 /* TRANSLATORS: Please translate these to your locale datetime
308 format using the format specified by
309 https://qt-project.org/doc/qt-5-snapshot/qdatetime.html#fromString-2 */
310 : dtr(ubuntuUiToolkit, QStringLiteral("HH:mm")));
311
312 case DATE_PROXIMITY_YESTERDAY:
313 /* en_US example: "Yesterday 13:00" */
314 /* TRANSLATORS: Please translate these to your locale datetime
315 format using the format specified by
316 https://qt-project.org/doc/qt-5-snapshot/qdatetime.html#fromString-2 */
317 return datetime.toString(isLocale12h()
318 ? dtr(ubuntuUiToolkit, QStringLiteral("'Yesterday\u2003'h:mm ap"))
319 /* TRANSLATORS: Please translate these to your locale datetime
320 format using the format specified by
321 https://qt-project.org/doc/qt-5-snapshot/qdatetime.html#fromString-2 */
322 : dtr(ubuntuUiToolkit, QStringLiteral("'Yesterday\u2003'HH:mm")));
323
324 case DATE_PROXIMITY_TOMORROW:
325 /* en_US example: "Tomorrow 1:00 PM" */
326 /* TRANSLATORS: Please translate these to your locale datetime
327 format using the format specified by
328 https://qt-project.org/doc/qt-5-snapshot/qdatetime.html#fromString-2 */
329 return datetime.toString(isLocale12h()
330 ? dtr(ubuntuUiToolkit, QStringLiteral("'Tomorrow\u2003'h:mm ap"))
331 /* TRANSLATORS: Please translate these to your locale datetime
332 format using the format specified by
333 https://qt-project.org/doc/qt-5-snapshot/qdatetime.html#fromString-2 */
334 : dtr(ubuntuUiToolkit, QStringLiteral("'Tomorrow\u2003'HH:mm")));
335
336 case DATE_PROXIMITY_LAST_WEEK:
337 case DATE_PROXIMITY_NEXT_WEEK:
338 /* en_US example: "Fri 1:00 PM" */
339 /* TRANSLATORS: Please translate these to your locale datetime
340 format using the format specified by
341 https://qt-project.org/doc/qt-5-snapshot/qdatetime.html#fromString-2 */
342 return datetime.toString(isLocale12h()
343 ? dtr(ubuntuUiToolkit, QStringLiteral("ddd'\u2003'h:mm ap"))
344 /* TRANSLATORS: Please translate these to your locale datetime
345 format using the format specified by
346 https://qt-project.org/doc/qt-5-snapshot/qdatetime.html#fromString-2 */
347 : dtr(ubuntuUiToolkit, QStringLiteral("ddd'\u2003'HH:mm")));
348
349 case DATE_PROXIMITY_FAR_BACK:
350 case DATE_PROXIMITY_FAR_FORWARD:
351 default:
352 /* TRANSLATORS: Please translate these to your locale datetime
353 format using the format specified by
354 https://qt-project.org/doc/qt-5-snapshot/qdatetime.html#fromString-2 */
355 return datetime.toString(isLocale12h()
356 ? dtr(ubuntuUiToolkit, QStringLiteral("ddd d MMM'\u2003'h:mm ap"))
357 /* TRANSLATORS: Please translate these to your locale datetime
358 format using the format specified by
359 https://qt-project.org/doc/qt-5-snapshot/qdatetime.html#fromString-2 */
360 : dtr(ubuntuUiToolkit, QStringLiteral("ddd d MMM'\u2003'HH:mm")));
361 }
362 return datetime.toString(Qt::DefaultLocaleShortDate);
363}
364
365UT_NAMESPACE_END
0366
=== renamed file 'src/UbuntuToolkit/i18n.cpp' => 'src/UbuntuToolkit/i18n-ubuntu.cpp'
=== added file 'src/UbuntuToolkit/i18n-windows.cpp'
--- src/UbuntuToolkit/i18n-windows.cpp 1970-01-01 00:00:00 +0000
+++ src/UbuntuToolkit/i18n-windows.cpp 2016-09-22 08:32:15 +0000
@@ -0,0 +1,365 @@
1/*
2 * Copyright 2012-2015 Canonical Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published by
6 * the Free Software Foundation; version 3.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Author: Tim Peeters <tim.peeters@canonical.om>
17 */
18
19#include "i18n_p.h"
20
21namespace C {
22#include <libintl.h>
23#include <glib.h>
24#include <glib/gi18n.h>
25}
26#include <stdlib.h>
27#include <locale.h>
28
29#include <QtCore/QDir>
30
31#include "timeutils_p.h"
32
33UT_NAMESPACE_BEGIN
34/*!
35 * \qmltype i18n
36 * \inqmlmodule Ubuntu.Components
37 * \ingroup ubuntu
38 * \brief i18n is a context property that provides internationalization support.
39 *
40 * i18n cannot be instantiated, and is already available as a context property.
41 * It is based on \l {https://www.gnu.org/software/gettext/} {gettext}, and thus the standard gettext tools can be used for translating
42 * a project. Example:
43 * \qml
44 * import QtQuick 2.4
45 * import Ubuntu.Components 0.1
46 *
47 * Item {
48 * width: units.gu(40)
49 * height: units.gu(50)
50 *
51 * Button {
52 * anchors.centerIn: parent
53 * text: i18n.tr("Press me")
54 * }
55 * }
56 * \endqml
57 */
58UbuntuI18n *UbuntuI18n::m_i18 = nullptr;
59
60UbuntuI18n::UbuntuI18n(QObject* parent) : QObject(parent)
61{
62 /*
63 * setlocale
64 * category = LC_ALL: All types of i18n: LC_MESSAGES, LC_NUMERIC, LC_TIME
65 * locale = "": Lookup the environment for $LC_ALL, $LC_* and $LANG in that order
66 * Returns: for example en_US.utf8, da_DK or POSIX
67 *
68 * Note: $LANGUAGE is implicitly respected by gettext() calls and
69 * defines the order of multiple locales
70 */
71 m_language = QString::fromLocal8Bit(setlocale(LC_ALL, ""));
72}
73
74UbuntuI18n::~UbuntuI18n()
75{
76 m_i18 = nullptr;
77}
78
79/*!
80 * \qmlproperty string i18n::domain
81 * The gettext domain to be used for the translation. The default domain
82 * is the applicationName specified in the application's \l MainView, or the empty string "" if
83 * no applicationName was given or no \l MainView is used.
84 * Use dtr() functions instead of tr() to use a different domain for a single translation
85 * that ignores i18n.domain.
86 */
87QString UbuntuI18n::domain() const {
88 return m_domain;
89}
90
91/*!
92 * \qmlproperty string i18n::language
93 * The language that is used for the translation. The default value is
94 * the user's locale dending on $LC_ALL, $LC_MESSAGES and $LANG at the time
95 * of running the application. See the gettext manual for details.
96 */
97QString UbuntuI18n::language() const {
98 return m_language;
99}
100
101/**
102 * \qmlmethod void i18n::bindtextdomain(string domain_name, string dir_name)
103 * Specify that the domain_name message catalog can be found
104 * in dir_name rather than in the system locale data base.
105 */
106void UbuntuI18n::bindtextdomain(const QString& domain_name, const QString& dir_name) {
107 C::bindtextdomain(domain_name.toUtf8(), dir_name.toUtf8());
108 Q_EMIT domainChanged();
109}
110
111void UbuntuI18n::setDomain(const QString &domain) {
112 if (m_domain == domain)
113 return;
114
115 m_domain = domain;
116 C::textdomain(domain.toUtf8());
117 /*
118 The default is /usr/share/locale if we don't set a folder
119 For click we use APP_DIR/share/locale
120 e.g. /usr/share/click/preinstalled/com.example.foo/current/share/locale
121 */
122 QString appDir = QString::fromLocal8Bit(getenv("APP_DIR"));
123 if (!QDir::isAbsolutePath (appDir)) {
124 appDir = QStringLiteral("/usr");
125 }
126 QString localePath(QDir(appDir).filePath(QStringLiteral("share/locale")));
127 C::bindtextdomain(domain.toUtf8(), localePath.toUtf8());
128 Q_EMIT domainChanged();
129}
130
131void UbuntuI18n::setLanguage(const QString &lang) {
132 if (m_language == lang)
133 return;
134
135 m_language = lang;
136
137 /*
138 This is needed for LP: #1263163.
139
140 LANGUAGE may be set to one or more languages for example "fi" or
141 "sv:de". gettext prioritizes LANGUAGE over LC_ALL, LC_*, and
142 LANG, so if the session has already set LANGUAGE, calls to
143 gettext will only use that. We must override it here so that
144 future calls to gettext are done in the new language.
145
146 This only affects the current process. It does not override the
147 user's session LANGUAGE.
148 */
149 setenv("LANGUAGE", lang.toUtf8().constData(), 1);
150
151 /*
152 The inverse form of setlocale as used in the constructor, passing
153 a valid locale string updates all category type defaults.
154 */
155 setlocale(LC_ALL, lang.toUtf8());
156 Q_EMIT languageChanged();
157}
158
159/*!
160 * \qmlmethod string i18n::tr(string text)
161 * Translate \a text using gettext and return the translation.
162 */
163QString UbuntuI18n::tr(const QString& text)
164{
165 return QString::fromUtf8(C::gettext(text.toUtf8()));
166}
167
168/*!
169 * \qmlmethod string i18n::tr(string singular, string plural, int n)
170 * Translate the given input string \a singular or \a plural (depending on the number of items \a n)
171 * using gettext.
172 * Note that tr() does not automatically insert the values in the QString,
173 * so it should be called like this:
174 * tr("%1 file", "%1 files", count).arg(count)
175 */
176QString UbuntuI18n::tr(const QString &singular, const QString &plural, int n)
177{
178 return QString::fromUtf8(C::ngettext(singular.toUtf8(), plural.toUtf8(), n));
179}
180
181/*!
182 * \qmlmethod string i18n::dtr(string domain, string text)
183 * Translate \a text using gettext. Uses the specified domain \a domain instead of i18n.domain.
184 */
185QString UbuntuI18n::dtr(const QString& domain, const QString& text)
186{
187 if (domain.isNull()) {
188 return QString::fromUtf8(C::dgettext(NULL, text.toUtf8()));
189 } else {
190 return QString::fromUtf8(C::dgettext(domain.toUtf8(), text.toUtf8()));
191 }
192}
193
194/*!
195 * \qmlmethod string i18n::dtr(string domain, string singular, string plural, int n)
196 * Translate the given text using gettext. Should be called like this:
197 * tr(domain, "%1 file", "%1 files", count).arg(count)
198 * Uses \a domain for the domain instead of i18n.domain, and \a singular or \a plural
199 * as input for the translation depending on the number of items \a n.
200 */
201QString UbuntuI18n::dtr(const QString& domain, const QString& singular, const QString& plural, int n)
202{
203 if (domain.isNull()) {
204 return QString::fromUtf8(C::dngettext(NULL, singular.toUtf8(), plural.toUtf8(), n));
205 } else {
206 return QString::fromUtf8(C::dngettext(domain.toUtf8(), singular.toUtf8(), plural.toUtf8(), n));
207 }
208}
209
210/*!
211 * \qmlmethod string i18n::ctr(string context, string text)
212 * Translate \a text using gettext and return the translation.
213 * \a context is only visible to the translator and helps disambiguating for very short texts
214 */
215QString UbuntuI18n::ctr(const QString& context, const QString& text)
216{
217 return dctr(QString(), context, text);
218}
219
220/*!
221 * \qmlmethod string i18n::dctr(string domain, string context, string text)
222 * Translate \a text using gettext. Uses the specified domain \a domain instead of i18n.domain.
223 * \a context is only visible to the translator and helps disambiguating for very short texts
224 */
225QString UbuntuI18n::dctr(const QString& domain, const QString& context, const QString& text)
226{
227 if (domain.isNull()) {
228 return QString::fromUtf8(C::g_dpgettext2(NULL, context.toUtf8(), text.toUtf8()));
229 } else {
230 return QString::fromUtf8(C::g_dpgettext2(domain.toUtf8(), context.toUtf8(), text.toUtf8()));
231 }
232}
233
234/*!
235 * \qmlmethod string i18n::tag(string text)
236 * Mark \a text for translation at a later point. Typically this allows an API
237 * to take the original string and pass it to dtr (or dgettext).
238 *
239 * \qml
240 * import QtQuick 2.4
241 * import UserMetrics 0.1
242 *
243 * Metric {
244 * name: "distance"
245 * format: i18n.tag("Distance covered today: %1 km")
246 * emptyFormat: i18n.tag("No running today")
247 * domain: "runner.forest"
248 * }
249 * \endqml
250 *
251 * The strings tagged for localzation above are passed to the implementation
252 * of UserMetrics verbatim, as well as the domain of the app. Display and
253 * translation of the strings will happen in the lockscreen, where the same
254 * strings will be passed to i18n.tr.
255 */
256QString UbuntuI18n::tag(const QString& text)
257{
258 return text;
259}
260
261/*!
262 * \qmlmethod string i18n::tag(string context, string text)
263 * Mark \a text for translation at a later point. Typically this allows an API
264 * to take the original string and pass it to dctr (or g_dpgettext2).
265 * \a context is only visible to the translator and helps disambiguating for very short texts
266 */
267QString UbuntuI18n::tag(const QString& context, const QString& text)
268{
269 Q_UNUSED(context);
270 return text;
271}
272/*!
273 * \qmlmethod string i18n::relativeDateTime(datetime dateTime)
274 * Translate a datetime based on proximity to current time.
275 */
276QString UbuntuI18n::relativeDateTime(const QDateTime& datetime)
277{
278 static const QString ubuntuUiToolkit = QStringLiteral("ubuntu-ui-toolkit");
279
280 QDateTime relativeTo(QDateTime::currentDateTime());
281 const date_proximity_t prox = getDateProximity(relativeTo, datetime);
282
283 switch (prox) {
284 case DATE_PROXIMITY_NOW:
285 /* TRANSLATORS: Time based "this is happening/happened now" */
286 return dtr(ubuntuUiToolkit, QStringLiteral("Now"));
287
288 case DATE_PROXIMITY_HOUR:
289 {
290 qint64 diff = datetime.toMSecsSinceEpoch() - relativeTo.toMSecsSinceEpoch();
291 qint64 minutes = qRound(float(diff) / 60000);
292 if (minutes < 0) {
293 return dtr(ubuntuUiToolkit, QStringLiteral("%1 minute ago"),
294 QStringLiteral("%1 minutes ago"), qAbs(minutes)).arg(qAbs(minutes));
295 }
296 return dtr(ubuntuUiToolkit, QStringLiteral("%1 minute"),
297 QStringLiteral("%1 minutes"), minutes).arg(minutes);
298 }
299
300 case DATE_PROXIMITY_TODAY:
301 /* en_US example: "1:00 PM" */
302 /* TRANSLATORS: Please translate these to your locale datetime
303 format using the format specified by
304 https://qt-project.org/doc/qt-5-snapshot/qdatetime.html#fromString-2 */
305 return datetime.toString(isLocale12h()
306 ? dtr(ubuntuUiToolkit, QStringLiteral("h:mm ap"))
307 /* TRANSLATORS: Please translate these to your locale datetime
308 format using the format specified by
309 https://qt-project.org/doc/qt-5-snapshot/qdatetime.html#fromString-2 */
310 : dtr(ubuntuUiToolkit, QStringLiteral("HH:mm")));
311
312 case DATE_PROXIMITY_YESTERDAY:
313 /* en_US example: "Yesterday 13:00" */
314 /* TRANSLATORS: Please translate these to your locale datetime
315 format using the format specified by
316 https://qt-project.org/doc/qt-5-snapshot/qdatetime.html#fromString-2 */
317 return datetime.toString(isLocale12h()
318 ? dtr(ubuntuUiToolkit, QStringLiteral("'Yesterday\u2003'h:mm ap"))
319 /* TRANSLATORS: Please translate these to your locale datetime
320 format using the format specified by
321 https://qt-project.org/doc/qt-5-snapshot/qdatetime.html#fromString-2 */
322 : dtr(ubuntuUiToolkit, QStringLiteral("'Yesterday\u2003'HH:mm")));
323
324 case DATE_PROXIMITY_TOMORROW:
325 /* en_US example: "Tomorrow 1:00 PM" */
326 /* TRANSLATORS: Please translate these to your locale datetime
327 format using the format specified by
328 https://qt-project.org/doc/qt-5-snapshot/qdatetime.html#fromString-2 */
329 return datetime.toString(isLocale12h()
330 ? dtr(ubuntuUiToolkit, QStringLiteral("'Tomorrow\u2003'h:mm ap"))
331 /* TRANSLATORS: Please translate these to your locale datetime
332 format using the format specified by
333 https://qt-project.org/doc/qt-5-snapshot/qdatetime.html#fromString-2 */
334 : dtr(ubuntuUiToolkit, QStringLiteral("'Tomorrow\u2003'HH:mm")));
335
336 case DATE_PROXIMITY_LAST_WEEK:
337 case DATE_PROXIMITY_NEXT_WEEK:
338 /* en_US example: "Fri 1:00 PM" */
339 /* TRANSLATORS: Please translate these to your locale datetime
340 format using the format specified by
341 https://qt-project.org/doc/qt-5-snapshot/qdatetime.html#fromString-2 */
342 return datetime.toString(isLocale12h()
343 ? dtr(ubuntuUiToolkit, QStringLiteral("ddd'\u2003'h:mm ap"))
344 /* TRANSLATORS: Please translate these to your locale datetime
345 format using the format specified by
346 https://qt-project.org/doc/qt-5-snapshot/qdatetime.html#fromString-2 */
347 : dtr(ubuntuUiToolkit, QStringLiteral("ddd'\u2003'HH:mm")));
348
349 case DATE_PROXIMITY_FAR_BACK:
350 case DATE_PROXIMITY_FAR_FORWARD:
351 default:
352 /* TRANSLATORS: Please translate these to your locale datetime
353 format using the format specified by
354 https://qt-project.org/doc/qt-5-snapshot/qdatetime.html#fromString-2 */
355 return datetime.toString(isLocale12h()
356 ? dtr(ubuntuUiToolkit, QStringLiteral("ddd d MMM'\u2003'h:mm ap"))
357 /* TRANSLATORS: Please translate these to your locale datetime
358 format using the format specified by
359 https://qt-project.org/doc/qt-5-snapshot/qdatetime.html#fromString-2 */
360 : dtr(ubuntuUiToolkit, QStringLiteral("ddd d MMM'\u2003'HH:mm")));
361 }
362 return datetime.toString(Qt::DefaultLocaleShortDate);
363}
364
365UT_NAMESPACE_END

Subscribers

People subscribed via source and target branches