From 354fc2c05e901b65f4a0516473632a4df3878ed6 Mon Sep 17 00:00:00 2001 From: Michael Terry Date: Fri, 18 Feb 2011 10:50:49 -0500 Subject: add polkit support and use new gnome-settings-daemon ntp-setting support --- configure.ac | 7 +- data/datetime-dialog.ui | 354 +++++++++++++++++++++++++----------------------- src/datetime-prefs.c | 223 ++++++++++++++++++++++++++---- 3 files changed, 387 insertions(+), 197 deletions(-) diff --git a/configure.ac b/configure.ac index 3cf45ef..2418f12 100644 --- a/configure.ac +++ b/configure.ac @@ -113,15 +113,18 @@ AS_IF([test "x$with_gtk" = x3], [AC_MSG_FAILURE([Value for --with-gtk was neither 2 nor 3])] ) +# FIXME: polkit-gtk-1 isn't gtk3-compatible AS_IF([test "x$with_gtk" = x3], [PKG_CHECK_MODULES(PREF, gio-2.0 >= $GIO_REQUIRED_VERSION gtk+-3.0 >= $GTK3_REQUIRED_VERSION - unique-3.0) + unique-3.0 + polkit-gtk-1) ], [test "x$with_gtk" = x2], [PKG_CHECK_MODULES(PREF, gio-2.0 >= $GIO_REQUIRED_VERSION gtk+-2.0 >= $GTK_REQUIRED_VERSION - unique-1.0) + unique-1.0 + polkit-gtk-1) ], [AC_MSG_FAILURE([Value for --with-gtk was neither 2 nor 3])] ) diff --git a/data/datetime-dialog.ui b/data/datetime-dialog.ui index 42f3bb6..f2a5938 100644 --- a/data/datetime-dialog.ui +++ b/data/datetime-dialog.ui @@ -133,82 +133,91 @@ 12 6 - - - - - - - + True False - 12 - True + 6 - - True - False - 6 - - - True - False - 0 - _Region: - True - regionCombo - - - False - True - 0 - - - - - True - False - - - True - True - 1 - - - - - True - True - 0 - + - + True False - 6 + 12 + True - + True False - 0 - Time_zone: - True - timezoneCombo + 6 + + + True + False + 0 + _Region: + True + regionCombo + + + False + True + 0 + + + + + True + False + + + True + True + 1 + + - False + True True 0 - + True False + 6 + + + True + False + 0 + Time_zone: + True + timezoneCombo + + + False + True + 0 + + + + + True + False + + + True + True + 1 + + - True + False True 1 @@ -220,98 +229,30 @@ 1 - - - False - True - 2 - - - - - True - False - 2 - 2 - 6 - 6 - + True False - 6 + 2 + 2 + 6 + 6 - - _Manually - True - True - False - False - True - 0 - True - True - - - False - True - 0 - - - - - _Automatically from the Internet - True - True - False - False - True - 0 - True - manualTimeRadio - - - False - True - 1 - - - - - 1 - 2 - - - - - True - False - 0 - Set the time: - - - GTK_FILL - GTK_FILL - - - - - True - False - 12 - - + True False 6 - + + _Manually True - False - 0 - Tim_e: + True + False + False True - timeSpinner + 0 + True + True False @@ -320,11 +261,16 @@ - + + _Automatically from the Internet True True - - True + False + False + True + 0 + True + manualTimeRadio False @@ -334,24 +280,62 @@ - False - True - 0 + 1 + 2 - + True False - 6 + 0 + Set the time: + + + GTK_FILL + GTK_FILL + + + + + True + False + 12 - + True False - 0 - _Date: - True - dateSpinner + 6 + + + True + False + 0 + Tim_e: + True + timeSpinner + + + False + True + 0 + + + + + True + True + + 11 + 1 + True + + + False + True + 1 + + False @@ -360,11 +344,40 @@ - + True - True - - True + False + 6 + + + True + False + 0 + _Date: + True + dateSpinner + + + False + True + 0 + + + + + True + True + + 11 + 1 + True + + + False + True + 1 + + False @@ -374,29 +387,33 @@ - False - True - 1 + 1 + 2 + 1 + 2 + + + - 1 - 2 - 1 - 2 + False + True + 2 - - - - False + True True - 3 + end + 0 + + + @@ -443,6 +460,7 @@ True False + 6 True @@ -555,6 +573,7 @@ True False + 6 True @@ -796,9 +815,6 @@ 1 - - - diff --git a/src/datetime-prefs.c b/src/datetime-prefs.c index 1957b7f..87eec94 100644 --- a/src/datetime-prefs.c +++ b/src/datetime-prefs.c @@ -27,8 +27,10 @@ with this program. If not, see . #include #include +#include #include #include +#include #include "settings-shared.h" #include "utils.h" @@ -42,36 +44,36 @@ bind_hours_set (const GValue * value, const GVariantType * type, gpointer user_d const gchar * output = NULL; gboolean is_12hour_button = (gboolean)GPOINTER_TO_INT(user_data); - if (g_value_get_boolean(value)) { + if (g_value_get_boolean(value)) { /* Only do anything if we're setting active = true */ - output = is_12hour_button ? "12-hour" : "24-hour"; - } else { + output = is_12hour_button ? "12-hour" : "24-hour"; + } else { return NULL; } - return g_variant_new_string (output); + return g_variant_new_string (output); } /* Turns a string gsettings into a boolean property */ static gboolean bind_hours_get (GValue * value, GVariant * variant, gpointer user_data) { - const gchar * str = g_variant_get_string(variant, NULL); - gboolean output = FALSE; + const gchar * str = g_variant_get_string(variant, NULL); + gboolean output = FALSE; gboolean is_12hour_button = (gboolean)GPOINTER_TO_INT(user_data); - if (g_strcmp0(str, "locale-default") == 0) { - output = (is_12hour_button == is_locale_12h ()); - } else if (g_strcmp0(str, "12-hour") == 0) { - output = is_12hour_button; - } else if (g_strcmp0(str, "24-hour") == 0) { - output = !is_12hour_button; - } else { - return FALSE; - } + if (g_strcmp0(str, "locale-default") == 0) { + output = (is_12hour_button == is_locale_12h ()); + } else if (g_strcmp0(str, "12-hour") == 0) { + output = is_12hour_button; + } else if (g_strcmp0(str, "24-hour") == 0) { + output = !is_12hour_button; + } else { + return FALSE; + } - g_value_set_boolean (value, output); - return TRUE; + g_value_set_boolean (value, output); + return TRUE; } static void @@ -94,6 +96,163 @@ add_widget_dependency (GtkWidget * parent, GtkWidget * dependent) widget_dependency_cb (parent, NULL, dependent); } +static void +polkit_dependency_cb (GtkWidget * parent, GParamSpec *pspec, GtkWidget * dependent) +{ + gboolean authorized, sensitive; + g_object_get (G_OBJECT (parent), + "is-authorized", &authorized, + "sensitive", &sensitive, NULL); + gtk_widget_set_sensitive (dependent, authorized && sensitive); +} + +static void +add_polkit_dependency (GtkWidget * parent, GtkWidget * dependent) +{ + g_signal_connect (parent, "notify::is-authorized", G_CALLBACK(polkit_dependency_cb), + dependent); + g_signal_connect (parent, "notify::sensitive", G_CALLBACK(polkit_dependency_cb), + dependent); + polkit_dependency_cb (parent, NULL, dependent); +} + +void ntp_set_answered (GObject *object, GAsyncResult *res, gpointer autoRadio) +{ + GError * error = NULL; + GDBusProxy * proxy = G_DBUS_PROXY (object); + GVariant * answers = g_dbus_proxy_call_finish (proxy, res, &error); + + if (error != NULL) { + g_warning("Could not set 'using_ntp' for SettingsDaemon: %s", error->message); + g_error_free(error); + return; + } + + g_variant_unref (answers); +} + +static void +toggle_ntp (GtkWidget * autoRadio, GParamSpec * pspec, gpointer user_data) +{ + gboolean active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (autoRadio)); + GDBusProxy * proxy = G_DBUS_PROXY (g_object_get_data (G_OBJECT (autoRadio), "proxy")); + + g_dbus_proxy_call (proxy, "SetUsingNtp", g_variant_new ("(b)", active), + G_DBUS_CALL_FLAGS_NONE, -1, NULL, ntp_set_answered, autoRadio); +} + +void ntp_query_answered (GObject *object, GAsyncResult *res, gpointer autoRadio) +{ + GError * error = NULL; + GDBusProxy * proxy = G_DBUS_PROXY (object); + GVariant * answers = g_dbus_proxy_call_finish (proxy, res, &error); + + if (error != NULL) { + g_warning("Could not query DBus proxy for SettingsDaemon: %s", error->message); + g_error_free(error); + return; + } + + gboolean can_use_ntp, is_using_ntp; + g_variant_get (answers, "(bb)", &can_use_ntp, &is_using_ntp); + + gtk_widget_set_sensitive (GTK_WIDGET (autoRadio), can_use_ntp); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (autoRadio), is_using_ntp); + + g_signal_connect (autoRadio, "notify::active", G_CALLBACK(toggle_ntp), NULL); + + g_variant_unref (answers); +} + +void ntp_proxy_ready (GObject *object, GAsyncResult *res, gpointer autoRadio) +{ + GError * error = NULL; + GDBusProxy * 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); + g_error_free(error); + return; + } + + /* Now attach proxy to button so we can use it later */ + g_object_set_data_full (G_OBJECT (autoRadio), "proxy", proxy, g_object_unref); + + /* And finally ask it what is up */ + g_dbus_proxy_call (proxy, "GetUsingNtp", NULL, G_DBUS_CALL_FLAGS_NONE, -1, + NULL, ntp_query_answered, autoRadio); +} + +static void +setup_ntp (GtkWidget * autoRadio) +{ + /* Do some quick checks to see if ntp is running or installed */ + + /* Start with assumption ntp is unusable until we prove otherwise */ + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (autoRadio), FALSE); + gtk_widget_set_sensitive (autoRadio, FALSE); + + 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, ntp_proxy_ready, autoRadio); +} + +/*static int +input_time_text (GtkWidget * spinner, gdouble *value, gpointer user_data) +{ + //const gchar * text = gtk_entry_get_text (GTK_ENTRY (spinner)); + + return TRUE; +}*/ + +static gboolean +format_time_text (GtkWidget * spinner, gpointer user_data) +{ + GDateTime * datetime = (GDateTime *)g_object_get_data (G_OBJECT (spinner), "datetime"); + + const gchar * format; + if (is_locale_12h ()) { + format = "%I:%M:%S %p"; + } else { + format = "%H:%M:%S"; + } + + gchar * formatted = g_date_time_format (datetime, format); + gtk_entry_set_text (GTK_ENTRY (spinner), formatted); + + return TRUE; +} + +static gboolean +update_spinner (GtkWidget * spinner) +{ + /* Add datetime object to spinner, which will hold the real time value, rather + then using the value of the spinner itself. */ + GDateTime * datetime = g_date_time_new_now_local (); + g_object_set_data_full (G_OBJECT (spinner), "datetime", datetime, (GDestroyNotify)g_date_time_unref); + + format_time_text (spinner, NULL); + + return TRUE; +} + +static void +setup_time_spinner (GtkWidget * spinner) +{ + /* Set up spinner to have reasonable behavior */ + gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (spinner), FALSE); + //g_signal_connect (spinner, "input", G_CALLBACK (input_time_text), NULL); + g_signal_connect (spinner, "output", G_CALLBACK (format_time_text), NULL); + + /* 2 seconds is what the indicator itself uses */ + guint time_id = g_timeout_add_seconds (2, (GSourceFunc)update_spinner, spinner); + g_signal_connect_swapped (spinner, "destroy", G_CALLBACK (g_source_remove), GINT_TO_POINTER(time_id)); + + update_spinner (spinner); +} + static GtkWidget * create_dialog (void) { @@ -110,10 +269,16 @@ create_dialog (void) gtk_builder_set_translation_domain (builder, GETTEXT_PACKAGE); - GSettings * conf = g_settings_new (SETTINGS_INTERFACE); + GSettings * conf = g_settings_new (SETTINGS_INTERFACE); #define WIG(name) GTK_WIDGET (gtk_builder_get_object (builder, name)) + /* Add policykit button */ + GtkWidget * polkit_button = polkit_lock_button_new ("org.gnome.settingsdaemon.datetimemechanism.configure"); + polkit_lock_button_set_unlock_text (POLKIT_LOCK_BUTTON (polkit_button), _("Unlock to change these settings")); + polkit_lock_button_set_lock_text (POLKIT_LOCK_BUTTON (polkit_button), _("Lock to prevent further changes")); + gtk_box_pack_start (GTK_BOX (WIG ("timeDateBox")), polkit_button, FALSE, TRUE, 0); + /* Set up settings bindings */ g_settings_bind (conf, SETTINGS_SHOW_CLOCK_S, WIG ("showClockCheck"), @@ -150,12 +315,18 @@ create_dialog (void) add_widget_dependency (WIG ("showClockCheck"), WIG ("clockOptions")); add_widget_dependency (WIG ("showLocationsCheck"), WIG ("locationsButton")); add_widget_dependency (WIG ("manualTimeRadio"), WIG ("manualOptions")); + add_polkit_dependency (polkit_button, WIG ("timeDateOptions")); /* Hacky proxy test for whether evolution-data-server is installed */ gchar * evo_path = g_find_program_in_path ("evolution"); gtk_widget_set_sensitive (WIG ("showEventsCheck"), (evo_path != NULL)); g_free (evo_path); + /* Check if ntp is usable and enabled */ + setup_ntp (WIG ("automaticTimeRadio")); + + setup_time_spinner (WIG ("timeSpinner")); + GtkWidget * dlg = WIG ("timeDateDialog"); #undef WIG @@ -180,17 +351,17 @@ message_received (UniqueApp * app, gint command, UniqueMessageData *message_data int main (int argc, char ** argv) { - g_type_init (); + g_type_init (); - /* Setting up i18n and gettext. Apparently, we need - all of these. */ - setlocale (LC_ALL, ""); - bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR); - textdomain (GETTEXT_PACKAGE); + /* Setting up i18n and gettext. Apparently, we need + all of these. */ + setlocale (LC_ALL, ""); + bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR); + textdomain (GETTEXT_PACKAGE); - gtk_init (&argc, &argv); + gtk_init (&argc, &argv); - UniqueApp * app = unique_app_new ("com.canonical.indicator.datetime.preferences", NULL); + UniqueApp * app = unique_app_new ("com.canonical.indicator.datetime.preferences", NULL); if (unique_app_is_running (app)) { unique_app_send_message (app, UNIQUE_ACTIVATE, NULL); -- cgit v1.2.3