[Gnucash-changes] r12982 - gnucash/trunk/src - Register book open/close callbacks during gui init.

Chris Shoemaker chris at cvs.gnucash.org
Thu Jan 26 12:38:27 EST 2006


Author: chris
Date: 2006-01-26 12:38:26 -0500 (Thu, 26 Jan 2006)
New Revision: 12982
Trac: http://svn.gnucash.org/trac/changeset/12982

Modified:
   gnucash/trunk/src/gnome-utils/gnc-main-window.c
   gnucash/trunk/src/gnome-utils/gnc-main-window.h
   gnucash/trunk/src/gnome/top-level.c
Log:
   Register book open/close callbacks during gui init.
   Split handling of persistent application state into book-level data 
   and window-level data.


Modified: gnucash/trunk/src/gnome/top-level.c
===================================================================
--- gnucash/trunk/src/gnome/top-level.c	2006-01-26 14:25:29 UTC (rev 12981)
+++ gnucash/trunk/src/gnome/top-level.c	2006-01-26 17:38:26 UTC (rev 12982)
@@ -67,6 +67,8 @@
 #include "top-level.h"
 #include "window-report.h"
 #include "gnc-window.h"
+#include "gnc-gkeyfile-utils.h"
+#include <g-wrap-wct.h>
 
 
 /** GLOBALS *********************************************************/
@@ -195,6 +197,184 @@
   return TRUE;
 }
 
