Split an odd corner case off of the register delete code and give it

its own menu item.  This is the new "reinitialize transaction" menu
item.


git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@7381 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
David Hampton 2002-10-26 03:54:14 +00:00
parent 111939ef7e
commit 6cb4340303
11 changed files with 223 additions and 187 deletions

View File

@ -1,3 +1,30 @@
2002-10-25 David Hampton <hampton@employees.org>
* src/gnome/window-register.c: Split the transaction delete
functionality into two functions. The first deletes a split or
transaction, as expected. The second handles what was an odd
corner case of the delete command, and removes all splits except
for the one attached to the current register. This is now called
the "reinitialize" function. (Fixes 85904).
* src/register/ledger-core/split-register.h:
* src/register/ledger-core/split-register-p.h: Make
gnc_split_register_get_current_trans_split() a public function.
* src/register/ledger-core/split-register.c
(gnc_split_register_emtpy_current_trans_except_split): New
function that lets you specify which split to keep when
reinitializing a transaction.
* src/gnome-utils/gnc-gui-query.c: Add a couple more variant ways
to create a dialog box. At some point these should all be cleaned
up and maybe made a subclass of a gnome dialog.
* src/register/ledger-core/gnc-regwidget.c:
* src/engine/Transaction.c: Move trans_has_reconciled_splits()
function from one file to another and rename it
xaccTransHasReconciledSplits().
2002-10-24 Christian Stimming <stimming@tuhh.de>
* src/gnome/window-acct-tree.c,

View File

@ -2675,6 +2675,39 @@ xaccTransCountSplits (Transaction *trans)
return g_list_length (trans->splits);
}
gboolean
xaccTransHasReconciledSplitsByAccount (Transaction *trans, Account *account)
{
GList *node;
for (node = xaccTransGetSplitList (trans); node; node = node->next)
{
Split *split = node->data;
if (account && (xaccSplitGetAccount(split) != account))
continue;
switch (xaccSplitGetReconcile (split))
{
case YREC:
case FREC:
return TRUE;
default:
break;
}
}
return FALSE;
}
gboolean
xaccTransHasReconciledSplits (Transaction *trans)
{
return xaccTransHasReconciledSplitsByAccount (trans, NULL);
}
/********************************************************************\
\********************************************************************/

View File

