Replace the changes in r13361 with a better method for determining

when a change in the register needs to be reflected in the available
user actions.  Now updates the Void and Unvoid actions which
implements the enhancement request in 330763.


git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@13610 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
David Hampton 2006-03-12 21:54:04 +00:00
parent 5af42fc6b1
commit 872a2cafa8
10 changed files with 162 additions and 71 deletions

View File

@ -1,3 +1,16 @@
2006-03-12 David Hampton <hampton@employees.org>
* src/register/register-gnome/gnucash-sheet.[ch]:
* src/register/ledger-core/split-register.[ch]:
* src/register/ledger-core/split-register-control.c:
* src/gnome/gnc-split-reg.[ch]:
* src/gnome/gnc-plugin-page-register.c:
* src/engine/Transaction.h: Replace the changes in r13361 with a
better method for determining when a change in the register needs
to be reflected in the available user actions. Now updates the
Void and Unvoid actions which implements the enhancement request
in 330763.
2006-03-11 David Hampton <hampton@employees.org>
* src/register/register-gnome/combocell-gnome.c:

View File

@ -92,6 +92,9 @@ Splits plus the value of all of its sub-Accounts.
#include "gnc-engine.h"
#include "Split.h"
#define GNC_IS_TRANS(obj) (QOF_CHECK_TYPE((obj), GNC_ID_TRANS))
#define GNC_TRANS(obj) (QOF_CHECK_CAST((obj), GNC_ID_TRANS, Transaction))
/** @name Transaction Type field values
@{
*/

View File

