projects
/
pspp
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
Introduce Arg class.
[pspp]
/
src
/
ui
/
gui
/
find-dialog.c
diff --git
a/src/ui/gui/find-dialog.c
b/src/ui/gui/find-dialog.c
index 765a3a65d257d8acd730bd72003262e3e62da0da..16f5e365761a12ab3b13cec78ea4d91e42da3bce 100644
(file)
--- a/
src/ui/gui/find-dialog.c
+++ b/
src/ui/gui/find-dialog.c
@@
-1,5
+1,5
@@
/* PSPPIRE - a graphical user interface for PSPP.
/* PSPPIRE - a graphical user interface for PSPP.
- Copyright (C) 2007, 2009, 2011, 2012 Free Software Foundation
+ Copyright (C) 2007, 2009, 2011, 2012
, 2015, 2020
Free Software Foundation
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@
-25,6
+25,7
@@
which match particular strings */
#include <regex.h>
#include <stdlib.h>
#include <sys/types.h>
#include <regex.h>
#include <stdlib.h>
#include <sys/types.h>
+#include <math.h>
#include "data/data-in.h"
#include "data/datasheet.h"
#include "data/data-in.h"
#include "data/datasheet.h"
@@
-36,11
+37,11
@@
which match particular strings */
#include "ui/gui/dict-display.h"
#include "ui/gui/find-dialog.h"
#include "ui/gui/helper.h"
#include "ui/gui/dict-display.h"
#include "ui/gui/find-dialog.h"
#include "ui/gui/helper.h"
-#include "ui/gui/psppire-data-sheet.h"
#include "ui/gui/psppire-data-store.h"
#include "ui/gui/psppire-data-window.h"
#include "ui/gui/psppire-dialog.h"
#include "ui/gui/psppire-selector.h"
#include "ui/gui/psppire-data-store.h"
#include "ui/gui/psppire-data-window.h"
#include "ui/gui/psppire-dialog.h"
#include "ui/gui/psppire-selector.h"
+#include <ssw-sheet.h>
#include "gl/xalloc.h"
#include "gl/xalloc.h"
@@
-100,28
+101,23
@@
refresh (GObject *obj, const struct find_dialog *fd)
static void
do_find (GObject *obj, const struct find_dialog *fd)
{
static void
do_find (GObject *obj, const struct find_dialog *fd)
{
-
PsppireDataSheet *data_sheet
;
+
SswSheet *sheet = SSW_SHEET (fd->de->data_editor->data_sheet)
;
casenumber x = -1;
gint column = -1;
casenumber x = -1;
gint column = -1;
- glong row;
-
- data_sheet = psppire_data_editor_get_active_data_sheet (fd->de->data_editor);
- row = psppire_data_sheet_get_selected_case (data_sheet);
- if ( row < 0 )
- row = 0;
+ gint unused;
+ gint row = 0;
+ ssw_sheet_get_active_cell (sheet, &unused, &row);
find_value (fd, row, &x, &column);
find_value (fd, row, &x, &column);
-
- if ( x != -1)
+ if (x != -1)
{
gtk_notebook_set_current_page (GTK_NOTEBOOK (fd->de->data_editor),
PSPPIRE_DATA_EDITOR_DATA_VIEW);
{
gtk_notebook_set_current_page (GTK_NOTEBOOK (fd->de->data_editor),
PSPPIRE_DATA_EDITOR_DATA_VIEW);
-
psppire_data_sheet_goto_case (data_sheet
, x);
-
psppire_data_sheet_goto_variable (data_sheet, column
);
+
ssw_sheet_scroll_to (sheet, column
, x);
+
ssw_sheet_set_active_cell (sheet, column, x, NULL
);
}
}
-
}
/* Callback on the selector.
}
/* Callback on the selector.
@@
-276,7
+272,7
@@
forward (casenumber *i, struct datasheet *data UNUSED)
static void
forward_wrap (casenumber *i, struct datasheet *data)
{
static void
forward_wrap (casenumber *i, struct datasheet *data)
{
- if (
++*i >= datasheet_get_n_rows (data)
) *i = 0;
+ if (
++*i >= datasheet_get_n_rows (data)
) *i = 0;
}
static void
}
static void
@@
-289,7
+285,7
@@
backward (casenumber *i, struct datasheet *data UNUSED)
static void
backward_wrap (casenumber *i, struct datasheet *data)
{
static void
backward_wrap (casenumber *i, struct datasheet *data)
{
- if (
--*i < 0
)
+ if (
--*i < 0
)
*i = datasheet_get_n_rows (data) - 1;
}
*i = datasheet_get_n_rows (data) - 1;
}
@@
-317,6
+313,9
@@
cp1c (casenumber current, struct datasheet *data)
static casenumber
cm1 (casenumber current, struct datasheet *data)
{
static casenumber
cm1 (casenumber current, struct datasheet *data)
{
+ if (current == 0)
+ return datasheet_get_n_rows (data) - 1;
+
return current - 1;
}
return current - 1;
}
@@
-365,11
+364,18
@@
enum iteration_type{
n_iterators
};
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},
{cp1, last, forward},
+
+ /* Forward iterator (circular) */
{cp1c, cm1, forward_wrap},
{cp1c, cm1, forward_wrap},
+
+ /* Reverse iterator (linear) */
{cm1, minus1, backward},
{cm1, minus1, backward},
+
+ /* Reverse iterator (circular */
{cm1c, cp1, backward_wrap}
};
{cm1c, cp1, backward_wrap}
};
@@
-385,19
+391,19
@@
get_iteration_params (const struct find_dialog *fd)
gboolean reverse = gtk_toggle_button_get_active
(GTK_TOGGLE_BUTTON (get_widget_assert (fd->xml, "find-backwards")));
gboolean reverse = gtk_toggle_button_get_active
(GTK_TOGGLE_BUTTON (get_widget_assert (fd->xml, "find-backwards")));
- if (
wrap
)
+ if (
wrap
)
{
{
- if (
reverse
)
- return &
ip
[REVERSE_WRAP];
+ if (
reverse
)
+ return &
case_iterator
[REVERSE_WRAP];
else
else
- return &
ip
[FORWARD_WRAP];
+ return &
case_iterator
[FORWARD_WRAP];
}
else
{
}
else
{
- if (
reverse
)
- return &
ip
[REVERSE];
+ if (
reverse
)
+ return &
case_iterator
[REVERSE];
else
else
- return &
ip
[FORWARD];
+ return &
case_iterator
[FORWARD];
}
}
}
}
@@
-426,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;
{
struct comparator parent;
-
union value pattern
;
+
double rounded_ref
;
};
/* A comparator which matches string values or parts thereof */
};
/* A comparator which matches string values or parts thereof */
@@
-447,13
+455,29
@@
struct regexp_comparator
regex_t re;
};
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)
{
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;
}
}
@@
-473,11
+497,11
@@
string_label_compare (const struct comparator *cmptr,
width = strlen (text);
width = strlen (text);
- assert (
cmptr->flags & STR_CMP_LABELS);
+ assert (cmptr->flags & STR_CMP_LABELS);
g_return_val_if_fail (width > 0, false);
g_return_val_if_fail (width > 0, false);
- if (
cmptr->flags & STR_CMP_SUBSTR)
+ if (cmptr->flags & STR_CMP_SUBSTR)
return (NULL != g_strstr_len (text, width, ssc->pattern));
else
return (0 == strncmp (text, ssc->pattern, width));
return (NULL != g_strstr_len (text, width, ssc->pattern));
else
return (0 == strncmp (text, ssc->pattern, width));
@@
-495,11
+519,11
@@
string_value_compare (const struct comparator *cmptr,
int width = var_get_width (cmptr->var);
g_return_val_if_fail (width > 0, false);
int width = var_get_width (cmptr->var);
g_return_val_if_fail (width > 0, false);
- assert (
! (cmptr->flags & STR_CMP_LABELS));
+ assert (! (cmptr->flags & STR_CMP_LABELS));
text = value_to_text (*val, cmptr->var);
text = value_to_text (*val, cmptr->var);
- if (
cmptr->flags & STR_CMP_SUBSTR)
+ if (cmptr->flags & STR_CMP_SUBSTR)
found = (NULL != g_strstr_len (text, width, ssc->pattern));
else
found = (0 == strncmp (text, ssc->pattern, width));
found = (NULL != g_strstr_len (text, width, ssc->pattern));
else
found = (0 == strncmp (text, ssc->pattern, width));
@@
-522,7
+546,7
@@
regexp_value_compare (const struct comparator *cmptr,
int width = var_get_width (cmptr->var);
int width = var_get_width (cmptr->var);
- assert (
! (cmptr->flags & STR_CMP_LABELS)
);
+ assert (
! (cmptr->flags & STR_CMP_LABELS)
);
g_return_val_if_fail (width > 0, false);
g_return_val_if_fail (width > 0, false);
@@
-549,7
+573,7
@@
regexp_label_compare (const struct comparator *cmptr,
int width ;
int width ;
- assert (
cmptr->flags & STR_CMP_LABELS);
+ assert (cmptr->flags & STR_CMP_LABELS);
text = var_lookup_value_label (cmptr->var, val);
width = strlen (text);
text = var_lookup_value_label (cmptr->var, val);
width = strlen (text);
@@
-570,27
+594,21
@@
regexp_destroy (struct comparator *cmptr)
regfree (&rec->re);
}
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 *
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 = &
v
c->parent;
+ struct
numeric_comparator *nc = XZALLOC (struct numeric_comparator
);
+ struct comparator *cmptr = &
n
c->parent;
cmptr->flags = 0;
cmptr->var = var;
cmptr->flags = 0;
cmptr->var = var;
- cmptr->compare = value_compare
;
- c
mptr->destroy = cmptr_value_destroy
;
+ cmptr->compare = value_compare;
+ c
onst 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;
}
return cmptr;
}
@@
-599,13
+617,13
@@
static struct comparator *
string_comparator_create (const struct variable *var, const char *target,
enum string_cmp_flags flags)
{
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;
cmptr->var = var;
struct comparator *cmptr = &ssc->parent;
cmptr->flags = flags;
cmptr->var = var;
- if (
flags & STR_CMP_LABELS)
+ if (flags & STR_CMP_LABELS)
cmptr->compare = string_label_compare;
else
cmptr->compare = string_value_compare;
cmptr->compare = string_label_compare;
else
cmptr->compare = string_value_compare;
@@
-621,7
+639,7
@@
regexp_comparator_create (const struct variable *var, const char *target,
enum string_cmp_flags flags)
{
int code;
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;
struct comparator *cmptr = &rec->parent;
cmptr->flags = flags;
@@
-632,7
+650,7
@@
regexp_comparator_create (const struct variable *var, const char *target,
cmptr->destroy = regexp_destroy;
code = regcomp (&rec->re, target, 0);
cmptr->destroy = regexp_destroy;
code = regcomp (&rec->re, target, 0);
- if (
code != 0
)
+ if (
code != 0
)
{
char *errbuf = NULL;
size_t errbuf_size = regerror (code, &rec->re, errbuf, 0);
{
char *errbuf = NULL;
size_t errbuf_size = regerror (code, &rec->re, errbuf, 0);
@@
-643,7
+661,7
@@
regexp_comparator_create (const struct variable *var, const char *target,
msg (ME, _("Bad regular expression: %s"), errbuf);
msg (ME, _("Bad regular expression: %s"), errbuf);
- free (
cmptr);
+ free (cmptr);
free (errbuf);
return NULL;
}
free (errbuf);
return NULL;
}
@@
-664,10
+682,10
@@
comparator_compare (const struct comparator *cmptr,
static void
comparator_destroy (struct comparator *cmptr)
{
static void
comparator_destroy (struct comparator *cmptr)
{
- if (
! cmptr
)
+ if (
! cmptr
)
return ;
return ;
- if (
cmptr->destroy
)
+ if (
cmptr->destroy
)
cmptr->destroy (cmptr);
free (cmptr);
cmptr->destroy (cmptr);
free (cmptr);
@@
-678,13
+696,13
@@
static struct comparator *
comparator_factory (const struct variable *var, const char *str,
enum string_cmp_flags flags)
{
comparator_factory (const struct variable *var, const char *str,
enum string_cmp_flags flags)
{
- if (
flags & STR_CMP_REGEXP
)
+ if (
flags & STR_CMP_REGEXP
)
return regexp_comparator_create (var, str, flags);
return regexp_comparator_create (var, str, flags);
- if (
flags & (STR_CMP_SUBSTR | STR_CMP_LABELS)
)
+ if (
flags & (STR_CMP_SUBSTR | STR_CMP_LABELS)
)
return string_comparator_create (var, str, flags);
return string_comparator_create (var, str, flags);
- return
value
_comparator_create (var, str);
+ return
numeric
_comparator_create (var, str);
}
}
@@
-702,10
+720,9
@@
find_value (const struct find_dialog *fd, casenumber current_row,
const char *target_string = gtk_entry_get_text (GTK_ENTRY (fd->value_entry));
enum string_cmp_flags flags = 0;
const char *target_string = gtk_entry_get_text (GTK_ENTRY (fd->value_entry));
enum string_cmp_flags flags = 0;
- g_assert (current_row >= 0);
var = dict_lookup_var (fd->dict->dict, var_name);
var = dict_lookup_var (fd->dict->dict, var_name);
- if (
! var
)
+ if (
! var
)
return ;
width = var_get_width (var);
return ;
width = var_get_width (var);
@@
-713,15
+730,15
@@
find_value (const struct find_dialog *fd, casenumber current_row,
*column = var_get_dict_index (var);
*row = -1;
*column = var_get_dict_index (var);
*row = -1;
- if (
gtk_toggle_button_get_active
+ if (gtk_toggle_button_get_active
(GTK_TOGGLE_BUTTON (fd->match_substring_checkbox)))
flags |= STR_CMP_SUBSTR;
(GTK_TOGGLE_BUTTON (fd->match_substring_checkbox)))
flags |= STR_CMP_SUBSTR;
- if (
gtk_toggle_button_get_active
+ if (gtk_toggle_button_get_active
(GTK_TOGGLE_BUTTON (fd->match_regexp_checkbox)))
flags |= STR_CMP_REGEXP;
(GTK_TOGGLE_BUTTON (fd->match_regexp_checkbox)))
flags |= STR_CMP_REGEXP;
- if (
gtk_toggle_button_get_active
+ if (gtk_toggle_button_get_active
(GTK_TOGGLE_BUTTON (fd->value_labels_checkbox)))
flags |= STR_CMP_LABELS;
(GTK_TOGGLE_BUTTON (fd->value_labels_checkbox)))
flags |= STR_CMP_LABELS;
@@
-733,7
+750,7
@@
find_value (const struct find_dialog *fd, casenumber current_row,
comparator_factory (var, target_string, flags);
value_init (&val, width);
comparator_factory (var, target_string, flags);
value_init (&val, width);
- if (
! cmptr)
+ if (! cmptr)
goto finish;
for (i = ip->start (current_row, fd->data);
goto finish;
for (i = ip->start (current_row, fd->data);
@@
-742,7
+759,7
@@
find_value (const struct find_dialog *fd, casenumber current_row,
{
datasheet_get_value (fd->data, i, var_get_case_index (var), &val);
{
datasheet_get_value (fd->data, i, var_get_case_index (var), &val);
- if (
comparator_compare (cmptr, &val))
+ if (comparator_compare (cmptr, &val))
{
*row = i;
break;
{
*row = i;
break;