[gnumeric] Search: add facility to search for numbers regardless of formatting.



commit 0e96bd2d348cbeb8398dbb6b52af436036de330d
Author: Morten Welinder <welinder anemone home>
Date:   Mon May 25 19:35:22 2009 -0400

    Search: add facility to search for numbers regardless of formatting.
---
 ChangeLog                   |    9 +++++
 src/dialogs/ChangeLog       |    4 ++
 src/dialogs/dialog-search.c |    9 +++++-
 src/dialogs/search.glade    |   25 ++++++++++++++-
 src/search.c                |   73 +++++++++++++++++++++++++++++++++++++++++-
 src/search.h                |    4 ++
 6 files changed, 120 insertions(+), 4 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 3fd461e..1bde86e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2009-05-25  Morten Welinder  <terra gnome org>
+
+	* src/search.c (gnm_search_replace_set_property,
+	gnm_search_replace_get_property, gnm_search_replace_class_init):
+	Add new is-number property.
+	(gnm_search_replace_comment): Comments are not numbers.
+	(gnm_search_replace_cell, gnm_search_replace_value): Handle number
+	search.
+
 2009-05-24  Andreas J. Guelzow <aguelzow pyrshep ca>
 
 	* configure.in: increase libgsf requirement to 1.14.15
diff --git a/src/dialogs/ChangeLog b/src/dialogs/ChangeLog
index 9149268..d042ea9 100644
--- a/src/dialogs/ChangeLog
+++ b/src/dialogs/ChangeLog
@@ -1,3 +1,7 @@
+2009-05-25  Morten Welinder  <terra gnome org>
+
+	* dialog-search.c (search_clicked): Handle number search.
+
 2009-05-23  Morten Welinder <terra gnome org>
 
 	* Release 1.9.8
