From 827b730e805df12fd9db07871cb342bb39c458a1 Mon Sep 17 00:00:00 2001 From: Zwarf Date: Sun, 11 Sep 2022 23:13:36 +0200 Subject: [PATCH] Make location service reliable Everything related to finding the users location is now in a seperate file to make the code more readable. Furthermore, the error handling is improved and also a timeout is included now. --- src/meson.build | 1 + src/window/location-service.c | 80 ++++++++++++++++++++++++++++++ src/window/location-service.h | 8 +++ src/window/picplanner-window.c | 90 +++------------------------------- src/window/picplanner-window.h | 7 ++- 5 files changed, 102 insertions(+), 84 deletions(-) create mode 100644 src/window/location-service.c create mode 100644 src/window/location-service.h diff --git a/src/meson.build b/src/meson.build index fac113e..cc6cbaa 100644 --- a/src/meson.build +++ b/src/meson.build @@ -14,6 +14,7 @@ picplanner_sources = [ 'search/search.c', 'map/draw-layer.c', 'map/marker.c', + 'window/location-service.c' ] picplanner_deps = [ diff --git a/src/window/location-service.c b/src/window/location-service.c new file mode 100644 index 0000000..c7cb46e --- /dev/null +++ b/src/window/location-service.c @@ -0,0 +1,80 @@ +#include "location-service.h" + +/* GeoClue */ +guint timer; + +static GClueSimple *simple = NULL; +static GClueClient *client = NULL; +static GCancellable *cancellabel = NULL; + + +static void +stop_location_search (gpointer user_data) +{ + (void) user_data; + + g_clear_object (&client); + g_clear_object (&simple); + cancellabel = NULL; + g_source_remove (timer); +} + +static gboolean +on_timeout (gpointer user_data) +{ + (void) user_data; + + g_cancellable_cancel (cancellabel); + return FALSE; +} + +static void +set_user_location (GObject *source_object, + GAsyncResult *res, + gpointer user_data) + +{ + (void) source_object; + (void) user_data; + double latitude; + double longitude; + GError *error = NULL; + static GClueLocation *location; + + simple = gclue_simple_new_with_thresholds_finish (res, &error); + + if (error == NULL) + { + location = gclue_simple_get_location (simple); + latitude = gclue_location_get_latitude (location); + longitude = gclue_location_get_longitude (location); + picplanner_set_location (latitude, longitude, PICPLANNER_WINDOW (user_data)); + } + else + { + g_print ("Cannot receive location!\n"); + g_error_free (error); + } + stop_location_search (NULL); +} + +/* + * Get the users location + */ +void +get_user_location (GtkButton *self, + gpointer user_data) +{ + (void) self; + + if (cancellabel == NULL) + { + timer = g_timeout_add_seconds (30, on_timeout, NULL); + cancellabel = g_cancellable_new (); + gclue_simple_new ("picplanner", + GCLUE_ACCURACY_LEVEL_EXACT, + cancellabel, + set_user_location, + user_data); + } +} \ No newline at end of file diff --git a/src/window/location-service.h b/src/window/location-service.h new file mode 100644 index 0000000..662d7b3 --- /dev/null +++ b/src/window/location-service.h @@ -0,0 +1,8 @@ +#pragma once + +#include +#include "picplanner-window.h" + +void +get_user_location (GtkButton *self, + gpointer user_data); \ No newline at end of file diff --git a/src/window/picplanner-window.c b/src/window/picplanner-window.c index e083338..44ce8dd 100644 --- a/src/window/picplanner-window.c +++ b/src/window/picplanner-window.c @@ -24,7 +24,6 @@ #include "calculations/calculations_sun.h" #include "calculations/calculations_moon.h" #include "calculations/calculations_milky_way.h" -#include "search/search.h" /* @@ -33,13 +32,6 @@ */ #define INPUT_CHANGED_TIMEOUT_LENGTH 100 -/* - * Definitions neccessary for GeoClue - */ -static gint timeout = 30; /* seconds */ -static GClueAccuracyLevel accuracy_level = GCLUE_ACCURACY_LEVEL_EXACT; -static gint time_threshold; - struct _PicplannerWindow { @@ -85,10 +77,6 @@ struct _PicplannerWindow guint input_timeout_id; gboolean input_new; - /* GeoClue */ - GClueSimple *simple; - GClueClient *client; - /* All settings of PicPlanner */ GSettings *settings; @@ -241,71 +229,6 @@ search_location (GtkWidget *self, g_free (search_string); } - -static gboolean -on_location_timeout (PicplannerWindow *window) -{ - g_clear_object (&window->client); - g_clear_object (&window->simple); - - return FALSE; -} - -static void -set_user_location (GObject *source_object, - GAsyncResult *res, - gpointer user_data) - -{ - g_print ("Gathering location information\n"); - PicplannerWindow *window = PICPLANNER_WINDOW (user_data); - GError *error = NULL; - - window->simple = gclue_simple_new_with_thresholds_finish (res, &error); - - if (error == NULL) - { - GClueLocation *location; - location = gclue_simple_get_location (window->simple); - g_print ("\nNew location:\n"); - g_print ("Latitude: %f°\nLongitude: %f°\nAccuracy: %f meters\n", - gclue_location_get_latitude (location), - gclue_location_get_longitude (location), - gclue_location_get_accuracy (location)); - gtk_spin_button_set_value (GTK_SPIN_BUTTON (window->north_entry), - gclue_location_get_latitude(location)); - gtk_spin_button_set_value (GTK_SPIN_BUTTON (window->east_entry), - gclue_location_get_longitude(location)); - } - else - { - g_print ("Cannot receive location!\n"); - } - on_location_timeout (window); - -} - -/* - * Get the users location - */ -static void -get_user_location (GtkButton *self, - PicplannerWindow *window) -{ - (void) self; - (void) window; - g_print ("Looking for users location...\n"); - - gclue_simple_new_with_thresholds ("picplanner", - accuracy_level, - time_threshold, - 0, - NULL, - set_user_location, - window); -} - - /* * Show the map in fullscreen */ @@ -333,6 +256,13 @@ stack_changed (AdwViewStack *self, gtk_widget_set_visible (window->map_button, FALSE); } +void +picplanner_set_location (double latitude, double longitude, PicplannerWindow *window) +{ + gtk_spin_button_set_value (GTK_SPIN_BUTTON (window->north_entry), latitude); + gtk_spin_button_set_value (GTK_SPIN_BUTTON (window->east_entry), longitude); +} + /* * Changing the date_time variable after a user input was recognized. @@ -802,12 +732,6 @@ picplanner_window_init (PicplannerWindow *window) gtk_spin_button_set_value (GTK_SPIN_BUTTON (window->spin_button_minute), g_date_time_get_minute (window->date_time)); - /* - * Initialize GeoClue - */ - window->simple = NULL; - window->client = NULL; - /* * Callbacks */ diff --git a/src/window/picplanner-window.h b/src/window/picplanner-window.h index 4e69859..9cadd64 100644 --- a/src/window/picplanner-window.h +++ b/src/window/picplanner-window.h @@ -20,11 +20,12 @@ #include #include -#include #include #include #include "picplanner-config.h" #include "picplanner-application.h" +#include "search/search.h" +#include "location-service.h" G_BEGIN_DECLS @@ -35,6 +36,10 @@ G_BEGIN_DECLS G_DECLARE_FINAL_TYPE (PicplannerWindow, picplanner_window, PICPLANNER, WINDOW, AdwApplicationWindow) PicplannerWindow *picplanner_window_new (PicplannerApplication *app); + void picplanner_window_open (PicplannerWindow *win, GFile *file); +void +picplanner_set_location (double latitude, double longitude, PicplannerWindow *window); + G_END_DECLS