Add a cmp() function for Recurrence (lists).

git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@15631 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
Joshua Sled 2007-02-19 22:08:57 +00:00
parent c123a68e28
commit 3373f77979
4 changed files with 93 additions and 3 deletions

View File

@ -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

View File

@ -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);
}

View File

@ -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 */

View File

@ -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