diff --git a/src/dialogs/dialog-search.c b/src/dialogs/dialog-search.c
index 5b5979f..61bf8d0 100644
--- a/src/dialogs/dialog-search.c
+++ b/src/dialogs/dialog-search.c
@@ -72,6 +72,7 @@ typedef struct {
 static const char * const search_type_group[] = {
 	"search_type_text",
 	"search_type_regexp",
+	"search_type_number",
 	NULL
 };
 
@@ -287,10 +288,15 @@ search_clicked (G_GNUC_UNUSED GtkWidget *widget, DialogState *dd)
 	int i;
 	GnmSearchReplaceScope scope;
 	char *text;
+	gboolean is_regexp, is_number;
 
 	i = gnumeric_glade_group_value (gui, scope_group);
 	scope = (i == -1) ? GNM_SRS_SHEET : (GnmSearchReplaceScope)i;
 
+	i = gnumeric_glade_group_value (gui, search_type_group);
+	is_regexp = (i == 1);
+	is_number = (i == 2);
+
 	text = g_utf8_normalize (gtk_entry_get_text (dd->gentry), -1, G_NORMALIZE_DEFAULT);
 
 	sr = g_object_new (GNM_SEARCH_REPLACE_TYPE,
@@ -298,7 +304,8 @@ search_clicked (G_GNUC_UNUSED GtkWidget *widget, DialogState *dd)
 			   "scope", scope,
 			   "range-text", gnm_expr_entry_get_text (dd->rangetext),
 			   "search-text", text,
-			   "is-regexp", gnumeric_glade_group_value (gui, search_type_group) == 1,
+			   "is-regexp", is_regexp,
+			   "is-number", is_number,
 			   "ignore-case", is_checked (gui, "ignore_case"),
 			   "match-words", is_checked (gui, "match_words"),
 			   "search-strings", is_checked (gui, "search_string"),
diff --git a/src/dialogs/search.glade b/src/dialogs/search.glade
index e0e6306..654e0e0 100644
--- a/src/dialogs/search.glade
+++ b/src/dialogs/search.glade
@@ -501,7 +501,7 @@
 			<widget class="GtkTable" id="table5">
 			  <property name="border_width">12</property>
 			  <property name="visible">True</property>
-			  <property name="n_rows">2</property>
+			  <property name="n_rows">3</property>
 			  <property name="n_columns">1</property>
 			  <property name="homogeneous">True</property>
 			  <property name="row_spacing">6</property>
@@ -551,6 +551,29 @@
 			      <property name="y_options"></property>
 			    </packing>
 			  </child>
+
+			  <child>
+			    <widget class="GtkRadioButton" id="search_type_number">
+			      <property name="visible">True</property>
+			      <property name="can_focus">True</property>
+			      <property name="label" translatable="yes">_Number</property>
+			      <property name="use_underline">True</property>
+			      <property name="relief">GTK_RELIEF_NORMAL</property>
+			      <property name="focus_on_click">True</property>
+			      <property name="active">False</property>
+			      <property name="inconsistent">False</property>
+			      <property name="draw_indicator">True</property>
+			      <property name="group">search_type_text</property>
+			    </widget>
+			    <packing>
+			      <property name="left_attach">0</property>
+			      <property name="right_attach">1</property>
+			      <property name="top_attach">2</property>
+			      <property name="bottom_attach">3</property>
+			      <property name="x_options">fill</property>
+			      <property name="y_options"></property>
+			    </packing>
+			  </child>
 			</widget>
 		      </child>
 
diff --git a/src/search.c b/src/search.c
index f7ab347..894a4a2 100644
--- a/src/search.c
+++ b/src/search.c
@@ -15,6 +15,7 @@
 #include "workbook.h"
 #include "position.h"
 #include "cell.h"
+#include "number-match.h"
 #include "value.h"
 #include "sheet-object-cell-comment.h"
 #include <gsf/gsf-impl-utils.h>
@@ -30,6 +31,7 @@ typedef struct {
 
 enum {
 	PROP_0,
+	PROP_IS_NUMBER,
 	PROP_SEARCH_STRINGS,
 	PROP_SEARCH_OTHER_VALUES,
 	PROP_SEARCH_EXPRESSIONS,
@@ -47,18 +49,58 @@ enum {
 
 /* ------------------------------------------------------------------------- */
 
+static gboolean
+check_number (GnmSearchReplace *sr)
+{
+	GODateConventions const *date_conv =
+		workbook_date_conv (sr->sheet->workbook);
+	GOSearchReplace *gosr = (GOSearchReplace *)sr;
+	GnmValue *v = format_match_number (gosr->search_text, NULL, date_conv);
+
+	if (v) {
+		sr->the_number = value_get_as_float (v);
+		value_release (v);
+		return TRUE;
+	} else {
+		sr->the_number = 0;
+		return FALSE;
+	}
+}
+
+static gboolean
+gnm_search_match_value (GnmSearchReplace const *sr, GnmValue const *val)
+{
+	gnm_float f;
+	if (!VALUE_IS_NUMBER (val))
+		return FALSE;
+
+	f = value_get_as_float (val);
+	/* Exact match for now.  */
+	return (sr->the_number == f);
+}
+
+
 char *
 gnm_search_replace_verify (GnmSearchReplace *sr, gboolean repl)
 {
 	GError *error = NULL;
+	GOSearchReplace *gosr = (GOSearchReplace *)sr;
 	g_return_val_if_fail (sr != NULL, NULL);
 
-	if (!go_search_replace_verify (GO_SEARCH_REPLACE (sr), repl, &error)) {
+	if (!go_search_replace_verify (gosr, repl, &error)) {
 		char *msg = g_strdup (error->message);
 		g_error_free (error);
 		return msg;
 	}
 
+	if (sr->is_number && gosr->is_regexp)
+		return g_strdup (_("Searching for regular expressions and numbers are mutually exclusive."));
+
+	if (sr->is_number) {
+		if (!check_number (sr))
+			return g_strdup (_("The search text must be a number."));
+	}
+
 	if (sr->scope == GNM_SRS_RANGE) {
 		GSList *range_list;
 
@@ -194,6 +236,9 @@ gnm_search_filter_matching (GnmSearchReplace *sr, const GPtrArray *cells)
 	unsigned i;
 	GPtrArray *result = g_ptr_array_new ();
 
+	if (sr->is_number)
+		check_number (sr);
+
 	for (i = 0; i < cells->len; i++) {
 		GnmSearchReplaceCellResult cell_res;
 		GnmSearchReplaceValueResult value_res;
@@ -259,6 +304,7 @@ gnm_search_replace_comment (GnmSearchReplace *sr,
 	g_return_val_if_fail (sr, FALSE);
 
 	if (!sr->search_comments) return FALSE;
+	if (sr->is_number) return FALSE;
 
 	res->comment = sheet_get_comment (ep->sheet, &ep->eval);
 	if (!res->comment) return FALSE;
@@ -311,6 +357,12 @@ gnm_search_replace_cell (GnmSearchReplace *sr,
 	is_string = is_value && (VALUE_IS_STRING (v));
 	is_other = is_value && !is_string;
 
+	if (sr->is_number) {
+		if (!is_value || !VALUE_IS_NUMBER (v))
+			return FALSE;
+		return gnm_search_match_value (sr, v);
+	}
+
 	if ((is_expr && sr->search_expressions) ||
 	    (is_string && sr->search_strings) ||
 	    (is_other && sr->search_other_values)) {
@@ -370,7 +422,9 @@ gnm_search_replace_value (GnmSearchReplace *sr,
 	cell = res->cell = sheet_cell_get (ep->sheet, ep->eval.col, ep->eval.row);
 	if (!cell || !gnm_cell_has_expr (cell) || !cell->value)
 		return FALSE;
-	else {
+	else if (sr->is_number) {
+		return gnm_search_match_value (sr, cell->value);
+	} else {
 		char *val = g_utf8_normalize (value_peek_string (cell->value), -1, G_NORMALIZE_DEFAULT);
 		gboolean res = go_search_match_string (GO_SEARCH_REPLACE (sr), val);
 		g_free (val);
@@ -452,6 +506,9 @@ gnm_search_replace_get_property (GObject     *object,
 	GnmSearchReplace *sr = (GnmSearchReplace *)object;
 
 	switch (property_id) {
+	case PROP_IS_NUMBER:
+		g_value_set_boolean (value, sr->is_number);
+		break;
 	case PROP_SEARCH_STRINGS:
 		g_value_set_boolean (value, sr->search_strings);
 		break;
@@ -526,6 +583,9 @@ gnm_search_replace_set_property (GObject      *object,
 	GnmSearchReplace *sr = (GnmSearchReplace *)object;
 
 	switch (property_id) {
+	case PROP_IS_NUMBER:
+		sr->is_number = g_value_get_boolean (value);
+		break;
 	case PROP_SEARCH_STRINGS:
 		sr->search_strings = g_value_get_boolean (value);
 		break;
@@ -597,6 +657,15 @@ gnm_search_replace_class_init (GObjectClass *gobject_class)
 
 	g_object_class_install_property
 		(gobject_class,
+		 PROP_IS_NUMBER,
+		 g_param_spec_boolean ("is-number",
+				       _("Is Number"),
+				       _("Search for Specific Number Regardless of Formatting?"),
+				       FALSE,
+				       GSF_PARAM_STATIC |
+				       G_PARAM_READWRITE));
+	g_object_class_install_property
+		(gobject_class,
 		 PROP_SEARCH_STRINGS,
 		 g_param_spec_boolean ("search-strings",
 				       _("Search Strings"),
diff --git a/src/search.h b/src/search.h
index 030a420..ea2cdee 100644
--- a/src/search.h
+++ b/src/search.h
@@ -4,6 +4,7 @@
 
 #include <gnumeric.h>
 #include <position.h>
+#include <numbers.h>
 #include <goffice/utils/regutf8.h>
 
 G_BEGIN_DECLS
@@ -56,6 +57,9 @@ struct _GnmSearchReplace {
 
 	gboolean query;		/* Ask before each change.  */
 
+	gboolean is_number;     /* Search for specific number.  */
+	gnm_float the_number;   /* protected. */
+
 	/* The following identify what kinds of cells are the target.  */
 	gboolean search_strings;
 	gboolean search_other_values;



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]