+/** Restore all persistent program state.  This function finds the
+ *  "new" state file associated with a specific book guid.  It then
+ *  iterates through this state information, calling a helper function
+ *  to recreate each open window.
+ *
+ *  If the "new" state file cannot be found, this function will open
+ *  an account tree window and then attempt to invoke the old gnucash
+ *  1.x state routines.  This provides a fluid transition for users
+ *  from the old to the new state systems.
+ *
+ *  @note The name of the state file is based on the name of the data
+ *  file, not the path name of the data file.  If there are multiple
+ *  data files with the same name, the state files will be suffixed
+ *  with a number.  E.G. test_account, test_account_2, test_account_3,
+ *  etc.
+ *
+ *  @param session A pointer to the current session.
+ *
+ *  @param unused An unused pointer. */
+static void
+gnc_restore_all_state (gpointer session, gpointer unused)
+{
+    GKeyFile *keyfile = NULL;
+    QofBook *book;
+    const GUID *guid;
+    const gchar *url, *guid_string;    
+    gchar *file_guid, *filename = NULL;
+    GError *error = NULL;
+    
+    url = qof_session_get_url(session);
+    ENTER("session %p (%s)", session, url);
+    if (!url) {
+        LEAVE("no url, nothing to do");
+        return;
+    }
+    
+    /* Get the book GUID */
+    book = qof_session_get_book(session);
+    guid = qof_entity_get_guid(QOF_ENTITY(book));
+    guid_string = guid_to_string(guid);
+    
+    keyfile = gnc_find_state_file(url, guid_string, &filename);
+    if (filename)
+        g_free(filename);
+
+    if (!keyfile) {
+        gnc_main_window_restore_default_state();
+        
+#if (GNUCASH_MAJOR_VERSION < 2) || ((GNUCASH_MAJOR_VERSION == 2) && (GNUCASH_MINOR_VERSION == 0))
+        /* See if there's an old style state file to be found */
+        scm_call_1(scm_c_eval_string("gnc:main-window-book-open-handler"),
+                   (session ?
+                    gw_wcp_assimilate_ptr (session, scm_c_eval_string("<gnc:Session*>")) :
+                    SCM_BOOL_F));
+#endif
+        
+        LEAVE("old");
+        return;
+    }
+    
+#ifdef DEBUG
+    /*  Debugging: dump a copy to stdout and the trace log */
+    {
+        gchar *file_data;
+        gsize file_length;
+        file_data = g_key_file_to_data(keyfile, &file_length, NULL);
+        DEBUG("=== File Data Read===\n%s\n=== File End ===\n", file_data);
+        g_free(file_data);
+    }
+#endif
+    
+    /* validate top level info */
+    file_guid = g_key_file_get_string(keyfile, STATE_FILE_TOP, 
+                                      STATE_FILE_BOOK_GUID, &error);
+    if (error) {
+        g_warning("error reading group %s key %s: %s",
+                  STATE_FILE_TOP, STATE_FILE_BOOK_GUID, error->message);
+        LEAVE("can't read guid");
+        goto cleanup;
+    }
+    if (!file_guid || strcmp(guid_string, file_guid)) {
+        g_warning("guid mismatch: book guid %s, state file guid %s",
+                  guid_string, file_guid);
+        LEAVE("guid values do not match");
+        goto cleanup;
+    }
+    
+    gnc_main_window_restore_all_windows(keyfile);
+    
+    /* Clean up */
+    LEAVE("ok");
+ cleanup:
+    if (error)
+        g_error_free(error);
+    if (file_guid)
+        g_free(file_guid);
+    g_key_file_free(keyfile);
+}
+
+
+/** Save all persistent program state to disk.  This function finds the
+ *  name of the "new" state file associated with a specific book guid.
+ *  It saves some top level data, then iterates through the list of
+ *  open windows calling a helper function to save each window.
+ *
+ *  @note The name of the state file is based on the name of the data
+ *  file, not the path name of the data file.  If there are multiple
+ *  data files with the same name, the state files will be suffixed
+ *  with a number.  E.G. test_account, test_account_2, test_account_3,
+ *  etc.
+ *
+ *  @param session The QofSession whose state should be saved.
+ *
+ *  @param unused */
+static void
+gnc_save_all_state (gpointer session, gpointer unused)
+{
+    QofBook *book;
+    const char *url, *guid_string;
+    gchar *filename;
+    const GUID *guid;
+    GError *error = NULL;
+    GKeyFile *keyfile = NULL;
+    
+    
+    url = qof_session_get_url(session);
+    ENTER("session %p (%s)", session, url);
+    if (!url) {
+        LEAVE("no url, nothing to do");
+        return;
+    }
+
+    /* Get the book GUID */
+    book = qof_session_get_book(session);
+    guid = qof_entity_get_guid(QOF_ENTITY(book));
+    guid_string = guid_to_string(guid);
+
+    /* Find the filename to use.  This returns the data from the
+     * file so its possible that we could reuse the data and
+     * maintain comments that were added to the data file, but
+     * that's not something we currently do. For now the existing
+     * data is dumped and completely regenerated.*/
+    keyfile = gnc_find_state_file(url, guid_string, &filename);
+    if (keyfile)
+        g_key_file_free(keyfile);
+
+    keyfile = g_key_file_new();
+    /* Store top level info in the data structure */
+    g_key_file_set_string(keyfile, STATE_FILE_TOP, STATE_FILE_BOOK_GUID,
+                          guid_string);
+
+    gnc_main_window_save_all_windows(keyfile);
+    
+#ifdef DEBUG
+    /*  Debugging: dump a copy to the trace log */
+    {
+        gchar *file_data;
+        gsize file_length;
+        file_data = g_key_file_to_data(keyfile, &file_length, NULL);
+        DEBUG("=== File Data Written===\n%s\n=== File End ===\n", file_data);
+        g_free(file_data);
+    }
+#endif
+
+    /* Write it all out to disk */
+    gnc_key_file_save_to_file(filename, keyfile, &error);
+    if (error) {
+        g_critical(_("Error: Failure saving state file.\n  %s"), 
+                   error->message);
+        g_error_free(error);
+    }
+    g_free(filename);
+    
+    /* Clean up */
+    g_key_file_free(keyfile);
+    LEAVE("");
+}
+
 void
 gnc_main_gui_init (void)
 {
@@ -232,7 +412,14 @@
 
     /* Run the ui startup hooks. */
     gnc_hook_run(HOOK_UI_STARTUP, NULL);
+
+    gnc_hook_add_dangler(HOOK_BOOK_OPENED,
+                         gnc_restore_all_state, NULL);
+    gnc_hook_add_dangler(HOOK_BOOK_CLOSED,
+                         gnc_save_all_state, NULL);
+
     LEAVE(" ");
     return;
 }
