Skip to content

Commit b51a706

Browse files
committed
Bug 797944 - Crash when opening new file from existing one
If you have report pages that are left open when the current book is 'Saved' and then use the 'File->Open' to open a new book Gnucash may crash. This was traced to the use of a g_idle_add to delay loading the reports in the pages that was not being cleared when the first book was closed. To fix this the g_idle_add has been removed and the loading of the report has been moved to the page focus function. By using a flag to indicate when pages are being restored, the report loading is delayed until the page is focused which has also decreased book loading time especially if no report pages were the current page when the book was closed.
1 parent bf9b267 commit b51a706

File tree

3 files changed

+46
-26
lines changed

3 files changed

+46
-26
lines changed

gnucash/gnome-utils/gnc-main-window.c

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,8 @@ typedef struct GncMainWindowPrivate
231231
* group, the values are structures of type
232232
* MergedActionEntry. */
233233
GHashTable *merged_actions_table;
234+
/** Set when restoring plugin pages */
235+
gboolean restoring_pages;
234236
} GncMainWindowPrivate;
235237

236238
GNC_DEFINE_TYPE_WITH_CODE(GncMainWindow, gnc_main_window, GTK_TYPE_WINDOW,
@@ -529,6 +531,14 @@ typedef struct
529531
} GncMainWindowSaveData;
530532

531533

