diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/datetime-prefs.c | 223 |
1 files changed, 197 insertions, 26 deletions
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 <http://www.gnu.org/licenses/>. #include <libintl.h> #include <locale.h> +#include <glib/gi18n.h> #include <gtk/gtk.h> #include <unique/unique.h> +#include <polkitgtk/polkitgtk.h> #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); |