mirror of
https://github.com/Gnucash/gnucash.git
synced 2026-07-29 15:53:45 -05:00
2002-08-18 Joshua Sled <jsled@asynchronous.org>
* src/gnome-utils/gnc-frequency.c: Added support for a "changed" signal so callers can use their own calendar to show the effects of editing the FreqSpec. * src/gnome/dialog-sx-from-trans.c: Added support for using the dense-calendar for showing the effects of option changes. * src/gnome/dialog-scheduledxaction.c: Added editor support for using the dense-calendar for showing the effects of FreqSpec changes; re-arranged the editor layout to accomodate. Added editor support for showing the last-occurred date of an SX. * src/gnome/glade/sched-xact.glade: Changes to sx-from-trans dialog, SX editor, GNCFrequency-widgets. * src/gnome/dialog-sxsincelast.c (sxsincelast_entry_changed): Added support for variable-entry parsing errors to go to an on-screen status bar instead of being printed to stderr [Bug#90354]. * src/gnome/druid-loan.c (gnc_loan_druid_length_changed): Added change-handler to the total-loan-length spin; when it changes, the remaining-length spin changes the same [Bug#90785]. (gnc_ui_sx_loan_druid_create): Adjusted the size/granularity of the interest-rate spin-button to 3 sig.digits. [Bug#90780]. * src/gnome/glade/sched-xact.glade: Changed [back?] the shrink/auto-shrink flags on the since-last-run-druid, fixing Bug#90364 and strangely fixing Bug#90365. git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@7183 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
@@ -1,3 +1,35 @@
|
||||
2002-08-18 Joshua Sled <jsled@asynchronous.org>
|
||||
|
||||
* src/gnome-utils/gnc-frequency.c: Added support for a "changed"
|
||||
signal so callers can use their own calendar to show the effects
|
||||
of editing the FreqSpec.
|
||||
|
||||
* src/gnome/dialog-sx-from-trans.c: Added support for using the
|
||||
dense-calendar for showing the effects of option changes.
|
||||
|
||||
* src/gnome/dialog-scheduledxaction.c: Added editor support for
|
||||
using the dense-calendar for showing the effects of FreqSpec
|
||||
changes; re-arranged the editor layout to accomodate. Added
|
||||
editor support for showing the last-occurred date of an SX.
|
||||
|
||||
* src/gnome/glade/sched-xact.glade: Changes to sx-from-trans
|
||||
dialog, SX editor, GNCFrequency-widgets.
|
||||
|
||||
* src/gnome/dialog-sxsincelast.c (sxsincelast_entry_changed):
|
||||
Added support for variable-entry parsing errors to go to an
|
||||
on-screen status bar instead of being printed to stderr
|
||||
[Bug#90354].
|
||||
|
||||
* src/gnome/druid-loan.c (gnc_loan_druid_length_changed): Added
|
||||
change-handler to the total-loan-length spin; when it changes, the
|
||||
remaining-length spin changes the same [Bug#90785].
|
||||
(gnc_ui_sx_loan_druid_create): Adjusted the size/granularity of
|
||||
the interest-rate spin-button to 3 sig.digits. [Bug#90780].
|
||||
|
||||
* src/gnome/glade/sched-xact.glade: Changed [back?] the
|
||||
shrink/auto-shrink flags on the since-last-run-druid, fixing
|
||||
Bug#90364 and strangely fixing Bug#90365.
|
||||
|
||||
2002-08-15 Christian Stimming <stimming@tuhh.de>
|
||||
|
||||
* src/import-export/hbci/*: much more HBCI work. Ini-Letter of
|
||||
|
||||
@@ -77,10 +77,14 @@ gboolean gnc_exp_parser_parse (const char * expression,
|
||||
gnc_numeric *value_p,
|
||||
char **error_loc_p );
|
||||
|
||||
/* Parses as per gnc_exp_parser_parse, but with an optional last argument
|
||||
/**
|
||||
* Parses as per gnc_exp_parser_parse, but with an optional last argument
|
||||
* dealing with a non-shared variable list and state, local to the expression
|
||||
* being parsed. This is a hashTable of variable names mapping to
|
||||
* gnc_numeric pointers. */
|
||||
* gnc_numeric pointers.
|
||||
* @note It is the CALLER'S RESPONSIBILITY to g_free() both the keys and
|
||||
* values of varHash when done.
|
||||
**/
|
||||
gboolean gnc_exp_parser_parse_separate_vars (const char * expression,
|
||||
gnc_numeric *value_p,
|
||||
char **error_loc_p,
|
||||
|
||||
+110
-127
@@ -120,6 +120,8 @@ static short module = MOD_SX;
|
||||
|
||||
/** PROTOTYPES ******************************************************/
|
||||
|
||||
static int int_cmp( int a, int b );
|
||||
|
||||
/**
|
||||
* Destroys all sub-FreqSpecs in a composite FreqSpec.
|
||||
* Assertion error if it's not a COMPOSITE FreqSpec.
|
||||
@@ -268,20 +270,22 @@ static inline guint32 min( guint32 a, guint32 b )
|
||||
}
|
||||
|
||||
void
|
||||
xaccFreqSpecGetNextInstance(
|
||||
FreqSpec *fs,
|
||||
const GDate* in_date,
|
||||
GDate* out_date )
|
||||
xaccFreqSpecGetNextInstance( FreqSpec *fs,
|
||||
const GDate* in_date,
|
||||
GDate* out_date )
|
||||
{
|
||||
GList *list;
|
||||
GList *list;
|
||||
|
||||
g_return_if_fail( fs );
|
||||
switch( fs->type ) {
|
||||
case INVALID:
|
||||
g_return_if_fail(FALSE);
|
||||
/* this is okay, just lame. */
|
||||
g_date_clear( out_date, 1 );
|
||||
break;
|
||||
|
||||
case ONCE:
|
||||
if ( g_date_compare( &(fs->s.once.date), CONST_HACK in_date ) > 0 ) {
|
||||
if ( g_date_compare( &(fs->s.once.date),
|
||||
CONST_HACK in_date ) > 0 ) {
|
||||
*out_date = fs->s.once.date;
|
||||
} else {
|
||||
/* Date is past due. Return an invalid date. */
|
||||
@@ -290,147 +294,125 @@ xaccFreqSpecGetNextInstance(
|
||||
break;
|
||||
|
||||
case DAILY: {
|
||||
guint32 julian_in_date, julian_next_repeat, complete_intervals;
|
||||
guint32 julian_in_date, julian_next_repeat, complete_intervals;
|
||||
|
||||
julian_in_date = g_date_julian( CONST_HACK in_date );
|
||||
complete_intervals =
|
||||
(julian_in_date - fs->s.daily.offset_from_epoch) /
|
||||
fs->s.daily.interval_days;
|
||||
julian_next_repeat =
|
||||
fs->s.daily.offset_from_epoch +
|
||||
(complete_intervals + 1) * fs->s.daily.interval_days;
|
||||
g_date_set_julian( out_date, julian_next_repeat );
|
||||
} break;
|
||||
julian_in_date = g_date_julian( CONST_HACK in_date );
|
||||
complete_intervals =
|
||||
(julian_in_date - fs->s.daily.offset_from_epoch) /
|
||||
fs->s.daily.interval_days;
|
||||
julian_next_repeat =
|
||||
fs->s.daily.offset_from_epoch +
|
||||
(complete_intervals + 1) * fs->s.daily.interval_days;
|
||||
g_date_set_julian( out_date, julian_next_repeat );
|
||||
} break;
|
||||
|
||||
case WEEKLY: {
|
||||
/* This implementation stores the offset from epoch as the number
|
||||
* of days, not week epoch offset and day in week offset.
|
||||
* It is very similar to the daily repeat representation. */
|
||||
guint32 julian_in_date, julian_next_repeat, complete_intervals;
|
||||
/* This implementation stores the offset from epoch as the number
|
||||
* of days, not week epoch offset and day in week offset.
|
||||
* It is very similar to the daily repeat representation. */
|
||||
guint32 julian_in_date, julian_next_repeat, complete_intervals;
|
||||
|
||||
julian_in_date = g_date_julian( CONST_HACK in_date );
|
||||
complete_intervals =
|
||||
(julian_in_date - fs->s.weekly.offset_from_epoch) /
|
||||
(fs->s.weekly.interval_weeks * 7);
|
||||
julian_next_repeat =
|
||||
fs->s.weekly.offset_from_epoch +
|
||||
(complete_intervals + 1) * fs->s.weekly.interval_weeks * 7;
|
||||
g_date_set_julian( out_date, julian_next_repeat );
|
||||
|
||||
/* This code passes the test, but it seems large and complicated...
|
||||
* it uses a separate week offset from epoch and day in week offset. */
|
||||
/* guint32 julian_in_date, julian_next_repeat, complete_intervals,
|
||||
in_weeks_from_epoch, after_repeat_in_week_interval;
|
||||
julian_in_date = g_date_julian( CONST_HACK in_date );
|
||||
in_weeks_from_epoch = (julian_in_date-1) / 7;
|
||||
complete_intervals =
|
||||
(in_weeks_from_epoch -
|
||||
fs->s.weekly.offset_from_epoch) /
|
||||
fs->s.weekly.interval_weeks;
|
||||
after_repeat_in_week_interval =
|
||||
((julian_in_date-1) % 7 >= fs->s.weekly.day_of_week ||
|
||||
(in_weeks_from_epoch - fs->s.weekly.offset_from_epoch) %
|
||||
fs->s.weekly.interval_weeks > 0 ) ? 1 : 0;
|
||||
julian_next_repeat =
|
||||
(fs->s.weekly.offset_from_epoch +
|
||||
(complete_intervals + after_repeat_in_week_interval) *
|
||||
fs->s.weekly.interval_weeks) * 7 +
|
||||
fs->s.weekly.day_of_week + 1;
|
||||
g_date_set_julian( out_date, julian_next_repeat );
|
||||
*/
|
||||
} break;
|
||||
julian_in_date = g_date_julian( CONST_HACK in_date );
|
||||
complete_intervals =
|
||||
(julian_in_date - fs->s.weekly.offset_from_epoch) /
|
||||
(fs->s.weekly.interval_weeks * 7);
|
||||
julian_next_repeat =
|
||||
fs->s.weekly.offset_from_epoch +
|
||||
(complete_intervals + 1) * fs->s.weekly.interval_weeks * 7;
|
||||
g_date_set_julian( out_date, julian_next_repeat );
|
||||
} break;
|
||||
|
||||
case MONTHLY: {
|
||||
guint32 in_months_from_epoch, after_repeat_in_month_interval,
|
||||
complete_intervals, next_repeat_months_from_epoch, month, year;
|
||||
guint32 in_months_from_epoch, after_repeat_in_month_interval,
|
||||
complete_intervals, next_repeat_months_from_epoch, month, year;
|
||||
|
||||
in_months_from_epoch = (g_date_year( CONST_HACK in_date )-1) * 12 +
|
||||
g_date_month( CONST_HACK in_date ) - 1;
|
||||
complete_intervals =
|
||||
(in_months_from_epoch - fs->s.monthly.offset_from_epoch) /
|
||||
fs->s.monthly.interval_months;
|
||||
after_repeat_in_month_interval =
|
||||
(g_date_day( CONST_HACK in_date ) >= fs->s.monthly.day_of_month ||
|
||||
(in_months_from_epoch - fs->s.monthly.offset_from_epoch) %
|
||||
fs->s.monthly.interval_months > 0 ||
|
||||
g_date_day( CONST_HACK in_date ) >=
|
||||
g_date_days_in_month( g_date_month( CONST_HACK in_date ),
|
||||
g_date_year( CONST_HACK in_date ) ) ) ? 1 : 0;
|
||||
next_repeat_months_from_epoch =
|
||||
fs->s.monthly.offset_from_epoch +
|
||||
(complete_intervals + after_repeat_in_month_interval) *
|
||||
fs->s.monthly.interval_months;
|
||||
/* Hmmm... what happens if the day of the month is greater than the
|
||||
* number of days in this month?
|
||||
* Here I have constrained the day of the month by the number
|
||||
* of days in the month. This is compensated for above by checking if
|
||||
* the input day is the last day of that month, in which case it will
|
||||
* move to the next month interval.
|
||||
*/
|
||||
month = next_repeat_months_from_epoch % 12 + 1;
|
||||
year = next_repeat_months_from_epoch / 12 + 1;
|
||||
g_date_set_dmy( out_date,
|
||||
in_months_from_epoch = (g_date_year( CONST_HACK in_date )-1) * 12 +
|
||||
g_date_month( CONST_HACK in_date ) - 1;
|
||||
complete_intervals =
|
||||
(in_months_from_epoch - fs->s.monthly.offset_from_epoch) /
|
||||
fs->s.monthly.interval_months;
|
||||
after_repeat_in_month_interval =
|
||||
(g_date_day( CONST_HACK in_date ) >= fs->s.monthly.day_of_month ||
|
||||
(in_months_from_epoch - fs->s.monthly.offset_from_epoch) %
|
||||
fs->s.monthly.interval_months > 0 ||
|
||||
g_date_day( CONST_HACK in_date ) >=
|
||||
g_date_days_in_month( g_date_month( CONST_HACK in_date ),
|
||||
g_date_year( CONST_HACK in_date ) ) ) ? 1 : 0;
|
||||
next_repeat_months_from_epoch =
|
||||
fs->s.monthly.offset_from_epoch +
|
||||
(complete_intervals + after_repeat_in_month_interval) *
|
||||
fs->s.monthly.interval_months;
|
||||
/* Hmmm... what happens if the day of the month is greater than the
|
||||
* number of days in this month?
|
||||
* Here I have constrained the day of the month by the number
|
||||
* of days in the month. This is compensated for above by checking if
|
||||
* the input day is the last day of that month, in which case it will
|
||||
* move to the next month interval.
|
||||
*/
|
||||
month = next_repeat_months_from_epoch % 12 + 1;
|
||||
year = next_repeat_months_from_epoch / 12 + 1;
|
||||
g_date_set_dmy( out_date,
|
||||
min( fs->s.monthly.day_of_month,
|
||||
g_date_days_in_month( month, year ) ),
|
||||
g_date_days_in_month( month, year ) ),
|
||||
month,
|
||||
year );
|
||||
} break;
|
||||
} break;
|
||||
|
||||
case MONTH_RELATIVE: {
|
||||
guint32 in_months_from_epoch, after_repeat_in_month_interval,
|
||||
complete_intervals, next_repeat_months_from_epoch, month, year,
|
||||
wday_of_1st, day_of_repeat;
|
||||
guint32 in_months_from_epoch, after_repeat_in_month_interval,
|
||||
complete_intervals, next_repeat_months_from_epoch, month, year,
|
||||
wday_of_1st, day_of_repeat;
|
||||
|
||||
GDate date1;
|
||||
in_months_from_epoch = (g_date_year( CONST_HACK in_date )-1) * 12 +
|
||||
g_date_month( CONST_HACK in_date ) - 1;
|
||||
complete_intervals =
|
||||
(in_months_from_epoch - fs->s.month_relative.offset_from_epoch) /
|
||||
fs->s.month_relative.interval_months;
|
||||
month = g_date_month( CONST_HACK in_date );
|
||||
year = g_date_year( CONST_HACK in_date );
|
||||
g_date_set_dmy( &date1, 1, month, year );
|
||||
wday_of_1st = g_date_weekday( &date1 );
|
||||
day_of_repeat = (fs->s.month_relative.occurrence-1)*7 +
|
||||
((fs->s.month_relative.weekday + 7 - wday_of_1st)%7 + 1);
|
||||
after_repeat_in_month_interval =
|
||||
(g_date_day( CONST_HACK in_date ) >= day_of_repeat ||
|
||||
day_of_repeat > g_date_days_in_month( month, year ) ||
|
||||
(in_months_from_epoch - fs->s.month_relative.offset_from_epoch) %
|
||||
fs->s.month_relative.interval_months > 0 ) ? 1 : 0;
|
||||
GDate date1;
|
||||
in_months_from_epoch = (g_date_year( CONST_HACK in_date )-1) * 12 +
|
||||
g_date_month( CONST_HACK in_date ) - 1;
|
||||
complete_intervals =
|
||||
(in_months_from_epoch - fs->s.month_relative.offset_from_epoch) /
|
||||
fs->s.month_relative.interval_months;
|
||||
month = g_date_month( CONST_HACK in_date );
|
||||
year = g_date_year( CONST_HACK in_date );
|
||||
g_date_set_dmy( &date1, 1, month, year );
|
||||
wday_of_1st = g_date_weekday( &date1 );
|
||||
day_of_repeat = (fs->s.month_relative.occurrence-1)*7 +
|
||||
((fs->s.month_relative.weekday + 7 - wday_of_1st)%7 + 1);
|
||||
after_repeat_in_month_interval =
|
||||
(g_date_day( CONST_HACK in_date ) >= day_of_repeat ||
|
||||
day_of_repeat > g_date_days_in_month( month, year ) ||
|
||||
(in_months_from_epoch - fs->s.month_relative.offset_from_epoch) %
|
||||
fs->s.month_relative.interval_months > 0 ) ? 1 : 0;
|
||||
next_repeat_months_from_epoch =
|
||||
fs->s.month_relative.offset_from_epoch +
|
||||
(complete_intervals + after_repeat_in_month_interval) *
|
||||
fs->s.month_relative.interval_months;
|
||||
month = next_repeat_months_from_epoch % 12 + 1;
|
||||
year = next_repeat_months_from_epoch / 12 + 1;
|
||||
g_date_set_dmy( &date1, 1, month, year );
|
||||
wday_of_1st = g_date_weekday( &date1 );
|
||||
/* This calculates the day of the month in the month which forms
|
||||
* the next month in the cycle after the given input date.
|
||||
* However, this day may be larger than the number of days in that month... */
|
||||
day_of_repeat = (fs->s.month_relative.occurrence-1)*7 +
|
||||
((fs->s.month_relative.weekday + 7 - wday_of_1st)%7 + 1);
|
||||
while( day_of_repeat > g_date_days_in_month( month, year ) ) {
|
||||
/* If the repeat occurs after the end of the month, then
|
||||
* find the next month containing a day which satisfies the request.
|
||||
* Each candiate month separated by interval_months is considered
|
||||
* by this loop.*/
|
||||
++complete_intervals;
|
||||
next_repeat_months_from_epoch =
|
||||
fs->s.month_relative.offset_from_epoch +
|
||||
(complete_intervals + after_repeat_in_month_interval) *
|
||||
fs->s.month_relative.interval_months;
|
||||
complete_intervals * fs->s.month_relative.interval_months;
|
||||
month = next_repeat_months_from_epoch % 12 + 1;
|
||||
year = next_repeat_months_from_epoch / 12 + 1;
|
||||
g_date_set_dmy( &date1, 1, month, year );
|
||||
wday_of_1st = g_date_weekday( &date1 );
|
||||
/* This calculates the day of the month in the month which forms
|
||||
* the next month in the cycle after the given input date.
|
||||
* However, this day may be larger than the number of days in that month... */
|
||||
day_of_repeat = (fs->s.month_relative.occurrence-1)*7 +
|
||||
((fs->s.month_relative.weekday + 7 - wday_of_1st)%7 + 1);
|
||||
while( day_of_repeat > g_date_days_in_month( month, year ) ) {
|
||||
/* If the repeat occurs after the end of the month, then
|
||||
* find the next month containing a day which satisfies the request.
|
||||
* Each candiate month separated by interval_months is considered
|
||||
* by this loop.*/
|
||||
++complete_intervals;
|
||||
next_repeat_months_from_epoch =
|
||||
fs->s.month_relative.offset_from_epoch +
|
||||
complete_intervals * fs->s.month_relative.interval_months;
|
||||
month = next_repeat_months_from_epoch % 12 + 1;
|
||||
year = next_repeat_months_from_epoch / 12 + 1;
|
||||
g_date_set_dmy( &date1, 1, month, year );
|
||||
wday_of_1st = g_date_weekday( &date1 );
|
||||
day_of_repeat = (fs->s.month_relative.occurrence-1)*7 +
|
||||
((fs->s.month_relative.weekday + 7 - wday_of_1st)%7 + 1);
|
||||
/* Hmmm... It would be nice to know that this loop is
|
||||
* guaranteed to terminate... CHECK ME! */
|
||||
}
|
||||
g_date_set_dmy( out_date, day_of_repeat, month, year );
|
||||
} break;
|
||||
/* Hmmm... It would be nice to know that this loop is
|
||||
* guaranteed to terminate... CHECK ME! */
|
||||
}
|
||||
g_date_set_dmy( out_date, day_of_repeat, month, year );
|
||||
} break;
|
||||
|
||||
case COMPOSITE:
|
||||
list = fs->s.composites.subSpecs;
|
||||
@@ -934,6 +916,7 @@ xaccFreqSpecGetFreqStr( FreqSpec *fs, GString *str )
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
int
|
||||
int_cmp( int a, int b )
|
||||
{
|
||||
|
||||
@@ -282,7 +282,7 @@ gnc_account_sel_set_account( GNCAccountSel *gas, Account *acct )
|
||||
}
|
||||
acctStr = xaccAccountGetFullName( acct,
|
||||
gnc_get_account_separator() );
|
||||
gtk_entry_set_text( GTK_EDITABLE(gas->combo->entry), acctStr );
|
||||
gtk_entry_set_text( GTK_ENTRY(gas->combo->entry), acctStr );
|
||||
g_free( acctStr );
|
||||
}
|
||||
|
||||
|
||||
@@ -29,12 +29,15 @@
|
||||
#include <gtk/gtk.h>
|
||||
#include "gnc-dense-cal.h"
|
||||
|
||||
/* For PERR, only... */
|
||||
#include "gnc-engine-util.h"
|
||||
|
||||
/**
|
||||
* Todo:
|
||||
* . marking
|
||||
* . color-per-marker (configurable)
|
||||
* X all-or-nothing
|
||||
* . handle errors properly
|
||||
* \ handle errors properly
|
||||
* X mouse-over -> "hottip"
|
||||
* X rotated month labels
|
||||
* X weeksPerCol -> monthsPerCol
|
||||
@@ -99,6 +102,8 @@ enum gnc_dense_cal_signal_enum {
|
||||
|
||||
static gint gnc_dense_cal_signals[LAST_SIGNAL] = { 0 };
|
||||
|
||||
static short module = MOD_SX;
|
||||
|
||||
static void gnc_dense_cal_class_init (GncDenseCalClass *class);
|
||||
static void gnc_dense_cal_init (GncDenseCal *dcal);
|
||||
static void gnc_dense_cal_destroy (GtkObject *object);
|
||||
@@ -264,8 +269,8 @@ gnc_dense_cal_init (GncDenseCal *dcal)
|
||||
dcal->weekColors,
|
||||
MAX_COLORS, TRUE, TRUE,
|
||||
&colorAllocSuccess ) > 0 ) {
|
||||
/* FIXME : handle properly */
|
||||
printf( "Error allocating colors\n" );
|
||||
/* FIXME : handle [more] properly */
|
||||
PERR( "Error allocating colors\n" );
|
||||
}
|
||||
|
||||
/* Deal with the various label sizes. */
|
||||
@@ -275,16 +280,10 @@ gnc_dense_cal_init (GncDenseCal *dcal)
|
||||
gint lbearing, rbearing, width, ascent, descent;
|
||||
|
||||
dcal->monthLabelFont = gdk_font_load( LABEL_FONT_NAME );
|
||||
if ( dcal->monthLabelFont == NULL ) {
|
||||
printf( "Couldn't load font \"%s\"\n", LABEL_FONT_NAME );
|
||||
gtk_main_quit();
|
||||
}
|
||||
g_assert( dcal->monthLabelFont );
|
||||
|
||||
dcal->dayLabelFont = GTK_WIDGET(dcal)->style->font;
|
||||
if ( dcal->dayLabelFont == NULL ) {
|
||||
printf( "Couldn't get day-label font from widget->style\n" );
|
||||
gtk_main_quit();
|
||||
}
|
||||
g_assert( dcal->dayLabelFont );
|
||||
|
||||
maxWidth = maxHeight = maxAscent = maxLBearing = 0;
|
||||
for ( i=0; i<12; i++ ) {
|
||||
@@ -370,8 +369,8 @@ gnc_dense_cal_set_month( GncDenseCal *dcal, GDateMonth mon )
|
||||
recompute_extents( dcal );
|
||||
if ( GTK_WIDGET_REALIZED( dcal ) ) {
|
||||
recompute_x_y_scales( dcal );
|
||||
gtk_widget_queue_draw( GTK_WIDGET(dcal) );
|
||||
}
|
||||
gtk_widget_queue_draw( GTK_WIDGET(dcal) );
|
||||
}
|
||||
|
||||
void
|
||||
@@ -475,7 +474,7 @@ gnc_dense_cal_size_request( GtkWidget *widget,
|
||||
{
|
||||
GncDenseCal *dcal = GNC_DENSE_CAL(widget);
|
||||
if ( !dcal->initialized ) {
|
||||
printf( "Uninitialized size request\n" );
|
||||
PERR( "Uninitialized size request\n" );
|
||||
requisition->width = DENSE_CAL_DEFAULT_WIDTH;
|
||||
requisition->height = DENSE_CAL_DEFAULT_HEIGHT;
|
||||
return;
|
||||
@@ -546,10 +545,9 @@ recompute_mark_storage( GncDenseCal *dcal )
|
||||
goto createNew;
|
||||
}
|
||||
|
||||
dcal->markData = NULL;
|
||||
for ( i=0; i<oldNumMarks; i++ ) {
|
||||
/* Each of these just contains an elt of dcal->markData,
|
||||
* which we're about to free... */
|
||||
* which we're about to free, below... */
|
||||
g_list_free( dcal->marks[i] );
|
||||
}
|
||||
g_free( dcal->marks );
|
||||
@@ -559,6 +557,7 @@ recompute_mark_storage( GncDenseCal *dcal )
|
||||
g_list_free( ((gdc_mark_data*)l->data)->ourMarks );
|
||||
g_free( (gdc_mark_data*)l->data );
|
||||
}
|
||||
g_list_free( dcal->markData );
|
||||
dcal->markData = NULL;
|
||||
|
||||
createNew:
|
||||
@@ -748,9 +747,9 @@ gnc_dense_cal_expose( GtkWidget *widget,
|
||||
|
||||
/* FIXME: use a different GC for this */
|
||||
gdk_gc_set_foreground( widget->style->fg_gc[widget->state], &markColor );
|
||||
for ( i=0; i<num_weeks(dcal)*7; i++ ) {
|
||||
l = dcal->marks[i];
|
||||
for ( ; l ; l = l->next ) {
|
||||
//for ( i=0; i<num_weeks(dcal)*7; i++ ) {
|
||||
for ( i=0; i<dcal->numMarks; i++ ) {
|
||||
for ( l = dcal->marks[i]; l ; l = l->next ) {
|
||||
gdcmd = (gdc_mark_data*)l->data;
|
||||
doc_coords( dcal, i, &x1, &y1, &x2, &y2 );
|
||||
gdk_draw_rectangle( widget->window,
|
||||
@@ -1264,27 +1263,27 @@ wheres_this( GncDenseCal *dcal, int x, int y )
|
||||
y -= dcal->topPadding;
|
||||
|
||||
if ( (x < 0) || (y < 0) ) {
|
||||
printf( "x(%d) or y(%d) < 0\n", x, y );
|
||||
PERR( "x(%d) or y(%d) < 0\n", x, y );
|
||||
return -1;
|
||||
}
|
||||
if ( (x >= GTK_WIDGET(dcal)->allocation.width)
|
||||
|| (y >= GTK_WIDGET(dcal)->allocation.height) ) {
|
||||
printf( "x(%d) > allocation.width(%d) or y(%d) > allocation->height(%d)\n",
|
||||
x, y,
|
||||
GTK_WIDGET(dcal)->allocation.width,
|
||||
GTK_WIDGET(dcal)->allocation.height );
|
||||
PERR( "x(%d) > allocation.width(%d) or y(%d) > allocation->height(%d)\n",
|
||||
x, y,
|
||||
GTK_WIDGET(dcal)->allocation.width,
|
||||
GTK_WIDGET(dcal)->allocation.height );
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* "outside of displayed table" check */
|
||||
if ( x >= (num_cols(dcal) * (col_width(dcal) + COL_BORDER_SIZE)) ) {
|
||||
printf( "x(%d) > ( col_width(%d) * num_cols(%d) )\n",
|
||||
x, col_width(dcal), num_cols(dcal) );
|
||||
PERR( "x(%d) > ( col_width(%d) * num_cols(%d) )\n",
|
||||
x, col_width(dcal), num_cols(dcal) );
|
||||
return -1;
|
||||
}
|
||||
if ( y >= col_height(dcal) ) {
|
||||
printf( "y(%d) > col_height(%d)\n",
|
||||
y, col_height(dcal) );
|
||||
PERR( "y(%d) > col_height(%d)\n",
|
||||
y, col_height(dcal) );
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -1294,17 +1293,17 @@ wheres_this( GncDenseCal *dcal, int x, int y )
|
||||
x %= (col_width(dcal)+COL_BORDER_SIZE);
|
||||
x -= dcal->label_width;
|
||||
if ( x < 0 ) {
|
||||
printf( "X is over the label.\n" );
|
||||
PERR( "X is over the label.\n" );
|
||||
return -1;
|
||||
}
|
||||
if ( x >= day_width(dcal) * 7 ) {
|
||||
printf( "X is in the col_border space.\n" );
|
||||
PERR( "X is in the col_border space.\n" );
|
||||
return -1;
|
||||
}
|
||||
|
||||
y -= dcal->dayLabelHeight;
|
||||
if ( y < 0 ) {
|
||||
printf( "Y is over the label.\n" );
|
||||
PERR( "Y is over the label.\n" );
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -1317,7 +1316,7 @@ wheres_this( GncDenseCal *dcal, int x, int y )
|
||||
dayCol -= (g_date_weekday(&d) % 7);
|
||||
if ( weekRow == 0 ) {
|
||||
if ( dayCol < 0 ) {
|
||||
printf( "Before the beginning of the first month.\n" );
|
||||
PERR( "Before the beginning of the first month.\n" );
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@@ -1329,8 +1328,8 @@ wheres_this( GncDenseCal *dcal, int x, int y )
|
||||
g_date_set_dmy( &ccd, 1, dcal->month, dcal->year );
|
||||
g_date_add_months( &ccd, (colNum+1) * dcal->monthsPerCol );
|
||||
if ( g_date_julian(&d) >= g_date_julian(&ccd) ) {
|
||||
printf( "%d outside of column range [%d]\n",
|
||||
g_date_julian(&d), g_date_julian(&ccd) );
|
||||
PERR( "%d outside of column range [%d]\n",
|
||||
g_date_julian(&d), g_date_julian(&ccd) );
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@@ -1341,8 +1340,8 @@ wheres_this( GncDenseCal *dcal, int x, int y )
|
||||
g_date_subtract_months( &d, dcal->numMonths );
|
||||
if ( g_date_julian(&d) >= g_date_julian(&startD) ) {
|
||||
/* we're past the end of the displayed calendar, thus -1 */
|
||||
printf( "%d >= %d\n",
|
||||
g_date_julian( &d ), g_date_julian( &startD ) );
|
||||
PERR( "%d >= %d\n",
|
||||
g_date_julian( &d ), g_date_julian( &startD ) );
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -1384,16 +1383,15 @@ gnc_dense_cal_mark( GncDenseCal *dcal,
|
||||
gint i, doc;
|
||||
gdc_mark_data *newMark;
|
||||
GDate *d;
|
||||
GList *l;
|
||||
|
||||
if ( size == 0 ) {
|
||||
printf( "0 size not allowed\n" );
|
||||
PERR( "0 size not allowed\n" );
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ( name == NULL
|
||||
|| strlen(name) == 0 ) {
|
||||
printf( "name must be reasonable\n" );
|
||||
PERR( "name must be reasonable\n" );
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -1410,16 +1408,10 @@ gnc_dense_cal_mark( GncDenseCal *dcal,
|
||||
d = dateArray[i];
|
||||
doc = gdc_get_doc_offset( dcal, d );
|
||||
if ( doc < 0 ) {
|
||||
#if 0 /* Silently ignore. */
|
||||
printf( "This is TheErrorThatShouldBeAppropriately"
|
||||
"Handeled @ %d for \"%s\" with %d\n",
|
||||
i, name, doc );
|
||||
#endif /* 0 */
|
||||
continue;
|
||||
}
|
||||
l = g_list_alloc();
|
||||
l->data = newMark;
|
||||
dcal->marks[doc] = g_list_concat( dcal->marks[doc], l );
|
||||
g_assert( doc < dcal->numMarks );
|
||||
dcal->marks[doc] = g_list_append( dcal->marks[doc], newMark );
|
||||
newMark->ourMarks = g_list_append( newMark->ourMarks,
|
||||
GINT_TO_POINTER(doc) );
|
||||
}
|
||||
|
||||
+866
-985
File diff suppressed because it is too large
Load Diff
@@ -52,7 +52,7 @@ typedef struct _GNCFrequency {
|
||||
|
||||
typedef struct _GNCFrequencyClass {
|
||||
GtkVBoxClass parent_class;
|
||||
void (*value_changed) (GNCFrequency *gf);
|
||||
void (*changed) (GNCFrequency *gf);
|
||||
} GNCFrequencyClass;
|
||||
|
||||
struct pageDataTuple {
|
||||
|
||||
@@ -53,6 +53,10 @@
|
||||
/* FIXME: temp until variable-related-stuff settled. */
|
||||
#include "dialog-sxsincelast.h"
|
||||
|
||||
#ifdef HAVE_LANGINFO_D_FMT
|
||||
#include <langinfo.h>
|
||||
#endif
|
||||
|
||||
static short module = MOD_SX;
|
||||
|
||||
#define SX_LIST_WIN_PREFIX "sx_list_win"
|
||||
@@ -64,6 +68,7 @@ static short module = MOD_SX;
|
||||
|
||||
#define SXED_WIN_PREFIX "sx_editor_win"
|
||||
#define SXED_NAME_ENTRY "sxe_name"
|
||||
#define SXED_LAST_OCCUR_LABEL "last_occur_label"
|
||||
#define AUTOCREATE_OPT "autocreate_opt"
|
||||
#define NOTIFY_OPT "notify_opt"
|
||||
#define ADVANCE_OPT "advance_opt"
|
||||
@@ -73,6 +78,7 @@ static short module = MOD_SX;
|
||||
#define END_DATE_DATEENTRY "sxe_end_date"
|
||||
#define END_GNOME_NUMENTRY "end_gnome_nentry"
|
||||
#define REMAIN_GNOME_NUMENTRY "remain_gnome_nentry"
|
||||
#define REMAIN_ENTRY "remain_nentry"
|
||||
|
||||
#define END_NEVER_OPTION 0
|
||||
#define END_DATE_OPTION 1
|
||||
@@ -80,6 +86,18 @@ static short module = MOD_SX;
|
||||
|
||||
#define NUM_LEDGER_LINES_DEFAULT 6
|
||||
|
||||
#define EX_CAL_NUM_MONTHS 6
|
||||
#define EX_CAL_MO_PER_COL 2
|
||||
|
||||
#ifdef HAVE_LANGINFO_D_FMT
|
||||
# define GNC_D_FMT (nl_langinfo (D_FMT))
|
||||
#else
|
||||
# define GNC_D_FMT "%Y-%m-%d"
|
||||
#endif
|
||||
|
||||
#define GNC_D_WIDTH 25
|
||||
#define GNC_D_BUF_WIDTH 26
|
||||
|
||||
/** Datatypes ***********************************************************/
|
||||
|
||||
typedef enum _EndTypeEnum {
|
||||
@@ -113,8 +131,14 @@ struct _SchedXactionEditorDialog
|
||||
GnucashRegister *reg;
|
||||
|
||||
GNCFrequency *gncfreq;
|
||||
GncDenseCal *example_cal;
|
||||
GDate **cal_marks;
|
||||
gint markId;
|
||||
|
||||
GtkEditable *nameEntry;
|
||||
|
||||
GtkLabel *lastOccurLabel;
|
||||
|
||||
GtkToggleButton *autocreateOpt;
|
||||
GtkToggleButton *notifyOpt;
|
||||
GtkToggleButton *advanceOpt;
|
||||
@@ -174,8 +198,13 @@ static void set_endgroup_toggle_states( SchedXactionEditorDialog *sxed, EndType
|
||||
static void advance_toggle( GtkButton *b, SchedXactionEditorDialog *sxed );
|
||||
static gboolean gnc_sxed_check_consistent( SchedXactionEditorDialog *sxed );
|
||||
static gboolean gnc_sxed_check_changed( SchedXactionEditorDialog *sxed );
|
||||
|
||||
static void free_keys_and_numerics_ea( gpointer key,
|
||||
gpointer value,
|
||||
gpointer user_data );
|
||||
static void gnc_sxed_save_sx( SchedXactionEditorDialog *sxed );
|
||||
static void gnc_sxed_freq_changed( GNCFrequency *gf, gpointer ud );
|
||||
static void sxed_excal_update_adapt( GtkObject *o, gpointer ud );
|
||||
static void gnc_sxed_update_cal( SchedXactionEditorDialog *sxed );
|
||||
|
||||
/* ledger standard-handlers */
|
||||
static gncUIWidget sxe_ledger_get_parent( GNCLedgerDisplay *ld );
|
||||
@@ -218,7 +247,7 @@ static
|
||||
void
|
||||
sxed_close_handler ( gpointer user_data )
|
||||
{
|
||||
SchedXactionEditorDialog *sxed = user_data;
|
||||
SchedXactionEditorDialog *sxed = user_data;
|
||||
|
||||
gnc_sxed_reg_check_close( sxed );
|
||||
gnc_sxed_record_size( sxed );
|
||||
@@ -270,22 +299,23 @@ editor_help_button_clicked(GtkButton *b, SchedXactionEditorDialog *sxed)
|
||||
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 );
|
||||
if ( !value ) {
|
||||
value = g_new0( gnc_numeric, 1 );
|
||||
}
|
||||
g_hash_table_insert( ud, key, val );
|
||||
*(gnc_numeric*)value =
|
||||
double_to_gnc_numeric( rand() + 2, 1,
|
||||
GNC_NUMERIC_RND_MASK
|
||||
| GNC_RND_FLOOR );
|
||||
g_hash_table_insert( ud, key, value );
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
free_var_numeric( gpointer key, gpointer val, gpointer ud )
|
||||
free_keys_and_numerics_ea( gpointer key, gpointer val, gpointer ud )
|
||||
{
|
||||
g_assert( key );
|
||||
g_assert( val );
|
||||
g_free( (gchar*)key );
|
||||
g_free( (gnc_numeric*)val );
|
||||
}
|
||||
|
||||
@@ -312,8 +342,8 @@ editor_ok_button_clicked( GtkButton *b, SchedXactionEditorDialog *sxed )
|
||||
}
|
||||
|
||||
/* cleanup */
|
||||
gnc_close_gui_component_by_data (DIALOG_SCHEDXACTION_EDITOR_CM_CLASS,
|
||||
sxed);
|
||||
gnc_close_gui_component_by_data( DIALOG_SCHEDXACTION_EDITOR_CM_CLASS,
|
||||
sxed );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -619,11 +649,14 @@ gnc_sxed_check_consistent( SchedXactionEditorDialog *sxed )
|
||||
|
||||
/* Subtract out pre-defined vars */
|
||||
if ( g_hash_table_lookup_extended( vars, "i",
|
||||
&unusedKey, &unusedValue ) ) {
|
||||
&unusedKey,
|
||||
&unusedValue ) ) {
|
||||
ttVarCount -= 1;
|
||||
}
|
||||
|
||||
g_hash_table_foreach( vars, free_var_numeric, (gpointer)vars );
|
||||
g_hash_table_foreach( vars,
|
||||
free_keys_and_numerics_ea,
|
||||
NULL );
|
||||
g_hash_table_destroy( vars );
|
||||
|
||||
if ( unbalanceable
|
||||
@@ -907,18 +940,19 @@ scheduledxaction_dialog_destroy(GtkObject *object, gpointer data)
|
||||
{
|
||||
SchedXactionDialog *sxd = data;
|
||||
|
||||
if (!sxd) return;
|
||||
if ( !sxd ) return;
|
||||
|
||||
gnc_unregister_gui_component_by_data
|
||||
(DIALOG_SCHEDXACTION_CM_CLASS, sxd);
|
||||
(DIALOG_SCHEDXACTION_CM_CLASS, sxd);
|
||||
|
||||
g_free(sxd);
|
||||
g_free( sxd );
|
||||
}
|
||||
|
||||
/* Local destruction of dialog */
|
||||
static void
|
||||
scheduledxaction_editor_dialog_destroy(GtkObject *object, gpointer data)
|
||||
{
|
||||
int i;
|
||||
SchedXactionEditorDialog *sxed = data;
|
||||
|
||||
if (sxed == NULL)
|
||||
@@ -928,17 +962,21 @@ scheduledxaction_editor_dialog_destroy(GtkObject *object, gpointer data)
|
||||
(DIALOG_SCHEDXACTION_EDITOR_CM_CLASS, sxed);
|
||||
|
||||
if ( sxed->newsxP ) {
|
||||
/* FIXME: WTF??? */
|
||||
xaccSchedXactionFree( sxed->sx );
|
||||
}
|
||||
sxed->sx = NULL;
|
||||
|
||||
/* FIXME:
|
||||
* . what do we need to do to clean up the reg widget?
|
||||
* . what about the rest of the dialog?
|
||||
*/
|
||||
/* We don't need to deal with the ledger, as the gncRegWidget will do
|
||||
* so for us. */
|
||||
g_free (sxed->sxGUIDstr);
|
||||
sxed->sxGUIDstr = NULL;
|
||||
|
||||
for ( i=0; i<(EX_CAL_NUM_MONTHS*31); i++ ) {
|
||||
g_free( sxed->cal_marks[i] );
|
||||
}
|
||||
g_free( sxed->cal_marks );
|
||||
|
||||
g_free (sxed);
|
||||
}
|
||||
|
||||
@@ -1037,24 +1075,6 @@ gnc_sxl_record_size( SchedXactionDialog *sxd )
|
||||
gnc_save_window_size( SX_LIST_WIN_PREFIX, w, h );
|
||||
}
|
||||
|
||||
void
|
||||
gnc_ui_scheduled_xaction_dialog_destroy(SchedXactionDialog *sxd)
|
||||
{
|
||||
if (sxd == NULL)
|
||||
return;
|
||||
gnc_close_gui_component_by_data (DIALOG_SCHEDXACTION_CM_CLASS, sxd);
|
||||
}
|
||||
|
||||
void
|
||||
gnc_ui_scheduled_xaction_editor_dialog_destroy(SchedXactionEditorDialog *sxed)
|
||||
{
|
||||
if (sxed == NULL)
|
||||
return;
|
||||
|
||||
gnc_close_gui_component_by_data
|
||||
(DIALOG_SCHEDXACTION_EDITOR_CM_CLASS, sxed);
|
||||
}
|
||||
|
||||
void
|
||||
row_select_handler( GtkCList *clist,
|
||||
gint row,
|
||||
@@ -1116,6 +1136,8 @@ gnc_sxed_get_widgets( SchedXactionEditorDialog *sxed )
|
||||
|
||||
w = glade_xml_get_widget( sxed->gxml, SXED_NAME_ENTRY );
|
||||
sxed->nameEntry = GTK_EDITABLE(w);
|
||||
w = glade_xml_get_widget( sxed->gxml, SXED_LAST_OCCUR_LABEL );
|
||||
sxed->lastOccurLabel = GTK_LABEL(w);
|
||||
w = glade_xml_get_widget( sxed->gxml, AUTOCREATE_OPT );
|
||||
sxed->autocreateOpt = GTK_TOGGLE_BUTTON(w);
|
||||
w = glade_xml_get_widget( sxed->gxml, NOTIFY_OPT );
|
||||
@@ -1167,12 +1189,15 @@ gnc_ui_scheduled_xaction_editor_dialog_create( SchedXactionDialog *sxd,
|
||||
} widgets[] = {
|
||||
{ "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) },
|
||||
|
||||
{ END_DATE_DATEENTRY, "date-changed", sxed_excal_update_adapt, NULL },
|
||||
{ REMAIN_ENTRY , "changed", sxed_excal_update_adapt, NULL },
|
||||
|
||||
{ "autocreate_opt", "toggled", autocreate_toggled, NULL },
|
||||
{ "advance_opt", "toggled", advance_toggle, (gpointer)ADVANCE_DAYS_SPIN },
|
||||
{ "remind_opt", "toggled", advance_toggle, (gpointer)REMIND_DAYS_SPIN },
|
||||
@@ -1198,6 +1223,15 @@ gnc_ui_scheduled_xaction_editor_dialog_create( SchedXactionDialog *sxd,
|
||||
sxed->sxd = sxd;
|
||||
sxed->sx = sx;
|
||||
sxed->newsxP = newSX;
|
||||
/* Setup dense-cal local mark storage */
|
||||
{
|
||||
int i;
|
||||
sxed->cal_marks = g_new0( GDate*, EX_CAL_NUM_MONTHS * 31 );
|
||||
for( i=0; i<(EX_CAL_NUM_MONTHS * 31); i++ ) {
|
||||
sxed->cal_marks[i] = g_date_new();
|
||||
}
|
||||
sxed->markId = -1;
|
||||
}
|
||||
|
||||
/* NOTE: this must occur before processing the widget list, above, so
|
||||
* the gpointers stored with the advance_ and remind_opts are
|
||||
@@ -1216,8 +1250,6 @@ gnc_ui_scheduled_xaction_editor_dialog_create( SchedXactionDialog *sxd,
|
||||
GTK_SIGNAL_FUNC(scheduledxaction_editor_dialog_destroy),
|
||||
sxed);
|
||||
|
||||
/* FIXME: want delete-event, too. [?] */
|
||||
|
||||
for ( i=0; widgets[i].name != NULL; i++ ) {
|
||||
button = glade_xml_get_widget( sxed->gxml, widgets[i].name );
|
||||
if ( widgets[i].objectData != NULL ) {
|
||||
@@ -1230,8 +1262,8 @@ gnc_ui_scheduled_xaction_editor_dialog_create( SchedXactionDialog *sxd,
|
||||
GTK_SIGNAL_FUNC( widgets[i].fn ), sxed );
|
||||
}
|
||||
|
||||
/* FIXME: For some reason the Glade-specified sensitivity settings
|
||||
* are not being honored. */
|
||||
/* For some reason the Glade-specified sensitivity settings are not
|
||||
* being honored... ? */
|
||||
gtk_widget_set_sensitive( GTK_WIDGET(sxed->notifyOpt), FALSE );
|
||||
gtk_widget_set_sensitive( GTK_WIDGET(sxed->advanceSpin), FALSE );
|
||||
gtk_widget_set_sensitive( GTK_WIDGET(sxed->remindSpin), FALSE );
|
||||
@@ -1249,7 +1281,8 @@ gnc_ui_scheduled_xaction_editor_dialog_create( SchedXactionDialog *sxd,
|
||||
}
|
||||
}
|
||||
|
||||
/* create the frequency-selection macrowidget */
|
||||
/* create the frequency-selection macrowidget and example
|
||||
* [dense-]calendar. */
|
||||
schedXact_editor_create_freq_sel( sxed );
|
||||
/* create the template-transaction ledger window */
|
||||
schedXact_editor_create_ledger( sxed );
|
||||
@@ -1276,28 +1309,26 @@ void
|
||||
schedXact_editor_create_freq_sel( SchedXactionEditorDialog *sxed )
|
||||
{
|
||||
GtkFrame *f;
|
||||
GtkBox *b;
|
||||
|
||||
f = GTK_FRAME( glade_xml_get_widget( sxed->gxml,
|
||||
"recur_frame" ) );
|
||||
|
||||
f = GTK_FRAME(glade_xml_get_widget( sxed->gxml, "gncfreq_frame" ));
|
||||
b = GTK_BOX( glade_xml_get_widget( sxed->gxml,
|
||||
"recur_box" ) );
|
||||
sxed->gncfreq =
|
||||
GNC_FREQUENCY( gnc_frequency_new( xaccSchedXactionGetFreqSpec(sxed->sx),
|
||||
xaccSchedXactionGetStartDate(sxed->sx) ) );
|
||||
if ( sxed->gncfreq == NULL ) {
|
||||
PERR( "gnc_frequency_new returned 0\n" );
|
||||
return;
|
||||
}
|
||||
g_assert( sxed->gncfreq );
|
||||
gtk_signal_connect( GTK_OBJECT(sxed->gncfreq), "changed",
|
||||
GTK_SIGNAL_FUNC(gnc_sxed_freq_changed),
|
||||
sxed );
|
||||
gtk_container_add( GTK_CONTAINER(f), GTK_WIDGET(sxed->gncfreq) );
|
||||
}
|
||||
|
||||
static void
|
||||
sxe_ledger_destroy( GNCLedgerDisplay *ld )
|
||||
{
|
||||
SchedXactionEditorDialog *sxed;
|
||||
sxed =(SchedXactionEditorDialog*)
|
||||
gnc_ledger_display_get_user_data( ld );
|
||||
DEBUG( "ledger's being destroyed... we probably want "
|
||||
"to clean up in some appropriate way." );
|
||||
f = GTK_FRAME(glade_xml_get_widget( sxed->gxml, "example_cal_frame" ));
|
||||
sxed->example_cal = GNC_DENSE_CAL(gnc_dense_cal_new());
|
||||
g_assert( sxed->example_cal );
|
||||
gnc_dense_cal_set_num_months( sxed->example_cal, EX_CAL_NUM_MONTHS );
|
||||
gnc_dense_cal_set_months_per_col( sxed->example_cal, EX_CAL_MO_PER_COL );
|
||||
gtk_container_add( GTK_CONTAINER(f), GTK_WIDGET(sxed->example_cal) );
|
||||
}
|
||||
|
||||
static
|
||||
@@ -1386,6 +1417,18 @@ schedXact_editor_populate( SchedXactionEditorDialog *sxed )
|
||||
if ( name != NULL ) {
|
||||
gtk_entry_set_text( GTK_ENTRY(sxed->nameEntry), name );
|
||||
}
|
||||
{
|
||||
gd = xaccSchedXactionGetLastOccurDate( sxed->sx );
|
||||
if ( g_date_valid( gd ) ) {
|
||||
gchar dateBuf[ GNC_D_BUF_WIDTH ];
|
||||
g_date_strftime( dateBuf, GNC_D_WIDTH, GNC_D_FMT, gd );
|
||||
gtk_label_set_text( sxed->lastOccurLabel, dateBuf );
|
||||
} else {
|
||||
gtk_label_set_text( sxed->lastOccurLabel, _( "(never)" ) );
|
||||
}
|
||||
gd = NULL;
|
||||
}
|
||||
|
||||
gd = xaccSchedXactionGetEndDate( sxed->sx );
|
||||
if ( g_date_valid( gd ) ) {
|
||||
gtk_toggle_button_set_active( sxed->optEndDate, TRUE );
|
||||
@@ -1491,6 +1534,9 @@ schedXact_editor_populate( SchedXactionEditorDialog *sxed )
|
||||
gnc_split_register_load(splitReg, splitList, NULL );
|
||||
} /* otherwise, use the existing stuff. */
|
||||
}
|
||||
|
||||
/* Update the example cal */
|
||||
gnc_sxed_update_cal( sxed );
|
||||
}
|
||||
|
||||
static
|
||||
@@ -1667,7 +1713,7 @@ void
|
||||
endgroup_rb_toggled( GtkButton *b, gpointer d )
|
||||
{
|
||||
/* figure out which one */
|
||||
SchedXactionEditorDialog *sxed;
|
||||
SchedXactionEditorDialog *sxed;
|
||||
gint id;
|
||||
|
||||
sxed = (SchedXactionEditorDialog*)d;
|
||||
@@ -1688,8 +1734,14 @@ endgroup_rb_toggled( GtkButton *b, gpointer d )
|
||||
g_error( "Unknown id %d", id );
|
||||
break;
|
||||
}
|
||||
|
||||
gnc_sxed_update_cal( sxed );
|
||||
}
|
||||
|
||||
/**
|
||||
* This is a copy of more complex code from dialog-sxsincelast.c. They
|
||||
* should probably be combined into a single useful function somewhere.
|
||||
**/
|
||||
static
|
||||
void
|
||||
generate_instances( SchedXaction *sx,
|
||||
@@ -1758,14 +1810,13 @@ putSchedXactionInDialog( gpointer data, gpointer user_data )
|
||||
generate_instances( sx, calEndDate, &instList );
|
||||
g_date_free( calEndDate );
|
||||
|
||||
/* FIXME: cleanup the date memory, here... */
|
||||
/* cleanup the date memory, here... */
|
||||
if ( instList == NULL ) {
|
||||
/* This was a bug [#90326]; while we do want to generate
|
||||
* instances within the visible calendar range, we also want
|
||||
* to generate the first, next SX instance regardless of the
|
||||
* calendar range. Thus, if the generate_instances above
|
||||
* returns nothing, double-check with the SX.
|
||||
*/
|
||||
* returns nothing, double-check with the SX. */
|
||||
nextInstDate = g_date_new();
|
||||
*nextInstDate = xaccSchedXactionGetNextInstance( sx, NULL );
|
||||
if ( g_date_valid( nextInstDate ) ) {
|
||||
@@ -1803,9 +1854,9 @@ putSchedXactionInDialog( gpointer data, gpointer user_data )
|
||||
xaccSchedXactionGetName(sx),
|
||||
freqDesc->str );
|
||||
g_string_free( freqDesc, TRUE );
|
||||
g_free( instArray );
|
||||
g_list_foreach( instList, _gnc_sxd_free_dates, NULL );
|
||||
g_list_free( instList );
|
||||
g_free( instArray );
|
||||
}
|
||||
|
||||
text[0] = xaccSchedXactionGetName( sx );
|
||||
@@ -1859,9 +1910,9 @@ static
|
||||
void
|
||||
sxed_reg_recordCB( GtkWidget *w, gpointer d )
|
||||
{
|
||||
SchedXactionEditorDialog *sxed = (SchedXactionEditorDialog*)d;
|
||||
SplitRegister *reg;
|
||||
Transaction *trans;
|
||||
SchedXactionEditorDialog *sxed = (SchedXactionEditorDialog*)d;
|
||||
SplitRegister *reg;
|
||||
Transaction *trans;
|
||||
|
||||
reg = gnc_ledger_display_get_split_register( sxed->ledger );
|
||||
trans = gnc_split_register_get_current_trans( reg );
|
||||
@@ -1910,7 +1961,8 @@ gnc_sxed_reg_check_close(SchedXactionEditorDialog *sxed)
|
||||
pending_changes = gnc_split_register_changed (reg);
|
||||
if (pending_changes) {
|
||||
const char *message =
|
||||
_("The current template transaction has been changed.\n"
|
||||
_("The current template transaction "
|
||||
"has been changed.\n"
|
||||
"Would you like to record the changes?");
|
||||
if (gnc_verify_dialog_parented(sxed->dialog, TRUE, message)) {
|
||||
sxed_reg_recordCB(sxed->dialog, sxed);
|
||||
@@ -1947,7 +1999,8 @@ gnc_sxd_row_click_handler( GtkCList *clist,
|
||||
sxd->currentSortType = GTK_SORT_ASCENDING;
|
||||
break;
|
||||
default:
|
||||
PERR( "Unknown current sort type %d", sxd->currentSortType );
|
||||
PERR( "Unknown current sort type %d",
|
||||
sxd->currentSortType );
|
||||
}
|
||||
/* By defn, the current sort_compare method is correct. */
|
||||
gtk_clist_set_sort_column( clist, col );
|
||||
@@ -1985,7 +2038,9 @@ gnc_sxd_clist_compare_sx_name( GtkCList *cl, gconstpointer a, gconstpointer b )
|
||||
|
||||
static
|
||||
gint
|
||||
gnc_sxd_clist_compare_sx_freq( GtkCList *cl, gconstpointer a, gconstpointer b )
|
||||
gnc_sxd_clist_compare_sx_freq( GtkCList *cl,
|
||||
gconstpointer a,
|
||||
gconstpointer b )
|
||||
{
|
||||
SchedXaction *sxa, *sxb;
|
||||
|
||||
@@ -2042,22 +2097,143 @@ static
|
||||
void
|
||||
gnc_sxd_set_sort_compare( GtkCList *cl, gint col )
|
||||
{
|
||||
gint (*fn)( GtkCList *, gconstpointer, gconstpointer );
|
||||
|
||||
fn = NULL;
|
||||
switch ( col ) {
|
||||
case 0: /* SX name */
|
||||
gtk_clist_set_compare_func( cl, NULL );
|
||||
gtk_clist_set_compare_func( cl, gnc_sxd_clist_compare_sx_name );
|
||||
fn = gnc_sxd_clist_compare_sx_name;
|
||||
break;
|
||||
case 1: /* SX frequency */
|
||||
gtk_clist_set_compare_func( cl, NULL );
|
||||
gtk_clist_set_compare_func( cl, gnc_sxd_clist_compare_sx_freq );
|
||||
fn = gnc_sxd_clist_compare_sx_freq;
|
||||
break;
|
||||
case 2: /* next-occur date */
|
||||
gtk_clist_set_compare_func( cl, NULL );
|
||||
gtk_clist_set_compare_func(
|
||||
cl, gnc_sxd_clist_compare_sx_next_occur );
|
||||
fn = gnc_sxd_clist_compare_sx_next_occur;
|
||||
break;
|
||||
default: /* ?? */
|
||||
DEBUG( "invalid column value %d", col );
|
||||
g_assert( FALSE );
|
||||
}
|
||||
gtk_clist_set_compare_func( cl, NULL );
|
||||
gtk_clist_set_compare_func( cl, fn );
|
||||
}
|
||||
|
||||
typedef enum { NO_END, DATE_END, COUNT_END } END_TYPE;
|
||||
|
||||
static
|
||||
void
|
||||
gnc_sxed_update_cal( SchedXactionEditorDialog *sxed )
|
||||
{
|
||||
int i;
|
||||
FreqSpec *fs;
|
||||
GDate d;
|
||||
END_TYPE endType;
|
||||
GDate endDate;
|
||||
int numRemain;
|
||||
|
||||
endType = NO_END;
|
||||
numRemain = -1;
|
||||
/* figure out the end restriction */
|
||||
if ( gtk_toggle_button_get_active( sxed->optEndDate ) ) {
|
||||
time_t tt;
|
||||
struct tm *tmpTm;
|
||||
endType = DATE_END;
|
||||
tt = gnome_date_edit_get_date( sxed->endDateEntry );
|
||||
tmpTm = g_new0( struct tm, 1 );
|
||||
*tmpTm = *(localtime( &tt ));
|
||||
g_date_set_day( &endDate, tmpTm->tm_mday );
|
||||
g_date_set_month( &endDate, tmpTm->tm_mon+1 );
|
||||
g_date_set_year( &endDate, tmpTm->tm_year + 1900 );
|
||||
g_free( tmpTm );
|
||||
} else if ( gtk_toggle_button_get_active( sxed->optEndNone ) ) {
|
||||
endType = NO_END;
|
||||
} else if ( gtk_toggle_button_get_active( sxed->optEndCount ) ) {
|
||||
endType = COUNT_END;
|
||||
numRemain =
|
||||
(gint)gnome_number_entry_get_number(
|
||||
sxed->endRemainEntry );
|
||||
} else {
|
||||
g_assert( FALSE );
|
||||
}
|
||||
|
||||
if ( sxed->markId != -1 ) {
|
||||
gnc_dense_cal_mark_remove( sxed->example_cal, sxed->markId );
|
||||
sxed->markId = -1;
|
||||
}
|
||||
|
||||
fs = xaccFreqSpecMalloc( gnc_get_current_book() );
|
||||
gnc_frequency_save_state( sxed->gncfreq, fs, &d );
|
||||
g_date_subtract_days( &d, 1 );
|
||||
xaccFreqSpecGetNextInstance( fs, &d, &d );
|
||||
|
||||
/* Deal with the fact that this SX may have been run before [the
|
||||
* calendar should only show upcoming instances]... */
|
||||
{
|
||||
GDate *lastInst;
|
||||
|
||||
lastInst = xaccSchedXactionGetLastOccurDate( sxed->sx );
|
||||
if ( g_date_valid( lastInst )
|
||||
&& g_date_compare( lastInst, &d ) <= 0 ) {
|
||||
d = *lastInst;
|
||||
}
|
||||
xaccFreqSpecGetNextInstance( fs, &d, &d );
|
||||
}
|
||||
|
||||
if ( !g_date_valid( &d ) ) {
|
||||
/* Nothing to do. */
|
||||
xaccFreqSpecFree( fs );
|
||||
return;
|
||||
}
|
||||
|
||||
i = 0;
|
||||
gnc_dense_cal_set_month( sxed->example_cal,
|
||||
g_date_month( &d ) );
|
||||
gnc_dense_cal_set_year( sxed->example_cal,
|
||||
g_date_year( &d ) );
|
||||
while ( (i < EX_CAL_NUM_MONTHS * 31)
|
||||
&& g_date_valid( &d )
|
||||
/* Restrict based on end date */
|
||||
&& ( endType == NO_END
|
||||
|| ( endType == DATE_END
|
||||
&& g_date_compare( &d, &endDate ) <= 0 )
|
||||
|| ( endType == COUNT_END
|
||||
&& i < numRemain ) ) ) {
|
||||
*(sxed->cal_marks[i++]) = d;
|
||||
xaccFreqSpecGetNextInstance( fs, &d, &d );
|
||||
}
|
||||
if ( i <= 0 ) {
|
||||
xaccFreqSpecFree( fs );
|
||||
return;
|
||||
}
|
||||
|
||||
{
|
||||
gchar *name;
|
||||
GString *info;
|
||||
|
||||
name = gtk_editable_get_chars( sxed->nameEntry, 0, -1 );
|
||||
info = g_string_sized_new( 16 );
|
||||
xaccFreqSpecGetFreqStr( fs, info );
|
||||
sxed->markId = gnc_dense_cal_mark( sxed->example_cal, i,
|
||||
sxed->cal_marks,
|
||||
name, info->str );
|
||||
gtk_widget_queue_draw( GTK_WIDGET( sxed->example_cal ) );
|
||||
g_free( name );
|
||||
g_string_free( info, TRUE );
|
||||
}
|
||||
|
||||
xaccFreqSpecFree( fs );
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
gnc_sxed_freq_changed( GNCFrequency *gf, gpointer ud )
|
||||
{
|
||||
gnc_sxed_update_cal( (SchedXactionEditorDialog*)ud );
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
sxed_excal_update_adapt( GtkObject *o, gpointer ud )
|
||||
{
|
||||
gnc_sxed_update_cal( (SchedXactionEditorDialog*)ud );
|
||||
}
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
#include "gnc-book-p.h"
|
||||
#include "gnc-engine-util.h"
|
||||
#include "gnc-ui-util.h"
|
||||
#include "gnc-dense-cal.h"
|
||||
|
||||
#define SX_GLADE_FILE "sched-xact.glade"
|
||||
#define SXFTD_DIALOG_GLADE_NAME "sx_from_real_trans"
|
||||
@@ -50,6 +51,10 @@
|
||||
#define SXFTD_FREQ_OPTION_MENU "freq_option_menu"
|
||||
#define SXFTD_END_DATE_EDIT "end_date_edit"
|
||||
#define SXFTD_START_DATE_EDIT "start_date_edit"
|
||||
#define SXFTD_EX_CAL_FRAME "ex_cal_frame"
|
||||
|
||||
#define SXFTD_EXCAL_NUM_MONTHS 4
|
||||
#define SXFTD_EXCAL_MONTHS_PER_COL 4
|
||||
|
||||
static short module = MOD_SX;
|
||||
|
||||
@@ -57,17 +62,19 @@ static void sxftd_ok_clicked(GtkWidget *w, gpointer user_data);
|
||||
static void sxftd_freq_option_changed( GtkWidget *w, gpointer user_data );
|
||||
static void sxftd_advanced_clicked(GtkWidget *w, gpointer user_data);
|
||||
static void sxftd_cancel_clicked(GtkWidget *w, gpointer user_data);
|
||||
static void sxftd_destroy( GtkWidget *w, gpointer user_data );
|
||||
|
||||
typedef enum {NEVER_END, END_ON_DATE, END_AFTER_N_OCCS, BAD_END} endType;
|
||||
typedef enum { NEVER_END, END_ON_DATE, END_AFTER_N_OCCS, BAD_END } endType;
|
||||
|
||||
typedef enum {FREQ_DAILY = 0, /* I know the =0 is redundant, but I'm using
|
||||
* the numeric equivalences explicitly here
|
||||
*/
|
||||
FREQ_WEEKLY,
|
||||
FREQ_BIWEEKLY,
|
||||
FREQ_MONTHLY,
|
||||
FREQ_QUARTERLY,
|
||||
FREQ_ANNUALLY } SxftiFreqType;
|
||||
typedef enum { FREQ_DAILY = 0, /* I know the =0 is redundant, but I'm using
|
||||
* the numeric equivalences explicitly here
|
||||
*/
|
||||
FREQ_WEEKLY,
|
||||
FREQ_BIWEEKLY,
|
||||
FREQ_MONTHLY,
|
||||
FREQ_QUARTERLY,
|
||||
FREQ_ANNUALLY
|
||||
} SxftiFreqType;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
@@ -75,8 +82,14 @@ typedef struct
|
||||
GtkWidget *dialog;
|
||||
Transaction *trans;
|
||||
SchedXaction *sx;
|
||||
} SXFromTransInfo;
|
||||
|
||||
GncDenseCal *example_cal;
|
||||
/** Storage for the maximum possible number of marks we could put on the
|
||||
* calendar. */
|
||||
GDate **cal_marks;
|
||||
gint mark_id;
|
||||
|
||||
} SXFromTransInfo;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
@@ -85,6 +98,9 @@ typedef struct
|
||||
guint n_occurrences;
|
||||
} getEndTuple;
|
||||
|
||||
static void sxftd_update_example_cal( SXFromTransInfo *sxfti );
|
||||
static void sxftd_update_excal_adapt( GtkObject *o, gpointer ud );
|
||||
|
||||
/* Stolen from jsled - nice and neat, actually (if a little light on
|
||||
* for typechecking, but we'll be careful) . . .
|
||||
*/
|
||||
@@ -94,16 +110,26 @@ typedef struct
|
||||
gchar *signal;
|
||||
void (*handlerFn)();
|
||||
} widgetSignalHandlerTuple;
|
||||
|
||||
|
||||
static void
|
||||
sxfti_attach_callbacks(SXFromTransInfo *sxfti)
|
||||
{
|
||||
|
||||
widgetSignalHandlerTuple callbacks[] =
|
||||
{
|
||||
/* Whenever any of the controls change, we want to update the
|
||||
* calendar. */
|
||||
{ SXFTD_START_DATE_EDIT, "date-changed", sxftd_update_excal_adapt },
|
||||
{ SXFTD_NEVER_END_BUTTON, "clicked", sxftd_update_excal_adapt },
|
||||
{ SXFTD_END_ON_DATE_BUTTON, "clicked", sxftd_update_excal_adapt },
|
||||
{ SXFTD_END_DATE_EDIT, "date-changed", sxftd_update_excal_adapt },
|
||||
{ SXFTD_N_OCCURRENCES_BUTTON, "clicked", sxftd_update_excal_adapt },
|
||||
{ SXFTD_N_OCCURRENCES_ENTRY, "changed", sxftd_update_excal_adapt },
|
||||
|
||||
{ SXFTD_OK_BUTTON, "clicked", sxftd_ok_clicked },
|
||||
{ SXFTD_ADVANCED_BUTTON, "clicked", sxftd_advanced_clicked },
|
||||
{ SXFTD_CANCEL_BUTTON, "clicked", sxftd_cancel_clicked },
|
||||
|
||||
{ NULL, NULL, NULL }
|
||||
};
|
||||
|
||||
@@ -116,11 +142,8 @@ sxfti_attach_callbacks(SXFromTransInfo *sxfti)
|
||||
|
||||
gtk_signal_connect( GTK_OBJECT(w), callbacks[i].signal,
|
||||
GTK_SIGNAL_FUNC(callbacks[i].handlerFn),
|
||||
sxfti);
|
||||
|
||||
sxfti );
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -285,6 +308,7 @@ sxftd_update_fs( SXFromTransInfo *sxfti, GDate *date, FreqSpec *fs )
|
||||
|
||||
default:
|
||||
PERR("Nonexistent frequency selected. This is a bug.");
|
||||
g_assert( FALSE );
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -309,6 +333,24 @@ sxftd_init( SXFromTransInfo *sxfti )
|
||||
|
||||
sxfti_attach_callbacks(sxfti);
|
||||
|
||||
/* Setup the example calendar and related data structures. */
|
||||
{
|
||||
int i;
|
||||
|
||||
w = GTK_WIDGET(glade_xml_get_widget( sxfti->gxml, SXFTD_EX_CAL_FRAME ));
|
||||
sxfti->example_cal = GNC_DENSE_CAL(gnc_dense_cal_new());
|
||||
g_assert( sxfti->example_cal );
|
||||
gnc_dense_cal_set_num_months( sxfti->example_cal, SXFTD_EXCAL_NUM_MONTHS );
|
||||
gnc_dense_cal_set_months_per_col( sxfti->example_cal, SXFTD_EXCAL_MONTHS_PER_COL );
|
||||
gtk_container_add( GTK_CONTAINER(w), GTK_WIDGET(sxfti->example_cal) );
|
||||
|
||||
sxfti->mark_id = -1;
|
||||
sxfti->cal_marks = g_new0( GDate*, (SXFTD_EXCAL_NUM_MONTHS * 31) );
|
||||
for ( i=0; i < SXFTD_EXCAL_NUM_MONTHS * 31; i++ ) {
|
||||
sxfti->cal_marks[i] = g_date_new();
|
||||
}
|
||||
}
|
||||
|
||||
/* Get the name from the transaction, try that as the initial SX name. */
|
||||
transName = xaccTransGetDescription( sxfti->trans );
|
||||
xaccSchedXactionSetName( sxfti->sx, transName );
|
||||
@@ -342,6 +384,11 @@ sxftd_init( SXFromTransInfo *sxfti )
|
||||
gtk_signal_connect( GTK_OBJECT(w), "selection-done",
|
||||
GTK_SIGNAL_FUNC(sxftd_freq_option_changed),
|
||||
sxfti );
|
||||
gtk_signal_connect( GTK_OBJECT(w), "destroy",
|
||||
GTK_SIGNAL_FUNC(sxftd_destroy),
|
||||
sxfti );
|
||||
|
||||
sxftd_update_example_cal( sxfti );
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -404,19 +451,18 @@ sxftd_compute_sx(SXFromTransInfo *sxfti)
|
||||
return sxftd_errno;
|
||||
}
|
||||
|
||||
static void
|
||||
sxftd_delete(SXFromTransInfo *sxfti, gboolean delete_sx)
|
||||
static
|
||||
void
|
||||
sxftd_close(SXFromTransInfo *sxfti, gboolean delete_sx)
|
||||
{
|
||||
|
||||
/* FIXME: do we need to clean up the GladeXML pointer ?*/
|
||||
gnome_dialog_close( GNOME_DIALOG(sxfti->dialog));
|
||||
|
||||
if(sxfti->sx && delete_sx)
|
||||
if ( sxfti->sx && delete_sx )
|
||||
{
|
||||
xaccSchedXactionFree(sxfti->sx);
|
||||
}
|
||||
sxfti->sx = NULL;
|
||||
|
||||
gnome_dialog_close( GNOME_DIALOG(sxfti->dialog));
|
||||
|
||||
g_free(sxfti);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -447,7 +493,7 @@ sxftd_ok_clicked(GtkWidget *w, gpointer user_data)
|
||||
}
|
||||
}
|
||||
|
||||
sxftd_delete(sxfti, FALSE);
|
||||
sxftd_close(sxfti, FALSE);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -479,13 +525,16 @@ sxftd_freq_option_changed( GtkWidget *w, gpointer user_data )
|
||||
tmp_tt = mktime( tmpTm );
|
||||
g_free( tmpTm );
|
||||
gnome_date_edit_set_time( GNOME_DATE_EDIT(start_date), tmp_tt );
|
||||
|
||||
xaccFreqSpecFree( fs );
|
||||
sxftd_update_example_cal( sxfti );
|
||||
}
|
||||
|
||||
static void
|
||||
sxftd_cancel_clicked(GtkWidget *w, gpointer user_data)
|
||||
{
|
||||
SXFromTransInfo *sxfti = user_data;
|
||||
sxftd_delete(sxfti, TRUE);
|
||||
sxftd_close(sxfti, TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -506,16 +555,17 @@ sxftd_advanced_clicked(GtkWidget *w, gpointer user_data)
|
||||
while (g_main_iteration(FALSE));
|
||||
|
||||
adv_dlg = gnc_ui_scheduled_xaction_dialog_create();
|
||||
adv_edit_dlg = gnc_ui_scheduled_xaction_editor_dialog_create(adv_dlg,
|
||||
sxfti->sx,
|
||||
TRUE /* newSX */);
|
||||
adv_edit_dlg =
|
||||
gnc_ui_scheduled_xaction_editor_dialog_create(adv_dlg,
|
||||
sxfti->sx,
|
||||
TRUE /* newSX */);
|
||||
/* close ourself, since advanced editing entails us, and there are sync
|
||||
* issues otherwise. */
|
||||
sxftd_delete(sxfti, FALSE);
|
||||
sxftd_close(sxfti, FALSE);
|
||||
}
|
||||
|
||||
void
|
||||
gnc_sx_create_from_trans(Transaction *trans)
|
||||
gnc_sx_create_from_trans( Transaction *trans )
|
||||
{
|
||||
int errno;
|
||||
SXFromTransInfo *sxfti = g_new0( SXFromTransInfo, 1);
|
||||
@@ -538,3 +588,110 @@ gnc_sx_create_from_trans(Transaction *trans)
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
sxftd_destroy( GtkWidget *w, gpointer user_data )
|
||||
{
|
||||
int i;
|
||||
SXFromTransInfo *sxfti = (SXFromTransInfo*)user_data;
|
||||
|
||||
for ( i=0; i<SXFTD_EXCAL_NUM_MONTHS*31; i++ ) {
|
||||
g_date_free( sxfti->cal_marks[i] );
|
||||
}
|
||||
g_free( sxfti->cal_marks );
|
||||
|
||||
if ( sxfti->sx ) {
|
||||
xaccSchedXactionFree(sxfti->sx);
|
||||
sxfti->sx = NULL;
|
||||
}
|
||||
|
||||
/* FIXME: do we need to clean up the GladeXML pointer? */
|
||||
|
||||
g_free(sxfti);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the example calendar; make sure to take into account the end
|
||||
* specification.
|
||||
**/
|
||||
static
|
||||
void
|
||||
sxftd_update_example_cal( SXFromTransInfo *sxfti )
|
||||
{
|
||||
GtkWidget *start_date;
|
||||
struct tm *tmpTm;
|
||||
time_t tmp_tt;
|
||||
GDate date, startDate;
|
||||
int i;
|
||||
FreqSpec *fs;
|
||||
getEndTuple get;
|
||||
gchar *name;
|
||||
GString *info;
|
||||
|
||||
i = 0;
|
||||
fs = xaccFreqSpecMalloc( gnc_get_current_book() );
|
||||
get = sxftd_get_end_info( sxfti );
|
||||
|
||||
start_date = glade_xml_get_widget( sxfti->gxml, SXFTD_START_DATE_EDIT );
|
||||
tmp_tt = gnome_date_edit_get_date( GNOME_DATE_EDIT(start_date) );
|
||||
tmpTm = g_new0( struct tm, 1 );
|
||||
*tmpTm = *localtime( &tmp_tt );
|
||||
/* go one day before what's in the box so we can get the correct start
|
||||
* date. */
|
||||
g_date_set_day( &date, tmpTm->tm_mday-1 );
|
||||
g_date_set_month( &date, tmpTm->tm_mon+1 );
|
||||
g_date_set_year( &date, tmpTm->tm_year+1900 );
|
||||
g_free( tmpTm );
|
||||
|
||||
sxftd_update_fs( sxfti, &date, fs );
|
||||
xaccFreqSpecGetNextInstance( fs, &date, &date );
|
||||
startDate = date;
|
||||
|
||||
while ( (i < (SXFTD_EXCAL_NUM_MONTHS * 31))
|
||||
&& g_date_valid( &date )
|
||||
/* Do checking against end restriction. */
|
||||
&& ( ( get.type == NEVER_END )
|
||||
|| ( get.type == END_ON_DATE
|
||||
&& g_date_compare( &date, &(get.end_date) ) <= 0 )
|
||||
|| ( get.type == END_AFTER_N_OCCS
|
||||
&& i < get.n_occurrences ) ) ) {
|
||||
|
||||
*sxfti->cal_marks[i++] = date;
|
||||
xaccFreqSpecGetNextInstance( fs, &date, &date );
|
||||
}
|
||||
/* remove old marks */
|
||||
if ( sxfti->mark_id != -1 ) {
|
||||
gnc_dense_cal_mark_remove( sxfti->example_cal, sxfti->mark_id );
|
||||
sxfti->mark_id = -1;
|
||||
}
|
||||
if ( i > 0 ) {
|
||||
GtkWidget *w;
|
||||
gnc_dense_cal_set_month( sxfti->example_cal,
|
||||
g_date_month( &startDate ) );
|
||||
gnc_dense_cal_set_year( sxfti->example_cal,
|
||||
g_date_year( &startDate ) );
|
||||
w = glade_xml_get_widget( sxfti->gxml, SXFTD_NAME_ENTRY );
|
||||
name = gtk_editable_get_chars( GTK_EDITABLE(w), 0, -1 );
|
||||
info = g_string_sized_new( 16 );
|
||||
xaccFreqSpecGetFreqStr( fs, info );
|
||||
sxfti->mark_id =
|
||||
gnc_dense_cal_mark( sxfti->example_cal,
|
||||
i, sxfti->cal_marks,
|
||||
name, info->str );
|
||||
gtk_widget_queue_draw( GTK_WIDGET(sxfti->example_cal) );
|
||||
g_free( name );
|
||||
g_string_free( info, TRUE );
|
||||
}
|
||||
|
||||
xaccFreqSpecFree( fs );
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
void
|
||||
sxftd_update_excal_adapt( GtkObject *o, gpointer ud )
|
||||
{
|
||||
SXFromTransInfo *sxfti = (SXFromTransInfo*)ud;
|
||||
sxftd_update_example_cal( sxfti );
|
||||
}
|
||||
|
||||
@@ -102,6 +102,8 @@
|
||||
#define REMINDER_LIST "reminders_list"
|
||||
#define SX_GLADE_FILE "sched-xact.glade"
|
||||
|
||||
#define TO_CREATE_STATUS "to_create_status"
|
||||
|
||||
#define SELECT_ALL_BUTTON "select_all_button"
|
||||
#define UNSELECT_ALL_BUTTON "unselect_all_button"
|
||||
#define OK_BUTTON "ok_button"
|
||||
@@ -157,6 +159,8 @@ typedef struct _sxSinceLastData {
|
||||
GladeXML *gxml;
|
||||
|
||||
GtkProgressBar *prog;
|
||||
GtkStatusbar *toCreateStatus;
|
||||
guint statusCtxId;
|
||||
|
||||
/* Multi-stage processing-related stuff... */
|
||||
GList /* <toCreateTuple*> */ *autoCreateList;
|
||||
@@ -1238,6 +1242,17 @@ sxsincelast_init( sxSinceLastData *sxsld )
|
||||
sxsld->prog = GTK_PROGRESS_BAR(glade_xml_get_widget( sxsld->gxml,
|
||||
WHAT_TO_DO_PROGRESS ));
|
||||
|
||||
sxsld->toCreateStatus =
|
||||
GTK_STATUSBAR(
|
||||
glade_xml_get_widget( sxsld->gxml, TO_CREATE_STATUS ) );
|
||||
sxsld->statusCtxId =
|
||||
gtk_statusbar_get_context_id( sxsld->toCreateStatus,
|
||||
/* Sure, we're overusing this
|
||||
* string, but I don't see why
|
||||
* the Statusbar even
|
||||
* cares... */
|
||||
TO_CREATE_STATUS );
|
||||
|
||||
create_autoCreate_ledger( sxsld );
|
||||
create_created_ledger( sxsld );
|
||||
|
||||
@@ -1356,8 +1371,8 @@ generate_instances( SchedXaction *sx,
|
||||
static void
|
||||
_free_varBindings_hash_elts( gpointer key, gpointer value, gpointer data )
|
||||
{
|
||||
if ( key )
|
||||
g_free( key );
|
||||
g_assert( key );
|
||||
g_free( key );
|
||||
if ( value )
|
||||
g_free( value );
|
||||
}
|
||||
@@ -1791,9 +1806,10 @@ static void
|
||||
andequal_numerics_set( gpointer key, gpointer value, gpointer data )
|
||||
{
|
||||
gboolean *allVarsBound = data;
|
||||
if ( strcmp( (gchar*)key, "i" ) != 0 ) {
|
||||
*allVarsBound &= (value != NULL);
|
||||
if ( strcmp( (gchar*)key, "i" ) == 0 ) {
|
||||
return;
|
||||
}
|
||||
*allVarsBound &= (value != NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1805,6 +1821,8 @@ sxsincelast_entry_changed( GtkEditable *e, gpointer ud )
|
||||
gchar *entryText;
|
||||
gnc_numeric *num, *ourNum;
|
||||
GHashTable *dummyVarHash;
|
||||
static const int MSG_BUF_LEN = 127;
|
||||
char msgBuf[MSG_BUF_LEN+1];
|
||||
|
||||
sxsld = (sxSinceLastData*)ud;
|
||||
tci = (toCreateInstance*)gtk_object_get_data( GTK_OBJECT(e), "tci" );
|
||||
@@ -1812,27 +1830,48 @@ sxsincelast_entry_changed( GtkEditable *e, gpointer ud )
|
||||
num = (gnc_numeric*)gtk_object_get_data( GTK_OBJECT(e), "numeric" );
|
||||
entryText = gtk_editable_get_chars( e, 0, -1 );
|
||||
dummyVarHash = g_hash_table_new( NULL, NULL );
|
||||
/* FIXME: these debugs probably want to go into a staus bar... */
|
||||
/* FIXME: Should be using xaccParseAmount instead of parser_parse_separate_vars? */
|
||||
/* FIXME?: Should be using xaccParseAmount instead of
|
||||
* parser_parse_separate_vars? */
|
||||
gtk_statusbar_pop( sxsld->toCreateStatus, sxsld->statusCtxId );
|
||||
|
||||
if ( !gnc_exp_parser_parse_separate_vars( entryText, num,
|
||||
NULL, dummyVarHash ) ) {
|
||||
DEBUG( "error parsing entry \"%s\"", entryText );
|
||||
num = NULL;
|
||||
if ( entryText != NULL
|
||||
&& strlen(entryText) > 0 ) {
|
||||
snprintf( msgBuf, MSG_BUF_LEN,
|
||||
"error parsing entry near \"%s\"", entryText );
|
||||
gtk_statusbar_push( sxsld->toCreateStatus,
|
||||
sxsld->statusCtxId,
|
||||
msgBuf );
|
||||
}
|
||||
} else if ( g_hash_table_size( dummyVarHash ) != 0 ) {
|
||||
DEBUG( "no new variables allowed in variable "
|
||||
"bindings for expression \"%s\"", entryText );
|
||||
num = NULL;
|
||||
snprintf( msgBuf, MSG_BUF_LEN,
|
||||
"No new variables allowed in "
|
||||
"expression \"%s\"", entryText );
|
||||
gtk_statusbar_push( sxsld->toCreateStatus,
|
||||
sxsld->statusCtxId,
|
||||
msgBuf );
|
||||
} else if ( gnc_numeric_check( *num ) != GNC_ERROR_OK ) {
|
||||
DEBUG( "entry \"%s\" is not "
|
||||
"gnc_numeric-parseable", entryText );
|
||||
snprintf( msgBuf, MSG_BUF_LEN,
|
||||
"Entry \"%s\" is not "
|
||||
"parseable", entryText );
|
||||
gtk_statusbar_push( sxsld->toCreateStatus,
|
||||
sxsld->statusCtxId,
|
||||
msgBuf );
|
||||
num = NULL;
|
||||
} else {
|
||||
#if 0 /* 0 -- this is fine. */
|
||||
DEBUG( "\"%s\" parses as \"%f\"", entryText,
|
||||
gnc_numeric_to_double( *num ) );
|
||||
#endif /* 0 -- this is fine. */
|
||||
snprintf( msgBuf, MSG_BUF_LEN,
|
||||
"%f", gnc_numeric_to_double( *num ) );
|
||||
gtk_statusbar_push( sxsld->toCreateStatus,
|
||||
sxsld->statusCtxId,
|
||||
msgBuf );
|
||||
}
|
||||
|
||||
g_hash_table_foreach( dummyVarHash,
|
||||
_free_varBindings_hash_elts,
|
||||
NULL );
|
||||
g_hash_table_destroy( dummyVarHash );
|
||||
|
||||
{
|
||||
@@ -1875,9 +1914,8 @@ sxsincelast_destroy( GtkObject *o, gpointer ud )
|
||||
/* appropriate place to destroy data structures */
|
||||
clean_sincelast_data( sxsld );
|
||||
|
||||
/* FIXME: need more freeing for ledgers? why do these result in
|
||||
* "gnc_close_gui_component: component not found" messages? */
|
||||
|
||||
/* We don't need to close the ledgers, as the gnc-reg-widget will do
|
||||
* this for us. */
|
||||
gnc_ledger_display_close( sxsld->ac_ledger );
|
||||
sxsld->ac_ledger = NULL;
|
||||
|
||||
@@ -1925,7 +1963,6 @@ gnc_sxsl_del_vars_table_ea( gpointer key,
|
||||
g_assert( key );
|
||||
if ( key )
|
||||
g_free( (gchar*)key );
|
||||
|
||||
if ( value )
|
||||
g_free( (gnc_numeric*)value );
|
||||
}
|
||||
@@ -2376,10 +2413,10 @@ sxsincelast_tc_row_sel( GtkCTree *ct,
|
||||
* variables if they're present in the expression. */
|
||||
varHashSize = g_hash_table_size( tci->varBindings );
|
||||
{
|
||||
gpointer *foo, *bar;
|
||||
gpointer *unusedKey, *unusedVal;
|
||||
if ( g_hash_table_lookup_extended( tci->varBindings, "i",
|
||||
(gpointer)&foo,
|
||||
(gpointer)&bar ) ) {
|
||||
(gpointer)&unusedKey,
|
||||
(gpointer)&unusedVal ) ) {
|
||||
varHashSize -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
+36
-7
@@ -257,6 +257,8 @@ static void ld_cancel_check( GnomeDruid *gd, LoanDruidData *ldd );
|
||||
|
||||
static void ld_prm_type_changed( GtkWidget *w, gint index, gpointer ud );
|
||||
|
||||
static void gnc_loan_druid_length_changed( GtkEditable *e, gpointer ud );
|
||||
|
||||
static void ld_escrow_toggle( GtkToggleButton *tb, gpointer ud );
|
||||
static void ld_opt_toggled( GtkToggleButton *tb, gpointer ud );
|
||||
static void ld_opt_consistency( GtkToggleButton *tb, gpointer ud );
|
||||
@@ -302,11 +304,13 @@ gnc_ui_sx_loan_druid_create()
|
||||
{
|
||||
int i;
|
||||
GtkAlignment *a;
|
||||
/* "gas" == GncAccountSel */
|
||||
struct gas_in_tables_data {
|
||||
GNCAccountSel **loc;
|
||||
GtkTable *table;
|
||||
int left, right, top, bottom;
|
||||
} gas_data[] = {
|
||||
/* These ints are the GtkTable boundries */
|
||||
{ &ldd->prmAccountGAS, ldd->prmTable, 1, 4, 0, 1 },
|
||||
{ &ldd->repAssetsFromGAS, ldd->repTable, 1, 4, 2, 3 },
|
||||
{ &ldd->repPrincToGAS, ldd->repTable, 1, 2, 3, 4 },
|
||||
@@ -345,6 +349,7 @@ gnc_ui_sx_loan_druid_create()
|
||||
}
|
||||
|
||||
gtk_widget_set_sensitive( GTK_WIDGET(ldd->prmVarFrame), FALSE );
|
||||
|
||||
{
|
||||
GtkAlignment *a;
|
||||
GNCOptionInfo typeOptInfo[] = {
|
||||
@@ -366,9 +371,9 @@ gnc_ui_sx_loan_druid_create()
|
||||
{
|
||||
GtkAdjustment *a;
|
||||
|
||||
/* 8.0 [%], range of 0.05..100.0 with ticks at 0.05[%]. */
|
||||
a = GTK_ADJUSTMENT(gtk_adjustment_new( 8.0, 0.05,
|
||||
100.0, 0.05,
|
||||
/* 8.0 [%], range of 0.005..100.0 with ticks at 0.001[%]. */
|
||||
a = GTK_ADJUSTMENT(gtk_adjustment_new( 8.0, 0.001,
|
||||
100.0, 0.001,
|
||||
1.0, 1.0 ));
|
||||
gtk_spin_button_set_adjustment( ldd->prmIrateSpin, a );
|
||||
gtk_spin_button_set_value( ldd->prmIrateSpin, 8.00 );
|
||||
@@ -379,6 +384,9 @@ gnc_ui_sx_loan_druid_create()
|
||||
9999, 1,
|
||||
12, 12 ));
|
||||
gtk_spin_button_set_adjustment( ldd->prmLengthSpin, a );
|
||||
gtk_signal_connect( GTK_OBJECT(ldd->prmLengthSpin), "changed",
|
||||
GTK_SIGNAL_FUNC(gnc_loan_druid_length_changed),
|
||||
ldd );
|
||||
|
||||
a = GTK_ADJUSTMENT(gtk_adjustment_new( 360, 1,
|
||||
9999, 1,
|
||||
@@ -700,7 +708,7 @@ static
|
||||
void
|
||||
ld_cancel_check( GnomeDruid *gd, LoanDruidData *ldd )
|
||||
{
|
||||
const char *cancelMsg = _( "Are you sure you want to close "
|
||||
const char *cancelMsg = _( "Are you sure you want to cancel "
|
||||
"the Mortgage/Loan Setup Druid?" );
|
||||
if ( gnc_verify_dialog_parented( ldd->dialog, FALSE, cancelMsg ) ) {
|
||||
gnc_close_gui_component_by_data( DIALOG_LOAN_DRUID_CM_CLASS,
|
||||
@@ -1027,7 +1035,7 @@ ld_rep_prep( GnomeDruidPage *gdp, gpointer arg1, gpointer ud )
|
||||
GString *str;
|
||||
str = g_string_sized_new( 64 );
|
||||
|
||||
g_string_sprintfa( str, "pmt( %.4f / 12 : %d : %0.2f : 0 : 0 )",
|
||||
g_string_sprintfa( str, "pmt( %.5f / 12 : %d : %0.2f : 0 : 0 )",
|
||||
(ldd->ld.interestRate / 100),
|
||||
ldd->ld.numPer,
|
||||
gnc_numeric_to_double(ldd->ld.principal) );
|
||||
@@ -1330,7 +1338,7 @@ ld_fin_fin ( GnomeDruidPage *gdp, gpointer arg1, gpointer ud )
|
||||
g_free( tmpStr );
|
||||
gnc_ttsplitinfo_set_account( ttsi, ldd->ld.repPriAcct );
|
||||
tmpGS = g_string_sized_new( 64 );
|
||||
g_string_sprintf( tmpGS, "ppmt( %.4f / 12 : i : %d : %0.2f : 0 : 0 )",
|
||||
g_string_sprintf( tmpGS, "ppmt( %.5f / 12 : i : %d : %0.2f : 0 : 0 )",
|
||||
(ldd->ld.interestRate / 100),
|
||||
ldd->ld.numPer,
|
||||
gnc_numeric_to_double(ldd->ld.principal));
|
||||
@@ -1346,7 +1354,7 @@ ld_fin_fin ( GnomeDruidPage *gdp, gpointer arg1, gpointer ud )
|
||||
g_free( tmpStr );
|
||||
gnc_ttsplitinfo_set_account( ttsi, ldd->ld.repIntAcct );
|
||||
tmpGS = g_string_sized_new( 64 );
|
||||
g_string_sprintf( tmpGS, "ipmt( %.4f / 12 : i : %d : %0.2f : 0 : 0 )",
|
||||
g_string_sprintf( tmpGS, "ipmt( %.5f / 12 : i : %d : %0.2f : 0 : 0 )",
|
||||
(ldd->ld.interestRate / 100),
|
||||
ldd->ld.numPer,
|
||||
gnc_numeric_to_double( ldd->ld.principal ) );
|
||||
@@ -1500,3 +1508,24 @@ ld_fin_fin ( GnomeDruidPage *gdp, gpointer arg1, gpointer ud )
|
||||
|
||||
ld_close_handler( ldd );
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
gnc_loan_druid_length_changed( GtkEditable *e, gpointer ud )
|
||||
{
|
||||
LoanDruidData *ldd;
|
||||
gchar *txt;
|
||||
gint pos;
|
||||
|
||||
ldd = (LoanDruidData*)ud;
|
||||
txt = gtk_editable_get_chars( e, 0, -1 );
|
||||
if ( !txt )
|
||||
return;
|
||||
|
||||
gtk_editable_select_region( GTK_EDITABLE(ldd->prmRemainSpin), 0, -1 );
|
||||
gtk_editable_delete_selection( GTK_EDITABLE(ldd->prmRemainSpin) );
|
||||
pos = 0;
|
||||
gtk_editable_insert_text( GTK_EDITABLE(ldd->prmRemainSpin),
|
||||
txt, strlen(txt), &pos );
|
||||
g_free( txt );
|
||||
}
|
||||
|
||||
+922
-880
File diff suppressed because it is too large
Load Diff
@@ -2523,6 +2523,24 @@ gnc_register_recur_cb(GtkWidget *w, gpointer data)
|
||||
SplitRegister *reg = gnc_ledger_display_get_split_register (regData->ledger);
|
||||
Transaction *pending_trans = gnc_split_register_get_current_trans (reg);
|
||||
|
||||
/* FIXME: If the transaction has a sched-xact KVP frame, then go to the
|
||||
* editor for the existing SX; otherwise, do the sx-from-trans dialog. */
|
||||
{
|
||||
kvp_frame *txn_frame;
|
||||
kvp_value *kvp_val;
|
||||
/* set a kvp-frame element in the transaction indicating and
|
||||
* pointing-to the SX this was created from. */
|
||||
txn_frame = xaccTransGetSlots( pending_trans );
|
||||
if ( txn_frame != NULL ) {
|
||||
DEBUG( "Got frame, looking up key" );
|
||||
kvp_val = kvp_frame_get_slot( txn_frame, "from-sched-xaction" );
|
||||
if ( kvp_val ) {
|
||||
DEBUG( "Find SX with GUID \"%s\"",
|
||||
guid_to_string( kvp_value_get_guid( kvp_val ) ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
gnc_sx_create_from_trans(pending_trans);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user