@ -2,7 +2,7 @@
* gnc-plugin-page-register.c --
*
* Copyright (C) 2003 Jan Arne Petersen <jpetersen@uni-bonn.de>
* Copyright (C) 2003,2005 David Hampton <hampton@employees.org>
* Copyright (C) 2003,2005,2006 David Hampton <hampton@employees.org>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@ -57,6 +57,7 @@
#include "gnc-date.h"
#include "gnc-date-edit.h"
#include "gnc-engine.h"
#include "gnc-event.h"
#include "gnc-gnome-utils.h"
#include "gnc-gobject-utils.h"
#include "gnc-gui-query.h"
@ -148,8 +149,12 @@ static void gnc_plugin_page_register_cmd_transaction_report (GtkAction *action,
static void gnc_plugin_page_help_changed_cb( GNCSplitReg *gsr, GncPluginPageRegister *register_page );
static void gnc_plugin_page_register_refresh_cb (GHashTable *changes, gpointer user_data);
static void gnc_plugin_page_register_update_split_button (SplitRegister *reg, GncPluginPageRegister *page);
static void gnc_plugin_page_register_ui_update (gpointer various, GncPluginPageRegister *page);
static void gppr_account_destroy_cb (Account *account);
static void gnc_plugin_page_register_event_handler (QofEntity *entity,
QofEventId event_type,
GncPluginPageRegister *page,
GncEventData *ed);
/************************************************************/
/* Actions */
@ -355,6 +360,7 @@ typedef struct GncPluginPageRegisterPrivate
GtkWidget *widget;
gint event_handler_id;
gint component_manager_id;
GUID key; /* The guid of the Account we're watching */
@ -456,8 +462,6 @@ gnc_plugin_page_register_new_common (GNCLedgerDisplay *ledger)
// Do not free the list. It is owned by the query.
reg = gnc_ledger_display_get_split_register(priv->ledger);
gnc_split_register_set_trans_collapsed_cb
(reg, (GFunc)gnc_plugin_page_register_update_split_button, register_page);
priv->component_manager_id = 0;
return plugin_page;
@ -600,38 +604,41 @@ gnc_plugin_page_register_get_account (GncPluginPageRegister *page)
static void
gnc_plugin_page_register_update_split_button (SplitRegister *reg, GncPluginPageRegister *page)
gnc_plugin_page_register_ui_update (gpointer various, GncPluginPageRegister *page)
{
GncPluginPageRegisterPrivate *priv;
SplitRegister *reg;
GtkAction *action;
gboolean expanded;
gboolean expanded, voided;
Transaction *trans;
/* Set 'Split Transaction' */
priv = GNC_PLUGIN_PAGE_REGISTER_GET_PRIVATE(page);
reg = gnc_ledger_display_get_split_register(priv->ledger);
expanded = gnc_split_register_current_trans_expanded(reg);
action = gnc_plugin_page_get_action (GNC_PLUGIN_PAGE(page),
"SplitTransactionAction");
gtk_action_set_sensitive (action, reg->style == REG_STYLE_LEDGER);
g_signal_handlers_block_by_func
(action, gnc_plugin_page_register_cmd_expand_transaction, page);
gtk_toggle_action_set_active (GTK_TOGGLE_ACTION(action), expanded);
g_signal_handlers_unblock_by_func
(action, gnc_plugin_page_register_cmd_expand_transaction, page);
}
static void
gnc_plugin_page_register_update_toolbar (SplitRegister *reg, GncPluginPageRegister *page)
{
GtkAction *action;
/* Set 'Void' and 'Unvoid' */
trans = gnc_split_register_get_current_trans(reg);
voided = xaccTransHasSplitsInState(trans, VREC);
action = gnc_plugin_page_get_action (GNC_PLUGIN_PAGE(page),
"VoidTransactionAction");
gtk_action_set_sensitive (GTK_ACTION(action), !voided);
action = gnc_plugin_page_get_action (GNC_PLUGIN_PAGE(page),
"SplitTransactionAction");
/* set sensitivity of split button */
gtk_action_set_sensitive (action, reg->style == REG_STYLE_LEDGER);
/* set activity of split button */
gnc_plugin_page_register_update_split_button (reg, page);
"UnvoidTransactionAction");
gtk_action_set_sensitive (GTK_ACTION(action), voided);
}
static void
gnc_plugin_page_register_update_menus (GncPluginPageRegister *page)
gnc_plugin_page_register_ui_initial_state (GncPluginPageRegister *page)
{
GncPluginPageRegisterPrivate *priv ;
GtkActionGroup *action_group;
@ -726,8 +733,8 @@ gnc_plugin_page_register_create_widget (GncPluginPage *plugin_page)
reg->use_double_line);
gnc_ledger_display_refresh(priv->ledger);
gnc_plugin_page_register_update_menus (page);
gnc_plugin_page_register_update_toolbar (reg, page);
gnc_plugin_page_register_ui_initial_state (page);
gnc_plugin_page_register_ui_update (NULL, page);
plugin_page->summarybar = gsr_create_summary_bar(priv->gsr);
if (plugin_page->summarybar) {
@ -736,6 +743,8 @@ gnc_plugin_page_register_create_widget (GncPluginPage *plugin_page)
FALSE, FALSE, 0);
}
priv->event_handler_id = qof_event_register_handler
((QofEventHandler)gnc_plugin_page_register_event_handler, page);
priv->component_manager_id =
gnc_register_gui_component(GNC_PLUGIN_PAGE_REGISTER_NAME,
gnc_plugin_page_register_refresh_cb,
@ -748,6 +757,8 @@ gnc_plugin_page_register_create_widget (GncPluginPage *plugin_page)
priv->component_manager_id, xaccAccountGetGUID(acct),
QOF_EVENT_DESTROY | QOF_EVENT_MODIFY);
gnc_split_reg_set_moved_cb
(priv->gsr, (GFunc)gnc_plugin_page_register_ui_update, page);
/* DRH - Probably lots of other stuff from regWindowLedger should end up here. */
LEAVE(" ");
@ -772,6 +783,11 @@ gnc_plugin_page_register_destroy_widget (GncPluginPage *plugin_page)
priv->component_manager_id = 0;
}
if (priv->event_handler_id) {
qof_event_unregister_handler(priv->event_handler_id);
priv->event_handler_id = 0;
}
if (priv->sd.dialog) {
gtk_widget_destroy(priv->sd.dialog);
memset(&priv->sd, 0, sizeof(priv->sd));
@ -1895,10 +1911,8 @@ gnc_plugin_page_register_cmd_void_transaction (GtkAction *action,
trans = gnc_split_register_get_current_trans(reg);
if (trans == NULL)
return;
if (xaccTransHasSplitsInState(trans, VREC)) {
gnc_error_dialog(NULL, _("This transaction has already been voided."));
if (xaccTransHasSplitsInState(trans, VREC))
return;
}
if (xaccTransHasReconciledSplits(trans) || xaccTransHasSplitsInState(trans, CREC)) {
gnc_error_dialog(NULL, _("You cannot void a transaction with reconciled or cleared splits."));
return;
@ -1937,10 +1951,8 @@ gnc_plugin_page_register_cmd_unvoid_transaction (GtkAction *action,
priv = GNC_PLUGIN_PAGE_REGISTER_GET_PRIVATE(page);
reg = gnc_ledger_display_get_split_register(priv->ledger);
trans = gnc_split_register_get_current_trans(reg);
if (!xaccTransHasSplitsInState(trans, VREC)) {
gnc_error_dialog(NULL, _("This transaction is not voided."));
if (!xaccTransHasSplitsInState(trans, VREC))
return;
}
gnc_split_register_unvoid_current_trans(reg);
LEAVE(" ");
}
@ -2174,7 +2186,6 @@ gnc_plugin_page_register_cmd_style_changed (GtkAction *action,
GncPluginPageRegister *plugin_page)
{
GncPluginPageRegisterPrivate *priv;
SplitRegister *reg;
SplitRegisterStyle value;
ENTER("(action %p, radio action %p, plugin_page %p)",
@ -2188,8 +2199,7 @@ gnc_plugin_page_register_cmd_style_changed (GtkAction *action,
value = gtk_radio_action_get_current_value(current);
gnc_split_reg_change_style(priv->gsr, value);
reg = gnc_ledger_display_get_split_register(priv->ledger);
gnc_plugin_page_register_update_toolbar (reg, plugin_page);
gnc_plugin_page_register_ui_update (NULL, plugin_page);
LEAVE(" ");
}
@ -2731,6 +2741,8 @@ gnc_plugin_page_register_refresh_cb (GHashTable *changes, gpointer user_data)
gnucash_register_refresh_from_gconf(priv->gsr->reg);
gtk_widget_queue_draw(priv->widget);
}
gnc_plugin_page_register_ui_update(NULL, page);
}
/** This function is called when an account has been edited and an
@ -2777,5 +2789,76 @@ gppr_account_destroy_cb (Account *account)
}
}
/** This function is the handler for all event messages from the
* engine. Its purpose is to update the account tree model any time
* an account is added to the engine or deleted from the engine.
* This change to the model is then propagated to any/all overlying
* filters and views. This function listens to the ADD, REMOVE, and
* DESTROY events.
*
* @internal
*
* @warning There is a "Catch 22" situation here.
* gtk_tree_model_row_deleted() can't be called until after the item
* has been deleted from the real model (which is the engine's
* account tree for us), but once the account has been deleted from
* the engine we have no way to determine the path to pass to
* row_deleted(). This is a PITA, but the only other choice is to
* have this model mirror the engine's accounts instead of
* referencing them directly.
*
* @param entity The guid of the affected item.
*
* @param type The type of the affected item. This function only
* cares about items of type "account".
*
* @param event type The type of the event. This function only cares
* about items of type ADD, REMOVE, MODIFY, and DESTROY.
*
* @param user_data A pointer to the account tree model.
*/
static void
gnc_plugin_page_register_event_handler (QofEntity *entity,
QofEventId event_type,
GncPluginPageRegister *page,
GncEventData *ed)
{
Transaction *trans;
QofBook *book;
GncPluginPage *visible_page;
GtkWidget *window;
g_return_if_fail(page); /* Required */
if (!GNC_IS_TRANS(entity))
return;
ENTER("entity %p of type %d, page %p, event data %p",
entity, event_type, page, ed);
if (!(event_type & (QOF_EVENT_MODIFY | QOF_EVENT_DESTROY))) {
LEAVE("not a modify");
return;
}
trans = GNC_TRANS(entity);
book = qof_instance_get_book(QOF_INSTANCE(trans));
if (!gnc_plugin_page_has_book(GNC_PLUGIN_PAGE(page), book)) {
LEAVE("not in this book");
return;
}
window = gnc_plugin_page_get_window(GNC_PLUGIN_PAGE(page));
visible_page = gnc_main_window_get_current_page(GNC_MAIN_WINDOW(window));
if (GNC_PLUGIN_PAGE(page) != visible_page) {
LEAVE("page not visible");
return;
}
gnc_plugin_page_register_ui_update(NULL, page);
LEAVE(" ");
return;
}
/** @} */
/** @} */

View File

@ -2021,3 +2021,9 @@ gnc_split_reg_get_read_only( GNCSplitReg *gsr )
g_assert( gsr );
return gsr->read_only;
}
void
gnc_split_reg_set_moved_cb( GNCSplitReg *gsr, GFunc cb, gpointer cb_data )
{
gnucash_register_set_moved_cb (gsr->reg, cb, cb_data);
}

View File

@ -238,4 +238,6 @@ void gsr_default_reinit_handler( GNCSplitReg *gsr, gpointer data );
void gsr_default_expand_handler( GNCSplitReg *gsr, gpointer data );
void gsr_default_schedule_handler( GNCSplitReg *gsr, gpointer data );
void gnc_split_reg_set_moved_cb( GNCSplitReg *gsr, GFunc cb, gpointer cb_data );
#endif /* GNC_SPLIT_REG_H */

View File

@ -423,7 +423,7 @@ gnc_split_register_move_cursor (VirtualLocation *p_new_virt_loc,
reg->style == REG_STYLE_JOURNAL);
}
gnc_split_register_collapse_current_trans(reg);
info->trans_expanded = FALSE;
do_refresh = TRUE;
}

