diff options
-rw-r--r-- | data/glade/libgweather.xml | 19 | ||||
-rw-r--r-- | data/meson.build | 6 | ||||
-rw-r--r-- | doc/libgweather.toml.in | 10 | ||||
-rw-r--r-- | doc/urlmap.js | 1 | ||||
-rw-r--r-- | libgweather/gweather-location-entry.c | 860 | ||||
-rw-r--r-- | libgweather/gweather-location-entry.h | 57 | ||||
-rw-r--r-- | libgweather/gweather-timezone-menu.c | 408 | ||||
-rw-r--r-- | libgweather/gweather-timezone-menu.h | 50 | ||||
-rw-r--r-- | libgweather/gweather.h | 2 | ||||
-rw-r--r-- | libgweather/meson.build | 10 | ||||
-rw-r--r-- | libgweather/tools/meson.build | 6 | ||||
-rw-r--r-- | libgweather/tools/test_locations.c | 72 | ||||
-rw-r--r-- | libgweather/tools/test_locations_utc.c | 75 | ||||
-rw-r--r-- | meson.build | 16 | ||||
-rw-r--r-- | meson_options.txt | 2 |
15 files changed, 9 insertions, 1585 deletions
diff --git a/data/glade/libgweather.xml b/data/glade/libgweather.xml deleted file mode 100644 index c6de8b3..0000000 --- a/data/glade/libgweather.xml +++ /dev/null @@ -1,19 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<glade-catalog version="3.0" name="libgweather" library="gweather-3" domain="libgweather-3.0" depends="gtk+" book="libgweather-3.0"> - <glade-widget-classes> - <glade-widget-class name="GWeatherLocationEntry" title="Location Entry" generic-name="locentry" get-type-function="gweather_location_entry_get_type"> - <!-- There are no editable properties, because GtkBuilder can't handle boxed types --> - </glade-widget-class> - - <glade-widget-class name="GWeatherTimezoneMenu" title="Timezone Menu" generic-name="tzmenu" get-type-function="gweather_timezone_menu_get_type"> - <properties> - <property id="tzid" name="Timezone" /> - </properties> - </glade-widget-class> - </glade-widget-classes> - - <glade-widget-group name="GWeather" title="GWeather"> - <glade-widget-class-ref name="GWeatherLocationEntry" /> - <glade-widget-class-ref name="GWeatherTimezoneMenu" /> - </glade-widget-group> -</glade-catalog> diff --git a/data/meson.build b/data/meson.build index 5e04c29..e25732d 100644 --- a/data/meson.build +++ b/data/meson.build @@ -1,9 +1,3 @@ -if enable_glade_catalog - install_data('glade/libgweather.xml', - install_dir: glade_catalogdir, - ) -endif - xmllint = find_program('xmllint', required: false) if xmllint.found() test('Valid Locations file', diff --git a/doc/libgweather.toml.in b/doc/libgweather.toml.in index 4199068..0baa11b 100644 --- a/doc/libgweather.toml.in +++ b/doc/libgweather.toml.in @@ -6,7 +6,7 @@ repository_url = "https://gitlab.gnome.org/GNOME/libgweather.git" authors = "The GWeather authors" license = "GPL-2.0-or-later" description = "Weather data collection" -dependencies = [ "GObject-2.0", "Gio-2.0", "Gtk-3.0" ] +dependencies = [ "GObject-2.0", "Gio-2.0", "GdkPixbuf-2.0" ] devhelp = true search_index = true @@ -20,10 +20,10 @@ search_index = true description = "GObject interfaces and objects" docs_url = "https://docs.gtk.org/gio/" - [dependencies."Gtk-3.0"] - name = "Gtk" - description = "The GTK toolkit" - docs_url = "https://docs.gtk.org/gtk3/" + [dependencies."GdkPixbuf-2.0"] + name = "GdkPixbuf" + description = "Image loading library" + docs_url = "https://docs.gtk.org/gdk-pixbuf/" [theme] name = "basic" diff --git a/doc/urlmap.js b/doc/urlmap.js index 04776e1..d9e4599 100644 --- a/doc/urlmap.js +++ b/doc/urlmap.js @@ -6,6 +6,5 @@ baseURLs = [ [ 'GLib', 'https://docs.gtk.org/glib/' ], [ 'GObject', 'https://docs.gtk.org/gobject/' ], [ 'Gio', 'https://docs.gtk.org/gio/' ], - [ 'Gtk', 'https://docs.gtk.org/gtk3/' ], [ 'GdkPixbuf', 'https://docs.gtk.org/gdk-pixbuf/' ], ] diff --git a/libgweather/gweather-location-entry.c b/libgweather/gweather-location-entry.c deleted file mode 100644 index d0a4e2b..0000000 --- a/libgweather/gweather-location-entry.c +++ /dev/null @@ -1,860 +0,0 @@ -/* gweather-location-entry.c - Location-selecting text entry - * - * SPDX-FileCopyrightText: 2008, Red Hat, Inc. - * SPDX-License-Identifier: LGPL-2.1-or-later - */ - -#include "config.h" - -#include "gweather-location-entry.h" - -#include "gweather-private.h" - -#include <string.h> -#include <gio/gio.h> -#include <geocode-glib/geocode-glib.h> - -/** - * GWeatherLocationEntry: - * - * A subclass of [class@Gtk.SearchEntry] that provides autocompletion on - * [struct@GWeather.Location]s. - */ - -struct _GWeatherLocationEntryPrivate { - GWeatherLocation *location; - GWeatherLocation *top; - gboolean show_named_timezones; - gboolean custom_text; - GCancellable *cancellable; - GtkTreeModel *model; -}; - -G_DEFINE_TYPE_WITH_PRIVATE (GWeatherLocationEntry, gweather_location_entry, GTK_TYPE_SEARCH_ENTRY) - -enum { - PROP_0, - - PROP_TOP, - PROP_SHOW_NAMED_TIMEZONES, - PROP_LOCATION, - - LAST_PROP -}; - -static void set_property (GObject *object, guint prop_id, - const GValue *value, GParamSpec *pspec); -static void get_property (GObject *object, guint prop_id, - GValue *value, GParamSpec *pspec); - -static void set_location_internal (GWeatherLocationEntry *entry, - GtkTreeModel *model, - GtkTreeIter *iter, - GWeatherLocation *loc); -static void -fill_location_entry_model (GtkListStore *store, GWeatherLocation *loc, - const char *parent_display_name, - const char *parent_sort_local_name, - const char *parent_compare_local_name, - const char *parent_compare_english_name, - gboolean show_named_timezones); - -enum LOC -{ - LOC_GWEATHER_LOCATION_ENTRY_COL_DISPLAY_NAME = 0, - LOC_GWEATHER_LOCATION_ENTRY_COL_LOCATION, - LOC_GWEATHER_LOCATION_ENTRY_COL_LOCAL_SORT_NAME, - LOC_GWEATHER_LOCATION_ENTRY_COL_LOCAL_COMPARE_NAME, - LOC_GWEATHER_LOCATION_ENTRY_COL_ENGLISH_COMPARE_NAME, - LOC_GWEATHER_LOCATION_ENTRY_NUM_COLUMNS -}; - -enum PLACE -{ - PLACE_GWEATHER_LOCATION_ENTRY_COL_DISPLAY_NAME = 0, - PLACE_GWEATHER_LOCATION_ENTRY_COL_PLACE, - PLACE_GWEATHER_LOCATION_ENTRY_COL_LOCAL_SORT_NAME, - PLACE_GWEATHER_LOCATION_ENTRY_COL_LOCAL_COMPARE_NAME -}; - -static gboolean matcher (GtkEntryCompletion *completion, const char *key, - GtkTreeIter *iter, gpointer user_data); -static gboolean match_selected (GtkEntryCompletion *completion, - GtkTreeModel *model, - GtkTreeIter *iter, - gpointer entry); -static void entry_changed (GWeatherLocationEntry *entry); -static void _no_matches (GtkEntryCompletion *completion, GWeatherLocationEntry *entry); - -static void -gweather_location_entry_init (GWeatherLocationEntry *entry) -{ - GtkEntryCompletion *completion; - GWeatherLocationEntryPrivate *priv; - - priv = entry->priv = gweather_location_entry_get_instance_private (entry); - - completion = gtk_entry_completion_new (); - - gtk_entry_completion_set_popup_set_width (completion, FALSE); - gtk_entry_completion_set_text_column (completion, LOC_GWEATHER_LOCATION_ENTRY_COL_DISPLAY_NAME); - gtk_entry_completion_set_match_func (completion, matcher, NULL, NULL); - gtk_entry_completion_set_inline_completion (completion, TRUE); - - g_signal_connect (completion, "match-selected", - G_CALLBACK (match_selected), entry); - - g_signal_connect (completion, "no-matches", - G_CALLBACK (_no_matches), entry); - - gtk_entry_set_completion (GTK_ENTRY (entry), completion); - g_object_unref (completion); - - priv->custom_text = FALSE; - g_signal_connect (entry, "changed", - G_CALLBACK (entry_changed), NULL); -} - -static void -finalize (GObject *object) -{ - GWeatherLocationEntry *entry; - GWeatherLocationEntryPrivate *priv; - - entry = GWEATHER_LOCATION_ENTRY (object); - priv = entry->priv; - - if (priv->location) - gweather_location_unref (priv->location); - if (priv->top) - gweather_location_unref (priv->top); - if (priv->model) - g_object_unref (priv->model); - - G_OBJECT_CLASS (gweather_location_entry_parent_class)->finalize (object); -} - -static void -dispose (GObject *object) -{ - GWeatherLocationEntry *entry; - GWeatherLocationEntryPrivate *priv; - - entry = GWEATHER_LOCATION_ENTRY (object); - priv = entry->priv; - - if (priv->cancellable) { - g_cancellable_cancel (priv->cancellable); - g_object_unref (priv->cancellable); - priv->cancellable = NULL; - } - - G_OBJECT_CLASS (gweather_location_entry_parent_class)->dispose (object); -} - -static int -tree_compare_local_name (GtkTreeModel *model, - GtkTreeIter *a, - GtkTreeIter *b, - gpointer user_data) -{ - g_autofree gchar *name_a = NULL, *name_b = NULL; - - gtk_tree_model_get (model, a, - LOC_GWEATHER_LOCATION_ENTRY_COL_LOCAL_SORT_NAME, &name_a, - -1); - gtk_tree_model_get (model, b, - LOC_GWEATHER_LOCATION_ENTRY_COL_LOCAL_SORT_NAME, &name_b, - -1); - - return g_utf8_collate (name_a, name_b); -} - - -static void -constructed (GObject *object) -{ - GWeatherLocationEntry *entry; - GtkListStore *store = NULL; - GtkEntryCompletion *completion; - - entry = GWEATHER_LOCATION_ENTRY (object); - - if (!entry->priv->top) - entry->priv->top = gweather_location_get_world (); - - store = gtk_list_store_new (5, G_TYPE_STRING, GWEATHER_TYPE_LOCATION, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING); - gtk_tree_sortable_set_default_sort_func (GTK_TREE_SORTABLE (store), - tree_compare_local_name, NULL, NULL); - fill_location_entry_model (store, entry->priv->top, NULL, NULL, NULL, NULL, entry->priv->show_named_timezones); - - entry->priv->model = GTK_TREE_MODEL (store); - completion = gtk_entry_get_completion (GTK_ENTRY (entry)); - gtk_entry_completion_set_match_func (completion, matcher, NULL, NULL); - gtk_entry_completion_set_model (completion, GTK_TREE_MODEL (store)); - - G_OBJECT_CLASS (gweather_location_entry_parent_class)->constructed (object); -} - -static void -gweather_location_entry_class_init (GWeatherLocationEntryClass *location_entry_class) -{ - GObjectClass *object_class = G_OBJECT_CLASS (location_entry_class); - - object_class->constructed = constructed; - object_class->finalize = finalize; - object_class->set_property = set_property; - object_class->get_property = get_property; - object_class->dispose = dispose; - - /* properties */ - g_object_class_install_property ( - object_class, PROP_TOP, - g_param_spec_boxed ("top", - "Top Location", - "The GWeatherLocation whose children will be used to fill in the entry", - GWEATHER_TYPE_LOCATION, - G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY)); - g_object_class_install_property ( - object_class, PROP_SHOW_NAMED_TIMEZONES, - g_param_spec_boolean ("show-named-timezones", - "Show named timezones", - "Whether UTC and other named timezones are shown in the list of locations", - FALSE, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); - g_object_class_install_property ( - object_class, PROP_LOCATION, - g_param_spec_boxed ("location", - "Location", - "The selected GWeatherLocation", - GWEATHER_TYPE_LOCATION, - G_PARAM_READWRITE)); -} - -static void -set_property (GObject *object, guint prop_id, - const GValue *value, GParamSpec *pspec) -{ - GWeatherLocationEntry *entry = GWEATHER_LOCATION_ENTRY (object); - - switch (prop_id) { - case PROP_TOP: - entry->priv->top = g_value_dup_boxed (value); - break; - case PROP_SHOW_NAMED_TIMEZONES: - entry->priv->show_named_timezones = g_value_get_boolean (value); - break; - case PROP_LOCATION: - gweather_location_entry_set_location (GWEATHER_LOCATION_ENTRY (object), - g_value_get_boxed (value)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -get_property (GObject *object, guint prop_id, - GValue *value, GParamSpec *pspec) -{ - GWeatherLocationEntry *entry = GWEATHER_LOCATION_ENTRY (object); - - switch (prop_id) { - case PROP_SHOW_NAMED_TIMEZONES: - g_value_set_boolean (value, entry->priv->show_named_timezones); - break; - case PROP_LOCATION: - g_value_set_boxed (value, entry->priv->location); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -entry_changed (GWeatherLocationEntry *entry) -{ - GtkEntryCompletion *completion; - const gchar *text; - - completion = gtk_entry_get_completion (GTK_ENTRY (entry)); - - if (entry->priv->cancellable) { - g_cancellable_cancel (entry->priv->cancellable); - g_object_unref (entry->priv->cancellable); - entry->priv->cancellable = NULL; - gtk_entry_completion_delete_action (completion, 0); - } - - gtk_entry_completion_set_match_func (gtk_entry_get_completion (GTK_ENTRY (entry)), matcher, NULL, NULL); - gtk_entry_completion_set_model (gtk_entry_get_completion (GTK_ENTRY (entry)), entry->priv->model); - - text = gtk_entry_get_text (GTK_ENTRY (entry)); - - if (text && *text) - entry->priv->custom_text = TRUE; - else - set_location_internal (entry, NULL, NULL, NULL); -} - -static void -set_location_internal (GWeatherLocationEntry *entry, - GtkTreeModel *model, - GtkTreeIter *iter, - GWeatherLocation *loc) -{ - GWeatherLocationEntryPrivate *priv; - char *name; - - priv = entry->priv; - - if (priv->location) - gweather_location_unref (priv->location); - - g_assert (iter == NULL || loc == NULL); - - if (iter) { - gtk_tree_model_get (model, iter, - LOC_GWEATHER_LOCATION_ENTRY_COL_DISPLAY_NAME, &name, - LOC_GWEATHER_LOCATION_ENTRY_COL_LOCATION, &priv->location, - -1); - gtk_entry_set_text (GTK_ENTRY (entry), name); - priv->custom_text = FALSE; - g_free (name); - } else if (loc) { - priv->location = gweather_location_ref (loc); - gtk_entry_set_text (GTK_ENTRY (entry), gweather_location_get_name (loc)); - priv->custom_text = FALSE; - } else { - priv->location = NULL; - gtk_entry_set_text (GTK_ENTRY (entry), ""); - priv->custom_text = TRUE; - } - - gtk_editable_set_position (GTK_EDITABLE (entry), -1); - g_object_notify (G_OBJECT (entry), "location"); -} - -/** - * gweather_location_entry_set_location: - * @entry: a #GWeatherLocationEntry - * @loc: (allow-none): a #GWeatherLocation in @entry, or %NULL to - * clear @entry - * - * Sets @entry's location to @loc, and updates the text of the - * entry accordingly. - * Note that if the database contains a location that compares - * equal to @loc, that will be chosen in place of @loc. - **/ -void -gweather_location_entry_set_location (GWeatherLocationEntry *entry, - GWeatherLocation *loc) -{ - GtkEntryCompletion *completion; - GtkTreeModel *model; - GtkTreeIter iter; - GWeatherLocation *cmploc; - - g_return_if_fail (GWEATHER_IS_LOCATION_ENTRY (entry)); - - completion = gtk_entry_get_completion (GTK_ENTRY (entry)); - model = gtk_entry_completion_get_model (completion); - - if (loc == NULL) { - set_location_internal (entry, model, NULL, NULL); - return; - } - - gtk_tree_model_get_iter_first (model, &iter); - do { - gtk_tree_model_get (model, &iter, - LOC_GWEATHER_LOCATION_ENTRY_COL_LOCATION, &cmploc, - -1); - if (gweather_location_equal (loc, cmploc)) { - set_location_internal (entry, model, &iter, NULL); - gweather_location_unref (cmploc); - return; - } - - gweather_location_unref (cmploc); - } while (gtk_tree_model_iter_next (model, &iter)); - - set_location_internal (entry, model, NULL, loc); -} - -/** - * gweather_location_entry_get_location: - * @entry: a #GWeatherLocationEntry - * - * Gets the location that was set by a previous call to - * gweather_location_entry_set_location() or was selected by the user. - * - * Return value: (transfer full) (allow-none): the selected location - * (which you must unref when you are done with it), or %NULL if no - * location is selected. - **/ -GWeatherLocation * -gweather_location_entry_get_location (GWeatherLocationEntry *entry) -{ - g_return_val_if_fail (GWEATHER_IS_LOCATION_ENTRY (entry), NULL); - - if (entry->priv->location) - return gweather_location_ref (entry->priv->location); - else - return NULL; -} - -/** - * gweather_location_entry_has_custom_text: - * @entry: a #GWeatherLocationEntry - * - * Checks whether or not @entry's text has been modified by the user. - * Note that this does not mean that no location is associated with @entry. - * gweather_location_entry_get_location() should be used for this. - * - * Return value: %TRUE if @entry's text was modified by the user, or %FALSE if - * it's set to the default text of a location. - **/ -gboolean -gweather_location_entry_has_custom_text (GWeatherLocationEntry *entry) -{ - g_return_val_if_fail (GWEATHER_IS_LOCATION_ENTRY (entry), FALSE); - - return entry->priv->custom_text; -} - -/** - * gweather_location_entry_set_city: - * @entry: a #GWeatherLocationEntry - * @city_name: (allow-none): the city name, or %NULL - * @code: the METAR station code - * - * Sets @entry's location to a city with the given @code, and given - * @city_name, if non-%NULL. If there is no matching city, sets - * @entry's location to %NULL. - * - * Return value: %TRUE if @entry's location could be set to a matching city, - * %FALSE otherwise. - **/ -gboolean -gweather_location_entry_set_city (GWeatherLocationEntry *entry, - const char *city_name, - const char *code) -{ - GtkEntryCompletion *completion; - GtkTreeModel *model; - GtkTreeIter iter; - GWeatherLocation *cmploc; - const char *cmpcode; - char *cmpname; - - g_return_val_if_fail (GWEATHER_IS_LOCATION_ENTRY (entry), FALSE); - g_return_val_if_fail (code != NULL, FALSE); - - completion = gtk_entry_get_completion (GTK_ENTRY (entry)); - model = gtk_entry_completion_get_model (completion); - - gtk_tree_model_get_iter_first (model, &iter); - do { - gtk_tree_model_get (model, &iter, - LOC_GWEATHER_LOCATION_ENTRY_COL_LOCATION, &cmploc, - -1); - - cmpcode = gweather_location_get_code (cmploc); - if (!cmpcode || strcmp (cmpcode, code) != 0) { - gweather_location_unref (cmploc); - continue; - } - - if (city_name) { - cmpname = gweather_location_get_city_name (cmploc); - if (!cmpname || strcmp (cmpname, city_name) != 0) { - gweather_location_unref (cmploc); - g_free (cmpname); - continue; - } - g_free (cmpname); - } - - set_location_internal (entry, model, &iter, NULL); - gweather_location_unref (cmploc); - return TRUE; - } while (gtk_tree_model_iter_next (model, &iter)); - - set_location_internal (entry, model, NULL, NULL); - - return FALSE; -} - -static void -fill_location_entry_model (GtkListStore *store, GWeatherLocation *loc, - const char *parent_display_name, - const char *parent_sort_local_name, - const char *parent_compare_local_name, - const char *parent_compare_english_name, - gboolean show_named_timezones) -{ - g_autoptr(GWeatherLocation) child = NULL; - char *display_name, *local_sort_name, *local_compare_name, *english_compare_name; - - switch (gweather_location_get_level (loc)) { - case GWEATHER_LOCATION_WORLD: - case GWEATHER_LOCATION_REGION: - /* Ignore these levels of hierarchy; just recurse, passing on - * the names from the parent node. - */ - while ((child = gweather_location_next_child (loc, child))) - fill_location_entry_model (store, child, - parent_display_name, - parent_sort_local_name, - parent_compare_local_name, - parent_compare_english_name, - show_named_timezones); - break; - - case GWEATHER_LOCATION_COUNTRY: - /* Recurse, initializing the names to the country name */ - while ((child = gweather_location_next_child (loc, child))) - fill_location_entry_model (store, child, - gweather_location_get_name (loc), - gweather_location_get_sort_name (loc), - gweather_location_get_sort_name (loc), - gweather_location_get_english_sort_name (loc), - show_named_timezones); - break; - - case GWEATHER_LOCATION_ADM1: - /* Recurse, adding the ADM1 name to the country name */ - /* Translators: this is the name of a location followed by a region, for example: - * 'London, United Kingdom' - * You shouldn't need to translate this string unless the language has a different comma. - */ - display_name = g_strdup_printf (_("%s, %s"), gweather_location_get_name (loc), parent_display_name); - local_sort_name = g_strdup_printf ("%s, %s", parent_sort_local_name, gweather_location_get_sort_name (loc)); - local_compare_name = g_strdup_printf ("%s, %s", gweather_location_get_sort_name (loc), parent_compare_local_name); - english_compare_name = g_strdup_printf ("%s, %s", gweather_location_get_english_sort_name (loc), parent_compare_english_name); - - while ((child = gweather_location_next_child (loc, child))) - fill_location_entry_model (store, child, - display_name, local_sort_name, local_compare_name, english_compare_name, - show_named_timezones); - - g_free (display_name); - g_free (local_compare_name); - g_free (english_compare_name); - break; - - case GWEATHER_LOCATION_CITY: - /* If there are multiple (<location>) children, we use the one - * closest to the city center. - * - * Locations are already sorted by increasing distance from - * the city. - */ - case GWEATHER_LOCATION_WEATHER_STATION: - /* <location> with no parent <city> */ - /* Translators: this is the name of a location followed by a region, for example: - * 'London, United Kingdom' - * You shouldn't need to translate this string unless the language has a different comma. - */ - display_name = g_strdup_printf (_("%s, %s"), - gweather_location_get_name (loc), parent_display_name); - local_sort_name = g_strdup_printf ("%s, %s", - parent_sort_local_name, gweather_location_get_sort_name (loc)); - local_compare_name = g_strdup_printf ("%s, %s", - gweather_location_get_sort_name (loc), parent_compare_local_name); - english_compare_name = g_strdup_printf ("%s, %s", - gweather_location_get_english_sort_name (loc), parent_compare_english_name); - - gtk_list_store_insert_with_values (store, NULL, -1, - LOC_GWEATHER_LOCATION_ENTRY_COL_LOCATION, loc, - LOC_GWEATHER_LOCATION_ENTRY_COL_DISPLAY_NAME, display_name, - LOC_GWEATHER_LOCATION_ENTRY_COL_LOCAL_SORT_NAME, local_sort_name, - LOC_GWEATHER_LOCATION_ENTRY_COL_LOCAL_COMPARE_NAME, local_compare_name, - LOC_GWEATHER_LOCATION_ENTRY_COL_ENGLISH_COMPARE_NAME, english_compare_name, - -1); - - g_free (display_name); - g_free (local_compare_name); - g_free (english_compare_name); - break; - - case GWEATHER_LOCATION_NAMED_TIMEZONE: - if (show_named_timezones) { - gtk_list_store_insert_with_values (store, NULL, -1, - LOC_GWEATHER_LOCATION_ENTRY_COL_LOCATION, loc, - LOC_GWEATHER_LOCATION_ENTRY_COL_DISPLAY_NAME, gweather_location_get_name (loc), - LOC_GWEATHER_LOCATION_ENTRY_COL_LOCAL_SORT_NAME, gweather_location_get_sort_name (loc), - LOC_GWEATHER_LOCATION_ENTRY_COL_LOCAL_COMPARE_NAME, gweather_location_get_sort_name (loc), - LOC_GWEATHER_LOCATION_ENTRY_COL_ENGLISH_COMPARE_NAME, gweather_location_get_english_sort_name (loc), - -1); - } - break; - - case GWEATHER_LOCATION_DETACHED: - g_assert_not_reached (); - } -} - -static char * -find_word (const char *full_name, const char *word, int word_len, - gboolean whole_word, gboolean is_first_word) -{ - char *p; - - if (word == NULL || *word == '\0') - return NULL; - - p = (char *)full_name - 1; - while ((p = strchr (p + 1, *word))) { - if (strncmp (p, word, word_len) != 0) - continue; - - if (p > (char *)full_name) { - char *prev = g_utf8_prev_char (p); - - /* Make sure p points to the start of a word */ - if (g_unichar_isalpha (g_utf8_get_char (prev))) - continue; - - /* If we're matching the first word of the key, it has to - * match the first word of the location, city, state, or - * country, or the abbreviation (in parenthesis). - * Eg, it either matches the start of the string - * (which we already know it doesn't at this point) or - * it is preceded by the string ", " or "(" (which isn't actually - * a perfect test. FIXME) - */ - if (is_first_word) { - if (prev == (char *)full_name || - ((prev - 1 <= full_name && strncmp (prev - 1, ", ", 2) != 0) - && *prev != '(')) - continue; - } - } - - if (whole_word && g_unichar_isalpha (g_utf8_get_char (p + word_len))) - continue; - - return p; - } - return NULL; -} - -static gboolean -match_compare_name (const char *key, const char *name) -{ - gboolean is_first_word = TRUE; - size_t len; - - /* Ignore whitespace before the string */ - key += strspn (key, " "); - - /* All but the last word in KEY must match a full word from NAME, - * in order (but possibly skipping some words from NAME). - */ - len = strcspn (key, " "); - while (key[len]) { - name = find_word (name, key, len, TRUE, is_first_word); - if (!name) - return FALSE; - - key += len; - while (*key && !g_unichar_isalpha (g_utf8_get_char (key))) - key = g_utf8_next_char (key); - while (*name && !g_unichar_isalpha (g_utf8_get_char (name))) - name = g_utf8_next_char (name); - - len = strcspn (key, " "); - is_first_word = FALSE; - } - - /* The last word in KEY must match a prefix of a following word in NAME */ - if (len == 0) { - return TRUE; - } else { - // if we get here, key[len] == 0, so... - g_assert (len == strlen(key)); - return find_word (name, key, len, FALSE, is_first_word) != NULL; - } -} - -static gboolean -matcher (GtkEntryCompletion *completion, const char *key, - GtkTreeIter *iter, gpointer user_data) -{ - char *local_compare_name, *english_compare_name; - gboolean match; - - gtk_tree_model_get (gtk_entry_completion_get_model (completion), iter, - LOC_GWEATHER_LOCATION_ENTRY_COL_LOCAL_COMPARE_NAME, &local_compare_name, - LOC_GWEATHER_LOCATION_ENTRY_COL_ENGLISH_COMPARE_NAME, &english_compare_name, - -1); - - match = match_compare_name (key, local_compare_name) || - match_compare_name (key, english_compare_name) || - g_ascii_strcasecmp (key, english_compare_name) == 0; - - g_free (local_compare_name); - g_free (english_compare_name); - return match; -} - -static gboolean -match_selected (GtkEntryCompletion *completion, - GtkTreeModel *model, - GtkTreeIter *iter, - gpointer entry) -{ - GWeatherLocationEntryPrivate *priv; - - priv = ((GWeatherLocationEntry *)entry)->priv; - - if (model != priv->model) { - GeocodePlace *place; - char *display_name; - GeocodeLocation *loc; - GWeatherLocation *location; - GWeatherLocation *scope = NULL; - const char* country_code; - - gtk_tree_model_get (model, iter, - PLACE_GWEATHER_LOCATION_ENTRY_COL_PLACE, &place, - PLACE_GWEATHER_LOCATION_ENTRY_COL_DISPLAY_NAME, &display_name, - -1); - - country_code = geocode_place_get_country_code (place); - if (country_code != NULL && gweather_location_get_level (priv->top) == GWEATHER_LOCATION_WORLD) - scope = gweather_location_find_by_country_code (priv->top, country_code); - if (!scope) - scope = priv->top; - - loc = geocode_place_get_location (place); - location = gweather_location_find_nearest_city (scope, geocode_location_get_latitude (loc), geocode_location_get_longitude (loc)); - - location = _gweather_location_new_detached (location, display_name, TRUE, - geocode_location_get_latitude (loc) * M_PI / 180.0, - geocode_location_get_longitude (loc) * M_PI / 180.0); - - set_location_internal (entry, model, NULL, location); - - g_object_unref (place); - g_free (display_name); - } else { - set_location_internal (entry, model, iter, NULL); - } - return TRUE; -} - -static gboolean -new_matcher (GtkEntryCompletion *completion, const char *key, - GtkTreeIter *iter, gpointer user_data) -{ - return TRUE; -} - -static void -fill_store (gpointer data, gpointer user_data) -{ - GeocodePlace *place = GEOCODE_PLACE (data); - GeocodeLocation *loc = geocode_place_get_location (place); - const char *display_name; - char *normalized; - char *compare_name; - - display_name = geocode_location_get_description (loc); - normalized = g_utf8_normalize (display_name, -1, G_NORMALIZE_ALL); - compare_name = g_utf8_casefold (normalized, -1); - - gtk_list_store_insert_with_values (user_data, NULL, -1, - PLACE_GWEATHER_LOCATION_ENTRY_COL_PLACE, place, - PLACE_GWEATHER_LOCATION_ENTRY_COL_DISPLAY_NAME, display_name, - PLACE_GWEATHER_LOCATION_ENTRY_COL_LOCAL_SORT_NAME, compare_name, - PLACE_GWEATHER_LOCATION_ENTRY_COL_LOCAL_COMPARE_NAME, compare_name, - -1); - - g_free (normalized); - g_free (compare_name); -} - -static void -_got_places (GObject *source_object, - GAsyncResult *result, - gpointer user_data) -{ - GList *places; - GWeatherLocationEntry *self = user_data; - GError *error = NULL; - GtkListStore *store = NULL; - GtkEntryCompletion *completion; - - places = geocode_forward_search_finish (GEOCODE_FORWARD (source_object), result, &error); - if (places == NULL) { - /* return without touching anything if cancelled (the entry might have been disposed) */ - if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { - g_clear_error (&error); - return; - } - - g_clear_error (&error); - completion = gtk_entry_get_completion (user_data); - gtk_entry_completion_set_match_func (completion, matcher, NULL, NULL); - gtk_entry_completion_set_model (completion, self->priv->model); - goto out; - } - - completion = gtk_entry_get_completion (user_data); - store = gtk_list_store_new (5, G_TYPE_STRING, GEOCODE_TYPE_PLACE, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING); - gtk_tree_sortable_set_default_sort_func (GTK_TREE_SORTABLE (store), - tree_compare_local_name, NULL, NULL); - g_list_foreach (places, fill_store, store); - g_list_free (places); - gtk_entry_completion_set_match_func (completion, new_matcher, NULL, NULL); - gtk_entry_completion_set_model (completion, GTK_TREE_MODEL (store)); - g_object_unref (store); - - out: - gtk_entry_completion_delete_action (completion, 0); - g_clear_object (&self->priv->cancellable); -} - -static void -_no_matches (GtkEntryCompletion *completion, GWeatherLocationEntry *entry) { - const gchar *key = gtk_entry_get_text(GTK_ENTRY (entry)); - GeocodeForward *forward; - - if (entry->priv->cancellable) { - g_cancellable_cancel (entry->priv->cancellable); - g_object_unref (entry->priv->cancellable); - entry->priv->cancellable = NULL; - } else { - gtk_entry_completion_insert_action_text (completion, 0, _("Loading…")); - } - - entry->priv->cancellable = g_cancellable_new (); - - forward = geocode_forward_new_for_string(key); - geocode_forward_search_async (forward, entry->priv->cancellable, _got_places, entry); -} - -/** - * gweather_location_entry_new: - * @top: the top-level location for the entry. - * - * Creates a new #GWeatherLocationEntry. - * - * @top will normally be the location returned from - * gweather_location_get_world(), but you can create an entry that - * only accepts a smaller set of locations if you want. - * - * Return value: the new #GWeatherLocationEntry - **/ -GtkWidget * -gweather_location_entry_new (GWeatherLocation *top) -{ - return g_object_new (GWEATHER_TYPE_LOCATION_ENTRY, - "top", top, - NULL); -} diff --git a/libgweather/gweather-location-entry.h b/libgweather/gweather-location-entry.h deleted file mode 100644 index ccd606c..0000000 --- a/libgweather/gweather-location-entry.h +++ /dev/null @@ -1,57 +0,0 @@ -/* gweather-location-entry.h - Location-selecting text entry - * - * SPDX-FileCopyrightText: 2008, Red Hat, Inc. - * SPDX-License-Identifier: GPL-2.0-or-later - */ - -#pragma once - -#if !(defined(IN_GWEATHER_H) || defined(GWEATHER_COMPILATION)) -#error "gweather-location-entry.h must not be included individually, include gweather.h instead" -#endif - -#include <gtk/gtk.h> -#include <libgweather/gweather-location.h> - -G_BEGIN_DECLS - -typedef struct _GWeatherLocationEntry GWeatherLocationEntry; -typedef struct _GWeatherLocationEntryClass GWeatherLocationEntryClass; -typedef struct _GWeatherLocationEntryPrivate GWeatherLocationEntryPrivate; - -#define GWEATHER_TYPE_LOCATION_ENTRY (gweather_location_entry_get_type ()) -#define GWEATHER_LOCATION_ENTRY(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GWEATHER_TYPE_LOCATION_ENTRY, GWeatherLocationEntry)) -#define GWEATHER_LOCATION_ENTRY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GWEATHER_TYPE_LOCATION_ENTRY, GWeatherLocationEntryClass)) -#define GWEATHER_IS_LOCATION_ENTRY(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GWEATHER_TYPE_LOCATION_ENTRY)) -#define GWEATHER_IS_LOCATION_ENTRY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GWEATHER_TYPE_LOCATION_ENTRY)) -#define GWEATHER_LOCATION_ENTRY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GWEATHER_TYPE_LOCATION_ENTRY, GWeatherLocationEntryClass)) - -struct _GWeatherLocationEntry { - GtkSearchEntry parent; - - /*< private >*/ - GWeatherLocationEntryPrivate *priv; -}; - -struct _GWeatherLocationEntryClass { - GtkSearchEntryClass parent_class; -}; - -GWEATHER_AVAILABLE_IN_ALL -GType gweather_location_entry_get_type (void); - -GWEATHER_AVAILABLE_IN_ALL -GtkWidget * gweather_location_entry_new (GWeatherLocation *top); -GWEATHER_AVAILABLE_IN_ALL -void gweather_location_entry_set_location (GWeatherLocationEntry *entry, - GWeatherLocation *loc); -GWEATHER_AVAILABLE_IN_ALL -GWeatherLocation * gweather_location_entry_get_location (GWeatherLocationEntry *entry); -GWEATHER_AVAILABLE_IN_ALL -gboolean gweather_location_entry_has_custom_text (GWeatherLocationEntry *entry); -GWEATHER_AVAILABLE_IN_ALL -gboolean gweather_location_entry_set_city (GWeatherLocationEntry *entry, - const char *city_name, - const char *code); - -G_END_DECLS diff --git a/libgweather/gweather-timezone-menu.c b/libgweather/gweather-timezone-menu.c deleted file mode 100644 index c2f5b99..0000000 --- a/libgweather/gweather-timezone-menu.c +++ /dev/null @@ -1,408 +0,0 @@ -/* gweather-timezone-menu.c - Timezone-selecting menu - * - * SPDX-FileCopyrightText: 2008, Red Hat, Inc. - * SPDX-License-Identifier: LGPL-2.1-or-later - */ - -#include "config.h" - -#include "gweather-timezone-menu.h" - -#include "gweather-private.h" - -#include <string.h> - -/** - * GWeatherTimezoneMenu: - * - * A [class@Gtk.ComboBox] subclass for choosing a [struct@GWeather.Timezone]. - */ - -G_DEFINE_TYPE (GWeatherTimezoneMenu, gweather_timezone_menu, GTK_TYPE_COMBO_BOX) - -enum { - PROP_0, - - PROP_TOP, - PROP_TZID, - - LAST_PROP -}; - -static void set_property (GObject *object, guint prop_id, - const GValue *value, GParamSpec *pspec); -static void get_property (GObject *object, guint prop_id, - GValue *value, GParamSpec *pspec); - -static void changed (GtkComboBox *combo); - -static GtkTreeModel *gweather_timezone_model_new (GWeatherLocation *top); -static gboolean row_separator_func (GtkTreeModel *model, GtkTreeIter *iter, - gpointer data); -static void is_sensitive (GtkCellLayout *cell_layout, GtkCellRenderer *cell, - GtkTreeModel *tree_model, GtkTreeIter *iter, gpointer data); - -static void -gweather_timezone_menu_init (GWeatherTimezoneMenu *menu) -{ - GtkCellRenderer *renderer; - - gtk_combo_box_set_row_separator_func (GTK_COMBO_BOX (menu), - row_separator_func, NULL, NULL); - - renderer = gtk_cell_renderer_text_new (); - gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (menu), renderer, TRUE); - gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (menu), renderer, - "markup", 0, - NULL); - gtk_cell_layout_set_cell_data_func (GTK_CELL_LAYOUT (menu), - renderer, is_sensitive, NULL, NULL); -} - -static void -finalize (GObject *object) -{ - GWeatherTimezoneMenu *menu = GWEATHER_TIMEZONE_MENU (object); - - if (menu->zone) - gweather_timezone_unref (menu->zone); - - G_OBJECT_CLASS (gweather_timezone_menu_parent_class)->finalize (object); -} - -static void -gweather_timezone_menu_class_init (GWeatherTimezoneMenuClass *timezone_menu_class) -{ - GObjectClass *object_class = G_OBJECT_CLASS (timezone_menu_class); - GtkComboBoxClass *combo_class = GTK_COMBO_BOX_CLASS (timezone_menu_class); - - object_class->finalize = finalize; - object_class->set_property = set_property; - object_class->get_property = get_property; - - combo_class->changed = changed; - - /* properties */ - g_object_class_install_property ( - object_class, PROP_TOP, - g_param_spec_boxed ("top", - "Top Location", - "The GWeatherLocation whose children will be used to fill in the menu", - GWEATHER_TYPE_LOCATION, - G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY)); - g_object_class_install_property ( - object_class, PROP_TZID, - g_param_spec_string ("tzid", - "TZID", - "The selected TZID", - NULL, - G_PARAM_READWRITE)); -} - -static void -set_property (GObject *object, guint prop_id, - const GValue *value, GParamSpec *pspec) -{ - GtkTreeModel *model; - - switch (prop_id) { - case PROP_TOP: - model = gweather_timezone_model_new (g_value_get_boxed (value)); - gtk_combo_box_set_model (GTK_COMBO_BOX (object), model); - g_object_unref (model); - gtk_combo_box_set_active (GTK_COMBO_BOX (object), 0); - break; - - case PROP_TZID: - gweather_timezone_menu_set_tzid (GWEATHER_TIMEZONE_MENU (object), - g_value_get_string (value)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -get_property (GObject *object, guint prop_id, - GValue *value, GParamSpec *pspec) -{ - GWeatherTimezoneMenu *menu = GWEATHER_TIMEZONE_MENU (object); - - switch (prop_id) { - case PROP_TZID: - g_value_set_string (value, gweather_timezone_menu_get_tzid (menu)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -enum { - GWEATHER_TIMEZONE_MENU_NAME, - GWEATHER_TIMEZONE_MENU_ZONE -}; - -static void -changed (GtkComboBox *combo) -{ - GWeatherTimezoneMenu *menu = GWEATHER_TIMEZONE_MENU (combo); - GtkTreeIter iter; - - if (menu->zone) - gweather_timezone_unref (menu->zone); - - gtk_combo_box_get_active_iter (combo, &iter); - gtk_tree_model_get (gtk_combo_box_get_model (combo), &iter, - GWEATHER_TIMEZONE_MENU_ZONE, &menu->zone, - -1); - - g_object_notify (G_OBJECT (combo), "tzid"); -} - -static void -append_offset (GString *desc, int offset) -{ - int hours, minutes; - - hours = offset / 60; - minutes = (offset > 0) ? offset % 60 : -offset % 60; - - if (minutes) - g_string_append_printf (desc, "GMT%+d:%02d", hours, minutes); - else if (hours) - g_string_append_printf (desc, "GMT%+d", hours); - else - g_string_append (desc, "GMT"); -} - -static char * -get_offset (GWeatherTimezone *zone) -{ - GString *desc; - - desc = g_string_new (NULL); - append_offset (desc, gweather_timezone_get_offset (zone)); - if (gweather_timezone_has_dst (zone)) { - g_string_append (desc, " / "); - append_offset (desc, gweather_timezone_get_dst_offset (zone)); - } - return g_string_free (desc, FALSE); -} - -static void -insert_location (GtkTreeStore *store, GWeatherTimezone *zone, const char *loc_name, GtkTreeIter *parent) -{ - GtkTreeIter iter; - char *name, *offset; - - offset = get_offset (zone); - name = g_strdup_printf ("%s <small>(%s)</small>", - loc_name ? loc_name : gweather_timezone_get_name (zone), - offset); - gtk_tree_store_append (store, &iter, parent); - gtk_tree_store_set (store, &iter, - GWEATHER_TIMEZONE_MENU_NAME, name, - GWEATHER_TIMEZONE_MENU_ZONE, zone, - -1); - g_free (name); - g_free (offset); -} - -static void -insert_locations (GtkTreeStore *store, GWeatherLocation *loc) -{ - int i; - - if (gweather_location_get_level (loc) < GWEATHER_LOCATION_COUNTRY) { - GWeatherLocation **children; - - G_GNUC_BEGIN_IGNORE_DEPRECATIONS - - children = gweather_location_get_children (loc); - for (i = 0; children[i]; i++) - insert_locations (store, children[i]); - - G_GNUC_END_IGNORE_DEPRECATIONS - } else { - GWeatherTimezone **zones; - GtkTreeIter iter; - - zones = gweather_location_get_timezones (loc); - if (zones[1]) { - gtk_tree_store_append (store, &iter, NULL); - gtk_tree_store_set (store, &iter, - GWEATHER_TIMEZONE_MENU_NAME, gweather_location_get_name (loc), - -1); - - for (i = 0; zones[i]; i++) { - insert_location (store, zones[i], NULL, &iter); - } - } else if (zones[0]) { - insert_location (store, zones[0], gweather_location_get_name (loc), NULL); - } - - gweather_location_free_timezones (loc, zones); - } -} - -static GtkTreeModel * -gweather_timezone_model_new (GWeatherLocation *top) -{ - g_autoptr(GWeatherLocation) world = NULL; - GtkTreeStore *store; - GtkTreeModel *model; - GtkTreeIter iter; - char *unknown; - GWeatherTimezone *utc; - - store = gtk_tree_store_new (2, G_TYPE_STRING, GWEATHER_TYPE_TIMEZONE); - model = GTK_TREE_MODEL (store); - - unknown = g_markup_printf_escaped ("<i>%s</i>", C_("timezone", "Unknown")); - - gtk_tree_store_append (store, &iter, NULL); - gtk_tree_store_set (store, &iter, - GWEATHER_TIMEZONE_MENU_NAME, unknown, - GWEATHER_TIMEZONE_MENU_ZONE, NULL, - -1); - - utc = gweather_timezone_get_utc (); - if (utc) { - insert_location (store, utc, NULL, NULL); - gweather_timezone_unref (utc); - } - - gtk_tree_store_append (store, &iter, NULL); - - g_free (unknown); - - if (!top) - top = world = gweather_location_get_world (); - - insert_locations (store, top); - - return model; -} - -static gboolean -row_separator_func (GtkTreeModel *model, GtkTreeIter *iter, gpointer data) -{ - char *name; - - gtk_tree_model_get (model, iter, - GWEATHER_TIMEZONE_MENU_NAME, &name, - -1); - if (name) { - g_free (name); - return FALSE; - } else - return TRUE; -} - -static void -is_sensitive (GtkCellLayout *cell_layout, GtkCellRenderer *cell, - GtkTreeModel *tree_model, GtkTreeIter *iter, gpointer data) -{ - gboolean sensitive; - - sensitive = !gtk_tree_model_iter_has_child (tree_model, iter); - g_object_set (cell, "sensitive", sensitive, NULL); -} - -/** - * gweather_timezone_menu_new: - * @top: the top-level location for the menu. - * - * Creates a new #GWeatherTimezoneMenu. - * - * @top will normally be the location returned from - * gweather_location_get_world(), but you can create a menu that - * contains the timezones from a smaller set of locations if you want. - * - * Return value: the new #GWeatherTimezoneMenu - **/ -GtkWidget * -gweather_timezone_menu_new (GWeatherLocation *top) -{ - return g_object_new (GWEATHER_TYPE_TIMEZONE_MENU, - "top", top, - NULL); -} - -typedef struct { - GtkComboBox *combo; - const char *tzid; -} SetTimezoneData; - -static gboolean -check_tzid (GtkTreeModel *model, GtkTreePath *path, - GtkTreeIter *iter, gpointer data) -{ - SetTimezoneData *tzd = data; - GWeatherTimezone *zone; - gboolean ok; - - gtk_tree_model_get (model, iter, - GWEATHER_TIMEZONE_MENU_ZONE, &zone, - -1); - if (!zone) - return FALSE; - - if (!strcmp (gweather_timezone_get_tzid (zone), tzd->tzid)) { - gtk_combo_box_set_active_iter (tzd->combo, iter); - ok = TRUE; - } else - ok = FALSE; - - gweather_timezone_unref (zone); - return ok; -} - -/** - * gweather_timezone_menu_set_tzid: - * @menu: a #GWeatherTimezoneMenu - * @tzid: (allow-none): a tzdata id (eg, "America/New_York") - * - * Sets @menu to the given @tzid. If @tzid is %NULL, sets @menu to - * "Unknown". - **/ -void -gweather_timezone_menu_set_tzid (GWeatherTimezoneMenu *menu, - const char *tzid) -{ - SetTimezoneData tzd; - - g_return_if_fail (GWEATHER_IS_TIMEZONE_MENU (menu)); - - if (!tzid) { - gtk_combo_box_set_active (GTK_COMBO_BOX (menu), 0); - return; - } - - tzd.combo = GTK_COMBO_BOX (menu); - tzd.tzid = tzid; - gtk_tree_model_foreach (gtk_combo_box_get_model (tzd.combo), - check_tzid, &tzd); -} - -/** - * gweather_timezone_menu_get_tzid: - * @menu: a #GWeatherTimezoneMenu - * - * Gets @menu's timezone id. - * - * Return value: (allow-none): @menu's tzid, or %NULL if no timezone - * is selected. - **/ -const char * -gweather_timezone_menu_get_tzid (GWeatherTimezoneMenu *menu) -{ - g_return_val_if_fail (GWEATHER_IS_TIMEZONE_MENU (menu), NULL); - - if (!menu->zone) - return NULL; - return gweather_timezone_get_tzid (menu->zone); -} - diff --git a/libgweather/gweather-timezone-menu.h b/libgweather/gweather-timezone-menu.h deleted file mode 100644 index 884f32a..0000000 --- a/libgweather/gweather-timezone-menu.h +++ /dev/null @@ -1,50 +0,0 @@ -/* gweather-timezone-menu.h - Timezone-selecting menu - * - * SPDX-FileCopyrightText: 2008, Red Hat, Inc. - * SPDX-License-Identifier: GPL-2.0-or-later - */ - -#pragma once - -#if !(defined(IN_GWEATHER_H) || defined(GWEATHER_COMPILATION)) -#error "gweather-timezone-menu.h must not be included individually, include gweather.h instead" -#endif - -#include <gtk/gtk.h> -#include <libgweather/gweather-location.h> - -G_BEGIN_DECLS - -typedef struct _GWeatherTimezoneMenu GWeatherTimezoneMenu; -typedef struct _GWeatherTimezoneMenuClass GWeatherTimezoneMenuClass; - -#define GWEATHER_TYPE_TIMEZONE_MENU (gweather_timezone_menu_get_type ()) -#define GWEATHER_TIMEZONE_MENU(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GWEATHER_TYPE_TIMEZONE_MENU, GWeatherTimezoneMenu)) -#define GWEATHER_TIMEZONE_MENU_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GWEATHER_TYPE_TIMEZONE_MENU, GWeatherTimezoneMenuClass)) -#define GWEATHER_IS_TIMEZONE_MENU(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GWEATHER_TYPE_TIMEZONE_MENU)) -#define GWEATHER_IS_TIMEZONE_MENU_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GWEATHER_TYPE_TIMEZONE_MENU)) -#define GWEATHER_TIMEZONE_MENU_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GWEATHER_TYPE_TIMEZONE_MENU, GWeatherTimezoneMenuClass)) - -struct _GWeatherTimezoneMenu { - GtkComboBox parent; - - /*< private >*/ - GWeatherTimezone *zone; -}; - -struct _GWeatherTimezoneMenuClass { - GtkComboBoxClass parent_class; - -}; - -GWEATHER_AVAILABLE_IN_ALL -GType gweather_timezone_menu_get_type (void); -GWEATHER_AVAILABLE_IN_ALL -GtkWidget * gweather_timezone_menu_new (GWeatherLocation *top); -GWEATHER_AVAILABLE_IN_ALL -void gweather_timezone_menu_set_tzid (GWeatherTimezoneMenu *menu, - const char *tzid); -GWEATHER_AVAILABLE_IN_ALL -const char * gweather_timezone_menu_get_tzid (GWeatherTimezoneMenu *menu); - -G_END_DECLS diff --git a/libgweather/gweather.h b/libgweather/gweather.h index 131f311..04a5506 100644 --- a/libgweather/gweather.h +++ b/libgweather/gweather.h @@ -15,7 +15,5 @@ #include <libgweather/gweather-location.h> #include <libgweather/gweather-timezone.h> #include <libgweather/gweather-weather.h> -#include <libgweather/gweather-location-entry.h> -#include <libgweather/gweather-timezone-menu.h> #undef IN_GWEATHER_H diff --git a/libgweather/meson.build b/libgweather/meson.build index ccd8995..944c08e 100644 --- a/libgweather/meson.build +++ b/libgweather/meson.build @@ -96,7 +96,7 @@ configure_file( deps_libgweather = [ dependency('gio-2.0', version: glib_req_version), - dependency('gtk+-3.0', version: gtk_req_version), + dependency('gdk-pixbuf-2.0'), dependency('libsoup-2.4', version: libsoup_req_version), dependency('libxml-2.0', version: libxml_req_version), dependency('geocode-glib-1.0'), @@ -106,9 +106,7 @@ deps_libgweather = [ gweather_headers = [ 'gweather-location.h', - 'gweather-location-entry.h', 'gweather-timezone.h', - 'gweather-timezone-menu.h', 'gweather-weather.h', 'gweather-enums.h' ] @@ -129,8 +127,6 @@ gweather_c_sources = [ 'gweather-weather.c', 'gweather-location.c', 'gweather-timezone.c', - 'gweather-location-entry.c', - 'gweather-timezone-menu.c', ] gweather_priv_sources = [ @@ -196,7 +192,7 @@ if build_gir dependencies: deps_libgweather, nsversion: libgweather_api_version, namespace: 'GWeather', - includes: ['GObject-2.0', 'Gtk-3.0'], + includes: ['Gio-2.0', 'GdkPixbuf-2.0'], symbol_prefix: 'gweather', identifier_prefix: 'GWeather', export_packages: 'gweather-' + libgweather_api_version, @@ -225,7 +221,7 @@ libgweather_dep = declare_dependency( if build_vapi and build_gir gnome.generate_vapi('gweather-' + libgweather_api_version, sources: gweather_gir[0], - packages: ['gobject-2.0', 'gtk+-3.0'], + packages: ['gio-2.0', 'gdk-pixbuf-2.0'], metadata_dirs: '.', install: true, ) diff --git a/libgweather/tools/meson.build b/libgweather/tools/meson.build index c1f63c6..b50e194 100644 --- a/libgweather/tools/meson.build +++ b/libgweather/tools/meson.build @@ -1,11 +1,5 @@ tools = [ { - 'name': 'locations', - }, - { - 'name': 'locations_utc', - }, - { 'name': 'metar', }, { diff --git a/libgweather/tools/test_locations.c b/libgweather/tools/test_locations.c deleted file mode 100644 index c930101..0000000 --- a/libgweather/tools/test_locations.c +++ /dev/null @@ -1,72 +0,0 @@ -/* test_locations.c: Test GWeatherLocationEntry - * - * SPDX-FileCopyrightText: The GWeather authors - * SPDX-License-Identifier: GPL-2.0-or-later - */ - -#include <gtk/gtk.h> -#include <libgweather/gweather.h> - -static void -deleted (GtkWidget *widget, GdkEvent *event, gpointer data) -{ - gtk_main_quit (); -} - -static void -location_changed (GObject *object, GParamSpec *param, gpointer tzmenu) -{ - GWeatherLocationEntry *entry = GWEATHER_LOCATION_ENTRY (object); - GWeatherLocation *loc; - GWeatherTimezone *zone; - - loc = gweather_location_entry_get_location (entry); - if (loc == NULL) - return; - - zone = gweather_location_get_timezone (loc); - if (zone) - gweather_timezone_menu_set_tzid (tzmenu, gweather_timezone_get_tzid (zone)); - else - gweather_timezone_menu_set_tzid (tzmenu, NULL); - if (zone) - gweather_timezone_unref (zone); - gweather_location_unref (loc); -} - -int -main (int argc, char **argv) -{ - GtkWidget *window, *vbox, *entry; - GtkWidget *combo; - gtk_init (&argc, &argv); - - g_setenv ("LIBGWEATHER_LOCATIONS_PATH", - TEST_LOCATIONS, - FALSE); - - window = gtk_window_new (GTK_WINDOW_TOPLEVEL); - gtk_window_set_title (GTK_WINDOW (window), "location"); - gtk_container_set_border_width (GTK_CONTAINER (window), 8); - g_signal_connect (window, "delete-event", - G_CALLBACK (deleted), NULL); - - vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 8); - gtk_container_add (GTK_CONTAINER (window), vbox); - - entry = gweather_location_entry_new (NULL); - gtk_widget_set_size_request (entry, 400, -1); - gtk_box_pack_start (GTK_BOX (vbox), entry, FALSE, TRUE, 0); - - combo = gweather_timezone_menu_new (NULL); - gtk_box_pack_start (GTK_BOX (vbox), combo, FALSE, TRUE, 0); - - g_signal_connect (entry, "notify::location", - G_CALLBACK (location_changed), combo); - - gtk_widget_show_all (window); - - gtk_main (); - - return 0; -} diff --git a/libgweather/tools/test_locations_utc.c b/libgweather/tools/test_locations_utc.c deleted file mode 100644 index 105f1ed..0000000 --- a/libgweather/tools/test_locations_utc.c +++ /dev/null @@ -1,75 +0,0 @@ -/* test_locations_utc.c: Test GWeatherLocationEntry with UTC time zone - * - * SPDX-FileCopyrightText: The GWeather authors - * SPDX-License-Identifier: GPL-2.0-or-later - */ - -#include <gtk/gtk.h> -#include <libgweather/gweather.h> - -static void -deleted (GtkWidget *widget, GdkEvent *event, gpointer data) -{ - gtk_main_quit (); -} - -static void -location_changed (GObject *object, GParamSpec *param, gpointer tzmenu) -{ - GWeatherLocationEntry *entry = GWEATHER_LOCATION_ENTRY (object); - GWeatherLocation *loc; - GWeatherTimezone *zone; - - loc = gweather_location_entry_get_location (entry); - if (loc == NULL) - return; - - zone = gweather_location_get_timezone (loc); - if (zone) - gweather_timezone_menu_set_tzid (tzmenu, gweather_timezone_get_tzid (zone)); - else - gweather_timezone_menu_set_tzid (tzmenu, NULL); - if (zone) - gweather_timezone_unref (zone); - gweather_location_unref (loc); -} - -int -main (int argc, char **argv) -{ - GtkWidget *window, *vbox, *entry; - GtkWidget *combo; - - gtk_init (&argc, &argv); - - g_setenv ("LIBGWEATHER_LOCATIONS_PATH", - TEST_LOCATIONS, - FALSE); - - window = gtk_window_new (GTK_WINDOW_TOPLEVEL); - gtk_window_set_title (GTK_WINDOW (window), "location"); - gtk_container_set_border_width (GTK_CONTAINER (window), 8); - g_signal_connect (window, "delete-event", - G_CALLBACK (deleted), NULL); - - vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 8); - gtk_container_add (GTK_CONTAINER (window), vbox); - - entry = g_object_new (GWEATHER_TYPE_LOCATION_ENTRY, - "show-named-timezones", TRUE, - NULL); - gtk_widget_set_size_request (entry, 400, -1); - gtk_box_pack_start (GTK_BOX (vbox), entry, FALSE, TRUE, 0); - - combo = gweather_timezone_menu_new (NULL); - gtk_box_pack_start (GTK_BOX (vbox), combo, FALSE, TRUE, 0); - - g_signal_connect (entry, "notify::location", - G_CALLBACK (location_changed), combo); - - gtk_widget_show_all (window); - - gtk_main (); - - return 0; -} diff --git a/meson.build b/meson.build index 774342d..989b3c9 100644 --- a/meson.build +++ b/meson.build @@ -30,7 +30,6 @@ pkgdatadir = datadir / 'libgweather' pkglibdir = libdir / 'libgweather' glib_req_version = '>= 2.44.0' -gtk_req_version = '>= 3.13.5' libsoup_req_version = '>= 2.44.0' libxml_req_version = '>= 2.6.0' @@ -45,16 +44,6 @@ pylint_flags = [ '-d', 'C0326', ] -if get_option('glade_catalog') == 'false' - enable_glade_catalog = false -else - glade_dep = dependency('gladeui-2.0', required: get_option('glade_catalog') == 'true') - enable_glade_catalog = glade_dep.found() - if enable_glade_catalog - glade_catalogdir = datadir / 'glade/catalogs' - endif -endif - gen_locations_variant = find_program('build-aux/meson/gen_locations_variant.py') subdir('data') @@ -73,11 +62,9 @@ pkgconfig.generate( version: meson.project_version(), libraries: lib_libgweather, subdirs: libgweather_full_version, - requires: [ - 'gtk+-3.0', - ], requires_private: [ 'gio-2.0', + 'gdk-pixbuf-2.0', 'libsoup-2.4', 'libxml-2.0', 'geocode-glib-1.0', @@ -96,7 +83,6 @@ summary({ summary({ 'Debug': get_option('debug'), 'Optimization': get_option('optimization'), - 'Glade catalog': enable_glade_catalog, 'Introspection': build_gir, 'Generate VAPI': build_vapi, 'API reference': get_option('gtk_doc'), diff --git a/meson_options.txt b/meson_options.txt index 9957f09..0e354da 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -2,8 +2,6 @@ option('zoneinfo_dir', type: 'string', value: '/usr/share/zoneinfo', description: 'zoneinfo directory') option('owm_apikey', type: 'string', value: '', description: 'Specify an API key for OpenWeatherMap (optional)') -option('glade_catalog', type: 'combo', choices : ['true', 'false', 'auto'], value : 'auto', - description: 'Install a glade catalog file') option('enable_vala', type: 'combo', choices : ['true', 'false', 'auto'], value : 'auto', description: 'Install vala bindings') option('gtk_doc', type: 'boolean', value: true, |