From ef4473ebbc389ed4c3d0c21d952aa1c5e0d25148 Mon Sep 17 00:00:00 2001 From: Mahmoud Abdelghany Date: Wed, 26 Mar 2025 17:12:04 +0200 Subject: [PATCH 01/22] made the auto-downloader button visible --- src/play-preferences-dialog.ui | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/play-preferences-dialog.ui b/src/play-preferences-dialog.ui index 1e4cd2ef..1241e5d2 100644 --- a/src/play-preferences-dialog.ui +++ b/src/play-preferences-dialog.ui @@ -90,7 +90,7 @@ Auto Download - false + true Automatically Download Latest Puzzles On Startup -- GitLab From d9280972c2503c57c1702ae0e8fb13e2ae77b8eb Mon Sep 17 00:00:00 2001 From: Mahmoud Abdelghany Date: Wed, 26 Mar 2025 20:55:56 +0200 Subject: [PATCH 02/22] initial initial attempt just messing around . --- src/crosswords-app.c | 57 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 56 insertions(+), 1 deletion(-) diff --git a/src/crosswords-app.c b/src/crosswords-app.c index 8b629472..4c87f610 100644 --- a/src/crosswords-app.c +++ b/src/crosswords-app.c @@ -28,10 +28,13 @@ #include "crosswords-init.h" #include "play-window.h" #include "puzzle-downloader.h" - +#include "puzzle-set.h" +#include "puzzle-set-list.h" +#include struct _CrosswordsApp { AdwApplication parent; + }; @@ -110,6 +113,20 @@ crosswords_app_open (GApplication *app, } +static gboolean +check_network_availability (void) +{ + GResolver *resolver = g_resolver_get_default (); + GList *addresses = g_resolver_lookup_by_name (resolver, "google.com", NULL, NULL); + if (addresses) { + g_list_free_full (addresses, g_object_unref); + return TRUE; + } + return FALSE; +} + + + static void crosswords_app_startup (GApplication *app) { @@ -125,6 +142,44 @@ crosswords_app_startup (GApplication *app) crosswords_init (); +g_autoptr (GSettings) settings = g_settings_new ("org.gnome.Crosswords"); +gboolean auto_download = g_settings_get_boolean (settings, "auto-download-puzzle-sets"); +if (auto_download) { + g_print ("Auto-download is enabled\n"); + + if (!check_network_availability ()) { + g_print ("No network available, skipping auto-download\n"); + return; + } + + g_auto(GStrv) shown_puzzle_sets = g_settings_get_strv (settings, "shown-puzzle-sets"); + // Get the list of user-enabled puzzle sets from GSettings + GListModel *puzzle_set_list = puzzle_set_list_get (); + + guint n_items = g_list_model_get_n_items (puzzle_set_list); + for (guint i = 0; i < n_items; i++) { + g_autoptr (PuzzleSet) puzzle_set = g_list_model_get_item (puzzle_set_list, i); + const gchar *id = puzzle_set_get_id (puzzle_set); + const gchar *short_name = puzzle_set_get_short_name (puzzle_set); + guint puzzle_count = puzzle_set_get_n_puzzles (puzzle_set); + // Check if the puzzle set is in the shown-puzzle-sets list + gboolean is_enabled = FALSE; + for (gint j = 0; shown_puzzle_sets[j] != NULL; j++) { + if (g_strcmp0 (id, shown_puzzle_sets[j]) == 0) { + is_enabled = TRUE; + break; + } + } + + // Only process if the puzzle set is enabled and has an auto-downloader + if (is_enabled && puzzle_set_get_auto_download (puzzle_set)) { + g_print ("Auto downloaders available for %s\nPuzzle Count: %d\n", short_name, puzzle_count); + } + } + } else { + g_print ("Auto-download is disabled\n"); + } + gtk_application_set_accels_for_action (GTK_APPLICATION (app), "app.quit", quit_accels); gtk_application_set_accels_for_action (GTK_APPLICATION (app), "app.open", open_accels); -- GitLab From 7ad7e0c36551c273c94511d9f123c613a1bc7b8d Mon Sep 17 00:00:00 2001 From: Mahmoud Abdelghany Date: Thu, 27 Mar 2025 01:50:19 +0200 Subject: [PATCH 03/22] somehow working first attempt , it auto downloads but i lowkey destroyed the whole codebase with print statments trying to make it so i'll need to fix that ,also it gives a a dialog that blocks the ui during downloading i have also to fix that . it doesnt keep track on last update time and lastly i used wierd way to check fornetwork connectivity cause my machiene have some problems with flatpack --- src/crosswords-app.c | 132 ++++++++++++------------- src/puzzle-set.c | 226 +++++++++++++++++++++++++++++-------------- src/puzzle-set.h | 2 + 3 files changed, 219 insertions(+), 141 deletions(-) diff --git a/src/crosswords-app.c b/src/crosswords-app.c index 4c87f610..f9e126aa 100644 --- a/src/crosswords-app.c +++ b/src/crosswords-app.c @@ -18,7 +18,6 @@ * SPDX-License-Identifier: GPL-3.0-or-later */ - #include "crosswords-config.h" #include #include @@ -31,13 +30,23 @@ #include "puzzle-set.h" #include "puzzle-set-list.h" #include + +static gboolean +check_network_availability (void) +{ + GResolver *resolver = g_resolver_get_default (); + GList *addresses = g_resolver_lookup_by_name (resolver, "google.com", NULL, NULL); + if (addresses) { + g_list_free_full (addresses, g_object_unref); + return TRUE; + } + return FALSE; +} struct _CrosswordsApp { AdwApplication parent; - }; - static void crosswords_app_init (CrosswordsApp *app); static void crosswords_app_class_init (CrosswordsAppClass *klass); static void crosswords_app_activate (GApplication *app); @@ -52,15 +61,16 @@ static void crosswords_app_actions_about (GSimpleAction *action, GVariant *param, gpointer user_data); static void crosswords_app_startup (GApplication *app); -static void crosswords_app_actions_open (GSimpleAction *action, - GVariant *param, gpointer user_data); +static void crosswords_app_actions_open (GSimpleAction *action, + GVariant *param, + gpointer user_data); G_DEFINE_TYPE(CrosswordsApp, crosswords_app, ADW_TYPE_APPLICATION); static void crosswords_app_init (CrosswordsApp *app) { - /* Nothing to do*/ + /* Nothing to do */ } static void @@ -80,6 +90,50 @@ crosswords_app_activate (GApplication *app) NULL); gtk_window_present (window); + + // Trigger auto-downloads for eligible puzzle sets + g_autoptr (GSettings) settings_auto = g_settings_new ("org.gnome.Crosswords"); + gboolean auto_download = g_settings_get_boolean (settings_auto, "auto-download-puzzle-sets"); + if (auto_download) { + g_print ("Auto-download is enabled, triggering downloads\n"); + + if (!check_network_availability()) { + g_print ("No network available, skipping auto-download\n"); + return; + } + + g_auto(GStrv) shown_puzzle_sets = g_settings_get_strv (settings_auto, "shown-puzzle-sets"); + GListModel *puzzle_set_list = puzzle_set_list_get(); + guint n_items = g_list_model_get_n_items (puzzle_set_list); + + for (guint i = 0; i < n_items; i++) { + g_autoptr (PuzzleSet) puzzle_set = g_list_model_get_item (puzzle_set_list, i); + const gchar *id = puzzle_set_get_id (puzzle_set); + + // Check if the puzzle set is in the shown-puzzle-sets list + gboolean is_enabled = FALSE; + for (gint j = 0; shown_puzzle_sets[j] != NULL; j++) { + if (g_strcmp0 (id, shown_puzzle_sets[j]) == 0) { + is_enabled = TRUE; + break; + } + } + + // Only process if the puzzle set is enabled and has an auto-downloader + if (is_enabled && puzzle_set_get_auto_download (puzzle_set)) { + g_print ("Initiating auto-download for PuzzleSet: %s\n", id); + // Start the puzzle set (mimics selecting the puzzle set) + puzzle_set_puzzles_start (puzzle_set); + // Trigger the download (mimics clicking the "Download Puzzle" button) + start_download_cb (puzzle_set, window); + } else { + g_print ("Skipping auto-download for PuzzleSet: %s (enabled: %d, auto_download: %d)\n", + id, is_enabled, puzzle_set_get_auto_download (puzzle_set)); + } + } + } else { + g_print ("Auto-download is disabled\n"); + } } static void @@ -113,19 +167,6 @@ crosswords_app_open (GApplication *app, } -static gboolean -check_network_availability (void) -{ - GResolver *resolver = g_resolver_get_default (); - GList *addresses = g_resolver_lookup_by_name (resolver, "google.com", NULL, NULL); - if (addresses) { - g_list_free_full (addresses, g_object_unref); - return TRUE; - } - return FALSE; -} - - static void crosswords_app_startup (GApplication *app) @@ -140,46 +181,7 @@ crosswords_app_startup (GApplication *app) G_APPLICATION_CLASS (crosswords_app_parent_class)->startup (app); - crosswords_init (); -g_autoptr (GSettings) settings = g_settings_new ("org.gnome.Crosswords"); -gboolean auto_download = g_settings_get_boolean (settings, "auto-download-puzzle-sets"); -if (auto_download) { - g_print ("Auto-download is enabled\n"); - - if (!check_network_availability ()) { - g_print ("No network available, skipping auto-download\n"); - return; - } - - g_auto(GStrv) shown_puzzle_sets = g_settings_get_strv (settings, "shown-puzzle-sets"); - // Get the list of user-enabled puzzle sets from GSettings - GListModel *puzzle_set_list = puzzle_set_list_get (); - - guint n_items = g_list_model_get_n_items (puzzle_set_list); - for (guint i = 0; i < n_items; i++) { - g_autoptr (PuzzleSet) puzzle_set = g_list_model_get_item (puzzle_set_list, i); - const gchar *id = puzzle_set_get_id (puzzle_set); - const gchar *short_name = puzzle_set_get_short_name (puzzle_set); - guint puzzle_count = puzzle_set_get_n_puzzles (puzzle_set); - // Check if the puzzle set is in the shown-puzzle-sets list - gboolean is_enabled = FALSE; - for (gint j = 0; shown_puzzle_sets[j] != NULL; j++) { - if (g_strcmp0 (id, shown_puzzle_sets[j]) == 0) { - is_enabled = TRUE; - break; - } - } - - // Only process if the puzzle set is enabled and has an auto-downloader - if (is_enabled && puzzle_set_get_auto_download (puzzle_set)) { - g_print ("Auto downloaders available for %s\nPuzzle Count: %d\n", short_name, puzzle_count); - } - } - } else { - g_print ("Auto-download is disabled\n"); - } - gtk_application_set_accels_for_action (GTK_APPLICATION (app), "app.quit", quit_accels); gtk_application_set_accels_for_action (GTK_APPLICATION (app), "app.open", open_accels); @@ -215,15 +217,14 @@ crosswords_app_class_init (CrosswordsAppClass *klass) application_class->startup = crosswords_app_startup; gtk_application_class->window_added = crosswords_app_window_added; - } /* Actions */ static void crosswords_app_actions_quit (GSimpleAction *action, - GVariant *param, - gpointer user_data) + GVariant *param, + gpointer user_data) { GtkApplication *app; GList *app_list; @@ -243,8 +244,8 @@ crosswords_app_actions_quit (GSimpleAction *action, static void crosswords_app_actions_about (GSimpleAction *action, - GVariant *param, - gpointer user_data) + GVariant *param, + gpointer user_data) { CrosswordsApp *app; AdwAboutDialog *dialog; @@ -261,9 +262,7 @@ crosswords_app_actions_about (GSimpleAction *action, adw_about_dialog_set_translator_credits (dialog, _("translator-credits")); adw_about_dialog_set_copyright (dialog, crosswords_copyright); - /* The default size is a bit small for all the items */ - // gtk_about_dialgo_set_content_size (GTK_WINDOW (dialog), 515, 640); adw_dialog_set_content_width (ADW_DIALOG (dialog), 515); adw_dialog_set_content_height (ADW_DIALOG (dialog), 640); @@ -315,6 +314,7 @@ crosswords_app_actions_open (GSimpleAction *action, NULL, NULL); } + /* Public methods */ CrosswordsApp * @@ -325,4 +325,4 @@ crosswords_app_new (void) "flags", G_APPLICATION_HANDLES_OPEN, "register-session", TRUE, NULL); -} +} \ No newline at end of file diff --git a/src/puzzle-set.c b/src/puzzle-set.c index c3cdb4aa..8bf14153 100644 --- a/src/puzzle-set.c +++ b/src/puzzle-set.c @@ -57,6 +57,9 @@ static guint puzzle_set_signals[LAST_SIGNAL] = { 0 }; static GParamSpec *obj_props[N_PROPS] = {NULL, }; + + + typedef struct { PuzzleSetConfig *config; @@ -79,7 +82,6 @@ typedef struct gulong network_monitor_signal; } PuzzleSetPrivate; - static void puzzle_set_init (PuzzleSet *self); static void puzzle_set_class_init (PuzzleSetClass *klass); static void puzzle_set_set_property (GObject *object, @@ -97,16 +99,59 @@ static void puzzle_set_real_change_phase (PuzzleSet *puzzle_set PuzzlePhase phase); static void puzzle_set_real_puzzles_done (PuzzleSet *puzzle_set); static void puzzle_set_save (PuzzleSet *self); -static void start_download_cb (PuzzleSet *self); +void start_download_cb (PuzzleSet *puzzle_set, + GtkWindow *parent_window); static void puzzle_set_set_downloader_state (PuzzleSet *self, DownloaderState state); - G_DEFINE_TYPE_WITH_PRIVATE (PuzzleSet, puzzle_set, G_TYPE_OBJECT); -static -void puzzle_set_init (PuzzleSet *self) + +void +start_download_cb (PuzzleSet *self, GtkWindow *parent_window) +{ + PuzzleSetPrivate *priv; + g_autoptr (GError) error = NULL; + + g_print ("start_download_cb called for PuzzleSet: %s\n", puzzle_set_get_id (self)); + + priv = puzzle_set_get_instance_private (self); + + g_assert (priv->downloader != NULL); + g_assert (priv->downloader_cancellable == NULL); + + priv->downloader_cancellable = g_cancellable_new (); + puzzle_downloader_run_async (priv->downloader, + parent_window, + priv->downloader_cancellable, + &error); + if (error) + { + g_print (" Failed to start download: %s\n", error->message); + g_warning ("Could not run downloader: %s\n", error->message); + puzzle_set_set_downloader_state (self, DOWNLOADER_STATE_DISABLED); + return; + } + else + { + g_print (" Download started successfully\n"); + puzzle_set_set_downloader_state (self, DOWNLOADER_STATE_DOWNLOADING); + } +} + +static void +on_start_download (PuzzlePicker *picker, PuzzleSet *self) +{ + PuzzleSetPrivate *priv = puzzle_set_get_instance_private (self); + GtkWindow *parent_window = (GtkWindow *) gtk_widget_get_root (priv->picker); + start_download_cb (self, parent_window); +} + + + +static void +puzzle_set_init (PuzzleSet *self) { PuzzleSetPrivate *priv; @@ -117,6 +162,8 @@ void puzzle_set_init (PuzzleSet *self) priv->state = DOWNLOADER_STATE_READY; priv->n_won = 0; priv->n_puzzles = 0; + + g_print ("puzzle_set_init called for PuzzleSet: %s\n", puzzle_set_get_id (self)); } static void @@ -225,6 +272,8 @@ puzzle_set_get_property (GObject *object, priv = puzzle_set_get_instance_private (PUZZLE_SET (object)); + g_print ("puzzle_set_get_property called for PuzzleSet: %s, prop_id: %u\n", puzzle_set_get_id (PUZZLE_SET (object)), prop_id); + switch (prop_id) { case PROP_SET_TYPE: @@ -255,6 +304,8 @@ puzzle_set_set_property (GObject *object, priv = puzzle_set_get_instance_private (PUZZLE_SET (object)); + g_print ("puzzle_set_set_property called for PuzzleSet: %s, prop_id: %u\n", puzzle_set_get_id (PUZZLE_SET (object)), prop_id); + switch (prop_id) { case PROP_SET_TYPE: @@ -276,6 +327,8 @@ puzzle_set_dispose (GObject *object) priv = puzzle_set_get_instance_private (PUZZLE_SET (object)); + g_print ("puzzle_set_dispose called for PuzzleSet: %s\n", puzzle_set_get_id (PUZZLE_SET (object))); + g_clear_signal_handler (&priv->network_monitor_signal, g_network_monitor_get_default ()); @@ -291,11 +344,12 @@ puzzle_set_dispose (GObject *object) static void select_puzzle_cb (PuzzleSet *puzzle_set, const gchar *puzzle_name) - { PuzzleSetPrivate *priv; guint index; + g_print ("select_puzzle_cb called for PuzzleSet: %s, puzzle_name: %s\n", puzzle_set_get_id (puzzle_set), puzzle_name); + if (!puzzle_name) return; @@ -316,12 +370,15 @@ select_puzzle_cb (PuzzleSet *puzzle_set, } } -/* Called when the puzzle set is selected */ + + static void puzzle_set_real_puzzles_start (PuzzleSet *self) { PuzzleSetPrivate *priv; + g_print ("puzzle_set_real_puzzles_start called for PuzzleSet: %s\n", puzzle_set_get_id (self)); + priv = puzzle_set_get_instance_private (self); priv->xword = play_xword_new (); @@ -339,10 +396,10 @@ puzzle_set_real_puzzles_start (PuzzleSet *self) "puzzle-selected", G_CALLBACK (select_puzzle_cb), self); - g_signal_connect_swapped (G_OBJECT (priv->picker), - "start-download", - G_CALLBACK (start_download_cb), - self); + g_signal_connect (G_OBJECT (priv->picker), + "start-download", + G_CALLBACK (on_start_download), + self); g_object_ref_sink (priv->xword); g_object_ref_sink (priv->picker); @@ -354,6 +411,8 @@ puzzle_set_real_change_phase (PuzzleSet *self, { PuzzleSetPrivate *priv; + g_print ("puzzle_set_real_change_phase called for PuzzleSet: %s, phase: %d\n", puzzle_set_get_id (self), phase); + priv = puzzle_set_get_instance_private (self); if (priv->picker) @@ -379,6 +438,8 @@ puzzle_set_real_puzzles_done (PuzzleSet *self) { PuzzleSetPrivate *priv; + g_print ("puzzle_set_real_puzzles_done called for PuzzleSet: %s\n", puzzle_set_get_id (self)); + priv = puzzle_set_get_instance_private (self); puzzle_set_save (self); @@ -398,6 +459,8 @@ puzzle_set_save (PuzzleSet *self) PuzzleSetModelRow *row = NULL; guint index = 0; + g_print ("puzzle_set_save called for PuzzleSet: %s\n", puzzle_set_get_id (self)); + priv = puzzle_set_get_instance_private (self); if (priv->phase != PUZZLE_PHASE_GAME) @@ -413,18 +476,18 @@ puzzle_set_save (PuzzleSet *self) puzzle_set_model_row_set_guesses (row, guesses); } - static void import_done_func (PuzzleSetModelRow *row, PuzzleSet *self) { PuzzleSetPrivate *priv; + g_print ("import_done_func called for PuzzleSet: %s, puzzle_name: %s\n", puzzle_set_get_id (self), puzzle_set_model_row_get_puzzle_name (row)); + g_assert (PUZZLE_IS_SET (self)); priv = puzzle_set_get_instance_private (self); - /* If we have a picker, select the puzzle */ if (priv->picker) puzzle_picker_puzzle_selected (PUZZLE_PICKER (priv->picker), puzzle_set_model_row_get_puzzle_name (row)); @@ -437,11 +500,12 @@ puzzle_set_downloader_finished (PuzzleSet *self, { PuzzleSetPrivate *priv; + g_print ("puzzle_set_downloader_finished called for PuzzleSet: %s, uri: %s, delete_when_done: %d\n", puzzle_set_get_id (self), uri, delete_when_done); + g_assert (PUZZLE_IS_SET (self)); priv = puzzle_set_get_instance_private (PUZZLE_SET (self)); - /* if URI is NULL, then the operation was canceled */ if (uri) { g_autoptr (GError) error = NULL; @@ -451,6 +515,8 @@ puzzle_set_downloader_finished (PuzzleSet *self, file = g_file_new_for_uri (uri); temp_path = g_file_get_path (file); + g_print (" Importing puzzle from path: %s\n", temp_path); + puzzle_set_model_import_puzzle_path (priv->model, temp_path, delete_when_done, @@ -461,54 +527,27 @@ puzzle_set_downloader_finished (PuzzleSet *self, if (error) { + g_print (" Error importing puzzle: %s\n", error->message); GtkWidget *toast_overlay; GtkRoot *root; g_autofree gchar *msg = NULL; - msg = g_strdup_printf (_("Problem loading puzzle: %s"), - error -> message); + msg = g_strdup_printf (_("Problem loading puzzle: %s"), error->message); root = gtk_widget_get_root (GTK_WIDGET (priv->picker)); toast_overlay = play_window_get_overlay (PLAY_WINDOW (root)); adw_toast_overlay_add_toast (ADW_TOAST_OVERLAY (toast_overlay), - adw_toast_new (msg)); + adw_toast_new (msg)); } } + else + { + g_print (" Download was canceled (uri is NULL)\n"); + } g_clear_object (&priv->downloader_cancellable); puzzle_set_set_downloader_state (self, DOWNLOADER_STATE_READY); } -static void -start_download_cb (PuzzleSet *self) -{ - GtkWindow *parent_window; - PuzzleSetPrivate *priv; - - g_autoptr (GError) error = NULL; - - priv = puzzle_set_get_instance_private (self); - g_assert (priv->downloader != NULL); - g_assert (priv->downloader_cancellable == NULL); - - parent_window = (GtkWindow *) gtk_widget_get_root (priv->picker); - priv->downloader_cancellable = g_cancellable_new (); - puzzle_downloader_run_async (priv->downloader, - parent_window, - priv->downloader_cancellable, - &error); - if (error) - { - /* FIXME(error): put up a dialog */ - g_warning ("Could not run downloader: %s\n", - error->message); - puzzle_set_set_downloader_state (self, DOWNLOADER_STATE_DISABLED); - return; - } - else - { - puzzle_set_set_downloader_state (self, DOWNLOADER_STATE_DOWNLOADING); - } -} /* Public Functions */ @@ -517,6 +556,8 @@ puzzle_set_get_puzzle_type (PuzzleSet *puzzle_set) { PuzzleSetPrivate *priv; + g_print ("puzzle_set_get_puzzle_type called for PuzzleSet: %s\n", puzzle_set_get_id (puzzle_set)); + g_return_val_if_fail (PUZZLE_IS_SET (puzzle_set), PUZZLE_SET_TYPE_RESOURCE); priv = puzzle_set_get_instance_private (puzzle_set); @@ -541,6 +582,8 @@ puzzle_set_get_short_name (PuzzleSet *puzzle_set) { PuzzleSetPrivate *priv; + g_print ("puzzle_set_get_short_name called for PuzzleSet: %s\n", puzzle_set_get_id (puzzle_set)); + g_return_val_if_fail (PUZZLE_IS_SET (puzzle_set), NULL); priv = puzzle_set_get_instance_private (puzzle_set); @@ -553,6 +596,8 @@ puzzle_set_get_long_name (PuzzleSet *puzzle_set) { PuzzleSetPrivate *priv; + g_print ("puzzle_set_get_long_name called for PuzzleSet: %s\n", puzzle_set_get_id (puzzle_set)); + g_return_val_if_fail (PUZZLE_IS_SET (puzzle_set), NULL); priv = puzzle_set_get_instance_private (puzzle_set); @@ -565,6 +610,8 @@ puzzle_set_get_locale (PuzzleSet *puzzle_set) { PuzzleSetPrivate *priv; + g_print ("puzzle_set_get_locale called for PuzzleSet: %s\n", puzzle_set_get_id (puzzle_set)); + g_return_val_if_fail (PUZZLE_IS_SET (puzzle_set), NULL); priv = puzzle_set_get_instance_private (puzzle_set); @@ -577,6 +624,8 @@ puzzle_set_get_language (PuzzleSet *puzzle_set) { PuzzleSetPrivate *priv; + g_print ("puzzle_set_get_language called for PuzzleSet: %s\n", puzzle_set_get_id (puzzle_set)); + g_return_val_if_fail (PUZZLE_IS_SET (puzzle_set), NULL); priv = puzzle_set_get_instance_private (puzzle_set); @@ -584,15 +633,13 @@ puzzle_set_get_language (PuzzleSet *puzzle_set) return puzzle_set_config_get_language (priv->config); } -/* Note: the difference between disabled and shown is that 'disabled' - * is set in the puzzleset and can't be overridden or change, and - * 'shown' is a user preference and can change. - */ gboolean puzzle_set_get_disabled (PuzzleSet *puzzle_set) { PuzzleSetPrivate *priv; + g_print ("puzzle_set_get_disabled called for PuzzleSet: %s\n", puzzle_set_get_id (puzzle_set)); + g_return_val_if_fail (PUZZLE_IS_SET (puzzle_set), TRUE); priv = puzzle_set_get_instance_private (puzzle_set); @@ -605,6 +652,8 @@ puzzle_set_get_shown (PuzzleSet *puzzle_set) { PuzzleSetPrivate *priv; + g_print ("puzzle_set_get_shown called for PuzzleSet: %s\n", puzzle_set_get_id (puzzle_set)); + g_return_val_if_fail (PUZZLE_IS_SET (puzzle_set), TRUE); priv = puzzle_set_get_instance_private (puzzle_set); @@ -614,10 +663,12 @@ puzzle_set_get_shown (PuzzleSet *puzzle_set) void puzzle_set_set_shown (PuzzleSet *puzzle_set, - gboolean shown) + gboolean shown) { PuzzleSetPrivate *priv; + g_print ("puzzle_set_set_shown called for PuzzleSet: %s, shown: %d\n", puzzle_set_get_id (puzzle_set), shown); + g_return_if_fail (PUZZLE_IS_SET (puzzle_set)); shown = !!shown; @@ -635,6 +686,8 @@ puzzle_set_get_auto_download (PuzzleSet *puzzle_set) { PuzzleSetPrivate *priv; + g_print ("puzzle_set_get_auto_download called for PuzzleSet: %s\n", puzzle_set_get_id (puzzle_set)); + g_return_val_if_fail (PUZZLE_IS_SET (puzzle_set), FALSE); priv = puzzle_set_get_instance_private (puzzle_set); @@ -652,6 +705,8 @@ puzzle_set_get_tags (PuzzleSet *puzzle_set) { PuzzleSetPrivate *priv; + g_print ("puzzle_set_get_tags called for PuzzleSet: %s\n", puzzle_set_get_id (puzzle_set)); + g_return_val_if_fail (PUZZLE_IS_SET (puzzle_set), 0); priv = puzzle_set_get_instance_private (puzzle_set); @@ -662,6 +717,8 @@ puzzle_set_get_tags (PuzzleSet *puzzle_set) void puzzle_set_puzzles_start (PuzzleSet *puzzle_set) { + g_print ("puzzle_set_puzzles_start called for PuzzleSet: %s\n", puzzle_set_get_id (puzzle_set)); + g_return_if_fail (PUZZLE_IS_SET (puzzle_set)); g_signal_emit (puzzle_set, puzzle_set_signals[PUZZLES_START], 0); @@ -671,6 +728,8 @@ void puzzle_set_change_phase (PuzzleSet *puzzle_set, PuzzlePhase phase) { + g_print ("puzzle_set_change_phase called for PuzzleSet: %s, phase: %d\n", puzzle_set_get_id (puzzle_set), phase); + g_return_if_fail (PUZZLE_IS_SET (puzzle_set)); g_signal_emit (puzzle_set, puzzle_set_signals[CHANGE_PHASE], 0, phase); @@ -679,6 +738,7 @@ puzzle_set_change_phase (PuzzleSet *puzzle_set, void puzzle_set_puzzles_done (PuzzleSet *puzzle_set) { + g_print ("puzzle_set_puzzles_done called for PuzzleSet: %s\n", puzzle_set_get_id (puzzle_set)); g_return_if_fail (PUZZLE_IS_SET (puzzle_set)); @@ -688,19 +748,21 @@ puzzle_set_puzzles_done (PuzzleSet *puzzle_set) void puzzle_set_reveal_canceled (PuzzleSet *puzzle_set) { + g_print ("puzzle_set_reveal_canceled called for PuzzleSet: %s\n", puzzle_set_get_id (puzzle_set)); g_return_if_fail (PUZZLE_IS_SET (puzzle_set)); g_signal_emit (puzzle_set, puzzle_set_signals[REVEAL_CANCELED], 0); } - GtkWidget * puzzle_set_get_widget (PuzzleSet *self, PuzzlePhase phase) { PuzzleSetPrivate *priv; + g_print ("puzzle_set_get_widget called for PuzzleSet: %s, phase: %d\n", puzzle_set_get_id (self), phase); + g_return_val_if_fail (PUZZLE_IS_SET (self), NULL); priv = puzzle_set_get_instance_private (self); @@ -711,7 +773,6 @@ puzzle_set_get_widget (PuzzleSet *self, return priv->xword; return NULL; - } IpuzPuzzle * @@ -720,6 +781,8 @@ puzzle_set_get_puzzle (PuzzleSet *self, { PuzzleSetPrivate *priv; + g_print ("puzzle_set_get_puzzle called for PuzzleSet: %s, phase: %d\n", puzzle_set_get_id (self), phase); + g_return_val_if_fail (PUZZLE_IS_SET (self), NULL); priv = puzzle_set_get_instance_private (self); @@ -736,6 +799,8 @@ puzzle_set_get_title (PuzzleSet *self, PuzzleSetPrivate *priv; const char *title = NULL; + g_print ("puzzle_set_get_title called for PuzzleSet: %s, phase: %d\n", puzzle_set_get_id (self), phase); + g_return_val_if_fail (PUZZLE_IS_SET (self), NULL); g_return_val_if_fail (phase != PUZZLE_PHASE_MAIN, NULL); @@ -757,11 +822,12 @@ puzzle_set_reset_puzzle (PuzzleSet *self) { PuzzleSetPrivate *priv; + g_print ("puzzle_set_reset_puzzle called for PuzzleSet: %s\n", puzzle_set_get_id (self)); + g_return_if_fail (PUZZLE_IS_SET (self)); priv = puzzle_set_get_instance_private (self); - /* FIXME(game): Make PlayXword an interface so we can have multiple types */ if (PLAY_IS_XWORD (priv->xword)) play_xword_clear_puzzle (PLAY_XWORD (priv->xword)); } @@ -772,11 +838,12 @@ puzzle_set_reveal_toggled (PuzzleSet *self, { PuzzleSetPrivate *priv; + g_print ("puzzle_set_reveal_toggled called for PuzzleSet: %s, reveal: %d\n", puzzle_set_get_id (self), reveal); + g_return_if_fail (PUZZLE_IS_SET (self)); priv = puzzle_set_get_instance_private (self); - /* FIXME(game): Make PlayXword an interface so we can have multiple types */ if (PLAY_IS_XWORD (priv->xword)) play_xword_set_reveal_mode (PLAY_XWORD (priv->xword), reveal ? GRID_REVEAL_ERRORS_BOARD : GRID_REVEAL_NONE); @@ -787,11 +854,12 @@ puzzle_set_show_hint (PuzzleSet *self) { PuzzleSetPrivate *priv; + g_print ("puzzle_set_show_hint called for PuzzleSet: %s\n", puzzle_set_get_id (self)); + g_return_if_fail (PUZZLE_IS_SET (self)); priv = puzzle_set_get_instance_private (self); - /* FIXME(game): Make PlayXword an interface so we can have multiple types */ if (PLAY_IS_XWORD (priv->xword)) play_xword_show_hint (PLAY_XWORD (priv->xword)); } @@ -802,6 +870,8 @@ puzzle_set_get_uri (PuzzleSet *self, { PuzzleSetPrivate *priv; + g_print ("puzzle_set_get_uri called for PuzzleSet: %s, phase: %d\n", puzzle_set_get_id (self), phase); + g_return_val_if_fail (PUZZLE_IS_SET (self), NULL); priv = puzzle_set_get_instance_private (self); @@ -817,9 +887,6 @@ puzzle_set_get_uri (PuzzleSet *self, return NULL; } -/* This is used from command line or dbus calls to load uris. It's - * different from puzzle_picker->load_uri which is internally driven, - * and requires a .ipuz file. */ void puzzle_set_import_uri (PuzzleSet *self, const gchar *uri) @@ -828,6 +895,8 @@ puzzle_set_import_uri (PuzzleSet *self, GtkWindow *parent_window; g_autoptr (GError) error = NULL; + g_print ("puzzle_set_import_uri called for PuzzleSet: %s, uri: %s\n", puzzle_set_get_id (self), uri); + g_return_if_fail (PUZZLE_IS_SET (self)); priv = puzzle_set_get_instance_private (self); @@ -836,6 +905,7 @@ puzzle_set_import_uri (PuzzleSet *self, if (priv->downloader_cancellable) { + g_print (" Cannot import multiple URIs simultaneously\n"); g_warning ("Currently can't import multiple uris simultaneously"); return; } @@ -849,24 +919,20 @@ puzzle_set_import_uri (PuzzleSet *self, &error); if (error) { - /* FIXME(error): put up a dialog */ - g_warning ("Could not run downloader: %s", - error->message); + g_print (" Failed to run downloader: %s\n", error->message); + g_warning ("Could not run downloader: %s", error->message); puzzle_set_set_downloader_state (self, DOWNLOADER_STATE_READY); return; } } -/* - * Public functions - */ - - static void network_available_cb (GNetworkMonitor *monitor, gboolean network_available, PuzzleSet *puzzle_set) { + g_print ("network_available_cb called for PuzzleSet: %s, network_available: %d\n", puzzle_set_get_id (puzzle_set), network_available); + if (network_available) { } @@ -881,6 +947,8 @@ puzzle_set_set_downloader_state (PuzzleSet *self, { PuzzleSetPrivate *priv; + g_print ("puzzle_set_set_downloader_state called for PuzzleSet: %s, state: %d\n", puzzle_set_get_id (self), state); + g_assert (PUZZLE_IS_SET (self)); priv = puzzle_set_get_instance_private (self); @@ -888,7 +956,6 @@ puzzle_set_set_downloader_state (PuzzleSet *self, if (priv->state == state) return; - /* There's no recovery from a disabled downloader */ if (priv->state != DOWNLOADER_STATE_DISABLED) { priv->state = state; @@ -906,6 +973,8 @@ won_changed_cb (PuzzleSet *self, PuzzleSetPrivate *priv; guint n_won; + g_print ("won_changed_cb called for PuzzleSet: %s\n", puzzle_set_get_id (self)); + priv = puzzle_set_get_instance_private (self); n_won = puzzle_set_model_get_n_won (model); @@ -923,6 +992,8 @@ items_changed_cb (PuzzleSet *self) PuzzleSetPrivate *priv; guint n_puzzles; + g_print ("items_changed_cb called for PuzzleSet: %s\n", puzzle_set_get_id (self)); + priv = puzzle_set_get_instance_private (self); n_puzzles = g_list_model_get_n_items (G_LIST_MODEL (priv->model)); @@ -941,6 +1012,8 @@ puzzle_set_set_config (PuzzleSet *self, PuzzleSetPrivate *priv; ConfigButtonType button_type; + g_print ("puzzle_set_set_config called for PuzzleSet: %s\n", puzzle_set_get_id (self)); + g_assert (PUZZLE_IS_SET (self)); priv = puzzle_set_get_instance_private (self); @@ -961,12 +1034,10 @@ puzzle_set_set_config (PuzzleSet *self, else priv->downloader = puzzle_downloader_new_from_config (config); - /* Everything loaded fine; show the button and listen for changes */ if (priv->downloader) { puzzle_set_set_downloader_state (self, DOWNLOADER_STATE_READY); - /* listen to network changes if we require network */ if (puzzle_downloader_get_requires_network (priv->downloader)) { GNetworkMonitor *monitor; @@ -997,6 +1068,8 @@ puzzle_set_get_n_puzzles (PuzzleSet *puzzle_set) { PuzzleSetPrivate *priv; + g_print ("puzzle_set_get_n_puzzles called for PuzzleSet: %s\n", puzzle_set_get_id (puzzle_set)); + g_return_val_if_fail (PUZZLE_IS_SET (puzzle_set), 0); priv = puzzle_set_get_instance_private (puzzle_set); @@ -1009,6 +1082,8 @@ puzzle_set_get_n_won (PuzzleSet *puzzle_set) { PuzzleSetPrivate *priv; + g_print ("puzzle_set_get_n_won called for PuzzleSet: %s\n", puzzle_set_get_id (puzzle_set)); + g_return_val_if_fail (PUZZLE_IS_SET (puzzle_set), 0); priv = puzzle_set_get_instance_private (puzzle_set); @@ -1016,7 +1091,6 @@ puzzle_set_get_n_won (PuzzleSet *puzzle_set) return priv->n_won; } -/* Can return NULL if resource can't be loaded. */ PuzzleSet * puzzle_set_new (GResource *resource) { @@ -1024,6 +1098,8 @@ puzzle_set_new (GResource *resource) PuzzleSet *puzzle_set; PuzzleSetConfig *config; + g_print ("puzzle_set_new called\n"); + puzzle_set = g_object_new (PUZZLE_TYPE_SET, "set-type", PUZZLE_SET_TYPE_RESOURCE, NULL); @@ -1035,7 +1111,7 @@ puzzle_set_new (GResource *resource) if (config) puzzle_set_set_config (puzzle_set, config); else - g_clear_object (& puzzle_set); + g_clear_object (&puzzle_set); return puzzle_set; -} +} \ No newline at end of file diff --git a/src/puzzle-set.h b/src/puzzle-set.h index df9d6c8b..32148f76 100644 --- a/src/puzzle-set.h +++ b/src/puzzle-set.h @@ -99,4 +99,6 @@ guint puzzle_set_get_n_puzzles (PuzzleSet *puzzle_set); guint puzzle_set_get_n_won (PuzzleSet *puzzle_set); +void start_download_cb (PuzzleSet *puzzle_set, + GtkWindow *parent_window); G_END_DECLS -- GitLab From 1e310c33492e36dd650647e4236f3903bff32606 Mon Sep 17 00:00:00 2001 From: Mahmoud Abdelghany Date: Fri, 28 Mar 2025 23:18:42 +0200 Subject: [PATCH 04/22] my initial take on implementing the auto puzzle downloader --- src/crosswords-app.c | 85 ++++--------- src/puzzle-downloader.c | 97 ++++++++++++++- src/puzzle-downloader.h | 2 +- src/puzzle-set.c | 265 +++++++++++++++++----------------------- src/puzzle-set.h | 4 +- 5 files changed, 236 insertions(+), 217 deletions(-) diff --git a/src/crosswords-app.c b/src/crosswords-app.c index f9e126aa..52a89c92 100644 --- a/src/crosswords-app.c +++ b/src/crosswords-app.c @@ -18,18 +18,22 @@ * SPDX-License-Identifier: GPL-3.0-or-later */ + #include "crosswords-config.h" #include #include #include +#include #include "crosswords-app.h" #include "crosswords-credits.h" #include "crosswords-init.h" #include "play-window.h" #include "puzzle-downloader.h" #include "puzzle-set.h" -#include "puzzle-set-list.h" -#include +struct _CrosswordsApp +{ + AdwApplication parent; +}; static gboolean check_network_availability (void) @@ -42,10 +46,6 @@ check_network_availability (void) } return FALSE; } -struct _CrosswordsApp -{ - AdwApplication parent; -}; static void crosswords_app_init (CrosswordsApp *app); static void crosswords_app_class_init (CrosswordsAppClass *klass); @@ -61,16 +61,15 @@ static void crosswords_app_actions_about (GSimpleAction *action, GVariant *param, gpointer user_data); static void crosswords_app_startup (GApplication *app); -static void crosswords_app_actions_open (GSimpleAction *action, - GVariant *param, - gpointer user_data); +static void crosswords_app_actions_open (GSimpleAction *action, + GVariant *param, gpointer user_data); G_DEFINE_TYPE(CrosswordsApp, crosswords_app, ADW_TYPE_APPLICATION); static void crosswords_app_init (CrosswordsApp *app) { - /* Nothing to do */ + /* Nothing to do*/ } static void @@ -90,50 +89,16 @@ crosswords_app_activate (GApplication *app) NULL); gtk_window_present (window); - - // Trigger auto-downloads for eligible puzzle sets - g_autoptr (GSettings) settings_auto = g_settings_new ("org.gnome.Crosswords"); - gboolean auto_download = g_settings_get_boolean (settings_auto, "auto-download-puzzle-sets"); - if (auto_download) { - g_print ("Auto-download is enabled, triggering downloads\n"); - - if (!check_network_availability()) { - g_print ("No network available, skipping auto-download\n"); - return; - } - - g_auto(GStrv) shown_puzzle_sets = g_settings_get_strv (settings_auto, "shown-puzzle-sets"); - GListModel *puzzle_set_list = puzzle_set_list_get(); - guint n_items = g_list_model_get_n_items (puzzle_set_list); - - for (guint i = 0; i < n_items; i++) { - g_autoptr (PuzzleSet) puzzle_set = g_list_model_get_item (puzzle_set_list, i); - const gchar *id = puzzle_set_get_id (puzzle_set); - - // Check if the puzzle set is in the shown-puzzle-sets list - gboolean is_enabled = FALSE; - for (gint j = 0; shown_puzzle_sets[j] != NULL; j++) { - if (g_strcmp0 (id, shown_puzzle_sets[j]) == 0) { - is_enabled = TRUE; - break; + gboolean auto_download = g_settings_get_boolean (settings, "auto-download-puzzle-sets"); + if (auto_download) + { + if (!check_network_availability ()) + { + g_warning ("No network available, skipping auto-download\n"); + return; } - } - - // Only process if the puzzle set is enabled and has an auto-downloader - if (is_enabled && puzzle_set_get_auto_download (puzzle_set)) { - g_print ("Initiating auto-download for PuzzleSet: %s\n", id); - // Start the puzzle set (mimics selecting the puzzle set) - puzzle_set_puzzles_start (puzzle_set); - // Trigger the download (mimics clicking the "Download Puzzle" button) - start_download_cb (puzzle_set, window); - } else { - g_print ("Skipping auto-download for PuzzleSet: %s (enabled: %d, auto_download: %d)\n", - id, is_enabled, puzzle_set_get_auto_download (puzzle_set)); - } + puzzle_set_auto_download_all (settings, window); } - } else { - g_print ("Auto-download is disabled\n"); - } } static void @@ -167,7 +132,6 @@ crosswords_app_open (GApplication *app, } - static void crosswords_app_startup (GApplication *app) { @@ -181,6 +145,7 @@ crosswords_app_startup (GApplication *app) G_APPLICATION_CLASS (crosswords_app_parent_class)->startup (app); + crosswords_init (); gtk_application_set_accels_for_action (GTK_APPLICATION (app), "app.quit", quit_accels); @@ -217,14 +182,15 @@ crosswords_app_class_init (CrosswordsAppClass *klass) application_class->startup = crosswords_app_startup; gtk_application_class->window_added = crosswords_app_window_added; + } /* Actions */ static void crosswords_app_actions_quit (GSimpleAction *action, - GVariant *param, - gpointer user_data) + GVariant *param, + gpointer user_data) { GtkApplication *app; GList *app_list; @@ -244,8 +210,8 @@ crosswords_app_actions_quit (GSimpleAction *action, static void crosswords_app_actions_about (GSimpleAction *action, - GVariant *param, - gpointer user_data) + GVariant *param, + gpointer user_data) { CrosswordsApp *app; AdwAboutDialog *dialog; @@ -262,7 +228,9 @@ crosswords_app_actions_about (GSimpleAction *action, adw_about_dialog_set_translator_credits (dialog, _("translator-credits")); adw_about_dialog_set_copyright (dialog, crosswords_copyright); + /* The default size is a bit small for all the items */ + // gtk_about_dialgo_set_content_size (GTK_WINDOW (dialog), 515, 640); adw_dialog_set_content_width (ADW_DIALOG (dialog), 515); adw_dialog_set_content_height (ADW_DIALOG (dialog), 640); @@ -314,7 +282,6 @@ crosswords_app_actions_open (GSimpleAction *action, NULL, NULL); } - /* Public methods */ CrosswordsApp * @@ -325,4 +292,4 @@ crosswords_app_new (void) "flags", G_APPLICATION_HANDLES_OPEN, "register-session", TRUE, NULL); -} \ No newline at end of file +} diff --git a/src/puzzle-downloader.c b/src/puzzle-downloader.c index af0e8704..660b0424 100644 --- a/src/puzzle-downloader.c +++ b/src/puzzle-downloader.c @@ -24,7 +24,9 @@ #include #include "puzzle-downloader.h" #include "puzzle-downloader-dialog.h" - +#include "puzzle-set.h" +#include "puzzle-set-list.h" +#include "puzzle-set-config.h" #define MASTER_SCHEMA "org.gnome.Crosswords.puzzle-sets" #define PUZZLE_SET_PATH_PREFIX "/org/gnome/Crosswords/puzzle-sets/" @@ -260,6 +262,24 @@ downloader_cancel_timeout_cb (PuzzleDownloader *downloader) return G_SOURCE_REMOVE; } +static gboolean +auto_downloader_cancel_timeout_cb (PuzzleDownloader *downloader) +{ + g_assert (PUZZLE_IS_DOWNLOADER (downloader)); + g_debug ("Timeout reached for auto-download with header: %s, cancelling subprocess", downloader->header); + if (downloader->temp_file) + { + unlink (downloader->temp_file); + g_clear_pointer (&downloader->temp_file, g_free); + } + if (downloader->subprocess) + g_subprocess_force_exit (downloader->subprocess); + downloader->cancel_timeout = 0; + g_signal_emit (downloader, obj_signals[FINISHED], 0, NULL, FALSE); + + return G_SOURCE_REMOVE; +} + static void downloader_cancel_timeout_add (PuzzleDownloader *downloader) { @@ -462,9 +482,7 @@ command_finished_cb (GSubprocess *subprocess, /* Clear subprocess info so we can run another command */ downloader_cancel_timeout_remove (downloader); - g_clear_pointer (&downloader->cancel_dialog, adw_dialog_close); g_clear_object (&downloader->subprocess); - /* If we successfully run the subcommand and captured it's stdout, * we either load the file, or potentially convert it. */ if (temp_file) @@ -492,6 +510,39 @@ command_finished_cb (GSubprocess *subprocess, } } +static void +auto_command_finished_cb (GSubprocess *subprocess, GAsyncResult *res, + PuzzleDownloader *downloader) +{ + gchar *temp_file = NULL; + downloader_cancel_timeout_remove (downloader); + if (g_subprocess_get_successful (subprocess)) + temp_file = stdout_to_temp_file (subprocess); + else + g_warning ("Auto-download failed for downloader with header: %s", + downloader->header); + if (temp_file) + { + if (downloader->format == DOWNLOADER_FORMAT_IPUZ) + { + g_autofree gchar *uri = NULL; + + uri = g_filename_to_uri (temp_file, NULL, NULL); + g_signal_emit (downloader, obj_signals[FINISHED], 0, uri, TRUE); + g_free (temp_file); + } + else + { + g_assert (downloader->temp_file == NULL); + downloader->temp_file = temp_file; + convert_puz_to_ipuz (downloader); + } + } + else + { + g_signal_emit (downloader, obj_signals[FINISHED], 0, NULL, FALSE); + } +} static gchar ** generate_argv (PuzzleDownloader *downloader) { @@ -935,3 +986,43 @@ puzzle_downloader_run_async (PuzzleDownloader *downloader, run_input_dialog (downloader); } } + +void +puzzle_downloader_run_auto (PuzzleDownloader *downloader, GCancellable *cancellable) +{ + g_autoptr (GError) tmp_error = NULL; + gchar **argv; + + g_return_if_fail (PUZZLE_IS_DOWNLOADER (downloader)); + g_return_if_fail (downloader->command_string != NULL); + + if (downloader->subprocess) + return; + + argv = generate_argv (downloader); + if (argv == NULL) + { + g_warning ("puzzle_downloader_run_auto: Invalid command in downloader: %s", downloader->command_string); + return; + } + + downloader->subprocess = g_subprocess_newv ((const char *const *)argv, + G_SUBPROCESS_FLAGS_STDOUT_PIPE, + &tmp_error); + g_strfreev (argv); + + if (tmp_error != NULL) + { + g_warning ("puzzle_downloader_run_auto: Error creating subprocess for downloader ID: %s: %s", + downloader->id, tmp_error->message); + g_clear_error (&tmp_error); + return; + } + downloader->cancel_timeout = g_timeout_add (10000, + (GSourceFunc) auto_downloader_cancel_timeout_cb, + downloader); + g_subprocess_wait_async (downloader->subprocess, + downloader->wait_cancellable, + (GAsyncReadyCallback) auto_command_finished_cb, + downloader); +} \ No newline at end of file diff --git a/src/puzzle-downloader.h b/src/puzzle-downloader.h index efbdf1ba..fa6fdabf 100644 --- a/src/puzzle-downloader.h +++ b/src/puzzle-downloader.h @@ -60,7 +60,7 @@ void puzzle_downloader_run_async (PuzzleDownloader *dow GtkWindow *parent_window, GCancellable *cancellable, GError **error); - +void puzzle_downloader_run_auto (PuzzleDownloader *downloader, GCancellable *cancellable); G_END_DECLS diff --git a/src/puzzle-set.c b/src/puzzle-set.c index 8bf14153..53d686c0 100644 --- a/src/puzzle-set.c +++ b/src/puzzle-set.c @@ -32,7 +32,7 @@ #include "puzzle-set.h" #include "puzzle-set-config.h" #include "puzzle-set-model.h" - +#include "puzzle-set-list.h" enum { PUZZLES_START, @@ -57,9 +57,6 @@ static guint puzzle_set_signals[LAST_SIGNAL] = { 0 }; static GParamSpec *obj_props[N_PROPS] = {NULL, }; - - - typedef struct { PuzzleSetConfig *config; @@ -82,6 +79,7 @@ typedef struct gulong network_monitor_signal; } PuzzleSetPrivate; + static void puzzle_set_init (PuzzleSet *self); static void puzzle_set_class_init (PuzzleSetClass *klass); static void puzzle_set_set_property (GObject *object, @@ -99,59 +97,16 @@ static void puzzle_set_real_change_phase (PuzzleSet *puzzle_set PuzzlePhase phase); static void puzzle_set_real_puzzles_done (PuzzleSet *puzzle_set); static void puzzle_set_save (PuzzleSet *self); -void start_download_cb (PuzzleSet *puzzle_set, - GtkWindow *parent_window); +static void start_download_cb (PuzzleSet *self); static void puzzle_set_set_downloader_state (PuzzleSet *self, DownloaderState state); -G_DEFINE_TYPE_WITH_PRIVATE (PuzzleSet, puzzle_set, G_TYPE_OBJECT); - - - -void -start_download_cb (PuzzleSet *self, GtkWindow *parent_window) -{ - PuzzleSetPrivate *priv; - g_autoptr (GError) error = NULL; - - g_print ("start_download_cb called for PuzzleSet: %s\n", puzzle_set_get_id (self)); - - priv = puzzle_set_get_instance_private (self); - - g_assert (priv->downloader != NULL); - g_assert (priv->downloader_cancellable == NULL); - - priv->downloader_cancellable = g_cancellable_new (); - puzzle_downloader_run_async (priv->downloader, - parent_window, - priv->downloader_cancellable, - &error); - if (error) - { - g_print (" Failed to start download: %s\n", error->message); - g_warning ("Could not run downloader: %s\n", error->message); - puzzle_set_set_downloader_state (self, DOWNLOADER_STATE_DISABLED); - return; - } - else - { - g_print (" Download started successfully\n"); - puzzle_set_set_downloader_state (self, DOWNLOADER_STATE_DOWNLOADING); - } -} - -static void -on_start_download (PuzzlePicker *picker, PuzzleSet *self) -{ - PuzzleSetPrivate *priv = puzzle_set_get_instance_private (self); - GtkWindow *parent_window = (GtkWindow *) gtk_widget_get_root (priv->picker); - start_download_cb (self, parent_window); -} +G_DEFINE_TYPE_WITH_PRIVATE (PuzzleSet, puzzle_set, G_TYPE_OBJECT); -static void -puzzle_set_init (PuzzleSet *self) +static +void puzzle_set_init (PuzzleSet *self) { PuzzleSetPrivate *priv; @@ -162,8 +117,6 @@ puzzle_set_init (PuzzleSet *self) priv->state = DOWNLOADER_STATE_READY; priv->n_won = 0; priv->n_puzzles = 0; - - g_print ("puzzle_set_init called for PuzzleSet: %s\n", puzzle_set_get_id (self)); } static void @@ -272,8 +225,6 @@ puzzle_set_get_property (GObject *object, priv = puzzle_set_get_instance_private (PUZZLE_SET (object)); - g_print ("puzzle_set_get_property called for PuzzleSet: %s, prop_id: %u\n", puzzle_set_get_id (PUZZLE_SET (object)), prop_id); - switch (prop_id) { case PROP_SET_TYPE: @@ -304,8 +255,6 @@ puzzle_set_set_property (GObject *object, priv = puzzle_set_get_instance_private (PUZZLE_SET (object)); - g_print ("puzzle_set_set_property called for PuzzleSet: %s, prop_id: %u\n", puzzle_set_get_id (PUZZLE_SET (object)), prop_id); - switch (prop_id) { case PROP_SET_TYPE: @@ -327,8 +276,6 @@ puzzle_set_dispose (GObject *object) priv = puzzle_set_get_instance_private (PUZZLE_SET (object)); - g_print ("puzzle_set_dispose called for PuzzleSet: %s\n", puzzle_set_get_id (PUZZLE_SET (object))); - g_clear_signal_handler (&priv->network_monitor_signal, g_network_monitor_get_default ()); @@ -344,12 +291,11 @@ puzzle_set_dispose (GObject *object) static void select_puzzle_cb (PuzzleSet *puzzle_set, const gchar *puzzle_name) + { PuzzleSetPrivate *priv; guint index; - g_print ("select_puzzle_cb called for PuzzleSet: %s, puzzle_name: %s\n", puzzle_set_get_id (puzzle_set), puzzle_name); - if (!puzzle_name) return; @@ -370,15 +316,12 @@ select_puzzle_cb (PuzzleSet *puzzle_set, } } - - +/* Called when the puzzle set is selected */ static void puzzle_set_real_puzzles_start (PuzzleSet *self) { PuzzleSetPrivate *priv; - g_print ("puzzle_set_real_puzzles_start called for PuzzleSet: %s\n", puzzle_set_get_id (self)); - priv = puzzle_set_get_instance_private (self); priv->xword = play_xword_new (); @@ -396,10 +339,10 @@ puzzle_set_real_puzzles_start (PuzzleSet *self) "puzzle-selected", G_CALLBACK (select_puzzle_cb), self); - g_signal_connect (G_OBJECT (priv->picker), - "start-download", - G_CALLBACK (on_start_download), - self); + g_signal_connect_swapped (G_OBJECT (priv->picker), + "start-download", + G_CALLBACK (start_download_cb), + self); g_object_ref_sink (priv->xword); g_object_ref_sink (priv->picker); @@ -411,8 +354,6 @@ puzzle_set_real_change_phase (PuzzleSet *self, { PuzzleSetPrivate *priv; - g_print ("puzzle_set_real_change_phase called for PuzzleSet: %s, phase: %d\n", puzzle_set_get_id (self), phase); - priv = puzzle_set_get_instance_private (self); if (priv->picker) @@ -438,8 +379,6 @@ puzzle_set_real_puzzles_done (PuzzleSet *self) { PuzzleSetPrivate *priv; - g_print ("puzzle_set_real_puzzles_done called for PuzzleSet: %s\n", puzzle_set_get_id (self)); - priv = puzzle_set_get_instance_private (self); puzzle_set_save (self); @@ -459,8 +398,6 @@ puzzle_set_save (PuzzleSet *self) PuzzleSetModelRow *row = NULL; guint index = 0; - g_print ("puzzle_set_save called for PuzzleSet: %s\n", puzzle_set_get_id (self)); - priv = puzzle_set_get_instance_private (self); if (priv->phase != PUZZLE_PHASE_GAME) @@ -476,18 +413,18 @@ puzzle_set_save (PuzzleSet *self) puzzle_set_model_row_set_guesses (row, guesses); } + static void import_done_func (PuzzleSetModelRow *row, PuzzleSet *self) { PuzzleSetPrivate *priv; - g_print ("import_done_func called for PuzzleSet: %s, puzzle_name: %s\n", puzzle_set_get_id (self), puzzle_set_model_row_get_puzzle_name (row)); - g_assert (PUZZLE_IS_SET (self)); priv = puzzle_set_get_instance_private (self); + /* If we have a picker, select the puzzle */ if (priv->picker) puzzle_picker_puzzle_selected (PUZZLE_PICKER (priv->picker), puzzle_set_model_row_get_puzzle_name (row)); @@ -500,12 +437,11 @@ puzzle_set_downloader_finished (PuzzleSet *self, { PuzzleSetPrivate *priv; - g_print ("puzzle_set_downloader_finished called for PuzzleSet: %s, uri: %s, delete_when_done: %d\n", puzzle_set_get_id (self), uri, delete_when_done); - g_assert (PUZZLE_IS_SET (self)); priv = puzzle_set_get_instance_private (PUZZLE_SET (self)); + /* if URI is NULL, then the operation was canceled */ if (uri) { g_autoptr (GError) error = NULL; @@ -515,8 +451,6 @@ puzzle_set_downloader_finished (PuzzleSet *self, file = g_file_new_for_uri (uri); temp_path = g_file_get_path (file); - g_print (" Importing puzzle from path: %s\n", temp_path); - puzzle_set_model_import_puzzle_path (priv->model, temp_path, delete_when_done, @@ -527,27 +461,54 @@ puzzle_set_downloader_finished (PuzzleSet *self, if (error) { - g_print (" Error importing puzzle: %s\n", error->message); GtkWidget *toast_overlay; GtkRoot *root; g_autofree gchar *msg = NULL; - msg = g_strdup_printf (_("Problem loading puzzle: %s"), error->message); + msg = g_strdup_printf (_("Problem loading puzzle: %s"), + error -> message); root = gtk_widget_get_root (GTK_WIDGET (priv->picker)); toast_overlay = play_window_get_overlay (PLAY_WINDOW (root)); adw_toast_overlay_add_toast (ADW_TOAST_OVERLAY (toast_overlay), - adw_toast_new (msg)); + adw_toast_new (msg)); } } - else - { - g_print (" Download was canceled (uri is NULL)\n"); - } g_clear_object (&priv->downloader_cancellable); puzzle_set_set_downloader_state (self, DOWNLOADER_STATE_READY); } +static void +start_download_cb (PuzzleSet *self) +{ + GtkWindow *parent_window; + PuzzleSetPrivate *priv; + + g_autoptr (GError) error = NULL; + + priv = puzzle_set_get_instance_private (self); + + g_assert (priv->downloader != NULL); + g_assert (priv->downloader_cancellable == NULL); + parent_window = (GtkWindow *) gtk_widget_get_root (priv->picker); + priv->downloader_cancellable = g_cancellable_new (); + puzzle_downloader_run_async (priv->downloader, + parent_window, + priv->downloader_cancellable, + &error); + if (error) + { + /* FIXME(error): put up a dialog */ + g_warning ("Could not run downloader: %s\n", + error->message); + puzzle_set_set_downloader_state (self, DOWNLOADER_STATE_DISABLED); + return; + } + else + { + puzzle_set_set_downloader_state (self, DOWNLOADER_STATE_DOWNLOADING); + } +} /* Public Functions */ @@ -556,8 +517,6 @@ puzzle_set_get_puzzle_type (PuzzleSet *puzzle_set) { PuzzleSetPrivate *priv; - g_print ("puzzle_set_get_puzzle_type called for PuzzleSet: %s\n", puzzle_set_get_id (puzzle_set)); - g_return_val_if_fail (PUZZLE_IS_SET (puzzle_set), PUZZLE_SET_TYPE_RESOURCE); priv = puzzle_set_get_instance_private (puzzle_set); @@ -582,8 +541,6 @@ puzzle_set_get_short_name (PuzzleSet *puzzle_set) { PuzzleSetPrivate *priv; - g_print ("puzzle_set_get_short_name called for PuzzleSet: %s\n", puzzle_set_get_id (puzzle_set)); - g_return_val_if_fail (PUZZLE_IS_SET (puzzle_set), NULL); priv = puzzle_set_get_instance_private (puzzle_set); @@ -596,8 +553,6 @@ puzzle_set_get_long_name (PuzzleSet *puzzle_set) { PuzzleSetPrivate *priv; - g_print ("puzzle_set_get_long_name called for PuzzleSet: %s\n", puzzle_set_get_id (puzzle_set)); - g_return_val_if_fail (PUZZLE_IS_SET (puzzle_set), NULL); priv = puzzle_set_get_instance_private (puzzle_set); @@ -610,8 +565,6 @@ puzzle_set_get_locale (PuzzleSet *puzzle_set) { PuzzleSetPrivate *priv; - g_print ("puzzle_set_get_locale called for PuzzleSet: %s\n", puzzle_set_get_id (puzzle_set)); - g_return_val_if_fail (PUZZLE_IS_SET (puzzle_set), NULL); priv = puzzle_set_get_instance_private (puzzle_set); @@ -624,8 +577,6 @@ puzzle_set_get_language (PuzzleSet *puzzle_set) { PuzzleSetPrivate *priv; - g_print ("puzzle_set_get_language called for PuzzleSet: %s\n", puzzle_set_get_id (puzzle_set)); - g_return_val_if_fail (PUZZLE_IS_SET (puzzle_set), NULL); priv = puzzle_set_get_instance_private (puzzle_set); @@ -633,13 +584,15 @@ puzzle_set_get_language (PuzzleSet *puzzle_set) return puzzle_set_config_get_language (priv->config); } +/* Note: the difference between disabled and shown is that 'disabled' + * is set in the puzzleset and can't be overridden or change, and + * 'shown' is a user preference and can change. + */ gboolean puzzle_set_get_disabled (PuzzleSet *puzzle_set) { PuzzleSetPrivate *priv; - g_print ("puzzle_set_get_disabled called for PuzzleSet: %s\n", puzzle_set_get_id (puzzle_set)); - g_return_val_if_fail (PUZZLE_IS_SET (puzzle_set), TRUE); priv = puzzle_set_get_instance_private (puzzle_set); @@ -652,8 +605,6 @@ puzzle_set_get_shown (PuzzleSet *puzzle_set) { PuzzleSetPrivate *priv; - g_print ("puzzle_set_get_shown called for PuzzleSet: %s\n", puzzle_set_get_id (puzzle_set)); - g_return_val_if_fail (PUZZLE_IS_SET (puzzle_set), TRUE); priv = puzzle_set_get_instance_private (puzzle_set); @@ -663,12 +614,10 @@ puzzle_set_get_shown (PuzzleSet *puzzle_set) void puzzle_set_set_shown (PuzzleSet *puzzle_set, - gboolean shown) + gboolean shown) { PuzzleSetPrivate *priv; - g_print ("puzzle_set_set_shown called for PuzzleSet: %s, shown: %d\n", puzzle_set_get_id (puzzle_set), shown); - g_return_if_fail (PUZZLE_IS_SET (puzzle_set)); shown = !!shown; @@ -686,8 +635,6 @@ puzzle_set_get_auto_download (PuzzleSet *puzzle_set) { PuzzleSetPrivate *priv; - g_print ("puzzle_set_get_auto_download called for PuzzleSet: %s\n", puzzle_set_get_id (puzzle_set)); - g_return_val_if_fail (PUZZLE_IS_SET (puzzle_set), FALSE); priv = puzzle_set_get_instance_private (puzzle_set); @@ -705,8 +652,6 @@ puzzle_set_get_tags (PuzzleSet *puzzle_set) { PuzzleSetPrivate *priv; - g_print ("puzzle_set_get_tags called for PuzzleSet: %s\n", puzzle_set_get_id (puzzle_set)); - g_return_val_if_fail (PUZZLE_IS_SET (puzzle_set), 0); priv = puzzle_set_get_instance_private (puzzle_set); @@ -717,8 +662,6 @@ puzzle_set_get_tags (PuzzleSet *puzzle_set) void puzzle_set_puzzles_start (PuzzleSet *puzzle_set) { - g_print ("puzzle_set_puzzles_start called for PuzzleSet: %s\n", puzzle_set_get_id (puzzle_set)); - g_return_if_fail (PUZZLE_IS_SET (puzzle_set)); g_signal_emit (puzzle_set, puzzle_set_signals[PUZZLES_START], 0); @@ -728,8 +671,6 @@ void puzzle_set_change_phase (PuzzleSet *puzzle_set, PuzzlePhase phase) { - g_print ("puzzle_set_change_phase called for PuzzleSet: %s, phase: %d\n", puzzle_set_get_id (puzzle_set), phase); - g_return_if_fail (PUZZLE_IS_SET (puzzle_set)); g_signal_emit (puzzle_set, puzzle_set_signals[CHANGE_PHASE], 0, phase); @@ -738,7 +679,6 @@ puzzle_set_change_phase (PuzzleSet *puzzle_set, void puzzle_set_puzzles_done (PuzzleSet *puzzle_set) { - g_print ("puzzle_set_puzzles_done called for PuzzleSet: %s\n", puzzle_set_get_id (puzzle_set)); g_return_if_fail (PUZZLE_IS_SET (puzzle_set)); @@ -748,21 +688,19 @@ puzzle_set_puzzles_done (PuzzleSet *puzzle_set) void puzzle_set_reveal_canceled (PuzzleSet *puzzle_set) { - g_print ("puzzle_set_reveal_canceled called for PuzzleSet: %s\n", puzzle_set_get_id (puzzle_set)); g_return_if_fail (PUZZLE_IS_SET (puzzle_set)); g_signal_emit (puzzle_set, puzzle_set_signals[REVEAL_CANCELED], 0); } + GtkWidget * puzzle_set_get_widget (PuzzleSet *self, PuzzlePhase phase) { PuzzleSetPrivate *priv; - g_print ("puzzle_set_get_widget called for PuzzleSet: %s, phase: %d\n", puzzle_set_get_id (self), phase); - g_return_val_if_fail (PUZZLE_IS_SET (self), NULL); priv = puzzle_set_get_instance_private (self); @@ -773,6 +711,7 @@ puzzle_set_get_widget (PuzzleSet *self, return priv->xword; return NULL; + } IpuzPuzzle * @@ -781,8 +720,6 @@ puzzle_set_get_puzzle (PuzzleSet *self, { PuzzleSetPrivate *priv; - g_print ("puzzle_set_get_puzzle called for PuzzleSet: %s, phase: %d\n", puzzle_set_get_id (self), phase); - g_return_val_if_fail (PUZZLE_IS_SET (self), NULL); priv = puzzle_set_get_instance_private (self); @@ -799,8 +736,6 @@ puzzle_set_get_title (PuzzleSet *self, PuzzleSetPrivate *priv; const char *title = NULL; - g_print ("puzzle_set_get_title called for PuzzleSet: %s, phase: %d\n", puzzle_set_get_id (self), phase); - g_return_val_if_fail (PUZZLE_IS_SET (self), NULL); g_return_val_if_fail (phase != PUZZLE_PHASE_MAIN, NULL); @@ -822,12 +757,11 @@ puzzle_set_reset_puzzle (PuzzleSet *self) { PuzzleSetPrivate *priv; - g_print ("puzzle_set_reset_puzzle called for PuzzleSet: %s\n", puzzle_set_get_id (self)); - g_return_if_fail (PUZZLE_IS_SET (self)); priv = puzzle_set_get_instance_private (self); + /* FIXME(game): Make PlayXword an interface so we can have multiple types */ if (PLAY_IS_XWORD (priv->xword)) play_xword_clear_puzzle (PLAY_XWORD (priv->xword)); } @@ -838,12 +772,11 @@ puzzle_set_reveal_toggled (PuzzleSet *self, { PuzzleSetPrivate *priv; - g_print ("puzzle_set_reveal_toggled called for PuzzleSet: %s, reveal: %d\n", puzzle_set_get_id (self), reveal); - g_return_if_fail (PUZZLE_IS_SET (self)); priv = puzzle_set_get_instance_private (self); + /* FIXME(game): Make PlayXword an interface so we can have multiple types */ if (PLAY_IS_XWORD (priv->xword)) play_xword_set_reveal_mode (PLAY_XWORD (priv->xword), reveal ? GRID_REVEAL_ERRORS_BOARD : GRID_REVEAL_NONE); @@ -854,12 +787,11 @@ puzzle_set_show_hint (PuzzleSet *self) { PuzzleSetPrivate *priv; - g_print ("puzzle_set_show_hint called for PuzzleSet: %s\n", puzzle_set_get_id (self)); - g_return_if_fail (PUZZLE_IS_SET (self)); priv = puzzle_set_get_instance_private (self); + /* FIXME(game): Make PlayXword an interface so we can have multiple types */ if (PLAY_IS_XWORD (priv->xword)) play_xword_show_hint (PLAY_XWORD (priv->xword)); } @@ -870,8 +802,6 @@ puzzle_set_get_uri (PuzzleSet *self, { PuzzleSetPrivate *priv; - g_print ("puzzle_set_get_uri called for PuzzleSet: %s, phase: %d\n", puzzle_set_get_id (self), phase); - g_return_val_if_fail (PUZZLE_IS_SET (self), NULL); priv = puzzle_set_get_instance_private (self); @@ -887,6 +817,9 @@ puzzle_set_get_uri (PuzzleSet *self, return NULL; } +/* This is used from command line or dbus calls to load uris. It's + * different from puzzle_picker->load_uri which is internally driven, + * and requires a .ipuz file. */ void puzzle_set_import_uri (PuzzleSet *self, const gchar *uri) @@ -895,8 +828,6 @@ puzzle_set_import_uri (PuzzleSet *self, GtkWindow *parent_window; g_autoptr (GError) error = NULL; - g_print ("puzzle_set_import_uri called for PuzzleSet: %s, uri: %s\n", puzzle_set_get_id (self), uri); - g_return_if_fail (PUZZLE_IS_SET (self)); priv = puzzle_set_get_instance_private (self); @@ -905,7 +836,6 @@ puzzle_set_import_uri (PuzzleSet *self, if (priv->downloader_cancellable) { - g_print (" Cannot import multiple URIs simultaneously\n"); g_warning ("Currently can't import multiple uris simultaneously"); return; } @@ -919,20 +849,24 @@ puzzle_set_import_uri (PuzzleSet *self, &error); if (error) { - g_print (" Failed to run downloader: %s\n", error->message); - g_warning ("Could not run downloader: %s", error->message); + /* FIXME(error): put up a dialog */ + g_warning ("Could not run downloader: %s", + error->message); puzzle_set_set_downloader_state (self, DOWNLOADER_STATE_READY); return; } } +/* + * Public functions + */ + + static void network_available_cb (GNetworkMonitor *monitor, gboolean network_available, PuzzleSet *puzzle_set) { - g_print ("network_available_cb called for PuzzleSet: %s, network_available: %d\n", puzzle_set_get_id (puzzle_set), network_available); - if (network_available) { } @@ -947,8 +881,6 @@ puzzle_set_set_downloader_state (PuzzleSet *self, { PuzzleSetPrivate *priv; - g_print ("puzzle_set_set_downloader_state called for PuzzleSet: %s, state: %d\n", puzzle_set_get_id (self), state); - g_assert (PUZZLE_IS_SET (self)); priv = puzzle_set_get_instance_private (self); @@ -956,6 +888,7 @@ puzzle_set_set_downloader_state (PuzzleSet *self, if (priv->state == state) return; + /* There's no recovery from a disabled downloader */ if (priv->state != DOWNLOADER_STATE_DISABLED) { priv->state = state; @@ -973,8 +906,6 @@ won_changed_cb (PuzzleSet *self, PuzzleSetPrivate *priv; guint n_won; - g_print ("won_changed_cb called for PuzzleSet: %s\n", puzzle_set_get_id (self)); - priv = puzzle_set_get_instance_private (self); n_won = puzzle_set_model_get_n_won (model); @@ -992,8 +923,6 @@ items_changed_cb (PuzzleSet *self) PuzzleSetPrivate *priv; guint n_puzzles; - g_print ("items_changed_cb called for PuzzleSet: %s\n", puzzle_set_get_id (self)); - priv = puzzle_set_get_instance_private (self); n_puzzles = g_list_model_get_n_items (G_LIST_MODEL (priv->model)); @@ -1012,8 +941,6 @@ puzzle_set_set_config (PuzzleSet *self, PuzzleSetPrivate *priv; ConfigButtonType button_type; - g_print ("puzzle_set_set_config called for PuzzleSet: %s\n", puzzle_set_get_id (self)); - g_assert (PUZZLE_IS_SET (self)); priv = puzzle_set_get_instance_private (self); @@ -1034,10 +961,12 @@ puzzle_set_set_config (PuzzleSet *self, else priv->downloader = puzzle_downloader_new_from_config (config); + /* Everything loaded fine; show the button and listen for changes */ if (priv->downloader) { puzzle_set_set_downloader_state (self, DOWNLOADER_STATE_READY); + /* listen to network changes if we require network */ if (puzzle_downloader_get_requires_network (priv->downloader)) { GNetworkMonitor *monitor; @@ -1068,8 +997,6 @@ puzzle_set_get_n_puzzles (PuzzleSet *puzzle_set) { PuzzleSetPrivate *priv; - g_print ("puzzle_set_get_n_puzzles called for PuzzleSet: %s\n", puzzle_set_get_id (puzzle_set)); - g_return_val_if_fail (PUZZLE_IS_SET (puzzle_set), 0); priv = puzzle_set_get_instance_private (puzzle_set); @@ -1082,8 +1009,6 @@ puzzle_set_get_n_won (PuzzleSet *puzzle_set) { PuzzleSetPrivate *priv; - g_print ("puzzle_set_get_n_won called for PuzzleSet: %s\n", puzzle_set_get_id (puzzle_set)); - g_return_val_if_fail (PUZZLE_IS_SET (puzzle_set), 0); priv = puzzle_set_get_instance_private (puzzle_set); @@ -1091,6 +1016,7 @@ puzzle_set_get_n_won (PuzzleSet *puzzle_set) return priv->n_won; } +/* Can return NULL if resource can't be loaded. */ PuzzleSet * puzzle_set_new (GResource *resource) { @@ -1098,8 +1024,6 @@ puzzle_set_new (GResource *resource) PuzzleSet *puzzle_set; PuzzleSetConfig *config; - g_print ("puzzle_set_new called\n"); - puzzle_set = g_object_new (PUZZLE_TYPE_SET, "set-type", PUZZLE_SET_TYPE_RESOURCE, NULL); @@ -1111,7 +1035,46 @@ puzzle_set_new (GResource *resource) if (config) puzzle_set_set_config (puzzle_set, config); else - g_clear_object (&puzzle_set); + g_clear_object (& puzzle_set); return puzzle_set; +} + +void +puzzle_set_auto_download_all (GSettings *settings, GtkWindow *parent_window) +{ + g_auto (GStrv) shown_puzzle_sets = g_settings_get_strv (settings, "shown-puzzle-sets"); + GListModel *puzzle_set_list = puzzle_set_list_get (); + guint n_items = g_list_model_get_n_items (puzzle_set_list); + + for (guint i = 0; i < n_items; i++) + { + g_autoptr (PuzzleSet) puzzle_set = g_list_model_get_item (puzzle_set_list, i); + const gchar *id = puzzle_set_get_id (puzzle_set); + gboolean is_enabled = FALSE; + + for (gint j = 0; shown_puzzle_sets[j] != NULL; j++) + { + if (g_strcmp0 (id, shown_puzzle_sets[j]) == 0) + { + is_enabled = TRUE; + break; + } + } + + if (is_enabled && puzzle_set_get_auto_download (puzzle_set)) + { + PuzzleSetPrivate *priv = puzzle_set_get_instance_private (puzzle_set); + PuzzleDownloader *downloader = priv->downloader; + + if (downloader == NULL) + { + g_warning ("Auto-downloader: No downloader for puzzle set %s, skipping", id); + continue; + } + g_return_if_fail (GTK_IS_WINDOW (parent_window)); + puzzle_downloader_run_auto (downloader, priv->downloader_cancellable); + puzzle_set_set_downloader_state (puzzle_set, DOWNLOADER_STATE_DOWNLOADING); + } + } } \ No newline at end of file diff --git a/src/puzzle-set.h b/src/puzzle-set.h index 32148f76..e46dcefe 100644 --- a/src/puzzle-set.h +++ b/src/puzzle-set.h @@ -97,8 +97,6 @@ void puzzle_set_import_uri (PuzzleSet *puzzle_set, const gchar *uri); guint puzzle_set_get_n_puzzles (PuzzleSet *puzzle_set); guint puzzle_set_get_n_won (PuzzleSet *puzzle_set); +void puzzle_set_auto_download_all (GSettings *settings, GtkWindow *parent_window); - -void start_download_cb (PuzzleSet *puzzle_set, - GtkWindow *parent_window); G_END_DECLS -- GitLab From f6a4d0a809c95056b1a4e692a5d00e2cc90e07d4 Mon Sep 17 00:00:00 2001 From: Mahmoud Abdelghany Date: Fri, 28 Mar 2025 23:32:05 +0200 Subject: [PATCH 05/22] minor changes on my initial take --- src/crosswords-app.c | 14 ++------------ src/puzzle-downloader.c | 2 ++ 2 files changed, 4 insertions(+), 12 deletions(-) diff --git a/src/crosswords-app.c b/src/crosswords-app.c index 52a89c92..27e2b3ad 100644 --- a/src/crosswords-app.c +++ b/src/crosswords-app.c @@ -35,17 +35,6 @@ struct _CrosswordsApp AdwApplication parent; }; -static gboolean -check_network_availability (void) -{ - GResolver *resolver = g_resolver_get_default (); - GList *addresses = g_resolver_lookup_by_name (resolver, "google.com", NULL, NULL); - if (addresses) { - g_list_free_full (addresses, g_object_unref); - return TRUE; - } - return FALSE; -} static void crosswords_app_init (CrosswordsApp *app); static void crosswords_app_class_init (CrosswordsAppClass *klass); @@ -90,9 +79,10 @@ crosswords_app_activate (GApplication *app) gtk_window_present (window); gboolean auto_download = g_settings_get_boolean (settings, "auto-download-puzzle-sets"); + GNetworkMonitor *monitor = g_network_monitor_get_default (); if (auto_download) { - if (!check_network_availability ()) + if (!g_network_monitor_get_network_available (monitor)) { g_warning ("No network available, skipping auto-download\n"); return; diff --git a/src/puzzle-downloader.c b/src/puzzle-downloader.c index 660b0424..2d0baa45 100644 --- a/src/puzzle-downloader.c +++ b/src/puzzle-downloader.c @@ -339,7 +339,9 @@ convertor_finished_cb (GSubprocess *subprocess, _("Downloaded file is not a valid crossword.")); /* Clear subprocess info so we can run another command */ + g_clear_pointer (&downloader->cancel_dialog, adw_dialog_close); g_clear_object (&downloader->subprocess); + if (downloader->temp_file) { unlink (downloader->temp_file); -- GitLab From 55d5cce8fa234ebcfcd6b7b9f2d5e066b353881f Mon Sep 17 00:00:00 2001 From: Mahmoud Abdelghany Date: Sat, 29 Mar 2025 04:13:14 +0200 Subject: [PATCH 06/22] fix function i accidently broke --- src/puzzle-downloader.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/puzzle-downloader.c b/src/puzzle-downloader.c index 2d0baa45..3b21d56e 100644 --- a/src/puzzle-downloader.c +++ b/src/puzzle-downloader.c @@ -323,6 +323,7 @@ downloader_show_error_dialog (PuzzleDownloader *downloader, */ + void convertor_finished_cb (GSubprocess *subprocess, GAsyncResult *res, @@ -339,9 +340,7 @@ convertor_finished_cb (GSubprocess *subprocess, _("Downloaded file is not a valid crossword.")); /* Clear subprocess info so we can run another command */ - g_clear_pointer (&downloader->cancel_dialog, adw_dialog_close); g_clear_object (&downloader->subprocess); - if (downloader->temp_file) { unlink (downloader->temp_file); @@ -354,6 +353,7 @@ convertor_finished_cb (GSubprocess *subprocess, g_signal_emit (downloader, obj_signals [FINISHED], 0, uri, TRUE); } + /* Kicks off a convertor. We expect the potentially slow bits to be * done by now, and while we do this asynchronously we don't use the * cancel dialog. -- GitLab From bad6fc2e62e9dd5a975fb8bb331a266b31ba2694 Mon Sep 17 00:00:00 2001 From: Mahmoud Abdelghany Date: Sat, 29 Mar 2025 04:22:03 +0200 Subject: [PATCH 07/22] modified: src/puzzle-downloader.c --- src/puzzle-downloader.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/puzzle-downloader.c b/src/puzzle-downloader.c index 3b21d56e..8dafd619 100644 --- a/src/puzzle-downloader.c +++ b/src/puzzle-downloader.c @@ -484,7 +484,9 @@ command_finished_cb (GSubprocess *subprocess, /* Clear subprocess info so we can run another command */ downloader_cancel_timeout_remove (downloader); + g_clear_pointer (&downloader->cancel_dialog, adw_dialog_close); g_clear_object (&downloader->subprocess); + /* If we successfully run the subcommand and captured it's stdout, * we either load the file, or potentially convert it. */ if (temp_file) -- GitLab From 166e1229816d16279ab190683508f44bb640dfae Mon Sep 17 00:00:00 2001 From: Mahmoud Abdelghany Date: Sat, 29 Mar 2025 04:24:55 +0200 Subject: [PATCH 08/22] fix some wrong indentation in function declarations --- src/puzzle-downloader.h | 3 ++- src/puzzle-set.h | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/puzzle-downloader.h b/src/puzzle-downloader.h index fa6fdabf..9a9c246b 100644 --- a/src/puzzle-downloader.h +++ b/src/puzzle-downloader.h @@ -60,7 +60,8 @@ void puzzle_downloader_run_async (PuzzleDownloader *dow GtkWindow *parent_window, GCancellable *cancellable, GError **error); -void puzzle_downloader_run_auto (PuzzleDownloader *downloader, GCancellable *cancellable); +void puzzle_downloader_run_auto (PuzzleDownloader *downloader, + GCancellable *cancellable); G_END_DECLS diff --git a/src/puzzle-set.h b/src/puzzle-set.h index e46dcefe..a014571c 100644 --- a/src/puzzle-set.h +++ b/src/puzzle-set.h @@ -97,6 +97,7 @@ void puzzle_set_import_uri (PuzzleSet *puzzle_set, const gchar *uri); guint puzzle_set_get_n_puzzles (PuzzleSet *puzzle_set); guint puzzle_set_get_n_won (PuzzleSet *puzzle_set); -void puzzle_set_auto_download_all (GSettings *settings, GtkWindow *parent_window); +void puzzle_set_auto_download_all (GSettings *settings, + GtkWindow *parent_window); G_END_DECLS -- GitLab From 5eae42b3e4837f6e7aef267d999e4db1fc97e863 Mon Sep 17 00:00:00 2001 From: Mahmoud Abdelghany Date: Sun, 30 Mar 2025 21:42:40 +0200 Subject: [PATCH 09/22] fix even more style issues + removed the g_warning for completley silent stuff --- src/crosswords-app.c | 10 +++++----- src/puzzle-downloader.c | 2 -- src/puzzle-downloader.h | 4 ++-- 3 files changed, 7 insertions(+), 9 deletions(-) diff --git a/src/crosswords-app.c b/src/crosswords-app.c index 27e2b3ad..8255704c 100644 --- a/src/crosswords-app.c +++ b/src/crosswords-app.c @@ -78,15 +78,15 @@ crosswords_app_activate (GApplication *app) NULL); gtk_window_present (window); - gboolean auto_download = g_settings_get_boolean (settings, "auto-download-puzzle-sets"); - GNetworkMonitor *monitor = g_network_monitor_get_default (); + gboolean auto_download; + GNetworkMonitor *monitor; + + auto_download = g_settings_get_boolean(settings, "auto-download-puzzle-sets"); + monitor = g_network_monitor_get_default(); if (auto_download) { if (!g_network_monitor_get_network_available (monitor)) - { - g_warning ("No network available, skipping auto-download\n"); return; - } puzzle_set_auto_download_all (settings, window); } } diff --git a/src/puzzle-downloader.c b/src/puzzle-downloader.c index 8dafd619..b7606512 100644 --- a/src/puzzle-downloader.c +++ b/src/puzzle-downloader.c @@ -353,7 +353,6 @@ convertor_finished_cb (GSubprocess *subprocess, g_signal_emit (downloader, obj_signals [FINISHED], 0, uri, TRUE); } - /* Kicks off a convertor. We expect the potentially slow bits to be * done by now, and while we do this asynchronously we don't use the * cancel dialog. @@ -486,7 +485,6 @@ command_finished_cb (GSubprocess *subprocess, downloader_cancel_timeout_remove (downloader); g_clear_pointer (&downloader->cancel_dialog, adw_dialog_close); g_clear_object (&downloader->subprocess); - /* If we successfully run the subcommand and captured it's stdout, * we either load the file, or potentially convert it. */ if (temp_file) diff --git a/src/puzzle-downloader.h b/src/puzzle-downloader.h index 9a9c246b..a6cd4c67 100644 --- a/src/puzzle-downloader.h +++ b/src/puzzle-downloader.h @@ -60,8 +60,8 @@ void puzzle_downloader_run_async (PuzzleDownloader *dow GtkWindow *parent_window, GCancellable *cancellable, GError **error); -void puzzle_downloader_run_auto (PuzzleDownloader *downloader, - GCancellable *cancellable); +void puzzle_downloader_run_auto (PuzzleDownloader *downloader, + GCancellable *cancellable); G_END_DECLS -- GitLab From 10fa9aa8ff1201a528de12dc39a262e7e049a5fb Mon Sep 17 00:00:00 2001 From: Mahmoud Abdelghany Date: Sun, 30 Mar 2025 21:44:36 +0200 Subject: [PATCH 10/22] more g_warning removed --- src/puzzle-downloader.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/puzzle-downloader.c b/src/puzzle-downloader.c index b7606512..6d7d0fc2 100644 --- a/src/puzzle-downloader.c +++ b/src/puzzle-downloader.c @@ -520,9 +520,7 @@ auto_command_finished_cb (GSubprocess *subprocess, GAsyncResult *res, downloader_cancel_timeout_remove (downloader); if (g_subprocess_get_successful (subprocess)) temp_file = stdout_to_temp_file (subprocess); - else - g_warning ("Auto-download failed for downloader with header: %s", - downloader->header); + if (temp_file) { if (downloader->format == DOWNLOADER_FORMAT_IPUZ) -- GitLab From a7fc82907b9736fb94dec866d4b4f83681f652cc Mon Sep 17 00:00:00 2001 From: Mahmoud Abdelghany Date: Tue, 1 Apr 2025 05:52:23 +0200 Subject: [PATCH 11/22] moved the startyp logic to crosswords-app-startup.c/h and make puzzle_downloader_run_auto() use run_command --- src/crosswords-app-startup.c | 84 ++++++++++++++++++++++++++++++++++++ src/crosswords-app-startup.h | 32 ++++++++++++++ src/crosswords-app.c | 15 ++----- src/meson.build | 1 + src/puzzle-downloader.c | 79 +++++++++++++-------------------- src/puzzle-downloader.h | 2 +- src/puzzle-set.c | 49 +++++---------------- src/puzzle-set.h | 8 ++-- 8 files changed, 166 insertions(+), 104 deletions(-) create mode 100644 src/crosswords-app-startup.c create mode 100644 src/crosswords-app-startup.h diff --git a/src/crosswords-app-startup.c b/src/crosswords-app-startup.c new file mode 100644 index 00000000..02cf2765 --- /dev/null +++ b/src/crosswords-app-startup.c @@ -0,0 +1,84 @@ +/* crosswords-app-startup.c + * + * Copyright 2025 Mahmoud Abdelghany + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * SPDX-License-Identifier: GPL-3.0-or-later + */ + + +#include "crosswords-config.h" +#include +#include +#include "crosswords-app-startup.h" +#include "puzzle-downloader.h" +#include "puzzle-set-list.h" +#include "puzzle-set.h" + +void +crosswords_app_startup_init (GSettings *settings, GtkWindow *parent_window) +{ + gboolean auto_download; + GNetworkMonitor *monitor; + monitor = g_network_monitor_get_default (); + auto_download = g_settings_get_boolean (settings, "auto-download-puzzle-sets"); + if (auto_download) + { + if (!g_network_monitor_get_network_available (monitor)) + return; + + GStrv shown_puzzle_sets; + GListModel *puzzle_set_list; + guint n_items; + + shown_puzzle_sets = g_settings_get_strv(settings, "shown-puzzle-sets"); + puzzle_set_list = puzzle_set_list_get(); + n_items = g_list_model_get_n_items(puzzle_set_list); + + + for (guint i = 0; i < n_items; i++) + { + g_autoptr (PuzzleSet) puzzle_set = g_list_model_get_item (puzzle_set_list, i); + const gchar *id = puzzle_set_get_id (puzzle_set); + gboolean is_enabled = FALSE; + + for (gint j = 0; shown_puzzle_sets[j] != NULL; j++) + { + if (g_strcmp0 (id, shown_puzzle_sets[j]) == 0) + { + is_enabled = TRUE; + break; + } + } + + if (is_enabled && puzzle_set_get_auto_download (puzzle_set)) + { + + PuzzleDownloader *downloader; + GCancellable *downloader_cancellable; + + downloader = puzzle_set_get_downloader(puzzle_set); + downloader_cancellable = puzzle_set_get_downloader_cancellable(puzzle_set); + + if (downloader == NULL) + continue; + g_return_if_fail (GTK_IS_WINDOW (parent_window)); + puzzle_downloader_run_auto (downloader, downloader_cancellable); + puzzle_set_set_downloader_state (puzzle_set, + DOWNLOADER_STATE_DOWNLOADING); + } + } + } +} diff --git a/src/crosswords-app-startup.h b/src/crosswords-app-startup.h new file mode 100644 index 00000000..6798e99b --- /dev/null +++ b/src/crosswords-app-startup.h @@ -0,0 +1,32 @@ +/* crosswords-app-startup.h + * + * Copyright 2025 Mahmoud Abdelghany + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * SPDX-License-Identifier: GPL-3.0-or-later + */ + + +#pragma once + +#include +#include + +G_BEGIN_DECLS + +void crosswords_app_startup_init (GSettings *settings, + GtkWindow *parent_window); + +G_END_DECLS \ No newline at end of file diff --git a/src/crosswords-app.c b/src/crosswords-app.c index 8255704c..9a6b8bee 100644 --- a/src/crosswords-app.c +++ b/src/crosswords-app.c @@ -23,13 +23,12 @@ #include #include #include -#include #include "crosswords-app.h" #include "crosswords-credits.h" #include "crosswords-init.h" #include "play-window.h" #include "puzzle-downloader.h" -#include "puzzle-set.h" +#include "crosswords-app-startup.h" struct _CrosswordsApp { AdwApplication parent; @@ -78,17 +77,9 @@ crosswords_app_activate (GApplication *app) NULL); gtk_window_present (window); - gboolean auto_download; - GNetworkMonitor *monitor; - auto_download = g_settings_get_boolean(settings, "auto-download-puzzle-sets"); - monitor = g_network_monitor_get_default(); - if (auto_download) - { - if (!g_network_monitor_get_network_available (monitor)) - return; - puzzle_set_auto_download_all (settings, window); - } + crosswords_app_startup_init (settings, window); + } static void diff --git a/src/meson.build b/src/meson.build index f6461ad7..d25a8f53 100644 --- a/src/meson.build +++ b/src/meson.build @@ -36,6 +36,7 @@ common_sources = files ( 'puzzle-set-model.c', 'puzzle-stack.c', 'svg.c', + 'crosswords-app-startup.c' ) common_headers = files ( diff --git a/src/puzzle-downloader.c b/src/puzzle-downloader.c index 6d7d0fc2..8cf56f18 100644 --- a/src/puzzle-downloader.c +++ b/src/puzzle-downloader.c @@ -101,7 +101,9 @@ static const gchar *format_name[] = { static void puzzle_downloader_init (PuzzleDownloader *self); static void puzzle_downloader_class_init (PuzzleDownloaderClass *klass); static void puzzle_downloader_dispose (GObject *object); -static void downloader_cancel_timeout_add (PuzzleDownloader *downloader); +static void downloader_cancel_timeout_add (PuzzleDownloader *downloader, + guint timeout_ms, + GSourceFunc timeout_cb); static void downloader_cancel_timeout_remove (PuzzleDownloader *downloader); static void downloader_show_error_dialog (PuzzleDownloader *downloader, const gchar *secondary_text); @@ -281,13 +283,12 @@ auto_downloader_cancel_timeout_cb (PuzzleDownloader *downloader) } static void -downloader_cancel_timeout_add (PuzzleDownloader *downloader) +downloader_cancel_timeout_add (PuzzleDownloader *downloader, + guint timeout_ms, + GSourceFunc timeout_cb) { g_assert (downloader->cancel_timeout == 0); - - downloader->cancel_timeout = g_timeout_add (2000, - (GSourceFunc) downloader_cancel_timeout_cb, - downloader); + downloader->cancel_timeout = g_timeout_add (timeout_ms, timeout_cb, downloader); } static void @@ -588,9 +589,12 @@ generate_argv (PuzzleDownloader *downloader) static void -run_command (PuzzleDownloader *downloader, - GCancellable *cancellable, - GError **error) +run_command (PuzzleDownloader *downloader, + GCancellable *cancellable, + GError **error, + GAsyncReadyCallback finished_cb, + guint timeout_ms, + GSourceFunc timeout_cb) { g_autoptr (GError) tmp_error = NULL; gchar **argv; @@ -619,12 +623,12 @@ run_command (PuzzleDownloader *downloader, return; } - downloader_cancel_timeout_add (downloader); + downloader_cancel_timeout_add (downloader, timeout_ms, timeout_cb); downloader->wait_cancellable = g_cancellable_new (); g_subprocess_wait_async (downloader->subprocess, downloader->wait_cancellable, - (GAsyncReadyCallback) command_finished_cb, + finished_cb, downloader); } @@ -710,7 +714,7 @@ start_file_import (PuzzleDownloader *downloader) if (downloader->format != DOWNLOADER_FORMAT_IPUZ) downloader->temp_file = g_file_get_path (destination); - downloader_cancel_timeout_add (downloader); + downloader_cancel_timeout_add (downloader, 2000, (GSourceFunc) downloader_cancel_timeout_cb); downloader->wait_cancellable = g_cancellable_new (); flags = G_FILE_COPY_OVERWRITE; @@ -824,7 +828,9 @@ on_input_dialog_response (PuzzleDownloaderDialog *dialog, else if (downloader->type == DOWNLOADER_TYPE_ENTRY) downloader->string_value = puzzle_downloader_dialog_get_entry (dialog); - run_command (downloader, NULL, NULL); + run_command (downloader, NULL, NULL, + (GAsyncReadyCallback)command_finished_cb, 2000, + (GSourceFunc)downloader_cancel_timeout_cb); } else { @@ -979,7 +985,9 @@ puzzle_downloader_run_async (PuzzleDownloader *downloader, } else if (downloader->type == DOWNLOADER_TYPE_AUTO) { - run_command (downloader, cancellable, error); + run_command (downloader, cancellable, error, + (GAsyncReadyCallback)command_finished_cb, 2000, + (GSourceFunc)downloader_cancel_timeout_cb); } else { @@ -988,41 +996,12 @@ puzzle_downloader_run_async (PuzzleDownloader *downloader, } void -puzzle_downloader_run_auto (PuzzleDownloader *downloader, GCancellable *cancellable) +puzzle_downloader_run_auto (PuzzleDownloader *downloader, + GCancellable *cancellable) { - g_autoptr (GError) tmp_error = NULL; - gchar **argv; - g_return_if_fail (PUZZLE_IS_DOWNLOADER (downloader)); - g_return_if_fail (downloader->command_string != NULL); - - if (downloader->subprocess) - return; - - argv = generate_argv (downloader); - if (argv == NULL) - { - g_warning ("puzzle_downloader_run_auto: Invalid command in downloader: %s", downloader->command_string); - return; - } - - downloader->subprocess = g_subprocess_newv ((const char *const *)argv, - G_SUBPROCESS_FLAGS_STDOUT_PIPE, - &tmp_error); - g_strfreev (argv); - - if (tmp_error != NULL) - { - g_warning ("puzzle_downloader_run_auto: Error creating subprocess for downloader ID: %s: %s", - downloader->id, tmp_error->message); - g_clear_error (&tmp_error); - return; - } - downloader->cancel_timeout = g_timeout_add (10000, - (GSourceFunc) auto_downloader_cancel_timeout_cb, - downloader); - g_subprocess_wait_async (downloader->subprocess, - downloader->wait_cancellable, - (GAsyncReadyCallback) auto_command_finished_cb, - downloader); -} \ No newline at end of file + g_autoptr (GError) error = NULL; + run_command (downloader, cancellable, &error, + (GAsyncReadyCallback)auto_command_finished_cb, 10000, + (GSourceFunc)auto_downloader_cancel_timeout_cb); +} diff --git a/src/puzzle-downloader.h b/src/puzzle-downloader.h index a6cd4c67..bde35bcc 100644 --- a/src/puzzle-downloader.h +++ b/src/puzzle-downloader.h @@ -61,7 +61,7 @@ void puzzle_downloader_run_async (PuzzleDownloader *dow GCancellable *cancellable, GError **error); void puzzle_downloader_run_auto (PuzzleDownloader *downloader, - GCancellable *cancellable); + GCancellable *cancellable); G_END_DECLS diff --git a/src/puzzle-set.c b/src/puzzle-set.c index 53d686c0..8a2142dc 100644 --- a/src/puzzle-set.c +++ b/src/puzzle-set.c @@ -98,8 +98,6 @@ static void puzzle_set_real_change_phase (PuzzleSet *puzzle_set static void puzzle_set_real_puzzles_done (PuzzleSet *puzzle_set); static void puzzle_set_save (PuzzleSet *self); static void start_download_cb (PuzzleSet *self); -static void puzzle_set_set_downloader_state (PuzzleSet *self, - DownloaderState state); G_DEFINE_TYPE_WITH_PRIVATE (PuzzleSet, puzzle_set, G_TYPE_OBJECT); @@ -875,7 +873,7 @@ network_available_cb (GNetworkMonitor *monitor, } } -static void +void puzzle_set_set_downloader_state (PuzzleSet *self, DownloaderState state) { @@ -1040,41 +1038,16 @@ puzzle_set_new (GResource *resource) return puzzle_set; } -void -puzzle_set_auto_download_all (GSettings *settings, GtkWindow *parent_window) +PuzzleDownloader * +puzzle_set_get_downloader (PuzzleSet *puzzle_set) { - g_auto (GStrv) shown_puzzle_sets = g_settings_get_strv (settings, "shown-puzzle-sets"); - GListModel *puzzle_set_list = puzzle_set_list_get (); - guint n_items = g_list_model_get_n_items (puzzle_set_list); - - for (guint i = 0; i < n_items; i++) - { - g_autoptr (PuzzleSet) puzzle_set = g_list_model_get_item (puzzle_set_list, i); - const gchar *id = puzzle_set_get_id (puzzle_set); - gboolean is_enabled = FALSE; - - for (gint j = 0; shown_puzzle_sets[j] != NULL; j++) - { - if (g_strcmp0 (id, shown_puzzle_sets[j]) == 0) - { - is_enabled = TRUE; - break; - } - } + PuzzleSetPrivate *priv = puzzle_set_get_instance_private (puzzle_set); + return priv->downloader; +} - if (is_enabled && puzzle_set_get_auto_download (puzzle_set)) - { - PuzzleSetPrivate *priv = puzzle_set_get_instance_private (puzzle_set); - PuzzleDownloader *downloader = priv->downloader; - - if (downloader == NULL) - { - g_warning ("Auto-downloader: No downloader for puzzle set %s, skipping", id); - continue; - } - g_return_if_fail (GTK_IS_WINDOW (parent_window)); - puzzle_downloader_run_auto (downloader, priv->downloader_cancellable); - puzzle_set_set_downloader_state (puzzle_set, DOWNLOADER_STATE_DOWNLOADING); - } - } +GCancellable * +puzzle_set_get_downloader_cancellable (PuzzleSet *puzzle_set) +{ + PuzzleSetPrivate *priv = puzzle_set_get_instance_private (puzzle_set); + return priv->downloader_cancellable; } \ No newline at end of file diff --git a/src/puzzle-set.h b/src/puzzle-set.h index a014571c..603a3f4c 100644 --- a/src/puzzle-set.h +++ b/src/puzzle-set.h @@ -23,7 +23,7 @@ #include #include - +#include "puzzle-downloader.h" #include "puzzle-set-config.h" @@ -97,7 +97,9 @@ void puzzle_set_import_uri (PuzzleSet *puzzle_set, const gchar *uri); guint puzzle_set_get_n_puzzles (PuzzleSet *puzzle_set); guint puzzle_set_get_n_won (PuzzleSet *puzzle_set); -void puzzle_set_auto_download_all (GSettings *settings, - GtkWindow *parent_window); +PuzzleDownloader *puzzle_set_get_downloader (PuzzleSet *puzzle_set); +GCancellable *puzzle_set_get_downloader_cancellable (PuzzleSet *puzzle_set); +void puzzle_set_set_downloader_state (PuzzleSet *puzzle_set, + DownloaderState state); G_END_DECLS -- GitLab From da05ffcd6da743ff96d7b2bca36ffd40aeef50b5 Mon Sep 17 00:00:00 2001 From: Mahmoud Abdelghany Date: Tue, 1 Apr 2025 06:06:58 +0200 Subject: [PATCH 12/22] removed some not needed includes from puzzle-downloader.c --- src/crosswords-app-startup.h | 2 +- src/crosswords-app.c | 2 -- src/puzzle-downloader.c | 3 --- 3 files changed, 1 insertion(+), 6 deletions(-) diff --git a/src/crosswords-app-startup.h b/src/crosswords-app-startup.h index 6798e99b..08fd9460 100644 --- a/src/crosswords-app-startup.h +++ b/src/crosswords-app-startup.h @@ -29,4 +29,4 @@ G_BEGIN_DECLS void crosswords_app_startup_init (GSettings *settings, GtkWindow *parent_window); -G_END_DECLS \ No newline at end of file +G_END_DECLS diff --git a/src/crosswords-app.c b/src/crosswords-app.c index 9a6b8bee..0f36b5ec 100644 --- a/src/crosswords-app.c +++ b/src/crosswords-app.c @@ -77,9 +77,7 @@ crosswords_app_activate (GApplication *app) NULL); gtk_window_present (window); - crosswords_app_startup_init (settings, window); - } static void diff --git a/src/puzzle-downloader.c b/src/puzzle-downloader.c index 8cf56f18..d45210d2 100644 --- a/src/puzzle-downloader.c +++ b/src/puzzle-downloader.c @@ -24,9 +24,6 @@ #include #include "puzzle-downloader.h" #include "puzzle-downloader-dialog.h" -#include "puzzle-set.h" -#include "puzzle-set-list.h" -#include "puzzle-set-config.h" #define MASTER_SCHEMA "org.gnome.Crosswords.puzzle-sets" #define PUZZLE_SET_PATH_PREFIX "/org/gnome/Crosswords/puzzle-sets/" -- GitLab From 43ba057218a902d578a8850f6dcf58b09b3e31ea Mon Sep 17 00:00:00 2001 From: Mahmoud Abdelghany Date: Tue, 1 Apr 2025 06:17:11 +0200 Subject: [PATCH 13/22] gerror --- src/crosswords-app-startup.c | 3 ++- src/puzzle-downloader.c | 4 ++-- src/puzzle-downloader.h | 3 ++- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/crosswords-app-startup.c b/src/crosswords-app-startup.c index 02cf2765..455a61ca 100644 --- a/src/crosswords-app-startup.c +++ b/src/crosswords-app-startup.c @@ -30,6 +30,7 @@ void crosswords_app_startup_init (GSettings *settings, GtkWindow *parent_window) { + g_autoptr (GError) error = NULL; gboolean auto_download; GNetworkMonitor *monitor; monitor = g_network_monitor_get_default (); @@ -75,7 +76,7 @@ crosswords_app_startup_init (GSettings *settings, GtkWindow *parent_window) if (downloader == NULL) continue; g_return_if_fail (GTK_IS_WINDOW (parent_window)); - puzzle_downloader_run_auto (downloader, downloader_cancellable); + puzzle_downloader_run_auto (downloader, downloader_cancellable, &error); puzzle_set_set_downloader_state (puzzle_set, DOWNLOADER_STATE_DOWNLOADING); } diff --git a/src/puzzle-downloader.c b/src/puzzle-downloader.c index d45210d2..2ffca25f 100644 --- a/src/puzzle-downloader.c +++ b/src/puzzle-downloader.c @@ -994,10 +994,10 @@ puzzle_downloader_run_async (PuzzleDownloader *downloader, void puzzle_downloader_run_auto (PuzzleDownloader *downloader, - GCancellable *cancellable) + GCancellable *cancellable, + GError **error) { g_return_if_fail (PUZZLE_IS_DOWNLOADER (downloader)); - g_autoptr (GError) error = NULL; run_command (downloader, cancellable, &error, (GAsyncReadyCallback)auto_command_finished_cb, 10000, (GSourceFunc)auto_downloader_cancel_timeout_cb); diff --git a/src/puzzle-downloader.h b/src/puzzle-downloader.h index bde35bcc..9f6f16db 100644 --- a/src/puzzle-downloader.h +++ b/src/puzzle-downloader.h @@ -61,7 +61,8 @@ void puzzle_downloader_run_async (PuzzleDownloader *dow GCancellable *cancellable, GError **error); void puzzle_downloader_run_auto (PuzzleDownloader *downloader, - GCancellable *cancellable); + GCancellable *cancellable, + GError **error); G_END_DECLS -- GitLab From c4d9b5e73bf2a6a1778c5dd9017861371b92a249 Mon Sep 17 00:00:00 2001 From: Mahmoud Abdelghany Date: Tue, 1 Apr 2025 06:32:46 +0200 Subject: [PATCH 14/22] gerror --- src/puzzle-downloader.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/puzzle-downloader.c b/src/puzzle-downloader.c index 2ffca25f..de4de717 100644 --- a/src/puzzle-downloader.c +++ b/src/puzzle-downloader.c @@ -998,7 +998,7 @@ puzzle_downloader_run_auto (PuzzleDownloader *downloader, GError **error) { g_return_if_fail (PUZZLE_IS_DOWNLOADER (downloader)); - run_command (downloader, cancellable, &error, + run_command (downloader, cancellable, error, (GAsyncReadyCallback)auto_command_finished_cb, 10000, (GSourceFunc)auto_downloader_cancel_timeout_cb); } -- GitLab From 73dd65fdeab7d4a00ae271456463837efa9c0f35 Mon Sep 17 00:00:00 2001 From: Mahmoud Abdelghany Date: Tue, 1 Apr 2025 20:15:09 +0200 Subject: [PATCH 15/22] mainly style changes + made crosswords_app_startup_init() take no arguments --- src/crosswords-app-startup.c | 20 ++++++--- src/crosswords-app-startup.h | 3 +- src/crosswords-app.c | 2 +- src/puzzle-downloader.c | 74 +++++++++++++++++--------------- src/puzzle-set.c | 1 + src/puzzle-set.h | 82 ++++++++++++++++++------------------ 6 files changed, 95 insertions(+), 87 deletions(-) diff --git a/src/crosswords-app-startup.c b/src/crosswords-app-startup.c index 455a61ca..0ec0d79e 100644 --- a/src/crosswords-app-startup.c +++ b/src/crosswords-app-startup.c @@ -27,14 +27,18 @@ #include "puzzle-set-list.h" #include "puzzle-set.h" +static GSettings *global_settings = NULL; + void -crosswords_app_startup_init (GSettings *settings, GtkWindow *parent_window) +crosswords_app_startup_init () { g_autoptr (GError) error = NULL; gboolean auto_download; GNetworkMonitor *monitor; monitor = g_network_monitor_get_default (); - auto_download = g_settings_get_boolean (settings, "auto-download-puzzle-sets"); + + global_settings = g_settings_new ("org.gnome.Crosswords"); + auto_download = g_settings_get_boolean (global_settings, "auto-download-puzzle-sets"); if (auto_download) { if (!g_network_monitor_get_network_available (monitor)) @@ -44,17 +48,19 @@ crosswords_app_startup_init (GSettings *settings, GtkWindow *parent_window) GListModel *puzzle_set_list; guint n_items; - shown_puzzle_sets = g_settings_get_strv(settings, "shown-puzzle-sets"); + shown_puzzle_sets = g_settings_get_strv(global_settings, "shown-puzzle-sets"); puzzle_set_list = puzzle_set_list_get(); n_items = g_list_model_get_n_items(puzzle_set_list); - for (guint i = 0; i < n_items; i++) { - g_autoptr (PuzzleSet) puzzle_set = g_list_model_get_item (puzzle_set_list, i); - const gchar *id = puzzle_set_get_id (puzzle_set); + g_autoptr(PuzzleSet) puzzle_set; + const gchar *id; gboolean is_enabled = FALSE; + puzzle_set = g_list_model_get_item(puzzle_set_list, i); + id = puzzle_set_get_id(puzzle_set); + for (gint j = 0; shown_puzzle_sets[j] != NULL; j++) { if (g_strcmp0 (id, shown_puzzle_sets[j]) == 0) @@ -75,7 +81,7 @@ crosswords_app_startup_init (GSettings *settings, GtkWindow *parent_window) if (downloader == NULL) continue; - g_return_if_fail (GTK_IS_WINDOW (parent_window)); + puzzle_downloader_run_auto (downloader, downloader_cancellable, &error); puzzle_set_set_downloader_state (puzzle_set, DOWNLOADER_STATE_DOWNLOADING); diff --git a/src/crosswords-app-startup.h b/src/crosswords-app-startup.h index 08fd9460..2be81bb7 100644 --- a/src/crosswords-app-startup.h +++ b/src/crosswords-app-startup.h @@ -26,7 +26,6 @@ G_BEGIN_DECLS -void crosswords_app_startup_init (GSettings *settings, - GtkWindow *parent_window); +void crosswords_app_startup_init (void); G_END_DECLS diff --git a/src/crosswords-app.c b/src/crosswords-app.c index 0f36b5ec..8fef48ff 100644 --- a/src/crosswords-app.c +++ b/src/crosswords-app.c @@ -77,7 +77,6 @@ crosswords_app_activate (GApplication *app) NULL); gtk_window_present (window); - crosswords_app_startup_init (settings, window); } static void @@ -134,6 +133,7 @@ crosswords_app_startup (GApplication *app) actions, G_N_ELEMENTS (actions), app); + crosswords_app_startup_init (); } static void diff --git a/src/puzzle-downloader.c b/src/puzzle-downloader.c index de4de717..a8060e2d 100644 --- a/src/puzzle-downloader.c +++ b/src/puzzle-downloader.c @@ -510,36 +510,36 @@ command_finished_cb (GSubprocess *subprocess, } } -static void -auto_command_finished_cb (GSubprocess *subprocess, GAsyncResult *res, - PuzzleDownloader *downloader) +static void auto_command_finished_cb(GSubprocess* subprocess, + GAsyncResult* res, + PuzzleDownloader* downloader) { - gchar *temp_file = NULL; - downloader_cancel_timeout_remove (downloader); - if (g_subprocess_get_successful (subprocess)) - temp_file = stdout_to_temp_file (subprocess); - + gchar* temp_file = NULL; + downloader_cancel_timeout_remove(downloader); + if (g_subprocess_get_successful(subprocess)) + temp_file = stdout_to_temp_file(subprocess); + if (temp_file) + { + if (downloader->format == DOWNLOADER_FORMAT_IPUZ) { - if (downloader->format == DOWNLOADER_FORMAT_IPUZ) - { - g_autofree gchar *uri = NULL; + g_autofree gchar* uri = NULL; - uri = g_filename_to_uri (temp_file, NULL, NULL); - g_signal_emit (downloader, obj_signals[FINISHED], 0, uri, TRUE); - g_free (temp_file); - } - else - { - g_assert (downloader->temp_file == NULL); - downloader->temp_file = temp_file; - convert_puz_to_ipuz (downloader); - } + uri = g_filename_to_uri(temp_file, NULL, NULL); + g_signal_emit(downloader, obj_signals[FINISHED], 0, uri, TRUE); + g_free(temp_file); } - else + else { - g_signal_emit (downloader, obj_signals[FINISHED], 0, NULL, FALSE); + g_assert(downloader->temp_file == NULL); + downloader->temp_file = temp_file; + convert_puz_to_ipuz(downloader); } + } + else + { + g_signal_emit(downloader, obj_signals[FINISHED], 0, NULL, FALSE); + } } static gchar ** generate_argv (PuzzleDownloader *downloader) @@ -586,12 +586,12 @@ generate_argv (PuzzleDownloader *downloader) static void -run_command (PuzzleDownloader *downloader, - GCancellable *cancellable, - GError **error, - GAsyncReadyCallback finished_cb, - guint timeout_ms, - GSourceFunc timeout_cb) +run_command(PuzzleDownloader *downloader, + GCancellable *cancellable, + GError **error, + GAsyncReadyCallback finished_cb, + guint timeout_ms, + GSourceFunc timeout_cb) { g_autoptr (GError) tmp_error = NULL; gchar **argv; @@ -982,9 +982,12 @@ puzzle_downloader_run_async (PuzzleDownloader *downloader, } else if (downloader->type == DOWNLOADER_TYPE_AUTO) { - run_command (downloader, cancellable, error, - (GAsyncReadyCallback)command_finished_cb, 2000, - (GSourceFunc)downloader_cancel_timeout_cb); + run_command(downloader, + cancellable, + error, + (GAsyncReadyCallback)command_finished_cb, + 2000, + (GSourceFunc)downloader_cancel_timeout_cb); } else { @@ -993,11 +996,12 @@ puzzle_downloader_run_async (PuzzleDownloader *downloader, } void -puzzle_downloader_run_auto (PuzzleDownloader *downloader, - GCancellable *cancellable, - GError **error) +puzzle_downloader_run_auto(PuzzleDownloader *downloader, + GCancellable *cancellable, + GError **error) { g_return_if_fail (PUZZLE_IS_DOWNLOADER (downloader)); + run_command (downloader, cancellable, error, (GAsyncReadyCallback)auto_command_finished_cb, 10000, (GSourceFunc)auto_downloader_cancel_timeout_cb); diff --git a/src/puzzle-set.c b/src/puzzle-set.c index 8a2142dc..a16e28d7 100644 --- a/src/puzzle-set.c +++ b/src/puzzle-set.c @@ -1038,6 +1038,7 @@ puzzle_set_new (GResource *resource) return puzzle_set; } +/* FIXME(refactor): These downloader-related functions might not belong here. */ PuzzleDownloader * puzzle_set_get_downloader (PuzzleSet *puzzle_set) { diff --git a/src/puzzle-set.h b/src/puzzle-set.h index 603a3f4c..81cc3ea4 100644 --- a/src/puzzle-set.h +++ b/src/puzzle-set.h @@ -59,47 +59,45 @@ struct _PuzzleSetClass void (* reveal_canceled) (PuzzleSet *puzzle_set); }; -PuzzleSet *puzzle_set_new (GResource *resource); -PuzzleSetType puzzle_set_get_puzzle_type (PuzzleSet *puzzle_set); -const gchar *puzzle_set_get_id (PuzzleSet *puzzle_set); -const gchar *puzzle_set_get_short_name (PuzzleSet *puzzle_set); -const gchar *puzzle_set_get_long_name (PuzzleSet *puzzle_set); -const gchar *puzzle_set_get_locale (PuzzleSet *puzzle_set); -const gchar *puzzle_set_get_language (PuzzleSet *puzzle_set); -gboolean puzzle_set_get_disabled (PuzzleSet *puzzle_set); -gboolean puzzle_set_get_shown (PuzzleSet *puzzle_set); -void puzzle_set_set_shown (PuzzleSet *puzzle_set, - gboolean shown); -gboolean puzzle_set_get_auto_download (PuzzleSet *puzzle_set); -ConfigSetTags puzzle_set_get_tags (PuzzleSet *puzzle_set); - - -void puzzle_set_puzzles_start (PuzzleSet *puzzle_set); -void puzzle_set_change_phase (PuzzleSet *puzzle_set, - PuzzlePhase phase); -void puzzle_set_puzzles_done (PuzzleSet *puzzle_set); -void puzzle_set_reveal_canceled (PuzzleSet *puzzle_set); - - -GtkWidget *puzzle_set_get_widget (PuzzleSet *puzzle_set, - PuzzlePhase phase); -IpuzPuzzle *puzzle_set_get_puzzle (PuzzleSet *puzzle_set, - PuzzlePhase phase); -const gchar *puzzle_set_get_title (PuzzleSet *puzzle_set, - PuzzlePhase phase); -void puzzle_set_reset_puzzle (PuzzleSet *puzzle_set); -void puzzle_set_reveal_toggled (PuzzleSet *puzzle_set, - gboolean reveal); -void puzzle_set_show_hint (PuzzleSet *puzzle_set); -const gchar *puzzle_set_get_uri (PuzzleSet *puzzle_set, - PuzzlePhase phase); -void puzzle_set_import_uri (PuzzleSet *puzzle_set, - const gchar *uri); -guint puzzle_set_get_n_puzzles (PuzzleSet *puzzle_set); -guint puzzle_set_get_n_won (PuzzleSet *puzzle_set); -PuzzleDownloader *puzzle_set_get_downloader (PuzzleSet *puzzle_set); -GCancellable *puzzle_set_get_downloader_cancellable (PuzzleSet *puzzle_set); -void puzzle_set_set_downloader_state (PuzzleSet *puzzle_set, - DownloaderState state); +PuzzleSet *puzzle_set_new (GResource *resource); +PuzzleSetType puzzle_set_get_puzzle_type (PuzzleSet *puzzle_set); +const gchar *puzzle_set_get_id (PuzzleSet *puzzle_set); +const gchar *puzzle_set_get_short_name (PuzzleSet *puzzle_set); +const gchar *puzzle_set_get_long_name (PuzzleSet *puzzle_set); +const gchar *puzzle_set_get_locale (PuzzleSet *puzzle_set); +const gchar *puzzle_set_get_language (PuzzleSet *puzzle_set); +gboolean puzzle_set_get_disabled (PuzzleSet *puzzle_set); +gboolean puzzle_set_get_shown (PuzzleSet *puzzle_set); +void puzzle_set_set_shown (PuzzleSet *puzzle_set, + gboolean shown); +gboolean puzzle_set_get_auto_download (PuzzleSet *puzzle_set); +ConfigSetTags puzzle_set_get_tags (PuzzleSet *puzzle_set); + +void puzzle_set_puzzles_start (PuzzleSet *puzzle_set); +void puzzle_set_change_phase (PuzzleSet *puzzle_set, + PuzzlePhase phase); +void puzzle_set_puzzles_done (PuzzleSet *puzzle_set); +void puzzle_set_reveal_canceled (PuzzleSet *puzzle_set); + +GtkWidget *puzzle_set_get_widget (PuzzleSet *puzzle_set, + PuzzlePhase phase); +IpuzPuzzle *puzzle_set_get_puzzle (PuzzleSet *puzzle_set, + PuzzlePhase phase); +const gchar *puzzle_set_get_title (PuzzleSet *puzzle_set, + PuzzlePhase phase); +void puzzle_set_reset_puzzle (PuzzleSet *puzzle_set); +void puzzle_set_reveal_toggled (PuzzleSet *puzzle_set, + gboolean reveal); +void puzzle_set_show_hint (PuzzleSet *puzzle_set); +const gchar *puzzle_set_get_uri (PuzzleSet *puzzle_set, + PuzzlePhase phase); +void puzzle_set_import_uri (PuzzleSet *puzzle_set, + const gchar *uri); +guint puzzle_set_get_n_puzzles (PuzzleSet *puzzle_set); +guint puzzle_set_get_n_won (PuzzleSet *puzzle_set); +PuzzleDownloader *puzzle_set_get_downloader (PuzzleSet *puzzle_set); +GCancellable *puzzle_set_get_downloader_cancellable (PuzzleSet *puzzle_set); +void puzzle_set_set_downloader_state (PuzzleSet *puzzle_set, + DownloaderState state); G_END_DECLS -- GitLab From 1f18305dea49216d5fbc99bdca16d218da8d4255 Mon Sep 17 00:00:00 2001 From: Mahmoud Abdelghany Date: Tue, 1 Apr 2025 20:20:39 +0200 Subject: [PATCH 16/22] styling --- src/puzzle-downloader.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/puzzle-downloader.c b/src/puzzle-downloader.c index a8060e2d..d04d3ec7 100644 --- a/src/puzzle-downloader.c +++ b/src/puzzle-downloader.c @@ -98,9 +98,9 @@ static const gchar *format_name[] = { static void puzzle_downloader_init (PuzzleDownloader *self); static void puzzle_downloader_class_init (PuzzleDownloaderClass *klass); static void puzzle_downloader_dispose (GObject *object); -static void downloader_cancel_timeout_add (PuzzleDownloader *downloader, - guint timeout_ms, - GSourceFunc timeout_cb); +static void downloader_cancel_timeout_add (PuzzleDownloader *downloader, + guint timeout_ms, + GSourceFunc timeout_cb); static void downloader_cancel_timeout_remove (PuzzleDownloader *downloader); static void downloader_show_error_dialog (PuzzleDownloader *downloader, const gchar *secondary_text); -- GitLab From e6c130968fe63994f199771ed1e4d98e7204fd99 Mon Sep 17 00:00:00 2001 From: Mahmoud Abdelghany Date: Tue, 1 Apr 2025 20:22:51 +0200 Subject: [PATCH 17/22] more minor style fixes --- src/puzzle-downloader.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/puzzle-downloader.c b/src/puzzle-downloader.c index d04d3ec7..e37c1ada 100644 --- a/src/puzzle-downloader.c +++ b/src/puzzle-downloader.c @@ -483,6 +483,7 @@ command_finished_cb (GSubprocess *subprocess, downloader_cancel_timeout_remove (downloader); g_clear_pointer (&downloader->cancel_dialog, adw_dialog_close); g_clear_object (&downloader->subprocess); + /* If we successfully run the subcommand and captured it's stdout, * we either load the file, or potentially convert it. */ if (temp_file) -- GitLab From e0617106be9cc470176be2e953e49b16b01b958c Mon Sep 17 00:00:00 2001 From: Jonathan Blandford Date: Sat, 12 Apr 2025 14:34:27 -0700 Subject: [PATCH 18/22] rename crosswords-app-startup to crosswords-init-startup This matches crosswords-init now. The difference between it and crosswords_init though is the former is synchronous, while this will start background tasks. --- src/crosswords-app.c | 7 ++++--- ...rds-app-startup.c => crosswords-init-startup.c} | 14 +++++++++++--- ...rds-app-startup.h => crosswords-init-startup.h} | 2 +- src/meson.build | 3 ++- 4 files changed, 18 insertions(+), 8 deletions(-) rename src/{crosswords-app-startup.c => crosswords-init-startup.c} (95%) rename src/{crosswords-app-startup.h => crosswords-init-startup.h} (95%) diff --git a/src/crosswords-app.c b/src/crosswords-app.c index 8fef48ff..37111645 100644 --- a/src/crosswords-app.c +++ b/src/crosswords-app.c @@ -26,9 +26,11 @@ #include "crosswords-app.h" #include "crosswords-credits.h" #include "crosswords-init.h" +#include "crosswords-init-startup.h" #include "play-window.h" #include "puzzle-downloader.h" -#include "crosswords-app-startup.h" + + struct _CrosswordsApp { AdwApplication parent; @@ -123,8 +125,8 @@ crosswords_app_startup (GApplication *app) G_APPLICATION_CLASS (crosswords_app_parent_class)->startup (app); - crosswords_init (); + crosswords_init_startup (); gtk_application_set_accels_for_action (GTK_APPLICATION (app), "app.quit", quit_accels); gtk_application_set_accels_for_action (GTK_APPLICATION (app), "app.open", open_accels); @@ -133,7 +135,6 @@ crosswords_app_startup (GApplication *app) actions, G_N_ELEMENTS (actions), app); - crosswords_app_startup_init (); } static void diff --git a/src/crosswords-app-startup.c b/src/crosswords-init-startup.c similarity index 95% rename from src/crosswords-app-startup.c rename to src/crosswords-init-startup.c index 0ec0d79e..ec120d66 100644 --- a/src/crosswords-app-startup.c +++ b/src/crosswords-init-startup.c @@ -22,15 +22,17 @@ #include "crosswords-config.h" #include #include -#include "crosswords-app-startup.h" +#include "crosswords-init-startup.h" #include "puzzle-downloader.h" #include "puzzle-set-list.h" #include "puzzle-set.h" + static GSettings *global_settings = NULL; -void -crosswords_app_startup_init () + +static void +startup_auto_download (void) { g_autoptr (GError) error = NULL; gboolean auto_download; @@ -89,3 +91,9 @@ crosswords_app_startup_init () } } } + +void +crosswords_init_startup (void) +{ + startup_auto_download (); +} diff --git a/src/crosswords-app-startup.h b/src/crosswords-init-startup.h similarity index 95% rename from src/crosswords-app-startup.h rename to src/crosswords-init-startup.h index 2be81bb7..26d9342d 100644 --- a/src/crosswords-app-startup.h +++ b/src/crosswords-init-startup.h @@ -26,6 +26,6 @@ G_BEGIN_DECLS -void crosswords_app_startup_init (void); +void crosswords_init_startup (void); G_END_DECLS diff --git a/src/meson.build b/src/meson.build index d25a8f53..cdbb3fdc 100644 --- a/src/meson.build +++ b/src/meson.build @@ -6,6 +6,7 @@ common_sources = files ( 'crosswords-app.c', 'crosswords-credits.c', 'crosswords-init.c', + 'crosswords-init-startup.c', 'crosswords-misc.c', 'crosswords-quirks.c', 'contrib/gnome-languages.c', @@ -36,7 +37,6 @@ common_sources = files ( 'puzzle-set-model.c', 'puzzle-stack.c', 'svg.c', - 'crosswords-app-startup.c' ) common_headers = files ( @@ -45,6 +45,7 @@ common_headers = files ( 'crosswords-app.h', 'crosswords-credits.h', 'crosswords-init.h', + 'crosswords-init-startup.h', 'crosswords-misc.h', 'crosswords-quirks.h', 'contrib/gnome-languages.h', -- GitLab From 1195323a7fff979806d8ce83154daef37624a990 Mon Sep 17 00:00:00 2001 From: Jonathan Blandford Date: Sat, 12 Apr 2025 14:39:06 -0700 Subject: [PATCH 19/22] Change crosswords_inside_flatpak to get_inside_flatpak Quick drive-by fix --- src/crosswords-init.c | 7 +++---- src/crosswords-init.h | 6 ++++-- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/crosswords-init.c b/src/crosswords-init.c index 9f924690..d7c229a9 100644 --- a/src/crosswords-init.c +++ b/src/crosswords-init.c @@ -113,7 +113,7 @@ crosswords_init_environment (void) extend_env_var ("PATH", LIBEXECDIR); /* FIXME: see Issue #53 "downloader environments should be cleaned up for flatpaks" */ - if (crosswords_inside_flatpak ()) + if (crosswords_get_inside_flatpak ()) { GDir *extensions_dir; const gchar *name; @@ -167,8 +167,7 @@ crosswords_init (void) /** - * crosswords_inside_flatpak: - * @void: + * crosswords_get_inside_flatpak: * * Let's us know if we're currently running within a flatpak. While we * don't want to do anything dramatically different in that situation, @@ -179,7 +178,7 @@ crosswords_init (void) * Returns: %TRUE, if we're running within a flatpak **/ gboolean -crosswords_inside_flatpak (void) +crosswords_get_inside_flatpak (void) { static gsize guard = 0; diff --git a/src/crosswords-init.h b/src/crosswords-init.h index 8fe3bc95..419916d8 100644 --- a/src/crosswords-init.h +++ b/src/crosswords-init.h @@ -25,7 +25,9 @@ G_BEGIN_DECLS -void crosswords_init (void); -gboolean crosswords_inside_flatpak (void); + +void crosswords_init (void); +gboolean crosswords_get_inside_flatpak (void); + G_END_DECLS -- GitLab From 060cb31d2724e75fec12d38563d9dc287743980e Mon Sep 17 00:00:00 2001 From: Jonathan Blandford Date: Sat, 12 Apr 2025 14:40:18 -0700 Subject: [PATCH 20/22] Style fixes * g_autoptr pointers have to be initialized to NULL, or asan will complain * space before paren when calling a function * remove extra newlines * make sure we declare variables at the top of the scope, and in the order they're used. --- src/crosswords-init-startup.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/crosswords-init-startup.c b/src/crosswords-init-startup.c index ec120d66..4931d431 100644 --- a/src/crosswords-init-startup.c +++ b/src/crosswords-init-startup.c @@ -41,27 +41,28 @@ startup_auto_download (void) global_settings = g_settings_new ("org.gnome.Crosswords"); auto_download = g_settings_get_boolean (global_settings, "auto-download-puzzle-sets"); + if (auto_download) { - if (!g_network_monitor_get_network_available (monitor)) - return; - GStrv shown_puzzle_sets; GListModel *puzzle_set_list; guint n_items; - shown_puzzle_sets = g_settings_get_strv(global_settings, "shown-puzzle-sets"); - puzzle_set_list = puzzle_set_list_get(); - n_items = g_list_model_get_n_items(puzzle_set_list); + if (!g_network_monitor_get_network_available (monitor)) + return; + + shown_puzzle_sets = g_settings_get_strv (global_settings, "shown-puzzle-sets"); + puzzle_set_list = puzzle_set_list_get (); + n_items = g_list_model_get_n_items (puzzle_set_list); for (guint i = 0; i < n_items; i++) { - g_autoptr(PuzzleSet) puzzle_set; + g_autoptr (PuzzleSet) puzzle_set = NULL; const gchar *id; gboolean is_enabled = FALSE; - puzzle_set = g_list_model_get_item(puzzle_set_list, i); - id = puzzle_set_get_id(puzzle_set); + puzzle_set = g_list_model_get_item (puzzle_set_list, i); + id = puzzle_set_get_id (puzzle_set); for (gint j = 0; shown_puzzle_sets[j] != NULL; j++) { @@ -74,7 +75,6 @@ startup_auto_download (void) if (is_enabled && puzzle_set_get_auto_download (puzzle_set)) { - PuzzleDownloader *downloader; GCancellable *downloader_cancellable; -- GitLab From 72fb8d097c6922427f42bac48afc71cd52ff8fa2 Mon Sep 17 00:00:00 2001 From: Jonathan Blandford Date: Sat, 12 Apr 2025 14:52:42 -0700 Subject: [PATCH 21/22] Syle fixes Mostly spacing before parens, and newline fixes. But also some indentation as well. --- src/puzzle-downloader.c | 77 ++++++++++++++++++++++------------------- 1 file changed, 42 insertions(+), 35 deletions(-) diff --git a/src/puzzle-downloader.c b/src/puzzle-downloader.c index e37c1ada..2cd57416 100644 --- a/src/puzzle-downloader.c +++ b/src/puzzle-downloader.c @@ -24,9 +24,12 @@ #include #include "puzzle-downloader.h" #include "puzzle-downloader-dialog.h" + + #define MASTER_SCHEMA "org.gnome.Crosswords.puzzle-sets" #define PUZZLE_SET_PATH_PREFIX "/org/gnome/Crosswords/puzzle-sets/" + enum { FINISHED, N_SIGNALS @@ -511,37 +514,41 @@ command_finished_cb (GSubprocess *subprocess, } } -static void auto_command_finished_cb(GSubprocess* subprocess, - GAsyncResult* res, - PuzzleDownloader* downloader) +static void +auto_command_finished_cb (GSubprocess *subprocess, + GAsyncResult *res, + PuzzleDownloader *downloader) { gchar* temp_file = NULL; - downloader_cancel_timeout_remove(downloader); - if (g_subprocess_get_successful(subprocess)) - temp_file = stdout_to_temp_file(subprocess); + + downloader_cancel_timeout_remove (downloader); + + if (g_subprocess_get_successful (subprocess)) + temp_file = stdout_to_temp_file (subprocess); if (temp_file) - { - if (downloader->format == DOWNLOADER_FORMAT_IPUZ) { - g_autofree gchar* uri = NULL; + if (downloader->format == DOWNLOADER_FORMAT_IPUZ) + { + g_autofree gchar* uri = NULL; - uri = g_filename_to_uri(temp_file, NULL, NULL); - g_signal_emit(downloader, obj_signals[FINISHED], 0, uri, TRUE); - g_free(temp_file); + uri = g_filename_to_uri(temp_file, NULL, NULL); + g_signal_emit(downloader, obj_signals[FINISHED], 0, uri, TRUE); + g_free(temp_file); + } + else + { + g_assert(downloader->temp_file == NULL); + downloader->temp_file = temp_file; + convert_puz_to_ipuz(downloader); + } } - else + else { - g_assert(downloader->temp_file == NULL); - downloader->temp_file = temp_file; - convert_puz_to_ipuz(downloader); + g_signal_emit(downloader, obj_signals[FINISHED], 0, NULL, FALSE); } - } - else - { - g_signal_emit(downloader, obj_signals[FINISHED], 0, NULL, FALSE); - } } + static gchar ** generate_argv (PuzzleDownloader *downloader) { @@ -587,12 +594,12 @@ generate_argv (PuzzleDownloader *downloader) static void -run_command(PuzzleDownloader *downloader, - GCancellable *cancellable, - GError **error, - GAsyncReadyCallback finished_cb, - guint timeout_ms, - GSourceFunc timeout_cb) +run_command (PuzzleDownloader *downloader, + GCancellable *cancellable, + GError **error, + GAsyncReadyCallback finished_cb, + guint timeout_ms, + GSourceFunc timeout_cb) { g_autoptr (GError) tmp_error = NULL; gchar **argv; @@ -827,8 +834,8 @@ on_input_dialog_response (PuzzleDownloaderDialog *dialog, downloader->string_value = puzzle_downloader_dialog_get_entry (dialog); run_command (downloader, NULL, NULL, - (GAsyncReadyCallback)command_finished_cb, 2000, - (GSourceFunc)downloader_cancel_timeout_cb); + (GAsyncReadyCallback) command_finished_cb, 2000, + (GSourceFunc) downloader_cancel_timeout_cb); } else { @@ -983,12 +990,12 @@ puzzle_downloader_run_async (PuzzleDownloader *downloader, } else if (downloader->type == DOWNLOADER_TYPE_AUTO) { - run_command(downloader, - cancellable, - error, - (GAsyncReadyCallback)command_finished_cb, - 2000, - (GSourceFunc)downloader_cancel_timeout_cb); + run_command (downloader, + cancellable, + error, + (GAsyncReadyCallback)command_finished_cb, + 2000, + (GSourceFunc) downloader_cancel_timeout_cb); } else { -- GitLab From 2861ed03106780f2b018641afc444ab5411dd629 Mon Sep 17 00:00:00 2001 From: Jonathan Blandford Date: Sat, 12 Apr 2025 15:27:15 -0700 Subject: [PATCH 22/22] Drive by indentation fix --- src/edit-app.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/edit-app.c b/src/edit-app.c index 1ae3a243..d457ce95 100644 --- a/src/edit-app.c +++ b/src/edit-app.c @@ -167,7 +167,7 @@ edit_app_startup (GApplication *app) /* FIXME(refactor): clean up the crosswords-init / edit-init mess */ g_type_ensure (CELL_TYPE_PREVIEW); - g_type_ensure (EDIT_TYPE_AUTOFILL_DETAILS); + g_type_ensure (EDIT_TYPE_AUTOFILL_DETAILS); g_type_ensure (EDIT_TYPE_ACROSTIC_DETAILS); g_type_ensure (EDIT_TYPE_BARS); g_type_ensure (EDIT_TYPE_CELL); -- GitLab