void gnc_state_save (const QofSession *session) { GError *error = NULL; if (!qof_session_get_url(session)) { DEBUG("No file associated with session - skip state saving"); return; } gnc_state_set_base (session); /* Write it all out to disk */ if (state_file_name) gnc_key_file_save_to_file(state_file_name, state_file, &error); else PWARN ("No state file name set, can't save state"); if (error) { PERR ("Error: Failure saving state file.\n %s", error->message); g_error_free (error); } }
/* XXX This exports the list of accounts to a file. It does not * export any transactions. It's a place-holder until full * book-closing is implemented. */ gboolean qof_session_export (QofSession *tmp_session, QofSession *real_session, QofPercentageFunc percentage_func) { QofBook *book, *book2; QofBackend *be; if ((!tmp_session) || (!real_session)) return FALSE; book = qof_session_get_book (real_session); ENTER ("tmp_session=%p real_session=%p book=%p book_id=%s", tmp_session, real_session, book, qof_session_get_url(tmp_session) ? qof_session_get_url(tmp_session) : "(null)"); /* There must be a backend or else. (It should always be the file * backend too.) */ book2 = qof_session_get_book(tmp_session); be = qof_book_get_backend(book2); if (!be) return FALSE; be->percentage = percentage_func; if (be->export_fn) { int err; (be->export_fn)(be, book); err = qof_backend_get_error(be); if (ERR_BACKEND_NO_ERR != err) { return FALSE; } } return TRUE; }
static void gnc_state_set_base (const QofSession *session) { gchar *basename, *original = NULL, *filename, *file_guid; gchar *sf_extension = NULL, *newstyle_filename = NULL; const gchar *uri; gchar guid_string[GUID_ENCODING_LENGTH+1]; QofBook *book; const GncGUID *guid; GKeyFile *key_file = NULL; gint i; /* Reset filenames possibly found in a previous run */ g_free (state_file_name); g_free (state_file_name_pre_241); state_file_name = NULL; state_file_name_pre_241 = NULL; uri = qof_session_get_url(session); ENTER("session %p (%s)", session, uri ? uri : "(null)"); if (!uri) { LEAVE("no uri, nothing to do"); return; } /* Get the book GncGUID */ book = qof_session_get_book(session); guid = qof_entity_get_guid(QOF_INSTANCE(book)); guid_to_string_buff(guid, guid_string); if (gnc_uri_is_file_uri (uri)) { /* The book_uri is a true file, use its basename. */ gchar *path = gnc_uri_get_path (uri); basename = g_path_get_basename (path); g_free (path); } else { /* The book_uri is composed of database connection parameters. */ gchar* protocol = NULL; gchar* host = NULL; gchar* dbname = NULL; gchar* username = NULL; gchar* password = NULL; gint portnum = 0; gnc_uri_get_components (uri, &protocol, &host, &portnum, &username, &password, &dbname); basename = g_strjoin ("_", protocol, host, username, dbname, NULL); g_free (protocol); g_free (host); g_free (username); g_free (password); g_free (dbname); } DEBUG ("Basename %s", basename); original = gnc_build_book_path (basename); g_free (basename); DEBUG ("Original %s", original); sf_extension = g_strdup (STATE_FILE_EXT); i = 1; while (1) { if (i == 1) filename = g_strconcat (original, sf_extension, NULL); else filename = g_strdup_printf ("%s_%d%s", original, i, sf_extension); DEBUG ("Trying %s", filename); key_file = gnc_key_file_load_from_file (filename, TRUE, FALSE, NULL); DEBUG ("Result %p", key_file); if (!key_file) { DEBUG ("No key file by that name"); if (g_strcmp0 (sf_extension, STATE_FILE_EXT) == 0) { DEBUG ("Trying old state file names for compatibility"); i = 1; g_free (sf_extension); sf_extension = g_strdup (""); /* Regardless of whether or not an old state file is found, * the currently tested name should be used for the future * state file. */ state_file_name = filename; continue; } /* No old style file found. We'll return with the new file name * we set earlier, and no existing key file. */ g_free (filename); break; } file_guid = g_key_file_get_string (key_file, STATE_FILE_TOP, STATE_FILE_BOOK_GUID, NULL); DEBUG ("File GncGUID is %s", file_guid ? file_guid : "<not found>"); if (g_strcmp0 (guid_string, file_guid) == 0) { DEBUG ("Matched !!!"); /* Save the found file for later use. Which name to save to * depends on whether it was an old or new style file name */ if (g_strcmp0 (sf_extension, STATE_FILE_EXT) == 0) state_file_name = filename; else state_file_name_pre_241 = filename; g_free (file_guid); break; } DEBUG ("Clean up this pass"); g_free (file_guid); g_key_file_free (key_file); g_free (filename); i++; } DEBUG("Clean up"); g_free(sf_extension); g_free(original); g_key_file_free (key_file); LEAVE (); }
/** 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 GncGUID *guid; GError *error = NULL; GKeyFile *keyfile = NULL; url = qof_session_get_url(session); ENTER("session %p (%s)", session, url ? url : "(null)"); if (!url) { LEAVE("no url, nothing to do"); return; } /* Get the book GncGUID */ book = qof_session_get_book(session); guid = qof_entity_get_guid(QOF_INSTANCE(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(""); }
/** 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. * * @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 GncGUID *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 ? url : "(null)"); if (!url) { LEAVE("no url, nothing to do"); return; } /* Get the book GncGUID */ book = qof_session_get_book(session); guid = qof_entity_get_guid(QOF_INSTANCE(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(); LEAVE("no state file"); 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); }
QString get_url() const { return QString::fromUtf8(qof_session_get_url(gobj())); }