mirror of
https://github.com/Gnucash/gnucash.git
synced 2025-02-25 18:55:30 -06:00
Don't ask to save a non-existant book.
To accomplish that we separate creating a book and creating a session; gnc_get_session no longer automatically creates a book if one isn't connected. We also add an initially_insensitive GtkAction array to gnc-plugin-basic-commands with a call to make its contents insensitive at plugin load so that the save button on the toolbar isn't lighted when there's nothing to save.
This commit is contained in:
parent
320db3270b
commit
4e6c497cd1
@ -651,7 +651,7 @@ gnc_file_query_save (GtkWindow *parent, gboolean can_cancel)
|
||||
static gboolean
|
||||
gnc_post_file_open (GtkWindow *parent, const char * filename, gboolean is_readonly)
|
||||
{
|
||||
QofSession *current_session, *new_session;
|
||||
QofSession *new_session;
|
||||
QofBook *new_book;
|
||||
GList *invalid_account_names;
|
||||
gboolean uh_oh = FALSE;
|
||||
@ -726,7 +726,7 @@ RESTART:
|
||||
/* -- this code is almost identical in FileOpen and FileSaveAs -- */
|
||||
if (gnc_current_session_exist())
|
||||
{
|
||||
current_session = gnc_get_current_session();
|
||||
QofSession *current_session = gnc_get_current_session();
|
||||
gnc_hook_run(HOOK_BOOK_CLOSED, current_session);
|
||||
gnc_close_gui_component_by_session (current_session);
|
||||
gnc_state_save (current_session);
|
||||
@ -735,7 +735,7 @@ RESTART:
|
||||
|
||||
/* load the accounts from the users datafile */
|
||||
/* but first, check to make sure we've got a session going. */
|
||||
new_session = qof_session_new (NULL);
|
||||
new_session = qof_session_new (qof_book_new());
|
||||
|
||||
// Begin the new session. If we are in read-only mode, ignore the locks.
|
||||
qof_session_begin (new_session, newfile, is_readonly, FALSE, FALSE);
|
||||
@ -1299,6 +1299,9 @@ gnc_file_save (GtkWindow *parent)
|
||||
QofSession *session;
|
||||
ENTER (" ");
|
||||
|
||||
if (!gnc_current_session_exist ())
|
||||
return; //No session means nothing to save.
|
||||
|
||||
/* hack alert -- Somehow make sure all in-progress edits get committed! */
|
||||
|
||||
/* If we don't have a filename/path to save to get one. */
|
||||
@ -1366,6 +1369,12 @@ gnc_file_save_as (GtkWindow *parent)
|
||||
|
||||
ENTER(" ");
|
||||
|
||||
if (!gnc_current_session_exist ())
|
||||
{
|
||||
LEAVE("No Session.");
|
||||
return;
|
||||
}
|
||||
|
||||
last = gnc_history_get_last();
|
||||
if ( last && gnc_uri_targets_local_fs (last))
|
||||
{
|
||||
|
@ -239,6 +239,14 @@ static const gchar *gnc_plugin_important_actions[] =
|
||||
NULL,
|
||||
};
|
||||
|
||||
/** The following items should be made insensitive at startup time. The
|
||||
* sensitivity will be changed by some later event. */
|
||||
static const gchar *gnc_plugin_initially_insensitive_actions[] =
|
||||
{
|
||||
"FileSaveAction",
|
||||
NULL,
|
||||
};
|
||||
|
||||
/** These actions are made not sensitive (i.e.,
|
||||
* their toolbar and menu items are grayed out and do not send events
|
||||
* when clicked) when the current book is "Read Only".
|
||||
@ -309,6 +317,11 @@ gnc_plugin_basic_commands_add_to_window (GncPlugin *plugin,
|
||||
GncMainWindow *window,
|
||||
GQuark type)
|
||||
{
|
||||
GtkActionGroup *action_group =
|
||||
gnc_main_window_get_action_group(window, PLUGIN_ACTIONS_NAME);
|
||||
gnc_plugin_update_actions(action_group,
|
||||
gnc_plugin_initially_insensitive_actions,
|
||||
"sensitive", FALSE);
|
||||
g_signal_connect(window, "page_changed",
|
||||
G_CALLBACK(gnc_plugin_basic_commands_main_window_page_changed),
|
||||
plugin);
|
||||
|
@ -64,7 +64,8 @@ test_qofsession_aqb_kvp( void )
|
||||
if (1)
|
||||
{
|
||||
// A file with no content at all, but a valid XML file
|
||||
QofSession *new_session = qof_session_new (NULL);
|
||||
QofBook *book = qof_book_new();
|
||||
QofSession *new_session = qof_session_new (book);
|
||||
char *newfile = g_strdup_printf("file://%s", file1);
|
||||
|
||||
qof_session_begin (new_session, newfile, TRUE, FALSE, FALSE);
|
||||
@ -92,7 +93,8 @@ test_qofsession_aqb_kvp( void )
|
||||
{
|
||||
// A file with no content except for the book_template_list kvp
|
||||
// slot
|
||||
QofSession *new_session = qof_session_new (NULL);
|
||||
QofBook *book = qof_book_new();
|
||||
QofSession *new_session = qof_session_new (book);
|
||||
char *newfile = g_strdup_printf("file://%s", file2);
|
||||
|
||||
qof_session_begin (new_session, newfile, TRUE, FALSE, FALSE);
|
||||
|
@ -91,7 +91,8 @@ setup (Fixture* fixture, gconstpointer pData)
|
||||
{
|
||||
gchar* url = (gchar*)pData;
|
||||
gnc_module_init_backend_dbi();
|
||||
fixture->session = qof_session_new (nullptr);
|
||||
auto book = qof_book_new();
|
||||
fixture->session = qof_session_new (book);
|
||||
/* When running distcheck the source directory is read-only, which
|
||||
* prevents creating the lock file. Force the session to get
|
||||
* around that.
|
||||
@ -391,7 +392,8 @@ test_dbi_store_and_reload (Fixture* fixture, gconstpointer pData)
|
||||
url = fixture->filename;
|
||||
|
||||
// Save the session data
|
||||
auto session_2 = qof_session_new (nullptr);
|
||||
auto book2{qof_book_new()};
|
||||
auto session_2 = qof_session_new (book2);
|
||||
qof_session_begin (session_2, url, FALSE, TRUE, TRUE);
|
||||
g_assert (session_2 != NULL);
|
||||
g_assert_cmpint (qof_session_get_error (session_2), == , ERR_BACKEND_NO_ERR);
|
||||
@ -402,7 +404,8 @@ test_dbi_store_and_reload (Fixture* fixture, gconstpointer pData)
|
||||
g_assert_cmpint (qof_session_get_error (session_2), == , ERR_BACKEND_NO_ERR);
|
||||
|
||||
// Reload the session data
|
||||
auto session_3 = qof_session_new (nullptr);
|
||||
auto book3{qof_book_new()};
|
||||
auto session_3 = qof_session_new (book3);
|
||||
g_assert (session_3 != NULL);
|
||||
qof_session_begin (session_3, url, TRUE, FALSE, FALSE);
|
||||
g_assert (session_3 != NULL);
|
||||
@ -442,7 +445,8 @@ test_dbi_safe_save (Fixture* fixture, gconstpointer pData)
|
||||
url = fixture->filename;
|
||||
|
||||
// Load the session data
|
||||
auto session_1 = qof_session_new (nullptr);
|
||||
auto book1{qof_book_new()};
|
||||
auto session_1 = qof_session_new (book1);
|
||||
qof_session_begin (session_1, url, FALSE, TRUE, TRUE);
|
||||
if (session_1 &&
|
||||
qof_session_get_error (session_1) != ERR_BACKEND_NO_ERR)
|
||||
@ -468,7 +472,7 @@ test_dbi_safe_save (Fixture* fixture, gconstpointer pData)
|
||||
}
|
||||
/* Destroy the session and reload it */
|
||||
|
||||
session_2 = qof_session_new (nullptr);
|
||||
session_2 = qof_session_new (qof_book_new());
|
||||
qof_session_begin (session_2, url, TRUE, FALSE, FALSE);
|
||||
if (session_2 &&
|
||||
qof_session_get_error (session_2) != ERR_BACKEND_NO_ERR)
|
||||
@ -508,7 +512,7 @@ static void
|
||||
test_dbi_version_control (Fixture* fixture, gconstpointer pData)
|
||||
{
|
||||
auto url = (gchar*)pData;
|
||||
QofBook* book = nullptr;
|
||||
QofBook* book{qof_book_new()};
|
||||
QofBackendError err;
|
||||
gint ourversion = gnc_prefs_get_long_version ();
|
||||
GncSqlBackend* sql_be = nullptr;
|
||||
@ -536,7 +540,7 @@ test_dbi_version_control (Fixture* fixture, gconstpointer pData)
|
||||
qof_book_commit_edit (book);
|
||||
qof_session_end (sess);
|
||||
qof_session_destroy (sess);
|
||||
sess = qof_session_new (nullptr);
|
||||
sess = qof_session_new (qof_book_new());
|
||||
qof_session_begin (sess, url, TRUE, FALSE, FALSE);
|
||||
qof_session_load (sess, NULL);
|
||||
err = qof_session_pop_error (sess);
|
||||
@ -549,7 +553,7 @@ test_dbi_version_control (Fixture* fixture, gconstpointer pData)
|
||||
qof_book_commit_edit (book);
|
||||
qof_session_end (sess);
|
||||
qof_session_destroy (sess);
|
||||
sess = qof_session_new (nullptr);
|
||||
sess = qof_session_new (qof_book_new());
|
||||
qof_session_begin (sess, url, TRUE, FALSE, FALSE);
|
||||
qof_session_load (sess, NULL);
|
||||
qof_session_ensure_all_data_loaded (sess);
|
||||
@ -578,14 +582,14 @@ test_dbi_business_store_and_reload (Fixture* fixture, gconstpointer pData)
|
||||
if (fixture->filename)
|
||||
url = fixture->filename;
|
||||
// Save the session data
|
||||
auto session_2 = qof_session_new (nullptr);
|
||||
auto session_2 = qof_session_new (qof_book_new());
|
||||
qof_session_begin (session_2, url, FALSE, TRUE, TRUE);
|
||||
qof_session_swap_data (fixture->session, session_2);
|
||||
qof_book_mark_session_dirty (qof_session_get_book (session_2));
|
||||
qof_session_save (session_2, NULL);
|
||||
|
||||
// Reload the session data
|
||||
auto session_3 = qof_session_new (nullptr);
|
||||
auto session_3 = qof_session_new (qof_book_new());
|
||||
qof_session_begin (session_3, url, TRUE, FALSE, FALSE);
|
||||
qof_session_load (session_3, NULL);
|
||||
|
||||
|
@ -1152,7 +1152,7 @@ gnc_book_get_root_account (QofBook *book)
|
||||
if (!book) return NULL;
|
||||
col = qof_book_get_collection (book, GNC_ID_ROOT_ACCOUNT);
|
||||
root = gnc_coll_get_root_account (col);
|
||||
if (root == NULL)
|
||||
if (root == NULL && !qof_book_shutting_down(book))
|
||||
root = gnc_account_create_root(book);
|
||||
return root;
|
||||
}
|
||||
@ -5875,6 +5875,8 @@ static void
|
||||
gnc_account_book_end(QofBook* book)
|
||||
{
|
||||
Account *root_account = gnc_book_get_root_account(book);
|
||||
if (!root_account)
|
||||
return;
|
||||
xaccAccountBeginEdit(root_account);
|
||||
xaccAccountDestroy(root_account);
|
||||
}
|
||||
|
@ -202,52 +202,49 @@ QofSessionImpl::load (QofPercentageFunc percentage_func) noexcept
|
||||
{
|
||||
/* We must have an empty book to load into or bad things will happen. */
|
||||
g_return_if_fail(m_book && qof_book_empty(m_book));
|
||||
|
||||
|
||||
if (!m_book_id.size ()) return;
|
||||
ENTER ("sess=%p book_id=%s", this, m_book_id.c_str ());
|
||||
|
||||
/* At this point, we should are supposed to have a valid book
|
||||
* id and a lock on the file. */
|
||||
* id and a lock on the file. */
|
||||
clear_error ();
|
||||
|
||||
/* This code should be sufficient to initialize *any* backend,
|
||||
* whether http, postgres, or anything else that might come along.
|
||||
* Basically, the idea is that by now, a backend has already been
|
||||
* created & set up. At this point, we only need to get the
|
||||
* top-level account group out of the backend, and that is a
|
||||
* generic, backend-independent operation.
|
||||
*/
|
||||
qof_book_set_backend (newbook, m_backend);
|
||||
* whether http, postgres, or anything else that might come along.
|
||||
* Basically, the idea is that by now, a backend has already been
|
||||
* created & set up. At this point, we only need to get the
|
||||
* top-level account group out of the backend, and that is a
|
||||
* generic, backend-independent operation.
|
||||
*/
|
||||
qof_book_set_backend (m_book, m_backend);
|
||||
|
||||
/* Starting the session should result in a bunch of accounts
|
||||
* and currencies being downloaded, but probably no transactions;
|
||||
* The GUI will need to do a query for that.
|
||||
*/
|
||||
* and currencies being downloaded, but probably no transactions;
|
||||
* The GUI will need to do a query for that.
|
||||
*/
|
||||
if (m_backend)
|
||||
{
|
||||
m_backend->set_percentage(percentage_func);
|
||||
m_backend->load (newbook, LOAD_TYPE_INITIAL_LOAD);
|
||||
m_backend->load (m_book, LOAD_TYPE_INITIAL_LOAD);
|
||||
push_error (m_backend->get_error(), {});
|
||||
}
|
||||
|
||||
auto err = get_error ();
|
||||
if ((err != ERR_BACKEND_NO_ERR) &&
|
||||
(err != ERR_FILEIO_FILE_TOO_OLD) &&
|
||||
(err != ERR_FILEIO_NO_ENCODING) &&
|
||||
(err != ERR_FILEIO_FILE_UPGRADE) &&
|
||||
(err != ERR_SQL_DB_TOO_OLD) &&
|
||||
(err != ERR_SQL_DB_TOO_NEW))
|
||||
(err != ERR_FILEIO_FILE_TOO_OLD) &&
|
||||
(err != ERR_FILEIO_NO_ENCODING) &&
|
||||
(err != ERR_FILEIO_FILE_UPGRADE) &&
|
||||
(err != ERR_SQL_DB_TOO_OLD) &&
|
||||
(err != ERR_SQL_DB_TOO_NEW))
|
||||
{
|
||||
/* Something broke, put back the old stuff */
|
||||
delete m_backend;
|
||||
qof_book_set_backend (newbook, NULL);
|
||||
qof_book_destroy (newbook);
|
||||
m_book = oldbook;
|
||||
m_backend = qof_book_get_backend (m_book);
|
||||
// Something failed, delete and restore new ones.
|
||||
destroy_backend();
|
||||
qof_book_destroy (m_book);
|
||||
m_book = qof_book_new();
|
||||
LEAVE ("error from backend %d", get_error ());
|
||||
return;
|
||||
}
|
||||
qof_book_destroy (oldbook);
|
||||
|
||||
LEAVE ("sess = %p, book_id=%s", this, m_book_id.c_str ());
|
||||
}
|
||||
|
@ -175,19 +175,25 @@ TEST (QofSessionTest, load)
|
||||
* and create a new one.
|
||||
*/
|
||||
qof_backend_register_provider (get_provider ());
|
||||
QofSession s;
|
||||
QofSession s{qof_book_new()};
|
||||
s.begin ("book1", false, false, false);
|
||||
auto book = s.get_book ();
|
||||
char *guidstr1 = guid_to_string(qof_instance_get_guid(s.get_book ()));
|
||||
s.load (nullptr);
|
||||
EXPECT_NE (book, s.get_book ());
|
||||
char *guidstr2 = guid_to_string(qof_instance_get_guid(s.get_book ()));
|
||||
EXPECT_STRNE (guidstr1, guidstr2);
|
||||
g_free(guidstr1);
|
||||
g_free(guidstr2);
|
||||
|
||||
/* Now we'll do the load without returning an error from the backend,
|
||||
* and ensure that it's the new book from the previous test.
|
||||
*/
|
||||
load_error = false;
|
||||
book = s.get_book();
|
||||
guidstr1 = guid_to_string(qof_instance_get_guid(s.get_book ()));
|
||||
s.load (nullptr);
|
||||
EXPECT_EQ (book, s.get_book ());
|
||||
guidstr2 = guid_to_string(qof_instance_get_guid(s.get_book ()));
|
||||
EXPECT_STREQ (guidstr1, guidstr2);
|
||||
g_free(guidstr1);
|
||||
g_free(guidstr2);
|
||||
EXPECT_EQ (s.get_error(), ERR_BACKEND_NO_ERR);
|
||||
//But it's still empty, to the book shouldn't need saving
|
||||
EXPECT_FALSE(qof_book_session_not_saved (s.get_book ()));
|
||||
|
Loading…
Reference in New Issue
Block a user