diff options
author | Michael Terry <mike@mterry.name> | 2011-02-22 15:17:48 -0600 |
---|---|---|
committer | Michael Terry <mike@mterry.name> | 2011-02-22 15:17:48 -0600 |
commit | deafbc1da6b3c29e04455e46414342bcb9841c2a (patch) | |
tree | 6bb04fbe40f5a5ffebb31a95b328c76d363e6379 | |
parent | 07c5056f4604b4294f42492e27ea3fcf85019dc3 (diff) | |
download | ayatana-indicator-datetime-deafbc1da6b3c29e04455e46414342bcb9841c2a.tar.gz ayatana-indicator-datetime-deafbc1da6b3c29e04455e46414342bcb9841c2a.tar.bz2 ayatana-indicator-datetime-deafbc1da6b3c29e04455e46414342bcb9841c2a.zip |
beginnings of completion support
-rw-r--r-- | data/datetime-dialog.ui | 85 | ||||
-rw-r--r-- | src/Makefile.am | 2 | ||||
-rw-r--r-- | src/datetime-prefs-locations.c | 15 | ||||
-rw-r--r-- | src/datetime-prefs.c | 30 | ||||
-rw-r--r-- | src/timezone-completion.c | 131 | ||||
-rw-r--r-- | src/timezone-completion.h | 59 |
6 files changed, 241 insertions, 81 deletions
diff --git a/data/datetime-dialog.ui b/data/datetime-dialog.ui index b5eba54..26c368b 100644 --- a/data/datetime-dialog.ui +++ b/data/datetime-dialog.ui @@ -6,6 +6,8 @@ <property name="can_focus">False</property> <property name="title" translatable="yes">Locations</property> <property name="modal">True</property> + <property name="default_width">300</property> + <property name="default_height">200</property> <property name="destroy_with_parent">True</property> <property name="icon_name">time-admin</property> <child> @@ -169,87 +171,10 @@ </packing> </child> <child> - <object class="GtkHBox" id="hbox4"> + <object class="GtkEntry" id="timezoneEntry"> <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="spacing">12</property> - <property name="homogeneous">True</property> - <child> - <object class="GtkHBox" id="hbox5"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="spacing">6</property> - <child> - <object class="GtkLabel" id="label7"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="xalign">0</property> - <property name="label" translatable="yes">_Region:</property> - <property name="use_underline">True</property> - <property name="mnemonic_widget">regionCombo</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">True</property> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkComboBox" id="regionCombo"> - <property name="visible">True</property> - <property name="can_focus">False</property> - </object> - <packing> - <property name="expand">True</property> - <property name="fill">True</property> - <property name="position">1</property> - </packing> - </child> - </object> - <packing> - <property name="expand">True</property> - <property name="fill">True</property> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkHBox" id="hbox6"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="spacing">6</property> - <child> - <object class="GtkLabel" id="label8"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="xalign">0</property> - <property name="label" translatable="yes">Time_zone:</property> - <property name="use_underline">True</property> - <property name="mnemonic_widget">timezoneCombo</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">True</property> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkComboBox" id="timezoneCombo"> - <property name="visible">True</property> - <property name="can_focus">False</property> - </object> - <packing> - <property name="expand">True</property> - <property name="fill">True</property> - <property name="position">1</property> - </packing> - </child> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">True</property> - <property name="position">1</property> - </packing> - </child> + <property name="can_focus">True</property> + <property name="invisible_char">•</property> </object> <packing> <property name="expand">False</property> diff --git a/src/Makefile.am b/src/Makefile.am index 4c94f7c..7e8ac4b 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -43,6 +43,8 @@ indicator_datetime_preferences_SOURCES =\ datetime-prefs.c \ datetime-prefs-locations.c \ datetime-prefs-locations.h \ + timezone-completion.c \ + timezone-completion.h \ utils.c \ utils.h \ settings-shared.h diff --git a/src/datetime-prefs-locations.c b/src/datetime-prefs-locations.c index 7df41e7..b13d082 100644 --- a/src/datetime-prefs-locations.c +++ b/src/datetime-prefs-locations.c @@ -29,6 +29,7 @@ with this program. If not, see <http://www.gnu.org/licenses/>. #include "datetime-prefs-locations.h" #include "settings-shared.h" +#include "timezone-completion.h" #define DATETIME_DIALOG_UI_FILE PKGDATADIR "/datetime-dialog.ui" @@ -86,6 +87,16 @@ handle_edit (GtkCellRendererText * renderer, gchar * path, gchar * new_text, } static void +handle_edit_started (GtkCellRendererText * renderer, GtkCellEditable * editable, + gchar * path, TimezoneCompletion * completion) +{ + if (GTK_IS_ENTRY (editable)) { + GtkEntry *entry = GTK_ENTRY (editable); + gtk_entry_set_completion (entry, GTK_ENTRY_COMPLETION (timezone_completion_new ())); + } +} + +static void fill_from_settings (GObject * store, GSettings * conf) { gchar ** locations = g_settings_get_strv (conf, SETTINGS_LOCATIONS_S); @@ -161,8 +172,10 @@ datetime_setup_locations_dialog (GtkWindow * parent) GObject * store = gtk_builder_get_object (builder, "locationsStore"); /* Configure tree */ + TimezoneCompletion * completion = timezone_completion_new (); GtkCellRenderer * cell = gtk_cell_renderer_text_new (); g_object_set (cell, "editable", TRUE, NULL); + g_signal_connect (cell, "editing-started", G_CALLBACK (handle_edit_started), completion); g_signal_connect (cell, "edited", G_CALLBACK (handle_edit), store); gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (tree), -1, _("Location"), cell, @@ -181,7 +194,9 @@ datetime_setup_locations_dialog (GtkWindow * parent) g_signal_connect (WIG ("removeButton"), "clicked", G_CALLBACK (handle_remove), tree); fill_from_settings (store, conf); + g_object_set_data_full (G_OBJECT (dlg), "conf", g_object_ref (conf), g_object_unref); + g_object_set_data_full (G_OBJECT (dlg), "completion", completion, g_object_unref); g_signal_connect (dlg, "destroy", G_CALLBACK (save_to_settings), store); gtk_window_set_transient_for (GTK_WINDOW (dlg), parent); diff --git a/src/datetime-prefs.c b/src/datetime-prefs.c index ee4b26a..dbacee1 100644 --- a/src/datetime-prefs.c +++ b/src/datetime-prefs.c @@ -36,6 +36,7 @@ with this program. If not, see <http://www.gnu.org/licenses/>. #include "settings-shared.h" #include "utils.h" #include "datetime-prefs-locations.h" +#include "timezone-completion.h" #include "cc-timezone-map.h" #define DATETIME_DIALOG_UI_FILE PKGDATADIR "/datetime-dialog.ui" @@ -176,8 +177,10 @@ tz_changed (CcTimezoneMap * map, TzLocation * location) if (location == NULL) return; - g_dbus_proxy_call (proxy, "SetTimezone", g_variant_new ("(s)", location->zone), + gchar * file = g_build_filename ("/usr/share/zoneinfo", location->zone, NULL); + g_dbus_proxy_call (proxy, "SetTimezone", g_variant_new ("(s)", file), G_DBUS_CALL_FLAGS_NONE, -1, NULL, dbus_set_answered, "timezone"); + g_free (file); } static void @@ -371,6 +374,25 @@ show_locations (GtkWidget * button, GtkWidget * dlg) gtk_widget_show_all (locationsDlg); } +static gboolean +timezone_selected (GtkEntryCompletion * widget, GtkTreeModel * model, + GtkTreeIter * iter, gpointer user_data) +{ + GValue value = {0}; + const gchar * strval; + + gtk_tree_model_get_value (model, iter, TIMEZONE_COMPLETION_ZONE, &value); + strval = g_value_get_string (&value); + + if (strval != NULL && strval[0] != 0) { + cc_timezone_map_set_timezone (tzmap, strval); + } + + g_value_unset (&value); + + return FALSE; // Do normal action too +} + static GtkWidget * create_dialog (void) { @@ -401,6 +423,12 @@ create_dialog (void) tzmap = cc_timezone_map_new (); gtk_container_add (GTK_CONTAINER (WIG ("mapBox")), GTK_WIDGET (tzmap)); + /* And completion entry */ + TimezoneCompletion * completion = timezone_completion_new (); + gtk_entry_set_completion (GTK_ENTRY (WIG ("timezoneEntry")), + GTK_ENTRY_COMPLETION (completion)); + g_signal_connect (completion, "match-selected", G_CALLBACK (timezone_selected), NULL); + /* Set up settings bindings */ g_settings_bind (conf, SETTINGS_SHOW_CLOCK_S, WIG ("showClockCheck"), "active", G_SETTINGS_BIND_DEFAULT); diff --git a/src/timezone-completion.c b/src/timezone-completion.c new file mode 100644 index 0000000..d98654a --- /dev/null +++ b/src/timezone-completion.c @@ -0,0 +1,131 @@ +/* -*- Mode: C; coding: utf-8; indent-tabs-mode: nil; tab-width: 2 -*- + +Copyright 2011 Canonical Ltd. + +Authors: + Michael Terry <michael.terry@canonical.com> + +This program is free software: you can redistribute it and/or modify it +under the terms of the GNU General Public License version 3, as published +by the Free Software Foundation. + +This program is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranties of +MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along +with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <gdk/gdk.h> +#include <glib/gi18n.h> +#include "timezone-completion.h" +#include "tz.h" + +enum { + LAST_SIGNAL +}; + +/* static guint signals[LAST_SIGNAL] = { }; */ + +typedef struct _TimezoneCompletionPrivate TimezoneCompletionPrivate; +struct _TimezoneCompletionPrivate +{ + void * placeholder; +}; + +#define TIMEZONE_COMPLETION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), TIMEZONE_COMPLETION_TYPE, TimezoneCompletionPrivate)) + +/* Prototypes */ +static void timezone_completion_class_init (TimezoneCompletionClass *klass); +static void timezone_completion_init (TimezoneCompletion *self); +static void timezone_completion_dispose (GObject *object); +static void timezone_completion_finalize (GObject *object); + +G_DEFINE_TYPE (TimezoneCompletion, timezone_completion, GTK_TYPE_ENTRY_COMPLETION); + +static GtkListStore * +get_initial_model (void) +{ + TzDB * db = tz_load_db (); + GPtrArray * locations = tz_get_locations (db); + + GtkListStore * store = gtk_list_store_new (TIMEZONE_COMPLETION_LAST, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING); + + gint i; + for (i = 0; i < locations->len; ++i) { + TzLocation * loc = g_ptr_array_index (locations, i); + GtkTreeIter iter; + gtk_list_store_append (store, &iter); + + /* FIXME: need something better than below for non-English locales */ + const gchar * last_bit = ((const gchar *)strrchr (loc->zone, '/')) + 1; + if (last_bit == NULL) + last_bit = loc->zone; + gchar * name = g_strdup (last_bit); + gchar * underscore; + while ((underscore = strchr (name, '_'))) { + *underscore = ' '; + } + + gtk_list_store_set (store, &iter, + TIMEZONE_COMPLETION_ZONE, loc->zone, + TIMEZONE_COMPLETION_NAME, name, + TIMEZONE_COMPLETION_COUNTRY, loc->country, + -1); + + g_free (name); + } + + tz_db_free (db); + return store; +} + +static void +timezone_completion_class_init (TimezoneCompletionClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + g_type_class_add_private (klass, sizeof (TimezoneCompletionPrivate)); + + object_class->dispose = timezone_completion_dispose; + object_class->finalize = timezone_completion_finalize; + + return; +} + +static void +timezone_completion_init (TimezoneCompletion *self) +{ + GtkListStore * model = get_initial_model (); + gtk_entry_completion_set_model (GTK_ENTRY_COMPLETION (self), GTK_TREE_MODEL (model)); + gtk_entry_completion_set_text_column (GTK_ENTRY_COMPLETION (self), TIMEZONE_COMPLETION_NAME); + return; +} + +static void +timezone_completion_dispose (GObject *object) +{ + G_OBJECT_CLASS (timezone_completion_parent_class)->dispose (object); + return; +} + +static void +timezone_completion_finalize (GObject *object) +{ + G_OBJECT_CLASS (timezone_completion_parent_class)->finalize (object); + return; +} + +TimezoneCompletion * +timezone_completion_new () +{ + TimezoneCompletion * self = g_object_new (TIMEZONE_COMPLETION_TYPE, NULL); + return self; +} + diff --git a/src/timezone-completion.h b/src/timezone-completion.h new file mode 100644 index 0000000..6b3ac2b --- /dev/null +++ b/src/timezone-completion.h @@ -0,0 +1,59 @@ +/* -*- Mode: C; coding: utf-8; indent-tabs-mode: nil; tab-width: 2 -*- + +Copyright 2011 Canonical Ltd. + +Authors: + Michael Terry <michael.terry@canonical.com> + +This program is free software: you can redistribute it and/or modify it +under the terms of the GNU General Public License version 3, as published +by the Free Software Foundation. + +This program is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranties of +MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along +with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#ifndef __TIMEZONE_COMPLETION_H__ +#define __TIMEZONE_COMPLETION_H__ + +#include <glib.h> +#include <glib-object.h> +#include <gtk/gtk.h> + +G_BEGIN_DECLS + +#define TIMEZONE_COMPLETION_TYPE (timezone_completion_get_type ()) +#define TIMEZONE_COMPLETION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TIMEZONE_COMPLETION_TYPE, TimezoneCompletion)) +#define TIMEZONE_COMPLETION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TIMEZONE_COMPLETION_TYPE, TimezoneCompletionClass)) +#define IS_TIMEZONE_COMPLETION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TIMEZONE_COMPLETION_TYPE)) +#define IS_TIMEZONE_COMPLETION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TIMEZONE_COMPLETION_TYPE)) +#define TIMEZONE_COMPLETION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TIMEZONE_COMPLETION_TYPE, TimezoneCompletionClass)) + +typedef struct _TimezoneCompletion TimezoneCompletion; +typedef struct _TimezoneCompletionClass TimezoneCompletionClass; + +struct _TimezoneCompletionClass { + GtkEntryCompletionClass parent_class; +}; + +struct _TimezoneCompletion { + GtkEntryCompletion parent; +}; + +#define TIMEZONE_COMPLETION_ZONE 0 +#define TIMEZONE_COMPLETION_NAME 1 +#define TIMEZONE_COMPLETION_COUNTRY 2 +#define TIMEZONE_COMPLETION_LAST 3 + +GType timezone_completion_get_type (void); +TimezoneCompletion * timezone_completion_new (); + +G_END_DECLS + +#endif /* __TIMEZONE_COMPLETION_H__ */ + |