Exemple #1
0
static gboolean
cell_has_expr_or_number_or_blank (GnmCell const * cell)
{
	return (gnm_cell_is_empty (cell) ||
		(cell != NULL && gnm_cell_is_number (cell)) ||
		(cell != NULL && gnm_cell_has_expr (cell)));
}
Exemple #2
0
/*
 * cell_calc_span:
 * @cell:   The cell we will examine
 * @col1:   return value: the first column used by this cell
 * @col2:   return value: the last column used by this cell
 *
 * This routine returns the column interval used by a GnmCell.
 */
void
cell_calc_span (GnmCell const *cell, int *col1, int *col2)
{
	Sheet *sheet;
	int h_align, v_align, left, max_col, min_col;
	int row, pos;
	int cell_width_pixel, indented_w;
	GnmStyle const *style;
	ColRowInfo const *ci;
	GnmRange const *merge_left;
	GnmRange const *merge_right;

	g_return_if_fail (cell != NULL);

	sheet = cell->base.sheet;
	style = gnm_cell_get_style (cell);
	h_align = gnm_style_default_halign (style, cell);

        /*
	 * Report only one column is used if
	 *	- Cell is in a hidden col
	 *	- Cell is a number
	 *	- Cell is the top left of a merged cell
	 *	- The text fits inside column (for non center across selection)
	 *	- The alignment mode are set to "justify"
	 */
	if (sheet != NULL &&
	    h_align != HALIGN_CENTER_ACROSS_SELECTION &&
	    (gnm_cell_is_merged (cell) ||
	     (!sheet->display_formulas && gnm_cell_is_number (cell)))) {
		*col1 = *col2 = cell->pos.col;
		return;
	}

	v_align = gnm_style_get_align_v (style);
	row   = cell->pos.row;
	indented_w = cell_width_pixel = gnm_cell_rendered_width (cell);
	if (h_align == HALIGN_LEFT || h_align == HALIGN_RIGHT) {
		indented_w += gnm_cell_rendered_offset (cell);
		if (sheet->text_is_rtl)
			h_align = (h_align == HALIGN_LEFT) ? HALIGN_RIGHT : HALIGN_LEFT;
	}

	ci = sheet_col_get_info	(sheet, cell->pos.col);
	if (gnm_cell_is_empty (cell) ||
	    !ci->visible ||
	    (h_align != HALIGN_CENTER_ACROSS_SELECTION &&
		 (gnm_style_get_wrap_text (style) ||
		  indented_w <= COL_INTERNAL_WIDTH (ci))) ||
	    h_align == HALIGN_JUSTIFY ||
	    h_align == HALIGN_FILL ||
	    h_align == HALIGN_DISTRIBUTED ||
	    v_align == VALIGN_JUSTIFY ||
	    v_align == VALIGN_DISTRIBUTED) {
		*col1 = *col2 = cell->pos.col;
		return;
	}

	gnm_sheet_merge_get_adjacent (sheet, &cell->pos, &merge_left, &merge_right);
	min_col = (merge_left != NULL) ? merge_left->end.col : -1;
	max_col = (merge_right != NULL) ? merge_right->start.col : gnm_sheet_get_max_cols (sheet);

	*col1 = *col2 = cell->pos.col;
	switch (h_align) {
	case HALIGN_LEFT:
		pos = cell->pos.col + 1;
		left = indented_w - COL_INTERNAL_WIDTH (ci);

		for (; left > 0 && pos < max_col; pos++){
			ColRowInfo const *ci = sheet_col_get_info (sheet, pos);

			if (ci->visible) {
				if (!cellspan_is_empty (pos, cell))
					return;

				/* The space consumed is:
				 *   - The margin_b from the last column
				 *   - The width of the cell
				 */
				left -= ci->size_pixels - 1;
				*col2 = pos;
			}
		}
		return;

	case HALIGN_RIGHT:
		pos = cell->pos.col - 1;
		left = indented_w - COL_INTERNAL_WIDTH (ci);

		for (; left > 0 && pos > min_col; pos--){
			ColRowInfo const *ci = sheet_col_get_info (sheet, pos);

			if (ci->visible) {
				if (!cellspan_is_empty (pos, cell))
					return;

				/* The space consumed is:
				 *   - The margin_a from the last column
				 *   - The width of this cell
				 */
				left -= ci->size_pixels - 1;
				*col1 = pos;
			}
		}
		return;

	case HALIGN_CENTER: {
		int remain_left, remain_right;
		int pos_l, pos_r;

		pos_l = pos_r = cell->pos.col;
		left = cell_width_pixel - COL_INTERNAL_WIDTH (ci);

		remain_left  = left / 2 + (left % 2);
		remain_right = left / 2;

		for (; remain_left > 0 || remain_right > 0;){
			ColRowInfo const *ci;

			if (--pos_l > min_col){
				ci = sheet_col_get_info (sheet, pos_l);

				if (ci->visible) {
					if (cellspan_is_empty (pos_l, cell)) {
						remain_left -= ci->size_pixels - 1;
						*col1 = pos_l;
					} else
						remain_left = 0;
				}
			} else
				remain_left = 0;

			if (++pos_r < max_col){
				ci = sheet_col_get_info (sheet, pos_r);

				if (ci->visible) {
					if (cellspan_is_empty (pos_r, cell)) {
						remain_right -= ci->size_pixels - 1;
						*col2 = pos_r;
					} else
						max_col = remain_right = 0;
				}
			} else
				remain_right = 0;
		} /* for */
		break;
	} /* case HALIGN_CENTER */

	case HALIGN_CENTER_ACROSS_SELECTION: {
		int const row = cell->pos.row;
		int pos_l, pos_r;

		pos_l = pos_r = cell->pos.col;
		while (--pos_l > min_col) {
			ColRowInfo const *ci = sheet_col_get_info (sheet, pos_l);
			if (ci->visible) {
				if (cellspan_is_empty (pos_l, cell)) {
					GnmStyle const * const style =
						sheet_style_get (cell->base.sheet, pos_l, row);

					if (gnm_style_get_align_h (style) != HALIGN_CENTER_ACROSS_SELECTION)
						break;
					*col1 = pos_l;
				} else
					break;
			}
		}
		while (++pos_r < max_col) {
			ColRowInfo const *ci = sheet_col_get_info (sheet, pos_r);
			if (ci->visible) {
				if (cellspan_is_empty (pos_r, cell)) {
					GnmStyle const * const style =
						sheet_style_get (cell->base.sheet, pos_r, row);

					if (gnm_style_get_align_h (style) != HALIGN_CENTER_ACROSS_SELECTION)
						break;
					*col2 = pos_r;
				} else
					break;
			}
		}
		break;
	}

	default:
		g_warning ("Unknown horizontal alignment type %x.", h_align);
	} /* switch */
}