6 * Jukka-Pekka Iivonen <jiivonen@hutcs.cs.hut.fi>
8 * (C) Copyright 2000, 2001, 2002 by Jukka-Pekka Iivonen <iivonen@iki.fi>
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, see <https://www.gnu.org/licenses/>.
24 #include <gnumeric-config.h>
25 #include <glib/gi18n-lib.h>
29 #include <sheet-filter.h>
30 #include <workbook-control.h>
34 #include <selection.h>
37 #include <tools/filter.h>
38 #include <tools/analysis-tools.h>
41 filter (data_analysis_output_t
*dao
, Sheet
*sheet
, GSList
*rows
,
42 gint input_col_b
, gint input_col_e
, gint input_row_b
, gint input_row_e
)
47 if (dao
->type
== InPlaceOutput
) {
48 sheet
->has_filtered_rows
= TRUE
;
49 colrow_set_visibility (sheet
, FALSE
,
50 FALSE
, input_row_b
+1, input_row_e
);
51 for (i
=input_row_b
; i
<=input_row_e
; i
++) {
52 ColRowInfo
*ri
= sheet_row_fetch (sheet
, i
);
53 ri
->in_advanced_filter
= TRUE
;
55 while (rows
!= NULL
) {
56 gint row
= GPOINTER_TO_INT (rows
->data
);
57 colrow_set_visibility (sheet
, FALSE
, TRUE
, row
, row
);
60 sheet_redraw_all (sheet
, TRUE
);
61 /* FIXME: what happens if we just have hidden the selection? */
64 for (i
=input_col_b
; i
<=input_col_e
; i
++) {
65 cell
= sheet_cell_get (sheet
, i
, input_row_b
);
67 dao_set_cell (dao
, i
- input_col_b
, r
, NULL
);
69 GnmValue
*value
= value_dup (cell
->value
);
70 dao_set_cell_value (dao
, i
- input_col_b
, r
,
76 while (rows
!= NULL
) {
77 gint row
= GPOINTER_TO_INT (rows
->data
);
78 for (i
=input_col_b
; i
<=input_col_e
; i
++) {
79 cell
= sheet_cell_get (sheet
, i
, row
);
81 dao_set_cell (dao
, i
- input_col_b
, r
,
85 value_dup (cell
->value
);
86 dao_set_cell_value (dao
,
98 * Advanced Filter tool.
101 advanced_filter (WorkbookControl
*wbc
,
102 data_analysis_output_t
*dao
,
105 gboolean unique_only_flag
)
111 Sheet
*sheet
= criteria
->v_range
.cell
.a
.sheet
;
113 /* I don't like this -- minimal fix for now. 509427. */
114 if (!VALUE_IS_CELLRANGE (criteria
))
115 return analysis_tools_invalid_field
;
117 crit
= parse_database_criteria (
118 eval_pos_init_sheet (&ep
, wb_control_cur_sheet (wbc
)),
122 return analysis_tools_invalid_field
;
124 rows
= find_rows_that_match (sheet
,
125 database
->v_range
.cell
.a
.col
,
126 database
->v_range
.cell
.a
.row
+ 1,
127 database
->v_range
.cell
.b
.col
,
128 database
->v_range
.cell
.b
.row
,
129 crit
, unique_only_flag
);
131 free_criterias (crit
);
134 return analysis_tools_no_records_found
;
136 dao_prepare_output (wbc
, dao
, _("Filtered"));
138 filter (dao
, sheet
, rows
,
139 database
->v_range
.cell
.a
.col
,
140 database
->v_range
.cell
.b
.col
, database
->v_range
.cell
.a
.row
,
141 database
->v_range
.cell
.b
.row
);
143 sv
= sheet_get_view (sheet
, wb_control_view (wbc
));
144 s
= r
= *(selection_first_range (sv
, NULL
, NULL
));
145 r
.end
.row
= r
.start
.row
;
146 sv_selection_reset (sv
);
147 sv_selection_add_range (sv
, &r
);
148 sv_selection_add_range (sv
, &s
);
150 wb_control_menu_state_update (wbc
, MS_FILTER_STATE_CHANGED
);
152 return analysis_tools_noerr
;
156 cb_show_all (GnmColRowIter
const *iter
, Sheet
*sheet
)
158 if (iter
->cri
->in_advanced_filter
) {
159 ColRowInfo
*ri
= sheet_row_fetch (sheet
, iter
->pos
);
160 if (!iter
->cri
->visible
)
161 colrow_set_visibility (sheet
, FALSE
, TRUE
,
162 iter
->pos
, iter
->pos
);
163 ri
->in_advanced_filter
= FALSE
;
169 filter_show_all (WorkbookControl
*wbc
)
171 Sheet
*sheet
= wb_control_cur_sheet (wbc
);
173 /* FIXME: This is slow. We should probably have a linked list
174 * containing the filtered rows in the sheet structure. */
175 sheet_colrow_foreach (sheet
, FALSE
, 0, -1,
176 (ColRowHandler
) cb_show_all
, sheet
);
177 sheet
->has_filtered_rows
= FALSE
;
178 sheet_redraw_all (sheet
, TRUE
);
180 wb_control_menu_state_update (wbc
, MS_FILTER_STATE_CHANGED
);
184 analysis_tool_advanced_filter_engine_run (data_analysis_output_t
*dao
,
185 analysis_tools_data_advanced_filter_t
*info
)
189 GnmValue
*database
= info
->base
.range_1
;
190 GnmValue
*criteria
= info
->base
.range_2
;
191 gint err
= analysis_tools_noerr
;
195 dao_set_italic (dao
, 0, 0, 0, 2);
196 set_cell_text_col (dao
, 0, 0, _("/Advanced Filter:"
198 "/Criteria Range:"));
199 range_init_value (&range
, database
);
200 name
= global_range_name (database
->v_range
.cell
.a
.sheet
, &range
);
201 dao_set_cell (dao
, 1, 1, name
);
203 range_init_value (&range
, criteria
);
204 name
= global_range_name (criteria
->v_range
.cell
.a
.sheet
, &range
);
205 dao_set_cell (dao
, 1, 2, name
);
210 crit
= parse_database_criteria (
211 eval_pos_init_sheet (&ep
, wb_control_cur_sheet (info
->base
.wbc
)),
215 err
= analysis_tools_invalid_field
;
219 rows
= find_rows_that_match (database
->v_range
.cell
.a
.sheet
,
220 database
->v_range
.cell
.a
.col
,
221 database
->v_range
.cell
.a
.row
+ 1,
222 database
->v_range
.cell
.b
.col
,
223 database
->v_range
.cell
.b
.row
,
224 crit
, info
->unique_only_flag
);
226 free_criterias (crit
);
229 err
= analysis_tools_no_records_found
;
233 filter (dao
, database
->v_range
.cell
.a
.sheet
, rows
,
234 database
->v_range
.cell
.a
.col
,
235 database
->v_range
.cell
.b
.col
, database
->v_range
.cell
.a
.row
,
236 database
->v_range
.cell
.b
.row
);
239 if (err
!= analysis_tools_noerr
) {
240 dao_set_merge (dao
, 0,0, 1, 0);
241 if (err
== analysis_tools_no_records_found
)
242 dao_set_cell (dao
, 0, 0, _("No matching records were found."));
243 else if (err
== analysis_tools_invalid_field
)
244 dao_set_cell (dao
, 0, 0, _("The given criteria are invalid."));
246 dao_set_cell_printf (dao
, 0, 0,
247 _("An unexpected error has occurred: "
251 dao_redraw_respan (dao
);
253 return analysis_tools_noerr
;
258 analysis_tool_advanced_filter_engine (G_GNUC_UNUSED GOCmdContext
*gcc
, data_analysis_output_t
*dao
, gpointer specs
,
259 analysis_tool_engine_t selector
, gpointer result
)
261 analysis_tools_data_advanced_filter_t
*info
= specs
;
263 case TOOL_ENGINE_UPDATE_DESCRIPTOR
:
264 return (dao_command_descriptor (dao
, _("Advanced Filter (%s)"), result
)
266 case TOOL_ENGINE_UPDATE_DAO
: {
268 rows
= info
->base
.range_1
->v_range
.cell
.b
.row
269 - info
->base
.range_1
->v_range
.cell
.a
.row
+ 1;
270 cols
= info
->base
.range_1
->v_range
.cell
.b
.col
271 - info
->base
.range_1
->v_range
.cell
.a
.col
+ 1;
274 dao_adjust (dao
, cols
, 3 + rows
);
277 case TOOL_ENGINE_CLEAN_UP
:
278 return analysis_tool_generic_b_clean (specs
);
279 case TOOL_ENGINE_LAST_VALIDITY_CHECK
:
281 case TOOL_ENGINE_PREPARE_OUTPUT_RANGE
:
282 dao_prepare_output (NULL
, dao
, _("Advanced Filter"));
284 case TOOL_ENGINE_FORMAT_OUTPUT_RANGE
:
285 return dao_format_output (dao
, _("Advanced Filter"));
286 case TOOL_ENGINE_PERFORM_CALC
:
288 return analysis_tool_advanced_filter_engine_run (dao
, info
);
290 return TRUE
; /* We shouldn't get here */