From b7ed99154a0542dd65ea17f876c11993cefbfa13 Mon Sep 17 00:00:00 2001 From: Joshua Sled Date: Sun, 6 Oct 2002 22:31:05 +0000 Subject: [PATCH] 2002-10-06 Joshua Sled * src/gnome/druid-loan.c: The druid now enforces valid account selection for the GNCAccountSel widgets; fixes Bug#90784. * src/gnome/gnc-account-sel.c (gas_destroy): GNCAccountSel now cleans up after itself, especially with removing its engine event observation. Moved from src/gnome-utils/ to src/gnome/ because of circular dep introduced below. * src/dialog-account/dialog-account.c (gnc_ui_new_account_with_types): Added new function to create a NewAccount dialog with only a valid-types filtering list. * src/gnome-utils/gnc-account-sel.c (gnc_account_sel_set_acct_filters): Added support for filtering the accounts available through the GNCAccountSel. (gnc_account_sel_set_new_account_ability): Added support for a conditional "New..." button which allows the creation a new account. If the selector has a filter in place, the filter will apply to the new-account creation as well. * src/gnome-utils/gnc-account-sel.c: Added ifdefs, comments around regions pertaining to unimplemented feature of completion. Fix for Bug#90779. (gnc_account_sel_event_cb): Added support for updating list contents when the account tree changes; the current selection is respected if the account still exists; fixes Bug#94951. * src/gnome/dialog-sxsincelast.c (sxsld_process_to_create_instance): Handle the corner case of not incrementing the state while postponing/ignoring a never-been-created SX. Handle only incrementing the counters of newly-come-due SXes. * src/engine/SchedXaction.c (gnc_sx_create_temporal_state): Fix corner case of creating the temporal state of a never-been-created SX; fixes Bug#94947. git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@7283 57a11ea4-9604-0410-9ed3-97b8803252fd --- ChangeLog | 39 ++ src/AccWindow.h | 9 + src/backend/file/test/test-file-stuff.c | 1 + src/backend/file/test/test-real-data.sh | 2 +- src/backend/file/test/test-xml-transaction.c | 5 + src/engine/SchedXaction.c | 23 +- src/gnome-utils/Makefile.am | 2 - src/gnome-utils/gnc-account-sel.c | 301 ------------ src/gnome/Makefile.am | 2 + src/gnome/dialog-sxsincelast.c | 52 +- src/gnome/druid-loan.c | 72 ++- src/gnome/glade/sched-xact.glade | 56 --- src/gnome/gnc-account-sel.c | 477 +++++++++++++++++++ src/{gnome-utils => gnome}/gnc-account-sel.h | 51 +- src/gnome/window-main.c | 2 +- 15 files changed, 694 insertions(+), 400 deletions(-) delete mode 100644 src/gnome-utils/gnc-account-sel.c create mode 100644 src/gnome/gnc-account-sel.c rename src/{gnome-utils => gnome}/gnc-account-sel.h (57%) diff --git a/ChangeLog b/ChangeLog index 1c0ff91685..05590b0336 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,42 @@ +2002-10-06 Joshua Sled + + * src/gnome/druid-loan.c: The druid now enforces valid account + selection for the GNCAccountSel widgets; fixes Bug#90784. + + * src/gnome/gnc-account-sel.c (gas_destroy): GNCAccountSel + now cleans up after itself, especially with removing its engine + event observation. Moved from src/gnome-utils/ to src/gnome/ + because of circular dep introduced below. + + * src/dialog-account/dialog-account.c + (gnc_ui_new_account_with_types): Added new function to create a + NewAccount dialog with only a valid-types filtering list. + + * src/gnome-utils/gnc-account-sel.c + (gnc_account_sel_set_acct_filters): Added support for filtering + the accounts available through the GNCAccountSel. + (gnc_account_sel_set_new_account_ability): Added support for a + conditional "New..." button which allows the creation a new + account. If the selector has a filter in place, the filter will + apply to the new-account creation as well. + + * src/gnome-utils/gnc-account-sel.c: Added ifdefs, comments around + regions pertaining to unimplemented feature of completion. + Fix for Bug#90779. + (gnc_account_sel_event_cb): Added support for updating list + contents when the account tree changes; the current selection is + respected if the account still exists; fixes Bug#94951. + + * src/gnome/dialog-sxsincelast.c + (sxsld_process_to_create_instance): Handle the corner case of not + incrementing the state while postponing/ignoring a + never-been-created SX. Handle only incrementing the counters of + newly-come-due SXes. + + * src/engine/SchedXaction.c (gnc_sx_create_temporal_state): Fix + corner case of creating the temporal state of a never-been-created + SX; fixes Bug#94947. + 2002-10-06 Christian Stimming * src/import-export/hbci/gnc-hbci-gettrans.c, gnc-hbci-actions.c: diff --git a/src/AccWindow.h b/src/AccWindow.h index 2e91df8ca5..fde1206327 100644 --- a/src/AccWindow.h +++ b/src/AccWindow.h @@ -40,6 +40,15 @@ AccountWindow * gnc_ui_new_account_window_with_default(AccountGroup *group, Account * parent); AccountWindow * gnc_ui_edit_account_window (Account *account); +/** + * @param unused The AccountGroup to create in; this isn't used. + * @param valid_types A GList of GNCAccountType gints [as pointers] which are + * allowed to be created. Unlike below, this function makes a copy of the + * valid_types list. + **/ +AccountWindow * gnc_ui_new_account_with_types( AccountGroup *unused, + GList *valid_types ); + Account * gnc_ui_new_accounts_from_name_window (const char *name); /* Note that the caller owns the valid_types list */ diff --git a/src/backend/file/test/test-file-stuff.c b/src/backend/file/test/test-file-stuff.c index f4a0110478..aac38455ce 100644 --- a/src/backend/file/test/test-file-stuff.c +++ b/src/backend/file/test/test-file-stuff.c @@ -363,6 +363,7 @@ test_files_in_dir(int argc, char **argv, gxpf_callback cb, { if(!S_ISDIR(file_info.st_mode)) { + printf( "testing load of file \"%s\":\n", argv[count] ); test_load_file(to_open, cb, parser, parser_tag, book); } } diff --git a/src/backend/file/test/test-real-data.sh b/src/backend/file/test/test-real-data.sh index de9445c3aa..a5d8c9eaf4 100755 --- a/src/backend/file/test/test-real-data.sh +++ b/src/backend/file/test/test-real-data.sh @@ -15,7 +15,7 @@ for i in $SRCDIR/test-files/xml2/*.gml2 ; do FILES=`perl $SRCDIR/grab-types.pl "gnc:$j" $i "$j/dataXXX.xml"` if [ ! -z "$FILES" ] ; then echo "Testing file `basename $i`, section $j" - + echo "[./test-xml-$j $FILES # from file $i]:" eval "./test-xml-$j $FILES" if [ $? != 0 ] ; then EXIT_VALUE=1 diff --git a/src/backend/file/test/test-xml-transaction.c b/src/backend/file/test/test-xml-transaction.c index ced837e439..1958c831d3 100644 --- a/src/backend/file/test/test-xml-transaction.c +++ b/src/backend/file/test/test-xml-transaction.c @@ -139,6 +139,11 @@ equals_node_val_vs_split_internal(xmlNodePtr node, Split* spl) gnc_numeric *num = dom_tree_to_gnc_numeric(mark); gnc_numeric val = xaccSplitGetAmount(spl); + if ( gnc_numeric_equal(*num, val)) { + return g_strdup_printf( "quantities differ under _equal: %lld/%lld v %lld/%lld", + (*num).num, (*num).denom, + val.num, val.denom ); + } if(!gnc_numeric_eq(*num, val)) { g_free(num); diff --git a/src/engine/SchedXaction.c b/src/engine/SchedXaction.c index 095a270159..adf6d4099c 100644 --- a/src/engine/SchedXaction.c +++ b/src/engine/SchedXaction.c @@ -147,6 +147,7 @@ delete_template_trans(SchedXaction *sx) void xaccSchedXactionFree( SchedXaction *sx ) { + GList *l; if ( sx == NULL ) return; @@ -171,10 +172,19 @@ xaccSchedXactionFree( SchedXaction *sx ) xaccAccountBeginEdit(sx->template_acct); xaccAccountDestroy(sx->template_acct); + + for ( l = sx->deferredList; l; l = l->next ) { + gnc_sx_destroy_temporal_state( l->data ); + l->data = NULL; + } + if ( sx->deferredList ) { + g_list_free( sx->deferredList ); + sx->deferredList = NULL; + } g_free( sx ); - return; + return; } @@ -489,12 +499,16 @@ xaccSchedXactionGetInstanceAfter( SchedXaction *sx, { GDate prev_occur, next_occur; - prev_occur = *date; + g_date_clear( &prev_occur, 1 ); + if ( date ) { + prev_occur = *date; + } if ( stateData != NULL ) { temporalStateData *tsd = (temporalStateData*)stateData; prev_occur = tsd->last_date; } + if ( ! g_date_valid( &prev_occur ) ) { /* We must be at the beginning. */ prev_occur = sx->start_date; @@ -679,6 +693,10 @@ gnc_sx_create_temporal_state( SchedXaction *sx ) temporalStateData *toRet = g_new0( temporalStateData, 1 ); toRet->last_date = sx->last_date; + if ( !g_date_valid( &toRet->last_date ) ) { + toRet->last_date = sx->start_date; + g_date_subtract_days( &toRet->last_date, 1 ); + } toRet->num_occur_rem = sx->num_occurances_remain; toRet->num_inst = sx->instance_num; return (void*)toRet; @@ -690,6 +708,7 @@ gnc_sx_incr_temporal_state( SchedXaction *sx, void *stateData ) GDate unused; temporalStateData *tsd = (temporalStateData*)stateData; + g_date_clear( &unused, 1 ); tsd->last_date = xaccSchedXactionGetInstanceAfter( sx, &unused, diff --git a/src/gnome-utils/Makefile.am b/src/gnome-utils/Makefile.am index a7a305dcc1..f25f22922e 100644 --- a/src/gnome-utils/Makefile.am +++ b/src/gnome-utils/Makefile.am @@ -25,7 +25,6 @@ libgncmod_gnome_utils_la_SOURCES = \ dialog-options.c \ dialog-utils.c \ druid-utils.c \ - gnc-account-sel.c \ gnc-account-tree.c \ gnc-amount-edit.c \ gnc-commodity-edit.c \ @@ -53,7 +52,6 @@ gncinclude_HEADERS = \ dialog-options.h \ dialog-utils.h \ druid-utils.h \ - gnc-account-sel.h \ gnc-account-tree.h \ gnc-amount-edit.h \ gnc-commodity-edit.h \ diff --git a/src/gnome-utils/gnc-account-sel.c b/src/gnome-utils/gnc-account-sel.c deleted file mode 100644 index 58c8ad7b44..0000000000 --- a/src/gnome-utils/gnc-account-sel.c +++ /dev/null @@ -1,301 +0,0 @@ -/** - * gnc-account-sel.c -- combobox style account selection widget, with - * auto-completion. - * - * Copyright (C) 2002 Joshua Sled - * All rights reserved. - * - * Gnucash is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public License - * as published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * Gnucash is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, contact: - * - * Free Software Foundation Voice: +1-617-542-5942 - * 59 Temple Place - Suite 330 Fax: +1-617-542-2652 - * Boston, MA 02111-1307, USA gnu@gnu.org - **/ - -#include "config.h" - -#include "gnc-account-sel.h" -#include "gnc-exp-parser.h" -#include "messages.h" -#include "gnc-ui-util.h" -#include "gnc-engine-util.h" - -#define ACCT_DATA_TAG "gnc-account-sel_acct" - -/* Signal codes */ -enum -{ - ACCOUNT_SEL_CHANGED, - LAST_SIGNAL -}; - -static gint account_sel_signals [LAST_SIGNAL] = { 0 }; - -static void gnc_account_sel_init (GNCAccountSel *gas); -static void gnc_account_sel_class_init (GNCAccountSelClass *class); -static void gas_accounts_to_names( gpointer data, gpointer user_data ); - -#if 0 -static void gnc_account_sel_changed( GtkEditable *entry, gpointer ud ); -static void gnc_account_sel_list_clicked( GtkButton *b, gpointer ud ); -static gint gnc_account_sel_key_press( GtkWidget *widget, - GdkEventKey *event ); -#endif /* 0 */ - -static GtkHBox *parent_class; - -guint -gnc_account_sel_get_type (void) -{ - static guint account_sel_type = 0; - - if (!account_sel_type){ - GtkTypeInfo account_sel_info = { - "GNCAccountSel", - sizeof (GNCAccountSel), - sizeof (GNCAccountSelClass), - (GtkClassInitFunc) gnc_account_sel_class_init, - (GtkObjectInitFunc) gnc_account_sel_init, - NULL, - NULL, - (GtkClassInitFunc) NULL, - }; - - account_sel_type = gtk_type_unique (GTK_TYPE_HBOX, &account_sel_info); - } - - return account_sel_type; -} - -static void -gnc_account_sel_class_init (GNCAccountSelClass *class) -{ - GtkObjectClass *object_class; - GtkWidgetClass *widget_class; - GtkHBoxClass *hbox_class; - - object_class = (GtkObjectClass*) class; - widget_class = (GtkWidgetClass*) class; - hbox_class = (GtkHBoxClass*) class; - - parent_class = gtk_type_class (gtk_entry_get_type ()); - - account_sel_signals [ACCOUNT_SEL_CHANGED] = - gtk_signal_new ("account_sel_changed", - GTK_RUN_FIRST, object_class->type, - GTK_SIGNAL_OFFSET (GNCAccountSelClass, - account_sel_changed), - gtk_signal_default_marshaller, - GTK_TYPE_NONE, 0); - - gtk_object_class_add_signals (object_class, - account_sel_signals, - LAST_SIGNAL); - - class->account_sel_changed = NULL; -} - -typedef struct { - GList **outList; - char accountSep; -} accounts_to_names_data; - -static void -gnc_account_sel_init (GNCAccountSel *gas) -{ - gas->initDone = FALSE; - gas->combo = GTK_COMBO(gtk_combo_new()); - gtk_container_add( GTK_CONTAINER(gas), GTK_WIDGET(gas->combo) ); - - gtk_editable_set_editable( GTK_EDITABLE(gas->combo->entry), FALSE ); -#if 0 - gtk_signal_connect( GTK_OBJECT(gas->combo->entry), "changed", - GTK_SIGNAL_FUNC( gnc_account_sel_changed ), - gas ); -#endif /* 0 */ - - /* Get the accounts, place into combo list and setup GCompletion */ - { - accounts_to_names_data atnd; - AccountGroup *ag; - GList *accts, *nameList; - - ag = gnc_book_get_group( gnc_get_current_book() ); - accts = (GList*)xaccGroupGetSubAccounts( ag ); - nameList = NULL; - atnd.outList = &nameList; - atnd.accountSep = gnc_get_account_separator(); - g_list_foreach( accts, gas_accounts_to_names, - (gpointer)&atnd ); - g_list_free( accts ); - - gtk_combo_set_popdown_strings( gas->combo, nameList ); - - gas->completion = g_completion_new( NULL ); - g_completion_add_items( gas->completion, nameList ); - } - gas->initDone = TRUE; -} - -static -void -gas_accounts_to_names( gpointer data, gpointer user_data ) -{ - accounts_to_names_data *atnd; - Account *a; - - atnd = (accounts_to_names_data*)user_data; - a = (Account*)data; - *atnd->outList = - g_list_append( *atnd->outList, - xaccAccountGetFullName(a, atnd->accountSep) ); -} - -#if 0 /* fscking gtk... */ -/* - * There is apparently no way -- in GTK 1.x -- to programatically select a - * region in the way we would like... so we've disallowed manual editing of - * the Account string. - */ -static -void -gnc_account_sel_changed( GtkEditable *entry, gpointer ud ) -{ - gchar *s, *prefix; - GNCAccountSel *gas = (GNCAccountSel*)ud; - - if ( !gas->initDone ) { - return; - } - s = gtk_editable_get_chars( entry, 0, -1 ); - g_completion_complete( gas->completion, s, &prefix ); - if ( prefix && (strlen(prefix) > 0) ) { - printf( "changed into \"%s\"; longest completion: \"%s\"\n", s, prefix ); - gtk_signal_handler_block_by_func( GTK_OBJECT(gas->combo->entry), - GTK_SIGNAL_FUNC(gnc_account_sel_changed), - ud ); - gtk_entry_set_text( GTK_ENTRY(gas->combo->entry), prefix ); - gtk_editable_select_region( GTK_EDITABLE(gas->combo->entry), - strlen(s), -1 ); - { - GdkEventKey k; - gboolean ret; - - k.type = GDK_KEY_RELEASE; - k.send_event = TRUE; - k.state = GDK_SHIFT_MASK; - k.keyval = GDK_End; - k.length = 0; - k.string = ""; - printf( "foo [%d : \"%s\"]\n", k.length, k.string ); - //gtk_widget_event( GTK_WIDGET(gas->combo->entry), &e ); - gtk_signal_emit_by_name( GTK_OBJECT(gas->combo->entry), - "key-press-event", - gas->combo->entry, &k, NULL, &ret ); - printf( "bar\n" ); - } - gtk_editable_set_position( GTK_EDITABLE(gas->combo->entry), - strlen(s) ); - gtk_signal_handler_unblock_by_func( GTK_OBJECT(gas->combo->entry), - GTK_SIGNAL_FUNC(gnc_account_sel_changed), - ud ); - g_free( prefix ); - } - g_free( s ); -} - -static -gint -gnc_account_sel_key_press(GtkWidget *widget, GdkEventKey *event) -{ - GNCAccountSel *gas = GNC_ACCOUNT_SEL(widget); - gint result; - - result = (* GTK_WIDGET_CLASS (parent_class)->key_press_event)(widget, event); - - switch (event->keyval) - { - case GDK_Tab: - /* FIXME: += equivalent. */ - break; -#if 0 - case GDK_DOWN: - /* dispaly combobox */ - break; -#endif /* 0 */ - case GDK_Return: -#if 0 - if (gae->evaluate_on_enter) - break; -#endif /* 0 */ - if (event->state & (GDK_CONTROL_MASK | GDK_MOD1_MASK | GDK_SHIFT_MASK)) - break; - return result; - case GDK_KP_Enter: - break; - default: - return result; - } - - return TRUE; -} -#endif /* 0 */ - -GtkWidget * -gnc_account_sel_new (void) -{ - GNCAccountSel *gas; - - gas = gtk_type_new (gnc_account_sel_get_type ()); - - return GTK_WIDGET (gas); -} - -GtkWidget * -gnc_account_sel_gtk_entry (GNCAccountSel *gas) -{ - g_return_val_if_fail(gas != NULL, NULL); - g_return_val_if_fail(GNC_IS_ACCOUNT_SEL(gas), NULL); - - return (GtkWidget *)gas->combo->entry; -} - -void -gnc_account_sel_set_account( GNCAccountSel *gas, Account *acct ) -{ - gchar *acctStr; - - if ( acct == NULL ) { - gtk_list_select_item( GTK_LIST(gas->combo->list), 0 ); - return; - } - acctStr = xaccAccountGetFullName( acct, - gnc_get_account_separator() ); - gtk_entry_set_text( GTK_ENTRY(gas->combo->entry), acctStr ); - g_free( acctStr ); -} - -Account* -gnc_account_sel_get_account( GNCAccountSel *gas ) -{ - AccountGroup *ag; - Account *ret; - gchar *txt; - - txt = gtk_editable_get_chars( GTK_EDITABLE(gas->combo->entry), 0, -1 ); - ag = gnc_book_get_group( gnc_get_current_book() ); - ret = xaccGetAccountFromFullName( ag, txt, gnc_get_account_separator() ); - g_free( txt ); - return ret; -} diff --git a/src/gnome/Makefile.am b/src/gnome/Makefile.am index 429ce3f6b7..02888e61e0 100644 --- a/src/gnome/Makefile.am +++ b/src/gnome/Makefile.am @@ -43,6 +43,7 @@ libgncgnome_la_SOURCES = \ druid-hierarchy.c \ druid-loan.c \ druid-stock-split.c \ + gnc-account-sel.c \ gnc-network.c \ gnc-splash.c \ mainwindow-account-tree.c \ @@ -79,6 +80,7 @@ noinst_HEADERS = \ dialog-scheduledxaction.h \ druid-hierarchy.h \ druid-loan.h \ + gnc-account-sel.h \ gnc-network.h \ gnc-splash.h \ gw-gnc.h \ diff --git a/src/gnome/dialog-sxsincelast.c b/src/gnome/dialog-sxsincelast.c index 8ac108c977..077710332c 100644 --- a/src/gnome/dialog-sxsincelast.c +++ b/src/gnome/dialog-sxsincelast.c @@ -1092,6 +1092,13 @@ sxsld_process_to_create_instance( sxSinceLastData *sxsld, break; } /* add to the postponed list. */ + { + char tmpBuf[50]; + g_date_strftime( tmpBuf, 49, "%c", tci->date ); + DEBUG( "Adding defer instance on %s for %s", + tmpBuf, + xaccSchedXactionGetName( tci->parentTCT->sx ) ); + } gnc_sx_add_defer_instance( tci->parentTCT->sx, tci->sxStateData ); break; case TO_CREATE: @@ -1128,11 +1135,18 @@ sxsld_process_to_create_instance( sxSinceLastData *sxsld, return; } xaccSchedXactionSetLastOccurDate( sx, tci->date ); - tmp = gnc_sx_get_instance_count( sx, NULL ); - gnc_sx_set_instance_count( sx, tmp+1 ); - if ( xaccSchedXactionHasOccurDef( sx ) ) { - tmp = xaccSchedXactionGetRemOccur(sx); - xaccSchedXactionSetRemOccur( sx, tmp-1 ); + + /* Handle an interesting corner case of postponing or + * ignoring the first instance. We only want to incrment the + * counters for newly-discovered-as-to-be-created SXes. + */ + if ( tci->origState == UNDEF ) { + tmp = gnc_sx_get_instance_count( sx, NULL ); + gnc_sx_set_instance_count( sx, tmp+1 ); + if ( xaccSchedXactionHasOccurDef( sx ) ) { + tmp = xaccSchedXactionGetRemOccur(sx); + xaccSchedXactionSetRemOccur( sx, tmp-1 ); + } } } } @@ -1288,6 +1302,8 @@ cancel_check( GnomeDruidPage *druid_page, "Are you sure you want to lose all " "Scheduled Transaction changes?" ); + /* FIXME: This may now be a bug, as we might have changed the SX + * states. */ if ( g_list_length( sxsld->createdTxnGUIDList ) == 0 ) { /* There's nothing to cancel, so just do so... */ return FALSE; @@ -1347,7 +1363,7 @@ cancel_check( GnomeDruidPage *druid_page, tciList = tciList->next ) { tci = (toCreateInstance*)tciList->data; if ( tci->prevState == POSTPONE - && tci->origState != POSTPONE ) { + && tci->origState != POSTPONE ) { /* Any valid [non-null] 'prevState != * POSTPONE' sx temporal state * pointers will be destroyed at the @@ -1540,6 +1556,8 @@ generate_instances( SchedXaction *sx, g_assert( g_date_valid(end) ); g_assert( g_date_valid(reminderEnd) ); + g_date_clear( &gd, 1 ); + /* Process valid next instances. */ seqStateData = gnc_sx_create_temporal_state( sx ); //gd = xaccSchedXactionGetNextInstance( sx, seqStateData ); @@ -1961,7 +1979,6 @@ sxsincelast_populate( sxSinceLastData *sxsld ) GList *sxList, *instanceList, *l, **containingList; SchedXaction *sx; - void *sx_state; GDate end, endPlusReminders; gint daysInAdvance; gboolean autocreateState, notifyState; @@ -1991,9 +2008,13 @@ sxsincelast_populate( sxSinceLastData *sxsld ) "the first time?" ); return FALSE; } - sx_state = gnc_sx_create_temporal_state( sx ); - g_hash_table_insert( sxsld->sxInitStates, - sx, sx_state ); + { + void *sx_state; + sx_state = gnc_sx_create_temporal_state( sx ); + g_hash_table_insert( sxsld->sxInitStates, + sx, sx_state ); + sx_state = NULL; + } g_date_set_time( &end, time(NULL) ); daysInAdvance = xaccSchedXactionGetAdvanceCreation( sx ); @@ -3474,21 +3495,22 @@ gnc_sxsld_free_tci( toCreateInstance *tci ) * but here's the rules... * * If we're not cancelling... - * . If ignored, then destroy. - * . If postponed, then don't. + * . If ignored, destroy. + * . If postponed, DON'T destroy. * . If to-create, destroy. * - * If we are cancelling.... + * If we are cancelling... * . If ignored, destroy. * . If postponed, destroy. + * . UNLESS previously postponed * . If to-create, destroy. * * So, we don't destroy postponed by default, and let the * cancel-specific case handle that destruction [thus the * valid-pointer check]. */ - if ( tci->prevState != POSTPONE - && tci->origState != POSTPONE + if ( tci->prevState != POSTPONE + && tci->origState != POSTPONE && tci->sxStateData != NULL ) { gnc_sx_destroy_temporal_state( tci->sxStateData ); tci->sxStateData = NULL; diff --git a/src/gnome/druid-loan.c b/src/gnome/druid-loan.c index 3123347e3e..4369b89d94 100644 --- a/src/gnome/druid-loan.c +++ b/src/gnome/druid-loan.c @@ -334,6 +334,7 @@ gnc_ui_sx_loan_druid_create() a = GTK_ALIGNMENT(gtk_alignment_new( 0.0, 0.5, 0.25, 1.0 )); gas = GNC_ACCOUNT_SEL(gnc_account_sel_new()); + gnc_account_sel_set_new_account_ability( gas, TRUE ); gtk_container_add( GTK_CONTAINER(a), GTK_WIDGET(gas) ); gtk_table_attach( gas_data[i].table, @@ -402,6 +403,7 @@ gnc_ui_sx_loan_druid_create() GTK_SIGNAL_FUNC(ld_escrow_toggle), ldd ); gtk_widget_set_sensitive( GTK_WIDGET(ldd->optEscrowHBox), FALSE ); ldd->optEscrowGAS = GNC_ACCOUNT_SEL(gnc_account_sel_new()); + gnc_account_sel_set_new_account_ability( ldd->optEscrowGAS, TRUE ); gtk_container_add( GTK_CONTAINER(ldd->optEscrowHBox), GTK_WIDGET(ldd->optEscrowGAS) ); @@ -820,6 +822,12 @@ ld_info_save( GnomeDruidPage *gdp, gpointer arg1, gpointer ud ) ldd = (LoanDruidData*)ud; ldd->ld.primaryAcct = gnc_account_sel_get_account( ldd->prmAccountGAS ); + if ( ldd->ld.primaryAcct == NULL ) { + gnc_info_dialog_parented( GTK_WINDOW(ldd->dialog), + "Please select a valid " + "loan account." ); + return TRUE; + } if ( ! ldd->ld.repPriAcct ) { ldd->ld.repPriAcct = ldd->ld.primaryAcct; } @@ -896,23 +904,30 @@ ld_info_prep( GnomeDruidPage *gdp, gpointer arg1, gpointer ud ) } static -void +gboolean ld_opts_save_state( LoanDruidData *ldd ) { if ( gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(ldd->optEscrowCb) ) ) { ldd->ld.escrowAcct = gnc_account_sel_get_account( ldd->optEscrowGAS ); + if ( ldd->ld.escrowAcct == NULL ) { + gnc_info_dialog_parented( GTK_WINDOW(ldd->dialog), + "Please select a valid " + "Escrow Account" ); + return TRUE; + } + } else { ldd->ld.escrowAcct = NULL; } + return FALSE; } static gboolean ld_opts_tran( GnomeDruidPage *gdp, gpointer arg1, gpointer ud ) { - ld_opts_save_state( (LoanDruidData*)ud ); - return FALSE; + return ld_opts_save_state( (LoanDruidData*)ud ); } static @@ -944,7 +959,7 @@ ld_opts_prep( GnomeDruidPage *gdp, gpointer arg1, gpointer ud ) } static -void +gboolean ld_rep_save( LoanDruidData *ldd ) { int i; @@ -961,10 +976,28 @@ ld_rep_save( LoanDruidData *ldd ) ldd->ld.repFromAcct = gnc_account_sel_get_account( ldd->repAssetsFromGAS ); + if ( ldd->ld.repFromAcct == NULL ) { + gnc_info_dialog_parented( GTK_WINDOW(ldd->dialog), + "Please select a valid " + "\"from\" account." ); + return TRUE; + } ldd->ld.repPriAcct = gnc_account_sel_get_account( ldd->repPrincToGAS ); + if ( ldd->ld.repPriAcct == NULL ) { + gnc_info_dialog_parented( GTK_WINDOW(ldd->dialog), + "Please select a valid " + "\"to\" account." ); + return TRUE; + } ldd->ld.repIntAcct = gnc_account_sel_get_account( ldd->repIntToGAS ); + if ( ldd->ld.repIntAcct == NULL ) { + gnc_info_dialog_parented( GTK_WINDOW(ldd->dialog), + "Please select a valid " + "\"interest\" account." ); + return TRUE; + } ldd->ld.remainderChoice = gnc_option_menu_get_active( GTK_WIDGET(ldd->repRemainderOpt) ); gnc_frequency_save_state( ldd->repGncFreq, @@ -979,6 +1012,7 @@ ld_rep_save( LoanDruidData *ldd ) rod->from = ldd->ld.repFromAcct; } } + return FALSE; } static @@ -989,7 +1023,9 @@ ld_rep_next( GnomeDruidPage *gdp, gpointer arg1, gpointer ud ) ldd = (LoanDruidData*)ud; - ld_rep_save( ldd ); + if ( ld_rep_save( ldd ) != FALSE ) { + return TRUE; + } if ( (ldd->currentIdx < 0) || (ldd->currentIdx >= ldd->ld.repayOptCount) @@ -1019,8 +1055,7 @@ ld_rep_back( GnomeDruidPage *gdp, gpointer arg1, gpointer ud ) LoanDruidData *ldd; ldd = (LoanDruidData*)ud; - ld_rep_save(ldd); - return FALSE; + return ld_rep_save(ldd); } static @@ -1107,7 +1142,7 @@ ld_pay_prep( GnomeDruidPage *gdp, gpointer arg1, gpointer ud ) } static -void +gboolean ld_pay_save_current( LoanDruidData *ldd ) { gchar *tmpStr; @@ -1131,7 +1166,19 @@ ld_pay_save_current( LoanDruidData *ldd ) g_free( tmpStr ); rod->from = gnc_account_sel_get_account( ldd->payAcctFromGAS ); + if ( rod->from == NULL ) { + gnc_info_dialog_parented( GTK_WINDOW(ldd->dialog), + "Please select a valid " + "\"from\" account." ); + return TRUE; + } rod->to = gnc_account_sel_get_account( ldd->payAcctToGAS ); + if ( rod->from == NULL ) { + gnc_info_dialog_parented( GTK_WINDOW(ldd->dialog), + "Please select a valid " + "\"to\" account." ); + return TRUE; + } /* if ( rb toggled ) * ensure freqspec/startdate setup @@ -1164,6 +1211,7 @@ ld_pay_save_current( LoanDruidData *ldd ) rod->startDate = NULL; } } + return FALSE; } static @@ -1175,7 +1223,9 @@ ld_pay_next( GnomeDruidPage *gdp, gpointer arg1, gpointer ud ) ldd = (LoanDruidData*)ud; /* save current data */ - ld_pay_save_current( ldd ); + if ( ld_pay_save_current( ldd ) != FALSE ) { + return TRUE; + } /* Go through opts list and select next enabled option. */ for ( i=(++ldd->currentIdx); @@ -1200,7 +1250,9 @@ ld_pay_back( GnomeDruidPage *gdp, gpointer arg1, gpointer ud ) ldd = (LoanDruidData*)ud; /* save current data */ - ld_pay_save_current( ldd ); + if ( ld_pay_save_current( ldd ) != FALSE ) { + return TRUE; + } for ( i=(--ldd->currentIdx); (i > -1) && !ldd->ld.repayOpts[i]->enabled; diff --git a/src/gnome/glade/sched-xact.glade b/src/gnome/glade/sched-xact.glade index 799b02b5ed..2042b449d2 100644 --- a/src/gnome/glade/sched-xact.glade +++ b/src/gnome/glade/sched-xact.glade @@ -5565,60 +5565,4 @@ Escrow - - GtkMenu - Since Last Run popup - - - GtkMenuItem - creation_state - - False - - - GtkMenu - creation_state_menu - - - GtkPixmapMenuItem - ignore - - activate - on_ignore_activate - Fri, 23 Aug 2002 22:16:45 GMT - - - False - GNOME_STOCK_MENU_STOP - - - - GtkPixmapMenuItem - postpone - - activate - on_postpone_activate - Fri, 23 Aug 2002 22:16:45 GMT - - - False - GNOME_STOCK_MENU_TIMER_STOP - - - - GtkPixmapMenuItem - create - - activate - on_create_activate - Fri, 23 Aug 2002 22:16:45 GMT - - - False - GNOME_STOCK_MENU_TIMER - - - - - diff --git a/src/gnome/gnc-account-sel.c b/src/gnome/gnc-account-sel.c new file mode 100644 index 0000000000..7c9b4d95dd --- /dev/null +++ b/src/gnome/gnc-account-sel.c @@ -0,0 +1,477 @@ +/** + * gnc-account-sel.c -- combobox style account selection widget + * + * Copyright (C) 2002 Joshua Sled + * All rights reserved. + * + * Gnucash is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public License + * as published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * Gnucash is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, contact: + * + * Free Software Foundation Voice: +1-617-542-5942 + * 59 Temple Place - Suite 330 Fax: +1-617-542-2652 + * Boston, MA 02111-1307, USA gnu@gnu.org + **/ + +#include "config.h" + +#include "AccWindow.h" +#include "gnc-account-sel.h" +#include "gnc-exp-parser.h" +#include "messages.h" +#include "gnc-ui-util.h" +#include "gnc-engine-util.h" +#include "gnc-event.h" + +#define ACCT_DATA_TAG "gnc-account-sel_acct" + +/* Signal codes */ +enum +{ + ACCOUNT_SEL_CHANGED, + LAST_SIGNAL +}; + +static gint account_sel_signals [LAST_SIGNAL] = { 0 }; + +static void gnc_account_sel_init (GNCAccountSel *gas); +static void gnc_account_sel_class_init (GNCAccountSelClass *class); +static void gas_accounts_to_names( gpointer data, gpointer user_data ); + +static void gas_populate_list( GNCAccountSel *gas ); +static void gas_strcmp_adapter( gpointer a, gpointer b ); +static void gnc_account_sel_event_cb( GUID *entity, + GNCEngineEventType event_type, + gpointer user_data ); + +static void gas_new_account_click( GtkButton *b, gpointer ud ); + +static void gas_destroy( GtkObject *o, gpointer user_data ); + +#if 0 /* completion not implemented */ +static void gnc_account_sel_changed( GtkEditable *entry, gpointer ud ); +static void gnc_account_sel_list_clicked( GtkButton *b, gpointer ud ); +static gint gnc_account_sel_key_press( GtkWidget *widget, + GdkEventKey *event ); +#endif /* 0 -- completion not implemented */ + +static GtkHBox *parent_class; + +guint +gnc_account_sel_get_type (void) +{ + static guint account_sel_type = 0; + + if (!account_sel_type){ + GtkTypeInfo account_sel_info = { + "GNCAccountSel", + sizeof (GNCAccountSel), + sizeof (GNCAccountSelClass), + (GtkClassInitFunc) gnc_account_sel_class_init, + (GtkObjectInitFunc) gnc_account_sel_init, + NULL, + NULL, + (GtkClassInitFunc) NULL, + }; + + account_sel_type = gtk_type_unique (GTK_TYPE_HBOX, &account_sel_info); + } + + return account_sel_type; +} + +static +void +gnc_account_sel_event_cb( GUID *entity, + GNCEngineEventType event_type, + gpointer user_data ) +{ + if ( ! ( event_type == GNC_EVENT_CREATE + || event_type == GNC_EVENT_MODIFY + || event_type == GNC_EVENT_DESTROY ) + || strcmp( xaccGUIDType( entity, + gnc_get_current_book() ), + GNC_ID_ACCOUNT ) != 0 ) { + return; + } + gas_populate_list( (GNCAccountSel*)user_data ); +} + +static +void +gnc_account_sel_class_init (GNCAccountSelClass *class) +{ + GtkObjectClass *object_class; + GtkWidgetClass *widget_class; + GtkHBoxClass *hbox_class; + + object_class = (GtkObjectClass*) class; + widget_class = (GtkWidgetClass*) class; + hbox_class = (GtkHBoxClass*) class; + + parent_class = gtk_type_class (gtk_entry_get_type ()); + + account_sel_signals [ACCOUNT_SEL_CHANGED] = + gtk_signal_new ("account_sel_changed", + GTK_RUN_FIRST, object_class->type, + GTK_SIGNAL_OFFSET (GNCAccountSelClass, + account_sel_changed), + gtk_signal_default_marshaller, + GTK_TYPE_NONE, 0); + + gtk_object_class_add_signals (object_class, + account_sel_signals, + LAST_SIGNAL); + + class->account_sel_changed = NULL; +} + +static void +gnc_account_sel_init (GNCAccountSel *gas) +{ + gas->initDone = FALSE; + gas->acctTypeFilters = FALSE; + gas->newAccountButton = NULL; + + gas->combo = GTK_COMBO(gtk_combo_new()); + gtk_combo_set_value_in_list( gas->combo, TRUE, TRUE ); + gtk_container_add( GTK_CONTAINER(gas), GTK_WIDGET(gas->combo) ); + + /* This is only because completion cannot be implemented. */ + gtk_editable_set_editable( GTK_EDITABLE(gas->combo->entry), FALSE ); + gtk_signal_connect( GTK_OBJECT(gas), "destroy", + GTK_SIGNAL_FUNC( gas_destroy ), + gas ); + + +#if 0 /* completion not implemented. */ + gtk_signal_connect( GTK_OBJECT(gas->combo->entry), "changed", + GTK_SIGNAL_FUNC( gnc_account_sel_changed ), + gas ); +#endif /* 0 -- completion not implemented. */ + + + /* Get the accounts, place into combo list */ + gas_populate_list( gas ); + + gas->eventHandlerId = + gnc_engine_register_event_handler( gnc_account_sel_event_cb, gas ); + + gas->initDone = TRUE; +} + +typedef struct { + GNCAccountSel *gas; + GList **outList; + char accountSep; +} accounts_to_names_data; + +/** + * Used in the g_list_foreach call in gas_populate_list to see if the given + * string is in [via strcmp] the list, and to set the flag as necessary. + **/ +typedef struct { + char *str; + gboolean flag; +} findData; + +static +void +gas_strcmp_adapter( gpointer listElt, gpointer ud ) +{ + findData *fd = (findData*)ud; + fd->flag |= ( strcmp( (char*)listElt, (char*)fd->str ) == 0 ); +} + +static +void +gas_populate_list( GNCAccountSel *gas ) +{ + accounts_to_names_data atnd; + AccountGroup *ag; + GList *accts, *nameList; + gchar *currentSel; + + currentSel = gtk_editable_get_chars( + GTK_EDITABLE(gas->combo->entry), 0, -1 ); + + ag = gnc_book_get_group( gnc_get_current_book() ); + accts = (GList*)xaccGroupGetSubAccounts( ag ); + + nameList = NULL; + atnd.gas = gas; + atnd.outList = &nameList; + atnd.accountSep = gnc_get_account_separator(); + + g_list_foreach( accts, gas_accounts_to_names, + (gpointer)&atnd ); + g_list_free( accts ); + + if ( g_list_length( nameList ) > 0 ) { + gtk_combo_set_popdown_strings( gas->combo, nameList ); + } + + /* If the account which was in the text box before still exists, then + * reset to it. */ + { + findData tmpfd; + gint pos; + tmpfd.str = currentSel; + tmpfd.flag = FALSE; + + g_list_foreach( nameList, gas_strcmp_adapter, &tmpfd ); + + if ( tmpfd.flag ) { + gtk_editable_delete_text( + GTK_EDITABLE(gas->combo->entry), 0, -1 ); + pos = 0; + gtk_editable_insert_text( + GTK_EDITABLE(gas->combo->entry), + currentSel, strlen(currentSel), &pos ); + } + } + g_list_free( nameList ); + if ( currentSel ) { + g_free( currentSel ); + } + +#if 0 /* completion not implemented */ + gas->completion = g_completion_new( NULL ); + g_completion_add_items( gas->completion, nameList ); +#endif /* 0 -- completion not implemented */ +} + +static +void +gas_accounts_to_names( gpointer data, gpointer user_data ) +{ + accounts_to_names_data *atnd; + Account *a; + + atnd = (accounts_to_names_data*)user_data; + a = (Account*)data; + /* Filter as we've been configured to do. */ + if ( atnd->gas->acctTypeFilters ) { + /* g_list_find is the poor-mans '(member ...)', especially + * easy when the data pointers in the list are just casted + * account type identifiers. */ + if ( g_list_find( atnd->gas->acctTypeFilters, + GINT_TO_POINTER(xaccAccountGetType( a )) ) + == NULL ) { + return; + } + } + *atnd->outList = + g_list_append( *atnd->outList, + xaccAccountGetFullName(a, atnd->accountSep) ); +} + +#if 0 /* completion not implemented */ +/* + * There is apparently no way -- in GTK 1.x -- to programatically select a + * region in the way we would like... so we've disallowed manual editing of + * the Account string. + */ +static +void +gnc_account_sel_changed( GtkEditable *entry, gpointer ud ) +{ + gchar *s, *prefix; + GNCAccountSel *gas = (GNCAccountSel*)ud; + + if ( !gas->initDone ) { + return; + } + s = gtk_editable_get_chars( entry, 0, -1 ); + g_completion_complete( gas->completion, s, &prefix ); + if ( prefix && (strlen(prefix) > 0) ) { + printf( "changed into \"%s\"; longest completion: \"%s\"\n", s, prefix ); + gtk_signal_handler_block_by_func( GTK_OBJECT(gas->combo->entry), + GTK_SIGNAL_FUNC(gnc_account_sel_changed), + ud ); + gtk_entry_set_text( GTK_ENTRY(gas->combo->entry), prefix ); + gtk_editable_select_region( GTK_EDITABLE(gas->combo->entry), + strlen(s), -1 ); + { + GdkEventKey k; + gboolean ret; + + k.type = GDK_KEY_RELEASE; + k.send_event = TRUE; + k.state = GDK_SHIFT_MASK; + k.keyval = GDK_End; + k.length = 0; + k.string = ""; + printf( "foo [%d : \"%s\"]\n", k.length, k.string ); + //gtk_widget_event( GTK_WIDGET(gas->combo->entry), &e ); + gtk_signal_emit_by_name( GTK_OBJECT(gas->combo->entry), + "key-press-event", + gas->combo->entry, &k, NULL, &ret ); + printf( "bar\n" ); + } + gtk_editable_set_position( GTK_EDITABLE(gas->combo->entry), + strlen(s) ); + gtk_signal_handler_unblock_by_func( GTK_OBJECT(gas->combo->entry), + GTK_SIGNAL_FUNC(gnc_account_sel_changed), + ud ); + g_free( prefix ); + } + g_free( s ); +} + +static +gint +gnc_account_sel_key_press(GtkWidget *widget, GdkEventKey *event) +{ + GNCAccountSel *gas = GNC_ACCOUNT_SEL(widget); + gint result; + + result = (* GTK_WIDGET_CLASS (parent_class)->key_press_event)(widget, event); + + switch (event->keyval) + { + case GDK_Tab: + /* FIXME: += equivalent keys. */ + break; + if (event->state & (GDK_CONTROL_MASK | GDK_MOD1_MASK | GDK_SHIFT_MASK)) + break; + return result; + case GDK_KP_Enter: + break; + default: + return result; + } + + return TRUE; +} +#endif /* 0 -- completion not implemented */ + +GtkWidget * +gnc_account_sel_new (void) +{ + GNCAccountSel *gas; + + gas = gtk_type_new (gnc_account_sel_get_type ()); + + return GTK_WIDGET (gas); +} + +GtkWidget * +gnc_account_sel_gtk_entry (GNCAccountSel *gas) +{ + g_return_val_if_fail(gas != NULL, NULL); + g_return_val_if_fail(GNC_IS_ACCOUNT_SEL(gas), NULL); + + return (GtkWidget *)gas->combo->entry; +} + +void +gnc_account_sel_set_account( GNCAccountSel *gas, Account *acct ) +{ + gchar *acctStr; + + if ( acct == NULL ) { + gtk_list_select_item( GTK_LIST(gas->combo->list), 0 ); + return; + } + acctStr = xaccAccountGetFullName( acct, + gnc_get_account_separator() ); + gtk_entry_set_text( GTK_ENTRY(gas->combo->entry), acctStr ); + g_free( acctStr ); +} + +Account* +gnc_account_sel_get_account( GNCAccountSel *gas ) +{ + AccountGroup *ag; + Account *ret; + gchar *txt; + + ret = NULL; + txt = gtk_editable_get_chars( GTK_EDITABLE(gas->combo->entry), 0, -1 ); + g_assert( txt != NULL ); + if ( strlen(txt) == 0 ) { + goto cleanup; + } + ag = gnc_book_get_group( gnc_get_current_book() ); + ret = xaccGetAccountFromFullName( ag, txt, gnc_get_account_separator() ); + cleanup: + g_free( txt ); + return ret; +} + + +void +gnc_account_sel_set_acct_filters( GNCAccountSel *gas, GList *filters ) +{ + if ( gas->acctTypeFilters != NULL ) { + g_list_free( gas->acctTypeFilters ); + gas->acctTypeFilters = NULL; + } + /* If it's null, then no filters exist. */ + if ( ! filters ) { + return; + } + /* This works because the GNCAccountTypes in the list are + * ints-casted-as-pointers. */ + gas->acctTypeFilters = g_list_copy( filters ); + gas_populate_list( gas ); +} + +static +void +gas_destroy( GtkObject *o, gpointer user_data ) +{ + GNCAccountSel *gas = (GNCAccountSel*)user_data; + if ( gas->acctTypeFilters ) { + g_list_free( gas->acctTypeFilters ); + } + gnc_engine_unregister_event_handler( gas->eventHandlerId ); +} + +void +gnc_account_sel_set_new_account_ability( GNCAccountSel *gas, + gboolean state ) +{ + g_assert( gas ); + if ( state == (gas->newAccountButton != NULL) ) { + /* We're already in that state; don't do anything. */ + return; + } + + if ( gas->newAccountButton ) { + g_assert( state == TRUE ); + /* destroy the existing button. */ + gtk_container_remove( GTK_CONTAINER(gas), + gas->newAccountButton ); + gtk_widget_destroy( gas->newAccountButton ); + gas->newAccountButton = NULL; + return; + } + + /* create the button. */ + gas->newAccountButton = gtk_button_new_with_label( _("New...") ); + gtk_signal_connect( GTK_OBJECT(gas->newAccountButton), + "clicked", + GTK_SIGNAL_FUNC( gas_new_account_click ), + gas ); + gtk_box_pack_start( GTK_BOX(gas), gas->newAccountButton, + FALSE, FALSE, 2 ); +} + +static +void +gas_new_account_click( GtkButton *b, gpointer ud ) +{ + GNCAccountSel *gas = (GNCAccountSel*)ud; + gnc_ui_new_account_with_types( NULL, gas->acctTypeFilters ); +} diff --git a/src/gnome-utils/gnc-account-sel.h b/src/gnome/gnc-account-sel.h similarity index 57% rename from src/gnome-utils/gnc-account-sel.h rename to src/gnome/gnc-account-sel.h index 3f945697cf..a1a99261f9 100644 --- a/src/gnome-utils/gnc-account-sel.h +++ b/src/gnome/gnc-account-sel.h @@ -1,11 +1,15 @@ /** - * gnc-account-sel.h -- combobox style account selection widget, with - * auto-completion. + * gnc-account-sel.h -- combobox style account selection widget. + * + * Note that this widget will track changes in the account tree, and update + * itself accordingly. If an account with the same name exists in the + * freshly-retreived account list, the widget will re-select that account. * * Copyright (C) 2002 Joshua Sled * All rights reserved. - * - * GnuCash is free software; you can redistribute it and/or modify + **/ + +/* GnuCash is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. @@ -21,7 +25,7 @@ * Free Software Foundation Voice: +1-617-542-5942 * 59 Temple Place - Suite 330 Fax: +1-617-542-2652 * Boston, MA 02111-1307, USA gnu@gnu.org - **/ + */ #ifndef GNC_ACCOUNT_SEL_H #define GNC_ACCOUNT_SEL_H @@ -37,18 +41,26 @@ BEGIN_GNOME_DECLS typedef struct { - GtkHBox hbox; - gboolean initDone; - GtkCombo *combo; - GCompletion *completion; + GtkHBox hbox; + gboolean initDone; + GtkCombo *combo; + GList *acctTypeFilters; + gint eventHandlerId; + /* The state of this pointer also serves as a flag about what state + * the widget is in WRT the new-account-button ability. */ + GtkWidget *newAccountButton; + +#if 0 /* completion not implemented. */ + GCompletion *completion; +#endif /* 0 - completion not implemented */ } GNCAccountSel; typedef struct { - GtkHBoxClass parent_class; + GtkHBoxClass parent_class; - /* Signals for notification/filtering of changes */ - void (*account_sel_changed) (GNCAccountSel *gas); + /* Signals for notification/filtering of changes */ + void (*account_sel_changed) (GNCAccountSel *gas); } GNCAccountSelClass; guint gnc_account_sel_get_type(void); @@ -66,6 +78,21 @@ void gnc_account_sel_set_account( GNCAccountSel *gas, Account *acct ); **/ Account* gnc_account_sel_get_account( GNCAccountSel *gas ); +/** + * The GNCAccountSel can be setup to filter the accounts displayed. + * @param filters A GList of GNCAccountType identifiers which are allowed. + * The list is copied, of course. + **/ +void gnc_account_sel_set_acct_filters( GNCAccountSel *gas, GList *filters ); + +/** + * Conditional inclusion of a new-account button to the right of the + * combobox. + * @param state TRUE if the new-account button is desired, FALSE otherwise. + **/ +void gnc_account_sel_set_new_account_ability( GNCAccountSel *gas, + gboolean state ); + END_GNOME_DECLS #endif /* !ndef GNC_ACCOUNT_SEL_H */ diff --git a/src/gnome/window-main.c b/src/gnome/window-main.c index 1912bc51e7..bb18c12c55 100644 --- a/src/gnome/window-main.c +++ b/src/gnome/window-main.c @@ -852,7 +852,7 @@ gnc_main_window_create_menus(GNCMDIInfo * maininfo) static GnomeUIInfo gnc_sched_xaction_tools_submenu_template[] = { { GNOME_APP_UI_ITEM, - N_("_List and Editor"), + N_("_Scheduled Transaction Editor"), N_("The list of Scheduled Transactions"), gnc_main_window_sched_xaction_cb, NULL, NULL, GNOME_APP_PIXMAP_NONE, NULL,