Merge lp:~larsu/unity8/lp1236413 into lp:unity8

Proposed by Lars Karlitski
Status: Merged
Approved by: Nick Dedekind
Approved revision: 467
Merged at revision: 489
Proposed branch: lp:~larsu/unity8/lp1236413
Merge into: lp:unity8
Diff against target: 490 lines (+306/-36)
10 files modified
plugins/Unity/Indicators/CMakeLists.txt (+1/-0)
plugins/Unity/Indicators/Messaging/qml/MessageMenuItemFactory.qml (+3/-4)
plugins/Unity/Indicators/Messaging/qml/SimpleTextMessage.qml (+9/-2)
plugins/Unity/Indicators/Messaging/qml/SnapDecision.qml (+9/-3)
plugins/Unity/Indicators/Messaging/qml/utils.js (+0/-27)
plugins/Unity/Indicators/plugin.cpp (+2/-0)
plugins/Unity/Indicators/timeformatter.cpp (+172/-0)
plugins/Unity/Indicators/timeformatter.h (+54/-0)
tests/plugins/Unity/Indicators/CMakeLists.txt (+1/-0)
tests/plugins/Unity/Indicators/timeformattertest.cpp (+55/-0)
To merge this branch: bzr merge lp:~larsu/unity8/lp1236413
Reviewer Review Type Date Requested Status
PS Jenkins bot (community) continuous-integration Approve
Nick Dedekind (community) Approve
Review via email: mp+191498@code.launchpad.net

Commit message

Indicators: add TimeFormatter and use it in the messaging menu

This component can be used to turn a timestamp and a format string into a string with the corresponding time and format. The string will change whenever the timezone changes.

Description of the change

Indicators: add TimeFormatter and use it in the messaging menu

This component can be used to turn a timestamp and a format string into a string with the corresponding time and format. The string will change whenever the timezone changes.

This patch includes a very simply test that doesn't cover the update-on-timezone-switching. What's the recommended way of spinning up a test bus in unity8's test framework?

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :

FAILED: Continuous integration, rev:467
http://jenkins.qa.ubuntu.com/job/unity8-ci/1440/
Executed test runs:
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-saucy/5075
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-touch/3016
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity-phablet-qmluitests-saucy/2308
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-saucy-amd64-ci/463
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-saucy-armhf-ci/1440
        deb: http://jenkins.qa.ubuntu.com/job/unity8-saucy-armhf-ci/1440/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-saucy-i386-ci/1439
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/autopilot-testrunner-otto-saucy/1243
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-saucy-amd64/950
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-saucy-amd64/950/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-saucy-armhf/3018
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-saucy-armhf/3018/artifact/work/output/*zip*/output.zip
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-runner-maguro/2523
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-runner-mako/2567
    SUCCESS: http://10.97.0.26:8080/job/touch-flash-device/62
    SUCCESS: http://10.97.0.26:8080/job/touch-flash-device/63

Click here to trigger a rebuild:
http://10.97.0.26:8080/job/unity8-ci/1440/rebuild

review: Needs Fixing (continuous-integration)
Revision history for this message
Albert Astals Cid (aacid) wrote :

Unrelated to this patch since it was broken before, but "hh:mm - MMM dd" screams for proper localization

Revision history for this message
Nick Dedekind (nick-dedekind) wrote :

I think the TimeFormatter object screams for shared private data (for dbus management).
Each message is going to be listening to the same dbus property, so we might as well connect all formatters to the same callback using qt signal.

TimeFormatter <------
TimeFormatter <------ (emit updated) TimeFormatterPrivate <------ dbus
TimeFormatter <------

review: Needs Fixing
Revision history for this message
Lars Karlitski (larsu) wrote :

This is why I'm using gdbus, it does exactly that.

Revision history for this message
Nick Dedekind (nick-dedekind) wrote :

> This is why I'm using gdbus, it does exactly that.

But isn't the fetching of the bus and subscriptions to it's signals all a bit much for a simple time formatter? It's async, so there's a queue churning for every call to g_bus_get.
The exact same thing is going to be happening to every object at the same time. So I think the updates should be coming from a singleton.

