From 6ee537e1a7fd053129c7cdaf2b3dcf7d34aa9cfa Mon Sep 17 00:00:00 2001 From: Robert Fewell <14uBobIT@gmail.com> Date: Tue, 20 Oct 2020 14:42:32 +0100 Subject: [PATCH] Allow the Check&Repair routine to be cancellable from CoA Add a callback for a keypress event when on the Accounts page that checks for the Escape key and presents a dialog to confirm whether to abort the Check&Repair. A similar dialog is used if you decide to quit Gnucash while the Check&Repair is still running. --- gnucash/gnome/gnc-plugin-page-account-tree.c | 80 ++++++++++++++++---- libgnucash/engine/Scrub.c | 6 ++ libgnucash/engine/Scrub.h | 1 + 3 files changed, 73 insertions(+), 14 deletions(-) diff --git a/gnucash/gnome/gnc-plugin-page-account-tree.c b/gnucash/gnome/gnc-plugin-page-account-tree.c index 7d5352c247..07654d1b76 100644 --- a/gnucash/gnome/gnc-plugin-page-account-tree.c +++ b/gnucash/gnome/gnc-plugin-page-account-tree.c @@ -425,6 +425,8 @@ gnc_plugin_page_account_tree_new (void) G_DEFINE_TYPE_WITH_PRIVATE(GncPluginPageAccountTree, gnc_plugin_page_account_tree, GNC_TYPE_PLUGIN_PAGE) +static gboolean show_abort_verify = TRUE; + static void prepare_scrubbing () { @@ -432,21 +434,42 @@ prepare_scrubbing () gnc_set_abort_scrub (FALSE); } +static void +finish_scrubbing (GncWindow *window, gulong handler_id) +{ + g_signal_handler_disconnect (G_OBJECT(window), handler_id); + show_abort_verify = TRUE; + gnc_resume_gui_refresh (); +} + static gboolean -finish (GncPluginPage* page) +gnc_plugin_page_account_finish_pending (GncPluginPage* page) { if (gnc_get_ongoing_scrub ()) { - gboolean ret = gnc_verify_dialog (GTK_WINDOW (gnc_plugin_page_get_window (GNC_PLUGIN_PAGE (page))), FALSE, _("'Check & Repair' is currently running, do you want to abort it?")); - if (ret) + if (show_abort_verify) { - gnc_set_abort_scrub (TRUE); - gnc_resume_gui_refresh (); // This is so quit does not complain about an ongoing operation. - return TRUE; + gboolean ret = gnc_verify_dialog (GTK_WINDOW(gnc_plugin_page_get_window + (GNC_PLUGIN_PAGE(page))), FALSE, + _("'Check & Repair' is currently running, do you want to abort it?")); + + show_abort_verify = FALSE; + + if (ret) + gnc_set_abort_scrub (TRUE); + + return ret; // verify response + } + else + { + if (gnc_get_abort_scrub ()) + return TRUE; // close + else + return FALSE; // no close } - return FALSE; } - return TRUE; + else + return TRUE; // normal close } static void @@ -466,8 +489,7 @@ gnc_plugin_page_account_tree_class_init (GncPluginPageAccountTreeClass *klass) gnc_plugin_class->save_page = gnc_plugin_page_account_tree_save_page; gnc_plugin_class->recreate_page = gnc_plugin_page_account_tree_recreate_page; gnc_plugin_class->focus_page_function = gnc_plugin_page_account_tree_focus_widget; - gnc_plugin_class->finish_pending = finish; - + gnc_plugin_class->finish_pending = gnc_plugin_page_account_finish_pending; plugin_page_signals[ACCOUNT_SELECTED] = g_signal_new ("account_selected", @@ -1955,17 +1977,42 @@ gnc_plugin_page_account_tree_cmd_lots (GtkAction *action, gnc_lot_viewer_dialog (GTK_WINDOW(window), account); } +static gboolean scrub_kp_handler (GtkWidget *widget, GdkEventKey *event, gpointer data) +{ + if (event->length == 0) return FALSE; + + switch (event->keyval) + { + case GDK_KEY_Escape: + { + gboolean abort_scrub = gnc_verify_dialog (GTK_WINDOW(widget), FALSE, + _("'Check & Repair' is currently running, do you want to abort it?")); + + if (abort_scrub) + gnc_set_abort_scrub (TRUE); + + return TRUE; + } + default: + break; + } + return FALSE; +} + static void gnc_plugin_page_account_tree_cmd_scrub (GtkAction *action, GncPluginPageAccountTree *page) { Account *account = gnc_plugin_page_account_tree_get_current_account (page); GncWindow *window; + gulong scrub_kp_handler_ID; g_return_if_fail (account != NULL); prepare_scrubbing (); window = GNC_WINDOW(GNC_PLUGIN_PAGE (page)->window); + scrub_kp_handler_ID = g_signal_connect (G_OBJECT(window), "key-press-event", + G_CALLBACK(scrub_kp_handler), NULL); gnc_window_set_progressbar_window (window); xaccAccountScrubOrphans (account, gnc_window_show_progress); @@ -1977,8 +2024,7 @@ gnc_plugin_page_account_tree_cmd_scrub (GtkAction *action, GncPluginPageAccountT gncScrubBusinessAccount(account, gnc_window_show_progress); - - gnc_resume_gui_refresh (); + finish_scrubbing (window, scrub_kp_handler_ID); } static void @@ -1986,12 +2032,15 @@ gnc_plugin_page_account_tree_cmd_scrub_sub (GtkAction *action, GncPluginPageAcco { Account *account = gnc_plugin_page_account_tree_get_current_account (page); GncWindow *window; + gulong scrub_kp_handler_ID; g_return_if_fail (account != NULL); prepare_scrubbing (); window = GNC_WINDOW(GNC_PLUGIN_PAGE (page)->window); + scrub_kp_handler_ID = g_signal_connect (G_OBJECT(window), "key-press-event", + G_CALLBACK(scrub_kp_handler), NULL); gnc_window_set_progressbar_window (window); xaccAccountTreeScrubOrphans (account, gnc_window_show_progress); @@ -2003,7 +2052,7 @@ gnc_plugin_page_account_tree_cmd_scrub_sub (GtkAction *action, GncPluginPageAcco gncScrubBusinessAccountTree(account, gnc_window_show_progress); - gnc_resume_gui_refresh (); + finish_scrubbing (window, scrub_kp_handler_ID); } static void @@ -2011,10 +2060,13 @@ gnc_plugin_page_account_tree_cmd_scrub_all (GtkAction *action, GncPluginPageAcco { Account *root = gnc_get_current_root_account (); GncWindow *window; + gulong scrub_kp_handler_ID; prepare_scrubbing (); window = GNC_WINDOW(GNC_PLUGIN_PAGE (page)->window); + scrub_kp_handler_ID = g_signal_connect (G_OBJECT(window), "key-press-event", + G_CALLBACK(scrub_kp_handler), NULL); gnc_window_set_progressbar_window (window); xaccAccountTreeScrubOrphans (root, gnc_window_show_progress); @@ -2025,7 +2077,7 @@ gnc_plugin_page_account_tree_cmd_scrub_all (GtkAction *action, GncPluginPageAcco gncScrubBusinessAccountTree(root, gnc_window_show_progress); - gnc_resume_gui_refresh (); + finish_scrubbing (window, scrub_kp_handler_ID); } /** @} */ diff --git a/libgnucash/engine/Scrub.c b/libgnucash/engine/Scrub.c index a16c0cf915..66a261324b 100644 --- a/libgnucash/engine/Scrub.c +++ b/libgnucash/engine/Scrub.c @@ -66,6 +66,12 @@ gnc_set_abort_scrub (gboolean abort) abort_now = abort; } +gboolean +gnc_get_abort_scrub (void) +{ + return abort_now; +} + gboolean gnc_get_ongoing_scrub (void) { diff --git a/libgnucash/engine/Scrub.h b/libgnucash/engine/Scrub.h index bfaea845af..34ec0e5985 100644 --- a/libgnucash/engine/Scrub.h +++ b/libgnucash/engine/Scrub.h @@ -74,6 +74,7 @@ * any scrubbing operation. */ void gnc_set_abort_scrub (gboolean abort); +gboolean gnc_get_abort_scrub (void); /** The gnc_get_ongoing_scrub () method returns TRUE if a scrub operation is ongoing. */