2002-06-18 Joshua Sled <jsled@asynchronous.org>

* src/gnome-utils/gnc-dense-cal.[ch]: Added; a multiply-markable,
	visually-dense Gtk calendar widget, to be used by
	Scheduled Transactions.

	* src/gnome/dialog-scheduledxaction.c
	(putSchedXactionInDialog): Renamed; supports marking the new
	GncDenseCal.
	(delete_button_clicked): Now much less lame about dealing with the
	CList when items are removed; supports [un]marking the
	GncDenseCal.

	* src/gnome/dialog-scheduledxaction.c (editor_ok_button_clicked):
	Query the user if they want to create an unbalanceable
	[varible-containing] transaction. Inform the user if they try to
	create an auto-create transaction which has variables, as this is
	not allowed.


git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@6980 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
Joshua Sled 2002-06-19 05:04:56 +00:00
parent 687188fda5
commit 1c4df2daac
8 changed files with 1932 additions and 131 deletions

View File

@ -1,3 +1,23 @@
2002-06-18 Joshua Sled <jsled@asynchronous.org>
* src/gnome-utils/gnc-dense-cal.[ch]: Added; a multiply-markable,
visually-dense Gtk calendar widget, to be used by
Scheduled Transactions.
* src/gnome/dialog-scheduledxaction.c
(putSchedXactionInDialog): Renamed; supports marking the new
GncDenseCal.
(delete_button_clicked): Now much less lame about dealing with the
CList when items are removed; supports [un]marking the
GncDenseCal.
* src/gnome/dialog-scheduledxaction.c (editor_ok_button_clicked):
Query the user if they want to create an unbalanceable
[varible-containing] transaction. Inform the user if they try to
create an auto-create transaction which has variables, as this is
not allowed.
2002-06-18 David Hampton <hampton@employees.org>
* src/gnome/window-main.c: Make a couple of functions globally
@ -231,21 +251,6 @@
2002-05-21 Joshua Sled <jsled@asynchronous.org>
* src/gnome/dialog-sx-from-trans.c (sxftd_get_end_info): Changed
to do the strtoul before we free the data itself; fixes "can't
create once/number-of-occurance SXes" [in from-transaction dialog]
bug.
* src/gnome/dialog-scheduledxaction.c (editor_ok_button_clicked):
Do a very lame but good-enough-for-now check to see if we can
determine if the template transactions will still balance. Note
that we don't do anything with the result of that check, yet, but
we perform it.
* src/app-utils/gnc-exp-parser.c (gnc_exp_parser_real_init): Added
so we can conditionaly add the "predefined variables" to the
binding table for parsing a given expression.
2002-05-18 David Hampton <hampton@employees.org>
* configure.in: Work around incompatibilities between autoconf

View File

