[gnumeric] Implement extending auto filters (by adding new columns) [#607086]



commit edf66ae6e27605a3cc25e640d237be375ed91534
Author: Andreas J Guelzow <aguelzow pyrshep ca>
Date:   Mon Jul 5 16:33:30 2010 -0600

    Implement extending auto filters (by adding new columns) [#607086]
    
    2010-07-05  Andreas J. Guelzow <aguelzow pyrshep ca>
    
    	* src/commands.c (cmd_autofilter_add_remove): handle extension of
    	  an existing autofilter.
    	* src/sheet-filter.h (gnm_sheet_filter_can_be_extended): new
    	* src/sheet-filter.c (gnm_sheet_filter_can_be_extended): new
    	* src/sheet-view.h (sv_selection_extends_filter): new
    	* src/sheet-view.c (sv_selection_extends_filter): new
    	(sv_selection_intersects_filter_rows): add qualifier
    	* src/wbc-gtk.c (wbcg_menu_state_update): check whether auto filter
    	  can be extended

 ChangeLog          |   12 +++++++
 src/commands.c     |   92 ++++++++++++++++++++++++++++++++++++++-------------
 src/sheet-filter.c |   14 ++++++++
 src/sheet-filter.h |    6 +++-
 src/sheet-view.c   |   21 +++++++++++-
 src/sheet-view.h   |    2 +
 src/wbc-gtk.c      |   29 +++++++++++++---
 7 files changed, 144 insertions(+), 32 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index ac508fd..2781b62 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,17 @@
 2010-07-05  Andreas J. Guelzow <aguelzow pyrshep ca>
 
+	* src/commands.c (cmd_autofilter_add_remove): handle extension of
+	  an existing autofilter.
+	* src/sheet-filter.h (gnm_sheet_filter_can_be_extended): new
+	* src/sheet-filter.c (gnm_sheet_filter_can_be_extended): new
+	* src/sheet-view.h (sv_selection_extends_filter): new
+	* src/sheet-view.c (sv_selection_extends_filter): new
+	(sv_selection_intersects_filter_rows): add qualifier
+	* src/wbc-gtk.c (wbcg_menu_state_update): check whether auto filter
+	  can be extended
+
+2010-07-05  Andreas J. Guelzow <aguelzow pyrshep ca>
+
 	* src/commands.c (CMD_AUTOFILTER_ADD_REMOVE): delete
 	(cmd_autofilter_add_remove_*): delete
 	(cmd_autofilter_add_remove): rewrite using cmd_generic (prep for
diff --git a/src/commands.c b/src/commands.c
index ec87ac7..8050b34 100644
--- a/src/commands.c
+++ b/src/commands.c
@@ -7536,21 +7536,57 @@ cmd_autofilter_add_remove (WorkbookControl *wbc)
 		GnmRange region;
 		GnmRange const *src = selection_first_range (sv,
 			GO_CMD_CONTEXT (wbc), _("Add Filter"));
+		GnmFilter *f_old = NULL;
 
 		if (src == NULL)
 			return TRUE;
 
-		/* only one row selected -- assume that the user wants to
-		 * filter the region below this row. */
-		region = *src;
-		if (src->start.row == src->end.row)
-			gnm_sheet_guess_region  (sv->sheet, &region);
-		if (region.start.row == region.end.row) {
-			go_cmd_context_error_invalid
-				(GO_CMD_CONTEXT (wbc),
-				 _("AutoFilter"),
-				 _("Requires more than 1 row"));
-			return TRUE;
+		f_old = gnm_sheet_filter_intersect_rows 
+			(sv->sheet, src->start.row, src->end.row);
+
+		if (f_old != NULL) {
+			GnmRange *r = gnm_sheet_filter_can_be_extended 
+				(sv->sheet, f_old, src);
+			if (r == NULL) {
+				char *error;
+				name = undo_range_name (sv->sheet, &(f_old->r));
+				error = g_strdup_printf 
+					(_("Auto Filter blocked by %s"),
+					 name);
+				g_free(name);
+				go_cmd_context_error_invalid
+					(GO_CMD_CONTEXT (wbc),
+					 _("AutoFilter"), error);
+				g_free (error);
+				return TRUE;
+			}
+			/* extending existing filter. */
+			undo = go_undo_binary_new 
+				(gnm_filter_ref (f_old), sv->sheet, 
+				 (GOUndoBinaryFunc) gnm_filter_attach,
+				 (GFreeFunc) gnm_filter_unref,
+				 NULL);
+			redo = go_undo_unary_new
+				(gnm_filter_ref (f_old), 
+				 (GOUndoUnaryFunc) gnm_filter_remove,
+				 (GFreeFunc) gnm_filter_unref);
+			gnm_filter_remove (f_old);
+			region = *r;
+			g_free (r);
+		} else {
+			/* if only one row is selected
+			 * assume that the user wants to
+			 * filter the region below this row. */
+			region = *src;
+			if (src->start.row == src->end.row)
+				gnm_sheet_guess_region  (sv->sheet, &region);
+			if (region.start.row == region.end.row) {
+				go_cmd_context_error_invalid
+					(GO_CMD_CONTEXT (wbc),
+					 _("AutoFilter"),
+					 _("Requires more than 1 row"));
+				return TRUE;
+			}
 		}
 		f = gnm_filter_new (sv->sheet, &region);
 		if (f == NULL) {
@@ -7558,23 +7594,31 @@ cmd_autofilter_add_remove (WorkbookControl *wbc)
 				(GO_CMD_CONTEXT (wbc),
 				 _("AutoFilter"),
 				 _("Unable to create Autofilter"));
+			if (f_old)
+				gnm_filter_attach (f_old, sv->sheet);
 			return TRUE;
 		}
-		gnm_filter_remove (f);
 
-		redo = go_undo_binary_new 
-			(gnm_filter_ref (f), sv->sheet, 
-			 (GOUndoBinaryFunc) gnm_filter_attach,
-			 (GFreeFunc) gnm_filter_unref,
-			 NULL);
-		undo = go_undo_unary_new
-			(f, 
-			 (GOUndoUnaryFunc) gnm_filter_remove,
-			 (GFreeFunc) gnm_filter_unref);
-		
+		gnm_filter_remove (f);
+		if (f_old)
+			gnm_filter_attach (f_old, sv->sheet);
+			
+		redo = go_undo_combine (go_undo_binary_new 
+					(gnm_filter_ref (f), sv->sheet, 
+					 (GOUndoBinaryFunc) gnm_filter_attach,
+					 (GFreeFunc) gnm_filter_unref,
+					 NULL), redo);
+		undo = go_undo_combine (undo,
+					go_undo_unary_new
+					(f, 
+					 (GOUndoUnaryFunc) gnm_filter_remove,
+					 (GFreeFunc) gnm_filter_unref));
+					
 		name = undo_range_name (sv->sheet, &(f->r));
-		descr = g_strdup_printf (_("Add Autofilter to %s"),
-					 name);
+		descr = g_strdup_printf 
+			((f_old == NULL) ? _("Add Autofilter to %s")
+			 : _("Extend Autofilter to %s"),
+			 name);
 	} else {
 		undo = go_undo_binary_new 
 			(gnm_filter_ref (f), sv->sheet, 
diff --git a/src/sheet-filter.c b/src/sheet-filter.c
index 83a9a27..d23b159 100644
--- a/src/sheet-filter.c
+++ b/src/sheet-filter.c
@@ -884,6 +884,20 @@ gnm_sheet_filter_intersect_rows (Sheet const *sheet, int from, int to)
 	return NULL;
 }
 
+GnmRange *
+gnm_sheet_filter_can_be_extended (Sheet const *sheet, GnmFilter const *f,
+				  GnmRange const *r)
+{
+	if (r->start.row < f->r.start.row || r->end.row > f->r.end.row)
+		return NULL;
+	if ((r->end.col > f->r.end.col) ||
+	    (r->start.col < f->r.start.col)) {
+		GnmRange *res = g_new (GnmRange, 1);
+		*res = range_union (&f->r, r);
+		return res;
+	}
+	return NULL;
+}
 
 
 /*************************************************************************/
diff --git a/src/sheet-filter.h b/src/sheet-filter.h
index 79071cf..3f81a85 100644
--- a/src/sheet-filter.h
+++ b/src/sheet-filter.h
@@ -84,7 +84,11 @@ gboolean		  gnm_filter_overlaps_range (GnmFilter const *filter, GnmRange const *
 void                      gnm_filter_reapply        (GnmFilter *filter);
 
 GnmFilter *gnm_sheet_filter_at_pos  (Sheet const *sheet, GnmCellPos const *pos);
-GnmFilter *gnm_sheet_filter_intersect_rows  (Sheet const *sheet, int from, int to);
+GnmFilter *gnm_sheet_filter_intersect_rows  (Sheet const *sheet, 
+					     int from, int to);
+GnmRange  *gnm_sheet_filter_can_be_extended (Sheet const *sheet,
+					     GnmFilter const *f,
+					     GnmRange const *r);
 void gnm_sheet_filter_insdel_colrow (Sheet *sheet,
 				     gboolean is_cols, gboolean is_insert,
 				     int start, int count,
diff --git a/src/sheet-view.c b/src/sheet-view.c
index 06a7153..901d1a9 100644
--- a/src/sheet-view.c
+++ b/src/sheet-view.c
@@ -693,7 +693,7 @@ sv_editpos_in_filter (SheetView const *sv)
 GnmFilter *
 sv_selection_intersects_filter_rows (SheetView const *sv)
 {
-	GnmRange *r;
+	GnmRange const *r;
 	g_return_val_if_fail (IS_SHEET_VIEW (sv), NULL);
 	r = selection_first_range (sv, NULL, NULL);
 
@@ -701,6 +701,25 @@ sv_selection_intersects_filter_rows (SheetView const *sv)
 		(sv->sheet, r->start.row, r->end.row);
 }
 
+/**
+ * sv_selection_extends_filter:
+ * @sv : #SheetView
+ *
+ * Returns: %NULL or GnmFilter whose rows intersect the rows
+ *          of the current selectiona range to which the filter can be 
+ *          extended.
+ **/
+GnmRange *
+sv_selection_extends_filter (SheetView const *sv, GnmFilter const *f)
+{
+	GnmRange const *r;
+	g_return_val_if_fail (IS_SHEET_VIEW (sv), NULL);
+	r = selection_first_range (sv, NULL, NULL);
+
+	return gnm_sheet_filter_can_be_extended (sv->sheet, f, r);
+}
+
+
 
 
 /**
diff --git a/src/sheet-view.h b/src/sheet-view.h
index 011709a..735e2db 100644
--- a/src/sheet-view.h
+++ b/src/sheet-view.h
@@ -87,6 +87,8 @@ gboolean      sv_is_region_empty_or_selected (SheetView const *sv,
 
 GnmFilter      *sv_editpos_in_filter (SheetView const *sv);
 GnmFilter      *sv_selection_intersects_filter_rows (SheetView const *sv);
+GnmRange       *sv_selection_extends_filter (SheetView const *sv, 
+					     GnmFilter const *f);
 GnmSheetSlicer *sv_editpos_in_slicer (SheetView const *sv);
 
 /* Manipulation */
diff --git a/src/wbc-gtk.c b/src/wbc-gtk.c
index fe04708..a9cd45c 100644
--- a/src/wbc-gtk.c
+++ b/src/wbc-gtk.c
@@ -1577,14 +1577,31 @@ wbcg_menu_state_update (WorkbookControl *wbc, int flags)
 		char const* label;
 		char const *new_tip;
 		gboolean active = TRUE;
+		GnmRange *r = NULL;
 
 		if ((!has_filter) && (NULL != f)) {
-			gchar *nlabel;
-			active = FALSE;
-			nlabel = g_strdup_printf (_("_Auto Filter blocked by %s"), 
-						  range_as_string (&f->r));
-			new_tip = _("The selection intersects an existing auto filter.");
-			wbc_gtk_set_action_label (wbcg, "DataAutoFilter", NULL, nlabel, new_tip);
+			gchar *nlabel = NULL;
+			if (NULL != (r = sv_selection_extends_filter (sv, f))) {
+				active = TRUE;
+				nlabel = g_strdup_printf 
+					(_("Extend _Auto Filter to %s"), 
+					 range_as_string (r));
+				new_tip = _("Extend the existing filter.");
+				wbc_gtk_set_action_label 
+					(wbcg, "DataAutoFilter", NULL, 
+					 nlabel, new_tip);
+				g_free (r);
+			} else {
+				active = FALSE;
+				nlabel = g_strdup_printf 
+					(_("Auto Filter blocked by %s"), 
+					 range_as_string (&f->r));
+				new_tip = _("The selection intersects an"
+					    "existing auto filter.");
+				wbc_gtk_set_action_label 
+					(wbcg, "DataAutoFilter", NULL, 
+					 nlabel, new_tip);
+			}
 			g_free (nlabel);
 		} else {
 			label = has_filter



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