+
 /****************** END OF FILE **********************/

Modified: gnucash/trunk/src/gnome-utils/gnc-main-window.c
===================================================================
--- gnucash/trunk/src/gnome-utils/gnc-main-window.c	2006-01-26 14:25:29 UTC (rev 12981)
+++ gnucash/trunk/src/gnome-utils/gnc-main-window.c	2006-01-26 17:38:26 UTC (rev 12982)
@@ -69,7 +69,6 @@
 #include "gnc-gconf-utils.h"
 // +JSLED
 #include "gnc-html.h"
-#include <g-wrap-wct.h>
 
 /** Names of signals generated by the main window. */
 enum {
@@ -598,110 +597,25 @@
   g_free(window_group);
 }
 
-
-/** Restore all windows.  This function finds the "new" state file
- *  associated with a specific book guid.  It then iterates through
- *  this state information, calling a helper function to recreate
- *  each open window.
- *
- *  If the "new" state file cannot be found, this function will open
- *  an account tree window and then attempt to invoke the old gnucash
- *  1.x state routines.  This provides a fluid transition for users
- *  from the old to the new state systems.
- *
- *  @note The name of the state file is based on the name of the data
- *  file, not the path name of the data file.  If there are multiple
- *  data files with the same name, the state files will be suffixed
- *  with a number.  E.G. test_account, test_account_2, test_account_3,
- *  etc.
- *
- *  @param session A pointer to the current session.
- *
- *  @param unused An unused pointer. */
-static void
-gnc_main_window_restore_all_state (gpointer session, gpointer unused)
+void
+gnc_main_window_restore_all_windows(const GKeyFile *keyfile)
 {
-  GncMainWindow *window;
-  GncMainWindowSaveData data;
-  QofBook *book;
-  const gchar *url, *guid_string;
-  gchar *file_guid, *filename = NULL;
-  const GUID *guid;
   gint i, window_count;
   GError *error = NULL;
-	
-  url = qof_session_get_url(session);
-  ENTER("session %p (%s)", session, url);
-  if (!url) {
-    LEAVE("no url, nothing to do");
-    return;
-  }
+  GncMainWindowSaveData data;
+  GncMainWindow *window;
 
-  /* Get the book GUID */
-  book = qof_session_get_book(session);
-  guid = qof_entity_get_guid(QOF_ENTITY(book));
-  guid_string = guid_to_string(guid);
-
-  data.key_file = gnc_find_state_file(url, guid_string, &filename);
-  if (filename)
-    g_free(filename);
-  if (!data.key_file) {
-    GtkAction *action;
-
-    /* The default state should be to have an Account Tree page open
-     * in the window. */
-    DEBUG("no saved state file");
-    window = g_list_nth_data(active_windows, 0);
-    action = gnc_main_window_find_action(window, "FileNewAccountTreeAction");
-    gtk_action_activate(action);
-
-#if (GNUCASH_MAJOR_VERSION < 2) || ((GNUCASH_MAJOR_VERSION == 2) && (GNUCASH_MINOR_VERSION == 0))
-    /* See if there's an old style state file to be found */
-    scm_call_1(scm_c_eval_string("gnc:main-window-book-open-handler"),
-	       (session ?
-		gw_wcp_assimilate_ptr (session, scm_c_eval_string("<gnc:Session*>")) :
-		SCM_BOOL_F));
-#endif
-
-    LEAVE("old");
-    return;
-  }
-
-#ifdef DEBUG
-  /*  Debugging: dump a copy to stdout and the trace log */
-  {
-    gchar *file_data;
-    gsize file_length;
-    file_data = g_key_file_to_data(data.key_file, &file_length, NULL);
-    DEBUG("=== File Data Read===\n%s\n=== File End ===\n", file_data);
-    g_free(file_data);
-  }
-#endif
-
-  /* validate top level info */
-  file_guid = g_key_file_get_string(data.key_file,
-				    STATE_FILE_TOP, STATE_FILE_BOOK_GUID,
-				    &error);
+  /* We use the same struct for reading and for writing, so we cast
+     away the const. */
+  data.key_file = (GKeyFile *) keyfile;
+  window_count = g_key_file_get_integer(data.key_file, STATE_FILE_TOP, 
+                                        WINDOW_COUNT, &error);
   if (error) {
     g_warning("error reading group %s key %s: %s",
-	      STATE_FILE_TOP, STATE_FILE_BOOK_GUID, error->message);
-    LEAVE("can't read guid");
-    goto cleanup;
-  }
-  if (!file_guid || strcmp(guid_string, file_guid)) {
-    g_warning("guid mismatch: book guid %s, state file guid %s",
-	      guid_string, file_guid);
-    LEAVE("guid values do not match");
-    goto cleanup;
-  }
-
-  window_count =
-    g_key_file_get_integer(data.key_file, STATE_FILE_TOP, WINDOW_COUNT, &error);
-  if (error) {
-    g_warning("error reading group %s key %s: %s",
 	      STATE_FILE_TOP, WINDOW_COUNT, error->message);
+    g_error_free(error);
     LEAVE("can't read count");
-    goto cleanup;
+    return;
   }
 
   /* Restore all state information on the open windows.  Window
@@ -711,18 +625,22 @@
     window = g_list_nth_data(active_windows, i);
     gnc_main_window_restore_window(window, &data);
   }
+}
 
-  /* Clean up */
-  LEAVE("ok");
- cleanup:
-  if (error)
-    g_error_free(error);
-  if (file_guid)
-    g_free(file_guid);
-  g_key_file_free(data.key_file);
+void
+gnc_main_window_restore_default_state(void)
+{
+    GtkAction *action;
+    GncMainWindow *window;
+    
+    /* The default state should be to have an Account Tree page open
+     * in the window. */
+    DEBUG("no saved state file");
+    window = g_list_nth_data(active_windows, 0);
+    action = gnc_main_window_find_action(window, "FileNewAccountTreeAction");
+    gtk_action_activate(action);
 }
 
-
 /** Save the state of a single page to a disk.  This function handles
  *  all the common tasks such as saving the page type and name, and
  *  anything else that might be common to all pages.  It then calls a
@@ -809,94 +727,23 @@
   LEAVE("window %p", window);
 }
 
-
-/** Save the state of all windows to disk.  This function finds the
- *  name of the "new" state file associated with a specific book guid.
- *  It saves some top level data, then iterates through the list of
- *  open windows calling a helper function to save each window.
- *
- *  @note The name of the state file is based on the name of the data
- *  file, not the path name of the data file.  If there are multiple
- *  data files with the same name, the state files will be suffixed
- *  with a number.  E.G. test_account, test_account_2, test_account_3,
- *  etc.
- *
- *  @param page The GncPluginPage whose state should be saved.
- *
- *  @param data A data structure containing state about the
- *  window/page saving process. */
-static void
-gnc_main_window_save_all_state (gpointer session, gpointer user_data)
+void
+gnc_main_window_save_all_windows(GKeyFile *keyfile)
 {
-	GncMainWindowSaveData data;
-	QofBook *book;
-	const char *url, *guid_string;
-	gchar *filename;
-	const GUID *guid;
-	GError *error = NULL;
+    GncMainWindowSaveData data;
 
-	url = qof_session_get_url(session);
-	ENTER("session %p (%s)", session, url);
-	if (!url) {
-	  LEAVE("no url, nothing to do");
-	  return;
-	}
+    /* Set up the iterator data structures */
+    data.key_file = keyfile;
+    data.window_num = 1;
+    data.page_num = 1;
 
-	/* Get the book GUID */
-	book = qof_session_get_book(session);
-	guid = qof_entity_get_guid(QOF_ENTITY(book));
-	guid_string = guid_to_string(guid);
-
-	/* Find the filename to use.  This returns the data from the
-	 * file so its possible that we could reuse the data and
-	 * maintain comments that were added to the data file, but
-	 * that's not something we currently do. For now the existing
-	 * data is dumped and completely regenerated.*/
-	data.key_file = gnc_find_state_file(url, guid_string, &filename);
-	if (data.key_file)
-	  g_key_file_free(data.key_file);
-
-	/* Set up the iterator data structures */
-	data.key_file = g_key_file_new();
-	data.window_num = 1;
-	data.page_num = 1;
-
-	/* Store top level info in the data structure */
-	g_key_file_set_string(data.key_file,
-			      STATE_FILE_TOP, STATE_FILE_BOOK_GUID,
-			      guid_string);
-	g_key_file_set_integer(data.key_file,
-			       STATE_FILE_TOP, WINDOW_COUNT,
-			       g_list_length(active_windows));
-
-	/* Dump all state information on the open windows */
-	g_list_foreach(active_windows, (GFunc)gnc_main_window_save_window, &data);
-
-#ifdef DEBUG
-	/*  Debugging: dump a copy to the trace log */
-	{
-	  gchar *file_data;
-	  gsize file_length;
-	  file_data = g_key_file_to_data(data.key_file, &file_length, NULL);
-	  DEBUG("=== File Data Written===\n%s\n=== File End ===\n", file_data);
-	  g_free(file_data);
-	}
-#endif
-
-	/* Write it all out to disk */
-	gnc_key_file_save_to_file(filename, data.key_file, &error);
-	if (error) {
-	  g_critical(_("Error: Failure saving state file.\n  %s"), error->message);
-	  g_error_free(error);
-	}
-	g_free(filename);
-
-	/* Clean up */
-	g_key_file_free(data.key_file);
-	LEAVE("");
+    g_key_file_set_integer(data.key_file,
+                           STATE_FILE_TOP, WINDOW_COUNT,
+                           g_list_length(active_windows));
+    /* Dump all state information on the open windows */
+    g_list_foreach(active_windows, (GFunc)gnc_main_window_save_window, &data);
 }
 
-
 /** See if the page already exists.  For each open window, look
  *  through the list of pages installed in that window and see if the
  *  specified page is there.
@@ -1686,11 +1533,6 @@
 			G_TYPE_NONE, 1,
 			G_TYPE_OBJECT);
 
-	gnc_hook_add_dangler(HOOK_BOOK_OPENED,
-			     gnc_main_window_restore_all_state, NULL);
-	gnc_hook_add_dangler(HOOK_BOOK_CLOSED,
-			     gnc_main_window_save_all_state, NULL);
-
 	gnc_gconf_general_register_cb (KEY_SHOW_CLOSE_BUTTON,
 				       gnc_main_window_update_tabs,
 				       NULL);

Modified: gnucash/trunk/src/gnome-utils/gnc-main-window.h
===================================================================
--- gnucash/trunk/src/gnome-utils/gnc-main-window.h	2006-01-26 14:25:29 UTC (rev 12981)
+++ gnucash/trunk/src/gnome-utils/gnc-main-window.h	2006-01-26 17:38:26 UTC (rev 12982)
@@ -274,6 +274,22 @@
 					  GdkEventButton *event,
 					  GncPluginPage *page);
 
+/** Restore the persistent state of all windows.
+ *
+ *  @param keyfile The GKeyFile containing persistent window state.
+ */ 
+void gnc_main_window_restore_all_windows(const GKeyFile *keyfile);
+
+/** Save the persistent state of all windows.
+ *
+ *  @param keyfile The GKeyFile to contain persistent window state.
+ */ 
+void gnc_main_window_save_all_windows(GKeyFile *keyfile);
+
+/** Restore the persistent state of one window to a sane default.
+ */ 
+void gnc_main_window_restore_default_state(void);
+
 /**
  * gnc_gtk_action_group_set_translation_domain:
  * @action_group: a #GtkActionGroup
@@ -295,6 +311,7 @@
 void 
 gnc_gtk_action_group_set_translation_domain (GtkActionGroup *action_group,
 					     const gchar    *domain);
+
 G_END_DECLS
 
 #endif /* __GNC_MAIN_WINDOW_H */



More information about the gnucash-changes mailing list