@ -245,6 +245,10 @@ char xaccTransGetTxnType (Transaction *trans);
*/
int xaccTransCountSplits (Transaction *trans);
gboolean xaccTransHasReconciledSplits (Transaction *trans);
gboolean xaccTransHasReconciledSplitsByAccount (Transaction *trans,
Account *account);
/* --------------------------------------------------------------- */
/* Commmodity routines. Each transaction's 'currency' is by definition
* the balancing common currency for the splits in that transaction.

View File

@ -513,7 +513,22 @@ gnc_generic_question_dialog(const char **buttons, const gchar *format, ...)
}
int
gnc_generic_warning_dialog(const char **buttons, const gchar *format, ...)
gnc_generic_question_dialog_parented(GtkWidget *parent, const char **buttons,
const gchar *format, ...)
{
int result;
va_list args;
va_start(args, format);
result = gnc_generic_dialog_common(parent,
GNOME_MESSAGE_BOX_QUESTION,
buttons, format, args);
va_end(args);
return(result);
}
int
gnc_generic_warning_dialog(const char **buttons, const char *format, ...)
{
int result;
va_list args;
@ -526,6 +541,21 @@ gnc_generic_warning_dialog(const char **buttons, const gchar *format, ...)
return(result);
}
int
gnc_generic_warning_dialog_parented(GtkWidget *parent, const char **buttons,
const char *format, ...)
{
int result;
va_list args;
va_start(args, format);
result = gnc_generic_dialog_common(parent,
GNOME_MESSAGE_BOX_WARNING,
buttons, format, args);
va_end(args);
return(result);
}
int
gnc_generic_error_dialog(const char **buttons, const gchar *format, ...)
{

View File

@ -48,10 +48,18 @@ extern int
gnc_generic_question_dialog(const char **buttons,
const char *format, ...) G_GNUC_PRINTF (2, 3);
extern int
gnc_generic_question_dialog_parented(GtkWidget *parent, const char **buttons,
const char *format, ...) G_GNUC_PRINTF (3, 4);
extern int
gnc_generic_warning_dialog(const char **buttons,
const char *format, ...) G_GNUC_PRINTF (2, 3);
extern int
gnc_generic_warning_dialog_parented(GtkWidget *parent, const char **buttons,
const char *format, ...) G_GNUC_PRINTF (3, 4);
extern int
gnc_generic_error_dialog(const char **buttons,
const char *format, ...) G_GNUC_PRINTF (2, 3);

View File

@ -742,6 +742,19 @@
<right_justify>False</right_justify>
</widget>
<widget>
<class>GtkMenuItem</class>
<name>reinitialize_transaction</name>
<tooltip>Erase all splits except the one for this account.</tooltip>
<signal>
<name>activate</name>
<handler>gnc_register_reinitialize_trans_cb</handler>
<last_modification_time>Wed, 16 Oct 2002 06:27:58 GMT</last_modification_time>
</signal>
<label>Re_initialize Transaction</label>
<right_justify>False</right_justify>
</widget>
<widget>
<class>GtkCheckMenuItem</class>
<name>menu_splits</name>
@ -1375,6 +1388,18 @@
<right_justify>False</right_justify>
</widget>
<widget>
<class>GtkMenuItem</class>
<name>popup_reinitialize</name>
<signal>
<name>activate</name>
<handler>gnc_register_reinitialize_trans_cb</handler>
<last_modification_time>Wed, 16 Oct 2002 06:27:31 GMT</last_modification_time>
</signal>
<label>ReInitialize Transaction</label>
<right_justify>False</right_justify>
</widget>
<widget>
<class>GtkCheckMenuItem</class>
<name>popup_splits</name>

View File

@ -177,6 +177,7 @@ void gnc_register_stock_split_cb (GtkWidget * w, gpointer data);
void gnc_register_edit_cb(GtkWidget *w, gpointer data);
void gnc_register_help_cb(GtkWidget *w, gpointer data);
void gnc_register_new_account_cb(GtkWidget * w, gpointer data);
void gnc_register_reinitialize_trans_cb(GtkWidget *w, gpointer data);
void gnc_register_delete_trans_cb(GtkWidget *w, gpointer data);
void gnc_register_duplicate_trans_cb(GtkWidget *w, gpointer data);
void gnc_register_recur_cb(GtkWidget *w, gpointer data);
@ -2365,133 +2366,71 @@ gnc_register_record_trans_cb (GtkWidget *w, gpointer data)
typedef enum
{
DELETE_TRANS,
DELETE_CANCEL,
DELETE_SPLITS,
DELETE_CANCEL
DELETE_TRANS,
} DeleteType;
static void
gnc_transaction_delete_toggle_cb(GtkToggleButton *button, gpointer data)
{
GtkWidget *text = gtk_object_get_user_data(GTK_OBJECT(button));
gchar *s = data;
gint pos = 0;
gtk_editable_delete_text(GTK_EDITABLE(text), 0, -1);
gtk_editable_insert_text(GTK_EDITABLE(text), s, strlen(s), &pos);
}
static gboolean
trans_has_reconciled_splits (Transaction *trans)
{
GList *node;
for (node = xaccTransGetSplitList (trans); node; node = node->next)
{
Split *split = node->data;
switch (xaccSplitGetReconcile (split))
{
case YREC:
case FREC:
return TRUE;
default:
break;
}
}
return FALSE;
}
/* Remove when porting to gtk2.0 */
#define GTK_STOCK_CANCEL GNOME_STOCK_BUTTON_CANCEL
#define GTK_STOCK_DELETE "Delete"
/********************************************************************\
* gnc_transaction_delete_query *
* creates and displays a dialog which asks the user wheter they *
* want to delete a whole transaction, or just a split. *
* It returns a DeleteType code indicating the user's choice. *
* gnc_register_reinitialize_trans_cb *
* *
* Args: parent - the parent window the dialog should use *
* Returns: DeleteType choice indicator *
\*******************************************************************/
static DeleteType
gnc_transaction_delete_query (GtkWindow *parent, Transaction *trans)
* Args: widget - the widget that called us *
* data - the data struct for this register *
* Return: none *
\********************************************************************/
void
gnc_register_reinitialize_trans_cb(GtkWidget *widget, gpointer data)
{
GtkWidget *dialog;
GtkWidget *trans_button;
GtkWidget *splits_button;
GtkWidget *text;
GladeXML *xml;
gint pos = 0;
gint result;
gboolean reconciled;
RegWindow *regData = data;
VirtualCellLocation vcell_loc;
SplitRegister *reg;
Transaction *trans;
Split *split;
char *buf = NULL;
gint result;
const char *two_choices[] = { N_(GTK_STOCK_CANCEL),
N_("Reinitialize"),
NULL };
const char *message = _("Are you sure you want to reinitialize this "
"transaction?");
const char *usual = _("This selection will delete the whole "
"transaction. This is what you usually want.");
const char *usual_recn = _("This selection will delete the whole "
"transaction.\n\n"
"You would be deleting a transaction "
"with reconciled splits!");
const char *warn = _("Warning: Just deleting all the other splits will "
"make your account unbalanced. You probably "
"shouldn't do this unless you're going to "
"immediately add another split to bring the "
"transaction back into balance.");
const char *warn_recn = _("You would be deleting reconciled splits!");
const char *cbuf;
char *buf;
const char *recn_warn = _("You would be modifying a "
"transaction with reconciled splits!\n"
"This is not a good idea as it will cause your "
"reconciled balance to be off.");
DeleteType return_value;
reg = gnc_ledger_display_get_split_register (regData->ledger);
reconciled = trans_has_reconciled_splits (trans);
trans = gnc_split_register_get_current_trans (reg);
if (xaccTransHasReconciledSplits (trans)) {
buf = g_strconcat (message, "\n\n", recn_warn, NULL);
result =
gnc_generic_warning_dialog_parented(regData->window, two_choices, buf);
} else {
buf = g_strdup (message);
result =
gnc_generic_question_dialog_parented(regData->window, two_choices,buf);
}
g_free(buf);
if (!result)
return;
xml = gnc_glade_xml_new ("register.glade", "Delete Transaction");
dialog = glade_xml_get_widget (xml, "Delete Transaction");
gnome_dialog_set_parent(GNOME_DIALOG(dialog), parent);
text = glade_xml_get_widget (xml, "text");
trans_button = glade_xml_get_widget (xml, "delete_all");
gtk_object_set_user_data(GTK_OBJECT(trans_button), text);
gtk_signal_connect(GTK_OBJECT(trans_button), "toggled",
GTK_SIGNAL_FUNC(gnc_transaction_delete_toggle_cb),
(gpointer) (reconciled ? usual_recn : usual));
splits_button = glade_xml_get_widget (xml, "delete_other");
gtk_object_set_user_data(GTK_OBJECT(splits_button), text);
if (reconciled)
buf = g_strconcat (warn, "\n\n", warn_recn, NULL);
else
buf = g_strdup (warn);
gtk_signal_connect(GTK_OBJECT(splits_button), "toggled",
GTK_SIGNAL_FUNC(gnc_transaction_delete_toggle_cb),
(gpointer) buf);
cbuf = reconciled ? usual_recn : usual;
gtk_editable_insert_text(GTK_EDITABLE(text), cbuf, strlen(cbuf), &pos);
gtk_text_set_line_wrap(GTK_TEXT(text), TRUE);
gtk_text_set_word_wrap(GTK_TEXT(text), TRUE);
result = gnome_dialog_run_and_close(GNOME_DIALOG(dialog));
g_free (buf);
if (result != 0)
return_value = DELETE_CANCEL;
else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(trans_button)))
return_value = DELETE_TRANS;
else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(splits_button)))
return_value = DELETE_SPLITS;
else
return_value = DELETE_CANCEL;
gtk_widget_destroy(dialog);
return return_value;
/*
* Find the "transaction" split for the current transaction. This is
* the split that appears at the top of the transaction in the
* register.
*/
split = gnc_split_register_get_current_split (reg);
if (!gnc_split_register_get_split_virt_loc(reg, split, &vcell_loc))
return;
split = gnc_split_register_get_current_trans_split (reg, &vcell_loc);
gnc_split_register_emtpy_current_trans_except_split (reg, split);
}
@ -2513,6 +2452,9 @@ gnc_register_delete_trans_cb(GtkWidget *widget, gpointer data)
char *buf = NULL;
Split *split;
gint result;
const char *two_choices[] = { N_(GTK_STOCK_CANCEL),
N_(GTK_STOCK_DELETE),
NULL };
reg = gnc_ledger_display_get_split_register (regData->ledger);
@ -2547,7 +2489,9 @@ gnc_register_delete_trans_cb(GtkWidget *widget, gpointer data)
{
const char *format = _("Are you sure you want to delete\n %s\n"
"from the transaction\n %s ?");
const char *recn_warn = _("You would be deleting a reconciled split!");
const char *recn_warn = _("You would be deleting a reconciled split!\n"
"This is not a good idea as it will cause your "
"reconciled balance to be off.");
const char *memo;
const char *desc;
char recn;
@ -2569,10 +2513,12 @@ gnc_register_delete_trans_cb(GtkWidget *widget, gpointer data)
new_buf = g_strconcat (buf, "\n\n", recn_warn, NULL);
g_free (buf);
buf = new_buf;
result =
gnc_generic_warning_dialog_parented(regData->window, two_choices, buf);
} else {
result =
gnc_generic_question_dialog_parented(regData->window, two_choices,buf);
}
result = gnc_verify_dialog_parented (regData->window, FALSE, buf);
g_free(buf);
if (!result)
@ -2586,20 +2532,24 @@ gnc_register_delete_trans_cb(GtkWidget *widget, gpointer data)
/* On a transaction cursor with 2 or fewer splits in single or double
* mode, we just delete the whole transaction, kerblooie */
if ((xaccTransCountSplits(trans) <= 2) && (style == REG_STYLE_LEDGER))
{
const char *message = _("Are you sure you want to delete the current "
"transaction?");
const char *recn_warn = _("You would be deleting a transaction "
"with reconciled splits!");
"with reconciled splits!\n"
"This is not a good idea as it will cause your "
"reconciled balance to be off.");
char *buf;
if (trans_has_reconciled_splits (trans))
if (xaccTransHasReconciledSplits (trans)) {
buf = g_strconcat (message, "\n\n", recn_warn, NULL);
else
result =
gnc_generic_warning_dialog_parented(regData->window, two_choices, buf);
} else {
buf = g_strdup (message);
result = gnc_verify_dialog_parented (regData->window, FALSE, buf);
result =
gnc_generic_question_dialog_parented(regData->window, two_choices,buf);
}
g_free (buf);
@ -2609,32 +2559,6 @@ gnc_register_delete_trans_cb(GtkWidget *widget, gpointer data)
gnc_split_register_delete_current_trans (reg);
return;
}
/* At this point we are on a transaction cursor with more than 2 splits
* or we are on a transaction cursor in multi-line mode or an auto mode.
* We give the user two choices: delete the whole transaction or delete
* all the splits except the transaction split. */
{
DeleteType del_type;
del_type = gnc_transaction_delete_query (GTK_WINDOW(regData->window),
trans);
if (del_type == DELETE_CANCEL)
return;
if (del_type == DELETE_TRANS)
{
gnc_split_register_delete_current_trans (reg);
return;
}
if (del_type == DELETE_SPLITS)
{
gnc_split_register_emtpy_current_trans (reg);
return;
}
}
}

