[gnumeric] Make Advanced Filter (except filter-in-place) undoable.



commit 1879398ac9c694cfcc8da8f843e651a7fcf9695e
Author: Andreas J. Guelzow <aguelzow pyrshep ca>
Date:   Tue May 4 15:47:10 2010 -0600

     Make Advanced Filter (except filter-in-place) undoable.
    
    2010-05-04 Andreas J. Guelzow <aguelzow pyrshep ca>
    
    	* dialog-advanced-filter.c (advanced_filter_ok_clicked_cb): use
    	  cmd_analysis_tool
    
    2010-05-04 Andreas J. Guelzow <aguelzow pyrshep ca>
    
    	* analysis-normality.c (analysis_tool_normality_engine_run):
    	  dao_autofit_columns is not needed
    	* analysis-tools.c (summary_statistics): ditto
    	* analysis-tools.h (analysis_tools_error_code_t): add items
    	(analysis_tool_advanced_filter_engine): new
    	(analysis_tools_data_advanced_filter_t): new
    	* filter.c (analysis_tool_advanced_filter_engine): new
    	(analysis_tool_advanced_filter_engine_run): new
    	(free_rows): deleted
    	(advanced_filter): replace defines with enum and use
    	  go_slist_free_custom
    	* filter.h: remove unneeded defines

 NEWS                                 |    1 +
 src/dialogs/ChangeLog                |    5 +
 src/dialogs/dialog-advanced-filter.c |   40 ++++++++--
 src/tools/ChangeLog                  |   15 ++++
 src/tools/analysis-normality.c       |    1 -
 src/tools/analysis-tools.c           |    2 -
 src/tools/analysis-tools.h           |   19 ++++-
 src/tools/filter.c                   |  139 +++++++++++++++++++++++++++++-----
 src/tools/filter.h                   |    5 -
 9 files changed, 188 insertions(+), 39 deletions(-)
