diff --git a/ChangeLog b/ChangeLog index f781535cd2..8d7384de0d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +2002-04-16 Joshua Sled + + * src/gnome/dialog-scheduledxaction.c + (editor_ok_button_clicked): Check to see if the user is attempting + to create a Scheduled Transaction which can't occur; confirm with + them if they are. + + * src/gnome-utils/gnc-frequency.c + (freq_option_value_changed): StartDate and frequency-specific + options now come into better sync [when possible] on + frequency-type change. + 2002-04-16 Joshua Sled * src/register/ledger-core/gnc-ledger-display.c: Some template-GL diff --git a/src/doc/TODO-schedxactions b/src/doc/TODO-schedxactions index 40c0f59cb1..0b14e07259 100644 --- a/src/doc/TODO-schedxactions +++ b/src/doc/TODO-schedxactions @@ -78,7 +78,15 @@ X create a template register . GNCFrequency . bugs - . transitioning to a new tab doesn't correctly setup the agreement + . Bi-weekly / Once + . Add dupe of start-date control[s] + . Precedent: monthly, yearly, &c. + . Bi-weekly, quarterly <= x < yearly + . Add example[s] -- perhaps wait for dense-calendar widget. + . yearly-only? + . if month > current month, choose previous year in start date? + . Add 'today' button for startDate? + X transitioning to a new tab doesn't correctly setup the agreement between the startdate and the page elements. X why does the accounts window go crazy when we change the FreqSpec parameters? X probably component-manager related... yup; FreqSpec Malloc/Free @@ -98,8 +106,8 @@ X create a template register . tab order . Can't click-out of the register . 'ESC' while editing template register causes window to go away badly - . attempting to create a Weekly SX with no days selected causes a segfault. - . the user should be prevented from doing this. + 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 X should use regWidget X Size/space issues [?] @@ -131,10 +139,9 @@ X create a template register which may not be the Right Thing] . need "since-last-run" UI for instanatiation. - . need effective cancellation support . need nifty visual style . use color-setting code in src/gnome-utils/druid-utils.[ch] - . support sorting in clists + . support sorting in various clists . tab-order . variable-binding table: . tab through variables -- if on last one: ( if something's unfilled, @@ -162,6 +169,7 @@ X create a template register X restore any obsolete-n-deleted SXes. X variable expressions don't get re-eval'd [as formula]? X need to do this only on tab-out of the field. + X need effective cancellation support X Change from dialogs to druid X/O create transactions X numeric diff --git a/src/gnome-utils/gnc-frequency.c b/src/gnome-utils/gnc-frequency.c index 1fc14afda8..6f1046eb3f 100644 --- a/src/gnome-utils/gnc-frequency.c +++ b/src/gnome-utils/gnc-frequency.c @@ -1,6 +1,6 @@ /********************************************************************\ * gnc-frequency.c -- GnuCash widget for frequency editing. * - * Copyright (C) 2001 Joshua Sled * + * Copyright (C) 2001,2002 Joshua Sled * * * * This program is free software; you can redistribute it and/or * * modify it under the terms of the GNU General Public License as * @@ -79,7 +79,7 @@ static void year_range_menu_helper( GtkWidget *dayOptMenu, /** Static Inits ********************/ -static struct pageDataTuple PAGES[] = { +static const struct pageDataTuple PAGES[] = { { 0, UIFREQ_NONE, "None" }, { 1, UIFREQ_ONCE, "Once" }, { 2, UIFREQ_DAILY, "Daily" }, @@ -95,7 +95,7 @@ static struct pageDataTuple PAGES[] = { { 0, 0, 0 } }; -static char *CHECKBOX_NAMES[] = { +static const char *CHECKBOX_NAMES[] = { "wd_check_sun", "wd_check_mon", "wd_check_tue", @@ -143,7 +143,9 @@ gnc_frequency_class_init( GNCFrequencyClass *klass ) GTK_SIGNAL_OFFSET( GNCFrequencyClass, value_changed ), gtk_signal_default_marshaller, GTK_TYPE_NONE, 0 ); - gtk_object_class_add_signals( objectClass, gnc_frequency_signals, LAST_SIGNAL ); + gtk_object_class_add_signals( objectClass, + gnc_frequency_signals, + LAST_SIGNAL ); klass->value_changed = NULL; } @@ -156,7 +158,7 @@ gnc_frequency_init( GNCFrequency *gf ) GtkWidget *o; GtkAdjustment *adj; - static char *cals[] = { + static const char *cals[] = { "daily_cal", "dailymf_cal", "weekly_cal", @@ -165,7 +167,7 @@ gnc_frequency_init( GNCFrequency *gf ) NULL }; - static struct optionMenuTuple { + static const struct optionMenuTuple { char *name; void (*fn)(); } optionMenus[] = { @@ -184,7 +186,7 @@ gnc_frequency_init( GNCFrequency *gf ) { NULL, NULL } }; - static struct spinvalTuple { + static const struct spinvalTuple { char *name; void (*fn)(); } spinVals[] = { @@ -305,12 +307,12 @@ gnc_frequency_setup( GNCFrequency *gf, FreqSpec *fs, GDate *startDate ) // setup the start date if ( ! g_date_valid(startDate) ) { - tmpTT = time(NULL); + tmpTT = time(NULL); } else { - tmpTm = g_new0( struct tm, 1 ); - g_date_to_struct_tm( startDate, tmpTm ); - tmpTT = mktime( tmpTm ); - g_free( tmpTm ); + tmpTm = g_new0( struct tm, 1 ); + g_date_to_struct_tm( startDate, tmpTm ); + tmpTT = mktime( tmpTm ); + g_free( tmpTm ); } gnome_date_edit_set_time( gf->startDate, tmpTT ); @@ -318,255 +320,261 @@ gnc_frequency_setup( GNCFrequency *gf, FreqSpec *fs, GDate *startDate ) case UIFREQ_NONE: break; case UIFREQ_ONCE: - { - GDate theDate; - tmpTm = g_new0( struct tm, 1 ); - /* set the date */ - if ( xaccFreqSpecGetOnce( fs, &theDate ) < 0 ) { - PERR( "Inappropriate FreqSpec type " - "[gnc-frequency: %d vs. FreqSpec: %d]\n", - uift, xaccFreqSpecGetUIType( fs ) ); - return; - } - g_date_to_struct_tm( &theDate, tmpTm ); - gnome_date_edit_set_time( gf->startDate, mktime(tmpTm) ); - g_free( tmpTm ); - } - break; + { + GDate theDate; + tmpTm = g_new0( struct tm, 1 ); + /* set the date */ + if ( xaccFreqSpecGetOnce( fs, &theDate ) < 0 ) { + PERR( "Inappropriate FreqSpec type " + "[gnc-frequency: %d vs. FreqSpec: %d]\n", + uift, xaccFreqSpecGetUIType( fs ) ); + return; + } + g_date_to_struct_tm( &theDate, tmpTm ); + gnome_date_edit_set_time( gf->startDate, mktime(tmpTm) ); + g_free( tmpTm ); + } + break; case UIFREQ_DAILY: - { - int dailyMult = -1; - if ( xaccFreqSpecGetDaily( fs, &dailyMult ) < 0 ) { - PERR( "Inappropriate FreqSpec type " - "[gnc-frequency: %d vs. FreqSpec: %d]\n", - uift, xaccFreqSpecGetUIType( fs ) ); - return; - } - o = glade_xml_get_widget( gf->gxml, "daily_spin" ); - gtk_spin_button_set_value( GTK_SPIN_BUTTON( o ), dailyMult ); - } - break; + { + int dailyMult = -1; + if ( xaccFreqSpecGetDaily( fs, &dailyMult ) < 0 ) { + PERR( "Inappropriate FreqSpec type " + "[gnc-frequency: %d vs. FreqSpec: %d]\n", + uift, xaccFreqSpecGetUIType( fs ) ); + return; + } + o = glade_xml_get_widget( gf->gxml, "daily_spin" ); + gtk_spin_button_set_value( GTK_SPIN_BUTTON( o ), dailyMult ); + } + break; case UIFREQ_DAILY_MF: - { - GList *fsList; - FreqSpec *subFS; - int weekMult, dayOfWeek; + { + GList *fsList; + FreqSpec *subFS; + int weekMult, dayOfWeek; - /* set the mult */ - fsList = xaccFreqSpecCompositeGet( fs ); - if ( g_list_length( fsList ) != 5 ) { - PERR( "Invalid Daily[M-F] FreqSpec" ); - return; - } - subFS = (FreqSpec*)fsList->data; - if ( xaccFreqSpecGetWeekly( subFS, &weekMult, &dayOfWeek ) < 0 ) { - PERR( "Inappropriate FreqSpec type " - "[gnc-frequency: %d vs. FreqSpec: %d]\n", - uift, xaccFreqSpecGetUIType( fs ) ); - return; - } - o = glade_xml_get_widget( gf->gxml, "dailymf_spin" ); - gtk_spin_button_set_value( GTK_SPIN_BUTTON(o), weekMult ); - } - break; + /* set the mult */ + fsList = xaccFreqSpecCompositeGet( fs ); + if ( g_list_length( fsList ) != 5 ) { + PERR( "Invalid Daily[M-F] FreqSpec" ); + return; + } + subFS = (FreqSpec*)fsList->data; + if ( xaccFreqSpecGetWeekly( subFS, &weekMult, &dayOfWeek ) < 0 ) { + PERR( "Inappropriate FreqSpec type " + "[gnc-frequency: %d vs. FreqSpec: %d]\n", + uift, xaccFreqSpecGetUIType( fs ) ); + return; + } + o = glade_xml_get_widget( gf->gxml, "dailymf_spin" ); + gtk_spin_button_set_value( GTK_SPIN_BUTTON(o), weekMult ); + } + break; case UIFREQ_WEEKLY: - { - int weeklyMult = -1; - int dayOfWeek; + { + int weeklyMult = -1; + int dayOfWeek; - for ( list = xaccFreqSpecCompositeGet( fs ); - list; list = g_list_next(list) ) { - subFS = (FreqSpec*)(list->data); - if ( weeklyMult == -1 ) { - if ( subFS == NULL ) { - PERR( "subFS is null\n" ); - return; - } - if ( xaccFreqSpecGetWeekly( subFS, - &weeklyMult, - &dayOfWeek ) < 0 ) { - PERR( "Inappropriate FreqSpec type " - "[gnc-frequency: %d, FreqSpec: %d]\n", - uift, xaccFreqSpecGetUIType( fs ) ); - return; - } - } else { - int otherWeeklyMult = -1; - - if ( subFS == NULL ) { - PERR( "subFS is null\n" ); - return; - } - if ( xaccFreqSpecGetWeekly( subFS, - &otherWeeklyMult, - &dayOfWeek ) < 0 ) { - PERR( "Inappropriate FreqSpec type " - "[gnc-frequency: %d, FreqSpec: %d]\n", - uift, xaccFreqSpecGetUIType( fs ) ); - return; - } - if ( weeklyMult != otherWeeklyMult ) { - PERR( "Inconsistent weekly FreqSpec " - "multipliers seen " - "[first: %d vs. other: %d]\n", - weeklyMult, otherWeeklyMult ); - return; - } - } - if ( dayOfWeek > 6 ) { - PERR( "dayOfWeek > 6 [%d]", dayOfWeek ); - return; - } - str = CHECKBOX_NAMES[dayOfWeek]; - o = glade_xml_get_widget( gf->gxml, str ); - gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(o), TRUE ); + for ( list = xaccFreqSpecCompositeGet( fs ); + list; list = g_list_next(list) ) { + subFS = (FreqSpec*)(list->data); + if ( weeklyMult == -1 ) { + if ( subFS == NULL ) { + PERR( "subFS is null\n" ); + return; } - o = glade_xml_get_widget( gf->gxml, "weekly_spin" ); - gtk_spin_button_set_value( GTK_SPIN_BUTTON(o), weeklyMult ); - } - break; + if ( xaccFreqSpecGetWeekly( subFS, + &weeklyMult, + &dayOfWeek ) < 0 ) { + PERR( "Inappropriate FreqSpec type " + "[gnc-frequency: %d, FreqSpec: %d]\n", + uift, xaccFreqSpecGetUIType( fs ) ); + return; + } + } else { + int otherWeeklyMult = -1; + + if ( subFS == NULL ) { + PERR( "subFS is null\n" ); + return; + } + if ( xaccFreqSpecGetWeekly( subFS, + &otherWeeklyMult, + &dayOfWeek ) < 0 ) { + PERR( "Inappropriate FreqSpec type " + "[gnc-frequency: %d, FreqSpec: %d]\n", + uift, xaccFreqSpecGetUIType( fs ) ); + return; + } + if ( weeklyMult != otherWeeklyMult ) { + PERR( "Inconsistent weekly FreqSpec " + "multipliers seen " + "[first: %d vs. other: %d]\n", + weeklyMult, otherWeeklyMult ); + return; + } + } + if ( dayOfWeek > 6 ) { + PERR( "dayOfWeek > 6 [%d]", dayOfWeek ); + return; + } + str = CHECKBOX_NAMES[dayOfWeek]; + o = glade_xml_get_widget( gf->gxml, str ); + gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(o), TRUE ); + } + o = glade_xml_get_widget( gf->gxml, "weekly_spin" ); + gtk_spin_button_set_value( GTK_SPIN_BUTTON(o), weeklyMult ); + } + break; case UIFREQ_BI_WEEKLY: - /* set the initial date...? */ - break; + /* set the initial date...? */ + break; case UIFREQ_SEMI_MONTHLY: - { - int monthlyMult; - int firstDayOfMonth, secondDayOfMonth, monthOffset; - list = xaccFreqSpecCompositeGet( fs ); - /* mult */ - o = glade_xml_get_widget( gf->gxml, "semimonthly_spin" ); - subFS = (FreqSpec*)(g_list_nth( list, 0 )->data); - if ( xaccFreqSpecGetMonthly( subFS, &monthlyMult, - &firstDayOfMonth, &monthOffset ) < 0 ) { - PERR( "Inappropriate FreqSpec type " - "[gnc-frequency: %d, FreqSpec: %d]\n", - uift, xaccFreqSpecGetUIType( fs ) ); - return; - } - gtk_spin_button_set_value( GTK_SPIN_BUTTON(o), monthlyMult ); - /* first date */ - o = glade_xml_get_widget( gf->gxml, "semimonthly_first" ); - gtk_option_menu_set_history( GTK_OPTION_MENU(o), firstDayOfMonth-1 ); - /* second date */ - subFS = (FreqSpec*)(g_list_nth( list, 1 )->data); - o = glade_xml_get_widget( gf->gxml, "semimonthly_second" ); - if ( xaccFreqSpecGetMonthly( subFS, &monthlyMult, - &secondDayOfMonth, &monthOffset ) < 0 ) { - PERR( "Inappropriate FreqSpec type\n" ); - return; - } - gtk_option_menu_set_history( GTK_OPTION_MENU(o), secondDayOfMonth-1 ); - } - break; + { + int monthlyMult; + int firstDayOfMonth, secondDayOfMonth, monthOffset; + list = xaccFreqSpecCompositeGet( fs ); + /* mult */ + o = glade_xml_get_widget( gf->gxml, "semimonthly_spin" ); + subFS = (FreqSpec*)(g_list_nth( list, 0 )->data); + if ( xaccFreqSpecGetMonthly( subFS, &monthlyMult, + &firstDayOfMonth, &monthOffset ) < 0 ) { + PERR( "Inappropriate FreqSpec type " + "[gnc-frequency: %d, FreqSpec: %d]\n", + uift, xaccFreqSpecGetUIType( fs ) ); + return; + } + gtk_spin_button_set_value( GTK_SPIN_BUTTON(o), monthlyMult ); + /* first date */ + o = glade_xml_get_widget( gf->gxml, "semimonthly_first" ); + gtk_option_menu_set_history( GTK_OPTION_MENU(o), firstDayOfMonth-1 ); + /* second date */ + subFS = (FreqSpec*)(g_list_nth( list, 1 )->data); + o = glade_xml_get_widget( gf->gxml, "semimonthly_second" ); + if ( xaccFreqSpecGetMonthly( subFS, &monthlyMult, + &secondDayOfMonth, &monthOffset ) < 0 ) { + PERR( "Inappropriate FreqSpec type\n" ); + return; + } + gtk_option_menu_set_history( GTK_OPTION_MENU(o), secondDayOfMonth-1 ); + } + break; case UIFREQ_MONTHLY: - { - int monthlyMult, dayOfMonth, monthOffset; - if ( xaccFreqSpecGetMonthly( fs, &monthlyMult, - &dayOfMonth, &monthOffset ) < 0 ) { - PERR( "Inappropriate FreqSpec type " - "[gnc-frequency: %d, FreqSpec: %d]\n", - uift, xaccFreqSpecGetUIType( fs ) ); - return; - } - o = glade_xml_get_widget( gf->gxml, "monthly_spin" ); - gtk_spin_button_set_value( GTK_SPIN_BUTTON(o), monthlyMult ); - o = glade_xml_get_widget( gf->gxml, "monthly_day" ); - gtk_option_menu_set_history( GTK_OPTION_MENU(o), dayOfMonth-1 ); - /* set the day-of-month */ - } - break; + { + int monthlyMult, dayOfMonth, monthOffset; + if ( xaccFreqSpecGetMonthly( fs, &monthlyMult, + &dayOfMonth, &monthOffset ) < 0 ) { + PERR( "Inappropriate FreqSpec type " + "[gnc-frequency: %d, FreqSpec: %d]\n", + uift, xaccFreqSpecGetUIType( fs ) ); + return; + } + o = glade_xml_get_widget( gf->gxml, "monthly_spin" ); + gtk_spin_button_set_value( GTK_SPIN_BUTTON(o), monthlyMult ); + o = glade_xml_get_widget( gf->gxml, "monthly_day" ); + gtk_option_menu_set_history( GTK_OPTION_MENU(o), dayOfMonth-1 ); + /* set the day-of-month */ + } + break; case UIFREQ_QUARTERLY: - { - int monthlyMult, dayOfMonth, monthOffset; + { + int monthlyMult, dayOfMonth, monthOffset; - if ( xaccFreqSpecGetMonthly( fs, &monthlyMult, - &dayOfMonth, &monthOffset ) < 0 ) { - PERR( "Inappropriate FreqSpec type " - "[gnc-frequency: %d, FreqSpec: %d]\n", - uift, xaccFreqSpecGetUIType( fs ) ); - return; - } - if ( monthlyMult != 3 ) { - PERR( "monthly multiplier != 3 [=%d]", monthlyMult ); - return; - } - year_range_menu_helper( glade_xml_get_widget( gf->gxml, "quarterly_day" ), - glade_xml_get_widget( gf->gxml, "quarterly_occur" ), - 3, gnome_date_edit_get_date( gf->startDate ) ); - } - break; + if ( xaccFreqSpecGetMonthly( fs, &monthlyMult, + &dayOfMonth, &monthOffset ) < 0 ) { + PERR( "Inappropriate FreqSpec type " + "[gnc-frequency: %d, FreqSpec: %d]\n", + uift, xaccFreqSpecGetUIType( fs ) ); + return; + } + if ( monthlyMult != 3 ) { + PERR( "monthly multiplier != 3 [=%d]", monthlyMult ); + return; + } + year_range_menu_helper( glade_xml_get_widget( gf->gxml, + "quarterly_day" ), + glade_xml_get_widget( gf->gxml, + "quarterly_occur" ), + 3, gnome_date_edit_get_date( gf->startDate ) ); + } + break; case UIFREQ_TRI_ANUALLY: - { - int monthlyMult, dayOfMonth, monthOffset; + { + int monthlyMult, dayOfMonth, monthOffset; - if ( xaccFreqSpecGetMonthly( fs, &monthlyMult, - &dayOfMonth, &monthOffset ) < 0 ) { - PERR( "Inappropriate FreqSpec type " - "[gnc-frequency: %d, FreqSpec: %d]\n", - uift, xaccFreqSpecGetUIType( fs ) ); - return; - } - if ( monthlyMult != 4 ) { - PERR( "Month-multiplier != 4 [=%d]", monthlyMult ); - return; - } - year_range_menu_helper( glade_xml_get_widget( gf->gxml, "triyearly_day" ), - glade_xml_get_widget( gf->gxml, "triyearly_occur" ), - 4, gnome_date_edit_get_date( gf->startDate ) ); - } - break; + if ( xaccFreqSpecGetMonthly( fs, &monthlyMult, + &dayOfMonth, &monthOffset ) < 0 ) { + PERR( "Inappropriate FreqSpec type " + "[gnc-frequency: %d, FreqSpec: %d]\n", + uift, xaccFreqSpecGetUIType( fs ) ); + return; + } + if ( monthlyMult != 4 ) { + PERR( "Month-multiplier != 4 [=%d]", monthlyMult ); + return; + } + year_range_menu_helper( glade_xml_get_widget( gf->gxml, + "triyearly_day" ), + glade_xml_get_widget( gf->gxml, + "triyearly_occur" ), + 4, gnome_date_edit_get_date( gf->startDate ) ); + } + break; case UIFREQ_SEMI_YEARLY: - { - int monthlyMult, dayOfMonth, monthOffset; + { + int monthlyMult, dayOfMonth, monthOffset; - if ( xaccFreqSpecGetMonthly( fs, &monthlyMult, - &dayOfMonth, &monthOffset ) < 0 ) { - PERR( "Inappropriate FreqSpec type " - "[gnc-frequency: %d, FreqSpec: %d]\n", - uift, xaccFreqSpecGetUIType( fs ) ); - return; - } - if ( monthlyMult != 6 ) { - PERR( "month-mult != 6 [=%d]", monthlyMult ); - return; - } - year_range_menu_helper( glade_xml_get_widget( gf->gxml, "semiyearly_day" ), - glade_xml_get_widget( gf->gxml, "semiyearly_occur" ), - 6, gnome_date_edit_get_date( gf->startDate ) ); - } - break; + if ( xaccFreqSpecGetMonthly( fs, &monthlyMult, + &dayOfMonth, &monthOffset ) < 0 ) { + PERR( "Inappropriate FreqSpec type " + "[gnc-frequency: %d, FreqSpec: %d]\n", + uift, xaccFreqSpecGetUIType( fs ) ); + return; + } + if ( monthlyMult != 6 ) { + PERR( "month-mult != 6 [=%d]", monthlyMult ); + return; + } + year_range_menu_helper( glade_xml_get_widget( gf->gxml, + "semiyearly_day" ), + glade_xml_get_widget( gf->gxml, + "semiyearly_occur" ), + 6, gnome_date_edit_get_date( gf->startDate ) ); + } + break; case UIFREQ_YEARLY: - { - int monthlyMult, dayOfMonth, monthOffset; + { + int monthlyMult, dayOfMonth, monthOffset; - if ( xaccFreqSpecGetMonthly( fs, &monthlyMult, - &dayOfMonth, &monthOffset ) < 0 ) { - PERR( "Inappropriate FreqSpec type " - "[gnc-frequency: %d, FreqSpec: %d]\n", - uift, xaccFreqSpecGetUIType( fs ) ); - return; - } - if ( (monthlyMult % 12) != 0) { - PERR( "monthly-mult %% 12 != 0 [=%d]", ( monthlyMult % 12 ) ); - return; - } + if ( xaccFreqSpecGetMonthly( fs, &monthlyMult, + &dayOfMonth, &monthOffset ) < 0 ) { + PERR( "Inappropriate FreqSpec type " + "[gnc-frequency: %d, FreqSpec: %d]\n", + uift, xaccFreqSpecGetUIType( fs ) ); + return; + } + if ( (monthlyMult % 12) != 0) { + PERR( "monthly-mult %% 12 != 0 [=%d]", ( monthlyMult % 12 ) ); + return; + } - /* set the mult */ - o = glade_xml_get_widget( gf->gxml, "yearly_spin" ); - gtk_spin_button_set_value( GTK_SPIN_BUTTON(o), - (int)rint(floor(monthlyMult / 12)) ); - tmpTT = gnome_date_edit_get_date( gf->startDate ); - tmpTm = localtime( &tmpTT ); - o = glade_xml_get_widget( gf->gxml, "yearly_month" ); - gtk_option_menu_set_history( GTK_OPTION_MENU(o), monthOffset ); - o = glade_xml_get_widget( gf->gxml, "yearly_day" ); - gtk_option_menu_set_history( GTK_OPTION_MENU(o), dayOfMonth-1 ); - } - break; + /* set the mult */ + o = glade_xml_get_widget( gf->gxml, "yearly_spin" ); + gtk_spin_button_set_value( GTK_SPIN_BUTTON(o), + (int)rint(floor(monthlyMult / 12)) ); + tmpTT = gnome_date_edit_get_date( gf->startDate ); + tmpTm = localtime( &tmpTT ); + o = glade_xml_get_widget( gf->gxml, "yearly_month" ); + gtk_option_menu_set_history( GTK_OPTION_MENU(o), monthOffset ); + o = glade_xml_get_widget( gf->gxml, "yearly_day" ); + gtk_option_menu_set_history( GTK_OPTION_MENU(o), dayOfMonth-1 ); + } + break; default: - PERR( "unknown ui freq type %d [%d, %s]\n", - uift, __LINE__, __FILE__ ); - break; + PERR( "unknown ui freq type %d [%d, %s]\n", + uift, __LINE__, __FILE__ ); + break; } update_appropriate_cal( gf ); } @@ -617,74 +625,80 @@ gnc_frequency_save_state( GNCFrequency *gf, FreqSpec *fs, GDate *outStartDate ) case UIFREQ_DAILY: o = glade_xml_get_widget( gf->gxml, "daily_spin" ); /* FIXME: initial date should be set correctly. */ - xaccFreqSpecSetDaily( fs, gd, - gtk_spin_button_get_value_as_int( GTK_SPIN_BUTTON(o) ) ); - xaccFreqSpecSetUIType( fs, uift ); - g_date_free( gd ); + { + gint foo; + + foo = gtk_spin_button_get_value_as_int( GTK_SPIN_BUTTON(o) ); + xaccFreqSpecSetDaily( fs, gd, foo ); + xaccFreqSpecSetUIType( fs, uift ); + g_date_free( gd ); + } break; case UIFREQ_DAILY_MF: - xaccFreqSpecSetComposite( fs ); - xaccFreqSpecSetUIType( fs, uift ); - gd2 = g_date_new(); - o = glade_xml_get_widget( gf->gxml, "dailymf_spin" ); - tmpInt = gtk_spin_button_get_value_as_int( GTK_SPIN_BUTTON(o) ); - /* Okay. Assume that the calendar is upgraded to */ - /* support selecting weeks, returning the Sunday selected. */ - /* Normalize to sunday. */ - tmpTm = g_new0( struct tm, 1 ); - g_date_to_struct_tm( gd, tmpTm ); - /* month-day += (week-day - current-week-day ) % 7 */ - /* week-day <- 0 */ - tmpTm->tm_mday -= ( tmpTm->tm_wday ) % 7; - g_date_set_time( gd, mktime( tmpTm ) ); + xaccFreqSpecSetComposite( fs ); + xaccFreqSpecSetUIType( fs, uift ); + gd2 = g_date_new(); + o = glade_xml_get_widget( gf->gxml, "dailymf_spin" ); + tmpInt = gtk_spin_button_get_value_as_int( GTK_SPIN_BUTTON(o) ); + /* Okay. Assume that the calendar is upgraded to */ + /* support selecting weeks, returning the Sunday selected. */ + /* Normalize to sunday. */ + tmpTm = g_new0( struct tm, 1 ); + g_date_to_struct_tm( gd, tmpTm ); + /* month-day += (week-day - current-week-day ) % 7 */ + /* week-day <- 0 */ + tmpTm->tm_mday -= ( tmpTm->tm_wday ) % 7; + g_date_set_time( gd, mktime( tmpTm ) ); - /* 1 == "mon", 5 == "fri" */ - for ( i=1; i<6; i++ ) { - *gd2 = *gd; - g_date_add_days( gd2, i ); - tmpFS = xaccFreqSpecMalloc(gnc_get_current_book ()); - xaccFreqSpecSetWeekly( tmpFS, gd2, tmpInt ); - xaccFreqSpecCompositeAdd( fs, tmpFS ); - } - g_date_free( gd ); - g_date_free( gd2 ); - g_free( tmpTm ); - break; + /* 1 == "mon", 5 == "fri" */ + for ( i=1; i<6; i++ ) { + *gd2 = *gd; + g_date_add_days( gd2, i ); + tmpFS = xaccFreqSpecMalloc(gnc_get_current_book ()); + xaccFreqSpecSetWeekly( tmpFS, gd2, tmpInt ); + xaccFreqSpecCompositeAdd( fs, tmpFS ); + } + g_date_free( gd ); + g_date_free( gd2 ); + g_free( tmpTm ); + break; case UIFREQ_WEEKLY: - xaccFreqSpecSetComposite( fs ); - xaccFreqSpecSetUIType( fs, uift ); - o = glade_xml_get_widget( gf->gxml, "weekly_spin" ); - tmpInt = gtk_spin_button_get_value_as_int( GTK_SPIN_BUTTON(o) ); + xaccFreqSpecSetComposite( fs ); + xaccFreqSpecSetUIType( fs, uift ); + o = glade_xml_get_widget( gf->gxml, "weekly_spin" ); + tmpInt = gtk_spin_button_get_value_as_int( GTK_SPIN_BUTTON(o) ); - /* assume we have a good calendar that allows week selection. */ - /* for-now hack: normalize to Sunday. */ - tmpTm = g_new0( struct tm, 1 ); - g_date_to_struct_tm( gd, tmpTm ); - tmpTm->tm_mday -= tmpTm->tm_wday % 7; - g_date_set_time( gd, mktime( tmpTm ) ); + /* assume we have a good calendar that allows week selection. */ + /* for-now hack: normalize to Sunday. */ + tmpTm = g_new0( struct tm, 1 ); + g_date_to_struct_tm( gd, tmpTm ); + tmpTm->tm_mday -= tmpTm->tm_wday % 7; + g_date_set_time( gd, mktime( tmpTm ) ); - /* now, go through the check boxes and add composites based on that date. */ - for ( i=0; CHECKBOX_NAMES[i]!=NULL; i++ ) { - str = CHECKBOX_NAMES[i]; - o = glade_xml_get_widget( gf->gxml, str ); - if ( gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(o) ) ) { + /* now, go through the check boxes and add composites based on that date. */ + for ( i=0; CHECKBOX_NAMES[i]!=NULL; i++ ) { + str = CHECKBOX_NAMES[i]; + o = glade_xml_get_widget( gf->gxml, str ); + if ( gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(o) ) ) { - tmpFS = xaccFreqSpecMalloc - (gnc_get_current_book ()); - xaccFreqSpecSetUIType( tmpFS, uift ); - /* struct-copy is expected to work, here */ - /* [wish we didn't have to know about the GDate implementation...] */ - gd2 = g_date_new(); - *gd2 = *gd; - /* Add 'i' days off of Sunday... */ - g_date_add_days( gd2, i ); - xaccFreqSpecSetWeekly( tmpFS, gd2, tmpInt ); - g_date_free( gd2 ); - xaccFreqSpecCompositeAdd( fs, tmpFS ); - } - } - g_date_free( gd ); - g_free( tmpTm ); + tmpFS = xaccFreqSpecMalloc + (gnc_get_current_book ()); + xaccFreqSpecSetUIType( tmpFS, uift ); + + /* struct-copy is expected to work, here */ + /* [I wish we didn't have to know about the GDate + * implementation...] */ + gd2 = g_date_new(); + *gd2 = *gd; + /* Add 'i' days off of Sunday... */ + g_date_add_days( gd2, i ); + xaccFreqSpecSetWeekly( tmpFS, gd2, tmpInt ); + g_date_free( gd2 ); + xaccFreqSpecCompositeAdd( fs, tmpFS ); + } + } + g_date_free( gd ); + g_free( tmpTm ); break; case UIFREQ_BI_WEEKLY: xaccFreqSpecSetUIType( fs, uift ); @@ -902,52 +916,15 @@ spin_changed_helper( GtkAdjustment *adj, gpointer d ) update_appropriate_cal( (GNCFrequency*)d ); } -#if 0 -static void -daily_spin_value_changed( GtkAdjustment *adj, gpointer d ) -{ - GtkCalendar *cal; - - cal = GTK_CALENDAR( glade_xml_get_widget( ((GNCFrequency*)d)->gxml, - "daily_cal" ) ); - update_cal( d, cal ); -} -#endif - -#if 0 -static void -dailymf_spin_value_changed( GtkAdjustment *adj, gpointer d ) -{ - GtkCalendar *cal; - - cal = GTK_CALENDAR( glade_xml_get_widget( ((GNCFrequency*)d)->gxml, - "dailymf_cal" ) ); - update_cal( d, cal ); -} -#endif - -#if 0 -static void -weekly_spin_value_changed( GtkAdjustment *adj, gpointer d ) -{ - GtkCalendar *cal; - - cal = GTK_CALENDAR( glade_xml_get_widget( ((GNCFrequency*)d)->gxml, - "weekly_cal" ) ); - - update_cal( d, cal ); -} -#endif - static void weekly_days_changed( GtkButton *b, gpointer d ) { - GNCFrequency *gf; - GtkWidget *wcal; + GNCFrequency *gf; + GtkWidget *wcal; - gf = (GNCFrequency*)d; - wcal = glade_xml_get_widget( gf->gxml, "weekly_cal" ); - update_cal( gf, GTK_CALENDAR(wcal) ); + gf = (GNCFrequency*)d; + wcal = glade_xml_get_widget( gf->gxml, "weekly_cal" ); + update_cal( gf, GTK_CALENDAR(wcal) ); } static void @@ -979,22 +956,6 @@ monthly_sel_changed( GtkButton *b, gpointer d ) update_appropriate_cal( (GNCFrequency*)d ); } -#if 0 -static void -monthly_spin_value_changed( GtkAdjustment *adj, gpointer d ) -{ - update_appropriate_cal( (GNCFrequency*)d ); -} -#endif - -#if 0 -static void -semimonthly_spin_value_changed( GtkAdjustment *adj, gpointer d ) -{ - update_appropriate_cal( (GNCFrequency*)d ); -} -#endif - static void semimonthly_sel_changed( GtkButton *b, gpointer d ) { @@ -1031,31 +992,31 @@ semimonthly_sel_changed( GtkButton *b, gpointer d ) static void quarterly_sel_changed( GtkButton *b, gpointer d ) { - GNCFrequency *gf; - gf = (GNCFrequency*)d; - year_range_sels_changed( gf, 3, - glade_xml_get_widget( gf->gxml, "quarterly_occur" ), - glade_xml_get_widget( gf->gxml, "quarterly_day" ) ); + GNCFrequency *gf; + gf = (GNCFrequency*)d; + year_range_sels_changed( gf, 3, + glade_xml_get_widget( gf->gxml, "quarterly_occur" ), + glade_xml_get_widget( gf->gxml, "quarterly_day" ) ); } static void triyearly_sel_changed( GtkButton *b, gpointer d ) { - GNCFrequency *gf; - gf = (GNCFrequency*)d; - year_range_sels_changed( gf, 4, - glade_xml_get_widget( gf->gxml, "triyearly_occur" ), - glade_xml_get_widget( gf->gxml, "triyearly_day" ) ); + GNCFrequency *gf; + gf = (GNCFrequency*)d; + year_range_sels_changed( gf, 4, + glade_xml_get_widget( gf->gxml, "triyearly_occur" ), + glade_xml_get_widget( gf->gxml, "triyearly_day" ) ); } static void semiyearly_sel_changed( GtkButton *b, gpointer d ) { - GNCFrequency *gf; - gf = (GNCFrequency*)d; - year_range_sels_changed( gf, 6, - glade_xml_get_widget( gf->gxml, "semiyearly_occur" ), - glade_xml_get_widget( gf->gxml, "semiyearly_day" ) ); + GNCFrequency *gf; + gf = (GNCFrequency*)d; + year_range_sels_changed( gf, 6, + glade_xml_get_widget( gf->gxml, "semiyearly_occur" ), + glade_xml_get_widget( gf->gxml, "semiyearly_day" ) ); } static void @@ -1064,21 +1025,21 @@ year_range_sels_changed( GNCFrequency *gf, GtkWidget *occurW, GtkWidget *dayOfMonthW ) { - int occur, day; - time_t tmpTT; - struct tm *tmpTm; + int occur, day; + time_t tmpTT; + struct tm *tmpTm; - occur = gnc_option_menu_get_active( occurW ); - day = gnc_option_menu_get_active( dayOfMonthW ) + 1; + occur = gnc_option_menu_get_active( occurW ); + day = gnc_option_menu_get_active( dayOfMonthW ) + 1; - tmpTT = gnome_date_edit_get_date( gf->startDate ); - tmpTm = localtime( &tmpTT ); - tmpTm->tm_mday = day; - // jump the month to the closest appropriate month. - // FIXME: this could probably be made more "appropriate". - tmpTm->tm_mon += occur - (tmpTm->tm_mon % monthsInRange); - tmpTT = mktime( tmpTm ); - gnome_date_edit_set_time( gf->startDate, tmpTT ); + tmpTT = gnome_date_edit_get_date( gf->startDate ); + tmpTm = localtime( &tmpTT ); + tmpTm->tm_mday = day; + // jump the month to the closest appropriate month. + // FIXME: this could probably be made more "appropriate". + tmpTm->tm_mon += occur - (tmpTm->tm_mon % monthsInRange); + tmpTT = mktime( tmpTm ); + gnome_date_edit_set_time( gf->startDate, tmpTT ); } static void @@ -1114,13 +1075,92 @@ yearly_sel_changed( GtkButton *b, gpointer d ) update_appropriate_cal( gf ); } +static inline guint32 min( guint32 a, guint32 b ) +{ + return a > b ? b : a; +} + +static inline guint32 max( guint32 a, guint32 b ) +{ + return a > b ? a : b; +} + static void freq_option_value_changed( GtkMenuShell *b, gpointer d ) { - int optIdx; + GNCFrequency *gf = (GNCFrequency*)d; + int optIdx; + UIFreqType uift; + time_t startDate, tmpDate; + GnomeDateEdit *gde; + struct tm *tmpTm; + GtkWidget *o; + /* Set the new page. */ optIdx = gnc_option_menu_get_active( GTK_WIDGET(((GNCFrequency*)d)->freqOpt) ); gtk_notebook_set_page( ((GNCFrequency*)d)->nb, optIdx ); + + /* setup initial values for new page, as possible. */ + uift = PAGES[optIdx].uiFTVal; + gde = GNOME_DATE_EDIT(glade_xml_get_widget( gf->gxml, "sxe_start_date" )); + startDate = gnome_date_edit_get_date( gde ); + tmpTm = localtime( &startDate ); + + switch ( uift ) { + case UIFREQ_SEMI_MONTHLY: + { + gint tmpDayOfMonth; + /* first on the , then on the */ + o = glade_xml_get_widget( gf->gxml, "semimonthly_first" ); + tmpDayOfMonth = tmpTm->tm_mday; + tmpTm->tm_mday += 14; + tmpDate = mktime( tmpTm ); + tmpTm = localtime( &tmpDate ); + gtk_option_menu_set_history( GTK_OPTION_MENU(o), + min( tmpTm->tm_mday, tmpDayOfMonth ) - 1 ); + o = glade_xml_get_widget( gf->gxml, "semimonthly_second" ); + gtk_option_menu_set_history( GTK_OPTION_MENU(o), + max( tmpTm->tm_mday, tmpDayOfMonth ) - 1 ); + } + break; + case UIFREQ_MONTHLY: + /* on the */ + o = glade_xml_get_widget( gf->gxml, "monthly_day" ); + gtk_option_menu_set_history( GTK_OPTION_MENU(o), + tmpTm->tm_mday - 1 ); + break; + case UIFREQ_QUARTERLY: + /* on the */ + o = glade_xml_get_widget( gf->gxml, "quarterly_day" ); + gtk_option_menu_set_history( GTK_OPTION_MENU(o), + tmpTm->tm_mday - 1 ); + break; + case UIFREQ_TRI_ANUALLY: + /* on the */ + o = glade_xml_get_widget( gf->gxml, "triyearly_day" ); + gtk_option_menu_set_history( GTK_OPTION_MENU(o), + tmpTm->tm_mday - 1 ); + break; + case UIFREQ_SEMI_YEARLY: + /* on the */ + o = glade_xml_get_widget( gf->gxml, "semiyearly_day" ); + gtk_option_menu_set_history( GTK_OPTION_MENU(o), + tmpTm->tm_mday - 1 ); + break; + case UIFREQ_YEARLY: + /* on the , */ + o = glade_xml_get_widget( gf->gxml, "yearly_month" ); + gtk_option_menu_set_history( GTK_OPTION_MENU(o), + tmpTm->tm_mon ); + o = glade_xml_get_widget( gf->gxml, "yearly_day" ); + gtk_option_menu_set_history( GTK_OPTION_MENU(o), + tmpTm->tm_mday - 1 ); + break; + default: + /* nuttin can be done, for whatever reason. */ + break; + } + update_appropriate_cal( gf ); } static void @@ -1144,7 +1184,6 @@ start_date_changed( GnomeDateEdit *gde, gpointer d ) GtkWidget *o; struct tm *tmpTm; time_t dateFromGDE; - gint tmpint; gint page; UIFreqType uift; @@ -1166,15 +1205,18 @@ start_date_changed( GnomeDateEdit *gde, gpointer d ) break; case UIFREQ_SEMI_MONTHLY: - o = glade_xml_get_widget( gf->gxml, "semimonthly_first" ); - tmpint = gnc_option_menu_get_active( GTK_WIDGET(o) )+1; - o = glade_xml_get_widget( gf->gxml, "semimonthly_second" ); - if ( tmpint < gnc_option_menu_get_active( GTK_WIDGET(o) )+1 ) { + { + gint sm_first_day; o = glade_xml_get_widget( gf->gxml, "semimonthly_first" ); - } + first_day = gnc_option_menu_get_active( GTK_WIDGET(o) )+1; + o = glade_xml_get_widget( gf->gxml, "semimonthly_second" ); + if ( first_day < gnc_option_menu_get_active( GTK_WIDGET(o) )+1 ) { + o = glade_xml_get_widget( gf->gxml, "semimonthly_first" ); + } - tmpTm = localtime( &dateFromGDE ); - gtk_option_menu_set_history( GTK_OPTION_MENU(o), tmpTm->tm_mday-1 ); + tmpTm = localtime( &dateFromGDE ); + gtk_option_menu_set_history( GTK_OPTION_MENU(o), tmpTm->tm_mday-1 ); + } break; case UIFREQ_MONTHLY: o = glade_xml_get_widget( gf->gxml, "monthly_day" ); diff --git a/src/gnome-utils/gnc-frequency.h b/src/gnome-utils/gnc-frequency.h index 20f2b1aabb..5c15dadca1 100644 --- a/src/gnome-utils/gnc-frequency.h +++ b/src/gnome-utils/gnc-frequency.h @@ -1,6 +1,6 @@ /********************************************************************\ * gnc-frequency.h -- GnuCash widget for frequency editing. * - * Copyright (C) 2001 Joshua Sled * + * Copyright (C) 2001,2002 Joshua Sled * * * * This program is free software; you can redistribute it and/or * * modify it under the terms of the GNU General Public License as * @@ -35,10 +35,10 @@ BEGIN_GNOME_DECLS #define GNC_IS_FREQUENCY(obj) GTK_CHECK_TYPE(obj, gnc_frequency_get_type()) /** - * A GNCFrequency is a VBox containing a scrollable GtkNotebook which - * allows the user to specify the frequency [of a scheduled - * transaction or budgeting category, for instance], manipulating a - * FreqSpec object in the process. + * A GNCFrequency is a VBox containing a scrollable GtkNotebook [and other + * widgets] which allows the user to specify the frequency [of a scheduled + * transaction or budgeting category, for instance], manipulating a FreqSpec + * object in the process. **/ typedef struct _GNCFrequency { GtkVBox widget; diff --git a/src/gnome/dialog-scheduledxaction.c b/src/gnome/dialog-scheduledxaction.c index df08e34ab6..c40cae0283 100644 --- a/src/gnome/dialog-scheduledxaction.c +++ b/src/gnome/dialog-scheduledxaction.c @@ -1,7 +1,7 @@ /********************************************************************\ * dialog-scheduledxaction.c : dialog for scheduled transaction * * list and editor * - * Copyright (C) 2001 Joshua Sled * + * Copyright (C) 2001,2002 Joshua Sled * * * * This program is free software; you can redistribute it and/or * * modify it under the terms of the GNU General Public License as * @@ -240,15 +240,17 @@ editor_ok_button_clicked( GtkButton *b, SchedXactionEditorDialog *sxed ) FreqSpec *fs; GDate *gdate; - /* FIXME: Do checks on validity and such, interrupting the user if + /* FIXMEs: Do checks on validity and such, interrupting the user if * things aren't right. * - * . "weekly" FS has some days set. - * . "once" with reasonable start/end dates. - * - * . creating a "not scheduled" SX is probably not right... - * * . balancing the SX if contain numeric-only formula data. + * . agreement with create-automagically/notification controls + * X "weekly" FS has some days set. + * X "once" with reasonable start/end dates. + * X This doesn't work at the time the 'weekly' one was fixed with + * user-confirmation, below; the once SX is always valid. + * [X more generically, creating a "not scheduled" SX is probably not + * right... ] */ gnc_split_register_save ( gnc_ledger_display_get_split_register(sxed->ledger), FALSE ); @@ -376,9 +378,30 @@ editor_ok_button_clicked( GtkButton *b, SchedXactionEditorDialog *sxed ) /* now that we have it, set the start date */ xaccSchedXactionSetStartDate( sxed->sx, gdate ); - g_date_free( gdate ); + /* Now, see if the user is attempting to create a SX that can't exist + * [will never run]. */ + { + gboolean isInvalid; + gdate = g_date_new(); + *gdate = xaccSchedXactionGetNextInstance( sxed->sx, NULL ); + isInvalid = !g_date_valid( gdate ); + g_date_free( gdate ); + if ( isInvalid ) { + char *invalid_sx_check_msg = + _( "You have attempted to create a Scheduled " + "Transaction which will never run.\nDo you " + "really want to do this?" ); + if ( ! gnc_verify_dialog_parented( sxed->dialog, + invalid_sx_check_msg, + FALSE ) ) { + + return; + } + } + } + /* add to list */ putSchedXactionInClist( sxed->sx, sxed->sxd ); if ( sxed->new ) { diff --git a/src/gnome/dialog-sxsincelast.c b/src/gnome/dialog-sxsincelast.c index 6c90fed23d..2cb6d1e941 100644 --- a/src/gnome/dialog-sxsincelast.c +++ b/src/gnome/dialog-sxsincelast.c @@ -681,11 +681,11 @@ cancel_check( GnomeDruidPage *druid_page, { GList *l; sxSinceLastData *sxsld = (sxSinceLastData*)ud; - const char *lastrun_cancel_check_msg = - _( "Cancelling the Since-Last-Run dialog " - "will revert all changes.\n" - "Are you sure you want to lose all " - "Scheduled Transaction changes?" ); + char *lastrun_cancel_check_msg = + _( "Cancelling the Since-Last-Run dialog " + "will revert all changes.\n" + "Are you sure you want to lose all " + "Scheduled Transaction changes?" ); DEBUG( "cancel_check" );