534+
gboolean
535+
gnc_main_window_is_restoring_pages (GncMainWindow *window)
536+
{
537+
GncMainWindowPrivate *priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
538+
return priv->restoring_pages;
539+
}
540+
541+
532542
/* Iterator function to walk all pages in all windows, calling the
533543
* specified function for each page. */
534544
void
@@ -853,7 +863,7 @@ gnc_main_window_restore_window (GncMainWindow *window, GncMainWindowSaveData *da
853863
{
854864
gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(action), desired_visibility);
855865
}
856-
866+
priv->restoring_pages = TRUE;
857867
/* Now populate the window with pages. */
858868
for (i = 0; i < page_count; i++)
859869
{
@@ -865,7 +875,7 @@ gnc_main_window_restore_window (GncMainWindow *window, GncMainWindowSaveData *da
865875
while (gtk_events_pending ())
866876
gtk_main_iteration ();
867877
}
868-
878+
priv->restoring_pages = FALSE;
869879
/* Restore page ordering within the notebook. Use +1 notation so the
870880
* numbers in the page order match the page sections, at least for
871881
* the one window case. */
@@ -899,6 +909,9 @@ gnc_main_window_restore_window (GncMainWindow *window, GncMainWindowSaveData *da
899909
}
900910
gtk_notebook_set_current_page (GTK_NOTEBOOK(priv->notebook),
901911
order[0] - 1);
912+
913+
g_signal_emit_by_name (window, "page_changed",
914+
g_list_nth_data (priv->usage_order, 0));
902915
}
903916
if (order)
904917
{
@@ -2581,6 +2594,8 @@ gnc_main_window_init (GncMainWindow *window, void *data)
25812594
priv->event_handler_id =
25822595
qof_event_register_handler(gnc_main_window_event_handler, window);
25832596

2597+
priv->restoring_pages = FALSE;
2598+
25842599
/* Get the show_color_tabs value preference */
25852600
priv->show_color_tabs = gnc_prefs_get_bool(GNC_PREFS_GROUP_GENERAL, GNC_PREF_TAB_COLOR);
25862601

gnucash/gnome-utils/gnc-main-window.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -348,6 +348,16 @@ gboolean gnc_main_window_popup_menu_cb (GtkWidget *widget,
348348
*/
349349
void gnc_main_window_restore_all_windows(const GKeyFile *keyfile);
350350

351+
/** Check if the main window is restoring the plugin pages. This is
352+
* used on report pages to delay the creation of the report till the
353+
* page is focused.
354+
*
355+
* @param window When window whose pages should be checked.
356+
*
357+
* @return TRUE if pages are being restored
358+
*/
359+
gboolean gnc_main_window_is_restoring_pages (GncMainWindow *window);
360+
351361
/** Save the persistent state of all windows.
352362
*
353363
* @param keyfile The GKeyFile to contain persistent window state.

gnucash/gnome/gnc-plugin-page-report.c

Lines changed: 19 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,7 @@ static GncPluginPage *gnc_plugin_page_report_recreate_page (GtkWidget *window, G
153153
static void gnc_plugin_page_report_name_changed (GncPluginPage *page, const gchar *name);
154154
static void gnc_plugin_page_report_update_edit_menu (GncPluginPage *page, gboolean hide);
155155
static gboolean gnc_plugin_page_report_finish_pending (GncPluginPage *page);
156+
static void gnc_plugin_page_report_load_uri (GncPluginPage *page);
156157

157158
static int gnc_plugin_page_report_check_urltype(URLType t);
158159
//static void gnc_plugin_page_report_load_cb(gnc_html * html, URLType type,
@@ -243,12 +244,24 @@ gnc_plugin_page_report_focus_widget (GncPluginPage *report_plugin_page)
243244
if (GNC_IS_PLUGIN_PAGE_REPORT(report_plugin_page))
244245
{
245246
GncPluginPageReportPrivate *priv = GNC_PLUGIN_PAGE_REPORT_GET_PRIVATE(report_plugin_page);
246-
GtkWidget *widget = gnc_html_get_widget (priv->html);
247+
GtkWidget *window;
247248

248-
if (GTK_IS_WIDGET(widget))
249+
if (!priv)
250+
return FALSE;
251+
252+
window = gnc_plugin_page_get_window (report_plugin_page);
253+
254+
if (window && !gnc_main_window_is_restoring_pages (GNC_MAIN_WINDOW(window)))
249255
{
250-
if (!gtk_widget_is_focus (GTK_WIDGET(widget)))
251-
gtk_widget_grab_focus (GTK_WIDGET(widget));
256+
GtkWidget * widget = gnc_html_get_widget (priv->html);
257+
258+
gnc_plugin_page_report_load_uri (report_plugin_page);
259+
260+
if (GTK_IS_WIDGET(widget))
261+
{
262+
if (!gtk_widget_is_focus (GTK_WIDGET(widget)))
263+
gtk_widget_grab_focus (GTK_WIDGET(widget));
264+
}
252265
}
253266
}
254267
return FALSE;
@@ -332,7 +345,7 @@ gnc_plugin_page_report_set_progressbar (GncPluginPage *page, gboolean set)
332345
gtk_widget_set_size_request (GTK_WIDGET(progressbar), -1, -1); //reset
333346
}
334347

335-
static gboolean
348+
static void
336349
gnc_plugin_page_report_load_uri (GncPluginPage *page)
337350
{
338351
GncPluginPageReport *report;
@@ -346,7 +359,7 @@ gnc_plugin_page_report_load_uri (GncPluginPage *page)
346359
report = GNC_PLUGIN_PAGE_REPORT(page);
347360
priv = GNC_PLUGIN_PAGE_REPORT_GET_PRIVATE(report);
348361
if (!priv)
349-
return FALSE; // No priv means the page doesn't exist anymore.
362+
return; // No priv means the page doesn't exist anymore.
350363

351364
DEBUG( "Load uri id=%d", priv->reportId );
352365
id_name = g_strdup_printf("id=%d", priv->reportId );
@@ -375,20 +388,6 @@ gnc_plugin_page_report_load_uri (GncPluginPage *page)
375388

376389
// this resets the window for the progressbar to NULL
377390
gnc_window_set_progressbar_window( NULL );
378-
379-
return FALSE;
380-
}
381-
382-
static void
383-
gnc_plugin_page_report_realize_uri (GtkWidget *widget, GncPluginPage *page)
384-
{
385-
GtkAllocation allocation;
386-
387-
gtk_widget_get_allocation (widget, &allocation);
388-
PINFO("Realized Container size is %dw x %dh", allocation.width, allocation.height);
389-
390-
/* load uri when view idle */
391-
g_idle_add ((GSourceFunc)gnc_plugin_page_report_load_uri, page);
392391
}
393392

394393
static
@@ -457,10 +456,6 @@ gnc_plugin_page_report_create_widget( GncPluginPage *page )
457456
// FIXME. This is f^-1(f(x)), isn't it?
458457
DEBUG( "id=%d", priv->reportId );
459458

460-
/* load uri when view is realized */
461-
g_signal_connect (G_OBJECT(GTK_WIDGET(priv->container)), "realize",
462-
G_CALLBACK(gnc_plugin_page_report_realize_uri), page);
463-
464459
g_signal_connect (G_OBJECT(page), "inserted",
465460
G_CALLBACK(gnc_plugin_page_inserted_cb),
466461
NULL);

0 commit comments

Comments
 (0)