View File

@ -1626,32 +1626,6 @@ gnc_transaction_delete_toggle_cb(GtkToggleButton *button, gpointer data)
gtk_editable_insert_text(GTK_EDITABLE(text), s, strlen(s), &pos);
}
/* jsled: seems generic enough... should probably be moved to a
* better/more-generic place. */
static gboolean
trans_has_reconciled_splits (Transaction *trans)
{
GList *node;
for (node = xaccTransGetSplitList (trans); node; node = node->next)
{
Split *split = node->data;
switch (xaccSplitGetReconcile (split))
{
case YREC:
case FREC:
return TRUE;
default:
break;
}
}
return FALSE;
}
typedef enum
{
DELETE_TRANS,
@ -1700,7 +1674,7 @@ gnc_transaction_delete_query (GtkWindow *parent, Transaction *trans)
DeleteType return_value;
reconciled = trans_has_reconciled_splits (trans);
reconciled = xaccTransHasReconciledSplits (trans);
dialog = gnome_dialog_new(_("Delete Transaction"),
GNOME_STOCK_BUTTON_OK,
@ -1876,7 +1850,7 @@ deleteCB(GNCRegWidget *rw, gpointer data)
"with reconciled splits!");
char *buf;
if (trans_has_reconciled_splits (trans))
if (xaccTransHasReconciledSplits (trans))
buf = g_strconcat (message, "\n\n", recn_warn, NULL);
else
buf = g_strdup (message);

View File

@ -127,10 +127,6 @@ gnc_split_register_get_trans_split (SplitRegister *reg,
VirtualCellLocation vcell_loc,
VirtualCellLocation *trans_split_loc);
Split *
gnc_split_register_get_current_trans_split (SplitRegister *reg,
VirtualCellLocation *vcell_loc);
gboolean gnc_split_register_find_split (SplitRegister *reg,
Transaction *trans, Split *trans_split,
Split *split, CursorClass cursor_class,

View File

@ -1018,7 +1018,7 @@ gnc_split_register_delete_current_trans (SplitRegister *reg)
}
void
gnc_split_register_emtpy_current_trans (SplitRegister *reg)
gnc_split_register_emtpy_current_trans_except_split (SplitRegister *reg, Split *split)
{
SRInfo *info = gnc_split_register_get_info (reg);
Transaction *pending_trans;
@ -1027,7 +1027,6 @@ gnc_split_register_emtpy_current_trans (SplitRegister *reg)
Account *account;
GList *splits;
GList *node;
Split *split;
if (!reg) return;
@ -1037,8 +1036,6 @@ gnc_split_register_emtpy_current_trans (SplitRegister *reg)
pending_trans = xaccTransLookup (&info->pending_trans_guid,
gnc_get_current_book ());
/* get the current split based on cursor position */
split = gnc_split_register_get_current_split (reg);
if (split == NULL)
return;
@ -1094,6 +1091,16 @@ gnc_split_register_emtpy_current_trans (SplitRegister *reg)
g_list_free (splits);
}
void
gnc_split_register_emtpy_current_trans (SplitRegister *reg)
{
Split *split;
/* get the current split based on cursor position */
split = gnc_split_register_get_current_split (reg);
gnc_split_register_emtpy_current_trans_except_split (reg, split);
}
void
gnc_split_register_cancel_cursor_split_changes (SplitRegister *reg)
{

View File

@ -203,6 +203,13 @@ gboolean
gnc_split_register_get_split_amount_virt_loc (SplitRegister *reg, Split *split,
VirtualLocation *virt_loc);
/* Given the current virtual location, find the split that anchors
* this transaction to the current register. Otherwise, returns NULL.
*/
Split *
gnc_split_register_get_current_trans_split (SplitRegister *reg,
VirtualCellLocation *vcell_loc);
/* Duplicates either the current transaction or the current split
* depending on the register mode and cursor position. Returns the
* split just created, or the 'main' split of the transaction just
@ -231,6 +238,7 @@ void gnc_split_register_delete_current_trans (SplitRegister *reg);
/* Deletes the non-transaction splits associated wih the current
* cursor, if both are non-NULL. */
void gnc_split_register_emtpy_current_trans_except_split (SplitRegister *reg, Split *split);
void gnc_split_register_emtpy_current_trans (SplitRegister *reg);
/* Cancels any changes made to the current cursor, reloads the cursor