/* * Advanced Filter tool. */ gint advanced_filter (WorkbookControl *wbc, data_analysis_output_t *dao, GnmValue *database, GnmValue *criteria, gboolean unique_only_flag) { GSList *crit, *rows; GnmEvalPos ep; GnmRange r, s; SheetView *sv; Sheet *sheet = criteria->v_range.cell.a.sheet; /* I don't like this -- minimal fix for now. 509427. */ if (!VALUE_IS_CELLRANGE (criteria)) 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 analysis_tools_invalid_field; rows = find_rows_that_match (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, unique_only_flag); free_criterias (crit); if (rows == NULL) return analysis_tools_no_records_found; dao_prepare_output (wbc, dao, _("Filtered")); filter (dao, 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); g_slist_free_full (rows, (GDestroyNotify)g_free); sv = sheet_get_view (sheet, wb_control_view (wbc)); s = r = *(selection_first_range (sv, NULL, NULL)); r.end.row = r.start.row; sv_selection_reset (sv); sv_selection_add_range (sv, &r); sv_selection_add_range (sv, &s); wb_control_menu_state_update (wbc, MS_FILTER_STATE_CHANGED); return analysis_tools_noerr; }
/** * sv_select_cur_depends : * @sv: The sheet * * Select all cells that depend on the expression in the current cell. */ void sv_select_cur_depends (SheetView *sv) { GnmCell *cur_cell, dummy; GList *deps = NULL, *ptr = NULL; g_return_if_fail (IS_SHEET_VIEW (sv)); cur_cell = sheet_cell_get (sv->sheet, sv->edit_pos.col, sv->edit_pos.row); if (cur_cell == NULL) { dummy.base.sheet = sv_sheet (sv); dummy.pos = sv->edit_pos; cur_cell = &dummy; } cell_foreach_dep (cur_cell, cb_collect_deps, &deps); if (deps == NULL) return; sv_selection_reset (sv); /* Short circuit */ if (g_list_length (deps) == 1) { GnmCell *cell = deps->data; sv_selection_add_pos (sv, cell->pos.col, cell->pos.row); } else { GnmRange *cur = NULL; ptr = NULL; /* Merge the sorted list of cells into rows */ for (deps = g_list_sort (deps, &cb_compare_deps) ; deps ; ) { GnmCell *cell = deps->data; if (cur == NULL || cur->end.row != cell->pos.row || cur->end.col+1 != cell->pos.col) { if (cur) ptr = g_list_prepend (ptr, cur); cur = g_new (GnmRange, 1); cur->start.row = cur->end.row = cell->pos.row; cur->start.col = cur->end.col = cell->pos.col; } else cur->end.col = cell->pos.col; deps = g_list_remove (deps, cell); } if (cur) ptr = g_list_prepend (ptr, cur); /* Merge the coalesced rows into ranges */ deps = ptr; for (ptr = NULL ; deps ; ) { GnmRange *r1 = deps->data; GList *fwd; for (fwd = deps->next ; fwd ; ) { GnmRange *r2 = fwd->data; if (r1->start.col == r2->start.col && r1->end.col == r2->end.col && r1->start.row-1 == r2->end.row) { r1->start.row = r2->start.row; g_free (fwd->data); fwd = g_list_remove (fwd, r2); } else fwd = fwd->next; } ptr = g_list_prepend (ptr, r1); deps = g_list_remove (deps, r1); } /* now select the ranges */ while (ptr) { sv_selection_add_range (sv, ptr->data); g_free (ptr->data); ptr = g_list_remove (ptr, ptr->data); } } sheet_update (sv->sheet); }