Merge lp:~aacid/ubuntu-ui-toolkit/i18n-RelativeDateTime into lp:ubuntu-ui-toolkit/staging

Proposed by Albert Astals Cid
Status: Merged
Approved by: Zsombor Egri
Approved revision: 1611
Merged at revision: 1604
Proposed branch: lp:~aacid/ubuntu-ui-toolkit/i18n-RelativeDateTime
Merge into: lp:ubuntu-ui-toolkit/staging
Prerequisite: lp:~aacid/ubuntu-ui-toolkit/LiveTimer
Diff against target: 679 lines (+512/-24)
12 files modified
components.api (+1/-0)
src/Ubuntu/Components/plugin/i18n.cpp (+74/-0)
src/Ubuntu/Components/plugin/i18n.h (+1/-0)
src/Ubuntu/Components/plugin/timeutils_p.h (+24/-0)
tests/unit/tst_i18n/tst_i18n.pro (+3/-18)
tests/unit/tst_i18n/tst_i18n_LocalizedApp/src/LocalizedApp.qml (+43/-1)
tests/unit/tst_i18n/tst_i18n_LocalizedApp/src/tst_i18n_LocalizedApp.cpp (+5/-5)
tests/unit/tst_i18n/tst_i18n_LocalizedApp/tst_i18n_LocalizedApp.pro (+17/-0)
tests/unit/tst_i18n/tst_i18n_RelativeTime/po/en_US.po (+54/-0)
tests/unit/tst_i18n/tst_i18n_RelativeTime/src/RelativeTime.qml (+71/-0)
tests/unit/tst_i18n/tst_i18n_RelativeTime/src/tst_i18n_RelativeTime.cpp (+202/-0)
tests/unit/tst_i18n/tst_i18n_RelativeTime/tst_i18n_RelativeTime.pro (+17/-0)
To merge this branch: bzr merge lp:~aacid/ubuntu-ui-toolkit/i18n-RelativeDateTime
Reviewer Review Type Date Requested Status
Lukáš Tinkl (community) code-review Needs Fixing
PS Jenkins bot continuous-integration Approve
Zsombor Egri Approve
Review via email: mp+267788@code.launchpad.net

Commit message

Added relative date time i18n

Description of the change

Added relative date time i18n

To post a comment you must log in.
1608. By Nick Dedekind

i18n.relativeDateTime

1609. By Nick Dedekind

review comments

1610. By Nick Dedekind

split relative time i18n

1611. By Nick Dedekind

split relative time i18n from localizedApp

Revision history for this message
Albert Astals Cid (aacid) wrote :
Revision history for this message
Zsombor Egri (zsombi) wrote :

This one too.

review: Approve
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Lukáš Tinkl (lukas-kde) wrote :

One small optimization comment

