mirror of
https://github.com/Gnucash/gnucash.git
synced 2025-02-25 18:55:30 -06:00
2002-08-09 Joshua Sled <jsled@asynchronous.org>
* src/engine/FreqSpec.c (gnc_freq_spec_compare), (int_cmp), (_gnc_freq_spec_get_min): Added to support ordering FreqSpecs for sorting. * src/gnome/dialog-scheduledxaction.c: Added support for column-sorting the SX list, resolving Bug#87865 fixed. Cleaned up GDate allocation when done with them. Fixed Bug#90326 relating to next-instance-date calculation, which was b0rken when the dense-calendar was added in cases where the next SX instance is outside of the visible calendar range. git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@7148 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
23
ChangeLog
23
ChangeLog
@@ -1,3 +1,26 @@
|
||||
2002-08-09 Joshua Sled <jsled@asynchronous.org>
|
||||
|
||||
* src/engine/FreqSpec.c (gnc_freq_spec_compare),
|
||||
(int_cmp), (_gnc_freq_spec_get_min): Added to support ordering
|
||||
FreqSpecs for sorting.
|
||||
|
||||
* src/gnome/dialog-scheduledxaction.c: Added support for
|
||||
column-sorting the SX list, resolving Bug#87865 fixed. Cleaned up
|
||||
GDate allocation when done with them. Fixed Bug#90326 relating to
|
||||
next-instance-date calculation, which was b0rken when the
|
||||
dense-calendar was added in cases where the next SX instance is
|
||||
outside of the visible calendar range.
|
||||
|
||||
2002-08-06 Joshua Sled <jsled@asynchronous.org>
|
||||
|
||||
* src/gnome/dialog-sxsincelast.c: Added support for saving the
|
||||
state of the ledger if a review-ledger is transitioned away from
|
||||
after a "simple" edit [Bug#90075].
|
||||
|
||||
* src/gnome/dialog-sx-from-trans.c (sxftd_ok_clicked): *
|
||||
src/gnome/dialog-sxsincelast.c (gnc_sxsld_finish): Now updates the
|
||||
SX List [if open] when an obsolete SX is removed [Bug#84685].
|
||||
|
||||
2002-08-06 Joshua Sled <jsled@asynchronous.org>
|
||||
|
||||
* src/gnome/dialog-scheduledxaction.c (gnc_sxed_check_consistent):
|
||||
|
||||
@@ -933,3 +933,129 @@ xaccFreqSpecGetFreqStr( FreqSpec *fs, GString *str )
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
int_cmp( int a, int b )
|
||||
{
|
||||
if ( a < b )
|
||||
return -1;
|
||||
if ( a == b )
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the "min" FreqSpec sub-element of a composite FreqSpec.
|
||||
**/
|
||||
static
|
||||
FreqSpec*
|
||||
_gnc_freq_spec_get_min( FreqSpec *fs )
|
||||
{
|
||||
FreqSpec *toRet, *tmpFS;
|
||||
GList *l;
|
||||
|
||||
g_assert( xaccFreqSpecGetType(fs) == COMPOSITE );
|
||||
toRet = NULL;
|
||||
for ( l = xaccFreqSpecCompositeGet(fs);
|
||||
l;
|
||||
l = l->next ) {
|
||||
tmpFS = (FreqSpec*)l->data;
|
||||
|
||||
if ( toRet == NULL ) {
|
||||
toRet = tmpFS;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( gnc_freq_spec_compare( toRet, tmpFS ) > 0 ) {
|
||||
toRet = tmpFS;
|
||||
}
|
||||
}
|
||||
return toRet;
|
||||
}
|
||||
|
||||
int
|
||||
gnc_freq_spec_compare( FreqSpec *a, FreqSpec *b )
|
||||
{
|
||||
FreqType fta, ftb;
|
||||
int tmpInt;
|
||||
|
||||
if ( ! (a && b) ) {
|
||||
return 0;
|
||||
} else if ( !a && b ) {
|
||||
return 1;
|
||||
} else if ( a && !b ) {
|
||||
return -1;
|
||||
} /* else { this else intentionally left blank; both-valid code is
|
||||
* below. } */
|
||||
|
||||
fta = xaccFreqSpecGetType( a );
|
||||
ftb = xaccFreqSpecGetType( b );
|
||||
|
||||
if ( fta == COMPOSITE ) {
|
||||
a = _gnc_freq_spec_get_min( a );
|
||||
fta = xaccFreqSpecGetType( a );
|
||||
}
|
||||
if ( ftb == COMPOSITE ) {
|
||||
b = _gnc_freq_spec_get_min( b );
|
||||
ftb = xaccFreqSpecGetType( b );
|
||||
}
|
||||
|
||||
if ( fta < ftb ) {
|
||||
return -1;
|
||||
} else if ( fta > ftb ) {
|
||||
return 1;
|
||||
} /* else { this else intentionally left blank; '='-case code is
|
||||
* below. */
|
||||
|
||||
switch ( fta /* == ftb */ ) {
|
||||
case INVALID:
|
||||
return 0;
|
||||
break;
|
||||
case ONCE:
|
||||
return g_date_compare( &a->s.once.date,
|
||||
&b->s.once.date );
|
||||
break;
|
||||
case DAILY:
|
||||
tmpInt = int_cmp( a->s.daily.interval_days,
|
||||
b->s.daily.interval_days );
|
||||
if ( tmpInt != 0 ) {
|
||||
return tmpInt;
|
||||
}
|
||||
return int_cmp( a->s.daily.offset_from_epoch,
|
||||
b->s.daily.offset_from_epoch );
|
||||
break;
|
||||
case WEEKLY:
|
||||
tmpInt = int_cmp( a->s.weekly.interval_weeks,
|
||||
b->s.weekly.interval_weeks );
|
||||
if ( tmpInt != 0 ) {
|
||||
return tmpInt;
|
||||
}
|
||||
return int_cmp( a->s.weekly.offset_from_epoch,
|
||||
b->s.weekly.offset_from_epoch );
|
||||
break;
|
||||
case MONTHLY:
|
||||
tmpInt = int_cmp( a->s.monthly.interval_months,
|
||||
b->s.monthly.interval_months );
|
||||
if ( tmpInt != 0 ) {
|
||||
return tmpInt;
|
||||
}
|
||||
return int_cmp( a->s.monthly.day_of_month,
|
||||
b->s.monthly.day_of_month );
|
||||
break;
|
||||
case MONTH_RELATIVE:
|
||||
DEBUG( "MONTH-RELATIVE dates not supported." );
|
||||
g_assert( FALSE );
|
||||
break;
|
||||
case COMPOSITE:
|
||||
/* We shouldn't see a composite after doing the
|
||||
* composite-reduction above. */
|
||||
DEBUG( "This code should not be reached." );
|
||||
g_assert( FALSE );
|
||||
break;
|
||||
default:
|
||||
DEBUG( "Unknown freqspec type %d", fta );
|
||||
g_assert( FALSE );
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -206,4 +206,11 @@ void xaccFreqSpecGetNextInstance( FreqSpec *fs,
|
||||
const GDate* in_date,
|
||||
GDate* out_date );
|
||||
|
||||
/**
|
||||
* qsort-style comparison of FreqSpecs.
|
||||
* More frequently-occuring FreqSpecs are sorted before less-frequent FreqSpecs.
|
||||
* FIXME: What to do for composites?
|
||||
**/
|
||||
int gnc_freq_spec_compare( FreqSpec *a, FreqSpec *b );
|
||||
|
||||
#endif /* XACC_FREQSPEC_H */
|
||||
|
||||
@@ -94,6 +94,9 @@ struct _SchedXactionDialog
|
||||
GladeXML *gxml;
|
||||
GncDenseCal *gdcal;
|
||||
GHashTable *sxData;
|
||||
|
||||
gint currentSortCol;
|
||||
GtkSortType currentSortType;
|
||||
};
|
||||
|
||||
struct _SchedXactionEditorDialog
|
||||
@@ -150,6 +153,19 @@ static void edit_button_clicked( GtkButton *b, gpointer d );
|
||||
static void delete_button_clicked( GtkButton *b, gpointer d );
|
||||
static void close_button_clicked( GtkButton *b, gpointer d );
|
||||
static void gnc_sxl_record_size( SchedXactionDialog *sxd );
|
||||
static void gnc_sxd_row_click_handler( GtkCList *clist,
|
||||
gint col,
|
||||
gpointer ud );
|
||||
static void gnc_sxd_set_sort_compare( GtkCList *cl, gint col );
|
||||
static gint 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 );
|
||||
static gint gnc_sxd_clist_compare_sx_next_occur( GtkCList *cl,
|
||||
gconstpointer a,
|
||||
gconstpointer b );
|
||||
|
||||
static void gnc_sxed_record_size( SchedXactionEditorDialog *sxed );
|
||||
static void gnc_sxed_get_widgets( SchedXactionEditorDialog *sxed );
|
||||
@@ -977,6 +993,18 @@ gnc_ui_scheduled_xaction_dialog_create(void)
|
||||
gtk_signal_connect( GTK_OBJECT(button), "clicked",
|
||||
GTK_SIGNAL_FUNC(close_button_clicked), sxd );
|
||||
|
||||
w = glade_xml_get_widget( sxd->gxml, SX_LIST );
|
||||
gtk_signal_connect(GTK_OBJECT(w), "select-row",
|
||||
GTK_SIGNAL_FUNC(row_select_handler), sxd );
|
||||
gtk_signal_connect( GTK_OBJECT(w), "click-column",
|
||||
GTK_SIGNAL_FUNC(gnc_sxd_row_click_handler), sxd );
|
||||
|
||||
/* Default to sorting by ascending next-instance date. */
|
||||
sxd->currentSortCol = 2;
|
||||
sxd->currentSortType = GTK_SORT_ASCENDING;
|
||||
gnc_sxd_set_sort_compare( GTK_CLIST(w), sxd->currentSortCol );
|
||||
gtk_clist_set_auto_sort( GTK_CLIST(w), TRUE );
|
||||
|
||||
{
|
||||
int width, height;
|
||||
|
||||
@@ -1071,8 +1099,6 @@ schedXact_populate( SchedXactionDialog *sxd )
|
||||
for ( i=0; i<3; i++ ) {
|
||||
gtk_clist_set_column_auto_resize( sx_clist, i, TRUE );
|
||||
}
|
||||
gtk_signal_connect(GTK_OBJECT(sx_clist), "select-row",
|
||||
GTK_SIGNAL_FUNC(row_select_handler), sxd );
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@@ -1141,7 +1167,7 @@ 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) },
|
||||
@@ -1689,21 +1715,11 @@ generate_instances( SchedXaction *sx,
|
||||
seqStateData = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* In this version, we're just updating the clist so the column data is
|
||||
* correct. We already have valid hash table and dense-cal mappings.
|
||||
**/
|
||||
static
|
||||
void
|
||||
update_clist( gpointer data, gpointer user_data )
|
||||
_gnc_sxd_free_dates( gpointer data, gpointer user_data )
|
||||
{
|
||||
SchedXaction *sx;
|
||||
SchedXactionDialog *sxd;
|
||||
|
||||
sx = (SchedXaction*)data;
|
||||
sxd = (SchedXactionDialog*)user_data;
|
||||
|
||||
|
||||
g_date_free( (GDate*)data );
|
||||
}
|
||||
|
||||
static
|
||||
@@ -1742,6 +1758,22 @@ putSchedXactionInDialog( gpointer data, gpointer user_data )
|
||||
generate_instances( sx, calEndDate, &instList );
|
||||
g_date_free( calEndDate );
|
||||
|
||||
/* FIXME: 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.
|
||||
*/
|
||||
nextInstDate = g_date_new();
|
||||
*nextInstDate = xaccSchedXactionGetNextInstance( sx, NULL );
|
||||
if ( g_date_valid( nextInstDate ) ) {
|
||||
instList = g_list_append( instList,
|
||||
(gpointer)nextInstDate );
|
||||
}
|
||||
}
|
||||
|
||||
if ( instList == NULL ) {
|
||||
g_string_sprintf( nextDate, "not scheduled" );
|
||||
} else {
|
||||
@@ -1771,6 +1803,7 @@ putSchedXactionInDialog( gpointer data, gpointer user_data )
|
||||
xaccSchedXactionGetName(sx),
|
||||
freqDesc->str );
|
||||
g_string_free( freqDesc, TRUE );
|
||||
g_list_foreach( instList, _gnc_sxd_free_dates, NULL );
|
||||
g_list_free( instList );
|
||||
g_free( instArray );
|
||||
}
|
||||
@@ -1804,6 +1837,7 @@ putSchedXactionInDialog( gpointer data, gpointer user_data )
|
||||
gtk_clist_set_text( clist, row, i, text[i] );
|
||||
}
|
||||
}
|
||||
gtk_clist_sort( clist );
|
||||
gtk_clist_thaw( clist );
|
||||
g_hash_table_insert( sxd->sxData, (gpointer)sx, (gpointer)gdcMarkTag );
|
||||
|
||||
@@ -1893,3 +1927,137 @@ editor_component_sx_equality( gpointer find_data,
|
||||
return ( (SchedXaction*)find_data
|
||||
== ((SchedXactionEditorDialog*)user_data)->sx );
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
gnc_sxd_row_click_handler( GtkCList *clist,
|
||||
gint col,
|
||||
gpointer ud )
|
||||
{
|
||||
SchedXactionDialog *sxd = (SchedXactionDialog*)ud;
|
||||
|
||||
if ( col == sxd->currentSortCol ) {
|
||||
g_assert( sxd->currentSortType == GTK_SORT_ASCENDING
|
||||
|| sxd->currentSortType == GTK_SORT_DESCENDING );
|
||||
switch ( sxd->currentSortType ) {
|
||||
case GTK_SORT_ASCENDING:
|
||||
sxd->currentSortType = GTK_SORT_DESCENDING;
|
||||
break;
|
||||
case GTK_SORT_DESCENDING:
|
||||
sxd->currentSortType = GTK_SORT_ASCENDING;
|
||||
break;
|
||||
default:
|
||||
PERR( "Unknown current sort type %d", sxd->currentSortType );
|
||||
}
|
||||
/* By defn, the current sort_compare method is correct. */
|
||||
gtk_clist_set_sort_column( clist, col );
|
||||
gtk_clist_set_sort_type( clist, sxd->currentSortType );
|
||||
gtk_clist_sort( clist );
|
||||
return;
|
||||
}
|
||||
|
||||
sxd->currentSortCol = col;
|
||||
gnc_sxd_set_sort_compare( clist, sxd->currentSortCol );
|
||||
sxd->currentSortType = GTK_SORT_ASCENDING;
|
||||
gtk_clist_set_sort_column( clist, sxd->currentSortCol );
|
||||
gtk_clist_set_sort_type( clist, sxd->currentSortType );
|
||||
gtk_clist_sort( clist );
|
||||
}
|
||||
|
||||
static
|
||||
gint
|
||||
gnc_sxd_clist_compare_sx_name( GtkCList *cl, gconstpointer a, gconstpointer b )
|
||||
{
|
||||
SchedXaction *sxa, *sxb;
|
||||
|
||||
sxa = (SchedXaction*)(((GtkCListRow*)a)->data);
|
||||
sxb = (SchedXaction*)(((GtkCListRow*)b)->data);
|
||||
g_assert( sxa || sxb );
|
||||
if ( !sxa ) {
|
||||
return 1;
|
||||
}
|
||||
if ( !sxb ) {
|
||||
return -1;
|
||||
}
|
||||
return strcmp( xaccSchedXactionGetName( sxa ),
|
||||
xaccSchedXactionGetName( sxb ) );
|
||||
}
|
||||
|
||||
static
|
||||
gint
|
||||
gnc_sxd_clist_compare_sx_freq( GtkCList *cl, gconstpointer a, gconstpointer b )
|
||||
{
|
||||
SchedXaction *sxa, *sxb;
|
||||
|
||||
g_assert( a || b );
|
||||
if ( !a ) return 1;
|
||||
if ( !b ) return -1;
|
||||
sxa = (SchedXaction*)((GtkCListRow*)a)->data;
|
||||
sxb = (SchedXaction*)((GtkCListRow*)b)->data;
|
||||
g_assert( sxa || sxb );
|
||||
if ( !sxa ) return 1;
|
||||
if ( !sxb ) return -1;
|
||||
return gnc_freq_spec_compare( xaccSchedXactionGetFreqSpec( sxa ),
|
||||
xaccSchedXactionGetFreqSpec( sxb ) );
|
||||
}
|
||||
|
||||
static
|
||||
gint
|
||||
gnc_sxd_clist_compare_sx_next_occur( GtkCList *cl,
|
||||
gconstpointer a,
|
||||
gconstpointer b )
|
||||
{
|
||||
SchedXaction *sxa, *sxb;
|
||||
GDate gda, gdb;
|
||||
|
||||
sxa = (SchedXaction*)((GtkCListRow*)a)->data;
|
||||
sxb = (SchedXaction*)((GtkCListRow*)b)->data;
|
||||
|
||||
g_assert( sxa || sxb );
|
||||
if ( !sxa ) {
|
||||
return 1;
|
||||
}
|
||||
if ( !sxb ) {
|
||||
return -1;
|
||||
}
|
||||
g_assert( sxa && sxb );
|
||||
|
||||
gda = xaccSchedXactionGetNextInstance( sxa, NULL );
|
||||
gdb = xaccSchedXactionGetNextInstance( sxb, NULL );
|
||||
|
||||
if ( ! ( g_date_valid(&gda) && g_date_valid(&gdb) ) ) {
|
||||
return 0;
|
||||
}
|
||||
if ( !g_date_valid(&gda) ) {
|
||||
return 1;
|
||||
}
|
||||
if ( !g_date_valid(&gdb) ) {
|
||||
return -1;
|
||||
}
|
||||
return g_date_compare( &gda, &gdb );
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
void
|
||||
gnc_sxd_set_sort_compare( GtkCList *cl, gint col )
|
||||
{
|
||||
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 );
|
||||
break;
|
||||
case 1: /* SX frequency */
|
||||
gtk_clist_set_compare_func( cl, NULL );
|
||||
gtk_clist_set_compare_func( cl, 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 );
|
||||
break;
|
||||
default: /* ?? */
|
||||
DEBUG( "invalid column value %d", col );
|
||||
g_assert( FALSE );
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user