r17962 - gnucash/trunk/src/register/ledger-core - Bug #499215, #530819, #551643: Register: Fix transaction pasting, which was fairly broken. Pasting was being committed immediately, the transaction was not checked properly before opening, the blank split was being destroyed while the transaction was left pending, and more. These problems left the register in an inconsistent state that was being noticed in g_assert() calls in several spots. GnuCash would then crash.
Charles Day
cedayiv at cvs.gnucash.org
Wed Feb 25 14:10:24 EST 2009
Author: cedayiv
Date: 2009-02-25 14:10:23 -0500 (Wed, 25 Feb 2009)
New Revision: 17962
Trac: http://svn.gnucash.org/trac/changeset/17962
Modified:
gnucash/trunk/src/register/ledger-core/split-register.c
Log:
Bug #499215, #530819, #551643: Register: Fix transaction pasting, which was fairly broken. Pasting was being committed immediately, the transaction was not checked properly before opening, the blank split was being destroyed while the transaction was left pending, and more. These problems left the register in an inconsistent state that was being noticed in g_assert() calls in several spots. GnuCash would then crash.
Modified: gnucash/trunk/src/register/ledger-core/split-register.c
===================================================================
--- gnucash/trunk/src/register/ledger-core/split-register.c 2009-02-25 18:20:22 UTC (rev 17961)
+++ gnucash/trunk/src/register/ledger-core/split-register.c 2009-02-25 19:10:23 UTC (rev 17962)
@@ -690,7 +690,8 @@
scm_gc_protect_object(copied_item);
copied_class = cursor_class;
- LEAVE("");
+ LEAVE("%s %s", use_cut_semantics? "cut" : "copied",
+ cursor_class == CURSOR_CLASS_SPLIT? "split" : "transaction");
}
void
@@ -748,6 +749,7 @@
SRInfo *info = gnc_split_register_get_info(reg);
CursorClass cursor_class;
Transaction *trans;
+ Transaction *blank_trans;
Split *blank_split;
Split *trans_split;
Split *split;
@@ -756,12 +758,13 @@
if (copied_class == CURSOR_CLASS_NONE)
{
- LEAVE("no copied class");
+ LEAVE("no copied cursor class");
return;
}
blank_split = xaccSplitLookup (&info->blank_split_guid,
gnc_get_current_book ());
+ blank_trans = xaccSplitGetParent (blank_split);
split = gnc_split_register_get_current_split (reg);
trans = gnc_split_register_get_current_trans (reg);
@@ -779,14 +782,15 @@
/* Can't do anything with this. */
if (cursor_class == CURSOR_CLASS_NONE)
{
- LEAVE("no cursor class");
+ LEAVE("no current cursor class");
return;
}
/* This shouldn't happen, but be paranoid. */
if ((split == NULL) && (cursor_class == CURSOR_CLASS_TRANS))
{
- LEAVE("null split with transaction class");
+ g_warning("BUG DETECTED: transaction cursor with no anchoring split!");
+ LEAVE("transaction cursor with no anchoring split");
return;
}
@@ -794,21 +798,18 @@
{
const char *message = _("You are about to overwrite an existing split. "
"Are you sure you want to do that?");
- gboolean result;
if (copied_class == CURSOR_CLASS_TRANS)
{
+ /* An entire transaction was copied, but we're just on a split. */
LEAVE("can't copy trans to split");
return;
}
- if (split != NULL)
- result = gnc_verify_dialog (gnc_split_register_get_parent (reg),
- FALSE, "%s", message);
- else
- result = TRUE;
-
- if (!result)
+ /* Ask before overwriting an existing split. */
+ if (split != NULL &&
+ !gnc_verify_dialog (gnc_split_register_get_parent (reg),
+ FALSE, "%s", message))
{
LEAVE("user cancelled");
return;
@@ -830,8 +831,6 @@
const char *message = _("You are about to overwrite an existing "
"transaction. "
"Are you sure you want to do that?");
- gboolean result;
-
Account * copied_leader;
const GUID *new_guid;
int trans_split_index;
@@ -844,27 +843,27 @@
return;
}
- if (split != blank_split)
- result = gnc_verify_dialog(gnc_split_register_get_parent(reg),
- FALSE, "%s", message);
- else
- result = TRUE;
-
- if (!result)
+ /* Ask before overwriting an existing transaction. */
+ if (split != blank_split &&
+ !gnc_verify_dialog(gnc_split_register_get_parent(reg),
+ FALSE, "%s", message))
{
LEAVE("user cancelled");
return;
}
- gnc_suspend_gui_refresh ();
-
- /* in pasting, the old split is deleted. */
- if (split == blank_split)
+ /* Open the transaction for editing. */
+ if (gnc_split_register_begin_edit_or_warn(info, trans))
{
- info->blank_split_guid = *guid_null();
- blank_split = NULL;
+ LEAVE("can't begin editing");
+ return;
}
+ gnc_suspend_gui_refresh ();
+
+ DEBUG("Pasting txn, trans=%p, split=%p, blank_trans=%p, blank_split=%p",
+ trans, split, blank_trans, blank_split);
+
split_index = xaccTransGetSplitIndex(trans, split);
trans_split_index = xaccTransGetSplitIndex(trans, trans_split);
@@ -875,17 +874,30 @@
new_guid = &info->default_account;
gnc_copy_trans_scm_onto_trans_swap_accounts(copied_item, trans,
&copied_leader_guid,
- new_guid, TRUE,
+ new_guid, FALSE,
gnc_get_current_book ());
}
else
- gnc_copy_trans_scm_onto_trans(copied_item, trans, TRUE,
+ gnc_copy_trans_scm_onto_trans(copied_item, trans, FALSE,
gnc_get_current_book ());
num_splits = xaccTransCountSplits(trans);
if (split_index >= num_splits)
split_index = 0;
+ if (trans == blank_trans)
+ {
+ /* In pasting, the blank split is deleted. Pick a new one. */
+ blank_split = xaccTransGetSplit(trans, 0);
+ info->blank_split_guid = *xaccSplitGetGUID (blank_split);
+ info->blank_split_edited = TRUE;
+ DEBUG("replacement blank_split=%p", blank_split);
+
+ /* NOTE: At this point, the blank transaction virtual cell is still
+ * anchored by the old, deleted blank split. The register will
+ * have to be reloaded (redrawn) to correct this. */
+ }
+
info->cursor_hint_trans = trans;
info->cursor_hint_split = xaccTransGetSplit(trans, split_index);
info->cursor_hint_trans_split = xaccTransGetSplit(trans,
More information about the gnucash-changes
mailing list