Exemple #1
0
/**
 * gnm_app_clipboard_cut_copy:
 * @wbc: the workbook control that requested the operation.
 * @is_cut: is this a cut or a copy.
 * @sv: The source sheet for the copy.
 * @area: A single rectangular range to be copied.
 * @animate_range: Do we want ot add an animated cursor around things.
 *
 * When Cutting we
 *   Clear and free the contents of the clipboard and save the sheet and area
 *   to be cut.  DO NOT ACTUALLY CUT!  Paste will move the region if this was a
 *   cut operation.
 *
 * When Copying we
 *   Clear and free the contents of the clipboard and COPY the designated region
 *   into the clipboard.
 *
 * we need to pass @wbc as a control rather than a simple command-context so
 * that the control can claim the selection.
 **/
void
gnm_app_clipboard_cut_copy (WorkbookControl *wbc, gboolean is_cut,
			    SheetView *sv, GnmRange const *area,
			    gboolean animate_cursor)
{
	Sheet *sheet;

	g_return_if_fail (IS_SHEET_VIEW (sv));
	g_return_if_fail (area != NULL);
	g_return_if_fail (app != NULL);

	gnm_app_clipboard_clear (FALSE);
	sheet = sv_sheet (sv);
	g_free (app->clipboard_cut_range);
	app->clipboard_cut_range = gnm_range_dup (area);
	sv_weak_ref (sv, &(app->clipboard_sheet_view));

	if (!is_cut)
		app->clipboard_copied_contents =
			clipboard_copy_range (sheet, area);
	if (animate_cursor) {
		GList *l = g_list_append (NULL, (gpointer)area);
		sv_ant (sv, l);
		g_list_free (l);
	}

	if (wb_control_claim_selection (wbc)) {
		g_signal_emit (G_OBJECT (app), signals[CLIPBOARD_MODIFIED], 0);
	} else {
		gnm_app_clipboard_clear (FALSE);
		g_warning ("Unable to set selection ?");
	}
}
Exemple #2
0
/**
 * gnm_app_clipboard_cut_copy_obj:
 * @wbc: #WorkbookControl
 * @is_cut:
 * @sv: #SheetView
 * @objects: (element-type SheetObject): a list of #SheetObject which is freed
 *
 * Different than copying/cutting a region, this can actually cuts an object
 **/
void
gnm_app_clipboard_cut_copy_obj (WorkbookControl *wbc, gboolean is_cut,
				SheetView *sv, GSList *objects)
{
	g_return_if_fail (IS_SHEET_VIEW (sv));
	g_return_if_fail (objects != NULL);
	g_return_if_fail (app != NULL);

	gnm_app_clipboard_clear (FALSE);
	g_free (app->clipboard_cut_range);
	app->clipboard_cut_range = NULL;
	sv_weak_ref (sv, &(app->clipboard_sheet_view));
	app->clipboard_copied_contents
		= clipboard_copy_obj (sv_sheet (sv), objects);
	if (is_cut) {
		cmd_objects_delete (wbc, objects, _("Cut Object"));
		objects = NULL;
	}
	if (wb_control_claim_selection (wbc)) {
		g_signal_emit (G_OBJECT (app), signals[CLIPBOARD_MODIFIED], 0);
	} else {
		gnm_app_clipboard_clear (FALSE);
		g_warning ("Unable to set selection ?");
	}
	g_slist_free (objects);
}
/**
 * sv_menu_enable_insert :
 * @sv :
 * @col :
 * @row :
 *
 * control whether or not it is ok to insert cols or rows.  An internal routine
 * used by the selection mechanism to avoid erasing the entire sheet when
 * inserting the wrong dimension.
 */
static void
sv_menu_enable_insert (SheetView *sv, gboolean col, gboolean row)
{
	int flags = 0;

	g_return_if_fail (IS_SHEET_VIEW (sv));

	if (sv->enable_insert_cols != col) {
		flags |= MS_INSERT_COLS;
		sv->enable_insert_cols = col;
	}
	if (sv->enable_insert_rows != row) {
		flags |= MS_INSERT_ROWS;
		sv->enable_insert_rows = row;
	}
	if (sv->enable_insert_cells != (col|row)) {
		flags |= MS_INSERT_CELLS;
		sv->enable_insert_cells = (col|row);
	}

	/* during initialization it does not matter */
	if (!flags || sv->sheet == NULL)
		return;

	WORKBOOK_VIEW_FOREACH_CONTROL(sv_wbv (sv), wbc,
		wb_control_menu_state_update (wbc, flags););
/**
 * sv_selection_row_type :
 * @sv :
 * @col :
 *
 * Returns How much of column @col is selected in @sv.
 **/
ColRowSelectionType
sv_selection_row_type (SheetView const *sv, int row)
{
	GSList *ptr;
	GnmRange const *sr;
	int ret = COL_ROW_NO_SELECTION;

	g_return_val_if_fail (IS_SHEET_VIEW (sv), COL_ROW_NO_SELECTION);

	if (sv->selections == NULL)
		return COL_ROW_NO_SELECTION;

	for (ptr = sv->selections; ptr != NULL; ptr = ptr->next) {
		sr = ptr->data;

		if (sr->start.row > row || sr->end.row < row)
			continue;

		if (sr->start.col == 0 &&
		    sr->end.col == gnm_sheet_get_last_col (sv->sheet))
			return COL_ROW_FULL_SELECTION;

		ret = COL_ROW_PARTIAL_SELECTION;
	}

	return ret;
}
/**
 * sv_is_full_colrow_selected
 * @sv :
 * @is_cols :
 * @index :
 *
 * Returns TRUE if all of the selected cols/rows in the selection
 *	are fully selected and the selection contains the specified col.
 **/
gboolean
sv_is_full_colrow_selected (SheetView const *sv, gboolean is_cols, int index)
{
	GSList *l;
	gboolean found = FALSE;

	g_return_val_if_fail (IS_SHEET_VIEW (sv), FALSE);

	for (l = sv->selections; l != NULL; l = l->next){
		GnmRange const *r = l->data;
		if (is_cols) {
			if (r->start.row > 0 || r->end.row < gnm_sheet_get_last_row (sv->sheet))
				return FALSE;
			if (r->start.col <= index && index <= r->end.col)
				found = TRUE;
		} else {
			if (r->start.col > 0 || r->end.col < gnm_sheet_get_last_col (sv->sheet))
				return FALSE;
			if (r->start.row <= index && index <= r->end.row)
				found = TRUE;
		}
	}

	return found;
}
Exemple #6
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);
}
Exemple #7
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);
}