Example #1
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;
}
Example #2
0
static gboolean
sheet_cell_or_one_below_is_not_empty (Sheet *sheet, int col, int row)
{
	return !sheet_is_cell_empty (sheet, col, row) ||
		(row < gnm_sheet_get_last_row (sheet) &&
		 !sheet_is_cell_empty (sheet, col, row+1));
}
Example #3
0
/**
 * sv_selection_col_type :
 * @sv :
 * @col :
 *
 * Returns How much of column @col is selected in @sv.
 **/
ColRowSelectionType
sv_selection_col_type (SheetView const *sv, int col)
{
	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.col > col || sr->end.col < col)
			continue;

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

		ret = COL_ROW_PARTIAL_SELECTION;
	}

	return ret;
}
Example #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));
}
Example #5
0
GnmRange *
range_init_cols (GnmRange *r, Sheet const *sheet, int start_col, int end_col)
{
	r->start.col = start_col;
	r->start.row = 0;
	r->end.col = end_col;
	r->end.row = gnm_sheet_get_last_row (sheet);
	return r;
}
Example #6
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;
}
Example #7
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));
}
Example #8
0
void
colrow_autofit_col (Sheet *sheet, GnmRange *r)
{
	colrow_autofit (sheet, r, TRUE, TRUE,
			TRUE, FALSE, NULL, NULL);
	sheet_foreach_cell_in_range (sheet, CELL_ITER_IGNORE_BLANK,
				     r->start.col, 0,
				     r->end.col, gnm_sheet_get_last_row (sheet),
				     (CellIterFunc) &cb_clear_variable_width_content,
				     NULL);
}
Example #9
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 #10
0
void
filter_show_all (WorkbookControl *wbc)
{
	Sheet *sheet = wb_control_cur_sheet (wbc);

	/* FIXME: This is slow. We should probably have a linked list
	 * containing the filtered rows in the sheet structure. */
	colrow_foreach (&sheet->rows, 0, gnm_sheet_get_last_row (sheet),
			(ColRowHandler) cb_show_all, sheet);
	sheet->has_filtered_rows = FALSE;
	sheet_redraw_all (sheet, TRUE);

	wb_control_menu_state_update (wbc, MS_FILTER_STATE_CHANGED);
}
Example #11
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;
}
Example #12
0
/*
 * colrow_set_visibility_list :
 *
 * This is the high level command that is wrapped by undo and redo.
 * It should not be called by other commands.
 */
void
colrow_set_visibility_list (Sheet *sheet, gboolean is_cols,
			    gboolean visible, ColRowVisList *list)
{
	ColRowVisList *ptr;
	ColRowIndex *info;

	for (ptr = list; ptr != NULL ; ptr = ptr->next) {
		info = ptr->data;
		colrow_set_visibility (sheet, is_cols, visible,
				       info->first, info->last);
	}

	if (visible)
		sheet_colrow_optimize (sheet);

	if (is_cols)
		sheet_queue_respan (sheet, 0, gnm_sheet_get_last_row (sheet));
	if (list != NULL)
		sheet_redraw_all (sheet, TRUE);
}
Example #13
0
/**
 * pg_get_row_offset:
 * pg:
 * @y: offset
 * @row_origin: if not null the origin of the row containing pixel @y is put here
 *
 * Return value: Row containing pixel y (and origin in @row_origin)
 **/
static int
pg_get_row_offset (GnmPreviewGrid *pg, int const y, int *row_origin)
{
	int row   = 0;
	int pixel = 1;
	int const h = pg->defaults.row_height;

	g_return_val_if_fail (pg != NULL, 0);

	do {
		if (y <= (pixel + h) || h == 0) {
			if (row_origin)
				*row_origin = pixel;
			return row;
		}
		pixel += h;
	} while (++row < gnm_sheet_get_max_rows (pg->sheet));

	if (row_origin)
		*row_origin = pixel;

	return gnm_sheet_get_last_row (pg->sheet);
}
Example #14
0
/**
 * cmd_shift_cols:
 * @wbc:	The error context.
 * @sheet:	the sheet
 * @start_col:	first column
 * @end_col:	end column
 * @row:	row marking the start of the shift
 * @count:	numbers of rows to shift.  a negative numbers will
 *		delete count rows, positive number will insert
 *		count rows.
 *
 * Takes the cells in the region (start_col,row):(end_col,MAX_ROW)
 * and copies them @count units (possibly negative) downwards.
 */
void
cmd_shift_cols (WorkbookControl *wbc, Sheet *sheet,
		int start_col, int end_col, int row, int count)
{
	GnmExprRelocateInfo rinfo;
	char *desc;

	rinfo.reloc_type = GNM_EXPR_RELOCATE_MOVE_RANGE;
	rinfo.col_offset = 0;
	rinfo.row_offset = count;
	rinfo.origin_sheet = rinfo.target_sheet = sheet;
	rinfo.origin.start.col = start_col;
	rinfo.origin.start.row = row;
	rinfo.origin.end.col = end_col;
	rinfo.origin.end.row = gnm_sheet_get_last_row (sheet);
	if (count > 0)
		rinfo.origin.end.row -= count;

	desc = g_strdup_printf ((start_col != end_col)
				? _("Shift columns %s")
				: _("Shift column %s"),
				cols_name (start_col, end_col));
	cmd_paste_cut (wbc, &rinfo, FALSE, desc);
}
Example #15
0
void
colrow_restore_state_group (Sheet *sheet, gboolean is_cols,
			    ColRowIndexList *selection,
			    ColRowStateGroup *state_groups)
{
	ColRowStateGroup *ptr = state_groups;

	/* Cycle to end, we have to traverse the selections
	 * in parallel with the state_groups
	 */
	selection = g_list_last (selection);
	for (; selection != NULL && ptr != NULL ; ptr = ptr->next) {
		ColRowIndex const *index = selection->data;
		ColRowStateList *list = ptr->data;
		ColRowRLEState const *rles = list->data;

		/* MAGIC : the -1 was set above to flag this */
		if (rles->length == -1) {
			if (is_cols)
				sheet_col_set_default_size_pts (sheet, rles->state.size_pts);
			else
				sheet_row_set_default_size_pts (sheet, rles->state.size_pts);

			/* we are guaranteed to have at least 1 more record */
			ptr = ptr->next;
		}

		colrow_set_states (sheet, is_cols, index->first, ptr->data);
		/* force a re-render of cells with expanding formats */
		if (is_cols)
			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);
		selection = selection->prev;
	}
}
Example #16
0
static void
resize_columns (Sheet *sheet)
{
	GnmRange r;

	if (gnm_debug_flag ("stf"))
		g_printerr ("Auto-fitting columns...\n");

	/* If we have lots of rows, auto-fitting will take a very long
	   time.  It is probably better to look at only, say, 1000 rows
	   of data.  */
	range_init_full_sheet (&r, sheet);
	r.end.row = MIN (r.end.row, 1000);

	colrow_autofit (sheet, &r, TRUE,
			TRUE, /* Ignore strings */
			TRUE, /* Don't shrink */
			TRUE, /* Don't shrink */
			NULL, NULL);
	if (gnm_debug_flag ("stf"))
		g_printerr ("Auto-fitting columns...  done\n");

	sheet_queue_respan (sheet, 0, gnm_sheet_get_last_row (sheet));
}
Example #17
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;
}
Example #18
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;
}