Example #1
0
/*
 * 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;
}
Example #2
0
/**
 * sv_select_cur_col:
 * @sv: The sheet
 *
 * Selects an entire column
 */
void
sv_select_cur_col (SheetView *sv)
{
	GnmRange const *sel = selection_first_range (sv,  NULL, NULL);
	if (sel != NULL) {
		GnmRange r = *sel;
		sv_selection_reset (sv);
		sv_selection_add_full (sv,
			sv->edit_pos.col, sv->edit_pos.row,
			r.start.col, 0, r.end.col, gnm_sheet_get_last_row (sv->sheet));
		sheet_update (sv->sheet);
	}
}
Example #3
0
static gboolean
cb_exercise_pango (gpointer data)
{
	static int state = 0;

	WorkbookControl *wbc = data;
	SheetView	*sv  = wb_control_cur_sheet_view (wbc);

	if (state == 0) {
		sv_selection_reset (sv);
		sv_selection_add_full(sv, 0, 0, 0, 0, 40, STEP_SIZE*TEST_STEPS);
		cmd_area_set_text (wbc, sv, "=rand()", FALSE);
	} else if (state < TEST_STEPS) {
		SHEET_VIEW_FOREACH_CONTROL(wb_control_cur_sheet_view (wbc),
			sc, sc_set_top_left (sc, 0, state*STEP_SIZE););
Example #4
0
/**
 * sv_select_cur_array :
 * @sv: The sheet
 *
 * If the editpos is part of an array clear the selection and select the array.
 **/
void
sv_select_cur_array (SheetView *sv)
{
	GnmRange a;
	int const c = sv->edit_pos.col;
	int const r = sv->edit_pos.row;

	if (!gnm_cell_array_bound (sheet_cell_get (sv->sheet, c, r), &a))
		return;

	/* leave the edit pos where it is, select the entire array. */
	sv_selection_reset (sv);
	sv_selection_add_full (sv, c, r,
		a.start.col, a.start.row, a.end.col, a.end.row);
	sheet_update (sv->sheet);
}
Example #5
0
/**
 * sv_select_cur_inputs :
 * @sv: The sheet
 *
 * Select all cells that are direct potential inputs to the
 * current cell.
 **/
void
sv_select_cur_inputs (SheetView *sv)
{
	GnmCell  *cell;
	GSList   *ranges, *ptr;
	GnmEvalPos ep;

	g_return_if_fail (IS_SHEET_VIEW (sv));

	cell = sheet_cell_get (sv->sheet,
		sv->edit_pos.col, sv->edit_pos.row);
	if (cell == NULL || !gnm_cell_has_expr (cell))
		return;
	ranges = gnm_expr_top_get_ranges (cell->base.texpr);
	if (ranges == NULL)
		return;

	ep.eval = sv->edit_pos;
	ep.sheet = sv->sheet;
	ep.dep = NULL;

	sv_selection_reset (sv);
	for (ptr = ranges ; ptr != NULL ; ptr = ptr->next) {
		GnmValue *v = ptr->data;
		GnmRangeRef const *r = value_get_rangeref (v);

#warning "FIXME: What do we do in these 3D cases?"
		if (r->a.sheet != r->b.sheet)
			continue;
		if (r->a.sheet != NULL && r->a.sheet != sv->sheet)
			continue;

		sv_selection_add_full (sv,
			gnm_cellref_get_col (&r->a, &ep),
			gnm_cellref_get_row (&r->a, &ep),
			gnm_cellref_get_col (&r->a, &ep),
			gnm_cellref_get_row (&r->a, &ep),
			gnm_cellref_get_col (&r->b, &ep),
			gnm_cellref_get_row (&r->b, &ep));
		value_release (v);
	}
	g_slist_free (ranges);

	sheet_update (sv->sheet);
}
Example #6
0
/**
 * 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);
}
Example #7
0
static int
item_grid_button_pressed (GocItem *item, int button, double x_, double y_)
{
	GnmItemGrid *ig = GNM_ITEM_GRID (item);
	GocCanvas    *canvas = item->canvas;
	GnmPane *pane = GNM_PANE (canvas);
	SheetControlGUI *scg = ig->scg;
	WBCGtk *wbcg = scg_wbcg (scg);
	SheetControl	*sc = (SheetControl *)scg;
	SheetView	*sv = sc_view (sc);
	Sheet		*sheet = sv_sheet (sv);
	GnmCellPos	pos;
	gboolean edit_showed_dialog;
	gboolean already_selected;
	GdkEvent *event = goc_canvas_get_cur_event (item->canvas);
	gint64 x = x_ * canvas->pixels_per_unit, y = y_ * canvas->pixels_per_unit;

	gnm_pane_slide_stop (pane);

	pos.col = gnm_pane_find_col (pane, x, NULL);
	pos.row = gnm_pane_find_row (pane, y, NULL);

	/* GnmRange check first */
	if (pos.col >= gnm_sheet_get_max_cols (sheet))
		return TRUE;
	if (pos.row >= gnm_sheet_get_max_rows (sheet))
		return TRUE;

	/* A new object is ready to be realized and inserted */
	if (wbcg->new_object != NULL)
		return ig_obj_create_begin (ig, button, x, y);

	/* If we are not configuring an object then clicking on the sheet
	 * ends the edit.  */
	if (scg->selected_objects == NULL)
		wbcg_focus_cur_scg (wbcg);
	else if (wbc_gtk_get_guru (wbcg) == NULL)
		scg_mode_edit (scg);

	/* If we were already selecting a range of cells for a formula,
	 * reset the location to a new place, or extend the selection.
	 */
	if (button == 1 && scg->rangesel.active) {
		ig->selecting = GNM_ITEM_GRID_SELECTING_FORMULA_RANGE;
		if (event->button.state & GDK_SHIFT_MASK)
			scg_rangesel_extend_to (scg, pos.col, pos.row);
		else
			scg_rangesel_bound (scg, pos.col, pos.row, pos.col, pos.row);
		gnm_pane_slide_init (pane);
		gnm_simple_canvas_grab (item,
			GDK_POINTER_MOTION_MASK | GDK_BUTTON_RELEASE_MASK,
			NULL, gdk_event_get_time (event));
		return TRUE;
	}

	/* If the user is editing a formula (wbcg_rangesel_possible) then we
	 * enable the dynamic cell selection mode.
	 */
	if (button == 1 && wbcg_rangesel_possible (wbcg)) {
		scg_rangesel_start (scg, pos.col, pos.row, pos.col, pos.row);
		ig->selecting = GNM_ITEM_GRID_SELECTING_FORMULA_RANGE;
		gnm_pane_slide_init (pane);
		gnm_simple_canvas_grab (item,
			GDK_POINTER_MOTION_MASK | GDK_BUTTON_RELEASE_MASK,
			NULL, gdk_event_get_time (event));
		return TRUE;
	}

	/* While a guru is up ignore clicks */
	if (wbc_gtk_get_guru (wbcg) != NULL)
		return TRUE;

	/* This was a regular click on a cell on the spreadsheet.  Select it.
	 * but only if the entered expression is valid */
	if (!wbcg_edit_finish (wbcg, WBC_EDIT_ACCEPT, &edit_showed_dialog))
		return TRUE;

	if (button == 1 && !sheet_selection_is_allowed (sheet, &pos))
		return TRUE;

	/* Button == 1 is used to trigger hyperlinks (and possibly similar */
	/* special cases. Otherwise button == 2 should behave exactly like */
	/* button == 1. See bug #700792                                    */
	
	/* buttons 1 and 2 will always change the selection,  the other buttons will
	 * only effect things if the target is not already selected.  */
	already_selected = sv_is_pos_selected (sv, pos.col, pos.row);
	if (button == 1 || button == 2 || !already_selected) {
		if (!(event->button.state & (GDK_CONTROL_MASK|GDK_SHIFT_MASK)))
			sv_selection_reset (sv);

		if ((event->button.button != 1 && event->button.button != 2) 
		    || !(event->button.state & GDK_SHIFT_MASK) ||
		    sv->selections == NULL) {
			sv_selection_add_pos (sv, pos.col, pos.row,
					      (already_selected && (event->button.state & GDK_CONTROL_MASK)) ?
					      GNM_SELECTION_MODE_REMOVE :
					      GNM_SELECTION_MODE_ADD);
			sv_make_cell_visible (sv, pos.col, pos.row, FALSE);
		} else sv_selection_extend_to (sv, pos.col, pos.row);
		sheet_update (sheet);
	}

	if (edit_showed_dialog)
		return TRUE;  /* we already ignored the button release */

	switch (button) {
	case 1:
	case 2: {
		guint32 double_click_time;

		/*
		 *  If the second click is on a different cell than the
		 *  first one this cannot be a double-click
		 */
		if (already_selected) {
			g_object_get (gtk_widget_get_settings (GTK_WIDGET (canvas)),
				      "gtk-double-click-time", &double_click_time,
				      NULL);

			if ((ig->last_click_time + double_click_time) > gdk_event_get_time (event) &&
			    wbcg_edit_start (wbcg, FALSE, FALSE)) {
				break;
			}
		}

		ig->last_click_time = gdk_event_get_time (event);
		ig->selecting = GNM_ITEM_GRID_SELECTING_CELL_RANGE;
		gnm_pane_slide_init (pane);
		gnm_simple_canvas_grab (item,
			GDK_POINTER_MOTION_MASK | GDK_BUTTON_RELEASE_MASK,
			NULL, gdk_event_get_time (event));
		break;
	}

	case 3: scg_context_menu (scg, event, FALSE, FALSE);
		break;
	default :
		break;
	}

	return TRUE;
}