Esempio n. 1
0
/**
 * 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;
}
Esempio n. 2
0
/**
 * 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;
}
Esempio n. 3
0
GnmRange *
range_init_rows (GnmRange *r, Sheet const *sheet, int start_row, int end_row)
{
	r->start.col = 0;
	r->start.row = start_row;
	r->end.col = gnm_sheet_get_last_col (sheet);
	r->end.row = end_row;
	return r;
}
Esempio n. 4
0
/**
 * range_ensure_sanity :
 * @range : the range to check
 * @sheet : the sheet in which @range lives
 *
 * Silently clip a range to ensure that it does not contain areas
 * outside the valid bounds.  Does NOT fix inverted ranges.
 **/
void
range_ensure_sanity (GnmRange *range, Sheet const *sheet)
{
	range->start.col = MAX (0, range->start.col);
	range->end.col = MIN (range->end.col, gnm_sheet_get_last_col (sheet));

	range->start.row = MAX (0, range->start.row);
	range->end.row = MIN (range->end.row, gnm_sheet_get_last_row (sheet));
}
Esempio n. 5
0
GnmRange *
range_init_full_sheet (GnmRange *r, Sheet const *sheet)
{
	r->start.col = 0;
	r->start.row = 0;
	r->end.col = gnm_sheet_get_last_col (sheet);
	r->end.row = gnm_sheet_get_last_row (sheet);
	return r;
}
Esempio n. 6
0
/**
 * range_is_full :
 * @r    : the range.
 * @sheet : the sheet in which @r lives
 * @horiz : TRUE to check for a horizontal full ref (_cols_ [0..MAX))
 *
 * This determines whether @r completely spans a sheet
 * in the dimension specified by @horiz.
 *
 * Return value: TRUE if it is infinite else FALSE
 **/
gboolean
range_is_full (GnmRange const *r, Sheet const *sheet, gboolean horiz)
{
	if (horiz)
		return (r->start.col <= 0 &&
			r->end.col >= gnm_sheet_get_last_col (sheet));
	else
		return (r->start.row <= 0 &&
			r->end.row >= gnm_sheet_get_last_row (sheet));
}
Esempio n. 7
0
/**
 * sv_select_cur_row:
 * @sv: The sheet
 *
 * Selects an entire row
 */
void
sv_select_cur_row (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,
			0, r.start.row, gnm_sheet_get_last_col (sv->sheet), r.end.row);
		sheet_update (sv->sheet);
	}
}
Esempio n. 8
0
/*
 * sv_is_colrow_selected :
 * @sv : containing the selection
 * @colrow: The column or row number we are interested in.
 * @is_col: A flag indicating whether this it is a column or a row.
 *
 * Searches the selection list to see whether the entire col/row specified is
 * contained by the section regions.  Since the selection is stored as the set
 * overlapping user specifed regions we can safely search for the range directly.
 *
 * Eventually to be completely correct and deal with the case of someone manually
 * selection an entire col/row, in separate chunks,  we will need to do something
 * more advanced.
 */
gboolean
sv_is_colrow_selected (SheetView const *sv, int colrow, gboolean is_col)
{
	GSList *l;
	for (l = sv->selections; l != NULL; l = l->next) {
		GnmRange const *ss = l->data;

		if (is_col) {
			if (ss->start.row == 0 &&
			    ss->end.row >= gnm_sheet_get_last_row (sv->sheet) &&
			    ss->start.col <= colrow && colrow <= ss->end.col)
				return TRUE;
		} else {
			if (ss->start.col == 0 &&
			    ss->end.col >= gnm_sheet_get_last_col (sv->sheet) &&
			    ss->start.row <= colrow && colrow <= ss->end.row)
				return TRUE;
		}
	}
	return FALSE;
}
Esempio n. 9
0
/**
 * cmd_shift_rows:
 * @wbc :	The error context.
 * @sheet	the sheet
 * @col		column marking the start of the shift
 * @start_row	first row
 * @end_row	end row
 * @count	numbers of columns to shift.  negative numbers will
 *		delete count columns, positive number will insert
 *		count columns.
 *
 * Takes the cells in the region (col,start_row):(MAX_COL,end_row)
 * and copies them @count units (possibly negative) to the right.
 **/
