Merge Jean Laroche's '797900_check_repair_crash' into maint.

This commit is contained in:
John Ralls 2020-09-05 15:50:28 -07:00
commit 706277e6a8
5 changed files with 110 additions and 9 deletions

View File

@ -1146,6 +1146,11 @@ gnc_main_window_all_finish_pending (void)
return FALSE; return FALSE;
} }
} }
if (gnc_gui_refresh_suspended ())
{
gnc_warning_dialog (NULL, "%s", "An operation is still pending, wait for it to complete before quitting ");
return FALSE;
}
return TRUE; return TRUE;
} }
@ -3707,7 +3712,7 @@ static gboolean
gnc_quartz_should_quit (GtkosxApplication *theApp, GncMainWindow *window) gnc_quartz_should_quit (GtkosxApplication *theApp, GncMainWindow *window)
{ {
if (gnc_main_window_all_finish_pending()) if (gnc_main_window_all_finish_pending())
return gnc_main_window_quit (window); return !gnc_main_window_quit (window);
return TRUE; return TRUE;
} }

View File

@ -413,6 +413,30 @@ gnc_plugin_page_account_tree_new (void)
G_DEFINE_TYPE_WITH_PRIVATE(GncPluginPageAccountTree, gnc_plugin_page_account_tree, GNC_TYPE_PLUGIN_PAGE) G_DEFINE_TYPE_WITH_PRIVATE(GncPluginPageAccountTree, gnc_plugin_page_account_tree, GNC_TYPE_PLUGIN_PAGE)
static void
prepare_scrubbing ()
{
gnc_suspend_gui_refresh ();
gnc_set_abort_scrub (FALSE);
}
static gboolean
finish (GncPluginPage* page)
{
if (gnc_get_ongoing_scrub ())
{
gboolean ret = gnc_verify_dialog (NULL, FALSE, "%s", "A scrubbing operation is currently pending, do you want to abort it?");
if (ret)
{
gnc_set_abort_scrub (TRUE);
gnc_resume_gui_refresh (); // This is so quit does not complain about an ongoing operation.
return TRUE;
}
return FALSE;
}
return TRUE;
}
static void static void
gnc_plugin_page_account_tree_class_init (GncPluginPageAccountTreeClass *klass) gnc_plugin_page_account_tree_class_init (GncPluginPageAccountTreeClass *klass)
{ {
@ -430,6 +454,8 @@ gnc_plugin_page_account_tree_class_init (GncPluginPageAccountTreeClass *klass)
gnc_plugin_class->save_page = gnc_plugin_page_account_tree_save_page; 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->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->focus_page_function = gnc_plugin_page_account_tree_focus_widget;
gnc_plugin_class->finish_pending = finish;
plugin_page_signals[ACCOUNT_SELECTED] = plugin_page_signals[ACCOUNT_SELECTED] =
g_signal_new ("account_selected", g_signal_new ("account_selected",
@ -1913,7 +1939,7 @@ gnc_plugin_page_account_tree_cmd_scrub (GtkAction *action, GncPluginPageAccountT
g_return_if_fail (account != NULL); g_return_if_fail (account != NULL);
gnc_suspend_gui_refresh (); prepare_scrubbing ();
window = GNC_WINDOW(GNC_PLUGIN_PAGE (page)->window); window = GNC_WINDOW(GNC_PLUGIN_PAGE (page)->window);
gnc_window_set_progressbar_window (window); gnc_window_set_progressbar_window (window);
@ -1939,7 +1965,7 @@ gnc_plugin_page_account_tree_cmd_scrub_sub (GtkAction *action, GncPluginPageAcco
g_return_if_fail (account != NULL); g_return_if_fail (account != NULL);
gnc_suspend_gui_refresh (); prepare_scrubbing ();
window = GNC_WINDOW(GNC_PLUGIN_PAGE (page)->window); window = GNC_WINDOW(GNC_PLUGIN_PAGE (page)->window);
gnc_window_set_progressbar_window (window); gnc_window_set_progressbar_window (window);
@ -1962,7 +1988,7 @@ gnc_plugin_page_account_tree_cmd_scrub_all (GtkAction *action, GncPluginPageAcco
Account *root = gnc_get_current_root_account (); Account *root = gnc_get_current_root_account ();
GncWindow *window; GncWindow *window;
gnc_suspend_gui_refresh (); prepare_scrubbing ();
window = GNC_WINDOW(GNC_PLUGIN_PAGE (page)->window); window = GNC_WINDOW(GNC_PLUGIN_PAGE (page)->window);
gnc_window_set_progressbar_window (window); gnc_window_set_progressbar_window (window);

View File

@ -1912,6 +1912,25 @@ gnc_plugin_page_register_update_edit_menu (GncPluginPage* page, gboolean hide)
gtk_action_set_visible (action, !hide || can_paste); gtk_action_set_visible (action, !hide || can_paste);
} }
static gboolean abort_scrub = FALSE;
static gboolean is_scrubbing = FALSE;
static gboolean
finish_scrub (GncPluginPage* page)
{
if (is_scrubbing)
{
gboolean ret = gnc_verify_dialog (NULL, FALSE, "%s", "A scrubbing operation is currently pending, do you want to abort it?");
if (ret)
{
abort_scrub = TRUE;
gnc_resume_gui_refresh (); // This is so quit does not complain about an ongoing operation.
return TRUE;
}
return FALSE;
}
return TRUE;
}
static gboolean static gboolean
gnc_plugin_page_register_finish_pending (GncPluginPage* page) gnc_plugin_page_register_finish_pending (GncPluginPage* page)
@ -1923,6 +1942,9 @@ gnc_plugin_page_register_finish_pending (GncPluginPage* page)
const gchar* name; const gchar* name;
gint response; gint response;
if (!finish_scrub (page))
return FALSE;
reg_page = GNC_PLUGIN_PAGE_REGISTER (page); reg_page = GNC_PLUGIN_PAGE_REGISTER (page);
priv = GNC_PLUGIN_PAGE_REGISTER_GET_PRIVATE (reg_page); priv = GNC_PLUGIN_PAGE_REGISTER_GET_PRIVATE (reg_page);
reg = gnc_ledger_display_get_split_register (priv->ledger); reg = gnc_ledger_display_get_split_register (priv->ledger);
@ -4977,6 +4999,7 @@ gnc_plugin_page_register_cmd_scrub_all (GtkAction* action,
} }
gnc_suspend_gui_refresh(); gnc_suspend_gui_refresh();
is_scrubbing = TRUE;
window = GNC_WINDOW (GNC_PLUGIN_PAGE (plugin_page)->window); window = GNC_WINDOW (GNC_PLUGIN_PAGE (plugin_page)->window);
gnc_window_set_progressbar_window (window); gnc_window_set_progressbar_window (window);
@ -5000,6 +5023,8 @@ gnc_plugin_page_register_cmd_scrub_all (GtkAction* action,
char* progress_msg = g_strdup_printf (message, curr_split_no, split_count); char* progress_msg = g_strdup_printf (message, curr_split_no, split_count);
gnc_window_show_progress (progress_msg, (100 * curr_split_no) / split_count); gnc_window_show_progress (progress_msg, (100 * curr_split_no) / split_count);
g_free (progress_msg); g_free (progress_msg);
if (abort_scrub)
break;
} }
xaccTransScrubOrphans (trans); xaccTransScrubOrphans (trans);
@ -5020,6 +5045,7 @@ gnc_plugin_page_register_cmd_scrub_all (GtkAction* action,
gnc_window_show_progress (NULL, -1.0); gnc_window_show_progress (NULL, -1.0);
gnc_resume_gui_refresh(); gnc_resume_gui_refresh();
is_scrubbing = FALSE;
LEAVE (" "); LEAVE (" ");
} }

View File

@ -57,6 +57,20 @@
#define G_LOG_DOMAIN "gnc.engine.scrub" #define G_LOG_DOMAIN "gnc.engine.scrub"
static QofLogModule log_module = G_LOG_DOMAIN; static QofLogModule log_module = G_LOG_DOMAIN;
static gboolean abort_now = FALSE;
static gint scrub_depth = 0;
void
gnc_set_abort_scrub (gboolean abort)
{
abort_now = abort;
}
gboolean
gnc_get_ongoing_scrub (void)
{
return scrub_depth > 0;
}
/* ================================================================ */ /* ================================================================ */
@ -64,10 +78,11 @@ void
xaccAccountTreeScrubOrphans (Account *acc, QofPercentageFunc percentagefunc) xaccAccountTreeScrubOrphans (Account *acc, QofPercentageFunc percentagefunc)
{ {
if (!acc) return; if (!acc) return;
scrub_depth ++;
xaccAccountScrubOrphans (acc, percentagefunc); xaccAccountScrubOrphans (acc, percentagefunc);
gnc_account_foreach_descendant(acc, gnc_account_foreach_descendant(acc,
(AccountCb)xaccAccountScrubOrphans, percentagefunc); (AccountCb)xaccAccountScrubOrphans, percentagefunc);
scrub_depth--;
} }
static void static void
@ -83,6 +98,7 @@ TransScrubOrphansFast (Transaction *trans, Account *root)
{ {
Split *split = node->data; Split *split = node->data;
Account *orph; Account *orph;
if (abort_now) break;
if (split->acc) continue; if (split->acc) continue;
@ -110,6 +126,7 @@ xaccAccountScrubOrphans (Account *acc, QofPercentageFunc percentagefunc)
guint current_split = 0; guint current_split = 0;
if (!acc) return; if (!acc) return;
scrub_depth++;
str = xaccAccountGetName (acc); str = xaccAccountGetName (acc);
str = str ? str : "(null)"; str = str ? str : "(null)";
@ -120,12 +137,12 @@ xaccAccountScrubOrphans (Account *acc, QofPercentageFunc percentagefunc)
for (node = splits; node; node = node->next) for (node = splits; node; node = node->next)
{ {
Split *split = node->data; Split *split = node->data;
if (current_split % 100 == 0) if (current_split % 100 == 0)
{ {
char *progress_msg = g_strdup_printf (message, str, current_split, total_splits); char *progress_msg = g_strdup_printf (message, str, current_split, total_splits);
(percentagefunc)(progress_msg, (100 * current_split) / total_splits); (percentagefunc)(progress_msg, (100 * current_split) / total_splits);
g_free (progress_msg); g_free (progress_msg);
if (abort_now) break;
} }
TransScrubOrphansFast (xaccSplitGetParent (split), TransScrubOrphansFast (xaccSplitGetParent (split),
@ -133,6 +150,7 @@ xaccAccountScrubOrphans (Account *acc, QofPercentageFunc percentagefunc)
current_split++; current_split++;
} }
(percentagefunc)(NULL, -1.0); (percentagefunc)(NULL, -1.0);
scrub_depth--;
} }
@ -148,6 +166,7 @@ xaccTransScrubOrphans (Transaction *trans)
for (node = trans->splits; node; node = node->next) for (node = trans->splits; node; node = node->next)
{ {
Split *split = node->data; Split *split = node->data;
if (abort_now) break;
if (split->acc) if (split->acc)
{ {
@ -183,9 +202,13 @@ void
xaccAccountScrubSplits (Account *account) xaccAccountScrubSplits (Account *account)
{ {
GList *node; GList *node;
scrub_depth++;
for (node = xaccAccountGetSplitList (account); node; node = node->next) for (node = xaccAccountGetSplitList (account); node; node = node->next)
{
if (abort_now) break;
xaccSplitScrub (node->data); xaccSplitScrub (node->data);
}
scrub_depth--;
} }
void void
@ -291,9 +314,11 @@ xaccSplitScrub (Split *split)
void void
xaccAccountTreeScrubImbalance (Account *acc, QofPercentageFunc percentagefunc) xaccAccountTreeScrubImbalance (Account *acc, QofPercentageFunc percentagefunc)
{ {
scrub_depth++;
xaccAccountScrubImbalance (acc, percentagefunc); xaccAccountScrubImbalance (acc, percentagefunc);
gnc_account_foreach_descendant(acc, gnc_account_foreach_descendant(acc,
(AccountCb)xaccAccountScrubImbalance, percentagefunc); (AccountCb)xaccAccountScrubImbalance, percentagefunc);
scrub_depth--;
} }
void void
@ -305,6 +330,7 @@ xaccAccountScrubImbalance (Account *acc, QofPercentageFunc percentagefunc)
gint split_count = 0, curr_split_no = 0; gint split_count = 0, curr_split_no = 0;
if (!acc) return; if (!acc) return;
scrub_depth++;
str = xaccAccountGetName(acc); str = xaccAccountGetName(acc);
str = str ? str : "(null)"; str = str ? str : "(null)";
@ -316,6 +342,7 @@ xaccAccountScrubImbalance (Account *acc, QofPercentageFunc percentagefunc)
{ {
Split *split = node->data; Split *split = node->data;
Transaction *trans = xaccSplitGetParent(split); Transaction *trans = xaccSplitGetParent(split);
if (abort_now) break;
PINFO("Start processing split %d of %d", PINFO("Start processing split %d of %d",
curr_split_no + 1, split_count); curr_split_no + 1, split_count);
@ -340,6 +367,7 @@ xaccAccountScrubImbalance (Account *acc, QofPercentageFunc percentagefunc)
curr_split_no++; curr_split_no++;
} }
(percentagefunc)(NULL, -1.0); (percentagefunc)(NULL, -1.0);
scrub_depth--;
} }
static Split * static Split *
@ -1243,19 +1271,22 @@ scrub_trans_currency_helper (Transaction *t, gpointer data)
static void static void
scrub_account_commodity_helper (Account *account, gpointer data) scrub_account_commodity_helper (Account *account, gpointer data)
{ {
scrub_depth++;
xaccAccountScrubCommodity (account); xaccAccountScrubCommodity (account);
xaccAccountDeleteOldData (account); xaccAccountDeleteOldData (account);
scrub_depth--;
} }
void void
xaccAccountTreeScrubCommodities (Account *acc) xaccAccountTreeScrubCommodities (Account *acc)
{ {
if (!acc) return; if (!acc) return;
scrub_depth++;
xaccAccountTreeForEachTransaction (acc, scrub_trans_currency_helper, NULL); xaccAccountTreeForEachTransaction (acc, scrub_trans_currency_helper, NULL);
scrub_account_commodity_helper (acc, NULL); scrub_account_commodity_helper (acc, NULL);
gnc_account_foreach_descendant (acc, scrub_account_commodity_helper, NULL); gnc_account_foreach_descendant (acc, scrub_account_commodity_helper, NULL);
scrub_depth--;
} }
/* ================================================================ */ /* ================================================================ */
@ -1315,13 +1346,14 @@ xaccAccountTreeScrubQuoteSources (Account *root, gnc_commodity_table *table)
LEAVE("Oops"); LEAVE("Oops");
return; return;
} }
scrub_depth++;
gnc_commodity_table_foreach_commodity (table, check_quote_source, &new_style); gnc_commodity_table_foreach_commodity (table, check_quote_source, &new_style);
move_quote_source(root, GINT_TO_POINTER(new_style)); move_quote_source(root, GINT_TO_POINTER(new_style));
gnc_account_foreach_descendant (root, move_quote_source, gnc_account_foreach_descendant (root, move_quote_source,
GINT_TO_POINTER(new_style)); GINT_TO_POINTER(new_style));
LEAVE("Migration done"); LEAVE("Migration done");
scrub_depth--;
} }
/* ================================================================ */ /* ================================================================ */
@ -1333,6 +1365,7 @@ xaccAccountScrubKvp (Account *account)
gchar *str2; gchar *str2;
if (!account) return; if (!account) return;
scrub_depth++;
qof_instance_get_kvp (QOF_INSTANCE (account), &v, 1, "notes"); qof_instance_get_kvp (QOF_INSTANCE (account), &v, 1, "notes");
if (G_VALUE_HOLDS_STRING (&v)) if (G_VALUE_HOLDS_STRING (&v))
@ -1350,6 +1383,7 @@ xaccAccountScrubKvp (Account *account)
qof_instance_slot_delete (QOF_INSTANCE (account), "placeholder"); qof_instance_slot_delete (QOF_INSTANCE (account), "placeholder");
qof_instance_slot_delete_if_empty (QOF_INSTANCE (account), "hbci"); qof_instance_slot_delete_if_empty (QOF_INSTANCE (account), "hbci");
scrub_depth--;
} }
/* ================================================================ */ /* ================================================================ */

View File

@ -69,6 +69,16 @@
for orphaned inodes. for orphaned inodes.
@{ */ @{ */
/** The gnc_set_abort_scrub () method causes a currently running scrub operation
* to stop, if abort is TRUE; gnc_set_abort_scrub(FALSE) must be called before
* any scrubbing operation.
*/
void gnc_set_abort_scrub (gboolean abort);
/** The gnc_get_ongoing_scrub () method returns TRUE if a scrub operation is ongoing.
*/
gboolean gnc_get_ongoing_scrub (void);
/** The xaccTransScrubOrphans() method scrubs only the splits in the /** The xaccTransScrubOrphans() method scrubs only the splits in the
* given transaction. * given transaction.
*/ */