From 3373f7797901dbae1b33e8ed1f0f92cd4fc8fa5d Mon Sep 17 00:00:00 2001 From: Joshua Sled Date: Mon, 19 Feb 2007 22:08:57 +0000 Subject: [PATCH] Add a cmp() function for Recurrence (lists). git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@15631 57a11ea4-9604-0410-9ed3-97b8803252fd --- src/doc/sx.rst | 2 +- src/engine/Recurrence.c | 87 ++++++++++++++++++++++ src/engine/Recurrence.h | 4 + src/gnome/gnc-sx-list-tree-model-adapter.c | 3 +- 4 files changed, 93 insertions(+), 3 deletions(-) diff --git a/src/doc/sx.rst b/src/doc/sx.rst index 2a6f4b137a..b4c67da926 100644 --- a/src/doc/sx.rst +++ b/src/doc/sx.rst @@ -138,7 +138,7 @@ TODO - [x] gnc_sxed_update_cal - [x] gnc_sxed_save_sx - sx list - - [ ] recurrence_cmp(...) + - [x] recurrence_cmp(...) - [x] More compact recurrenceListToString(...). - [ ] remove FreqSpec code - [ ] SX code diff --git a/src/engine/Recurrence.c b/src/engine/Recurrence.c index 3bbffa4494..57fc55eefc 100644 --- a/src/engine/Recurrence.c +++ b/src/engine/Recurrence.c @@ -577,3 +577,90 @@ rtn: return g_string_free(buf, FALSE); } +/** + * The ordering, in increasing degrees of frequent-ness: + * + * day < week < {nth-weekday < month < end-month, last_weekday} < year < once + * + * all the monthly types are basically together, but are broken down + * internally cause they have to be ordered somehow. + **/ +static int cmp_order_indexes[] = +{ + 6, // PERIOD_ONCE + 1, // PERIOD_DAY + 2, // PERIOD_WEEK + // 3, // "semi-monthly" ... Note that this isn't presently used, just the + // // way the code worked out. :( + 4, // PERIOD_MONTH + 4, // PERIOD_END_OF_MONTH + 4, // PERIOD_NTH_WEEKDAY + 4, // PERIOD_LAST_WEEKDAY + 5, // PERIOD_YEAR +}; + +static int cmp_monthly_order_indexes[] = +{ + -1, // PERIOD_ONCE + -1, // PERIOD_DAY + -1, // PERIOD_WEEK + 2, // PERIOD_MONTH + 3, // PERIOD_END_OF_MONTH + 1, // PERIOD_NTH_WEEKDAY + 4, // PERIOD_LAST_WEEKDAY + -1, // PERIOD_YEAR +}; + +int +recurrenceCmp(Recurrence *a, Recurrence *b) +{ + PeriodType period_a, period_b; + int a_order_index, b_order_index; + + g_return_val_if_fail(a != NULL && b != NULL, 0); + g_return_val_if_fail(a != NULL, 1); + g_return_val_if_fail(b != NULL, -1); + + period_a = recurrenceGetPeriodType(a); + period_b = recurrenceGetPeriodType(b); + + a_order_index = cmp_order_indexes[period_a]; + b_order_index = cmp_order_indexes[period_b]; + if (a_order_index != b_order_index) + { + return a_order_index - b_order_index; + } + else if (a_order_index == cmp_order_indexes[PERIOD_MONTH]) + { + // re-order intra-month options: + a_order_index = cmp_monthly_order_indexes[period_a]; + b_order_index = cmp_monthly_order_indexes[period_b]; + g_assert(a_order_index != -1 && b_order_index != -1); + if (a_order_index != b_order_index) + return a_order_index - b_order_index; + } + /* else { the basic periods are equal; compare the multipliers } */ + + { + int a_mult, b_mult; + a_mult = recurrenceGetMultiplier(a); + b_mult = recurrenceGetMultiplier(b); + + return a_mult - b_mult; + } +} + +int +recurrenceListCmp(GList *a, GList *b) +{ + Recurrence *most_freq_a, *most_freq_b; + + g_return_val_if_fail(g_list_length(a) != 0 && g_list_length(b) != 0, 0); + g_return_val_if_fail(g_list_length(a) != 0, -1); + g_return_val_if_fail(g_list_length(b) != 0, 1); + + most_freq_a = (Recurrence*)g_list_nth_data(g_list_sort(a, (GCompareFunc)recurrenceCmp), 0); + most_freq_b = (Recurrence*)g_list_nth_data(g_list_sort(b, (GCompareFunc)recurrenceCmp), 0); + + return recurrenceCmp(most_freq_a, most_freq_b); +} diff --git a/src/engine/Recurrence.h b/src/engine/Recurrence.h index 5d1c26ff0f..4ddc946939 100644 --- a/src/engine/Recurrence.h +++ b/src/engine/Recurrence.h @@ -166,4 +166,8 @@ gboolean recurrenceListIsWeeklyMultiple(GList *recurrences); **/ gchar *recurrenceListToCompactString(GList *recurrence_list); +/** @return integer representing the relationship between @a a and @a b, with the semantics of qsort. **/ +int recurrenceCmp(Recurrence *a, Recurrence *b); +int recurrenceListCmp(GList *a, GList *b); + #endif /* RECURRENCE_H */ diff --git a/src/gnome/gnc-sx-list-tree-model-adapter.c b/src/gnome/gnc-sx-list-tree-model-adapter.c index c6c78ccbca..b66ed66faf 100644 --- a/src/gnome/gnc-sx-list-tree-model-adapter.c +++ b/src/gnome/gnc-sx-list-tree-model-adapter.c @@ -382,8 +382,7 @@ _freq_comparator(GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b, gpointer u if (a_inst == NULL) return 1; if (b_inst == NULL) return -1; - return gnc_freq_spec_compare(xaccSchedXactionGetFreqSpec(a_inst->sx), - xaccSchedXactionGetFreqSpec(b_inst->sx)); + return recurrenceListCmp(gnc_sx_get_schedule(a_inst->sx), gnc_sx_get_schedule(b_inst->sx)); } static gint