---
diff --git a/NEWS b/NEWS
index d94268a..383791f 100644
--- a/NEWS
+++ b/NEWS
@@ -6,6 +6,7 @@ Andreas:
 	* Make even active sheets invisible. [#616474]
 	* Improve date & time import from and export to ODF. [#617208]
 	* Protect against accidentally pushing data off the sheet. [#98562]
+	* Make Advanced Filter (except ifilter-in-place) undoable.
 
 Jean:
 	* Implement graph only sheets. [#158170]
diff --git a/src/dialogs/ChangeLog b/src/dialogs/ChangeLog
index 0b32e36..493ec93 100644
--- a/src/dialogs/ChangeLog
+++ b/src/dialogs/ChangeLog
@@ -1,3 +1,8 @@
+2010-05-04 Andreas J. Guelzow <aguelzow pyrshep ca>
+
+	* dialog-advanced-filter.c (advanced_filter_ok_clicked_cb): use 
+	  cmd_analysis_tool
+
 2010-04-22 Andreas J. Guelzow <aguelzow pyrshep ca>
 
 	* dialog-sheet-order.c (cb_sheet_order_cnt_visible): simplify
diff --git a/src/dialogs/dialog-advanced-filter.c b/src/dialogs/dialog-advanced-filter.c
index 1a19814..142951c 100644
--- a/src/dialogs/dialog-advanced-filter.c
+++ b/src/dialogs/dialog-advanced-filter.c
@@ -43,6 +43,8 @@
 #include <widgets/gnumeric-expr-entry.h>
 #include <widgets/gnm-dao.h>
 #include "filter.h"
+#include "analysis-tools.h"
+#include "commands.h"
 
 
 #define ADVANCED_FILTER_KEY         "advanced-filter-dialog"
@@ -108,7 +110,7 @@ static void
 advanced_filter_ok_clicked_cb (G_GNUC_UNUSED GtkWidget *button,
 			       AdvancedFilterState *state)
 {
-	data_analysis_output_t  dao;
+	data_analysis_output_t  *dao;
 	GnmValue                   *input;
 	GnmValue                   *criteria;
 	char                    *text;
@@ -122,27 +124,47 @@ advanced_filter_ok_clicked_cb (G_GNUC_UNUSED GtkWidget *button,
 	criteria = gnm_expr_entry_parse_as_value
 		(state->input_entry_2, state->sheet);
 
-        parse_output ((GenericToolState *) state, &dao);
+        dao  = parse_output ((GenericToolState *) state, NULL);
 
 	w = glade_xml_get_widget (state->gui, "unique-button");
 	unique = (1 == gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (w)));
 
-	err = advanced_filter (WORKBOOK_CONTROL (state->wbcg),
-			       &dao, input, criteria, unique);
+	if (dao->type == InPlaceOutput)
+		err = advanced_filter (WORKBOOK_CONTROL (state->wbcg),
+				       dao, input, criteria, unique);
+	else {
+		analysis_tools_data_advanced_filter_t  *
+			data = g_new0 (analysis_tools_data_advanced_filter_t, 1);
+		data->base.wbc = WORKBOOK_CONTROL (state->wbcg);
+		data->base.range_1 = input;
+		data->base.range_2 = criteria;
+		data->unique_only_flag = unique;
+
+		if (cmd_analysis_tool (WORKBOOK_CONTROL (state->wbcg), state->sheet,
+				       dao, data, analysis_tool_advanced_filter_engine)) {
+			err = data->base.err;
+			g_free (data);
+		} else 
+			err = analysis_tools_noerr;
+		
+	}
 
-	value_release (input);
-	value_release (criteria);
+	if (dao->type == InPlaceOutput || err != analysis_tools_noerr) {
+		value_release (input);
+		value_release (criteria);
+		g_free (dao);
+	}
 
 	switch (err) {
-	case OK:
+	case analysis_tools_noerr:
 		gtk_widget_destroy (state->dialog);
 		break;
-	case ERR_INVALID_FIELD:
+	case analysis_tools_invalid_field:
 		error_in_entry ((GenericToolState *) state,
 				GTK_WIDGET (state->input_entry_2),
 				_("The given criteria are invalid."));
 		break;
-	case NO_RECORDS_FOUND:
+	case analysis_tools_no_records_found:
 		go_gtk_notice_nonmodal_dialog ((GtkWindow *) state->dialog,
 					  &(state->warning_dialog),
 					  GTK_MESSAGE_INFO,
diff --git a/src/tools/ChangeLog b/src/tools/ChangeLog
index ed12505..d91236c 100644
--- a/src/tools/ChangeLog
+++ b/src/tools/ChangeLog
@@ -1,3 +1,18 @@
+2010-05-04 Andreas J. Guelzow <aguelzow pyrshep ca>
+
+	* analysis-normality.c (analysis_tool_normality_engine_run):
+	  dao_autofit_columns is not needed
+	* analysis-tools.c (summary_statistics): ditto
+	* analysis-tools.h (analysis_tools_error_code_t): add items
+	(analysis_tool_advanced_filter_engine): new
+	(analysis_tools_data_advanced_filter_t): new
+	* filter.c (analysis_tool_advanced_filter_engine): new
+	(analysis_tool_advanced_filter_engine_run): new
+	(free_rows): deleted
+	(advanced_filter): replace defines with enum and use 
+	  go_slist_free_custom
+	* filter.h: remove unneeded defines
+
 2010-04-16  Morten Welinder <terra gnome org>
 
 	* Release 1.10.2
diff --git a/src/tools/analysis-normality.c b/src/tools/analysis-normality.c
index c97e23c..75e9f0b 100644
--- a/src/tools/analysis-normality.c
+++ b/src/tools/analysis-normality.c
@@ -177,7 +177,6 @@ analysis_tool_normality_engine_run (data_analysis_output_t *dao,
 	gnm_func_unref (fd);
 	gnm_func_unref (fd_if);
 
-	dao_autofit_columns (dao);
 	dao_redraw_respan (dao);
 	return 0;
 }
diff --git a/src/tools/analysis-tools.c b/src/tools/analysis-tools.c
index 6629293..cba3699 100644
--- a/src/tools/analysis-tools.c
+++ b/src/tools/analysis-tools.c
@@ -942,8 +942,6 @@ summary_statistics (data_analysis_output_t *dao,
 	gnm_func_unref (fd_sum);
 	gnm_func_unref (fd_count);
 	gnm_func_unref (fd_sqrt);
-
-	dao_autofit_columns (dao);
 }
 
 static void
diff --git a/src/tools/analysis-tools.h b/src/tools/analysis-tools.h
index a2e325c..0964fc5 100644
--- a/src/tools/analysis-tools.h
+++ b/src/tools/analysis-tools.h
@@ -19,7 +19,9 @@ typedef enum {
 	analysis_tools_missing_data,
 	analysis_tools_too_few_cols,
 	analysis_tools_too_few_rows,
-	analysis_tools_replication_invalid
+	analysis_tools_replication_invalid,
+	analysis_tools_no_records_found,
+	analysis_tools_invalid_field
 } analysis_tools_error_code_t;
 
 
@@ -185,13 +187,13 @@ gboolean analysis_tool_ttest_paired_engine (data_analysis_output_t *dao, gpointe
 				     analysis_tool_engine_t selector, gpointer result);
 
 
-/*********************** TTest equal varinaces *********/
+/*********************** TTest equal variances *********/
 
 gboolean analysis_tool_ttest_eqvar_engine (data_analysis_output_t *dao, gpointer specs,
 				     analysis_tool_engine_t selector, gpointer result);
 
 
-/*********************** TTest unequal varinaces *******/
+/*********************** TTest unequal variances *******/
 
 gboolean analysis_tool_ttest_neqvar_engine (data_analysis_output_t *dao, gpointer specs,
 					    analysis_tool_engine_t selector, gpointer result);
@@ -202,6 +204,17 @@ gboolean analysis_tool_ttest_neqvar_engine (data_analysis_output_t *dao, gpointe
 gboolean analysis_tool_ztest_engine (data_analysis_output_t *dao, gpointer specs,
 				     analysis_tool_engine_t selector, gpointer result);
 
+/****************  Advanced Filter  ********************/
+
+typedef struct {
+	analysis_tools_data_generic_b_t base;
+	gboolean   unique_only_flag;
+} analysis_tools_data_advanced_filter_t;
+
+gboolean analysis_tool_advanced_filter_engine (data_analysis_output_t *dao, gpointer specs,
+					   analysis_tool_engine_t selector, gpointer result);
+
+
 
 
 /********************************************************************/
diff --git a/src/tools/filter.c b/src/tools/filter.c
index 5b284f4..450e2ac 100644
--- a/src/tools/filter.c
+++ b/src/tools/filter.c
@@ -35,18 +35,7 @@
 #include <value.h>
 
 #include "filter.h"
-
-
-static void
-free_rows (GSList *row_list)
-{
-	GSList *list;
-
-	for (list = row_list; list != NULL; list = list->next)
-	        g_free (list->data);
-	g_slist_free (row_list);
-}
-
+#include "analysis-tools.h"
 
 static void
 filter (data_analysis_output_t *dao, Sheet *sheet, GSList *rows,
@@ -116,14 +105,14 @@ advanced_filter (WorkbookControl        *wbc,
 
 	/* I don't like this -- minimal fix for now.  509427.  */
 	if (criteria->type != VALUE_CELLRANGE)
-		return ERR_INVALID_FIELD;
+		return analysis_tools_invalid_field;
 
 	crit = parse_database_criteria (
 		eval_pos_init_sheet (&ep, wb_control_cur_sheet (wbc)),
 		database, criteria);
 
 	if (crit == NULL)
-		return ERR_INVALID_FIELD;
+		return analysis_tools_invalid_field;
 
 	rows = find_rows_that_match (database->v_range.cell.a.sheet,
 				     database->v_range.cell.a.col,
@@ -135,7 +124,7 @@ advanced_filter (WorkbookControl        *wbc,
 	free_criterias (crit);
 
 	if (rows == NULL)
-		return NO_RECORDS_FOUND;
+		return analysis_tools_no_records_found;
 
 	dao_prepare_output (wbc, dao, _("Filtered"));
 
@@ -144,11 +133,9 @@ advanced_filter (WorkbookControl        *wbc,
 		database->v_range.cell.b.col, database->v_range.cell.a.row,
 		database->v_range.cell.b.row);
 
-	free_rows (rows);
-
-	dao_autofit_columns (dao);
+	go_slist_free_custom (rows, (GFreeFunc)g_free);
 
-	return OK;
+	return analysis_tools_noerr;
 }
 
 static gboolean
@@ -180,3 +167,117 @@ filter_show_all (Sheet *sheet)
 	sheet->has_filtered_rows = FALSE;
 	sheet_redraw_all (sheet, TRUE);
 }
+
+static gboolean
+analysis_tool_advanced_filter_engine_run (data_analysis_output_t *dao,
+					  analysis_tools_data_advanced_filter_t *info)
+{
+	GnmRange range;
+	char *name;
+	GnmValue  *database = info->base.range_1;
+	GnmValue  *criteria = info->base.range_2;
+	gint err = analysis_tools_noerr;
+        GSList  *crit, *rows;
+	GnmEvalPos ep;
+
+	dao_set_italic (dao, 0, 0, 0, 2);
+	set_cell_text_col (dao, 0, 0, _("/Advanced Filter:"
+					"/Source Range:"
+					"/Criteria Range:"));
+	range_init_value (&range, database);
+	name = global_range_name (database->v_range.cell.a.sheet, &range);
+	dao_set_cell (dao, 1, 1, name);
+	g_free (name);
+	range_init_value (&range, criteria);
+	name = global_range_name (criteria->v_range.cell.a.sheet, &range);
+	dao_set_cell (dao, 1, 2, name);
+	g_free (name);
+
+	dao->offset_row = 3;
+
+	crit = parse_database_criteria (
+		eval_pos_init_sheet (&ep, wb_control_cur_sheet (info->base.wbc)),
+		database, criteria);
+
+	if (crit == NULL) {
+		err = analysis_tools_invalid_field;
+		goto finish;
+	}
+
+	rows = find_rows_that_match (database->v_range.cell.a.sheet,
+				     database->v_range.cell.a.col,
+				     database->v_range.cell.a.row + 1,
+				     database->v_range.cell.b.col,
+				     database->v_range.cell.b.row,
+				     crit, info->unique_only_flag);
+
+	free_criterias (crit);
+
+	if (rows == NULL) {
+		err = analysis_tools_no_records_found;
+		goto finish;
+	}		
+
+	filter (dao, database->v_range.cell.a.sheet, rows,
+		database->v_range.cell.a.col,
+		database->v_range.cell.b.col, database->v_range.cell.a.row,
+		database->v_range.cell.b.row);
+
+	go_slist_free_custom (rows, (GFreeFunc)g_free);
+
+finish:
+	if (err != analysis_tools_noerr) {
+		dao_set_merge (dao, 0,0, 1, 0);
+		if (err == analysis_tools_no_records_found)
+			dao_set_cell (dao, 0, 0, _("No matching records were found."));
+		else if (err == analysis_tools_invalid_field)
+			dao_set_cell (dao, 0, 0, _("The given criteria are invalid."));
+		else
+			dao_set_cell_printf (dao, 0, 0, 
+					     _("An unexpected error has occurred: "
+					       "%d."), err);		
+	}
+
+	dao_redraw_respan (dao);
+
+	return analysis_tools_noerr;
+}
+
+
+gboolean
+analysis_tool_advanced_filter_engine (data_analysis_output_t *dao, gpointer specs,
+				   analysis_tool_engine_t selector, gpointer result)
+{
+	analysis_tools_data_advanced_filter_t *info = specs;
+	switch (selector) {
+	case TOOL_ENGINE_UPDATE_DESCRIPTOR:
+		return (dao_command_descriptor (dao, _("Advanced Filter (%s)"), result)
+			== NULL);
+	case TOOL_ENGINE_UPDATE_DAO: {
+		int rows, cols;
+		rows = info->base.range_1->v_range.cell.b.row 
+			- info->base.range_1->v_range.cell.a.row + 1;
+		cols = info->base.range_1->v_range.cell.b.col 
+			- info->base.range_1->v_range.cell.a.col + 1;
+		if (cols < 2)
+			cols = 2;
+		dao_adjust (dao, cols, 3 + rows);
+		return FALSE;
+	}
+	case TOOL_ENGINE_CLEAN_UP:
+		return analysis_tool_generic_b_clean (specs);
+	case TOOL_ENGINE_LAST_VALIDITY_CHECK:
+		return FALSE;
+	case TOOL_ENGINE_PREPARE_OUTPUT_RANGE:
+		dao_prepare_output (NULL, dao, _("Advanced Filter"));
+		return FALSE;
+	case TOOL_ENGINE_FORMAT_OUTPUT_RANGE:
+		return dao_format_output (dao, _("Advanced Filter"));
+	case TOOL_ENGINE_PERFORM_CALC:
+	default:
+		return analysis_tool_advanced_filter_engine_run (dao, info);
+	}
+	return TRUE;  /* We shouldn't get here */
+}
+
+
diff --git a/src/tools/filter.h b/src/tools/filter.h
index cb447cf..49b40b4 100644
--- a/src/tools/filter.h
+++ b/src/tools/filter.h
@@ -4,11 +4,6 @@
 #include <gnumeric.h>
 #include <dao.h>
 
-#define OK                 0
-#define N_COLUMNS_ERROR    1
-#define ERR_INVALID_FIELD  2
-#define NO_RECORDS_FOUND   3
-
 gint advanced_filter (WorkbookControl        *wbc,
 		      data_analysis_output_t *dao,
 		      GnmValue               *database, GnmValue *criteria,



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