Another note is that this should probably by in Utils rather than Indicators.

Revision history for this message
Nick Dedekind (nick-dedekind) wrote :

> > This is why I'm using gdbus, it does exactly that.
>
> But isn't the fetching of the bus and subscriptions to it's signals all a bit
> much for a simple time formatter? It's async, so there's a queue churning for
> every call to g_bus_get.
> The exact same thing is going to be happening to every object at the same
> time. So I think the updates should be coming from a singleton.
>
> Another note is that this should probably by in Utils rather than Indicators.

Right, discussed and thought it was light weight enough for now. Can make singleton if needed and move to Utils later.

Tested and all working.

review: Approve
Revision history for this message
PS Jenkins bot (ps-jenkins) :
review: Approve (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'plugins/Unity/Indicators/CMakeLists.txt'
2--- plugins/Unity/Indicators/CMakeLists.txt 2013-09-09 08:21:23 +0000
3+++ plugins/Unity/Indicators/CMakeLists.txt 2013-10-16 20:25:38 +0000
4@@ -36,6 +36,7 @@
5 unitymenumodelcache.cpp
6 unitymenumodelstack.cpp
7 visibleindicatorsmodel.cpp
8+ timeformatter.cpp
9 )
10 add_definitions(-DUNITYINDICATORS_LIBRARY)
11
12
13=== modified file 'plugins/Unity/Indicators/Messaging/qml/MessageMenuItemFactory.qml'
14--- plugins/Unity/Indicators/Messaging/qml/MessageMenuItemFactory.qml 2013-09-25 11:29:05 +0000
15+++ plugins/Unity/Indicators/Messaging/qml/MessageMenuItemFactory.qml 2013-10-16 20:25:38 +0000
16@@ -22,7 +22,6 @@
17 import Ubuntu.Components 0.1
18 import Unity.Indicators 0.1 as Indicators
19 import QMenuModel 0.1 as QMenuModel
20-import "utils.js" as Utils
21
22 Indicators.BaseMenuItem {
23 id: menuItem
24@@ -65,7 +64,7 @@
25 SimpleTextMessage {
26 // text
27 title: menu && menu.label ? menu.label : ""
28- time: menu ? Utils.formatDate(menu.ext.xCanonicalTime) : ""
29+ time: menu ? menu.ext.xCanonicalTime : 0
30 message: menu && menu.ext.xCanonicalText ? menu.ext.xCanonicalText : ""
31 // icons
32 avatar: menu && menu.ext.icon !== undefined ? menu.ext.icon : "qrc:/indicators/artwork/messaging/default_contact.png"
33@@ -90,7 +89,7 @@
34
35 // text
36 title: menu && menu.label ? menu.label : ""
37- time: menu ? Utils.formatDate(menu.ext.xCanonicalTime) : ""
38+ time: menu ? menu.ext.xCanonicalTime : 0
39 message: menu && menu.ext.xCanonicalText ? menu.ext.xCanonicalText : ""
40 replyButtonText: actionsDescription && actionsDescription[0].label ? actionsDescription[0].label : "Send"
41 // icons
42@@ -126,7 +125,7 @@
43
44 // text
45 title: menu && menu.label ? menu.label : ""
46- time: menu ? Utils.formatDate(menu.ext.xCanonicalTime) : ""
47+ time: menu ? menu.ext.xCanonicalTime : ""
48 message: menu && menu.ext.xCanonicalText ? menu.ext.xCanonicalText : ""
49 actionButtonText: actionsDescription && actionsDescription[0].label ? actionsDescription[0].label : "Call back"
50 replyButtonText: actionsDescription && actionsDescription[1].label ? actionsDescription[1].label : "Send"
51
52=== modified file 'plugins/Unity/Indicators/Messaging/qml/SimpleTextMessage.qml'
53--- plugins/Unity/Indicators/Messaging/qml/SimpleTextMessage.qml 2013-08-22 13:05:57 +0000
54+++ plugins/Unity/Indicators/Messaging/qml/SimpleTextMessage.qml 2013-10-16 20:25:38 +0000
55@@ -20,19 +20,20 @@
56
57 import QtQuick 2.0
58 import Ubuntu.Components 0.1
59+import Unity.Indicators 0.1
60
61 HeroMessage {
62 id: __heroMessage
63
64 property string title: ""
65- property string time: ""
66+ property var time
67 property string message: ""
68
69 property alias footer: footerLoader.sourceComponent
70
71 expandedHeight: fullMessage.y + fullMessage.height + units.gu(2)
72 heroMessageHeader.titleText.text: title
73- heroMessageHeader.subtitleText.text: time
74+ heroMessageHeader.subtitleText.text: timeFormatter.timeString
75 heroMessageHeader.bodyText.text: message
76
77 Item {
78@@ -49,6 +50,12 @@
79 opacity: 0.0
80 enabled: false
81
82+ TimeFormatter {
83+ id: timeFormatter
84+ time: __heroMessage.time
85+ format: "hh:mm - MMM dd"
86+ }
87+
88 Label {
89 id: bodyText
90 anchors {
91
92=== modified file 'plugins/Unity/Indicators/Messaging/qml/SnapDecision.qml'
93--- plugins/Unity/Indicators/Messaging/qml/SnapDecision.qml 2013-08-30 18:21:21 +0000
94+++ plugins/Unity/Indicators/Messaging/qml/SnapDecision.qml 2013-10-16 20:25:38 +0000
95@@ -21,13 +21,13 @@
96 import QtQuick 2.0
97 import Ubuntu.Components 0.1
98 import Unity.Indicators 0.1 as Indicators
99-import "utils.js" as Utils
100+import Unity.Indicators 0.1
101
102 HeroMessage {
103 id: snapDecision
104
105 property string title: ""
106- property string time: ""
107+ property var time
108 property string message: ""
109
110 property bool activateEnabled: true
111@@ -41,7 +41,7 @@
112 heroMessageHeader.titleText.text: title
113 heroMessageHeader.subtitleText.text: message
114 heroMessageHeader.subtitleText.color: "#e8e1d0"
115- heroMessageHeader.bodyText.text: time
116+ heroMessageHeader.bodyText.text: timeFormatter.timeString
117 heroMessageHeader.bodyText.color: "#8f8f88"
118
119 signal activate
120@@ -59,6 +59,12 @@
121 height: units.gu(4)
122 opacity: 0.0
123
124+ TimeFormatter {
125+ id: timeFormatter
126+ time: snapDecision.time
127+ format: "hh:mm - MMM dd"
128+ }
129+
130 Button {
131 text: "Message"
132 color: "#bababa"
133
134=== removed file 'plugins/Unity/Indicators/Messaging/qml/utils.js'
135--- plugins/Unity/Indicators/Messaging/qml/utils.js 2013-06-27 09:09:25 +0000
136+++ plugins/Unity/Indicators/Messaging/qml/utils.js 1970-01-01 00:00:00 +0000
137@@ -1,27 +0,0 @@
138-/*
139- * Copyright 2013 Canonical Ltd.
140- *
141- * This program is free software; you can redistribute it and/or modify
142- * it under the terms of the GNU Lesser General Public License as published by
143- * the Free Software Foundation; version 3.
144- *
145- * This program is distributed in the hope that it will be useful,
146- * but WITHOUT ANY WARRANTY; without even the implied warranty of
147- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
148- * GNU Lesser General Public License for more details.
149- *
150- * You should have received a copy of the GNU Lesser General Public License
151- * along with this program. If not, see <http://www.gnu.org/licenses/>.
152- *
153- * Authors:
154- * Renato Araujo Oliveira Filho <renato@canonical.com>
155- * Olivier Tilloy <olivier.tilloy@canonical.com>
156- */
157-
158-.pragma library
159-
160-function formatDate(timestamp) {
161- // timestamp is in microseconds since epoch
162- var date = new Date(timestamp / 1000);
163- return Qt.formatDateTime(date, "hh:mm - MMM dd");
164-}
165
166=== modified file 'plugins/Unity/Indicators/plugin.cpp'
167--- plugins/Unity/Indicators/plugin.cpp 2013-09-09 09:23:15 +0000
168+++ plugins/Unity/Indicators/plugin.cpp 2013-10-16 20:25:38 +0000
169@@ -33,6 +33,7 @@
170 #include "unitymenumodelcache.h"
171 #include "unitymenumodelstack.h"
172 #include "visibleindicatorsmodel.h"
173+#include "timeformatter.h"
174
175 static QObject* menuModelCacheSingleton(QQmlEngine* engine, QJSEngine* scriptEngine) {
176 Q_UNUSED(engine);
177@@ -51,6 +52,7 @@
178 qmlRegisterType<RootActionState>(uri, 0, 1, "RootActionState");
179 qmlRegisterType<ModelPrinter>(uri, 0, 1, "ModelPrinter");
180 qmlRegisterType<VisibleIndicatorsModel>(uri, 0, 1, "VisibleIndicatorsModel");
181+ qmlRegisterType<TimeFormatter>(uri, 0, 1, "TimeFormatter");
182
183 qmlRegisterSingletonType<UnityMenuModelCache>(uri, 0, 1, "UnityMenuModelCache", menuModelCacheSingleton);
184
185
186=== added file 'plugins/Unity/Indicators/timeformatter.cpp'
187--- plugins/Unity/Indicators/timeformatter.cpp 1970-01-01 00:00:00 +0000
188+++ plugins/Unity/Indicators/timeformatter.cpp 2013-10-16 20:25:38 +0000
189@@ -0,0 +1,172 @@
190+/*
191+ * Copyright 2013 Canonical Ltd.
192+ *
193+ * This program is free software; you can redistribute it and/or modify
194+ * it under the terms of the GNU General Public License as published by
195+ * the Free Software Foundation; version 3.
196+ *
197+ * This program is distributed in the hope that it will be useful,
198+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
199+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
200+ * GNU General Public License for more details.
201+ *
202+ * You should have received a copy of the GNU General Public License
203+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
204+ *
205+ * Author: Lars Uebernickel <lars.uebernickel@canonical.com>
206+ */
207+
208+#include "timeformatter.h"
209+
210+#include <gio/gio.h>
211+#include <QDateTime>
212+
213+struct TimeFormatterPrivate
214+{
215+ TimeFormatter *formatter;
216+
217+ QString format;
218+ QString timeString;
219+ qint64 time;
220+
221+ GDBusConnection *system_bus;
222+ guint subscription_id;
223+ GCancellable *cancellable;
224+};
225+
226+static void
227+timedate1_properties_changed (GDBusConnection *connection,
228+ const gchar *sender_name,
229+ const gchar *object_path,
230+ const gchar *interface_name,
231+ const gchar *signal_name,
232+ GVariant *parameters,
233+ gpointer user_data)
234+{
235+ Q_UNUSED(connection);
236+ Q_UNUSED(sender_name);
237+ Q_UNUSED(object_path);
238+ Q_UNUSED(interface_name);
239+ Q_UNUSED(signal_name);
240+
241+ TimeFormatterPrivate *priv = (TimeFormatterPrivate *)user_data;
242+ GVariant *changed;
243+ GVariantIter *iter;
244+ const gchar *name;
245+
246+ if (!g_variant_is_of_type (parameters, G_VARIANT_TYPE ("(sa{sv}as)")))
247+ return;
248+
249+ g_variant_get (parameters, "(s@a{sv}as)", NULL, &changed, &iter);
250+
251+ if (g_variant_lookup (changed, "Timezone", "s", NULL)) {
252+ priv->formatter->update();
253+ }
254+ else {
255+ while (g_variant_iter_next (iter, "&s", &name)) {
256+ if (g_str_equal (name, "Timezone")) {
257+ priv->formatter->update();
258+ break;
259+ }
260+ }
261+ }
262+
263+ g_variant_unref (changed);
264+ g_variant_iter_free (iter);
265+}
266+
267+static void
268+got_bus(GObject *object, GAsyncResult *result, gpointer user_data)
269+{
270+ Q_UNUSED(object);
271+
272+ TimeFormatterPrivate *priv = (TimeFormatterPrivate *)user_data;
273+ GError *error = NULL;
274+
275+ priv->system_bus = g_bus_get_finish (result, &error);
276+ if (priv->system_bus == NULL) {
277+ if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
278+ qWarning("TimeFormatter: cannot connect to the system bus: %s", error->message);
279+ g_error_free (error);
280+ return;
281+ }
282+
283+ /* Listen to the PropertiesChanged on the org.freedesktop.timedate1
284+ * interface from any sender. In practice, this signal will only be sent
285+ * from timedated (we can trust other processes on the system bus to behave
286+ * nicely). That way, we don't have to watch timedated's well-known name
287+ * and keep the process alive.
288+ */
289+ priv->subscription_id = g_dbus_connection_signal_subscribe (priv->system_bus,
290+ NULL, /* sender */
291+ "org.freedesktop.DBus.Properties",
292+ "PropertiesChanged",
293+ NULL,
294+ "org.freedesktop.timedate1",
295+ G_DBUS_SIGNAL_FLAGS_NONE,
296+ timedate1_properties_changed,
297+ priv, NULL);
298+}
299+
300+TimeFormatter::TimeFormatter(QObject *parent): QObject(parent)
301+{
302+ priv = new TimeFormatterPrivate;
303+ priv->formatter = this;
304+ priv->time = 0;
305+ priv->format = "yyyy-MM-dd hh:mm";
306+ priv->system_bus = NULL;
307+ priv->subscription_id = 0;
308+ priv->cancellable = g_cancellable_new ();
309+
310+ g_bus_get (G_BUS_TYPE_SYSTEM, priv->cancellable, got_bus, priv);
311+}
312+
313+TimeFormatter::~TimeFormatter()
314+{
315+ if (priv->system_bus) {
316+ g_dbus_connection_signal_unsubscribe (priv->system_bus, priv->subscription_id);
317+ g_object_unref (priv->system_bus);
318+ }
319+
320+ g_cancellable_cancel (priv->cancellable);
321+ g_object_unref (priv->cancellable);
322+}
323+
324+QString TimeFormatter::format() const
325+{
326+ return priv->format;
327+}
328+
329+QString TimeFormatter::timeString() const
330+{
331+ return priv->timeString;
332+}
333+
334+qint64 TimeFormatter::time() const
335+{
336+ return priv->time;
337+}
338+
339+void TimeFormatter::setFormat(const QString &format)
340+{
341+ if (priv->format != format) {
342+ priv->format = format;
343+ Q_EMIT formatChanged(priv->format);
344+ update();
345+ }
346+}
347+
348+void TimeFormatter::setTime(qint64 time)
349+{
350+ if (priv->time != time) {
351+ priv->time = time;
352+ Q_EMIT timeChanged(priv->time);
353+ update();
354+ }
355+}
356+
357+void TimeFormatter::update()
358+{
359+ priv->timeString = QDateTime::fromMSecsSinceEpoch(priv->time / 1000).toString(priv->format);
360+ Q_EMIT timeStringChanged(priv->timeString);
361+}
362
363=== added file 'plugins/Unity/Indicators/timeformatter.h'
364--- plugins/Unity/Indicators/timeformatter.h 1970-01-01 00:00:00 +0000
365+++ plugins/Unity/Indicators/timeformatter.h 2013-10-16 20:25:38 +0000
366@@ -0,0 +1,54 @@
367+/*
368+ * Copyright 2013 Canonical Ltd.
369+ *
370+ * This program is free software; you can redistribute it and/or modify
371+ * it under the terms of the GNU General Public License as published by
372+ * the Free Software Foundation; version 3.
373+ *
374+ * This program is distributed in the hope that it will be useful,
375+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
376+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
377+ * GNU General Public License for more details.
378+ *
379+ * You should have received a copy of the GNU General Public License
380+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
381+ *
382+ * Author: Lars Uebernickel <lars.uebernickel@canonical.com>
383+ */
384+
385+#ifndef TIME_FORMATTER_H
386+#define TIME_FORMATTER_H
387+
388+#include "unityindicatorsglobal.h"
389+#include <QObject>
390+
391+class UNITYINDICATORS_EXPORT TimeFormatter : public QObject
392+{
393+ Q_OBJECT
394+ Q_PROPERTY(QString format READ format WRITE setFormat NOTIFY formatChanged)
395+ Q_PROPERTY(QString timeString READ timeString NOTIFY timeStringChanged)
396+ Q_PROPERTY(qint64 time READ time WRITE setTime NOTIFY timeChanged)
397+
398+public:
399+ TimeFormatter(QObject *parent = 0);
400+ ~TimeFormatter();
401+
402+ QString format() const;
403+ QString timeString() const;
404+ qint64 time() const;
405+
406+ void setFormat(const QString &format);
407+ void setTime(qint64 time);
408+
409+ void update();
410+
411+Q_SIGNALS:
412+ void formatChanged(const QString &format);
413+ void timeStringChanged(const QString &timeString);
414+ void timeChanged(qint64 time);
415+
416+private:
417+ struct TimeFormatterPrivate *priv;
418+};
419+
420+#endif
421
422=== modified file 'tests/plugins/Unity/Indicators/CMakeLists.txt'
423--- tests/plugins/Unity/Indicators/CMakeLists.txt 2013-10-11 14:32:39 +0000
424+++ tests/plugins/Unity/Indicators/CMakeLists.txt 2013-10-16 20:25:38 +0000
425@@ -30,4 +30,5 @@
426 indicatorsmodeltest
427 menucontentactivatortest
428 rootactionstatetest
429+ timeformattertest
430 )
431
432=== added file 'tests/plugins/Unity/Indicators/timeformattertest.cpp'
433--- tests/plugins/Unity/Indicators/timeformattertest.cpp 1970-01-01 00:00:00 +0000
434+++ tests/plugins/Unity/Indicators/timeformattertest.cpp 2013-10-16 20:25:38 +0000
435@@ -0,0 +1,55 @@
436+/*
437+ * Copyright 2013 Canonical Ltd.
438+ *
439+ * This program is free software; you can redistribute it and/or modify
440+ * it under the terms of the GNU Lesser General Public License as published by
441+ * the Free Software Foundation; version 3.
442+ *
443+ * This program is distributed in the hope that it will be useful,
444+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
445+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
446+ * GNU Lesser General Public License for more details.
447+ *
448+ * You should have received a copy of the GNU Lesser General Public License
449+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
450+ *
451+ * Author: Lars Uebernickel <lars.uebernickel@canonical.com>
452+ */
453+
454+#include "timeformatter.h"
455+
456+#include <QtTest>
457+#include <QDebug>
458+
459+class TimeFormatterTest : public QObject
460+{
461+ Q_OBJECT
462+private Q_SLOTS:
463+
464+ void initTestCase()
465+ {
466+ setenv("UNITY_TEST_ENV", "1", 1);
467+ }
468+
469+ void cleanupTestCase()
470+ {
471+ unsetenv("UNITY_TEST_ENV");
472+ }
473+
474+ void testFormat()
475+ {
476+ const QString format = "hh:mm dd.MM.yy";
477+
478+ QDateTime time = QDateTime::currentDateTime();
479+
480+ TimeFormatter formatter;
481+ formatter.setTime(time.toMSecsSinceEpoch() * 1000);
482+ formatter.setFormat(format);
483+
484+ QCOMPARE(formatter.timeString(), time.toString(format));
485+ }
486+};
487+
488+QTEST_GUILESS_MAIN(TimeFormatterTest)
489+
490+#include "timeformattertest.moc"

Subscribers

People subscribed via source and target branches