View File

@ -205,30 +205,6 @@ gnc_split_register_expand_current_trans (SplitRegister *reg, gboolean expand)
reg->table->current_cursor_loc.vcell_loc);
}
void
gnc_split_register_collapse_current_trans (SplitRegister *reg)
{
SRInfo *info = gnc_split_register_get_info (reg);
if (!reg)
return;
info->trans_expanded = FALSE;
if (reg->expand_changed_cb)
(reg->expand_changed_cb)(reg, reg->expand_changed_cb_data);
}
void
gnc_split_register_set_trans_collapsed_cb (SplitRegister *reg, GFunc cb,
gpointer cb_data)
{
if (!reg)
return;
reg->expand_changed_cb = cb;
reg->expand_changed_cb_data = cb_data;
}
gboolean
gnc_split_register_current_trans_expanded (SplitRegister *reg)
{
@ -536,7 +512,7 @@ gnc_split_register_duplicate_current (SplitRegister *reg)
info->cursor_hint_trans_split = trans_split;
info->cursor_hint_cursor_class = CURSOR_CLASS_TRANS;
gnc_split_register_collapse_current_trans(reg);
info->trans_expanded = FALSE;
}
/* Refresh the GUI. */
@ -923,7 +899,7 @@ gnc_split_register_delete_current_trans (SplitRegister *reg)
return;
}
gnc_split_register_collapse_current_trans(reg);
info->trans_expanded = FALSE;
gnc_suspend_gui_refresh ();
@ -975,7 +951,7 @@ gnc_split_register_void_current_trans (SplitRegister *reg, const char *reason)
if (xaccSplitGetReconcile (split) == VREC)
return;
gnc_split_register_collapse_current_trans(reg);
info->trans_expanded = FALSE;
gnc_suspend_gui_refresh ();
@ -1024,7 +1000,7 @@ gnc_split_register_unvoid_current_trans (SplitRegister *reg)
if (xaccSplitGetReconcile (split) != VREC)
return;
gnc_split_register_collapse_current_trans(reg);
info->trans_expanded = FALSE;
gnc_suspend_gui_refresh ();

