X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fui%2Fgui%2Ffind-dialog.c;h=16f5e365761a12ab3b13cec78ea4d91e42da3bce;hb=339f1956cc72;hp=52f26d4a695c64df49a4658d6be6d0b3e64caa37;hpb=96994a54e60e9c95b8bba54c2281acf7059b1203;p=pspp diff --git a/src/ui/gui/find-dialog.c b/src/ui/gui/find-dialog.c index 52f26d4a69..16f5e36576 100644 --- a/src/ui/gui/find-dialog.c +++ b/src/ui/gui/find-dialog.c @@ -25,6 +25,7 @@ which match particular strings */ #include #include #include +#include #include "data/data-in.h" #include "data/datasheet.h" @@ -100,15 +101,17 @@ refresh (GObject *obj, const struct find_dialog *fd) static void do_find (GObject *obj, const struct find_dialog *fd) { + SswSheet *sheet = SSW_SHEET (fd->de->data_editor->data_sheet); casenumber x = -1; gint column = -1; - glong row = -1; + gint unused; + gint row = 0; + ssw_sheet_get_active_cell (sheet, &unused, &row); find_value (fd, row, &x, &column); if (x != -1) { - SswSheet *sheet = SSW_SHEET (fd->de->data_editor->data_sheet); gtk_notebook_set_current_page (GTK_NOTEBOOK (fd->de->data_editor), PSPPIRE_DATA_EDITOR_DATA_VIEW); @@ -310,8 +313,8 @@ cp1c (casenumber current, struct datasheet *data) static casenumber cm1 (casenumber current, struct datasheet *data) { - if (current == -1) - return datasheet_get_n_rows (data); + if (current == 0) + return datasheet_get_n_rows (data) - 1; return current - 1; } @@ -322,9 +325,6 @@ cm1c (casenumber current, struct datasheet *data) { casenumber next = current; - if (current == -1) - return datasheet_get_n_rows (data); - backward_wrap (&next, data); return next; @@ -340,9 +340,6 @@ last (casenumber current, struct datasheet *data) static casenumber minus1 (casenumber current, struct datasheet *data) { - if (current == -1) - return 0; - return -1; } @@ -367,11 +364,18 @@ enum iteration_type{ n_iterators }; -static const struct casenum_iterator ip[n_iterators] = +static const struct casenum_iterator case_iterator[n_iterators] = { + /* Forward iterator (linear) */ {cp1, last, forward}, + + /* Forward iterator (circular) */ {cp1c, cm1, forward_wrap}, + + /* Reverse iterator (linear) */ {cm1, minus1, backward}, + + /* Reverse iterator (circular */ {cm1c, cp1, backward_wrap} }; @@ -390,16 +394,16 @@ get_iteration_params (const struct find_dialog *fd) if (wrap) { if (reverse) - return &ip[REVERSE_WRAP]; + return &case_iterator[REVERSE_WRAP]; else - return &ip[FORWARD_WRAP]; + return &case_iterator[FORWARD_WRAP]; } else { if (reverse) - return &ip[REVERSE]; + return &case_iterator[REVERSE]; else - return &ip[FORWARD]; + return &case_iterator[FORWARD]; } } @@ -428,11 +432,13 @@ struct comparator }; -/* A comparator which operates on the unadulterated union values */ -struct value_comparator +/* A comparator which operates on the numerical values, + rounded to the number of decimal places indicated by + the variable's format. */ +struct numeric_comparator { struct comparator parent; - union value pattern; + double rounded_ref; }; /* A comparator which matches string values or parts thereof */ @@ -449,13 +455,29 @@ struct regexp_comparator regex_t re; }; +/* Returns 10 raised to the power of X. + X must be a non-negative integer. */ +static inline int +int_pow10 (int x) +{ + int ret = 1; + assert (x >= 0); + while (x--) + ret *= 10; + + return ret; +} static bool value_compare (const struct comparator *cmptr, const union value *v) { - const struct value_comparator *vc = (const struct value_comparator *) cmptr; - return 0 == value_compare_3way (v, &vc->pattern, var_get_width (cmptr->var)); + const struct numeric_comparator *nc = (const struct numeric_comparator *) cmptr; + const struct fmt_spec *fs = var_get_print_format (cmptr->var); + + double c = nearbyint (v->f * int_pow10 (fs->d)); + + return c == nc->rounded_ref; } @@ -572,27 +594,21 @@ regexp_destroy (struct comparator *cmptr) regfree (&rec->re); } -static void -cmptr_value_destroy (struct comparator *cmptr) -{ - struct value_comparator *vc - = UP_CAST (cmptr, struct value_comparator, parent); - value_destroy (&vc->pattern, var_get_width (cmptr->var)); -} - - static struct comparator * -value_comparator_create (const struct variable *var, const char *target) +numeric_comparator_create (const struct variable *var, const char *target) { - struct value_comparator *vc = xzalloc (sizeof (*vc)); - struct comparator *cmptr = &vc->parent; + struct numeric_comparator *nc = XZALLOC (struct numeric_comparator); + struct comparator *cmptr = &nc->parent; cmptr->flags = 0; cmptr->var = var; - cmptr->compare = value_compare ; - cmptr->destroy = cmptr_value_destroy; + cmptr->compare = value_compare; + const struct fmt_spec *fs = var_get_write_format (var); - text_to_value (target, var, &vc->pattern); + union value val; + text_to_value (target, var, &val); + nc->rounded_ref = nearbyint (val.f * int_pow10 (fs->d)); + value_destroy (&val, var_get_width (var)); return cmptr; } @@ -601,7 +617,7 @@ static struct comparator * string_comparator_create (const struct variable *var, const char *target, enum string_cmp_flags flags) { - struct string_comparator *ssc = xzalloc (sizeof (*ssc)); + struct string_comparator *ssc = XZALLOC (struct string_comparator); struct comparator *cmptr = &ssc->parent; cmptr->flags = flags; @@ -623,7 +639,7 @@ regexp_comparator_create (const struct variable *var, const char *target, enum string_cmp_flags flags) { int code; - struct regexp_comparator *rec = xzalloc (sizeof (*rec)); + struct regexp_comparator *rec = XZALLOC (struct regexp_comparator); struct comparator *cmptr = &rec->parent; cmptr->flags = flags; @@ -686,7 +702,7 @@ comparator_factory (const struct variable *var, const char *str, if (flags & (STR_CMP_SUBSTR | STR_CMP_LABELS)) return string_comparator_create (var, str, flags); - return value_comparator_create (var, str); + return numeric_comparator_create (var, str); }