void
cmd_shift_rows (WorkbookControl *wbc, Sheet *sheet,
		int col, int start_row, int end_row, int count)
{
	GnmExprRelocateInfo rinfo;
	char *desc;

	rinfo.reloc_type = GNM_EXPR_RELOCATE_MOVE_RANGE;
	rinfo.col_offset = count;
	rinfo.row_offset = 0;
	rinfo.origin_sheet = rinfo.target_sheet = sheet;
	rinfo.origin.start.row = start_row;
	rinfo.origin.start.col = col;
	rinfo.origin.end.row = end_row;
	rinfo.origin.end.col = gnm_sheet_get_last_col (sheet);
	if (count > 0)
		rinfo.origin.end.col -= count;

	desc = g_strdup_printf ((start_row != end_row)
				? _("Shift rows %s")
				: _("Shift row %s"),
				rows_name (start_row, end_row));
	cmd_paste_cut (wbc, &rinfo, FALSE, desc);
}
Esempio n. 10
0
/**
 * pg_get_col_offset:
 * @x: offset
 * @col_origin: if not null the origin of the column containing pixel @x is put here
 *
 * Return value: Column containing pixel x (and origin in @col_origin)
 **/
static int
pg_get_col_offset (GnmPreviewGrid *pg, int const x, int *col_origin)
{
	int col   = 0;
	int pixel = 1;
	int w;

	g_return_val_if_fail (pg != NULL, 0);

	do {
		w = pg->defaults.col_width;
		if (x <= (pixel + w) || w == 0) {
			if (col_origin)
				*col_origin = pixel;
			return col;
		}
		pixel += w;
	} while (++col < gnm_sheet_get_max_cols (pg->sheet));

	if (col_origin)
		*col_origin = pixel;

	return gnm_sheet_get_last_col (pg->sheet);
}
Esempio n. 11
0
/**
 * colrow_set_sizes:
 * @sheet: #Sheet
 * @is_cols:
 * @src:
 * @new_size:
 * @from:
 * @to:
 *
 * Returns: (transfer full):
 **/
ColRowStateGroup *
colrow_set_sizes (Sheet *sheet, gboolean is_cols,
		  ColRowIndexList *src, int new_size, int from, int to)