View File

@ -240,9 +240,6 @@ struct split_register
{
Table * table; /**< The table itself that implements the underlying GUI. */
GFunc expand_changed_cb;
gpointer expand_changed_cb_data;
SplitRegisterType type;
SplitRegisterStyle style;
@ -416,11 +413,6 @@ void gnc_split_register_expand_current_trans (SplitRegister *reg,
/** Mark the current transaction as collapsed, and do callbacks. */
void gnc_split_register_collapse_current_trans (SplitRegister *reg);
/** Register a callback function for when the register closes a
* transaction without the user explicitly asking for this to
* be changed. */
void gnc_split_register_set_trans_collapsed_cb (SplitRegister *reg, GFunc cb, gpointer cb_data);
/** Return TRUE if current trans is expanded and style is REG_STYLE_LEDGER. */
gboolean gnc_split_register_current_trans_expanded (SplitRegister *reg);

View File

@ -309,6 +309,8 @@ gnucash_sheet_cursor_move (GnucashSheet *sheet, VirtualLocation virt_loc)
/* Now turn on the editing controls. */
gnucash_sheet_activate_cursor_cell (sheet, changed_cells);
if (sheet->moved_cb)
(sheet->moved_cb)(sheet, sheet->moved_cb_data);
return changed_cells;
}
@ -2620,6 +2622,19 @@ gnucash_register_new (Table *table)
}
void gnucash_register_set_moved_cb (GnucashRegister *reg,
GFunc cb, gpointer cb_data)
{
GnucashSheet *sheet;
if (!reg || !reg->sheet)
return;
sheet = GNUCASH_SHEET(reg->sheet);
sheet->moved_cb = cb;
sheet->moved_cb_data = cb_data;
}
/*
Local Variables:
c-basic-offset: 8

View File

@ -123,6 +123,9 @@ typedef struct
guint changed_signal;
GtkAdjustment *hadj, *vadj;
GFunc moved_cb;
gpointer moved_cb_data;
} GnucashSheet;
@ -149,10 +152,6 @@ GType gnucash_register_get_type (void);
/* this already has scrollbars attached */
GtkWidget *gnucash_register_new (Table *table);
void gnucash_sheet_set_top_block (GnucashSheet *sheet, int new_top_block,
gint align);
SheetBlock *gnucash_sheet_get_block (GnucashSheet *sheet,
VirtualCellLocation vcell_loc);
@ -214,6 +213,8 @@ void gnucash_register_cut_clipboard (GnucashRegister *reg);
void gnucash_register_copy_clipboard (GnucashRegister *reg);
void gnucash_register_paste_clipboard (GnucashRegister *reg);
void gnucash_register_refresh_from_gconf (GnucashRegister *reg);
void gnucash_register_set_moved_cb (GnucashRegister *reg,
GFunc cb, gpointer cb_data);
typedef struct
{