aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Terry <mike@mterry.name>2011-02-22 15:17:48 -0600
committerMichael Terry <mike@mterry.name>2011-02-22 15:17:48 -0600
commitdeafbc1da6b3c29e04455e46414342bcb9841c2a (patch)
tree6bb04fbe40f5a5ffebb31a95b328c76d363e6379
parent07c5056f4604b4294f42492e27ea3fcf85019dc3 (diff)
downloadayatana-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.ui85
-rw-r--r--src/Makefile.am2
-rw-r--r--src/datetime-prefs-locations.c15
-rw-r--r--src/datetime-prefs.c30
-rw-r--r--src/timezone-completion.c131
-rw-r--r--src/timezone-completion.h59
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__ */
+