/* from & to are used to restrict fitting to that range. Pass 0, -1 if you want to use the */
/* whole row/column */
{
	int i;
	ColRowStateGroup *res = NULL;
	ColRowIndexList *ptr;

	for (ptr = src; ptr != NULL ; ptr = ptr->next) {
		ColRowIndex const *index = ptr->data;
		res = g_slist_prepend (res, colrow_get_states (sheet, is_cols,
			index->first, index->last));

		/* FIXME :
		 * If we are changing the size of more than half of the rows/col to
		 * something specific (not autosize) we should change the default
		 * row/col size instead.  However, it is unclear how to handle
		 * hard sizing.
		 *
		 * we need better management of rows/cols.  Currently if they are all
		 * defined calculation speed grinds to a halt.
		 */
		if (new_size > 0 && index->first == 0 &&
		    (index->last+1) >= colrow_max (is_cols, sheet)) {
			struct resize_closure closure;
			ColRowRLEState *rles = g_new0 (ColRowRLEState, 1);

			rles->length = -1; /* Flag as changing the default */

			closure.sheet	 = sheet;
			closure.new_size = new_size;
			closure.is_cols  = is_cols;
			if (is_cols) {
				rles->state.size_pts = sheet_col_get_default_size_pts (sheet);
				sheet_col_set_default_size_pixels (sheet, new_size);
				colrow_foreach (&sheet->cols, 0, gnm_sheet_get_last_col (sheet),
					&cb_set_colrow_size, &closure);
			} else {
				rles->state.size_pts = sheet_row_get_default_size_pts (sheet);
				sheet_row_set_default_size_pixels (sheet, new_size);
				colrow_foreach (&sheet->rows, 0, gnm_sheet_get_last_row (sheet),
					&cb_set_colrow_size, &closure);
			}

			/* force a re-render of cells with expanding formats */
			if (is_cols)
				sheet_foreach_cell_in_range (sheet, CELL_ITER_IGNORE_BLANK,
					0, 0, gnm_sheet_get_last_col (sheet), gnm_sheet_get_last_row (sheet),
					(CellIterFunc) &cb_clear_variable_width_content, NULL);

			/* Result is a magic 'default' record + >= 1 normal */
			return g_slist_prepend (res, g_slist_append (NULL, rles));
		}

		if (is_cols) {
			/* force a re-render of cells with expanding formats */
			sheet_foreach_cell_in_range (sheet, CELL_ITER_IGNORE_BLANK,
				index->first, 0, index->last, gnm_sheet_get_last_row (sheet),
				(CellIterFunc) &cb_clear_variable_width_content, NULL);

			/* In order to properly reposition cell comments in
			 * merged cells that cross the boundary we need to do
			 * everything.  Remove this when comments are handled
			 * properly */
			sheet->priv->reposition_objects.col = 0;
		}

		for (i = index->first ; i <= index->last ; ++i) {
			int tmp = new_size;
			if (tmp < 0) {
				int max = is_cols ? gnm_sheet_get_last_row (sheet)
					: gnm_sheet_get_last_col (sheet);
				if (from < 0)
					from = 0;
				if (to < 0 || to > max)
					to = max;
				if (from > max)
					from = to;
				/* Fall back to assigning the default if it is empty */
				tmp = (is_cols)
					? sheet_col_size_fit_pixels (sheet, i, from, to, FALSE)
					: sheet_row_size_fit_pixels (sheet, i, from, to, FALSE);
			}
			if (tmp > 0) {
				if (is_cols)
					sheet_col_set_size_pixels (sheet, i, tmp, new_size > 0);
				else
					sheet_row_set_size_pixels (sheet, i, tmp, new_size > 0);
			} else if (sheet_colrow_get (sheet, i, is_cols) != NULL) {
				if (is_cols)
					sheet_col_set_size_pixels (sheet, i,
						sheet_col_get_default_size_pixels (sheet), FALSE);
				else
					sheet_row_set_size_pixels (sheet, i,
						sheet_row_get_default_size_pixels (sheet), FALSE);
			}
		}
	}

	return res;
}
Esempio n. 12
0
/**
 * range_transpose:
 * @range: The range.
 * @sheet : the sheet in which @range lives
 * @boundary: The box to transpose inside
 *
 *   Effectively mirrors the ranges in 'boundary' around a
 * leading diagonal projected from offset.
 *
 * Return value: whether we clipped the range.
 **/
gboolean
range_transpose (GnmRange *range, Sheet const *sheet, GnmCellPos const *origin)
{
	gboolean clipped = FALSE;
	GnmRange src;
	int t;
	int last_col = gnm_sheet_get_last_col (sheet);
	int last_row = gnm_sheet_get_last_row (sheet);

	g_return_val_if_fail (range != NULL, TRUE);

	src = *range;

	/* Start col */
	t = origin->col + (src.start.row - origin->row);
	if (t > last_col) {
		clipped = TRUE;
		range->start.col = last_col;
	} else if (t < 0) {
		clipped = TRUE;
		range->start.col = 0;
	}
		range->start.col = t;

	/* Start row */
	t = origin->row + (src.start.col - origin->col);
	if (t > last_row) {
		clipped = TRUE;
		range->start.row = last_row;
	} else if (t < 0) {
		clipped = TRUE;
		range->start.row = 0;
	}
		range->start.row = t;


	/* End col */
	t = origin->col + (src.end.row - origin->row);
	if (t > last_col) {
		clipped = TRUE;
		range->end.col = last_col;
	} else if (t < 0) {
		clipped = TRUE;
		range->end.col = 0;
	}
		range->end.col = t;

	/* End row */
	t = origin->row + (src.end.col - origin->col);
	if (t > last_row) {
		clipped = TRUE;
		range->end.row = last_row;
	} else if (t < 0) {
		clipped = TRUE;
		range->end.row = 0;
	}
		range->end.row = t;

	g_assert (range_valid (range));

	return clipped;
}