When an account or budget is deleted, drop any associated saved state

git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@23432 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
Geert Janssens 2013-11-24 16:28:36 +00:00
parent 2fa8a82c43
commit 95c0933a84
7 changed files with 105 additions and 2 deletions

View File

@ -260,3 +260,45 @@ GKeyFile *gnc_state_get_current (void)
}
gint gnc_state_drop_sections_for (const gchar *partial_name)
{
gchar **groups;
gint found_count = 0, dropped_count = 0;
gsize i, num_groups;
GError *error = NULL;
if (!state_file)
{
PWARN ("No pre-existing state found, ignoring drop request");
return 0;
}
ENTER("");
groups = g_key_file_get_groups (state_file, &num_groups);
for (i = 0; i < num_groups; i++)
{
if (g_strstr_len (groups[i], -1, partial_name))
{
DEBUG ("Section \"%s\" matches \"%s\", removing", groups[i], partial_name);
found_count++;
if (!g_key_file_remove_group (state_file, groups[i], &error))
{
PWARN ("Warning: unable to remove section %s.\n %s",
groups[i],
error->message);
g_error_free (error);
}
else
dropped_count++;
}
}
g_strfreev (groups);
LEAVE("Found %i sections matching \"%s\", successfully removed %i",
found_count, partial_name, dropped_count);
return dropped_count;
}

View File

@ -85,6 +85,23 @@ void gnc_state_save (const QofSession *session);
*/
GKeyFile *gnc_state_get_current (void);
/** Drop all sections from the state file whose name contains
* partial_name.
*
* This function is meant to be called when an object is deleted
* for which state is kept. For example, when an account is
* deleted from GnuCash, all state sections that refer to it
* should get removed. In that case you can call this function
* with the account's guid as parameter.
*
* @param partial_name a string to match in the section names
* for most objects in GnuCash that maintain
* state, this will be the object's guid
*
* @return The number of successfully dropped sections.
*/
gint gnc_state_drop_sections_for (const gchar *partial_name);
#endif /* GNC_STATE_H */
/** @} */
/** @} */

View File

@ -56,7 +56,10 @@
#endif
#include "gnc-gkeyfile-utils.h"
#include "qof.h"
/* This static indicates the debugging module that this .o belongs to. */
static QofLogModule log_module = G_LOG_DOMAIN;
GKeyFile *
gnc_key_file_load_from_file (const gchar *filename,
@ -111,6 +114,7 @@ gnc_key_file_save_to_file (const gchar *filename,
g_return_val_if_fail(*error == NULL, FALSE);
contents = g_key_file_to_data(key_file, NULL, NULL);
DEBUG("Keyfile data:\n%s", contents);
length = strlen(contents);
fd = g_open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0666);
if (fd == -1)

View File

@ -56,6 +56,7 @@
#include "option-util.h"
#include "gnc-main-window.h"
#include "gnc-component-manager.h"
#include "gnc-state.h"
#include "qof.h"
@ -491,7 +492,8 @@ gnc_budget_view_delete_budget(GncBudgetView *view)
ENTER("view %p", view);
priv = GNC_BUDGET_VIEW_GET_PRIVATE (view);
gnc_tree_view_remove_state_information (GNC_TREE_VIEW (priv->tree_view));
gnc_state_drop_sections_for (guid_to_string (&priv->key));
g_object_set (G_OBJECT (priv->tree_view), "state-section", NULL, NULL);
LEAVE(" ");
}

View File

@ -57,6 +57,7 @@
#include "gnc-prefs.h"
#include "gnc-session.h"
#include "gnc-split-reg.h"
#include "gnc-state.h"
#include "gnc-tree-view-account.h"
#include "gnc-tree-model-account-types.h"
#include "gnc-ui.h"
@ -1388,12 +1389,17 @@ gnc_plugin_page_account_tree_cmd_delete_account (GtkAction *action, GncPluginPag
if (GTK_RESPONSE_ACCEPT == response)
{
GList *acct_list, *ptr;
const GncGUID *guid;
const gchar *guid_str;
gnc_set_busy_cursor(NULL, TRUE);
gnc_suspend_gui_refresh ();
/* Move subaccounts and transactions if this was requested */
xaccAccountBeginEdit (account);
if (NULL != saa)
{
GList *acct_list, *ptr;
xaccAccountBeginEdit (saa);
acct_list = gnc_account_get_children(account);
@ -1414,10 +1420,31 @@ gnc_plugin_page_account_tree_cmd_delete_account (GtkAction *action, GncPluginPag
/* Move the splits of the account to be deleted. */
xaccAccountMoveAllSplits (account, ta);
}
xaccAccountCommitEdit (account);
/* Drop all references from the state file for
* any subaccount the account still has
*/
acct_list = gnc_account_get_children(account);
for (ptr = acct_list; ptr; ptr = g_list_next(ptr))
{
guid = xaccAccountGetGUID (ptr->data);
guid_str = guid_to_string (guid);
gnc_state_drop_sections_for (guid_str);
}
g_list_free(acct_list);
/* Drop all references from the state file for this account
*/
guid = xaccAccountGetGUID (account);
guid_str = guid_to_string (guid);
gnc_state_drop_sections_for (guid_str);
/*
* Finally, delete the account, any subaccounts it may still
* have, and any splits it or its subaccounts may still have.
*/
xaccAccountBeginEdit (account);
xaccAccountDestroy (account);
gnc_resume_gui_refresh ();
gnc_unset_busy_cursor(NULL);

View File

@ -382,6 +382,12 @@ gnc_plugin_page_budget_refresh_cb(GHashTable *changes, gpointer user_data)
{
if (ei->event_mask & QOF_EVENT_DESTROY)
{
/* Budget has been deleted, close plugin page
* but prevent that action from writing state information
* for this budget account
*/
priv->delete_budget = TRUE;
gnc_budget_view_delete_budget (priv->budget_view);
gnc_plugin_page_budget_close_cb(user_data);
return;
}

View File

@ -3899,6 +3899,11 @@ gnc_plugin_page_register2_refresh_cb (GHashTable *changes, gpointer user_data) /
{
if (ei->event_mask & QOF_EVENT_DESTROY)
{
/* Account has been deleted, close plugin page
* but prevent that action from writing state information
* for this deleted account
*/
g_object_set (G_OBJECT (view), "state-section", NULL, NULL);
gnc_main_window_close_page (GNC_PLUGIN_PAGE (page));
return;
}