[gnumeric] Add new autofilter op. [#647401]



commit 1efc98349a5fee7a5593644da8465b8155a8499d
Author: Andreas J Guelzow <aguelzow pyrshep ca>
Date:   Thu Aug 2 22:07:52 2012 -0600

    Add new autofilter op. [#647401]
    
    2012-08-02  Andreas J. Guelzow <aguelzow pyrshep ca>
    
    	* autofilter-top10.ui: add radio buttons
    	* dialog-autofilter.c (cb_top10_count_changed): handle new buttons
    	(cb_top10_type_changed): simplified)
    	(dialog_auto_filter): handle new buttons
    
    2012-08-02  Andreas J. Guelzow <aguelzow pyrshep ca>
    
    	* openoffice-read.c (oo_filter_cond): adjust call of
    	gnm_filter_condition_new_bucket
    
    2012-08-02  Andreas J. Guelzow <aguelzow pyrshep ca>
    
    	* ms-excel-read.c (excel_read_AUTOFILTER): adjust call to
    	gnm_filter_condition_new_bucket
    	* xlsx-read.c (xlsx_CT_Top10): adjust call to
    	gnm_filter_condition_new_bucket
    
    2012-08-02  Andreas J. Guelzow <aguelzow pyrshep ca>
    
    	* src/sheet-filter.c (gnm_filter_condition_new_bucket): add argument
    	and change all callers
    	(gnm_filter_combo_apply): handle new filter ops
    	* src/sheet-filter.h (gnm_filter_condition_new_bucket): add argument
    	(GNM_FILTER_OP_*): add new values
    	* src/xml-sax-read.c (xml_sax_filter_condition): adjust call to
    	gnm_filter_condition_new_bucket

 ChangeLog                            |   10 +++++
 NEWS                                 |    1 +
 plugins/excel/ChangeLog              |    7 ++++
 plugins/excel/ms-excel-read.c        |    1 +
 plugins/excel/xlsx-read.c            |    2 +-
 plugins/openoffice/ChangeLog         |    5 +++
 plugins/openoffice/openoffice-read.c |    5 ++-
 src/dialogs/ChangeLog                |    7 ++++
 src/dialogs/autofilter-top10.ui      |   40 +++++++++++++++++++++-
 src/dialogs/dialog-autofilter.c      |   46 +++++++++++++++++++++----
 src/sheet-filter.c                   |   61 +++++++++++++++++++++++-----------
 src/sheet-filter.h                   |    7 +++-
 src/xml-sax-read.c                   |    4 +-
 13 files changed, 160 insertions(+), 36 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 57e439a..b365352 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2012-08-02  Andreas J. Guelzow <aguelzow pyrshep ca>
+
+	* src/sheet-filter.c (gnm_filter_condition_new_bucket): add argument
+	and change all callers
+	(gnm_filter_combo_apply): handle new filter ops
+	* src/sheet-filter.h (gnm_filter_condition_new_bucket): add argument
+	(GNM_FILTER_OP_*): add new values
+	* src/xml-sax-read.c (xml_sax_filter_condition): adjust call to
+	gnm_filter_condition_new_bucket
+
 2012-08-01  Morten Welinder  <terra gnome org>
 
 	* src/style-color.c (style_color_new_rgba16): Explicitly use a
diff --git a/NEWS b/NEWS
index a56f168..3754eaa 100644
--- a/NEWS
+++ b/NEWS
@@ -13,6 +13,7 @@ Andreas:
 	* Export/import opacity of fill-colours to/from ODF. [Part of #681009]
 	* Some basic custom-shape support in ODF import.
 	* Map captions onto text rectangles on ODF import.
+	* Add new autofilter op. [#647401]
 
 Jean:
 	* Fix component references issues. [#680190]
diff --git a/plugins/excel/ChangeLog b/plugins/excel/ChangeLog
index 07aeb22..f787dfc 100644
--- a/plugins/excel/ChangeLog
+++ b/plugins/excel/ChangeLog
@@ -1,3 +1,10 @@
+2012-08-02  Andreas J. Guelzow <aguelzow pyrshep ca>
+
+	* ms-excel-read.c (excel_read_AUTOFILTER): adjust call to
+	gnm_filter_condition_new_bucket
+	* xlsx-read.c (xlsx_CT_Top10): adjust call to
+	gnm_filter_condition_new_bucket
+
 2012-08-01  Jean Brefort  <jean brefort normalesup org>
 
 	* excel-xml-read.c (parse_color): Rename style_color_new_i8.
diff --git a/plugins/excel/ms-excel-read.c b/plugins/excel/ms-excel-read.c
index bdc5161..17d0209 100644
--- a/plugins/excel/ms-excel-read.c
+++ b/plugins/excel/ms-excel-read.c
@@ -5907,6 +5907,7 @@ excel_read_AUTOFILTER (BiffQuery *q, ExcelReadSheet *esheet)
 		cond = gnm_filter_condition_new_bucket (
 							(flags & 0x20) ? TRUE  : FALSE,
 							(flags & 0x40) ? FALSE : TRUE,
+							FALSE,
 							(flags >> 7) & 0x1ff);
 
 	if (cond == NULL) {
diff --git a/plugins/excel/xlsx-read.c b/plugins/excel/xlsx-read.c
index 15135d5..2d0bac2 100644
--- a/plugins/excel/xlsx-read.c
+++ b/plugins/excel/xlsx-read.c
@@ -1938,7 +1938,7 @@ xlsx_CT_Top10 (GsfXMLIn *xin, xmlChar const **attrs)
 		else if (attr_bool (xin, attrs, "top", &top)) ;
 		else if (attr_bool (xin, attrs, "percent", &percent)) ;
 
-	if (NULL != (cond = gnm_filter_condition_new_bucket (top, !percent, val)))
+	if (NULL != (cond = gnm_filter_condition_new_bucket (top, !percent, FALSE, val)))
 		gnm_filter_set_condition (state->filter, state->filter_cur_field,
 			cond, FALSE);
 }
diff --git a/plugins/openoffice/ChangeLog b/plugins/openoffice/ChangeLog
index 4ae8abd..49fefc3 100644
--- a/plugins/openoffice/ChangeLog
+++ b/plugins/openoffice/ChangeLog
@@ -1,5 +1,10 @@
 2012-08-02  Andreas J. Guelzow <aguelzow pyrshep ca>
 
+	* openoffice-read.c (oo_filter_cond): adjust call of
+	gnm_filter_condition_new_bucket
+
+2012-08-02  Andreas J. Guelzow <aguelzow pyrshep ca>
+
 	* openoffice-read.c (odf_caption): new, copy of odf_rect + error
 	message
 	(odf_custom_shape): change error message
diff --git a/plugins/openoffice/openoffice-read.c b/plugins/openoffice/openoffice-read.c
index 0e1ed3f..98ecc03 100644
--- a/plugins/openoffice/openoffice-read.c
+++ b/plugins/openoffice/openoffice-read.c
@@ -7195,9 +7195,9 @@ oo_filter_cond (GsfXMLIn *xin, xmlChar const **attrs)
 		{ "!match",		GNM_FILTER_OP_NO_MATCH },
 		{ "empty",		GNM_FILTER_OP_BLANKS },
 		{ "!empty",		GNM_FILTER_OP_NON_BLANKS },
-		{ "bottom percent",	GNM_FILTER_OP_BOTTOM_N_PERCENT },
+		{ "bottom percent",	GNM_FILTER_OP_BOTTOM_N_PERCENT_N },
 		{ "bottom values",	GNM_FILTER_OP_BOTTOM_N },
-		{ "top percent",	GNM_FILTER_OP_TOP_N_PERCENT },
+		{ "top percent",	GNM_FILTER_OP_TOP_N_PERCENT_N },
 		{ "top values",		GNM_FILTER_OP_TOP_N },
 
 		{ NULL,	0 },
@@ -7255,6 +7255,7 @@ oo_filter_cond (GsfXMLIn *xin, xmlChar const **attrs)
 				cond = gnm_filter_condition_new_bucket (
 					0 == (op & GNM_FILTER_OP_BOTTOM_MASK),
 					0 == (op & GNM_FILTER_OP_PERCENT_MASK),
+					0 == (op & GNM_FILTER_OP_REL_N_MASK),
 					value_get_as_float (v));
 			break;
 		}
diff --git a/src/dialogs/ChangeLog b/src/dialogs/ChangeLog
index e4beb32..ba2fb36 100644
--- a/src/dialogs/ChangeLog
+++ b/src/dialogs/ChangeLog
@@ -1,3 +1,10 @@
+2012-08-02  Andreas J. Guelzow <aguelzow pyrshep ca>
+
+	* autofilter-top10.ui: add radio buttons
+	* dialog-autofilter.c (cb_top10_count_changed): handle new buttons
+	(cb_top10_type_changed): simplified)
+	(dialog_auto_filter): handle new buttons
+
 2012-08-01  Jean Brefort  <jean brefort normalesup org>
 
 	* dialog-cell-format.c (setup_color_pickers), (border_get_mstyle),
diff --git a/src/dialogs/autofilter-top10.ui b/src/dialogs/autofilter-top10.ui
index 08c5b9d..28c2089 100644
--- a/src/dialogs/autofilter-top10.ui
+++ b/src/dialogs/autofilter-top10.ui
@@ -97,7 +97,7 @@
               </object>
               <packing>
                 <property name="left_attach">0</property>
-                <property name="top_attach">5</property>
+                <property name="top_attach">7</property>
                 <property name="width">1</property>
                 <property name="height">1</property>
               </packing>
@@ -121,6 +121,42 @@
               </packing>
             </child>
             <child>
+              <object class="GtkRadioButton" id="percentage-largest-number">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">False</property>
+                <property name="use_action_appearance">False</property>
+                <property name="xalign">0</property>
+                <property name="active">True</property>
+                <property name="draw_indicator">True</property>
+                <property name="group">items-largest</property>
+              </object>
+              <packing>
+                <property name="left_attach">0</property>
+                <property name="top_attach">5</property>
+                <property name="width">2</property>
+                <property name="height">1</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkRadioButton" id="percentage-smallest-number">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">False</property>
+                <property name="use_action_appearance">False</property>
+                <property name="xalign">0</property>
+                <property name="active">True</property>
+                <property name="draw_indicator">True</property>
+                <property name="group">items-largest</property>
+              </object>
+              <packing>
+                <property name="left_attach">0</property>
+                <property name="top_attach">6</property>
+                <property name="width">2</property>
+                <property name="height">1</property>
+              </packing>
+            </child>
+            <child>
               <object class="GtkRadioButton" id="items-smallest">
                 <property name="visible">True</property>
                 <property name="can_focus">True</property>
@@ -196,7 +232,7 @@
               </object>
               <packing>
                 <property name="left_attach">1</property>
-                <property name="top_attach">5</property>
+                <property name="top_attach">7</property>
                 <property name="width">1</property>
                 <property name="height">1</property>
               </packing>
diff --git a/src/dialogs/dialog-autofilter.c b/src/dialogs/dialog-autofilter.c
index 996243a..af9cda3 100644
--- a/src/dialogs/dialog-autofilter.c
+++ b/src/dialogs/dialog-autofilter.c
@@ -1,3 +1,4 @@
+/* vim: set sw=8: -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
 /**
  * dialog-autofilter.c:  A pair of dialogs for autofilter conditions
  *
@@ -59,6 +60,8 @@ static char const * const type_group[] = {
 	"items-smallest",
 	"percentage-largest",
 	"percentage-smallest",
+	"percentage-largest-number",
+	"percentage-smallest-number",
 	NULL
 };
 
@@ -171,6 +174,7 @@ cb_autofilter_ok (G_GNUC_UNUSED GtkWidget *button,
 		cond = gnm_filter_condition_new_bucket
 			(!(op & GNM_FILTER_OP_BOTTOM_MASK),
 			 !(op & GNM_FILTER_OP_PERCENT_MASK),
+			 !(op & GNM_FILTER_OP_REL_N_MASK),
 			 count);
 	}
 	if (cond != NULL)
@@ -246,6 +250,27 @@ cb_top10_count_changed (GtkSpinButton *button,
 	g_free(label);
 
 
+	w = go_gtk_builder_get_widget (state->gui, type_group[4]);
+	/* xgettext : %d gives the percentage of item number in the autofilter. */
+	/* This is input to ngettext. */
+	label = g_strdup_printf
+		(ngettext ("Show the top %3d%% of all items",
+			   "Show the top %3d%% of all items", val),
+		 val);
+	gtk_button_set_label (GTK_BUTTON (w),label);
+	g_free(label);
+
+	w = go_gtk_builder_get_widget (state->gui, type_group[5]);
+	/* xgettext : %d gives the percentage of the item number in the autofilter. */
+	/* This is input to ngettext. */
+	label = g_strdup_printf
+		(ngettext ("Show the bottom %3d%% of all items",
+			   "Show the bottom %3d%% of all items", val),
+		 val);
+	gtk_button_set_label (GTK_BUTTON (w),label);
+	g_free(label);
+
+
 }
 
 static void
@@ -256,8 +281,7 @@ cb_top10_type_changed (G_GNUC_UNUSED GtkToggleButton *button,
 	GtkWidget *spin = go_gtk_builder_get_widget (state->gui, "item_count");
 	GtkWidget *label = go_gtk_builder_get_widget (state->gui, "cp-label");
 
-	if (op == GNM_FILTER_OP_TOP_N_PERCENT ||
-	    op == GNM_FILTER_OP_BOTTOM_N_PERCENT) {
+	if ((op & GNM_FILTER_OP_PERCENT_MASK) != 0) {
 		gtk_spin_button_set_range (GTK_SPIN_BUTTON (spin), 1.,
 					   100.);
 		gtk_label_set_text (GTK_LABEL (label), _("Percentage:"));
@@ -491,25 +515,31 @@ dialog_auto_filter (WBCGtk *wbcg,
 		case GNM_FILTER_OP_BOTTOM_N_PERCENT:
 			radio = type_group[3];
 			break;
+		case GNM_FILTER_OP_TOP_N_PERCENT_N:
+			radio = type_group[4];
+			break;
+		case GNM_FILTER_OP_BOTTOM_N_PERCENT_N:
+			radio = type_group[5];
+			break;
 		}
 		w = go_gtk_builder_get_widget (state->gui, radio);
 		gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (w), TRUE);
-		w = go_gtk_builder_get_widget (state->gui, "item_count");
-		gtk_spin_button_set_value (GTK_SPIN_BUTTON (w), cond->count);
 	} else {
 		w = go_gtk_builder_get_widget (state->gui, "items-largest");
 		gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (w), TRUE);
-		w = go_gtk_builder_get_widget (state->gui, "item_count");
-		gtk_spin_button_set_value (GTK_SPIN_BUTTON (w), 1);
 	}
 
+	w = go_gtk_builder_get_widget (state->gui, "item_count");
 	g_signal_connect (G_OBJECT (w),
 			  "value-changed",
 			  G_CALLBACK (cb_top10_count_changed), state);
+	if (cond != NULL && GNM_FILTER_OP_TOP_N == (cond->op[0] & GNM_FILTER_OP_TYPE_MASK))
+		gtk_spin_button_set_value (GTK_SPIN_BUTTON (w), cond->count);
+	else
+		gtk_spin_button_set_value (GTK_SPIN_BUTTON (w),
+				   range_height(&(state->filter->r))/2);
 	cb_top10_count_changed (GTK_SPIN_BUTTON (w), state);
 	cb_top10_type_changed (NULL, state);
-	gtk_spin_button_set_value (GTK_SPIN_BUTTON (w),
-				   range_height(&(state->filter->r))/2);
 
 	rb = type_group;
 	while (*rb != NULL) {
diff --git a/src/sheet-filter.c b/src/sheet-filter.c
index 9eaa6fe..fccceda 100644
--- a/src/sheet-filter.c
+++ b/src/sheet-filter.c
@@ -85,10 +85,12 @@ gnm_filter_condition_new_double (GnmFilterOp op0, GnmValue *v0,
 }
 
 GnmFilterCondition *
-gnm_filter_condition_new_bucket (gboolean top, gboolean absolute, double n)
+gnm_filter_condition_new_bucket (gboolean top, gboolean absolute,
+				 gboolean rel_range, double n)
 {
 	GnmFilterCondition *res = g_new0 (GnmFilterCondition, 1);
-	res->op[0] = GNM_FILTER_OP_TOP_N | (top ? 0 : 1) | (absolute ? 0 : 2);
+	res->op[0] = GNM_FILTER_OP_TOP_N | (top ? 0 : 1) | 
+		(absolute ? 0 : (rel_range ? 2 : 4));
 	res->op[1] = GNM_FILTER_UNUSED;
 	res->count = n;
 	return res;
@@ -454,24 +456,43 @@ gnm_filter_combo_apply (GnmFilterCombo *fcombo, Sheet *target_sheet)
 			col, start_row, col, end_row,
 			(CellIterFunc) cb_filter_non_blanks, target_sheet);
 	else if (0x30 == (cond->op[0] & GNM_FILTER_OP_TYPE_MASK)) {
-		if (cond->op[0] & 0x2) { /* relative */
-			FilterPercentage data;
-			gnm_float	 offset;
-
-			data.find_max = (cond->op[0] & 0x1) ? FALSE : TRUE;
-			data.initialized = FALSE;
-			sheet_foreach_cell_in_range (filter->sheet,
-				CELL_ITER_IGNORE_HIDDEN | CELL_ITER_IGNORE_BLANK,
-				col, start_row, col, end_row,
-				(CellIterFunc) cb_filter_find_percentage, &data);
-			offset = (data.high - data.low) * cond->count / 100.;
-			data.high -= offset;
-			data.low  += offset;
-			data.target_sheet = target_sheet;
-			sheet_foreach_cell_in_range (filter->sheet,
-				CELL_ITER_IGNORE_HIDDEN,
-				col, start_row, col, end_row,
-				(CellIterFunc) cb_hide_unwanted_percentage, &data);
+		if (cond->op[0] & GNM_FILTER_OP_PERCENT_MASK) { /* relative */
+			if (cond->op[0] & GNM_FILTER_OP_REL_N_MASK) {
+				FilterItems data;
+				data.find_max = (cond->op[0] & 0x1) ? FALSE : TRUE;
+				data.elements    = 0;
+				data.count  = 0.5 + cond->count * (end_row - start_row + 1) /100.;
+				if (data.count < 1)
+					data.count = 1;
+				data.vals   = g_alloca (sizeof (GnmValue *) * data.count);
+				sheet_foreach_cell_in_range (filter->sheet,
+							     CELL_ITER_IGNORE_HIDDEN | CELL_ITER_IGNORE_BLANK,
+							     col, start_row, col, end_row,
+							     (CellIterFunc) cb_filter_find_items, &data);
+				data.target_sheet = target_sheet;
+				sheet_foreach_cell_in_range (filter->sheet,
+							     CELL_ITER_IGNORE_HIDDEN,
+							     col, start_row, col, end_row,
+							     (CellIterFunc) cb_hide_unwanted_items, &data);
+			} else {
+				FilterPercentage data;
+				gnm_float	 offset;
+
+				data.find_max = (cond->op[0] & 0x1) ? FALSE : TRUE;
+				data.initialized = FALSE;
+				sheet_foreach_cell_in_range (filter->sheet,
+							     CELL_ITER_IGNORE_HIDDEN | CELL_ITER_IGNORE_BLANK,
+							     col, start_row, col, end_row,
+							     (CellIterFunc) cb_filter_find_percentage, &data);
+				offset = (data.high - data.low) * cond->count / 100.;
+				data.high -= offset;
+				data.low  += offset;
+				data.target_sheet = target_sheet;
+				sheet_foreach_cell_in_range (filter->sheet,
+							     CELL_ITER_IGNORE_HIDDEN,
+							     col, start_row, col, end_row,
+							     (CellIterFunc) cb_hide_unwanted_percentage, &data);
+			}
 		} else { /* absolute */
 			FilterItems data;
 			data.find_max = (cond->op[0] & 0x1) ? FALSE : TRUE;
diff --git a/src/sheet-filter.h b/src/sheet-filter.h
index 29cf4aa..8ce8aa1 100644
--- a/src/sheet-filter.h
+++ b/src/sheet-filter.h
@@ -24,8 +24,12 @@ typedef enum {
 	GNM_FILTER_OP_BOTTOM_N		= 0x31,
 	GNM_FILTER_OP_TOP_N_PERCENT	= 0x32,
 	GNM_FILTER_OP_BOTTOM_N_PERCENT	= 0x33,
+	/* Next two added in 1.11.6 */
+	GNM_FILTER_OP_TOP_N_PERCENT_N	= 0x34,
+	GNM_FILTER_OP_BOTTOM_N_PERCENT_N	= 0x35,
 	GNM_FILTER_OP_BOTTOM_MASK	= 0x01,
-	GNM_FILTER_OP_PERCENT_MASK	= 0x02,
+	GNM_FILTER_OP_REL_N_MASK	= 0x04,
+	GNM_FILTER_OP_PERCENT_MASK	= 0x06,
 
 	/* Added in 1.7.7 */
 	GNM_FILTER_OP_GT_AVERAGE	= 0x40,
@@ -69,6 +73,7 @@ GnmFilterCondition *gnm_filter_condition_new_double (GnmFilterOp op1, GnmValue *
 						     GnmFilterOp op2, GnmValue *v2);
 GnmFilterCondition *gnm_filter_condition_new_bucket (gboolean top,
 						     gboolean absolute,
+						     gboolean rel_range,
 						     double n);
 
 GnmFilter		 *gnm_filter_new	    (Sheet *sheet, GnmRange const *r);
diff --git a/src/xml-sax-read.c b/src/xml-sax-read.c
index fe4ea9b..100404c 100644
--- a/src/xml-sax-read.c
+++ b/src/xml-sax-read.c
@@ -2242,8 +2242,8 @@ xml_sax_filter_condition (GsfXMLIn *xin, xmlChar const **attrs)
 		cond = gnm_filter_condition_new_single (
 			GNM_FILTER_OP_NON_BLANKS, NULL);
 	} else if (0 == g_ascii_strcasecmp (type, "bucket")) {
-		cond = gnm_filter_condition_new_bucket (
-			top, items, bucket_count);
+		cond = gnm_filter_condition_new_bucket
+			(top, items, TRUE, bucket_count);
 	} else {
 		go_io_warning (state->context, _("Unknown filter type \"%s\""), type);
 	}



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