aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--configure.ac16
-rw-r--r--data/datetime-dialog.ui6
-rw-r--r--data/indicator-datetime-preferences.desktop.in10
-rw-r--r--libmap/cc-timezone-map.c4
-rw-r--r--src/Makefile.am13
-rw-r--r--src/datetime-prefs.c387
-rw-r--r--src/datetime-service.c24
-rw-r--r--src/indicator-datetime.c18
-rw-r--r--src/timezone-completion.c21
-rw-r--r--src/utils.c24
-rw-r--r--src/utils.h1
11 files changed, 314 insertions, 210 deletions
diff --git a/configure.ac b/configure.ac
index 31de25e..0342b96 100644
--- a/configure.ac
+++ b/configure.ac
@@ -102,6 +102,7 @@ PKG_CHECK_MODULES(PREF, gio-2.0 >= $GIO_REQUIRED_VERSION
gtk+-3.0 >= $GTK3_REQUIRED_VERSION
unique-3.0
json-glib-1.0
+ libgnome-control-center
polkit-gobject-1)
PKG_CHECK_MODULES(LIBMAP, gio-2.0 >= $GIO_REQUIRED_VERSION
@@ -156,6 +157,20 @@ AC_SUBST(INDICATORDIR)
AC_SUBST(INDICATORICONSDIR)
###########################
+# Control Center Info
+###########################
+
+AS_IF([test "x$with_localinstall" = "xyes"],
+ [
+ CCPANELDIR="${libdir}/control-center-1/panels/"
+ ],
+ [
+ CCPANELDIR=`$PKG_CONFIG --variable=extensiondir libgnome-control-center`
+ ])
+
+AC_SUBST(CCPANELDIR)
+
+###########################
# DBus Service Info
###########################
@@ -216,4 +231,5 @@ Date and Time Indicator Configuration:
Prefix: $prefix
Indicator Dir: $INDICATORDIR
+ CC Panel Dir: $CCPANELDIR
])
diff --git a/data/datetime-dialog.ui b/data/datetime-dialog.ui
index 8479482..59d6753 100644
--- a/data/datetime-dialog.ui
+++ b/data/datetime-dialog.ui
@@ -134,13 +134,9 @@
<property name="step_increment">60</property>
<property name="page_increment">3600</property>
</object>
- <object class="GtkWindow" id="timeDateDialog">
+ <object class="GtkEventBox" id="timeDatePanel">
<property name="can_focus">False</property>
<property name="border_width">5</property>
- <property name="title" translatable="yes">Time &amp; Date</property>
- <property name="resizable">False</property>
- <property name="icon_name">time-admin</property>
- <property name="type_hint">dialog</property>
<child>
<object class="GtkNotebook" id="notebook1">
<property name="visible">True</property>
diff --git a/data/indicator-datetime-preferences.desktop.in b/data/indicator-datetime-preferences.desktop.in
index f37765b..226ae67 100644
--- a/data/indicator-datetime-preferences.desktop.in
+++ b/data/indicator-datetime-preferences.desktop.in
@@ -4,11 +4,13 @@ Version=1.0
_Name=Time & Date
_Comment=Change your clock and date settings
-Icon=time-admin
-TryExec=indicator-datetime-preferences
-Exec=indicator-datetime-preferences
+Icon=preferences-system-time
+TryExec=gnome-control-center
+Exec=gnome-control-center indicator-datetime
StartupNotify=true
Type=Application
-Categories=GNOME;GTK;Utility;DesktopSettings;Settings;
+Categories=GNOME;GTK;Utility;DesktopSettings;Settings;X-GNOME-SystemSettings;X-GNOME-Settings-Panel;
+X-GNOME-Settings-Panel=indicator-datetime
+OnlyShowIn=Unity;
diff --git a/libmap/cc-timezone-map.c b/libmap/cc-timezone-map.c
index 5ce1354..aeac9a0 100644
--- a/libmap/cc-timezone-map.c
+++ b/libmap/cc-timezone-map.c
@@ -686,10 +686,6 @@ cc_timezone_map_realize (GtkWidget *widget)
window = gdk_window_new (gtk_widget_get_parent_window (widget), &attr,
GDK_WA_X | GDK_WA_Y);
- gtk_widget_set_style (widget,
- gtk_style_attach (gtk_widget_get_style (widget),
- window));
-
gdk_window_set_user_data (window, widget);
cursor = gdk_cursor_new (GDK_HAND2);
diff --git a/src/Makefile.am b/src/Makefile.am
index 6d388c7..6ca07a8 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,5 +1,7 @@
-bin_PROGRAMS = indicator-datetime-preferences
+ccpaneldir = $(CCPANELDIR)
+ccpanel_LTLIBRARIES = libindicator-datetime.la
+
libexec_PROGRAMS = indicator-datetime-service
indicator_datetime_service_SOURCES = \
@@ -34,6 +36,7 @@ libdatetime_la_SOURCES = \
libdatetime_la_CFLAGS = \
$(INDICATOR_CFLAGS) \
-Wall -Werror \
+ -DTIMEZONE_FILE="\"/etc/timezone\"" \
-DG_LOG_DOMAIN=\"Indicator-Datetime\"
libdatetime_la_LIBADD = \
$(INDICATOR_LIBS)
@@ -41,7 +44,7 @@ libdatetime_la_LDFLAGS = \
-module \
-avoid-version
-indicator_datetime_preferences_SOURCES =\
+libindicator_datetime_la_SOURCES =\
datetime-prefs.c \
datetime-prefs-locations.c \
datetime-prefs-locations.h \
@@ -50,15 +53,17 @@ indicator_datetime_preferences_SOURCES =\
utils.c \
utils.h \
settings-shared.h
-indicator_datetime_preferences_CFLAGS = \
+libindicator_datetime_la_CFLAGS = \
-Wall \
-Werror \
-I$(top_srcdir)/libmap \
$(PREF_CFLAGS) \
+ -DTIMEZONE_FILE="\"/etc/timezone\"" \
-DPKGDATADIR="\"$(pkgdatadir)\""
-indicator_datetime_preferences_LDADD = \
+libindicator_datetime_la_LIBADD = \
$(top_builddir)/libmap/libmap.la \
$(PREF_LIBS)
+libindicator_datetime_la_LDFLAGS = -module -avoid-version
gen-%.xml.c: %.xml
@echo "Building $@ from $<"
diff --git a/src/datetime-prefs.c b/src/datetime-prefs.c
index 85068c7..bed5ff1 100644
--- a/src/datetime-prefs.c
+++ b/src/datetime-prefs.c
@@ -34,6 +34,7 @@ with this program. If not, see <http://www.gnu.org/licenses/>.
#include <gtk/gtk.h>
#include <unique/unique.h>
#include <polkit/polkit.h>
+#include <libgnome-control-center/cc-panel.h>
#include "dbus-shared.h"
#include "settings-shared.h"
@@ -44,16 +45,40 @@ with this program. If not, see <http://www.gnu.org/licenses/>.
#define DATETIME_DIALOG_UI_FILE PKGDATADIR "/datetime-dialog.ui"
-GDBusProxy * proxy = NULL;
-GtkWidget * auto_radio = NULL;
-GtkWidget * tz_entry = NULL;
-CcTimezoneMap * tzmap = NULL;
-GtkWidget * time_spin = NULL;
-GtkWidget * date_spin = NULL;
-guint save_time_id = 0;
-gboolean user_edited_time = FALSE;
-gboolean changing_time = FALSE;
-GtkWidget * loc_dlg = NULL;
+#define INDICATOR_DATETIME_TYPE_PANEL indicator_datetime_panel_get_type()
+
+typedef struct _IndicatorDatetimePanel IndicatorDatetimePanel;
+typedef struct _IndicatorDatetimePanelPrivate IndicatorDatetimePanelPrivate;
+typedef struct _IndicatorDatetimePanelClass IndicatorDatetimePanelClass;
+
+struct _IndicatorDatetimePanel
+{
+ CcPanel parent;
+ IndicatorDatetimePanelPrivate * priv;
+};
+
+struct _IndicatorDatetimePanelPrivate
+{
+ GtkBuilder * builder;
+ GDBusProxy * proxy;
+ GtkWidget * auto_radio;
+ GtkWidget * tz_entry;
+ CcTimezoneMap * tzmap;
+ GtkWidget * time_spin;
+ GtkWidget * date_spin;
+ guint save_time_id;
+ gboolean user_edited_time;
+ gboolean changing_time;
+ GtkWidget * loc_dlg;
+ TimezoneCompletion * completion;
+};
+
+struct _IndicatorDatetimePanelClass
+{
+ CcPanelClass parent_class;
+};
+
+G_DEFINE_DYNAMIC_TYPE (IndicatorDatetimePanel, indicator_datetime_panel, CC_TYPE_PANEL)
/* Turns the boolean property into a string gsettings */
static GVariant *
@@ -164,7 +189,7 @@ static void
dbus_set_answered (GObject *object, GAsyncResult *res, gpointer command)
{
GError * error = NULL;
- GVariant * answers = g_dbus_proxy_call_finish (proxy, res, &error);
+ GVariant * answers = g_dbus_proxy_call_finish (G_DBUS_PROXY (object), res, &error);
if (error != NULL) {
g_warning("Could not set '%s' for SettingsDaemon: %s", (gchar *)command, error->message);
@@ -176,19 +201,19 @@ dbus_set_answered (GObject *object, GAsyncResult *res, gpointer command)
}
static void
-toggle_ntp (GtkWidget * radio, GParamSpec * pspec, gpointer user_data)
+toggle_ntp (GtkWidget * radio, GParamSpec * pspec, IndicatorDatetimePanel * self)
{
gboolean active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (radio));
- g_dbus_proxy_call (proxy, "SetUsingNtp", g_variant_new ("(b)", active),
+ g_dbus_proxy_call (self->priv->proxy, "SetUsingNtp", g_variant_new ("(b)", active),
G_DBUS_CALL_FLAGS_NONE, -1, NULL, dbus_set_answered, "using_ntp");
}
static void
-ntp_query_answered (GObject *object, GAsyncResult *res, gpointer user_data)
+ntp_query_answered (GObject *object, GAsyncResult *res, IndicatorDatetimePanel * self)
{
GError * error = NULL;
- GVariant * answers = g_dbus_proxy_call_finish (proxy, res, &error);
+ GVariant * answers = g_dbus_proxy_call_finish (G_DBUS_PROXY (object), res, &error);
if (error != NULL) {
g_warning("Could not query DBus proxy for SettingsDaemon: %s", error->message);
@@ -199,43 +224,42 @@ ntp_query_answered (GObject *object, GAsyncResult *res, gpointer user_data)
gboolean can_use_ntp, is_using_ntp;
g_variant_get (answers, "(bb)", &can_use_ntp, &is_using_ntp);
- gtk_widget_set_sensitive (GTK_WIDGET (auto_radio), can_use_ntp);
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (auto_radio), is_using_ntp);
+ gtk_widget_set_sensitive (GTK_WIDGET (self->priv->auto_radio), can_use_ntp);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (self->priv->auto_radio), is_using_ntp);
- g_signal_connect (auto_radio, "notify::active", G_CALLBACK (toggle_ntp), NULL);
+ g_signal_connect (self->priv->auto_radio, "notify::active", G_CALLBACK (toggle_ntp), self);
g_variant_unref (answers);
}
static void
-sync_entry (const gchar * location)
+sync_entry (IndicatorDatetimePanel * self, const gchar * location)
{
gchar * name = get_current_zone_name (location);
- gtk_entry_set_text (GTK_ENTRY (tz_entry), name);
+ gtk_entry_set_text (GTK_ENTRY (self->priv->tz_entry), name);
g_free (name);
- gtk_entry_set_icon_from_stock (GTK_ENTRY (tz_entry), GTK_ENTRY_ICON_SECONDARY, NULL);
+ gtk_entry_set_icon_from_stock (GTK_ENTRY (self->priv->tz_entry),
+ GTK_ENTRY_ICON_SECONDARY, NULL);
}
static void
-tz_changed (CcTimezoneMap * map, TzLocation * location)
+tz_changed (CcTimezoneMap * map, TzLocation * location, IndicatorDatetimePanel * self)
{
if (location == NULL)
return;
- gchar * file = g_build_filename ("/usr/share/zoneinfo", location->zone, NULL);
- g_dbus_proxy_call (proxy, "SetTimezone", g_variant_new ("(s)", file),
+ g_dbus_proxy_call (self->priv->proxy, "SetTimezone", g_variant_new ("(s)", location->zone),
G_DBUS_CALL_FLAGS_NONE, -1, NULL, dbus_set_answered, "timezone");
- g_free (file);
- sync_entry (location->zone);
+ sync_entry (self, location->zone);
}
static void
-tz_query_answered (GObject *object, GAsyncResult *res, gpointer user_data)
+tz_query_answered (GObject *object, GAsyncResult *res, IndicatorDatetimePanel * self)
{
GError * error = NULL;
- GVariant * answers = g_dbus_proxy_call_finish (proxy, res, &error);
+ GVariant * answers = g_dbus_proxy_call_finish (G_DBUS_PROXY (object), res, &error);
if (error != NULL) {
g_warning("Could not query DBus proxy for SettingsDaemon: %s", error->message);
@@ -246,20 +270,20 @@ tz_query_answered (GObject *object, GAsyncResult *res, gpointer user_data)
const gchar * timezone;
g_variant_get (answers, "(&s)", &timezone);
- cc_timezone_map_set_timezone (tzmap, timezone);
+ cc_timezone_map_set_timezone (self->priv->tzmap, timezone);
- sync_entry (timezone);
- g_signal_connect (tzmap, "location-changed", G_CALLBACK (tz_changed), NULL);
+ sync_entry (self, timezone);
+ g_signal_connect (self->priv->tzmap, "location-changed", G_CALLBACK (tz_changed), self);
g_variant_unref (answers);
}
static void
-proxy_ready (GObject *object, GAsyncResult *res, gpointer user_data)
+proxy_ready (GObject *object, GAsyncResult *res, IndicatorDatetimePanel * self)
{
GError * error = NULL;
- proxy = g_dbus_proxy_new_for_bus_finish (res, &error);
+ self->priv->proxy = g_dbus_proxy_new_for_bus_finish (res, &error);
if (error != NULL) {
g_critical("Could not grab DBus proxy for SettingsDaemon: %s", error->message);
@@ -268,10 +292,10 @@ proxy_ready (GObject *object, GAsyncResult *res, gpointer user_data)
}
/* And now, do initial proxy configuration */
- g_dbus_proxy_call (proxy, "GetUsingNtp", NULL, G_DBUS_CALL_FLAGS_NONE, -1,
- NULL, ntp_query_answered, auto_radio);
- g_dbus_proxy_call (proxy, "GetTimezone", NULL, G_DBUS_CALL_FLAGS_NONE, -1,
- NULL, tz_query_answered, NULL);
+ g_dbus_proxy_call (self->priv->proxy, "GetUsingNtp", NULL, G_DBUS_CALL_FLAGS_NONE, -1,
+ NULL, (GAsyncReadyCallback)ntp_query_answered, self);
+ g_dbus_proxy_call (self->priv->proxy, "GetTimezone", NULL, G_DBUS_CALL_FLAGS_NONE, -1,
+ NULL, (GAsyncReadyCallback)tz_query_answered, self);
}
static void
@@ -290,7 +314,7 @@ service_proxy_ready (GObject *object, GAsyncResult *res, gpointer user_data)
{
GError * error = NULL;
- proxy = g_dbus_proxy_new_for_bus_finish (res, &error);
+ GDBusProxy * proxy = g_dbus_proxy_new_for_bus_finish (res, &error);
if (error != NULL) {
g_critical("Could not grab DBus proxy for indicator-datetime-service: %s", error->message);
@@ -304,51 +328,53 @@ service_proxy_ready (GObject *object, GAsyncResult *res, gpointer user_data)
}
static gboolean
-are_spinners_focused (void)
+are_spinners_focused (IndicatorDatetimePanel * self)
{
// save_time_id means that we were in focus and haven't finished our save
// yet, so act like we are still focused.
- return save_time_id || gtk_widget_has_focus (time_spin) || gtk_widget_has_focus (date_spin);
+ return self->priv->save_time_id ||
+ gtk_widget_has_focus (self->priv->time_spin) ||
+ gtk_widget_has_focus (self->priv->date_spin);
}
static gboolean
-save_time (gpointer user_data)
+save_time (IndicatorDatetimePanel * self)
{
- if (user_edited_time) {
- gdouble current_value = gtk_spin_button_get_value (GTK_SPIN_BUTTON (date_spin));
- g_dbus_proxy_call (proxy, "SetTime", g_variant_new ("(x)", (guint64)current_value),
+ if (self->priv->user_edited_time) {
+ gdouble current_value = gtk_spin_button_get_value (GTK_SPIN_BUTTON (self->priv->date_spin));
+ g_dbus_proxy_call (self->priv->proxy, "SetTime", g_variant_new ("(x)", (guint64)current_value),
G_DBUS_CALL_FLAGS_NONE, -1, NULL, dbus_set_answered, "time");
}
- user_edited_time = FALSE;
- save_time_id = 0;
+ self->priv->user_edited_time = FALSE;
+ self->priv->save_time_id = 0;
return FALSE;
}
static gboolean
-spin_focus_in (void)
+spin_focus_in (IndicatorDatetimePanel * self)
{
- if (save_time_id > 0) {
- g_source_remove (save_time_id);
- save_time_id = 0;
+ if (self->priv->save_time_id > 0) {
+ g_source_remove (self->priv->save_time_id);
+ self->priv->save_time_id = 0;
}
return FALSE;
}
static gboolean
-spin_focus_out (void)
+spin_focus_out (IndicatorDatetimePanel * self)
{
/* We want to only save when both spinners are unfocused. But it's difficult
to tell who is about to get focus during a focus-out. So we set an idle
callback to save the time if we don't focus in to another spinner by that
time. */
- if (save_time_id == 0) {
- save_time_id = g_idle_add ((GSourceFunc)save_time, NULL);
+ if (self->priv->save_time_id == 0) {
+ self->priv->save_time_id = g_idle_add ((GSourceFunc)save_time, self);
}
return FALSE;
}
static int
-input_time_text (GtkWidget * spinner, gdouble * value, gpointer user_data)
+input_time_text (GtkWidget * spinner, gdouble * value, IndicatorDatetimePanel * self)
{
gboolean is_time = (gboolean)GPOINTER_TO_INT (g_object_get_data (G_OBJECT (spinner), "is-time"));
const gchar * text = gtk_entry_get_text (GTK_ENTRY (spinner));
@@ -427,13 +453,13 @@ input_time_text (GtkWidget * spinner, gdouble * value, gpointer user_data)
return TRUE;
}
- gboolean prev_changing = changing_time;
- changing_time = TRUE;
+ gboolean prev_changing = self->priv->changing_time;
+ self->priv->changing_time = TRUE;
GDateTime * new_time = g_date_time_new_local (year, month, day, hour, minute, second);
*value = g_date_time_to_unix (new_time);
- user_edited_time = TRUE;
+ self->priv->user_edited_time = TRUE;
g_date_time_unref (new_time);
- changing_time = prev_changing;
+ self->priv->changing_time = prev_changing;
return TRUE;
}
@@ -464,89 +490,98 @@ format_time_text (GtkWidget * spinner, gpointer user_data)
}
static void
-spin_copy_value (GtkSpinButton * spinner, GtkSpinButton * other)
+spin_copy_value (GtkSpinButton * spinner, IndicatorDatetimePanel * self)
{
+ GtkSpinButton * other = NULL;
+ if (GTK_WIDGET (spinner) == self->priv->date_spin)
+ other = GTK_SPIN_BUTTON (self->priv->time_spin);
+ else
+ other = GTK_SPIN_BUTTON (self->priv->date_spin);
+
if (gtk_spin_button_get_value (spinner) != gtk_spin_button_get_value (other)) {
gtk_spin_button_set_value (other, gtk_spin_button_get_value (spinner));
}
- if (!changing_time) { /* Means user pressed spin buttons */
- user_edited_time = TRUE;
+ if (!self->priv->changing_time) { /* Means user pressed spin buttons */
+ self->priv->user_edited_time = TRUE;
}
}
static gboolean
-update_spinners (void)
+update_spinners (IndicatorDatetimePanel * self)
{
/* Add datetime object to spinner, which will hold the real time value, rather
then using the value of the spinner itself. And don't update while user is
editing. */
- if (!are_spinners_focused ()) {
- gboolean prev_changing = changing_time;
- changing_time = TRUE;
+ if (!are_spinners_focused (self)) {
+ gboolean prev_changing = self->priv->changing_time;
+ self->priv->changing_time = TRUE;
GDateTime * now = g_date_time_new_now_local ();
- gtk_spin_button_set_value (GTK_SPIN_BUTTON (time_spin), (gdouble)g_date_time_to_unix (now));
+ gtk_spin_button_set_value (GTK_SPIN_BUTTON (self->priv->time_spin),
+ (gdouble)g_date_time_to_unix (now));
/* will be copied to other spin button */
g_date_time_unref (now);
- changing_time = prev_changing;
+ self->priv->changing_time = prev_changing;
}
return TRUE;
}
static void
-setup_time_spinners (GtkWidget * time, GtkWidget * date)
+setup_time_spinners (IndicatorDatetimePanel * self, GtkWidget * time, GtkWidget * date)
{
- g_signal_connect (time, "input", G_CALLBACK (input_time_text), date);
- g_signal_connect (date, "input", G_CALLBACK (input_time_text), time);
+ g_signal_connect (time, "input", G_CALLBACK (input_time_text), self);
+ g_signal_connect (date, "input", G_CALLBACK (input_time_text), self);
g_signal_connect (time, "output", G_CALLBACK (format_time_text), date);
g_signal_connect (date, "output", G_CALLBACK (format_time_text), time);
- g_signal_connect (time, "focus-in-event", G_CALLBACK (spin_focus_in), date);
- g_signal_connect (date, "focus-in-event", G_CALLBACK (spin_focus_in), time);
+ g_signal_connect_swapped (time, "focus-in-event", G_CALLBACK (spin_focus_in), self);
+ g_signal_connect_swapped (date, "focus-in-event", G_CALLBACK (spin_focus_in), self);
- g_signal_connect (time, "focus-out-event", G_CALLBACK (spin_focus_out), date);
- g_signal_connect (date, "focus-out-event", G_CALLBACK (spin_focus_out), time);
+ g_signal_connect_swapped (time, "focus-out-event", G_CALLBACK (spin_focus_out), self);
+ g_signal_connect_swapped (date, "focus-out-event", G_CALLBACK (spin_focus_out), self);
- g_signal_connect (time, "value-changed", G_CALLBACK (spin_copy_value), date);
- g_signal_connect (date, "value-changed", G_CALLBACK (spin_copy_value), time);
+ g_signal_connect (time, "value-changed", G_CALLBACK (spin_copy_value), self);
+ g_signal_connect (date, "value-changed", G_CALLBACK (spin_copy_value), self);
g_object_set_data (G_OBJECT (time), "is-time", GINT_TO_POINTER (TRUE));
g_object_set_data (G_OBJECT (date), "is-time", GINT_TO_POINTER (FALSE));
- time_spin = time;
- date_spin = date;
+ self->priv->time_spin = time;
+ self->priv->date_spin = date;
/* 2 seconds is what the indicator itself uses */
- guint time_id = g_timeout_add_seconds (2, (GSourceFunc)update_spinners, NULL);
- g_signal_connect_swapped (time_spin, "destroy", G_CALLBACK (g_source_remove), GINT_TO_POINTER (time_id));
- update_spinners ();
+ guint time_id = g_timeout_add_seconds (2, (GSourceFunc)update_spinners, self);
+ g_signal_connect_swapped (self->priv->time_spin, "destroy",
+ G_CALLBACK (g_source_remove), GINT_TO_POINTER (time_id));
+ update_spinners (self);
}
static void
-hide_locations ()
+hide_locations (IndicatorDatetimePanel * self)
{
- if (loc_dlg != NULL)
- gtk_widget_destroy (loc_dlg);
+ if (self->priv->loc_dlg != NULL)
+ gtk_widget_destroy (self->priv->loc_dlg);
}
static void
-show_locations (GtkWidget * button, GtkWidget * dlg)
-{
- if (loc_dlg == NULL) {
- loc_dlg = datetime_setup_locations_dialog (tzmap);
- gtk_window_set_transient_for (GTK_WINDOW (loc_dlg), GTK_WINDOW (dlg));
- g_signal_connect (loc_dlg, "destroy", G_CALLBACK (gtk_widget_destroyed), &loc_dlg);
- g_signal_connect (dlg, "focus-in-event", G_CALLBACK (hide_locations), NULL);
- gtk_widget_show_all (loc_dlg);
+show_locations (IndicatorDatetimePanel * self)
+{
+ if (self->priv->loc_dlg == NULL) {
+ self->priv->loc_dlg = datetime_setup_locations_dialog (self->priv->tzmap);
+ GtkWidget * dlg = gtk_widget_get_toplevel (GTK_WIDGET (self));
+ gtk_window_set_transient_for (GTK_WINDOW (self->priv->loc_dlg), GTK_WINDOW (dlg));
+ g_signal_connect (self->priv->loc_dlg, "destroy", G_CALLBACK (gtk_widget_destroyed), &self->priv->loc_dlg);
+ g_signal_connect_swapped (dlg, "focus-in-event", G_CALLBACK (hide_locations), self);
+ gtk_widget_show_all (self->priv->loc_dlg);
}
else {
- gtk_window_present_with_time (GTK_WINDOW (loc_dlg), gtk_get_current_event_time ());
+ gtk_window_present_with_time (GTK_WINDOW (self->priv->loc_dlg), gtk_get_current_event_time ());
}
}
static gboolean
timezone_selected (GtkEntryCompletion * widget, GtkTreeModel * model,
- GtkTreeIter * iter, gpointer user_data)
+ GtkTreeIter * iter, IndicatorDatetimePanel * self)
{
const gchar * name, * zone;
@@ -572,7 +607,7 @@ timezone_selected (GtkEntryCompletion * widget, GtkTreeModel * model,
lat = strtod(strlat, NULL);
}
- zone = cc_timezone_map_get_timezone_at_coords (tzmap, lon, lat);
+ zone = cc_timezone_map_get_timezone_at_coords (self->priv->tzmap, lon, lat);
}
GSettings * conf = g_settings_new (SETTINGS_INTERFACE);
@@ -581,18 +616,18 @@ timezone_selected (GtkEntryCompletion * widget, GtkTreeModel * model,
g_free (tz_name);
g_object_unref (conf);
- cc_timezone_map_set_timezone (tzmap, zone);
+ cc_timezone_map_set_timezone (self->priv->tzmap, zone);
return FALSE; // Do normal action too
}
static gboolean
-entry_focus_out (GtkEntry * entry, GdkEventFocus * event)
+entry_focus_out (GtkEntry * entry, GdkEventFocus * event, IndicatorDatetimePanel * self)
{
// If the name left in the entry doesn't match the current timezone name,
// show an error icon. It's always an error for the user to manually type in
// a timezone.
- TzLocation * location = cc_timezone_map_get_location (tzmap);
+ TzLocation * location = cc_timezone_map_get_location (self->priv->tzmap);
if (location == NULL)
return FALSE;
@@ -608,36 +643,29 @@ entry_focus_out (GtkEntry * entry, GdkEventFocus * event)
return FALSE;
}
-static gboolean
-key_pressed (GtkWidget * widget, GdkEventKey * event, gpointer user_data)
+static void
+indicator_datetime_panel_init (IndicatorDatetimePanel * self)
{
- switch (event->keyval) {
- case GDK_KEY_Escape:
- gtk_widget_destroy (widget);
- return TRUE;
- }
- return FALSE;
-}
+ self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
+ INDICATOR_DATETIME_TYPE_PANEL,
+ IndicatorDatetimePanelPrivate);
-static GtkWidget *
-create_dialog (void)
-{
GError * error = NULL;
- GtkBuilder * builder = gtk_builder_new ();
- gtk_builder_add_from_file (builder, DATETIME_DIALOG_UI_FILE, &error);
+ self->priv->builder = gtk_builder_new ();
+ gtk_builder_add_from_file (self->priv->builder, DATETIME_DIALOG_UI_FILE, &error);
if (error != NULL) {
/* We have to abort, we can't continue without the ui file */
g_error ("Could not load ui file %s: %s", DATETIME_DIALOG_UI_FILE, error->message);
g_error_free (error);
- return NULL;
+ return;
}
- gtk_builder_set_translation_domain (builder, GETTEXT_PACKAGE);
+ gtk_builder_set_translation_domain (self->priv->builder, GETTEXT_PACKAGE);
GSettings * conf = g_settings_new (SETTINGS_INTERFACE);
-#define WIG(name) GTK_WIDGET (gtk_builder_get_object (builder, name))
+#define WIG(name) GTK_WIDGET (gtk_builder_get_object (self->priv->builder, name))
/* Add policykit button */
GtkWidget * polkit_button = gtk_lock_button_new (NULL);
@@ -653,16 +681,16 @@ create_dialog (void)
polkit_permission_new (polkit_name, NULL, NULL, polkit_perm_ready, polkit_button);
/* Add map */
- tzmap = cc_timezone_map_new ();
- gtk_container_add (GTK_CONTAINER (WIG ("mapBox")), GTK_WIDGET (tzmap));
+ self->priv->tzmap = cc_timezone_map_new ();
+ gtk_container_add (GTK_CONTAINER (WIG ("mapBox")), GTK_WIDGET (self->priv->tzmap));
/* Fufill the CC by Attribution license requirements for the Geonames lookup */
- cc_timezone_map_set_watermark (tzmap, "Geonames.org");
+ cc_timezone_map_set_watermark (self->priv->tzmap, "Geonames.org");
/* And completion entry */
- TimezoneCompletion * completion = timezone_completion_new ();
- timezone_completion_watch_entry (completion, GTK_ENTRY (WIG ("timezoneEntry")));
- g_signal_connect (completion, "match-selected", G_CALLBACK (timezone_selected), NULL);
- g_signal_connect (WIG ("timezoneEntry"), "focus-out-event", G_CALLBACK (entry_focus_out), NULL);
+ self->priv->completion = timezone_completion_new ();
+ timezone_completion_watch_entry (self->priv->completion, GTK_ENTRY (WIG ("timezoneEntry")));
+ g_signal_connect (self->priv->completion, "match-selected", G_CALLBACK (timezone_selected), self);
+ g_signal_connect (WIG ("timezoneEntry"), "focus-out-event", G_CALLBACK (entry_focus_out), self);
/* Set up settings bindings */
g_settings_bind (conf, SETTINGS_SHOW_CLOCK_S, WIG ("showClockCheck"),
@@ -704,21 +732,20 @@ create_dialog (void)
gtk_widget_set_sensitive (WIG ("showEventsCheck"), (evo_path != NULL));
g_free (evo_path);
- setup_time_spinners (WIG ("timeSpinner"), WIG ("dateSpinner"));
+ setup_time_spinners (self, WIG ("timeSpinner"), WIG ("dateSpinner"));
- GtkWidget * dlg = WIG ("timeDateDialog");
- auto_radio = WIG ("automaticTimeRadio");
- tz_entry = WIG ("timezoneEntry");
+ GtkWidget * panel = WIG ("timeDatePanel");
+ self->priv->auto_radio = WIG ("automaticTimeRadio");
+ self->priv->tz_entry = WIG ("timezoneEntry");
- g_signal_connect (WIG ("locationsButton"), "clicked", G_CALLBACK (show_locations), dlg);
- g_signal_connect (dlg, "key-press-event", G_CALLBACK (key_pressed), NULL);
+ g_signal_connect_swapped (WIG ("locationsButton"), "clicked", G_CALLBACK (show_locations), self);
/* Grab proxy for settings daemon */
g_dbus_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE, NULL,
"org.gnome.SettingsDaemon.DateTimeMechanism",
"/",
"org.gnome.SettingsDaemon.DateTimeMechanism",
- NULL, proxy_ready, NULL);
+ NULL, (GAsyncReadyCallback)proxy_ready, self);
/* Grab proxy for datetime service, to see if it's running. It would
actually be more ideal to see if the indicator module itself is running,
@@ -727,56 +754,92 @@ create_dialog (void)
us if there *was* a datetime module run this session. */
g_dbus_proxy_new_for_bus (G_BUS_TYPE_SESSION, G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, NULL,
SERVICE_NAME, SERVICE_OBJ, SERVICE_IFACE,
- NULL, service_proxy_ready, WIG ("showClockCheck"));
+ NULL, (GAsyncReadyCallback)service_proxy_ready,
+ WIG ("showClockCheck"));
#undef WIG
g_object_unref (conf);
- g_object_unref (builder);
- return dlg;
+ gtk_widget_show_all (panel);
+ gtk_container_add (GTK_CONTAINER (self), panel);
}
-static UniqueResponse
-message_received (UniqueApp * app, gint command, UniqueMessageData *message_data,
- guint time, gpointer user_data)
+static void
+indicator_datetime_panel_dispose (GObject * object)
{
- if (command == UNIQUE_ACTIVATE) {
- gtk_window_present_with_time (GTK_WINDOW (user_data), time);
- return UNIQUE_RESPONSE_OK;
+ IndicatorDatetimePanel * self = (IndicatorDatetimePanel *) object;
+
+ if (self->priv->builder) {
+ g_object_unref (self->priv->builder);
+ self->priv->builder = NULL;
}
- return UNIQUE_RESPONSE_PASSTHROUGH;
-}
-int
-main (int argc, char ** argv)
-{
- g_type_init ();
+ if (self->priv->proxy) {
+ g_object_unref (self->priv->proxy);
+ self->priv->proxy = NULL;
+ }
- /* Setting up i18n and gettext. Apparently, we need
- all of these. */
- setlocale (LC_ALL, "");
- bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR);
- textdomain (GETTEXT_PACKAGE);
+ if (self->priv->loc_dlg) {
+ gtk_widget_destroy (self->priv->loc_dlg);
+ self->priv->loc_dlg = NULL;
+ }
- gtk_init (&argc, &argv);
+ if (self->priv->save_time_id) {
+ g_source_remove (self->priv->save_time_id);
+ self->priv->save_time_id = 0;
+ }
- UniqueApp * app = unique_app_new ("com.canonical.indicator.datetime.preferences", NULL);
+ if (self->priv->completion) {
+ timezone_completion_watch_entry (self->priv->completion, NULL);
+ g_object_unref (self->priv->completion);
+ self->priv->completion = NULL;
+ }
- if (unique_app_is_running (app)) {
- unique_app_send_message (app, UNIQUE_ACTIVATE, NULL);
- } else {
- // We're first instance. Yay!
- GtkWidget * dlg = create_dialog ();
+ if (self->priv->tz_entry) {
+ gtk_widget_destroy (self->priv->tz_entry);
+ self->priv->tz_entry = NULL;
+ }
- g_signal_connect (app, "message-received", G_CALLBACK(message_received), dlg);
- unique_app_watch_window (app, GTK_WINDOW (dlg));
+ if (self->priv->time_spin) {
+ gtk_widget_destroy (self->priv->time_spin);
+ self->priv->time_spin = NULL;
+ }
- gtk_widget_show_all (dlg);
- g_signal_connect (dlg, "destroy", G_CALLBACK(gtk_main_quit), NULL);
- gtk_main ();
+ if (self->priv->date_spin) {
+ gtk_widget_destroy (self->priv->date_spin);
+ self->priv->date_spin = NULL;
}
+}
- return 0;
+static void
+indicator_datetime_panel_class_finalize (IndicatorDatetimePanelClass *klass)
+{
}
+static void
+indicator_datetime_panel_class_init (IndicatorDatetimePanelClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+ g_type_class_add_private (klass, sizeof (IndicatorDatetimePanelPrivate));
+
+ gobject_class->dispose = indicator_datetime_panel_dispose;
+}
+
+void
+g_io_module_load (GIOModule *module)
+{
+ bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR);
+ bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
+
+ indicator_datetime_panel_register_type (G_TYPE_MODULE (module));
+ g_io_extension_point_implement (CC_SHELL_PANEL_EXTENSION_POINT,
+ INDICATOR_DATETIME_TYPE_PANEL,
+ "indicator-datetime", 0);
+}
+
+void
+g_io_module_unload (GIOModule *module)
+{
+}
diff --git a/src/datetime-service.c b/src/datetime-service.c
index ff4306e..6c876aa 100644
--- a/src/datetime-service.c
+++ b/src/datetime-service.c
@@ -221,29 +221,15 @@ update_current_timezone (void) {
current_timezone = NULL;
}
- GError * error = NULL;
- gchar * tempzone = NULL;
- if (!g_file_get_contents(TIMEZONE_FILE, &tempzone, NULL, &error)) {
- g_warning("Unable to read timezone file '" TIMEZONE_FILE "': %s", error->message);
- g_error_free(error);
+ current_timezone = read_timezone ();
+ if (current_timezone == NULL) {
return;
}
- /* This shouldn't happen, so let's make it a big boom! */
- g_return_if_fail(tempzone != NULL);
-
- /* Note: this really makes sense as strstrip works in place
- so we end up with something a little odd without the dup
- so we have the dup to make sure everything is as expected
- for everyone else. */
- current_timezone = g_strdup(g_strstrip(tempzone));
- g_free(tempzone);
-
g_debug("System timezone is: %s", current_timezone);
check_timezone_sync();
- if (error != NULL) g_error_free(error);
return;
}
@@ -276,10 +262,8 @@ quick_set_tz_proxy_cb (GObject *object, GAsyncResult *res, gpointer zone)
return;
}
- gchar * file = g_build_filename ("/usr/share/zoneinfo", (char *)zone, NULL);
- g_dbus_proxy_call (proxy, "SetTimezone", g_variant_new ("(s)", file),
+ g_dbus_proxy_call (proxy, "SetTimezone", g_variant_new ("(s)", zone),
G_DBUS_CALL_FLAGS_NONE, -1, NULL, quick_set_tz_cb, NULL);
- g_free (file);
g_free (zone);
g_object_unref (proxy);
}
@@ -1129,7 +1113,7 @@ build_menus (DbusmenuMenuitem * root)
dbusmenu_menuitem_property_set (settings, DBUSMENU_MENUITEM_PROP_LABEL, _("Time & Date Settings..."));
/* insensitive until we check for available apps */
dbusmenu_menuitem_property_set_bool(settings, DBUSMENU_MENUITEM_PROP_ENABLED, FALSE);
- g_signal_connect(G_OBJECT(settings), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK(activate_cb), "gnome-control-center datetime");
+ g_signal_connect(G_OBJECT(settings), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK(activate_cb), "gnome-control-center indicator-datetime");
dbusmenu_menuitem_child_append(root, settings);
g_idle_add(check_for_timeadmin, NULL);
diff --git a/src/indicator-datetime.c b/src/indicator-datetime.c
index 19f0010..072253b 100644
--- a/src/indicator-datetime.c
+++ b/src/indicator-datetime.c
@@ -761,11 +761,18 @@ set_label_to_time_in_zone (IndicatorDatetime * self, GtkLabel * label,
GTimeZone * tz, const gchar * format,
GDateTime ** datetime)
{
+ gboolean unref_tz = FALSE;
+ if (tz == NULL) {
+ gchar * zone = read_timezone ();
+ if (zone == NULL)
+ return;
+ tz = g_time_zone_new(zone);
+ unref_tz = TRUE;
+ g_free (zone);
+ }
+
GDateTime * datetime_now;
- if (tz == NULL)
- datetime_now = g_date_time_new_now_local();
- else
- datetime_now = g_date_time_new_now(tz);
+ datetime_now = g_date_time_new_now(tz);
gchar * timestr;
if (format == NULL) {
@@ -793,6 +800,9 @@ set_label_to_time_in_zone (IndicatorDatetime * self, GtkLabel * label,
else
g_date_time_unref(datetime_now);
+ if (unref_tz)
+ g_time_zone_unref(tz);
+
return;
}
diff --git a/src/timezone-completion.c b/src/timezone-completion.c
index 6ba1e88..d190035 100644
--- a/src/timezone-completion.c
+++ b/src/timezone-completion.c
@@ -492,21 +492,26 @@ timezone_completion_watch_entry (TimezoneCompletion * completion, GtkEntry * ent
}
if (priv->entry) {
g_signal_handler_disconnect (priv->entry, priv->changed_id);
+ priv->changed_id = 0;
g_signal_handler_disconnect (priv->entry, priv->keypress_id);
+ priv->keypress_id = 0;
g_object_remove_weak_pointer (G_OBJECT (priv->entry), (gpointer *)&priv->entry);
gtk_entry_set_completion (priv->entry, NULL);
}
- guint id = g_signal_connect (entry, "changed", G_CALLBACK (entry_changed), completion);
- priv->changed_id = id;
+ priv->entry = entry;
- id = g_signal_connect (entry, "key-press-event", G_CALLBACK (entry_keypress), completion);
- priv->keypress_id = id;
+ if (entry) {
+ guint id = g_signal_connect (entry, "changed", G_CALLBACK (entry_changed), completion);
+ priv->changed_id = id;
- priv->entry = entry;
- g_object_add_weak_pointer (G_OBJECT (entry), (gpointer *)&priv->entry);
+ id = g_signal_connect (entry, "key-press-event", G_CALLBACK (entry_keypress), completion);
+ priv->keypress_id = id;
- gtk_entry_set_completion (entry, GTK_ENTRY_COMPLETION (completion));
+ g_object_add_weak_pointer (G_OBJECT (entry), (gpointer *)&priv->entry);
+
+ gtk_entry_set_completion (entry, GTK_ENTRY_COMPLETION (completion));
+ }
}
static GtkListStore *
@@ -640,7 +645,9 @@ timezone_completion_dispose (GObject * object)
}
if (priv->entry != NULL) {
+ gtk_entry_set_completion (priv->entry, NULL);
g_object_remove_weak_pointer (G_OBJECT (priv->entry), (gpointer *)&priv->entry);
+ priv->entry = NULL;
}
if (priv->initial_model != NULL) {
diff --git a/src/utils.c b/src/utils.c
index ab93ecf..73c8ab2 100644
--- a/src/utils.c
+++ b/src/utils.c
@@ -117,6 +117,30 @@ get_current_zone_name (const gchar * location)
return rv;
}
+gchar *
+read_timezone ()
+{
+ GError * error = NULL;
+ gchar * tempzone = NULL;
+ if (!g_file_get_contents(TIMEZONE_FILE, &tempzone, NULL, &error)) {
+ g_warning("Unable to read timezone file '" TIMEZONE_FILE "': %s", error->message);
+ g_error_free(error);
+ return NULL;
+ }
+
+ /* This shouldn't happen, so let's make it a big boom! */
+ g_return_val_if_fail(tempzone != NULL, NULL);
+
+ /* Note: this really makes sense as strstrip works in place
+ so we end up with something a little odd without the dup
+ so we have the dup to make sure everything is as expected
+ for everyone else. */
+ gchar * rv = g_strdup(g_strstrip(tempzone));
+ g_free(tempzone);
+
+ return rv;
+}
+
/* Translate msg according to the locale specified by LC_TIME */
static char *
T_(const char *msg)
diff --git a/src/utils.h b/src/utils.h
index c2bc0c5..788d516 100644
--- a/src/utils.h
+++ b/src/utils.h
@@ -30,6 +30,7 @@ G_BEGIN_DECLS
gboolean is_locale_12h (void);
void split_settings_location (const gchar * location, gchar ** zone, gchar ** name);
gchar * get_current_zone_name (const gchar * location);
+gchar * read_timezone ();
gchar * generate_format_string_full (gboolean show_day, gboolean show_date);
gchar * generate_format_string_at_time (GDateTime * time);