@@ -0,0 +1,172 @@
2+ * Copyright 2013 Canonical Ltd.
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
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 General Public License for more details.
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
16+ * Author: Lars Uebernickel <lars.uebernickel@canonical.com>
19+#include "timeformatter.h"
24+struct TimeFormatterPrivate
26+ TimeFormatter *formatter;
32+ GDBusConnection *system_bus;
33+ guint subscription_id;
34+ GCancellable *cancellable;
38+timedate1_properties_changed (GDBusConnection *connection,
39+ const gchar *sender_name,
40+ const gchar *object_path,
41+ const gchar *interface_name,
42+ const gchar *signal_name,
43+ GVariant *parameters,
46+ Q_UNUSED(connection);
47+ Q_UNUSED(sender_name);
48+ Q_UNUSED(object_path);
49+ Q_UNUSED(interface_name);
50+ Q_UNUSED(signal_name);
52+ TimeFormatterPrivate *priv = (TimeFormatterPrivate *)user_data;
57+ if (!g_variant_is_of_type (parameters, G_VARIANT_TYPE ("(sa{sv}as)")))
60+ g_variant_get (parameters, "(s@a{sv}as)", NULL, &changed, &iter);
62+ if (g_variant_lookup (changed, "Timezone", "s", NULL)) {
63+ priv->formatter->update();
66+ while (g_variant_iter_next (iter, "&s", &name)) {
67+ if (g_str_equal (name, "Timezone")) {
68+ priv->formatter->update();
74+ g_variant_unref (changed);
75+ g_variant_iter_free (iter);
79+got_bus(GObject *object, GAsyncResult *result, gpointer user_data)
83+ TimeFormatterPrivate *priv = (TimeFormatterPrivate *)user_data;
84+ GError *error = NULL;
86+ priv->system_bus = g_bus_get_finish (result, &error);
87+ if (priv->system_bus == NULL) {
88+ if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
89+ qWarning("TimeFormatter: cannot connect to the system bus: %s", error->message);
90+ g_error_free (error);
94+ /* Listen to the PropertiesChanged on the org.freedesktop.timedate1
95+ * interface from any sender. In practice, this signal will only be sent
96+ * from timedated (we can trust other processes on the system bus to behave
97+ * nicely). That way, we don't have to watch timedated's well-known name
98+ * and keep the process alive.
100+ priv->subscription_id = g_dbus_connection_signal_subscribe (priv->system_bus,
102+ "org.freedesktop.DBus.Properties",
103+ "PropertiesChanged",
105+ "org.freedesktop.timedate1",
106+ G_DBUS_SIGNAL_FLAGS_NONE,
107+ timedate1_properties_changed,
111+TimeFormatter::TimeFormatter(QObject *parent): QObject(parent)
113+ priv = new TimeFormatterPrivate;
114+ priv->formatter = this;
116+ priv->format = "yyyy-MM-dd hh:mm";
117+ priv->system_bus = NULL;
118+ priv->subscription_id = 0;
119+ priv->cancellable = g_cancellable_new ();
121+ g_bus_get (G_BUS_TYPE_SYSTEM, priv->cancellable, got_bus, priv);
124+TimeFormatter::~TimeFormatter()
126+ if (priv->system_bus) {
127+ g_dbus_connection_signal_unsubscribe (priv->system_bus, priv->subscription_id);
128+ g_object_unref (priv->system_bus);
131+ g_cancellable_cancel (priv->cancellable);
132+ g_object_unref (priv->cancellable);
135+QString TimeFormatter::format() const
137+ return priv->format;
140+QString TimeFormatter::timeString() const
142+ return priv->timeString;
145+qint64 TimeFormatter::time() const
150+void TimeFormatter::setFormat(const QString &format)
152+ if (priv->format != format) {
153+ priv->format = format;
154+ Q_EMIT formatChanged(priv->format);
159+void TimeFormatter::setTime(qint64 time)
161+ if (priv->time != time) {
163+ Q_EMIT timeChanged(priv->time);
168+void TimeFormatter::update()
170+ priv->timeString = QDateTime::fromMSecsSinceEpoch(priv->time / 1000).toString(priv->format);
171+ Q_EMIT timeStringChanged(priv->timeString);