summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--data/glade/libgweather.xml19
-rw-r--r--data/meson.build6
-rw-r--r--doc/libgweather.toml.in10
-rw-r--r--doc/urlmap.js1
-rw-r--r--libgweather/gweather-location-entry.c860
-rw-r--r--libgweather/gweather-location-entry.h57
-rw-r--r--libgweather/gweather-timezone-menu.c408
-rw-r--r--libgweather/gweather-timezone-menu.h50
-rw-r--r--libgweather/gweather.h2
-rw-r--r--libgweather/meson.build10
-rw-r--r--libgweather/tools/meson.build6
-rw-r--r--libgweather/tools/test_locations.c72
-rw-r--r--libgweather/tools/test_locations_utc.c75
-rw-r--r--meson.build16
-rw-r--r--meson_options.txt2
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,