@ -108,7 +108,11 @@ X create a template register
. SX editor
. tab order
. Can't click-out of the register
. 'ESC' while editing template register causes window to go away badly
B 'ESC' while editing template register causes window to go away badly
B Can't reliably edit the split values of an added split to a from-trans
created transaction -- the values get nulled after split-change.
B Note that this doesn't hold true for just-created splits on a fresh
SX...
X attempting to create a Weekly SX with no days selected causes a segfault.
X the user should be prevented from doing this.
X composite SX shouldn't segfault when asked to getFreqSpecStr for this
@ -124,7 +128,7 @@ X create a template register
. general: there's going to be all sorts of interaction issues like these
between these things [SX-from-trans, SX list, SX editor] that should be
handled.
. creating a SX from trans with the SX list open does not update the SX
B creating a SX from trans with the SX list open does not update the SX
list
X you can delete a freshly-from-trans'd SX from the list with the
from-trans dlg still open, then 'ok' the dlg to get a segfault.
@ -168,16 +172,16 @@ X create a template register
pop up the 'new scheduled transactions' dialog [option, time-of-day]
. fix first/last page issues.
. bugs
. correct "Back" button behavior in Druid paradigm
. tab-order on variable-entry window isn't always correct.
. created SXes are put in GL forever. :(
. But this is true of manually-created transactions, too ... is this
B inital "To-Create Transactions" varbinding table doesn't setup table correctly.
B correct "Back" button behavior in Druid paradigm
B created SXes are put in GL forever. :(
B But this is true of manually-created transactions, too ... is this
actually correct behavior?
. inital "To-Create Transactions" varbinding table doesn't setup table correctly.
. creating a bunch [FIXME:define "bunch"] of transactions takes too long
B creating a bunch [FIXME:define "bunch"] of transactions takes too long
X with no progress indication.
. cancelling a bunch [FIXME:define "bunch"] of xactions takes too long
. no progress indication.
B cancelling a bunch [FIXME:define "bunch"] of xactions takes too long
B no progress indication.
X twunder reports [2002.01.29] register growing a little bit at a time if
tab is hit to switch between register fields -- started with update on
1/21.

View File

@ -31,6 +31,7 @@ libgncmod_gnome_utils_la_SOURCES = \
gnc-currency-edit.c \
gnc-date-delta.c \
gnc-date-edit.c \
gnc-dense-cal.c \
gnc-frequency.c \
gnc-general-select.c \
gnc-gnome-utils.c \
@ -57,6 +58,7 @@ gncinclude_HEADERS = \
gnc-currency-edit.h \
gnc-date-delta.h \
gnc-date-edit.h \
gnc-dense-cal.h \
gnc-frequency.h \
gnc-general-select.h \
gnc-gnome-utils.h \

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,141 @@
#ifndef _DENSECAL_H_
#define _DENSECAL_H_
/********************************************************************\
* gnc-dense-cal.h : a custom densely-dispalyed calendar widget *
* Copyright (C) 2002 Joshua Sled <jsled@asynchronous.org> *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License as *
* published by the Free Software Foundation; either version 2 of *
* the License, or (at your option) any later version. *
* *
* This program 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 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 <gdk/gdk.h>
#include <gtk/gtkadjustment.h>
#include <gtk/gtkwidget.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#define GNC_DENSE_CAL(obj) GTK_CHECK_CAST (obj, gnc_dense_cal_get_type (), GncDenseCal)
#define GNC_DENSE_CAL_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, gnc_dense_cal_get_type (), GncDenseCalClass)
#define GNC_IS_DENSE_CAL(obj) GTK_CHECK_TYPE (obj, gnc_dense_cal_get_type ())
typedef struct _GncDenseCal GncDenseCal;
typedef struct _GncDenseCalClass GncDenseCalClass;
typedef struct _gdc_month_coords {
gint x, y;
} gdc_month_coords;
struct _GncDenseCal
{
GtkWidget widget;
gboolean initialized;
gboolean showPopup;
GtkWindow *transPopup;
gint min_x_scale;
gint min_y_scale;
gint x_scale;
gint y_scale;
gint numMonths;
gint monthsPerCol;
gint num_weeks; // computed
GDateMonth month;
gint year;
gint firstOfMonthOffset;
gint leftPadding;
gint topPadding;
gboolean needInitMonthLabels;
gdc_month_coords monthPositions[12];
GdkFont *monthLabelFont;
GdkFont *dayLabelFont;
GdkPixmap *monthLabels[12];
enum GDC_COLORS {
MONTH_THIS = 0,
MONTH_THAT,
MAX_COLORS };
GdkColor weekColors[MAX_COLORS];
guint label_lbearing;
guint label_ascent;
guint label_width;
guint label_height;
guint dayLabelHeight;
guint lastMarkTag;
/**
* A GList of gdc_mark_data structs, one for each active/valid markTag.
**/
GList *markData;
int numMarks;
// array of GList*s of per-cell markings.
GList **marks;
};
struct _GncDenseCalClass
{
GtkWidgetClass parent_class;
void (*marks_lost_cb)( GncDenseCal *dcal, gpointer user_data );
};
typedef struct _gdc_mark_data {
gchar *name;
gchar *info;
guint tag;
// GdkColor markStyle;
/**
* A GList of the dcal->marks indexes containing this mark.
**/
GList *ourMarks;
} gdc_mark_data;
GtkWidget* gnc_dense_cal_new ();
GtkType gnc_dense_cal_get_type (void);
void gnc_dense_cal_set_month( GncDenseCal *dcal, GDateMonth mon );
/**
* @param year Julian year: 2000 = 2000AD.
**/
void gnc_dense_cal_set_year( GncDenseCal *dcal, guint year );
void gnc_dense_cal_set_num_months( GncDenseCal *dcal, guint num_months );
void gnc_dense_cal_set_months_per_col( GncDenseCal *dcal, guint monthsPerCol );
guint gnc_dense_cal_get_num_months( GncDenseCal *dcal );
GDateMonth gnc_dense_cal_get_month( GncDenseCal *dcal );
GDateYear gnc_dense_cal_get_year( GncDenseCal *dcal );
guint gnc_dense_cal_mark( GncDenseCal *dcal,
guint size, GDate **daysArray,
gchar *name, gchar *info );
void gnc_dense_cal_mark_remove( GncDenseCal *dcal, guint markToRemove );
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* _DENSECAL_H_ */

View File

@ -35,6 +35,7 @@
#include "gnc-book-p.h"
#include "gnc-component-manager.h"
#include "gnc-date-edit.h"
#include "gnc-dense-cal.h"
#include "gnc-engine-util.h"
#include "gnc-frequency.h"
#include "gnc-gui-query.h"
@ -58,6 +59,7 @@ static short module = MOD_SX;
#define DIALOG_SCHEDXACTION_EDITOR_CM_CLASS "dialog-scheduledtransaction-editor"
#define SX_LIST_GLADE_NAME "Scheduled Transaction List"
#define SX_LIST_UPCOMING_FRAME "upcoming_cal_frame"
#define SX_EDITOR_GLADE_NAME "Scheduled Transaction Editor"
#define SX_OPT_STR "Scheduled Transactions"
#define AUTOCREATE_OPT "autocreate_opt"
@ -94,10 +96,10 @@ typedef enum _EndTypeEnum {
struct _SchedXactionDialog
{
GtkWidget *dialog;
GladeXML *gxml;
/* other pertinant scheduled-transaction-editor info */
GtkWidget *dialog;
GladeXML *gxml;
GncDenseCal *gdcal;
GHashTable *sxData;
};
struct _SchedXactionEditorDialog
@ -106,6 +108,7 @@ struct _SchedXactionEditorDialog
GtkWidget *dialog;
SchedXactionDialog *sxd;
SchedXaction *sx;
/* FIXME: what does "new" mean? */
int new;
GNCLedgerDisplay *ledger;
@ -120,7 +123,10 @@ struct _SchedXactionEditorDialog
/** Prototypes **********************************************************/
static void putSchedXactionInClist( gpointer data, gpointer user_data );
static void putSchedXactionInDialog( gpointer data, gpointer user_data );
static void generate_instances( SchedXaction *sx,
GDate *end, GList **instanceList );
static void schedXact_populate( SchedXactionDialog * );
static void schedXact_editor_init( SchedXactionEditorDialog * );
@ -149,12 +155,15 @@ static void sxe_register_redraw_all_cb( GnucashRegister *reg, gpointer d );
static void sxed_reg_recordCB( GtkWidget *w, gpointer d );
static void sxed_reg_cancelCB( GtkWidget *w, gpointer d );
#if 0 /* removed 2002.05.29 to get rid of compilation warnings after
* gncRegWidget addition. */
static void sxed_reg_deleteCB( GtkWidget *w, gpointer d );
static void sxed_reg_duplicateCB( GtkWidget *w, gpointer d );
static void sxed_reg_expand_trans_checkCB( GtkWidget *w, gpointer d );
static void sxed_reg_new_transCB( GtkWidget *w, gpointer d );
static void sxed_reg_jumpCB( GtkWidget *w, gpointer d );
static void sxed_reg_xferCB( GtkWidget *w, gpointer d );
#endif /* 0 -- removed 2002.05.29 */
static void gnc_sxed_reg_check_close(SchedXactionEditorDialog *sxed);
@ -234,9 +243,13 @@ static void
set_var_to_random_value( gpointer key, gpointer value, gpointer ud )
{
gnc_numeric *val;
val = g_new0( gnc_numeric, 1 );
*val = double_to_gnc_numeric( rand() + 2, 1,
GNC_NUMERIC_RND_MASK | GNC_RND_FLOOR );
if ( value != NULL ) {
g_free( value );
}
g_hash_table_insert( ud, key, val );
}
@ -249,6 +262,7 @@ editor_ok_button_clicked( GtkButton *b, SchedXactionEditorDialog *sxed )
GList *sxList;
FreqSpec *fs;
GDate *gdate;
gboolean ttHasVars;
/* FIXMEs: Do checks on validity and such, interrupting the user if
* things aren't right.
@ -266,11 +280,15 @@ editor_ok_button_clicked( GtkButton *b, SchedXactionEditorDialog *sxed )
* [X more generically, creating a "not scheduled" SX is probably not
* right... ]
*/
ttHasVars = FALSE;
gnc_split_register_save ( gnc_ledger_display_get_split_register(sxed->ledger),
FALSE );
/* numeric-formulas-get-balanced determination */
{
static const int NUM_ITERS_WITH_VARS = 5;
static const int NUM_ITERS_NO_VARS = 1;
int numIters, i;
GHashTable *vars;
GList *splitList = NULL;
char *str;
@ -278,10 +296,11 @@ editor_ok_button_clicked( GtkButton *b, SchedXactionEditorDialog *sxed )
kvp_value *v;
Split *s;
gnc_numeric creditSum, debitSum, tmp;
gboolean unbalanceable;
creditSum = debitSum = gnc_numeric_zero();
unbalanceable = FALSE; /* innocent until proven guilty */
vars = g_hash_table_new( g_str_hash, g_str_equal );
splitList = xaccSchedXactionGetSplits( sxed->sx );
numIters = NUM_ITERS_NO_VARS;
/**
* Plan:
* . Do a first pass to get the variables.
@ -291,63 +310,89 @@ editor_ok_button_clicked( GtkButton *b, SchedXactionEditorDialog *sxed )
* . false: indicate to user, allow decision.
*/
sxsl_get_sx_vars( sxed->sx, vars );
if ( g_hash_table_size( vars ) == 0 ) {
/* FIXME: just balance as is, DTRT. */
ttHasVars = (g_hash_table_size( vars ) != 0);
if ( g_hash_table_size( vars ) != 0 ) {
/* balance with random variable bindings some number
* of times in an attempt to ferret out
* un-balanceable transactions.
*
* NOTE: The Real Way to do this is with some
* symbolic math to eliminate the variables. This is
* hard, and we don't do it. This solution will
* suffice for now, and perhaps for the lifetime of
* the software. --jsled */
numIters = NUM_ITERS_WITH_VARS;
}
/* FIXME: since we have variables, we can deal with any
* possible auto-create flaggage. */
g_hash_table_foreach( vars, set_var_to_random_value,
(gpointer)vars );
for ( ; splitList; splitList = splitList->next ) {
s = (Split*)splitList->data;
f = xaccSplitGetSlots( s );
v = kvp_frame_get_slot_path( f,
GNC_SX_ID,
GNC_SX_CREDIT_FORMULA,
NULL );
if ( v
&& (str = kvp_value_get_string(v))
&& strlen( str ) != 0 ) {
if ( parse_vars_from_formula( str, vars, &tmp ) < 0 ) {
PERR( "Couldn't parse credit formula for "
"\"%s\" on second pass",
xaccSchedXactionGetName( sxed->sx ) );
return;
srand(time(NULL));
for ( i=0; i < numIters && !unbalanceable; i++ ) {
g_hash_table_foreach( vars, set_var_to_random_value,
(gpointer)vars );
creditSum = debitSum = gnc_numeric_zero();
for ( splitList = xaccSchedXactionGetSplits( sxed->sx );
splitList; splitList = splitList->next ) {
s = (Split*)splitList->data;
f = xaccSplitGetSlots( s );
v = kvp_frame_get_slot_path( f,
GNC_SX_ID,
GNC_SX_CREDIT_FORMULA,
NULL );
if ( v
&& (str = kvp_value_get_string(v))
&& strlen( str ) != 0 ) {
if ( parse_vars_from_formula( str, vars, &tmp ) < 0 ) {
PERR( "Couldn't parse credit formula for "
"\"%s\" on second pass",
xaccSchedXactionGetName( sxed->sx ) );
return;
}
creditSum = gnc_numeric_add_fixed( creditSum, tmp );
tmp = gnc_numeric_zero();
}
creditSum = gnc_numeric_add_fixed( creditSum, tmp );
tmp = gnc_numeric_zero();
}
v = kvp_frame_get_slot_path( f,
GNC_SX_ID,
GNC_SX_DEBIT_FORMULA,
NULL );
if ( v
&& (str = kvp_value_get_string(v))
&& strlen(str) != 0 ) {
if ( parse_vars_from_formula( str, vars, &tmp ) < 0 ) {
PERR( "Couldn't parse debit formula for "
"\"%s\" on second pass",
xaccSchedXactionGetName( sxed->sx ) );
return;
v = kvp_frame_get_slot_path( f,
GNC_SX_ID,
GNC_SX_DEBIT_FORMULA,
NULL );
if ( v
&& (str = kvp_value_get_string(v))
&& strlen(str) != 0 ) {
if ( parse_vars_from_formula( str, vars, &tmp ) < 0 ) {
PERR( "Couldn't parse debit formula for "
"\"%s\" on second pass",
xaccSchedXactionGetName( sxed->sx ) );
return;
}
debitSum = gnc_numeric_add_fixed( debitSum, tmp );
tmp = gnc_numeric_zero();
}
debitSum = gnc_numeric_add_fixed( debitSum, tmp );
tmp = gnc_numeric_zero();
}
}
if ( gnc_numeric_zero_p( gnc_numeric_sub_fixed( debitSum, creditSum ) ) ) {
printf( "true [%s - %s = %s]\n",
gnc_numeric_to_string( debitSum ),
gnc_numeric_to_string( creditSum ),
gnc_numeric_to_string(gnc_numeric_sub_fixed( debitSum, creditSum )) );
} else {
printf( "false [%s - %s = %s]\n",
gnc_numeric_to_string( debitSum ),
gnc_numeric_to_string( creditSum ),
gnc_numeric_to_string(gnc_numeric_sub_fixed( debitSum, creditSum )) );
unbalanceable |= !(gnc_numeric_zero_p( gnc_numeric_sub_fixed( debitSum, creditSum ) ));
#if DEBUG
if ( gnc_numeric_zero_p( gnc_numeric_sub_fixed( debitSum, creditSum ) ) ) {
printf( "true [%s - %s = %s]\n",
gnc_numeric_to_string( debitSum ),
gnc_numeric_to_string( creditSum ),
gnc_numeric_to_string(gnc_numeric_sub_fixed( debitSum, creditSum )) );
} else {
printf( "false [%s - %s = %s]\n",
gnc_numeric_to_string( debitSum ),
gnc_numeric_to_string( creditSum ),
gnc_numeric_to_string(gnc_numeric_sub_fixed( debitSum, creditSum )) );
}
#endif /* DEBUG */
}
g_hash_table_destroy( vars );
if ( unbalanceable
&& !gnc_verify_dialog_parented( sxed->dialog, FALSE,
"%s",
_("This transaction "
"appears unbalancable, "
"should it still be "
"created?") ) ) {
return;
}
}
/* read out data back into SchedXaction object. */
@ -436,8 +481,16 @@ editor_ok_button_clicked( GtkButton *b, SchedXactionEditorDialog *sxed )
w = glade_xml_get_widget( sxed->gxml, "notify_opt" );
notifyState = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(w) );
if ( ttHasVars && autocreateState ) {
gnc_info_dialog( _("You attempted to create a \"Create "
"Automatically\" "
"Scheduled Transaction which has Variables, "
"which is not allowed.\nPlease remove the "
"Create Automatically flag and try again.") );
return;
}
/* "Notify" only makes sense if AutoCreate is actived;
enforce that here. */
* enforce that here. */
xaccSchedXactionSetAutoCreate( sxed->sx,
autocreateState,
(autocreateState & notifyState) );
@ -495,7 +548,7 @@ editor_ok_button_clicked( GtkButton *b, SchedXactionEditorDialog *sxed )
}
/* add to list */
putSchedXactionInClist( sxed->sx, sxed->sxd );
putSchedXactionInDialog( sxed->sx, sxed->sxd );
if ( sxed->new ) {
book = gnc_get_current_book ();
sxList = gnc_book_get_schedxactions( book );
@ -580,6 +633,7 @@ gnc_ui_scheduled_xaction_dialog_create(void)
SchedXactionDialog *sxd = NULL;
GtkObject *sxdo;
GtkWidget *button;
GtkWidget *w;
GList *alreadyExisting = NULL;
alreadyExisting =
@ -597,13 +651,15 @@ gnc_ui_scheduled_xaction_dialog_create(void)
sxd->gxml = gnc_glade_xml_new( "sched-xact.glade", SX_LIST_GLADE_NAME );
sxd->dialog = glade_xml_get_widget( sxd->gxml, SX_LIST_GLADE_NAME );
sxd->sxData = g_hash_table_new( NULL, NULL );
sxdo = GTK_OBJECT(sxd->dialog);
gnc_register_gui_component( DIALOG_SCHEDXACTION_CM_CLASS,
NULL, /* no refresh handler */
sxd_close_handler,
sxd );
w = glade_xml_get_widget( sxd->gxml, SX_LIST_UPCOMING_FRAME );
sxd->gdcal = GNC_DENSE_CAL( gnc_dense_cal_new() );
gnc_dense_cal_set_months_per_col( sxd->gdcal, 4 );
gnc_dense_cal_set_num_months( sxd->gdcal, 12 );
gtk_container_add( GTK_CONTAINER(w), GTK_WIDGET(sxd->gdcal) );
gtk_signal_connect( sxdo, "destroy",
GTK_SIGNAL_FUNC(scheduledxaction_dialog_destroy),
@ -622,9 +678,14 @@ gnc_ui_scheduled_xaction_dialog_create(void)
gtk_signal_connect( GTK_OBJECT(button), "clicked",
GTK_SIGNAL_FUNC(close_button_clicked), sxd );
gnc_register_gui_component( DIALOG_SCHEDXACTION_CM_CLASS,
NULL, /* no refresh handler */
sxd_close_handler,
sxd );
schedXact_populate( sxd );
gtk_widget_show(sxd->dialog);
gtk_widget_show_all(sxd->dialog);
return sxd;
}
@ -657,7 +718,7 @@ row_select_handler( GtkCList *clist,
{
SchedXactionDialog *sxd;
SchedXaction *sx;
sxd = (SchedXactionDialog*)d;
if ( event == NULL ) {
@ -688,7 +749,7 @@ schedXact_populate( SchedXactionDialog *sxd )
book = gnc_get_current_book ();
sxList = gnc_book_get_schedxactions( book );
g_list_foreach( sxList, putSchedXactionInClist, sxd );
g_list_foreach( sxList, putSchedXactionInDialog, sxd );
sx_clist = GTK_CLIST( glade_xml_get_widget( sxd->gxml,
"sched_xact_list" ) );
@ -738,19 +799,19 @@ gnc_ui_scheduled_xaction_editor_dialog_create( SchedXactionDialog *sxd,
void (*fn)();
gpointer objectData;
} widgets[] = {
{ "ok_button", "clicked", editor_ok_button_clicked, NULL },
{ "ok_button", "clicked", editor_ok_button_clicked, NULL },
{ "cancel_button", "clicked", editor_cancel_button_clicked, NULL },
{ "help_button", "clicked", editor_help_button_clicked, NULL},
{ "help_button", "clicked", editor_help_button_clicked, NULL},
{ "rb_noend", "toggled", endgroup_rb_toggled, GINT_TO_POINTER(END_NEVER_OPTION) },
{ "rb_enddate", "toggled", endgroup_rb_toggled, GINT_TO_POINTER(END_DATE_OPTION) },
{ "rb_num_occur", "toggled", endgroup_rb_toggled, GINT_TO_POINTER(NUM_OCCUR_OPTION) },
{ "rb_noend", "toggled", endgroup_rb_toggled, GINT_TO_POINTER(END_NEVER_OPTION) },
{ "rb_enddate", "toggled", endgroup_rb_toggled, GINT_TO_POINTER(END_DATE_OPTION) },
{ "rb_num_occur", "toggled", endgroup_rb_toggled, GINT_TO_POINTER(NUM_OCCUR_OPTION) },
{ "autocreate_opt", "toggled", autocreate_toggled, NULL },
{ "advance_opt", "toggled", advance_toggle, (gpointer)"advance_days" },
{ "remind_opt", "toggled", advance_toggle, (gpointer)"remind_days" },
{ "autocreate_opt", "toggled", autocreate_toggled, NULL },
{ "advance_opt", "toggled", advance_toggle, (gpointer)"advance_days" },
{ "remind_opt", "toggled", advance_toggle, (gpointer)"remind_days" },
{ NULL, NULL, NULL, NULL }
{ NULL, NULL, NULL, NULL }
};
alreadyExists = gnc_find_gui_components( DIALOG_SCHEDXACTION_EDITOR_CM_CLASS,
@ -784,7 +845,7 @@ gnc_ui_scheduled_xaction_editor_dialog_create( SchedXactionDialog *sxd,
gtk_signal_connect(GTK_OBJECT(sxed->dialog), "destroy",
GTK_SIGNAL_FUNC(scheduledxaction_editor_dialog_destroy),
sxed);
/* FIXME: want delete-event, too. */
/* FIXME: want delete-event, too. [?] */
for ( i=0; widgets[i].name != NULL; i++ ) {
button = glade_xml_get_widget( sxed->gxml, widgets[i].name );
@ -872,7 +933,7 @@ schedXact_editor_create_ledger( SchedXactionEditorDialog *sxed )
{
GtkFrame *tempxaction_frame;
SplitRegister *splitreg;
GtkWidget *regWidget, *vbox, *toolbar;
GtkWidget *regWidget, *vbox;
int numLedgerLines = NUM_LEDGER_LINES_DEFAULT;
tempxaction_frame =
@ -1152,14 +1213,12 @@ edit_button_clicked( GtkButton *b, gpointer d )
SchedXactionEditorDialog *sxed;
sxd = (SchedXactionDialog*)d;
cl = GTK_CLIST(glade_xml_get_widget( sxd->gxml, "sched_xact_list" ));
for( sel = cl->selection; sel; sel = g_list_next(sel) ) {
row = (int)sel->data;
/* get the clist row for this listitem */
/* get the object UD */
sx = (SchedXaction*)gtk_clist_get_row_data( cl, row );
/* get the object UD */
sxed = gnc_ui_scheduled_xaction_editor_dialog_create( sxd, sx, 0 );
}
}
@ -1193,7 +1252,7 @@ delete_button_clicked( GtkButton *b, gpointer d )
realConfDelOpenMsg = g_string_new( beingEditedMessage );
beingEditedList = NULL;
for ( ; sel ; sel = sel->next ) {
sx = gtk_clist_get_row_data( cl, (int)sel->data );
sx = (SchedXaction*)gtk_clist_get_row_data( cl, (int)sel->data );
g_string_sprintfa( realConfDeleteMsg, "\n\"%s\"",
xaccSchedXactionGetName( sx ) );
if ( (l = gnc_find_gui_components( DIALOG_SCHEDXACTION_EDITOR_CM_CLASS,
@ -1240,20 +1299,39 @@ delete_button_clicked( GtkButton *b, gpointer d )
}
/* Now, actually do the deletions... */
sel = cl->selection;
book = gnc_get_current_book ();
sxList = gnc_book_get_schedxactions( book );
do {
sx = (SchedXaction*)
gtk_clist_get_row_data( cl, (int)sel->data );
for ( sel = cl->selection; sel; sel = sel->next ) {
guint tag;
gpointer unused;
gboolean foundP;
sx = (SchedXaction*)gtk_clist_get_row_data( cl, (int)sel->data );
sxList = g_list_remove( sxList, (gpointer)sx );
foundP = g_hash_table_lookup_extended( sxd->sxData, sx,
&unused, &tag );
g_assert( foundP );
/* FIXME: this should allow the possibility that an
* unscheduled transaction will have no mark tag. */
if ( tag != -1 ) {
gnc_dense_cal_mark_remove( sxd->gdcal, tag );
}
g_hash_table_remove( sxd->sxData, sx );
xaccSchedXactionFree( sx );
} while ( (sel = g_list_next(sel)) );
}
gnc_book_set_schedxactions( book, sxList );
gtk_clist_freeze( cl );
gtk_clist_clear( cl );
g_list_foreach( sxList, putSchedXactionInClist, sxd );
/* Remove the selected and deleted rows from the clist in
* reverse order so each index is valid. */
sel = g_list_copy( cl->selection );
sel = g_list_reverse( sel );
gtk_clist_unselect_all( cl );
for ( ; sel; sel = sel->next ) {
gtk_clist_remove( cl, (int)sel->data );
}
g_list_free( sel );
sel = NULL;
gtk_clist_thaw( cl );
}
@ -1292,7 +1370,49 @@ endgroup_rb_toggled( GtkButton *b, gpointer d )
static
void
putSchedXactionInClist( gpointer data, gpointer user_data )
generate_instances( SchedXaction *sx,
GDate *end, GList **instanceList )
{
GDate gd, *gdToReturn;
void *seqStateData;
/* Process valid next instances */
seqStateData = xaccSchedXactionCreateSequenceState( sx );
gd = xaccSchedXactionGetNextInstance( sx, seqStateData );
while ( g_date_valid(&gd)
&& g_date_compare( &gd, end ) <= 0 ) {
gdToReturn = g_date_new();
*gdToReturn = gd;
*instanceList = g_list_append( *instanceList, gdToReturn );
xaccSchedXactionIncrSequenceState( sx, seqStateData );
gd = xaccSchedXactionGetInstanceAfter( sx, &gd, seqStateData );
}
xaccSchedXactionDestroySequenceState( seqStateData );
seqStateData = NULL;
}
/**
* In this version, we're just updating the clist so the column data is
* correct. We already have valid hash table and dense-cal mappings.
**/
static
void
update_clist( gpointer data, gpointer user_data )
{
SchedXaction *sx;
SchedXactionDialog *sxd;
sx = (SchedXaction*)data;
sxd = (SchedXactionDialog*)user_data;
}
static
void
putSchedXactionInDialog( gpointer data, gpointer user_data )
{
SchedXaction *sx;
SchedXactionDialog *sxd;
@ -1302,7 +1422,11 @@ putSchedXactionInClist( gpointer data, gpointer user_data )
GString *nextDate;
gint row;
int i;
GDate gd;
GDate *nextInstDate, *calEndDate;
int instArraySize;
GDate **instArray;
GList *instList;
guint gdcMarkTag, oldMarkTag;
sx = (SchedXaction*)data;
sxd = (SchedXactionDialog*)user_data;
@ -1312,37 +1436,81 @@ putSchedXactionInClist( gpointer data, gpointer user_data )
xaccFreqSpecGetFreqStr( xaccSchedXactionGetFreqSpec(sx), freqStr );
gd = xaccSchedXactionGetNextInstance( sx, NULL );
calEndDate = g_date_new_dmy( 1,
gnc_dense_cal_get_month(sxd->gdcal),
gnc_dense_cal_get_year(sxd->gdcal) );
g_date_add_months( calEndDate,
gnc_dense_cal_get_num_months(sxd->gdcal) );
if ( ! g_date_valid( &gd ) ) {
instList = NULL;
generate_instances( sx, calEndDate, &instList );
g_date_free( calEndDate );
if ( instList == NULL ) {
g_string_sprintf( nextDate, "not scheduled" );
} else {
char tmpBuf[26];
g_date_strftime( tmpBuf, 25, "%a, %b %e, %Y", &gd );
nextInstDate = (GDate*)instList->data;
g_date_strftime( tmpBuf, 25, "%a, %b %e, %Y", nextInstDate );
g_string_sprintf( nextDate, "%s", tmpBuf );
}
/* Add markings to GncDenseCal */
gdcMarkTag = -1;
if ( instList != NULL ) {
GList *l;
FreqSpec *fs;
GString *freqDesc;
instArraySize = g_list_length( instList );
instArray = g_new0( GDate*, instArraySize );
for ( i=0, l=instList; l; l = l->next ) {
instArray[i++] = (GDate*)l->data;
}
freqDesc = g_string_sized_new(64);
fs = xaccSchedXactionGetFreqSpec(sx);
xaccFreqSpecGetFreqStr(fs, freqDesc );
gdcMarkTag = gnc_dense_cal_mark( sxd->gdcal,
instArraySize, instArray,
xaccSchedXactionGetName(sx),
freqDesc->str );
g_string_free( freqDesc, TRUE );
g_list_free( instList );
g_free( instArray );
}
text[0] = xaccSchedXactionGetName( sx );
text[1] = freqStr->str;
text[2] = nextDate->str;
/* FIXME: leaky? */
g_string_free( freqStr, FALSE );
g_string_free( nextDate, FALSE );
clist = GTK_CLIST( glade_xml_get_widget( sxd->gxml, "sched_xact_list" ) );
gtk_clist_freeze( clist );
row = gtk_clist_find_row_from_data( clist, sx );
if ( row != -1 ) {
gpointer unused;
gboolean foundP =
g_hash_table_lookup_extended( sxd->sxData,
(gpointer)sx,
&unused, &oldMarkTag );
g_assert( foundP );
}
if ( row == -1 ) {
/* new item to be inserted */
row = gtk_clist_append( clist, text );
gtk_clist_set_row_data( clist, row, sx );
} else {
/* old item being replaced. */
gnc_dense_cal_mark_remove( sxd->gdcal, oldMarkTag );
for ( i=0; i<3; i++ ) {
gtk_clist_set_text( clist, row, i, text[i] );
}
}
gtk_clist_thaw( clist );
g_hash_table_insert( sxd->sxData, (gpointer)sx, (gpointer)gdcMarkTag );
/* FIXME: leaky? -- shouldn't be with 'TRUE' below */
g_string_free( freqStr, TRUE );
g_string_free( nextDate, TRUE );
}
static
@ -1425,6 +1593,8 @@ refactor_transaction_delete_toggle_cb(GtkToggleButton *button, gpointer data)
}
/* FIXME */
#if 0 /* removed 2002.05.29 by jsled to remove compilation warnings after
* gncRegWidget addition. */
static DeleteType
refactor_transaction_delete_query(GtkWindow *parent)
{
@ -1581,6 +1751,7 @@ sxed_reg_xferCB( GtkWidget *w, gpointer d )
{
/* FIXME: should use a "templatized" xfer dlg. */
}
#endif /* 0 -- removed 2002.05.29 ... */
/********************************************************************\
* gnc_register_check_close *

View File

@ -1,6 +1,6 @@
/********************************************************************\
* dialog-sxsincelast.c - "since last run" dialog. *
* Copyright (c) 2001 Joshua Sled <jsled@asynchronous.org> *
* Copyright (c) 2001,2002 Joshua Sled <jsled@asynchronous.org> *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License as *
@ -1018,7 +1018,8 @@ process_auto_create_list( GList *autoCreateList, sxSinceLastData *sxsld )
q = xaccMallocQuery();
gnc_suspend_gui_refresh();
count = 0;
gtk_progress_configure( sxsld->prog, 0, 0, g_list_length( autoCreateList ) );
gtk_progress_configure( GTK_PROGRESS(sxsld->prog), 0, 0,
g_list_length( autoCreateList ) );
for ( ; autoCreateList ; autoCreateList = autoCreateList->next ) {
thisGUID = createdGUIDs = NULL;
act = (autoCreateTuple*)autoCreateList->data;
@ -1030,7 +1031,7 @@ process_auto_create_list( GList *autoCreateList, sxSinceLastData *sxsld )
NULL, &createdGUIDs );
count += g_list_length( createdGUIDs );
gtk_progress_set_value( sxsld->prog, count );
gtk_progress_set_value( GTK_PROGRESS(sxsld->prog), count );
while (g_main_iteration(FALSE));
sxsld->autoCreatedSomething = TRUE;
@ -2284,8 +2285,8 @@ create_autoCreate_ledger( sxSinceLastData *sxsld )
gnucash_register_set_initial_rows( 4 );
sxsld->ac_regWidget =
gnc_regWidget_new( sxsld->ac_ledger,
GTK_WINDOW( sxsld->sincelast_window ) );
GNC_REGWIDGET(gnc_regWidget_new( sxsld->ac_ledger,
GTK_WINDOW( sxsld->sincelast_window ) ));
vbox = glade_xml_get_widget( sxsld->gxml, AUTO_CREATE_VBOX );
toolbar = gnc_regWidget_get_toolbar( sxsld->ac_regWidget );
@ -2339,8 +2340,8 @@ create_created_ledger( sxSinceLastData *sxsld )
gnucash_register_set_initial_rows( 4 );
sxsld->created_regWidget =
gnc_regWidget_new( sxsld->created_ledger,
GTK_WINDOW( sxsld->sincelast_window ) );
GNC_REGWIDGET(gnc_regWidget_new( sxsld->created_ledger,
GTK_WINDOW( sxsld->sincelast_window ) ));
vbox = glade_xml_get_widget( sxsld->gxml, CREATED_VBOX );
toolbar = gnc_regWidget_get_toolbar( sxsld->created_regWidget );

View File

@ -2576,7 +2576,7 @@ December
<spacing>0</spacing>
<child>
<padding>0</padding>
<expand>True</expand>
<expand>False</expand>
<fill>True</fill>
</child>
@ -2633,7 +2633,7 @@ December
<class>GtkLabel</class>
<child_name>CList:title</child_name>
<name>label847752</name>
<label>Next</label>
<label>Next Occurance</label>
<justify>GTK_JUSTIFY_CENTER</justify>
<wrap>False</wrap>
<xalign>0.5</xalign>
@ -2687,6 +2687,24 @@ December
</widget>
</widget>
</widget>
<widget>
<class>GtkFrame</class>
<name>upcoming_cal_frame</name>
<border_width>2</border_width>
<label>Upcoming...</label>
<label_xalign>0.05</label_xalign>
<shadow_type>GTK_SHADOW_ETCHED_IN</shadow_type>
<child>
<padding>0</padding>
<expand>True</expand>
<fill>True</fill>
</child>
<widget>
<class>Placeholder</class>
</widget>
</widget>
</widget>
</widget>