aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJason Conti <jason.conti@gmail.com>2011-05-07 18:50:54 -0400
committerJason Conti <jason.conti@gmail.com>2011-05-07 18:50:54 -0400
commit1c1136159847953f85346b5c05d3dce6bab4ddca (patch)
tree8582c8dc57eb6968d49bf2ba428f41ad03c36dfd /src
parentea9ddbaa810db9fa91969afb693c4d27778a0a6d (diff)
downloadayatana-indicator-notifications-1c1136159847953f85346b5c05d3dce6bab4ddca.tar.gz
ayatana-indicator-notifications-1c1136159847953f85346b5c05d3dce6bab4ddca.tar.bz2
ayatana-indicator-notifications-1c1136159847953f85346b5c05d3dce6bab4ddca.zip
Ripped out datetime-prefs and the translations.
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am20
-rw-r--r--src/datetime-prefs-locations.c500
-rw-r--r--src/datetime-prefs-locations.h35
-rw-r--r--src/datetime-prefs.c769
-rw-r--r--src/timezone-completion.c688
-rw-r--r--src/timezone-completion.h63
6 files changed, 0 insertions, 2075 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 6d388c7..26447f7 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,5 +1,4 @@
-bin_PROGRAMS = indicator-datetime-preferences
libexec_PROGRAMS = indicator-datetime-service
indicator_datetime_service_SOURCES = \
@@ -41,25 +40,6 @@ libdatetime_la_LDFLAGS = \
-module \
-avoid-version
-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
-indicator_datetime_preferences_CFLAGS = \
- -Wall \
- -Werror \
- -I$(top_srcdir)/libmap \
- $(PREF_CFLAGS) \
- -DPKGDATADIR="\"$(pkgdatadir)\""
-indicator_datetime_preferences_LDADD = \
- $(top_builddir)/libmap/libmap.la \
- $(PREF_LIBS)
-
gen-%.xml.c: %.xml
@echo "Building $@ from $<"
@echo "const char * _$(subst -,_,$(subst .,_,$(basename $<))) = " > $@
diff --git a/src/datetime-prefs-locations.c b/src/datetime-prefs-locations.c
deleted file mode 100644
index af0e10d..0000000
--- a/src/datetime-prefs-locations.c
+++ /dev/null
@@ -1,500 +0,0 @@
-/* -*- Mode: C; coding: utf-8; indent-tabs-mode: nil; tab-width: 2 -*-
-
-A dialog for setting time and date preferences.
-
-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 <stdlib.h>
-#include <glib/gi18n-lib.h>
-#include <gtk/gtk.h>
-
-#include "datetime-prefs-locations.h"
-#include "settings-shared.h"
-#include "utils.h"
-#include "timezone-completion.h"
-
-#define DATETIME_DIALOG_UI_FILE PKGDATADIR "/datetime-dialog.ui"
-
-#define COL_NAME 0
-#define COL_TIME 1
-#define COL_ZONE 2
-#define COL_VISIBLE_NAME 3
-#define COL_ICON 4
-
-static gboolean update_times (GtkWidget * dlg);
-static void save_when_idle (GtkWidget * dlg);
-
-static void
-handle_add (GtkWidget * button, GtkTreeView * tree)
-{
- GtkListStore * store = GTK_LIST_STORE (gtk_tree_view_get_model (tree));
-
- GtkTreeIter iter;
- gtk_list_store_append (store, &iter);
-
- GtkTreePath * path = gtk_tree_model_get_path (GTK_TREE_MODEL (store), &iter);
- gtk_tree_view_set_cursor (tree, path, gtk_tree_view_get_column (tree, 0), TRUE);
- gtk_tree_path_free (path);
-}
-
-static void
-handle_remove (GtkWidget * button, GtkTreeView * tree)
-{
- GtkListStore * store = GTK_LIST_STORE (gtk_tree_view_get_model (tree));
- GtkTreeSelection * selection = gtk_tree_view_get_selection (tree);
-
- GList * paths = gtk_tree_selection_get_selected_rows (selection, NULL);
-
- /* Convert all paths to iters so we can safely delete multiple paths. For a
- GtkListStore, iters persist past model changes. */
- GList * tree_iters = NULL;
- GList * iter;
- for (iter = paths; iter; iter = iter->next) {
- GtkTreeIter * tree_iter = g_new(GtkTreeIter, 1);
- if (gtk_tree_model_get_iter (GTK_TREE_MODEL (store), tree_iter, (GtkTreePath *)iter->data)) {
- tree_iters = g_list_prepend (tree_iters, tree_iter);
- }
- gtk_tree_path_free (iter->data);
- }
- g_list_free (paths);
-
- // Find the next item to select
- GtkTreeIter *last_selected = g_list_nth_data(tree_iters, 0);
- GtkTreePath *path = gtk_tree_model_get_path(GTK_TREE_MODEL (store), last_selected);
- GtkTreeIter titer;
- if (!gtk_tree_model_get_iter(GTK_TREE_MODEL (store), &titer, path)) {
- g_debug("Failed to get last selected iter from path");
- last_selected = NULL;
- } else {
- if (!gtk_tree_model_iter_next(GTK_TREE_MODEL (store), &titer)) {
- if (gtk_tree_path_prev(path)) {
- if (!gtk_tree_model_get_iter(GTK_TREE_MODEL (store), &titer, path)) {
- g_debug("Failed to get iter from path");
- last_selected = NULL;
- } else {
- last_selected = &titer;
- }
- } else {
- g_debug("handle_remove: Failed to find another location to select (assume single selected)");
- last_selected = NULL;
- }
- } else {
- g_debug("Got next item in model");
- last_selected = &titer;
- }
- }
-
- if (last_selected) {
- gboolean clear = TRUE;
- path = gtk_tree_model_get_path(GTK_TREE_MODEL (store), last_selected);
-
- // Step over the path to find an item which isn't in the delete list
- if (g_list_length(tree_iters) > 1) {
- for (iter = tree_iters; iter; iter = iter->next) {
- GtkTreePath *ipath = gtk_tree_model_get_path(GTK_TREE_MODEL (store), (GtkTreeIter *)iter->data);
- if (gtk_tree_path_compare(path, ipath) == 0) {
- clear = FALSE;
- break;
- }
- }
- while (clear == FALSE) {
- if (gtk_tree_path_prev(path)) {
- clear = TRUE;
- for (iter = tree_iters; iter; iter = iter->next) {
- GtkTreePath *ipath = gtk_tree_model_get_path(GTK_TREE_MODEL (store), (GtkTreeIter *)iter->data);
- if (gtk_tree_path_compare(path, ipath) == 0) {
- clear = FALSE;
- break;
- }
- }
- if (clear) {
- if (!gtk_tree_model_get_iter(GTK_TREE_MODEL (store), &titer, path)) {
- g_debug("Failed to get iter from path");
- last_selected = NULL;
- } else {
- last_selected = &titer;
- }
- }
- } else {
- last_selected = NULL;
- break;
- }
- }
- }
- }
-
- /* Now delete each iterator */
- for (iter = tree_iters; iter; iter = iter->next) {
- gtk_list_store_remove (store, (GtkTreeIter *)iter->data);
- g_free (iter->data);
- }
- g_list_free (tree_iters);
-
- if (last_selected)
- gtk_tree_selection_select_iter(selection, last_selected);
-}
-
-static void
-handle_edit (GtkCellRendererText * renderer, gchar * path, gchar * new_text,
- GtkListStore * store)
-{
- GtkTreeIter iter;
-
- // Manual user edits are always wrong (unless they are undoing a previous
- // edit), so we set the error icon here if needed. Common way to get to
- // this code path is to lose entry focus.
- if (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (store), &iter, path)) {
- const gchar * name;
- gtk_tree_model_get (GTK_TREE_MODEL (store), &iter, COL_NAME, &name, -1);
- gboolean correct = g_strcmp0 (name, new_text) == 0;
-
- gtk_list_store_set (store, &iter,
- COL_VISIBLE_NAME, new_text,
- COL_ICON, correct ? NULL : GTK_STOCK_DIALOG_ERROR,
- -1);
- }
-}
-
-static gboolean
-timezone_selected (GtkEntryCompletion * widget, GtkTreeModel * model,
- GtkTreeIter * iter, GtkWidget * dlg)
-{
- const gchar * zone, * name;
-
- gtk_tree_model_get (model, iter,
- TIMEZONE_COMPLETION_ZONE, &zone,
- TIMEZONE_COMPLETION_NAME, &name,
- -1);
-
- if (zone == NULL || zone[0] == 0) {
- const gchar * strlon, * strlat;
- gdouble lon = 0.0, lat = 0.0;
-
- gtk_tree_model_get (model, iter,
- TIMEZONE_COMPLETION_LONGITUDE, &strlon,
- TIMEZONE_COMPLETION_LATITUDE, &strlat,
- -1);
-
- if (strlon != NULL && strlon[0] != 0) {
- lon = strtod(strlon, NULL);
- }
-
- if (strlat != NULL && strlat[0] != 0) {
- lat = strtod(strlat, NULL);
- }
-
- CcTimezoneMap * tzmap = CC_TIMEZONE_MAP (g_object_get_data (G_OBJECT (widget), "tzmap"));
- zone = cc_timezone_map_get_timezone_at_coords (tzmap, lon, lat);
- }
-
- GtkListStore * store = GTK_LIST_STORE (g_object_get_data (G_OBJECT (widget), "store"));
- GtkTreeIter * store_iter = (GtkTreeIter *)g_object_get_data (G_OBJECT (widget), "store_iter");
- if (store != NULL && store_iter != NULL) {
- gtk_list_store_set (store, store_iter,
- COL_VISIBLE_NAME, name,
- COL_ICON, NULL,
- COL_NAME, name,
- COL_ZONE, zone, -1);
- }
-
- update_times (dlg);
-
- return FALSE; // Do normal action too
-}
-
-static gboolean
-query_tooltip (GtkTreeView * tree, gint x, gint y, gboolean keyboard_mode,
- GtkTooltip * tooltip, GtkCellRenderer * cell)
-{
- GtkTreeModel * model;
- GtkTreeIter iter;
- if (!gtk_tree_view_get_tooltip_context (tree, &x, &y, keyboard_mode,
- &model, NULL, &iter))
- return FALSE;
-
- const gchar * icon;
- gtk_tree_model_get (model, &iter, COL_ICON, &icon, -1);
- if (icon == NULL)
- return FALSE;
-
- GtkTreeViewColumn * col = gtk_tree_view_get_column (tree, 0);
- gtk_tree_view_set_tooltip_cell (tree, tooltip, NULL, col, cell);
- gtk_tooltip_set_text (tooltip, _("You need to complete this location for it to appear in the menu."));
- return TRUE;
-}
-
-static void
-handle_edit_started (GtkCellRendererText * renderer, GtkCellEditable * editable,
- gchar * path, TimezoneCompletion * completion)
-{
- if (GTK_IS_ENTRY (editable)) {
- GtkEntry *entry = GTK_ENTRY (editable);
- timezone_completion_watch_entry (completion, entry);
-
- GtkListStore * store = GTK_LIST_STORE (g_object_get_data (G_OBJECT (completion), "store"));
- GtkTreeIter * store_iter = g_new(GtkTreeIter, 1);
- if (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (store), store_iter, path)) {
- g_object_set_data_full (G_OBJECT (completion), "store_iter", store_iter, g_free);
- }
- }
-}
-
-static gboolean
-update_times (GtkWidget * dlg)
-{
- /* For each entry, check zone in column 2 and set column 1 to it's time */
- TimezoneCompletion * completion = TIMEZONE_COMPLETION (g_object_get_data (G_OBJECT (dlg), "completion"));
- GtkListStore * store = GTK_LIST_STORE (g_object_get_data (G_OBJECT (completion), "store"));
- GObject * cell = G_OBJECT (g_object_get_data (G_OBJECT (completion), "name-cell"));
-
- gboolean editing;
- g_object_get (cell, "editing", &editing, NULL);
- if (editing) { /* No updates while editing, it cancels the edit */
- return TRUE;
- }
-
- g_signal_handlers_block_by_func (store, save_when_idle, dlg);
-
- GDateTime * now = g_date_time_new_now_local ();
-
- GtkTreeIter iter;
- if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter)) {
- do {
- const gchar * strzone;
-
- gtk_tree_model_get (GTK_TREE_MODEL (store), &iter, COL_ZONE, &strzone, -1);
-
- if (strzone != NULL && strzone[0] != 0) {
- GTimeZone * tz = g_time_zone_new (strzone);
- GDateTime * now_tz = g_date_time_to_timezone (now, tz);
- gchar * format = generate_format_string_at_time (now_tz);
- gchar * time_str = g_date_time_format (now_tz, format);
-
- gtk_list_store_set (store, &iter, COL_TIME, time_str, -1);
-
- g_free (time_str);
- g_free (format);
- g_date_time_unref (now_tz);
- g_time_zone_unref (tz);
- }
- } while (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter));
- }
-
- g_date_time_unref (now);
-
- g_signal_handlers_unblock_by_func (store, save_when_idle, dlg);
-
- return TRUE;
-}
-
-static void
-fill_from_settings (GObject * store, GSettings * conf)
-{
- gchar ** locations = g_settings_get_strv (conf, SETTINGS_LOCATIONS_S);
-
- gtk_list_store_clear (GTK_LIST_STORE (store));
-
- gchar ** striter;
- GtkTreeIter iter;
- for (striter = locations; *striter; ++striter) {
- gchar * zone, * name;
- split_settings_location (*striter, &zone, &name);
-
- gtk_list_store_append (GTK_LIST_STORE (store), &iter);
- gtk_list_store_set (GTK_LIST_STORE (store), &iter,
- COL_VISIBLE_NAME, name,
- COL_ICON, NULL,
- COL_NAME, name,
- COL_ZONE, zone, -1);
-
- g_free (zone);
- g_free (name);
- }
-
- g_strfreev (locations);
-}
-
-static void
-save_to_settings (GObject * store, GSettings * conf)
-{
- gboolean empty = TRUE;
- GVariantBuilder builder;
- g_variant_builder_init (&builder, G_VARIANT_TYPE_ARRAY);
-
- GtkTreeIter iter;
- if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter)) {
- do {
- const gchar * strzone, * strname;
-
- gtk_tree_model_get (GTK_TREE_MODEL (store), &iter,
- COL_NAME, &strname,
- COL_ZONE, &strzone,
- -1);
-
- if (strzone != NULL && strzone[0] != 0 && strname != NULL && strname[0] != 0) {
- gchar * settings_string = g_strdup_printf("%s %s", strzone, strname);
- g_variant_builder_add (&builder, "s", settings_string);
- g_free (settings_string);
- empty = FALSE;
- }
- } while (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter));
- }
-
- if (empty) {
- /* Empty list */
- g_variant_builder_clear (&builder);
- g_settings_set_strv (conf, SETTINGS_LOCATIONS_S, NULL);
- }
- else {
- GVariant * locations = g_variant_builder_end (&builder);
- g_settings_set_strv (conf, SETTINGS_LOCATIONS_S, g_variant_get_strv (locations, NULL));
- g_variant_unref (locations);
- }
-}
-
-static gboolean
-save_now (GtkWidget *dlg)
-{
- GSettings * conf = G_SETTINGS (g_object_get_data (G_OBJECT (dlg), "conf"));
- GObject * completion = G_OBJECT (g_object_get_data (G_OBJECT (dlg), "completion"));
- GObject * store = G_OBJECT (g_object_get_data (completion, "store"));
-
- save_to_settings (store, conf);
-
- g_object_set_data (G_OBJECT (dlg), "save-id", GINT_TO_POINTER(0));
-
- return FALSE;
-}
-
-static void
-save_when_idle (GtkWidget *dlg)
-{
- guint save_id = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (dlg), "save-id"));
-
- if (save_id == 0) {
- save_id = g_idle_add ((GSourceFunc)save_now, dlg);
- g_object_set_data (G_OBJECT (dlg), "save-id", GINT_TO_POINTER(save_id));
- }
-}
-
-static void
-dialog_closed (GtkWidget * dlg, GObject * store)
-{
- /* Cleanup a tad */
- guint time_id = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (dlg), "time-id"));
- g_source_remove (time_id);
-
- guint save_id = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (dlg), "save-id"));
- if (save_id > 0)
- g_source_remove (save_id);
-}
-
-static void
-selection_changed (GtkTreeSelection * selection, GtkWidget * remove_button)
-{
- gint count = gtk_tree_selection_count_selected_rows (selection);
- gtk_widget_set_sensitive (remove_button, count > 0);
-}
-
-GtkWidget *
-datetime_setup_locations_dialog (CcTimezoneMap * map)
-{
- GError * error = NULL;
- GtkBuilder * builder = gtk_builder_new ();
- gtk_builder_add_from_file (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;
- }
-
- gtk_builder_set_translation_domain (builder, GETTEXT_PACKAGE);
-
- GSettings * conf = g_settings_new (SETTINGS_INTERFACE);
-
-#define WIG(name) GTK_WIDGET (gtk_builder_get_object (builder, name))
-
- GtkWidget * dlg = WIG ("locationsDialog");
- GtkWidget * tree = WIG ("locationsView");
- GObject * store = gtk_builder_get_object (builder, "locationsStore");
-
- /* Configure tree */
- TimezoneCompletion * completion = timezone_completion_new ();
- g_object_set_data (G_OBJECT (completion), "tzmap", map);
- g_object_set_data (G_OBJECT (completion), "store", store);
- g_signal_connect (completion, "match-selected", G_CALLBACK (timezone_selected), dlg);
-
- 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,
- "text", COL_VISIBLE_NAME, NULL);
- GtkTreeViewColumn * loc_col = gtk_tree_view_get_column (GTK_TREE_VIEW (tree), 0);
- gtk_tree_view_column_set_expand (loc_col, TRUE);
- g_object_set_data (G_OBJECT (completion), "name-cell", cell);
-
- cell = gtk_cell_renderer_pixbuf_new ();
- gtk_tree_view_column_pack_start (loc_col, cell, FALSE);
- gtk_tree_view_column_add_attribute (loc_col, cell, "icon-name", COL_ICON);
-
- gtk_widget_set_has_tooltip (tree, TRUE);
- g_signal_connect (tree, "query-tooltip", G_CALLBACK (query_tooltip), cell);
-
- cell = gtk_cell_renderer_text_new ();
- gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (tree), -1,
- _("Time"), cell,
- "text", COL_TIME, NULL);
-
- GtkTreeSelection * selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (tree));
- gtk_tree_selection_set_mode (selection, GTK_SELECTION_MULTIPLE);
- g_signal_connect (selection, "changed", G_CALLBACK (selection_changed), WIG ("removeButton"));
- selection_changed (selection, WIG ("removeButton"));
-
- g_signal_connect (WIG ("addButton"), "clicked", G_CALLBACK (handle_add), tree);
- g_signal_connect (WIG ("removeButton"), "clicked", G_CALLBACK (handle_remove), tree);
-
- fill_from_settings (store, conf);
- g_signal_connect_swapped (store, "row-deleted", G_CALLBACK (save_when_idle), dlg);
- g_signal_connect_swapped (store, "row-inserted", G_CALLBACK (save_when_idle), dlg);
- g_signal_connect_swapped (store, "row-changed", G_CALLBACK (save_when_idle), dlg);
- g_signal_connect_swapped (store, "rows-reordered", G_CALLBACK (save_when_idle), dlg);
-
- 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 (dialog_closed), store);
-
- guint time_id = g_timeout_add_seconds (2, (GSourceFunc)update_times, dlg);
- g_object_set_data (G_OBJECT (dlg), "time-id", GINT_TO_POINTER(time_id));
- update_times (dlg);
-
-#undef WIG
-
- g_object_unref (conf);
- g_object_unref (builder);
-
- return dlg;
-}
-
diff --git a/src/datetime-prefs-locations.h b/src/datetime-prefs-locations.h
deleted file mode 100644
index e312894..0000000
--- a/src/datetime-prefs-locations.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/* -*- Mode: C; coding: utf-8; indent-tabs-mode: nil; tab-width: 2 -*-
-
-A dialog for setting time and date preferences.
-
-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 __DATETIME_PREFS_LOCATIONS_H__
-#define __DATETIME_PREFS_LOCATIONS_H__
-
-#include <gtk/gtk.h>
-#include "cc-timezone-map.h"
-
-G_BEGIN_DECLS
-
-GtkWidget * datetime_setup_locations_dialog (CcTimezoneMap * map);
-
-G_END_DECLS
-
-#endif
diff --git a/src/datetime-prefs.c b/src/datetime-prefs.c
deleted file mode 100644
index 9b00e60..0000000
--- a/src/datetime-prefs.c
+++ /dev/null
@@ -1,769 +0,0 @@
-/* -*- Mode: C; coding: utf-8; indent-tabs-mode: nil; tab-width: 2 -*-
-
-A dialog for setting time and date preferences.
-
-Copyright 2011 Canonical Ltd.
-
-Authors:
- Ted Gould <ted@canonical.com>
- 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 <stdlib.h>
-#include <libintl.h>
-#include <locale.h>
-#include <langinfo.h>
-#include <glib/gi18n-lib.h>
-#include <gdk/gdkkeysyms.h>
-#include <gtk/gtk.h>
-#include <unique/unique.h>
-#include <polkitgtk/polkitgtk.h>
-
-#include "dbus-shared.h"
-#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"
-
-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;
-
-/* Turns the boolean property into a string gsettings */
-static GVariant *
-bind_hours_set (const GValue * value, const GVariantType * type, gpointer user_data)
-{
- const gchar * output = NULL;
- gboolean is_12hour_button = (gboolean)GPOINTER_TO_INT(user_data);
-
- if (g_value_get_boolean(value)) {
- /* Only do anything if we're setting active = true */
- output = is_12hour_button ? "12-hour" : "24-hour";
- } else {
- return NULL;
- }
-
- 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;
- 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;
- }
-
- g_value_set_boolean (value, output);
- return TRUE;
-}
-
-static void
-widget_dependency_cb (GtkWidget * parent, GParamSpec *pspec, GtkWidget * dependent)
-{
- gboolean active, sensitive;
- g_object_get (G_OBJECT (parent),
- "active", &active,
- "sensitive", &sensitive, NULL);
- gtk_widget_set_sensitive (dependent, active && sensitive);
-}
-
-static void
-add_widget_dependency (GtkWidget * parent, GtkWidget * dependent)
-{
- g_signal_connect (parent, "notify::active", G_CALLBACK(widget_dependency_cb),
- dependent);
- g_signal_connect (parent, "notify::sensitive", G_CALLBACK(widget_dependency_cb),
- 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);
-}
-
-static void
-dbus_set_answered (GObject *object, GAsyncResult *res, gpointer command)
-{
- GError * error = NULL;
- GVariant * answers = g_dbus_proxy_call_finish (proxy, res, &error);
-
- if (error != NULL) {
- g_warning("Could not set '%s' for SettingsDaemon: %s", (gchar *)command, error->message);
- g_error_free(error);
- return;
- }
-
- g_variant_unref (answers);
-}
-
-static void
-toggle_ntp (GtkWidget * radio, GParamSpec * pspec, gpointer user_data)
-{
- gboolean active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (radio));
-
- g_dbus_proxy_call (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)
-{
- GError * error = NULL;
- 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 (auto_radio), can_use_ntp);
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (auto_radio), is_using_ntp);
-
- g_signal_connect (auto_radio, "notify::active", G_CALLBACK (toggle_ntp), NULL);
-
- g_variant_unref (answers);
-}
-
-static void
-sync_entry (const gchar * location)
-{
- gchar * name = get_current_zone_name (location);
- gtk_entry_set_text (GTK_ENTRY (tz_entry), name);
- g_free (name);
-
- gtk_entry_set_icon_from_stock (GTK_ENTRY (tz_entry), GTK_ENTRY_ICON_SECONDARY, NULL);
-}
-
-static void
-tz_changed (CcTimezoneMap * map, TzLocation * location)
-{
- 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_CALL_FLAGS_NONE, -1, NULL, dbus_set_answered, "timezone");
- g_free (file);
-
- sync_entry (location->zone);
-}
-
-static void
-tz_query_answered (GObject *object, GAsyncResult *res, gpointer user_data)
-{
- GError * error = NULL;
- 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;
- }
-
- const gchar * timezone;
- g_variant_get (answers, "(&s)", &timezone);
-
- cc_timezone_map_set_timezone (tzmap, timezone);
-
- sync_entry (timezone);
- g_signal_connect (tzmap, "location-changed", G_CALLBACK (tz_changed), NULL);
-
- g_variant_unref (answers);
-}
-
-static void
-proxy_ready (GObject *object, GAsyncResult *res, gpointer user_data)
-{
- GError * error = NULL;
-
- 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;
- }
-
- /* 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);
-}
-
-static void
-service_name_owner_changed (GDBusProxy * proxy, GParamSpec *pspec, gpointer user_data)
-{
- GtkWidget * widget = GTK_WIDGET (user_data);
- gchar * owner = g_dbus_proxy_get_name_owner (proxy);
-
- gtk_widget_set_sensitive (widget, (owner != NULL));
-
- g_free (owner);
-}
-
-static void
-service_proxy_ready (GObject *object, GAsyncResult *res, gpointer user_data)
-{
- GError * error = NULL;
-
- 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);
- g_error_free(error);
- return;
- }
-
- /* And now, do initial proxy configuration */
- g_signal_connect (proxy, "notify::g-name-owner", G_CALLBACK (service_name_owner_changed), user_data);
- service_name_owner_changed (proxy, NULL, user_data);
-}
-
-static gboolean
-are_spinners_focused (void)
-{
- // 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);
-}
-
-static gboolean
-save_time (gpointer user_data)
-{
- 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),
- G_DBUS_CALL_FLAGS_NONE, -1, NULL, dbus_set_answered, "time");
- }
- user_edited_time = FALSE;
- save_time_id = 0;
- return FALSE;
-}
-
-static gboolean
-spin_focus_in (void)
-{
- if (save_time_id > 0) {
- g_source_remove (save_time_id);
- save_time_id = 0;
- }
- return FALSE;
-}
-
-static gboolean
-spin_focus_out (void)
-{
- /* 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);
- }
- return FALSE;
-}
-
-static int
-input_time_text (GtkWidget * spinner, gdouble * value, gpointer user_data)
-{
- 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));
-
- gdouble current_value = gtk_spin_button_get_value (GTK_SPIN_BUTTON (spinner));
- *value = current_value;
-
- GDateTime * now = g_date_time_new_from_unix_local (current_value);
- gint year, month, day, hour, minute, second;
- year = g_date_time_get_year (now);
- month = g_date_time_get_month (now);
- day = g_date_time_get_day_of_month (now);
- hour = g_date_time_get_hour (now);
- minute = g_date_time_get_minute (now);
- second = g_date_time_get_second (now);
- g_date_time_unref (now);
-
- /* Parse this string as if it were in the output format */
- gint scanned = 0;
- gboolean passed = TRUE, skip = FALSE;
- if (is_time) {
- gint hour_in, minute_in, second_in;
-
- if (is_locale_12h ()) { // TODO: make this look-at/watch gsettings?
- char ampm[51];
-
- scanned = sscanf (text, "%u:%u:%u %50s", &hour_in, &minute_in, &second_in, ampm);
- passed = (scanned == 4);
-
- if (passed) {
- const char *pm_str = nl_langinfo (PM_STR);
- if (g_ascii_strcasecmp (pm_str, ampm) == 0) {
- hour_in += 12;
- }
- }
- } else {
- scanned = sscanf (text, "%u:%u:%u", &hour_in, &minute_in, &second_in);
- passed = (scanned == 3);
- }
-
- if (passed && (hour_in > 23 || minute_in > 59 || second_in > 59)) {
- passed = FALSE;
- }
- if (passed && hour == hour_in && minute == minute_in && second == second_in) {
- skip = TRUE; // no change
- } else {
- hour = hour_in;
- minute = minute_in;
- second = second_in;
- }
- }
- else {
- gint year_in, month_in, day_in;
-
- scanned = sscanf (text, "%u-%u-%u", &year_in, &month_in, &day_in);
-
- if (scanned != 3 || year_in < 1 || year_in > 9999 ||
- month_in < 1 || month_in > 12 || day_in < 1 || day_in > 31) {
- passed = FALSE;
- }
- if (passed && year == year_in && month == month_in && day == day_in) {
- skip = TRUE; // no change
- } else {
- year = year_in;
- month = month_in;
- day = day_in;
- }
- }
-
- if (!passed) {
- g_warning ("Could not understand %s", text);
- return TRUE;
- }
-
- if (skip) {
- return TRUE;
- }
-
- gboolean prev_changing = changing_time;
- 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;
- g_date_time_unref (new_time);
- changing_time = prev_changing;
-
- return TRUE;
-}
-
-static gboolean
-format_time_text (GtkWidget * spinner, gpointer user_data)
-{
- gboolean is_time = (gboolean)GPOINTER_TO_INT (g_object_get_data (G_OBJECT (spinner), "is-time"));
-
- const gchar * format;
- if (is_time) {
- if (is_locale_12h ()) { // TODO: make this look-at/watch gsettings?
- format = "%I:%M:%S %p";
- } else {
- format = "%H:%M:%S";
- }
- }
- else {
- format = "%Y-%m-%d";
- }
-
- GDateTime * datetime = g_date_time_new_from_unix_local (gtk_spin_button_get_value (GTK_SPIN_BUTTON (spinner)));
- gchar * formatted = g_date_time_format (datetime, format);
- gtk_entry_set_text (GTK_ENTRY (spinner), formatted);
- g_date_time_unref (datetime);
-
- return TRUE;
-}
-
-static void
-spin_copy_value (GtkSpinButton * spinner, GtkSpinButton * other)
-{
- 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;
- }
-}
-
-static gboolean
-update_spinners (void)
-{
- /* 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;
- 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));
- /* will be copied to other spin button */
- g_date_time_unref (now);
- changing_time = prev_changing;
- }
- return TRUE;
-}
-
-static void
-setup_time_spinners (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, "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 (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 (time, "value-changed", G_CALLBACK (spin_copy_value), date);
- g_signal_connect (date, "value-changed", G_CALLBACK (spin_copy_value), time);
-
- 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;
-
- /* 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 ();
-}
-
-static void
-hide_locations ()
-{
- if (loc_dlg != NULL)
- gtk_widget_destroy (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);
- }
- else {
- gtk_window_present_with_time (GTK_WINDOW (loc_dlg), gtk_get_current_event_time ());
- }
-}
-
-static gboolean
-timezone_selected (GtkEntryCompletion * widget, GtkTreeModel * model,
- GtkTreeIter * iter, gpointer user_data)
-{
- const gchar * name, * zone;
-
- gtk_tree_model_get (model, iter,
- TIMEZONE_COMPLETION_NAME, &name,
- TIMEZONE_COMPLETION_ZONE, &zone,
- -1);
-
- if (zone == NULL || zone[0] == 0) {
- const gchar * strlon, * strlat;
- gdouble lon = 0.0, lat = 0.0;
-
- gtk_tree_model_get (model, iter,
- TIMEZONE_COMPLETION_LONGITUDE, &strlon,
- TIMEZONE_COMPLETION_LATITUDE, &strlat,
- -1);
-
- if (strlon != NULL && strlon[0] != 0) {
- lon = strtod(strlon, NULL);
- }
-
- if (strlat != NULL && strlat[0] != 0) {
- lat = strtod(strlat, NULL);
- }
-
- zone = cc_timezone_map_get_timezone_at_coords (tzmap, lon, lat);
- }
-
- GSettings * conf = g_settings_new (SETTINGS_INTERFACE);
- gchar * tz_name = g_strdup_printf ("%s %s", zone, name);
- g_settings_set_string (conf, SETTINGS_TIMEZONE_NAME_S, tz_name);
- g_free (tz_name);
- g_object_unref (conf);
-
- cc_timezone_map_set_timezone (tzmap, zone);
-
- return FALSE; // Do normal action too
-}
-
-static gboolean
-entry_focus_out (GtkEntry * entry, GdkEventFocus * event)
-{
- // 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);
- if (location == NULL)
- return FALSE;
-
- gchar * name = get_current_zone_name (location->zone);
- gboolean correct = (g_strcmp0 (gtk_entry_get_text (entry), name) == 0);
- g_free (name);
-
- gtk_entry_set_icon_from_stock (entry, GTK_ENTRY_ICON_SECONDARY,
- correct ? NULL : GTK_STOCK_DIALOG_ERROR);
- gtk_entry_set_icon_tooltip_text (entry, GTK_ENTRY_ICON_SECONDARY,
- _("You need to choose a location to change the time zone."));
- gtk_entry_set_icon_activatable (entry, GTK_ENTRY_ICON_SECONDARY, FALSE);
- return FALSE;
-}
-
-static gboolean
-key_pressed (GtkWidget * widget, GdkEventKey * event, gpointer user_data)
-{
- switch (event->keyval) {
- case GDK_KEY_Escape:
- gtk_widget_destroy (widget);
- return TRUE;
- }
- return FALSE;
-}
-
-static GtkWidget *
-get_child_of_type (GtkContainer * parent, GType type)
-{
- GList * children, * iter;
-
- children = gtk_container_get_children (parent);
- for (iter = children; iter; iter = iter->next) {
- if (G_TYPE_CHECK_INSTANCE_TYPE (iter->data, type)) {
- return GTK_WIDGET (iter->data);
- }
- }
-
- return NULL;
-}
-
-static GtkWidget *
-create_dialog (void)
-{
- GError * error = NULL;
-
- GtkBuilder * builder = gtk_builder_new ();
- gtk_builder_add_from_file (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;
- }
-
- gtk_builder_set_translation_domain (builder, GETTEXT_PACKAGE);
-
- 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);
- /* Make sure border around button is visible */
- GtkWidget * polkit_button_button = get_child_of_type (GTK_CONTAINER (polkit_button), GTK_TYPE_BUTTON);
- if (polkit_button_button != NULL) {
- gtk_button_set_relief (GTK_BUTTON (polkit_button_button), GTK_RELIEF_NORMAL);
- }
-
- /* Add map */
- tzmap = cc_timezone_map_new ();
- gtk_container_add (GTK_CONTAINER (WIG ("mapBox")), GTK_WIDGET (tzmap));
- /* Fufill the CC by Attribution license requirements for the Geonames lookup */
- cc_timezone_map_set_watermark (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);
-
- /* Set up settings bindings */
- g_settings_bind (conf, SETTINGS_SHOW_CLOCK_S, WIG ("showClockCheck"),
- "active", G_SETTINGS_BIND_DEFAULT);
- g_settings_bind (conf, SETTINGS_SHOW_DAY_S, WIG ("showWeekdayCheck"),
- "active", G_SETTINGS_BIND_DEFAULT);
- g_settings_bind (conf, SETTINGS_SHOW_DATE_S, WIG ("showDateTimeCheck"),
- "active", G_SETTINGS_BIND_DEFAULT);
- g_settings_bind (conf, SETTINGS_SHOW_SECONDS_S, WIG ("showSecondsCheck"),
- "active", G_SETTINGS_BIND_DEFAULT);
- g_settings_bind_with_mapping (conf, SETTINGS_TIME_FORMAT_S,
- WIG ("show12HourRadio"), "active",
- G_SETTINGS_BIND_DEFAULT,
- bind_hours_get, bind_hours_set,
- GINT_TO_POINTER(TRUE), NULL);
- g_settings_bind_with_mapping (conf, SETTINGS_TIME_FORMAT_S,
- WIG ("show24HourRadio"), "active",
- G_SETTINGS_BIND_DEFAULT,
- bind_hours_get, bind_hours_set,
- GINT_TO_POINTER(FALSE), NULL);
- g_settings_bind (conf, SETTINGS_SHOW_CALENDAR_S, WIG ("showCalendarCheck"),
- "active", G_SETTINGS_BIND_DEFAULT);
- g_settings_bind (conf, SETTINGS_SHOW_WEEK_NUMBERS_S, WIG ("includeWeekNumbersCheck"),
- "active", G_SETTINGS_BIND_DEFAULT);
- g_settings_bind (conf, SETTINGS_SHOW_EVENTS_S, WIG ("showEventsCheck"),
- "active", G_SETTINGS_BIND_DEFAULT);
- g_settings_bind (conf, SETTINGS_SHOW_LOCATIONS_S, WIG ("showLocationsCheck"),
- "active", G_SETTINGS_BIND_DEFAULT);
-
- /* Set up sensitivities */
- add_widget_dependency (WIG ("showCalendarCheck"), WIG ("calendarOptions"));
- 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);
-
- setup_time_spinners (WIG ("timeSpinner"), WIG ("dateSpinner"));
-
- GtkWidget * dlg = WIG ("timeDateDialog");
- auto_radio = WIG ("automaticTimeRadio");
- 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);
-
- /* 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);
-
- /* 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,
- but that doesn't yet claim a name on the bus. Presumably the service
- would have been started by any such indicator, so this will at least tell
- 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"));
-
-#undef WIG
-
- g_object_unref (conf);
- g_object_unref (builder);
-
- return dlg;
-}
-
-static UniqueResponse
-message_received (UniqueApp * app, gint command, UniqueMessageData *message_data,
- guint time, gpointer user_data)
-{
- if (command == UNIQUE_ACTIVATE) {
- gtk_window_present_with_time (GTK_WINDOW (user_data), time);
- return UNIQUE_RESPONSE_OK;
- }
- return UNIQUE_RESPONSE_PASSTHROUGH;
-}
-
-int
-main (int argc, char ** argv)
-{
- g_type_init ();
-
- /* 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);
-
- 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);
- } else {
- // We're first instance. Yay!
- GtkWidget * dlg = create_dialog ();
-
- g_signal_connect (app, "message-received", G_CALLBACK(message_received), dlg);
- unique_app_watch_window (app, GTK_WINDOW (dlg));
-
- gtk_widget_show_all (dlg);
- g_signal_connect (dlg, "destroy", G_CALLBACK(gtk_main_quit), NULL);
- gtk_main ();
- }
-
- return 0;
-}
-
diff --git a/src/timezone-completion.c b/src/timezone-completion.c
deleted file mode 100644
index 7dcc28e..0000000
--- a/src/timezone-completion.c
+++ /dev/null
@@ -1,688 +0,0 @@
-/* -*- 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 <json-glib/json-glib.h>
-#include <gdk/gdk.h>
-#include <gdk/gdkkeysyms.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
-{
- GtkTreeModel * initial_model;
- GtkEntry * entry;
- guint queued_request;
- guint changed_id;
- guint keypress_id;
- GCancellable * cancel;
- gchar * request_text;
- GHashTable * request_table;
-};
-
-#define TIMEZONE_COMPLETION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), TIMEZONE_COMPLETION_TYPE, TimezoneCompletionPrivate))
-
-#define GEONAME_URL "http://geoname-lookup.ubuntu.com/?query=%s&release=%s&lang=%s"
-
-/* 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 gboolean
-match_func (GtkEntryCompletion *completion, const gchar *key,
- GtkTreeIter *iter, gpointer user_data)
-{
- // geonames does the work for us
- return TRUE;
-}
-
-static void
-save_and_use_model (TimezoneCompletion * completion, GtkTreeModel * model)
-{
- TimezoneCompletionPrivate * priv = TIMEZONE_COMPLETION_GET_PRIVATE(completion);
-
- g_hash_table_insert (priv->request_table, g_strdup (priv->request_text), g_object_ref_sink (model));
-
- if (model == priv->initial_model)
- gtk_entry_completion_set_match_func (GTK_ENTRY_COMPLETION (completion), NULL, NULL, NULL);
- else
- gtk_entry_completion_set_match_func (GTK_ENTRY_COMPLETION (completion), match_func, NULL, NULL);
-
- gtk_entry_completion_set_model (GTK_ENTRY_COMPLETION (completion), model);
-
- if (priv->entry != NULL) {
- gtk_entry_completion_complete (GTK_ENTRY_COMPLETION (completion));
-
- /* By this time, the changed signal has come and gone. We didn't give a
- model to use, so no popup appeared for user. Poke the entry again to show
- popup in 300ms. */
- g_signal_emit_by_name (priv->entry, "changed");
- }
-}
-
-static gint
-sort_zone (GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b,
- gpointer user_data)
-{
- /* Anything that has text as a prefix goes first, in mostly sorted order.
- Then everything else goes after, in mostly sorted order. */
- const gchar *casefolded_text = (const gchar *)user_data;
-
- const gchar *namea = NULL, *nameb = NULL;
- gtk_tree_model_get (model, a, TIMEZONE_COMPLETION_NAME, &namea, -1);
- gtk_tree_model_get (model, b, TIMEZONE_COMPLETION_NAME, &nameb, -1);
-
- gchar *casefolded_namea = NULL, *casefolded_nameb = NULL;
- casefolded_namea = g_utf8_casefold (namea, -1);
- casefolded_nameb = g_utf8_casefold (nameb, -1);
-
- gboolean amatches = FALSE, bmatches = FALSE;
- amatches = strncmp (casefolded_text, casefolded_namea, strlen(casefolded_text)) == 0;
- bmatches = strncmp (casefolded_text, casefolded_nameb, strlen(casefolded_text)) == 0;
-
- gint rv;
- if (amatches && !bmatches)
- rv = -1;
- else if (bmatches && !amatches)
- rv = 1;
- else
- rv = g_utf8_collate (casefolded_namea, casefolded_nameb);
-
- g_free (casefolded_namea);
- g_free (casefolded_nameb);
- return rv;
-}
-
-static void
-json_parse_ready (GObject *object, GAsyncResult *res, gpointer user_data)
-{
- TimezoneCompletion * completion = TIMEZONE_COMPLETION (user_data);
- TimezoneCompletionPrivate * priv = TIMEZONE_COMPLETION_GET_PRIVATE(completion);
- GError * error = NULL;
- const gchar * prev_name = NULL;
- const gchar * prev_admin1 = NULL;
- const gchar * prev_country = NULL;
-
- json_parser_load_from_stream_finish (JSON_PARSER (object), res, &error);
-
- if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED) && priv->cancel) {
- g_cancellable_reset (priv->cancel);
- }
-
- if (error != NULL) {
- if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
- save_and_use_model (completion, priv->initial_model);
- g_warning ("Could not parse geoname JSON data: %s", error->message);
- g_error_free (error);
- return;
- }
-
- GtkListStore * store = gtk_list_store_new (TIMEZONE_COMPLETION_LAST,
- G_TYPE_STRING,
- G_TYPE_STRING,
- G_TYPE_STRING,
- G_TYPE_STRING,
- G_TYPE_STRING,
- G_TYPE_STRING);
-
- JsonReader * reader = json_reader_new (json_parser_get_root (JSON_PARSER (object)));
-
- if (!json_reader_is_array (reader)) {
- g_warning ("Could not parse geoname JSON data");
- save_and_use_model (completion, priv->initial_model);
- g_object_unref (G_OBJECT (reader));
- return;
- }
-
- gint i, count = json_reader_count_elements (reader);
- for (i = 0; i < count; ++i) {
- if (!json_reader_read_element (reader, i))
- continue;
-
- if (json_reader_is_object (reader)) {
- const gchar * name = NULL;
- const gchar * admin1 = NULL;
- const gchar * country = NULL;
- const gchar * longitude = NULL;
- const gchar * latitude = NULL;
- gboolean skip = FALSE;
- if (json_reader_read_member (reader, "name")) {
- name = json_reader_get_string_value (reader);
- json_reader_end_member (reader);
- }
- if (json_reader_read_member (reader, "admin1")) {
- admin1 = json_reader_get_string_value (reader);
- json_reader_end_member (reader);
- }
- if (json_reader_read_member (reader, "country")) {
- country = json_reader_get_string_value (reader);
- json_reader_end_member (reader);
- }
- if (json_reader_read_member (reader, "longitude")) {
- longitude = json_reader_get_string_value (reader);
- json_reader_end_member (reader);
- }
- if (json_reader_read_member (reader, "latitude")) {
- latitude = json_reader_get_string_value (reader);
- json_reader_end_member (reader);
- }
-
- if (g_strcmp0(name, prev_name) == 0 &&
- g_strcmp0(admin1, prev_admin1) == 0 &&
- g_strcmp0(country, prev_country) == 0) {
- // Sometimes the data will have duplicate entries that only differ
- // in longitude and latitude. e.g. "rio de janeiro", "wellington"
- skip = TRUE;
- }
-
- if (!skip) {
- GtkTreeIter iter;
- gtk_list_store_append (store, &iter);
- gtk_list_store_set (store, &iter,
- TIMEZONE_COMPLETION_ZONE, NULL,
- TIMEZONE_COMPLETION_NAME, name,
- TIMEZONE_COMPLETION_ADMIN1, admin1,
- TIMEZONE_COMPLETION_COUNTRY, country,
- TIMEZONE_COMPLETION_LONGITUDE, longitude,
- TIMEZONE_COMPLETION_LATITUDE, latitude,
- -1);
- gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (store),
- TIMEZONE_COMPLETION_NAME, sort_zone,
- g_utf8_casefold(priv->request_text, -1),
- g_free);
- gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (store),
- TIMEZONE_COMPLETION_NAME,
- GTK_SORT_ASCENDING);
- }
-
- prev_name = name;
- prev_admin1 = admin1;
- prev_country = country;
- }
-
- json_reader_end_element (reader);
- }
-
- if (strlen (priv->request_text) < 4) {
- gchar * lower_text = g_ascii_strdown (priv->request_text, -1);
- if (g_strcmp0 (lower_text, "ut") == 0 ||
- g_strcmp0 (lower_text, "utc") == 0) {
- GtkTreeIter iter;
- gtk_list_store_append (store, &iter);
- gtk_list_store_set (store, &iter,
- TIMEZONE_COMPLETION_ZONE, "UTC",
- TIMEZONE_COMPLETION_NAME, "UTC",
- -1);
- }
- g_free (lower_text);
- }
-
- save_and_use_model (completion, GTK_TREE_MODEL (store));
- g_object_unref (G_OBJECT (reader));
-}
-
-static void
-geonames_data_ready (GObject *object, GAsyncResult *res, gpointer user_data)
-{
- TimezoneCompletion * completion = TIMEZONE_COMPLETION (user_data);
- TimezoneCompletionPrivate * priv = TIMEZONE_COMPLETION_GET_PRIVATE (completion);
- GError * error = NULL;
- GFileInputStream * stream;
-
- stream = g_file_read_finish (G_FILE (object), res, &error);
-
- if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED) && priv->cancel) {
- g_cancellable_reset (priv->cancel);
- }
-
- if (error != NULL) {
- if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
- save_and_use_model (completion, priv->initial_model);
- g_warning ("Could not connect to geoname lookup server: %s", error->message);
- g_error_free (error);
- return;
- }
-
- JsonParser * parser = json_parser_new ();
- json_parser_load_from_stream_async (parser, G_INPUT_STREAM (stream), priv->cancel,
- json_parse_ready, user_data);
-}
-
-/* Returns message locale, with possible country info too like en_US */
-static gchar *
-get_locale (void)
-{
- /* Check LANGUAGE, LC_ALL, LC_MESSAGES, and LANG, treat as colon-separated */
- const gchar *env_names[] = {"LANGUAGE", "LC_ALL", "LC_MESSAGES", "LANG", NULL};
- const gchar *env = NULL;
- gint i;
-
- for (i = 0; env_names[i]; i++) {
- env = g_getenv (env_names[i]);
- if (env != NULL && env[0] != 0)
- break;
- }
-
- if (env == NULL)
- return NULL;
-
- /* Now, we split on colons as expected, but also on . and @ to filter out
- extra pieces of locale we don't care about as we only use first chunk. */
- gchar **split = g_strsplit_set (env, ":.@", 2);
- if (split == NULL)
- return NULL;
-
- if (split[0] == NULL) {
- g_strfreev (split);
- return NULL;
- }
-
- gchar *locale = g_strdup (split[0]);
- g_strfreev (split);
- return locale;
-}
-
-static gchar *
-get_version (void)
-{
- static gchar *version = NULL;
-
- if (version == NULL) {
- gchar *stdout = NULL;
- g_spawn_command_line_sync ("lsb_release -rs", &stdout, NULL, NULL, NULL);
-
- if (stdout != NULL)
- version = g_strstrip (stdout);
- else
- version = g_strdup("");
- }
-
- return version;
-}
-
-static gboolean
-request_zones (TimezoneCompletion * completion)
-{
- TimezoneCompletionPrivate * priv = TIMEZONE_COMPLETION_GET_PRIVATE (completion);
-
- priv->queued_request = 0;
-
- if (priv->entry == NULL) {
- return FALSE;
- }
-
- /* Cancel any ongoing request */
- if (priv->cancel) {
- g_cancellable_cancel (priv->cancel);
- g_cancellable_reset (priv->cancel);
- }
- g_free (priv->request_text);
-
- const gchar * text = gtk_entry_get_text (priv->entry);
- priv->request_text = g_strdup (text);
-
- gchar * escaped = g_uri_escape_string (text, NULL, FALSE);
- gchar * version = get_version ();
- gchar * locale = get_locale ();
- gchar * url = g_strdup_printf (GEONAME_URL, escaped, version, locale);
- g_free (locale);
- g_free (version);
- g_free (escaped);
-
- GFile * file = g_file_new_for_uri (url);
- g_free (url);
-
- g_file_read_async (file, G_PRIORITY_DEFAULT, priv->cancel,
- geonames_data_ready, completion);
-
- return FALSE;
-}
-
-static void
-entry_changed (GtkEntry * entry, TimezoneCompletion * completion)
-{
- TimezoneCompletionPrivate * priv = TIMEZONE_COMPLETION_GET_PRIVATE (completion);
-
- if (priv->queued_request) {
- g_source_remove (priv->queued_request);
- priv->queued_request = 0;
- }
-
- /* See if we've already got this one */
- const gchar * text = gtk_entry_get_text (priv->entry);
- gpointer data;
- if (g_hash_table_lookup_extended (priv->request_table, text, NULL, &data)) {
- gtk_entry_completion_set_model (GTK_ENTRY_COMPLETION (completion), GTK_TREE_MODEL (data));
- }
- else {
- priv->queued_request = g_timeout_add (300, (GSourceFunc)request_zones, completion);
- gtk_entry_completion_set_model (GTK_ENTRY_COMPLETION (completion), NULL);
- }
- gtk_entry_completion_complete (GTK_ENTRY_COMPLETION (completion));
-}
-
-static GtkWidget *
-get_descendent (GtkWidget * parent, GType type)
-{
- if (g_type_is_a (G_OBJECT_TYPE (parent), type))
- return parent;
-
- if (GTK_IS_CONTAINER (parent)) {
- GList * children = gtk_container_get_children (GTK_CONTAINER (parent));
- GList * iter;
- for (iter = children; iter; iter = iter->next) {
- GtkWidget * found = get_descendent (GTK_WIDGET (iter->data), type);
- if (found) {
- g_list_free (children);
- return found;
- }
- }
- g_list_free (children);
- }
-
- return NULL;
-}
-
-/**
- * The popup window and its GtkTreeView are private to our parent completion
- * object. We can't get access to discover if there is a highlighted item or
- * even if the window is showing right now. So this is a super hack to find
- * it by looking through our toplevel's window group and finding a window with
- * a GtkTreeView that points at our model. There should be only one ever, so
- * we'll use the first one we find.
- */
-static GtkTreeView *
-find_popup_treeview (GtkWidget * widget, GtkTreeModel * model)
-{
- GtkWidget * toplevel = gtk_widget_get_toplevel (widget);
- if (!GTK_IS_WINDOW (toplevel))
- return NULL;
-
- GtkWindowGroup * group = gtk_window_get_group (GTK_WINDOW (toplevel));
- GList * windows = gtk_window_group_list_windows (group);
- GList * iter;
- for (iter = windows; iter; iter = iter->next) {
- if (iter->data == toplevel)
- continue; // Skip our own window, we don't have it
- GtkWidget * view = get_descendent (GTK_WIDGET (iter->data), GTK_TYPE_TREE_VIEW);
- if (view != NULL) {
- GtkTreeModel * tree_model = gtk_tree_view_get_model (GTK_TREE_VIEW (view));
- if (GTK_IS_TREE_MODEL_FILTER (tree_model))
- tree_model = gtk_tree_model_filter_get_model (GTK_TREE_MODEL_FILTER (tree_model));
- if (tree_model == model) {
- g_list_free (windows);
- return GTK_TREE_VIEW (view);
- }
- }
- }
- g_list_free (windows);
-
- return NULL;
-}
-
-static gboolean
-entry_keypress (GtkEntry * entry, GdkEventKey *event, TimezoneCompletion * completion)
-{
- if (event->keyval == GDK_ISO_Enter ||
- event->keyval == GDK_KP_Enter ||
- event->keyval == GDK_Return) {
- /* Make sure that user has a selection to choose, otherwise ignore */
- GtkTreeModel * model = gtk_entry_completion_get_model (GTK_ENTRY_COMPLETION (completion));
- GtkTreeView * view = find_popup_treeview (GTK_WIDGET (entry), model);
- if (view == NULL) {
- // Just beep if popup hasn't appeared yet.
- gtk_widget_error_bell (GTK_WIDGET (entry));
- return TRUE;
- }
-
- GtkTreeSelection * sel = gtk_tree_view_get_selection (view);
- GtkTreeModel * sel_model = NULL;
- if (!gtk_tree_selection_get_selected (sel, &sel_model, NULL)) {
- // No selection, we should help them out and select first item in list
- GtkTreeIter iter;
- if (gtk_tree_model_get_iter_first (sel_model, &iter))
- gtk_tree_selection_select_iter (sel, &iter);
- // And fall through to normal handler code
- }
- }
-
- return FALSE;
-}
-
-void
-timezone_completion_watch_entry (TimezoneCompletion * completion, GtkEntry * entry)
-{
- TimezoneCompletionPrivate * priv = TIMEZONE_COMPLETION_GET_PRIVATE (completion);
-
- if (priv->queued_request) {
- g_source_remove (priv->queued_request);
- priv->queued_request = 0;
- }
- if (priv->entry) {
- g_signal_handler_disconnect (priv->entry, priv->changed_id);
- g_signal_handler_disconnect (priv->entry, priv->keypress_id);
- 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;
-
- id = g_signal_connect (entry, "key-press-event", G_CALLBACK (entry_keypress), completion);
- priv->keypress_id = id;
-
- priv->entry = entry;
- g_object_add_weak_pointer (G_OBJECT (entry), (gpointer *)&priv->entry);
-
- gtk_entry_set_completion (entry, GTK_ENTRY_COMPLETION (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,
- 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);
- }
-
- GtkTreeIter iter;
- gtk_list_store_append (store, &iter);
- gtk_list_store_set (store, &iter,
- TIMEZONE_COMPLETION_ZONE, "UTC",
- TIMEZONE_COMPLETION_NAME, "UTC",
- -1);
-
- tz_db_free (db);
- return store;
-}
-
-static void
-data_func (GtkCellLayout *cell_layout, GtkCellRenderer *cell,
- GtkTreeModel *tree_model, GtkTreeIter *iter, gpointer user_data)
-{
- const gchar * name, * admin1, * country;
-
- gtk_tree_model_get (GTK_TREE_MODEL (tree_model), iter,
- TIMEZONE_COMPLETION_NAME, &name,
- TIMEZONE_COMPLETION_ADMIN1, &admin1,
- TIMEZONE_COMPLETION_COUNTRY, &country,
- -1);
-
- gchar * user_name;
- if (country == NULL || country[0] == 0) {
- user_name = g_strdup (name);
- } else if (admin1 == NULL || admin1[0] == 0) {
- user_name = g_strdup_printf ("%s <small>(%s)</small>", name, country);
- } else {
- user_name = g_strdup_printf ("%s <small>(%s, %s)</small>", name, admin1, country);
- }
-
- g_object_set (G_OBJECT (cell), "markup", user_name, NULL);
-}
-
-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)
-{
- TimezoneCompletionPrivate * priv = TIMEZONE_COMPLETION_GET_PRIVATE (self);
-
- priv->initial_model = GTK_TREE_MODEL (get_initial_model ());
-
- g_object_set (G_OBJECT (self),
- "text-column", TIMEZONE_COMPLETION_NAME,
- "popup-set-width", FALSE,
- NULL);
-
- priv->cancel = g_cancellable_new ();
-
- priv->request_table = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref);
-
- GtkCellRenderer * cell = gtk_cell_renderer_text_new ();
- gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (self), cell, TRUE);
- gtk_cell_layout_set_cell_data_func (GTK_CELL_LAYOUT (self), cell, data_func, NULL, NULL);
-
- return;
-}
-
-static void
-timezone_completion_dispose (GObject * object)
-{
- G_OBJECT_CLASS (timezone_completion_parent_class)->dispose (object);
-
- TimezoneCompletion * completion = TIMEZONE_COMPLETION (object);
- TimezoneCompletionPrivate * priv = TIMEZONE_COMPLETION_GET_PRIVATE (completion);
-
- if (priv->changed_id) {
- if (priv->entry)
- g_signal_handler_disconnect (priv->entry, priv->changed_id);
- priv->changed_id = 0;
- }
-
- if (priv->keypress_id) {
- if (priv->entry)
- g_signal_handler_disconnect (priv->entry, priv->keypress_id);
- priv->keypress_id = 0;
- }
-
- if (priv->entry != NULL) {
- g_object_remove_weak_pointer (G_OBJECT (priv->entry), (gpointer *)&priv->entry);
- }
-
- if (priv->initial_model != NULL) {
- g_object_unref (G_OBJECT (priv->initial_model));
- priv->initial_model = NULL;
- }
-
- if (priv->queued_request) {
- g_source_remove (priv->queued_request);
- priv->queued_request = 0;
- }
-
- if (priv->cancel != NULL) {
- g_cancellable_cancel (priv->cancel);
- g_object_unref (priv->cancel);
- priv->cancel = NULL;
- }
-
- if (priv->request_text != NULL) {
- g_free (priv->request_text);
- priv->request_text = NULL;
- }
-
- if (priv->request_table != NULL) {
- g_hash_table_destroy (priv->request_table);
- priv->request_table = NULL;
- }
-
- 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
deleted file mode 100644
index fdfb234..0000000
--- a/src/timezone-completion.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/* -*- 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_ADMIN1 2
-#define TIMEZONE_COMPLETION_COUNTRY 3
-#define TIMEZONE_COMPLETION_LONGITUDE 4
-#define TIMEZONE_COMPLETION_LATITUDE 5
-#define TIMEZONE_COMPLETION_LAST 6
-
-GType timezone_completion_get_type (void);
-TimezoneCompletion * timezone_completion_new ();
-void timezone_completion_watch_entry (TimezoneCompletion * completion, GtkEntry * entry);
-
-G_END_DECLS
-
-#endif /* __TIMEZONE_COMPLETION_H__ */
-