review: Needs Fixing (code-review)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'components.api'
--- components.api 2015-08-12 10:11:43 +0000
+++ components.api 2015-08-12 10:11:44 +0000
@@ -1405,3 +1405,4 @@
1405 function string dctr(string domain, string context, string text)1405 function string dctr(string domain, string context, string text)
1406 function string tag(string text)1406 function string tag(string text)
1407 function string tag(string context, string text)1407 function string tag(string context, string text)
1408 function string relativeDateTime(QDateTime datetime)
14081409
=== modified file 'src/Ubuntu/Components/plugin/i18n.cpp'
--- src/Ubuntu/Components/plugin/i18n.cpp 2015-03-03 13:47:48 +0000
+++ src/Ubuntu/Components/plugin/i18n.cpp 2015-08-12 10:11:44 +0000
@@ -17,6 +17,7 @@
17 */17 */
1818
19#include "i18n.h"19#include "i18n.h"
20#include "timeutils_p.h"
20#include <QtCore/QDir>21#include <QtCore/QDir>
2122
22namespace C {23namespace C {
@@ -252,3 +253,76 @@
252 Q_UNUSED(context);253 Q_UNUSED(context);
253 return text;254 return text;
254}255}
256/*!
257 * \qmlmethod string i18n::relativeDateTime(datetime dateTime)
258 * Translate a datetime based on proximity to current time.
259 */
260QString UbuntuI18n::relativeDateTime(const QDateTime& datetime)
261{
262 QDateTime relativeTo(QDateTime::currentDateTime());
263 const date_proximity_t prox = getDateProximity(relativeTo, datetime);
264
265 switch (prox) {
266 case DATE_PROXIMITY_NOW:
267 /* TRANSLATORS: Time based "this is happening/happened now" */
268 return dtr("ubuntu-ui-toolkit", "Now");
269
270 case DATE_PROXIMITY_HOUR:
271 {
272 qint64 diff = datetime.toMSecsSinceEpoch() - relativeTo.toMSecsSinceEpoch();
273 qint64 minutes = qRound(float(diff) / 60000);
274 if (minutes < 0) {
275 return dtr("ubuntu-ui-toolkit", "%1 minute ago", "%1 minutes ago", qAbs(minutes)).arg(qAbs(minutes));
276 }
277 return dtr("ubuntu-ui-toolkit", "%1 minute", "%1 minutes", minutes).arg(minutes);
278 }
279
280 case DATE_PROXIMITY_TODAY:
281 /* en_US example: "1:00 PM" */
282 /* TRANSLATORS: Please translated these to your locale datetime format using the format specified by
283 https://qt-project.org/doc/qt-5-snapshot/qdatetime.html#fromString-2 */
284 return datetime.toString(isLocale12h() ? dtr("ubuntu-ui-toolkit", "h:mm ap"):
285 /* TRANSLATORS: Please translated these to your locale datetime format using the format specified by
286 https://qt-project.org/doc/qt-5-snapshot/qdatetime.html#fromString-2 */
287 dtr("ubuntu-ui-toolkit", "HH:mm"));
288
289 case DATE_PROXIMITY_YESTERDAY:
290 /* en_US example: "Yesterday 13:00" */
291 /* TRANSLATORS: Please translated these to your locale datetime format using the format specified by
292 https://qt-project.org/doc/qt-5-snapshot/qdatetime.html#fromString-2 */
293 return datetime.toString(isLocale12h() ? dtr("ubuntu-ui-toolkit", "'Yesterday\u2003'h:mm ap") :
294 /* TRANSLATORS: Please translated these to your locale datetime format using the format specified by
295 https://qt-project.org/doc/qt-5-snapshot/qdatetime.html#fromString-2 */
296 dtr("ubuntu-ui-toolkit", "'Yesterday\u2003'HH:mm"));
297
298 case DATE_PROXIMITY_TOMORROW:
299 /* en_US example: "Tomorrow 1:00 PM" */
300 /* TRANSLATORS: Please translated these to your locale datetime format using the format specified by
301 https://qt-project.org/doc/qt-5-snapshot/qdatetime.html#fromString-2 */
302 return datetime.toString(isLocale12h() ? dtr("ubuntu-ui-toolkit", "'Tomorrow\u2003'h:mm ap") :
303 /* TRANSLATORS: Please translated these to your locale datetime format using the format specified by
304 https://qt-project.org/doc/qt-5-snapshot/qdatetime.html#fromString-2 */
305 dtr("ubuntu-ui-toolkit", "'Tomorrow\u2003'HH:mm"));
306
307 case DATE_PROXIMITY_LAST_WEEK:
308 case DATE_PROXIMITY_NEXT_WEEK:
309 /* en_US example: "Fri 1:00 PM" */
310 /* TRANSLATORS: Please translated these to your locale datetime format using the format specified by
311 https://qt-project.org/doc/qt-5-snapshot/qdatetime.html#fromString-2 */
312 return datetime.toString(isLocale12h() ? dtr("ubuntu-ui-toolkit", "ddd'\u2003'h:mm ap") :
313 /* TRANSLATORS: Please translated these to your locale datetime format using the format specified by
314 https://qt-project.org/doc/qt-5-snapshot/qdatetime.html#fromString-2 */
315 dtr("ubuntu-ui-toolkit", "ddd'\u2003'HH:mm"));
316
317 case DATE_PROXIMITY_FAR_BACK:
318 case DATE_PROXIMITY_FAR_FORWARD:
319 default:
320 /* TRANSLATORS: Please translated these to your locale datetime format using the format specified by
321 https://qt-project.org/doc/qt-5-snapshot/qdatetime.html#fromString-2 */
322 return datetime.toString(isLocale12h() ? dtr("ubuntu-ui-toolkit", "ddd d MMM'\u2003'h:mm ap") :
323 /* TRANSLATORS: Please translated these to your locale datetime format using the format specified by
324 https://qt-project.org/doc/qt-5-snapshot/qdatetime.html#fromString-2 */
325 dtr("ubuntu-ui-toolkit", "ddd d MMM'\u2003'HH:mm"));
326 }
327 return datetime.toString(Qt::DefaultLocaleShortDate);
328}
255329
=== modified file 'src/Ubuntu/Components/plugin/i18n.h'
--- src/Ubuntu/Components/plugin/i18n.h 2015-02-03 18:11:32 +0000
+++ src/Ubuntu/Components/plugin/i18n.h 2015-08-12 10:11:44 +0000
@@ -50,6 +50,7 @@
50 Q_INVOKABLE QString dctr(const QString& domain, const QString& context, const QString& text);50 Q_INVOKABLE QString dctr(const QString& domain, const QString& context, const QString& text);
51 Q_INVOKABLE QString tag(const QString& text);51 Q_INVOKABLE QString tag(const QString& text);
52 Q_INVOKABLE QString tag(const QString& context, const QString& text);52 Q_INVOKABLE QString tag(const QString& context, const QString& text);
53 Q_INVOKABLE QString relativeDateTime(const QDateTime& datetime);
5354
54 // getter55 // getter
55 QString domain() const;56 QString domain() const;
5657
=== modified file 'src/Ubuntu/Components/plugin/timeutils_p.h'
--- src/Ubuntu/Components/plugin/timeutils_p.h 2015-08-12 10:11:43 +0000
+++ src/Ubuntu/Components/plugin/timeutils_p.h 2015-08-12 10:11:44 +0000
@@ -20,9 +20,33 @@
20#include "livetimer.h"20#include "livetimer.h"
2121
22#include <QDateTime>22#include <QDateTime>
23#include <QLocale>
23#include <QObject>24#include <QObject>
24#include <QTimer>25#include <QTimer>
2526
27/* Check the system locale setting to see if the format is 24-hour
28 time or 12-hour time */
29inline bool isLocale12h(void)
30{
31 QString strTimeFormat = QLocale::system().timeFormat();
32 QStringList includes; includes << "AP"; includes << "ap";
33 QStringList excludes; excludes << "H"; excludes << "HH";
34
35 Q_FOREACH(const QString& exclude, excludes) {
36 if (strTimeFormat.contains(exclude)) {
37 return false;
38 }
39 }
40
41 Q_FOREACH(const QString& include, includes) {
42 if (strTimeFormat.contains(include)) {
43 return true;
44 }
45 }
46
47 return false;
48}
49
26typedef enum50typedef enum
27{51{
28 DATE_PROXIMITY_NOW,52 DATE_PROXIMITY_NOW,
2953
=== modified file 'tests/unit/tst_i18n/tst_i18n.pro'
--- tests/unit/tst_i18n/tst_i18n.pro 2015-05-18 09:53:55 +0000
+++ tests/unit/tst_i18n/tst_i18n.pro 2015-08-12 10:11:44 +0000
@@ -1,18 +1,3 @@
1include(../test-include.pri)1TEMPLATE = subdirs
2QT += gui2SUBDIRS += tst_i18n_LocalizedApp
3DEFINES += SRCDIR=\\\"$$PWD/\\\"3SUBDIRS += tst_i18n_RelativeTime
4
5DOMAIN = localizedApp
6mo.target = mo
7mo.commands = set -e;
8mo.commands += echo Generating localization for $$DOMAIN;
9mo.commands += mkdir -p $${DOMAIN}/share/locale/en/LC_MESSAGES;
10mo.commands += msgfmt $$PWD/po/en_US.po -o $${DOMAIN}/share/locale/en/LC_MESSAGES/$${DOMAIN}.mo;
11QMAKE_EXTRA_TARGETS += mo
12PRE_TARGETDEPS += mo
13
14SOURCES += \
15 src/tst_i18n.cpp
16
17OTHER_FILES += \
18 src/LocalizedApp.qml
194
=== added directory 'tests/unit/tst_i18n/tst_i18n_LocalizedApp'
=== added file 'tests/unit/tst_i18n/tst_i18n_LocalizedApp.o'
20Binary files tests/unit/tst_i18n/tst_i18n_LocalizedApp.o 1970-01-01 00:00:00 +0000 and tests/unit/tst_i18n/tst_i18n_LocalizedApp.o 2015-08-12 10:11:44 +0000 differ5Binary files tests/unit/tst_i18n/tst_i18n_LocalizedApp.o 1970-01-01 00:00:00 +0000 and tests/unit/tst_i18n/tst_i18n_LocalizedApp.o 2015-08-12 10:11:44 +0000 differ
=== renamed directory 'tests/unit/tst_i18n/localizedApp' => 'tests/unit/tst_i18n/tst_i18n_LocalizedApp/localizedApp'
=== renamed directory 'tests/unit/tst_i18n/po' => 'tests/unit/tst_i18n/tst_i18n_LocalizedApp/po'
=== renamed directory 'tests/unit/tst_i18n/src' => 'tests/unit/tst_i18n/tst_i18n_LocalizedApp/src'
=== modified file 'tests/unit/tst_i18n/tst_i18n_LocalizedApp/src/LocalizedApp.qml'
--- tests/unit/tst_i18n/src/LocalizedApp.qml 2015-03-03 13:20:06 +0000
+++ tests/unit/tst_i18n/tst_i18n_LocalizedApp/src/LocalizedApp.qml 2015-08-12 10:11:44 +0000
@@ -28,7 +28,7 @@
28 Button {28 Button {
29 id: button29 id: button
30 objectName: 'button'30 objectName: 'button'
31 anchors.centerIn: parent31 anchors.horizontalCenter: parent.horizontalCenter
32 text: i18n.tr('Count the kilometres')32 text: i18n.tr('Count the kilometres')
33 width: units.gu(15)33 width: units.gu(15)
34 }34 }
@@ -60,5 +60,47 @@
60 anchors.horizontalCenter: all2.horizontalCenter60 anchors.horizontalCenter: all2.horizontalCenter
61 text: i18n.tag('All Cats', 'All')61 text: i18n.tag('All Cats', 'All')
62 }62 }
63 Label {
64 id: timeNow
65 objectName: 'timeNow'
66 anchors.top: all3.bottom
67 anchors.horizontalCenter: all3.horizontalCenter
68 text: i18n.relativeDateTime(new Date())
69 }
70 Label {
71 id: timeMinuteBefore
72 objectName: 'timeMinuteBefore'
73 anchors.top: timeNow.bottom
74 anchors.horizontalCenter: timeNow.horizontalCenter
75 text: i18n.relativeDateTime(new Date(new Date().getTime() - 60000))
76 }
77 Label {
78 id: timeMinuteAfter
79 objectName: 'timeMinuteAfter'
80 anchors.top: timeMinuteBefore.bottom
81 anchors.horizontalCenter: timeMinuteBefore.horizontalCenter
82 text: i18n.relativeDateTime(new Date(new Date().getTime() + 60000))
83 }
84 Label {
85 id: tenMinutesBefore
86 objectName: 'tenMinutesBefore'
87 anchors.top: timeMinuteAfter.bottom
88 anchors.horizontalCenter: timeMinuteAfter.horizontalCenter
89 text: i18n.relativeDateTime(new Date(new Date().getTime() - 600000))
90 }
91 Label {
92 id: tenMinutesAfter
93 objectName: 'tenMinutesAfter'
94 anchors.top: tenMinutesBefore.bottom
95 anchors.horizontalCenter: tenMinutesBefore.horizontalCenter
96 text: i18n.relativeDateTime(new Date(new Date().getTime() + 600000))
97 }
98 Label {
99 id: timeFarAway
100 objectName: 'timeFarAway'
101 anchors.top: tenMinutesAfter.bottom
102 anchors.horizontalCenter: tenMinutesAfter.horizontalCenter
103 text: i18n.relativeDateTime(new Date(2000, 0, 1, 0, 0, 0, 0))
104 }
63 }105 }
64}106}
65107
=== renamed file 'tests/unit/tst_i18n/src/tst_i18n.cpp' => 'tests/unit/tst_i18n/tst_i18n_LocalizedApp/src/tst_i18n_LocalizedApp.cpp'
--- tests/unit/tst_i18n/src/tst_i18n.cpp 2015-02-03 18:11:32 +0000
+++ tests/unit/tst_i18n/tst_i18n_LocalizedApp/src/tst_i18n_LocalizedApp.cpp 2015-08-12 10:11:44 +0000
@@ -39,7 +39,7 @@
39#include "ucunits.h"39#include "ucunits.h"
40#include "i18n.h"40#include "i18n.h"
4141
42class tst_I18n : public QObject42class tst_I18n_LocalizedApp : public QObject
43{43{
44 Q_OBJECT44 Q_OBJECT
4545
@@ -47,7 +47,7 @@
47 QQuickView *view;47 QQuickView *view;
4848
49public:49public:
50 tst_I18n() :50 tst_I18n_LocalizedApp() :
51 view(0)51 view(0)
52 {52 {
53 }53 }
@@ -191,7 +191,7 @@
191 }191 }
192};192};
193193
194// The C++ equivalent of QTEST_MAIN(tst_I18n) with added initialization194// The C++ equivalent of QTEST_MAIN(tst_I18n_LocalizedApp) with added initialization
195int main(int argc, char *argv[])195int main(int argc, char *argv[])
196{196{
197 // LC_ALL would fail the test case; it must be unset before execution197 // LC_ALL would fail the test case; it must be unset before execution
@@ -199,8 +199,8 @@
199199
200 QGuiApplication app(argc, argv);200 QGuiApplication app(argc, argv);
201 app.setAttribute(Qt::AA_Use96Dpi, true);201 app.setAttribute(Qt::AA_Use96Dpi, true);
202 tst_I18n* testObject = new tst_I18n();202 tst_I18n_LocalizedApp* testObject = new tst_I18n_LocalizedApp();
203 return QTest::qExec(static_cast<QObject*>(testObject), argc, argv);203 return QTest::qExec(static_cast<QObject*>(testObject), argc, argv);
204}204}
205205
206#include "tst_i18n.moc"206#include "tst_i18n_LocalizedApp.moc"
207207
=== added file 'tests/unit/tst_i18n/tst_i18n_LocalizedApp/tst_i18n_LocalizedApp.pro'
--- tests/unit/tst_i18n/tst_i18n_LocalizedApp/tst_i18n_LocalizedApp.pro 1970-01-01 00:00:00 +0000
+++ tests/unit/tst_i18n/tst_i18n_LocalizedApp/tst_i18n_LocalizedApp.pro 2015-08-12 10:11:44 +0000
@@ -0,0 +1,17 @@
1include(../../test-include.pri)
2QT += gui
3DEFINES += SRCDIR=\\\"$$PWD/\\\"
4
5DOMAIN = localizedApp
6mo.target = mo
7mo.commands = set -e;
8mo.commands += echo Generating localization;
9mo.commands += msgfmt po/en_US.po -o $${DOMAIN}/share/locale/en/LC_MESSAGES/$${DOMAIN}.mo;
10QMAKE_EXTRA_TARGETS += mo
11PRE_TARGETDEPS += mo
12
13SOURCES += \
14 src/tst_i18n_LocalizedApp.cpp
15
16OTHER_FILES += \
17 src/LocalizedApp.qml
018
=== added directory 'tests/unit/tst_i18n/tst_i18n_RelativeTime'
=== added file 'tests/unit/tst_i18n/tst_i18n_RelativeTime.o'
1Binary files tests/unit/tst_i18n/tst_i18n_RelativeTime.o 1970-01-01 00:00:00 +0000 and tests/unit/tst_i18n/tst_i18n_RelativeTime.o 2015-08-12 10:11:44 +0000 differ19Binary files tests/unit/tst_i18n/tst_i18n_RelativeTime.o 1970-01-01 00:00:00 +0000 and tests/unit/tst_i18n/tst_i18n_RelativeTime.o 2015-08-12 10:11:44 +0000 differ
=== added directory 'tests/unit/tst_i18n/tst_i18n_RelativeTime/po'
=== added file 'tests/unit/tst_i18n/tst_i18n_RelativeTime/po/en_US.po'
--- tests/unit/tst_i18n/tst_i18n_RelativeTime/po/en_US.po 1970-01-01 00:00:00 +0000
+++ tests/unit/tst_i18n/tst_i18n_RelativeTime/po/en_US.po 2015-08-12 10:11:44 +0000
@@ -0,0 +1,54 @@
1msgid ""
2msgstr ""
3"Project-Id-Version: \n"
4"POT-Creation-Date: \n"
5"PO-Revision-Date: \n"
6"Last-Translator: Christian Dywan <christian.dywan@canonical.com>\n"
7"Language-Team: \n"
8"Language: \n"
9"MIME-Version: 1.0\n"
10"Content-Type: text/plain; charset=iso-8859-1\n"
11"Content-Transfer-Encoding: 8bit\n"
12
13msgid "Now"
14msgstr "tr:Now"
15
16msgid "%1 minute ago"
17msgid_plural "%1 minutes ago"
18msgstr[0] "tr:%1 minute ago"
19msgstr[1] "tr:%1 minutes ago"
20
21msgid "%1 minute"
22msgid_plural "%1 minutes"
23msgstr[0] "tr:%1 minute"
24msgstr[1] "tr:%1 minutes"
25
26msgid "h:mm ap"
27msgstr "'tr:'h:mm ap"
28
29msgid "HH:mm"
30msgstr "'tr:'HH:mm"
31
32msgid "'Yesterday 'h:mm ap"
33msgstr "'tr:Yesterday 'h:mm ap"
34
35msgid "'Yesterday 'HH:mm"
36msgstr "'tr:Yesterday 'HH:mm"
37
38msgid "'Tomorrow 'h:mm ap"
39msgstr "'tr:Tomorrow 'h:mm ap"
40
41msgid "'Tomorrow 'HH:mm"
42msgstr "'tr:Tomorrow 'HH:mm"
43
44msgid "ddd' 'h:mm ap"
45msgstr "'tr:'ddd' 'h:mm ap"
46
47msgid "ddd' 'HH:mm"
48msgstr "'tr:'ddd' 'HH:mm"
49
50msgid "ddd d MMM' 'h:mm ap"
51msgstr "'tr:FarAway'"
52
53msgid "ddd d MMM' 'HH:mm"
54msgstr "'tr:FarAway'"
055
=== added directory 'tests/unit/tst_i18n/tst_i18n_RelativeTime/src'
=== added file 'tests/unit/tst_i18n/tst_i18n_RelativeTime/src/RelativeTime.qml'
--- tests/unit/tst_i18n/tst_i18n_RelativeTime/src/RelativeTime.qml 1970-01-01 00:00:00 +0000
+++ tests/unit/tst_i18n/tst_i18n_RelativeTime/src/RelativeTime.qml 2015-08-12 10:11:44 +0000
@@ -0,0 +1,71 @@
1/*
2 * Copyright 2013 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
17import QtQuick 2.0
18import Ubuntu.Components 1.3
19
20MainView {
21 width: units.gu(48)
22 height: units.gu(60)
23 applicationName: "ubuntu-ui-toolkit"
24
25 Page {
26 objectName: 'page'
27
28 Label {
29 id: timeNow
30 objectName: 'timeNow'
31 anchors.top: parent.top
32 anchors.horizontalCenter: parent.horizontalCenter
33 text: i18n.relativeDateTime(new Date())
34 }
35 Label {
36 id: timeMinuteBefore
37 objectName: 'timeMinuteBefore'
38 anchors.top: timeNow.bottom
39 anchors.horizontalCenter: timeNow.horizontalCenter
40 text: i18n.relativeDateTime(new Date(new Date().getTime() - 60000))
41 }
42 Label {
43 id: timeMinuteAfter
44 objectName: 'timeMinuteAfter'
45 anchors.top: timeMinuteBefore.bottom
46 anchors.horizontalCenter: timeMinuteBefore.horizontalCenter
47 text: i18n.relativeDateTime(new Date(new Date().getTime() + 60000))
48 }
49 Label {
50 id: tenMinutesBefore
51 objectName: 'tenMinutesBefore'
52 anchors.top: timeMinuteAfter.bottom
53 anchors.horizontalCenter: timeMinuteAfter.horizontalCenter
54 text: i18n.relativeDateTime(new Date(new Date().getTime() - 600000))
55 }
56 Label {
57 id: tenMinutesAfter
58 objectName: 'tenMinutesAfter'
59 anchors.top: tenMinutesBefore.bottom
60 anchors.horizontalCenter: tenMinutesBefore.horizontalCenter
61 text: i18n.relativeDateTime(new Date(new Date().getTime() + 600000))
62 }
63 Label {
64 id: timeFarAway
65 objectName: 'timeFarAway'
66 anchors.top: tenMinutesAfter.bottom
67 anchors.horizontalCenter: tenMinutesAfter.horizontalCenter
68 text: i18n.relativeDateTime(new Date(2000, 0, 1, 0, 0, 0, 0))
69 }
70 }
71}
072
=== added file 'tests/unit/tst_i18n/tst_i18n_RelativeTime/src/tst_i18n_RelativeTime.cpp'
--- tests/unit/tst_i18n/tst_i18n_RelativeTime/src/tst_i18n_RelativeTime.cpp 1970-01-01 00:00:00 +0000
+++ tests/unit/tst_i18n/tst_i18n_RelativeTime/src/tst_i18n_RelativeTime.cpp 2015-08-12 10:11:44 +0000
@@ -0,0 +1,202 @@
1
2/*
3 * Copyright 2015 Canonical Ltd.
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU Lesser General Public License as published by
7 * the Free Software Foundation; version 3.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 *
17 * Author: Nick Dedekind <nick.dedekind@gmail.com>
18 */
19
20#include <QtCore/QString>
21#include <QtCore/QTextCodec>
22#include <QtCore/QStandardPaths>
23#include <QtCore/QDir>
24#include <QtCore/QProcessEnvironment>
25#include <QtTest/QTest>
26#include <QtTest/QSignalSpy>
27#include <QtCore/QCoreApplication>
28#include <QtQml/QQmlEngine>
29#include <QtQuick/QQuickView>
30#include <QtQuick/QQuickItem>
31#include <QtCore/QThread>
32#include <QtCore/QFileInfo>
33#include <QtCore/QDir>
34#include <QtTest/qtest_gui.h>
35
36namespace C {
37#include <libintl.h>
38}
39
40#include "ucunits.h"
41#include "i18n.h"
42
43class tst_I18n_RelativeTime : public QObject
44{
45 Q_OBJECT
46
47private:
48 QQuickView *view;
49
50public:
51 tst_I18n_RelativeTime() :
52 view(0)
53 {
54 }
55
56 QQuickItem *loadTest(const QString &document)
57 {
58 // load the document
59 view->setSource(QUrl::fromLocalFile(document));
60 QTest::waitForEvents();
61
62 return view->rootObject();
63 }
64
65 QQuickItem *testItem(QQuickItem *that, const QString &identifier)
66 {
67 if (that->property(identifier.toLocal8Bit()).isValid())
68 return that->property(identifier.toLocal8Bit()).value<QQuickItem*>();
69
70 QList<QQuickItem*> children = that->findChildren<QQuickItem*>(identifier);
71 return (children.count() > 0) ? children[0] : 0;
72 }
73
74private Q_SLOTS:
75
76 void initTestCase()
77 {
78 // Set test locale folder in the environment
79 // Using setenv because QProcessEnvironment ignores changes
80 QString testAppDir(QDir::currentPath() + "/ubuntu-ui-toolkit");
81 setenv("APP_DIR", testAppDir.toUtf8(), 1);
82
83 // Verify that we set it correctly
84 QVERIFY(QFileInfo(testAppDir + "/share/locale/en/LC_MESSAGES/ubuntu-ui-toolkit.mo").exists());
85
86 QString modules(UBUNTU_QML_IMPORT_PATH);
87 QVERIFY(QDir(modules).exists());
88
89 view = new QQuickView;
90 QQmlEngine *quickEngine = view->engine();
91
92 view->setGeometry(0,0, UCUnits::instance().gu(40), UCUnits::instance().gu(30));
93 //add modules folder so we have access to the plugin from QML
94 QStringList imports = quickEngine->importPathList();
95 imports.prepend(QDir(modules).absolutePath());
96 quickEngine->setImportPathList(imports);
97 }
98
99 void cleanupTestCase()
100 {
101 delete view;
102 }
103
104 void testCase_RelativeTime()
105 {
106 UbuntuI18n* i18n = &UbuntuI18n::instance();
107 // By default no domain is set
108 QCOMPARE(i18n->domain(), QString(""));
109
110 // Start out with no localization
111 i18n->setLanguage("C");
112 // Load the app which should pick up the locale we prepared
113 QQuickItem *root = loadTest("src/RelativeTime.qml");
114 QVERIFY(root);
115 QQuickItem *mainView = root;
116
117 // There no translation happens
118 QQuickItem* page(testItem(mainView, "page"));
119 QVERIFY(page);
120
121 QQuickItem* timeFarAway(testItem(page, "timeFarAway"));
122 QVERIFY(timeFarAway);
123 QCOMPARE(timeFarAway->property("text").toString(),
124 QDateTime(QDate(2000,1,1), QTime(0,0,0,0)).toString("ddd d MMM'\u2003'HH:mm"));
125 QQuickItem* timeNow(testItem(page, "timeNow"));
126 QVERIFY(timeNow);
127 QCOMPARE(timeNow->property("text").toString(), QString("Now"));
128 QQuickItem* timeMinuteBefore(testItem(page, "timeMinuteBefore"));
129 QVERIFY(timeMinuteBefore);
130 QCOMPARE(timeMinuteBefore->property("text").toString(), QString("1 minute ago"));
131 QQuickItem* timeMinuteAfter(testItem(page, "timeMinuteAfter"));
132 QVERIFY(timeMinuteAfter);
133 QCOMPARE(timeMinuteAfter->property("text").toString(), QString("1 minute"));
134 QQuickItem* tenMinutesBefore(testItem(page, "tenMinutesBefore"));
135 QVERIFY(tenMinutesBefore);
136 QCOMPARE(tenMinutesBefore->property("text").toString(), QString("10 minutes ago"));
137 QQuickItem* tenMinutesAfter(testItem(page, "tenMinutesAfter"));
138 QVERIFY(tenMinutesAfter);
139 QCOMPARE(tenMinutesAfter->property("text").toString(), QString("10 minutes"));
140
141 // There no translation happens in C++ either
142 QCOMPARE(i18n->relativeDateTime(QDateTime::currentDateTime()), QString("Now"));
143 QCOMPARE(i18n->relativeDateTime(QDateTime(QDate(2000,1,1), QTime(0,0,0,0))),
144 QDateTime(QDate(2000,1,1), QTime(0,0,0,0)).toString("ddd d MMM'\u2003'HH:mm"));
145 QCOMPARE(i18n->relativeDateTime(QDateTime::currentDateTime().addSecs(-60)), QString("1 minute ago"));
146 QCOMPARE(i18n->relativeDateTime(QDateTime::currentDateTime().addSecs(60)), QString("1 minute"));
147 QCOMPARE(i18n->relativeDateTime(QDateTime::currentDateTime().addSecs(-600)), QString("10 minutes ago"));
148 QCOMPARE(i18n->relativeDateTime(QDateTime::currentDateTime().addSecs(600)), QString("10 minutes"));
149
150 // Was the locale folder detected and set?
151 QString boundDomain(C::bindtextdomain(i18n->domain().toUtf8(), ((const char*)0)));
152 QString testAppDir(QDir::currentPath() + "/ubuntu-ui-toolkit");
153 QString expectedLocalePath(QDir(testAppDir).filePath("share/locale"));
154 QCOMPARE(boundDomain, expectedLocalePath);
155 // Is the domain gettext uses correct?
156 QString gettextDomain(C::textdomain(((const char*)0)));
157 QCOMPARE(gettextDomain, i18n->domain());
158 // Is the compiled en_US message catalog in the right location?
159 QString messageCatalog(boundDomain + "/en/LC_MESSAGES/ubuntu-ui-toolkit.mo");
160 QVERIFY(QFileInfo(messageCatalog).exists());
161
162 // Check if system has en_US locale, otherwise gettext won't work
163 QProcess localeA;
164 localeA.start("locale -a");
165 QVERIFY(localeA.waitForFinished());
166 QVERIFY(QString(localeA.readAll()).split("\n").contains("en_US.utf8"));
167
168 i18n->setLanguage("en_US.utf8");
169 QSignalSpy spy(i18n, SIGNAL(languageChanged()));
170 spy.wait();
171
172 // Inspect translated strings in QML
173 QCOMPARE(timeNow->property("text").toString(), QString("tr:Now"));
174 QCOMPARE(timeMinuteBefore->property("text").toString(), QString("tr:1 minute ago"));
175 QCOMPARE(timeMinuteAfter->property("text").toString(), QString("tr:1 minute"));
176 QCOMPARE(tenMinutesBefore->property("text").toString(), QString("tr:10 minutes ago"));
177 QCOMPARE(tenMinutesAfter->property("text").toString(), QString("tr:10 minutes"));
178 QCOMPARE(timeFarAway->property("text").toString(), QString("tr:FarAway"));
179
180 // Translate in C++
181 QCOMPARE(i18n->relativeDateTime(QDateTime::currentDateTime()), QString("tr:Now"));
182 QCOMPARE(i18n->relativeDateTime(QDateTime(QDate(2000,1,1), QTime(0,0,0,0))), QString("tr:FarAway"));
183 QCOMPARE(i18n->relativeDateTime(QDateTime::currentDateTime().addSecs(-60)), QString("tr:1 minute ago"));
184 QCOMPARE(i18n->relativeDateTime(QDateTime::currentDateTime().addSecs(60)), QString("tr:1 minute"));
185 QCOMPARE(i18n->relativeDateTime(QDateTime::currentDateTime().addSecs(-600)), QString("tr:10 minutes ago"));
186 QCOMPARE(i18n->relativeDateTime(QDateTime::currentDateTime().addSecs(600)), QString("tr:10 minutes"));
187 }
188};
189
190// The C++ equivalent of QTEST_MAIN(tst_I18n_RelativeTime) with added initialization
191int main(int argc, char *argv[])
192{
193 // LC_ALL would fail the test case; it must be unset before execution
194 unsetenv("LC_ALL");
195
196 QGuiApplication app(argc, argv);
197 app.setAttribute(Qt::AA_Use96Dpi, true);
198 tst_I18n_RelativeTime* testObject = new tst_I18n_RelativeTime();
199 return QTest::qExec(static_cast<QObject*>(testObject), argc, argv);
200}
201
202#include "tst_i18n_RelativeTime.moc"
0203
=== added file 'tests/unit/tst_i18n/tst_i18n_RelativeTime/tst_i18n_RelativeTime.pro'
--- tests/unit/tst_i18n/tst_i18n_RelativeTime/tst_i18n_RelativeTime.pro 1970-01-01 00:00:00 +0000
+++ tests/unit/tst_i18n/tst_i18n_RelativeTime/tst_i18n_RelativeTime.pro 2015-08-12 10:11:44 +0000
@@ -0,0 +1,17 @@
1include(../../test-include.pri)
2QT += gui
3DEFINES += SRCDIR=\\\"$$PWD/\\\"
4
5DOMAIN = ubuntu-ui-toolkit
6mo.target = mo
7mo.commands = set -e;
8mo.commands += echo Generating localization;
9mo.commands += msgfmt po/en_US.po -o $${DOMAIN}/share/locale/en/LC_MESSAGES/$${DOMAIN}.mo;
10QMAKE_EXTRA_TARGETS += mo
11PRE_TARGETDEPS += mo
12
13SOURCES += \
14 src/tst_i18n_RelativeTime.cpp
15
16OTHER_FILES += \
17 src/RelativeTime.qml
018
=== added directory 'tests/unit/tst_i18n/tst_i18n_RelativeTime/ubuntu-ui-toolkit'
=== added directory 'tests/unit/tst_i18n/tst_i18n_RelativeTime/ubuntu-ui-toolkit/share'
=== added directory 'tests/unit/tst_i18n/tst_i18n_RelativeTime/ubuntu-ui-toolkit/share/locale'
=== added directory 'tests/unit/tst_i18n/tst_i18n_RelativeTime/ubuntu-ui-toolkit/share/locale/en'
=== added directory 'tests/unit/tst_i18n/tst_i18n_RelativeTime/ubuntu-ui-toolkit/share/locale/en/LC_MESSAGES'

Subscribers

People subscribed via source and target branches