From bdce11e0162782a0aaae92a2247f75de983e32b6 Mon Sep 17 00:00:00 2001 From: Joshua Sled Date: Mon, 1 Oct 2001 03:25:26 +0000 Subject: [PATCH] 2001-09-30 Josh Sled * src/gnome/dialog-sxsincelast.c: Displays auto-created-and-notification-requested scheduled transactions in a GL rather than a clist. * src/register/ledger-core/split-register-model.c (gnc_template_register_model_new): Added date-cell entry/io-flags handler for template register, making date cell inactive, and stating "Scheduled" instead of a date. * src/gnome/dialog-sxsincelast.c (_create_transactions_on): Now does appropriate cleanup in the case it needs to create a temporary toCreateTuple for transaction-creation. (_create_each_transaction_helper): Cleanup failed transaction-creation appropriately. Support for returning a list of the GUIDs of created transactions. git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@5445 57a11ea4-9604-0410-9ed3-97b8803252fd --- ChangeLog | 18 ++ src/doc/TODO-schedxactions | 15 +- src/gnome/dialog-sxsincelast.c | 204 +++++++++++++++--- src/gnome/glade/sched-xact.glade | 81 +++---- .../ledger-core/split-register-layout.c | 2 + .../ledger-core/split-register-model.c | 26 +++ src/register/register-core/register-common.h | 1 + 7 files changed, 253 insertions(+), 94 deletions(-) diff --git a/ChangeLog b/ChangeLog index dbfcfeeb56..1a96068394 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,21 @@ +2001-09-30 Josh Sled + + * src/gnome/dialog-sxsincelast.c: Displays + auto-created-and-notification-requested scheduled transactions in + a GL rather than a clist. + + * src/register/ledger-core/split-register-model.c + (gnc_template_register_model_new): Added date-cell entry/io-flags + handler for template register, making date cell inactive, and + stating "Scheduled" instead of a date. + + * src/gnome/dialog-sxsincelast.c (_create_transactions_on): Now + does appropriate cleanup in the case it needs to create a + temporary toCreateTuple for transaction-creation. + (_create_each_transaction_helper): Cleanup failed + transaction-creation appropriately. Support for returning a list + of the GUIDs of created transactions. + 2001-09-28 Robert Graham Merkel * src/app-utils/date-utilities.scm ((gnc:deltasym-to-delta)): new function diff --git a/src/doc/TODO-schedxactions b/src/doc/TODO-schedxactions index cdc95fca10..02fcdf3e49 100644 --- a/src/doc/TODO-schedxactions +++ b/src/doc/TODO-schedxactions @@ -48,9 +48,9 @@ X create a template register X need variable fill-in UI... X re-use gnome-sheet code for a variable-binding table? -- ended up using GtkTable [for now?] - . need way to expire/purge scheduled transactions which have no chance of + X need way to expire/purge scheduled transactions which have no chance of being created [outside their end date; once-scheduled and past]. - . infrequent enough that a dialog should suffice. + X infrequent enough that a dialog should suffice. X need 'reminders' of upcoming scheduled transactions during since-last-run X Is it sufficient to look at the next instance of ea. transaction only? I think not... we probably want to look out until the transaction is @@ -73,10 +73,13 @@ X create a template register . to note which are "recurring" . the mozilla "reload" glyph is kinda neat... . Differently-colored "not-yet-created" entries for a configurable - window. + time window. . Context menus/sensitive toolbar button/menu item for creation of not-yet-created transactions. . The ability to turn a non-recurring transaction into a recurring one... + . inactive cells + . date + . recn . deal better with formulas in template transactions [real FormulaCell] . recognize purely numeric template transactions and balance at @@ -155,15 +158,17 @@ X create a template register . Scheduled Transaction Editor . Can't click-out of the register . auto-shrink on window create [the register is too wide, leading to too - much whitespace on the two top panels] + much whitespace on the two top panels -- sometimes]. . Size/space issues. . Un-selecting "End Date" leaves calendar widget sensitive . 'ESC' while editing template register causes window to go away [badly]. + . why does the accounts tab go crazy when we change the FreqSpec parameters? . Scheduled Transaction List . Since-last-run - . always goes one date past the instantiation date. + . any [horizontal] window size change height-grows the top/auto-create GL. + X always goes one date past the instantiation date. . tab-order on variable-entry window isn't always correct. X credit and debit seem reversed at instantiation time... . this is fixed, but is the fix correct? diff --git a/src/gnome/dialog-sxsincelast.c b/src/gnome/dialog-sxsincelast.c index 744fb56882..8e8c1e7d87 100644 --- a/src/gnome/dialog-sxsincelast.c +++ b/src/gnome/dialog-sxsincelast.c @@ -26,6 +26,7 @@ #include #include "Group.h" +#include "Query.h" #include "SchedXaction.h" #include "Transaction.h" #include "dialog-utils.h" @@ -38,6 +39,8 @@ #include "gnc-ui-util.h" #include "gnc-ui.h" #include "split-register.h" +#include "gnc-ledger-display.h" +#include "gnucash-sheet.h" #include "dialog-sxsincelast.h" @@ -106,6 +109,9 @@ typedef struct _sxSinceLastData { GList *actual_to_remove; + GNCLedgerDisplay *ac_ledger; + GnucashRegister *reg; + } sxSinceLastData; typedef struct _toCreateTuple { @@ -129,16 +135,23 @@ typedef struct { gboolean isSelected; } toDeleteTuple; +typedef struct _creation_helper_userdata { + /* the to-create tuple */ + toCreateTuple *tct; + /* a [pointer to a] GList to append the GUIDs of newly-created + transactions to, or NULL */ + GList **createdGUIDs; +} createData; /* Next reminder clist row index to create. */ static int rl_row = 0; /* Next to-create clist row index to create. */ static int tcl_row = 0; -/* Next auto-create clist row index to create. */ -static int acl_row = 0; static void sxsincelast_init( sxSinceLastData *sxsld ); +static void _create_autoCreate_gen_ledger( sxSinceLastData *sxsld ); +static gncUIWidget _sxsld_ledger_get_parent( GNCLedgerDisplay *ld ); static gboolean sxsincelast_populate( sxSinceLastData *sxsld ); static void sxsincelast_close_handler( gpointer ud ); @@ -152,7 +165,8 @@ static void sxsincelast_destroy( GtkObject *o, gpointer ud ); static void _create_transactions_on( SchedXaction *sx, GDate *gd, - toCreateTuple *tct ); + toCreateTuple *tct, + GList **createdGUIDs ); static gboolean _create_each_transaction_helper( Transaction *t, void *d ); static void _sxsl_get_sx_vars( SchedXaction *sx, GHashTable *varHash ); static void _hash_to_sorted_list( GHashTable *hashTable, GList **gl ); @@ -351,7 +365,6 @@ sxsincelast_init( sxSinceLastData *sxsld ) dialog_widgets_attach_handlers(sxsld->gxml_remind, widgets_remind, sxsld); dialog_widgets_attach_handlers(sxsld->gxml_obsolete, widgets_obsolete, sxsld); - /* FIXME: Magic Numbers to be replaced */ /* set all to-create clist columns to auto-resize. */ @@ -363,18 +376,22 @@ sxsincelast_init( sxSinceLastData *sxsld ) w = glade_xml_get_widget( sxsld->gxml_obsolete, SX_OBSOLETE_CLIST); + clist_set_all_cols_autoresize(GTK_CLIST(w), SX_OBSOLETE_CLIST_WIDTH); - rl_row = tcl_row = acl_row = 0; + rl_row = tcl_row = 0; sxsld->n_obsolete = 0; + _create_autoCreate_gen_ledger( sxsld ); + /* FIXME: deal with neither dialog being displayed [read: nothing-to-do.] */ - if ( sxsincelast_populate( sxsld ) ) { - gtk_widget_show_all( sxsld->sxsincelastDlg ); - sxsld->sincelast_displayed = TRUE; + if ( ! sxsincelast_populate( sxsld ) ) { + sxsincelast_close_handler( sxsld ); } + gtk_widget_show_all( sxsld->sxsincelastDlg ); + sxsld->sincelast_displayed = TRUE; } static void @@ -438,31 +455,45 @@ _free_toCreate_list_elts( gpointer data, gpointer user_data ) static void processAutoCreateList( GList *autoCreateList, sxSinceLastData *sxsld, SchedXaction *sx ) { - GtkCList *cl; + Query *autoCreateQuery; + GList *createdGUIDs = NULL; + GList *thisGUID; + GtkFrame *f; gboolean autoCreateState, notifyState; char *rowText[2]; /* get the "automagically created and notification requested" - * register, and create the entries in it. For now, this is a clist, - * but it _should_ be a GL... */ - cl = GTK_CLIST( glade_xml_get_widget( sxsld->gxml, "auto_create_clist" ) ); - gtk_clist_freeze( cl ); - while ( autoCreateList ) { - xaccSchedXactionGetAutoCreate( sx, &autoCreateState, ¬ifyState ); - _create_transactions_on( sx, (GDate*)autoCreateList->data, NULL ); - if ( notifyState ) { - rowText[0] = xaccSchedXactionGetName( sx ); - rowText[1] = g_new0( gchar, GNC_D_BUF_WIDTH ); - g_date_strftime( rowText[1], GNC_D_WIDTH, "%a, %b %e, %Y", - (GDate*)autoCreateList->data ); - gtk_clist_insert( cl, acl_row++, rowText ); - g_free( rowText[1] ); - } + * register, and create the entries in it. */ + f = GTK_FRAME( glade_xml_get_widget( sxsld->gxml, "auto_create_frame" ) ); + autoCreateQuery = xaccMallocQuery(); + xaccQuerySetGroup( autoCreateQuery, + gnc_book_get_group( gnc_get_current_book() ) ); + while ( autoCreateList ) { + xaccSchedXactionGetAutoCreate( sx, + &autoCreateState, + ¬ifyState ); + _create_transactions_on( sx, (GDate*)autoCreateList->data, + NULL, &createdGUIDs ); + if ( notifyState ) { + thisGUID = createdGUIDs; + for ( ; thisGUID ; (thisGUID = thisGUID->next) ) { + xaccQueryAddGUIDMatch( autoCreateQuery, + (GUID*)thisGUID->data, + QUERY_OR ); + } + thisGUID = createdGUIDs = NULL; + } autoCreateList = autoCreateList->next; } - gtk_clist_thaw( cl ); + gnc_ledger_display_set_query( sxsld->ac_ledger, autoCreateQuery ); + gnc_ledger_display_refresh( sxsld->ac_ledger ); + + xaccFreeQuery( autoCreateQuery ); + + g_list_free( createdGUIDs ); + createdGUIDs = NULL; } static void @@ -808,9 +839,11 @@ _clean_sincelast_dlg( sxSinceLastData *sxsld ) */ _clean_variable_table( sxsld ); +/* FIXME: this probably wants to clean up a autoCreate Query object, now */ +#if 0 w = glade_xml_get_widget( sxsld->gxml, "auto_create_clist" ); gtk_clist_clear( GTK_CLIST(w) ); - acl_row = 0; +#endif /* 0 */ w = glade_xml_get_widget( sxsld->gxml, TO_CREATE_CLIST ); gtk_clist_clear( GTK_CLIST(w) ); @@ -864,9 +897,13 @@ sxsincelast_close_handler( gpointer ud ) } else { + gnc_ledger_display_close( sxsld->ac_ledger ); + sxsld->ac_ledger = NULL; + gnome_dialog_close( GNOME_DIALOG( sxsld->sxsincelastDlg ) ); sxsld->sxsincelastDlg = NULL; sxsld->sincelast_displayed = FALSE; + sxsld->reg = NULL; } /* FIXME -- cleanup: @@ -956,7 +993,7 @@ sxsincelast_ok_clicked( GtkButton *b, gpointer ud ) g_return_if_fail( tcList ); do { tct = (toCreateTuple*)tcList->data; - _create_transactions_on( tct->sx, tct->date, tct ); + _create_transactions_on( tct->sx, tct->date, tct, NULL ); } while ( (tcList = tcList->next) ); /* FIXME: cleanup appropriately. */ @@ -1059,6 +1096,7 @@ _create_each_transaction_helper( Transaction *t, void *d ) kvp_frame *split_kvpf; kvp_value *kvp_val; gboolean errFlag; + createData *createUD; toCreateTuple *tct; gnc_commodity *commonCommodity = NULL; @@ -1073,7 +1111,8 @@ _create_each_transaction_helper( Transaction *t, void *d ) DEBUG( "I'm seeing Transaction \"%s\"", xaccTransGetDescription( t ) ); - tct = (toCreateTuple*)d; + createUD = (createData*)d; + tct = createUD->tct; newT = xaccMallocTransaction(); xaccTransBeginEdit( newT ); @@ -1235,8 +1274,17 @@ _create_each_transaction_helper( Transaction *t, void *d ) if ( errFlag ) { PERR( "Some error in new transaction creation..." ); xaccTransRollbackEdit( newT ); - } else { + xaccTransDestroy( newT ); xaccTransCommitEdit( newT ); + return FALSE; + } + + xaccTransCommitEdit( newT ); + + if ( createUD->createdGUIDs != NULL ) { + *createUD->createdGUIDs = + g_list_append( *(createUD->createdGUIDs), + (gpointer)xaccTransGetGUID(newT) ); } return TRUE; @@ -1247,12 +1295,17 @@ _create_each_transaction_helper( Transaction *t, void *d ) * will set the last occur date incorrectly. **/ static void -_create_transactions_on( SchedXaction *sx, GDate *gd, toCreateTuple *tct ) +_create_transactions_on( SchedXaction *sx, GDate *gd, + toCreateTuple *tct, + GList **createdGUIDs ) { + createData createUD; AccountGroup *ag; Account *acct; char *id; char tmpBuf[GNC_D_BUF_WIDTH]; + gboolean createdTCT; + { g_date_strftime( tmpBuf, GNC_D_WIDTH, GNC_D_FMT, gd ); @@ -1262,36 +1315,47 @@ _create_transactions_on( SchedXaction *sx, GDate *gd, toCreateTuple *tct ) if ( tct != NULL && g_date_compare( gd, tct->date ) != 0 ) { - PERR( "GDate and TCT date aren't equal, which isn't a Good Thing." ); + PERR( "GDate and TCT date aren't equal, " + "which isn't a Good Thing." ); return; } + createdTCT = FALSE; if ( tct == NULL ) { /* Create a faux tct for the creation-helper. */ tct = g_new0( toCreateTuple, 1 ); tct->sx = sx; tct->date = gd; tct->clistRow = -1; + + createdTCT = TRUE; } ag = gnc_book_get_template_group( gnc_get_current_book () ); id = guid_to_string( xaccSchedXactionGetGUID(sx) ); if(ag && id) { - acct = xaccGetAccountFromName( ag, id ); + acct = xaccGetAccountFromName( ag, id ); if(acct) { + createUD.tct = tct; + createUD.createdGUIDs = createdGUIDs; xaccAccountForEachTransaction( acct, _create_each_transaction_helper, - tct ); + /*tct*/ &createUD ); } } if (id) { g_free( id ); } - - xaccSchedXactionSetLastOccurDate( sx, tct->date ); + + xaccSchedXactionSetLastOccurDate( sx, tct->date ); + + if ( createdTCT ) { + g_free( tct ); + tct = NULL; + } } static void @@ -1865,3 +1929,73 @@ sx_obsolete_unselect_all_clicked(GtkButton *button, gpointer user_data) return; } + +static void +_create_autoCreate_gen_ledger( sxSinceLastData *sxsld ) +{ + GtkFrame *autoCreate_frame; + SplitRegister *splitreg; + GtkWidget *regWidget; + GtkWidget *popup; + + autoCreate_frame = + GTK_FRAME( glade_xml_get_widget( sxsld->gxml, + "auto_create_frame" ) ); + sxsld->ac_ledger = gnc_ledger_display_gl(); + + gnc_ledger_display_set_handlers( sxsld->ac_ledger, + NULL, + _sxsld_ledger_get_parent ); + gnc_ledger_display_set_user_data( sxsld->ac_ledger, (gpointer)sxsld ); + + splitreg = gnc_ledger_display_get_split_register( sxsld->ac_ledger ); + /* FIXME: make configurable */ + gnucash_register_set_initial_rows( 6 ); + + regWidget = gnucash_register_new( splitreg->table ); + gnc_table_init_gui( regWidget, splitreg ); + + gtk_container_add( GTK_CONTAINER(glade_xml_get_widget( sxsld->gxml, + "ac_vbox" )), + regWidget ); + sxsld->reg = GNUCASH_REGISTER(regWidget); + GNUCASH_SHEET(sxsld->reg->sheet)->window = GTK_WIDGET(sxsld->sxsincelastDlg); + +#if 0 + gtk_signal_connect( GTK_OBJECT(sxed->dialog), "activate_cursor", + GTK_SIGNAL_FUNC(sxe_register_record_cb), sxed ); + gtk_signal_connect( GTK_OBJECT(sxed->dialog), "redraw_all", + GTK_SIGNAL_FUNC(sxe_register_redraw_all_cb), sxed ); + +#endif /* 0 */ + +#if 0 + /* FIXME: we should do all the happy-fun register stuff... button bar + controls ... popups ... */ + popup = schedXaction_editor_create_reg_popup( sxsld ); + gnucash_register_attach_popup( sxsld->reg, popup, sxsld ); +#endif /* 0 */ + + /* configure... */ + /* don't use double-line */ + gnc_split_register_config(splitreg, + splitreg->type, splitreg->style, + FALSE); + + /* don't show present/future divider [by definition, not necessary] */ + gnc_split_register_show_present_divider( splitreg, FALSE ); + + /* force a refresh */ + gnc_ledger_display_refresh( sxsld->ac_ledger ); + +} + +static +gncUIWidget +_sxsld_ledger_get_parent( GNCLedgerDisplay *ld ) +{ + sxSinceLastData *sxsld; + + sxsld = (sxSinceLastData*)gnc_ledger_display_get_user_data( ld ); + return sxsld->sxsincelastDlg; +} diff --git a/src/gnome/glade/sched-xact.glade b/src/gnome/glade/sched-xact.glade index 020a765cbf..e196099ecd 100644 --- a/src/gnome/glade/sched-xact.glade +++ b/src/gnome/glade/sched-xact.glade @@ -3047,7 +3047,7 @@ December GtkFrame - frame67 + auto_create_frame 0.1 GTK_SHADOW_ETCHED_IN @@ -3064,29 +3064,10 @@ December 0 - GtkLabel - label847814 - - GTK_JUSTIFY_CENTER - False - 0.5 - 0.5 - 0 - 0 - - 0 - False - False - - - - - GtkScrolledWindow - scrolledwindow7 - GTK_POLICY_NEVER - GTK_POLICY_AUTOMATIC - GTK_UPDATE_CONTINUOUS - GTK_UPDATE_CONTINUOUS + GtkVBox + ac_vbox + False + 0 0 True @@ -3094,40 +3075,32 @@ December - GtkCList - auto_create_clist - True - 2 - 207,80 - GTK_SELECTION_SINGLE - True - GTK_SHADOW_IN + GtkHButtonBox + hbuttonbox7 + GTK_BUTTONBOX_START + 30 + 85 + 27 + 7 + 0 + + 0 + False + False + - GtkLabel - CList:title - label847815 - - GTK_JUSTIFY_CENTER - False - 0.5 - 0.5 - 0 - 0 + GtkButton + rec_button + True + True + + GTK_RELIEF_NORMAL + - - GtkLabel - CList:title - label847816 - - GTK_JUSTIFY_CENTER - False - 0.5 - 0.5 - 0 - 0 - + + Placeholder diff --git a/src/register/ledger-core/split-register-layout.c b/src/register/ledger-core/split-register-layout.c index 1bbfecb8c0..410a72e14f 100644 --- a/src/register/ledger-core/split-register-layout.c +++ b/src/register/ledger-core/split-register-layout.c @@ -584,6 +584,7 @@ gnc_split_register_layout_add_cells (SplitRegister *reg, CELL_ALIGN_LEFT, FALSE, FALSE); + } TableLayout * @@ -599,3 +600,4 @@ gnc_split_register_layout_new (SplitRegister *reg) return layout; } + diff --git a/src/register/ledger-core/split-register-model.c b/src/register/ledger-core/split-register-model.c index 88d9ffa637..ef27b80d43 100644 --- a/src/register/ledger-core/split-register-model.c +++ b/src/register/ledger-core/split-register-model.c @@ -651,6 +651,17 @@ gnc_split_register_get_date_help (VirtualLocation virt_loc, return g_strdup (string); } +static const char * +gnc_split_register_get_inactive_date_entry (VirtualLocation virt_loc, + gboolean translate, + gboolean *conditionally_changed, + gpointer user_data) +{ + /* This seems to be the one that initially gets used, the InactiveDateCell + is set to, and subsequently displayed. */ + return "Scheduled"; +} + static const char * gnc_split_register_get_num_entry (VirtualLocation virt_loc, gboolean translate, @@ -1176,6 +1187,13 @@ gnc_split_register_get_debcred_entry (VirtualLocation virt_loc, } } +static CellIOFlags +gnc_split_register_get_inactive_io_flags (VirtualLocation virt_loc, + gpointer user_data) +{ + return XACC_CELL_ALLOW_NONE; +} + static CellIOFlags gnc_split_register_get_standard_io_flags (VirtualLocation virt_loc, gpointer user_data) @@ -1828,6 +1846,14 @@ gnc_template_register_model_new (void) model = gnc_split_register_model_new (); + gnc_table_model_set_entry_handler( model, + gnc_split_register_get_inactive_date_entry, + DATE_CELL ); + + gnc_table_model_set_io_flags_handler( model, + gnc_split_register_get_inactive_io_flags, + DATE_CELL ); + gnc_table_model_set_entry_handler (model, gnc_template_register_get_xfrm_entry, XFRM_CELL); diff --git a/src/register/register-core/register-common.h b/src/register/register-core/register-common.h index d184a69b9f..1d227b9c06 100644 --- a/src/register/register-core/register-common.h +++ b/src/register/register-core/register-common.h @@ -31,6 +31,7 @@ #define BASIC_CELL_TYPE_NAME "basic-cell" #define COMBO_CELL_TYPE_NAME "combo-cell" #define DATE_CELL_TYPE_NAME "date-cell" +#define INACTIVE_DATE_CELL_TYPE_NAME "inactive-date-cell" #define NUM_CELL_TYPE_NAME "num-cell" #define PRICE_CELL_TYPE_NAME "price-cell" #define RECN_CELL_TYPE_NAME "recn-cell"