Exemplo n.º 1
0
static void
item_grid_draw_merged_range (cairo_t *cr, GnmItemGrid *ig,
			     int start_x, int start_y,
			     GnmRange const *view, GnmRange const *range,
			     gboolean draw_selection, GtkStyleContext *ctxt)
{
	int l, r, t, b, last;
	SheetView const *sv = scg_view (ig->scg);
	WorkbookView *wbv = sv_wbv (sv);
	gboolean show_function_cell_markers = wbv->show_function_cell_markers;
	gboolean show_extension_markers = wbv->show_extension_markers;
	Sheet const *sheet  = sv->sheet;
	GnmCell const *cell = sheet_cell_get (sheet, range->start.col, range->start.row);
	int const dir = sheet->text_is_rtl ? -1 : 1;

	/* load style from corner which may not be visible */
	GnmStyle const *style = sheet_style_get (sheet, range->start.col, range->start.row);
	gboolean const is_selected = draw_selection &&
		(sv->edit_pos.col != range->start.col ||
		 sv->edit_pos.row != range->start.row) &&
		sv_is_full_range_selected (sv, range);

	/* Get the coordinates of the visible region */
	l = r = start_x;
	if (view->start.col < range->start.col)
		l += dir * scg_colrow_distance_get (ig->scg, TRUE,
			view->start.col, range->start.col);
	if (range->end.col <= (last = view->end.col))
		last = range->end.col;
	r += dir * scg_colrow_distance_get (ig->scg, TRUE, view->start.col, last+1);

	t = b = start_y;
	if (view->start.row < range->start.row)
		t += scg_colrow_distance_get (ig->scg, FALSE,
			view->start.row, range->start.row);
	if (range->end.row <= (last = view->end.row))
		last = range->end.row;
	b += scg_colrow_distance_get (ig->scg, FALSE, view->start.row, last+1);

	if (l == r || t == b)
		return;

	if (style->conditions) {
		GnmEvalPos ep;
		int res;
		eval_pos_init (&ep, (Sheet *)sheet, range->start.col, range->start.row);
		if ((res = gnm_style_conditions_eval (style->conditions, &ep)) >= 0)
			style = g_ptr_array_index (style->cond_styles, res);
	}

	/* Check for background THEN selection */
	if (gnumeric_background_set (style, cr, is_selected, ctxt) ||
	    is_selected) {
		/* Remember X excludes the far pixels */
		if (dir > 0)
			cairo_rectangle (cr, l, t, r-l+1, b-t+1);
		else
			cairo_rectangle (cr, r, t, l-r+1, b-t+1);
		cairo_fill (cr);
	}

	/* Expand the coords to include non-visible areas too.  The clipped
	 * region is only necessary when drawing the background */
	if (range->start.col < view->start.col)
		l -= dir * scg_colrow_distance_get (ig->scg, TRUE,
			range->start.col, view->start.col);
	if (view->end.col < range->end.col)
		r += dir * scg_colrow_distance_get (ig->scg, TRUE,
			view->end.col+1, range->end.col+1);
	if (range->start.row < view->start.row)
		t -= scg_colrow_distance_get (ig->scg, FALSE,
			range->start.row, view->start.row);
	if (view->end.row < range->end.row)
		b += scg_colrow_distance_get (ig->scg, FALSE,
			view->end.row+1, range->end.row+1);

	if (cell != NULL) {
		ColRowInfo *ri = sheet_row_get (sheet, range->start.row);

		if (ri->needs_respan)
			row_calc_spans (ri, cell->pos.row, sheet);

		if (dir > 0) {
			if (show_function_cell_markers)
				draw_function_marker (ig, cell, cr, l, t,
						      r - l, b - t, dir);
			cell_draw (cell, cr,
				   l, t, r - l, b - t, -1,
				   show_extension_markers);
		} else {
			if (show_function_cell_markers)
				draw_function_marker (ig, cell, cr, r, t,
						      l - r, b - t, dir);
			cell_draw (cell, cr,
				   r, t, l - r, b - t, -1,
				   show_extension_markers);
		}
	}
	if (dir > 0)
		gnm_style_border_draw_diag (style, cr, l, t, r, b);
	else
		gnm_style_border_draw_diag (style, cr, r, t, l, b);
}
Exemplo n.º 2
0
static void
search_get_value (gint row, gint column, gpointer _dd, GValue *value)
{
	DialogState *dd = (DialogState *)_dd;
	GnumericLazyList *ll = GNUMERIC_LAZY_LIST (gtk_tree_view_get_model (dd->matches_table));
	GnmSearchFilterResult *item = g_ptr_array_index (dd->matches, row);
	GnmCell *cell;
	GnmComment *comment;

	if (item->locus == GNM_SRL_COMMENT) {
		cell = NULL;
		comment = sheet_get_comment (item->ep.sheet, &item->ep.eval);
	} else {
		cell = sheet_cell_get (item->ep.sheet,
				       item->ep.eval.col,
				       item->ep.eval.row);
		comment = NULL;
	}

	g_value_init (value, ll->column_headers[column]);

#if 0
	g_print ("col=%d,row=%d\n", column, row);
#endif

	switch (column) {
	case COL_SHEET:
		g_value_set_string (value, item->ep.sheet->name_unquoted);
		return;
	case COL_CELL:
		g_value_set_string (value, cellpos_as_string (&item->ep.eval));
		return;
	case COL_TYPE:
		switch (item->locus) {
		case GNM_SRL_COMMENT:
			g_value_set_static_string (value, _("Comment"));
			return;
		case GNM_SRL_VALUE:
			g_value_set_static_string (value, _("Result"));
			return;
		case GNM_SRL_CONTENTS: {
			GnmValue *v = cell ? cell->value : NULL;
			char const *type;

			gboolean is_expr = cell && gnm_cell_has_expr (cell);
			gboolean is_value = !is_expr && !gnm_cell_is_empty (cell) && v;

			if (!cell)
				type = _("Deleted");
			else if (is_expr)
				type = _("Expression");
			else if (is_value && VALUE_IS_STRING (v))
				type = _("String");
			else if (is_value && VALUE_IS_FLOAT (v))
				type = _("Number");
			else
				type = _("Other value");

			g_value_set_static_string (value, type);
			return;
		}

#ifndef DEBUG_SWITCH_ENUM
	default:
		g_assert_not_reached ();
#endif
		}

	case COL_CONTENTS:
		switch (item->locus) {
		case GNM_SRL_COMMENT:
			if (comment)
				g_value_set_string (value, cell_comment_text_get (comment));
			else
				g_value_set_static_string (value, _("Deleted"));
			return;
		case GNM_SRL_VALUE:
			if (cell && cell->value)
				g_value_take_string (value, value_get_as_string (cell->value));
			else
				g_value_set_static_string (value, _("Deleted"));
			return;
		case GNM_SRL_CONTENTS:
			if (cell)
				g_value_take_string (value, gnm_cell_get_entered_text (cell));
			else
				g_value_set_static_string (value, _("Deleted"));
			return;
#ifndef DEBUG_SWITCH_ENUM
	default:
		g_assert_not_reached ();
#endif
		}

#ifndef DEBUG_SWITCH_ENUM
	default:
		g_assert_not_reached ();
#endif
	}
}
Exemplo n.º 3
0
int gnumeric_sheet_get_cell(GnumericSheetPtr sheet, int x, int y,
			    GSheetCellPtr cell) {
  gsheetcell_zero(cell);
  GnmValue const *value = sheet_cell_get_value((Sheet*)sheet,x,y);
  if (value==NULL) return 0;
  if (value->type == VALUE_EMPTY) return 0;

  GnmCell const *gcell = sheet_cell_get((Sheet*)sheet,x,y);
  if (gcell) {
    if (gnm_cell_has_expr (gcell)) {
      if (gcell->base.texpr->expr) {
	const GnmExpr *expr = gcell->base.texpr->expr;
	if (expr) {
	  if (expr->oper==GNM_EXPR_OP_FUNCALL) {
	    if (expr->func.func) {
	      const char *name = expr->func.func->name;
	      if (name) {
		if (strcasecmp(name,"hyperlink")==0) {
		  // Hyperlink. Take url part.
		  char *url = NULL;
		  char *txt = NULL;
		  if (expr->func.argc==2) {
		    const GnmExpr *expr0 = expr->func.argv[0];
		    if (expr0) {
		      if (expr0->oper == GNM_EXPR_OP_CONSTANT) {
			url = value_get_as_string(expr0->constant.value);
		      }
		    }
		    const GnmExpr *expr1 = expr->func.argv[1];
		    if (expr1) {
		      if (expr1->oper == GNM_EXPR_OP_CONSTANT) {
			txt = value_get_as_string(expr1->constant.value);
		      }
		    }
		  }
		  if (url&&txt) {
		    if (strcasecmp(url,txt)==0) {
		      cell->all = url;
		      cell->url = g_strdup(url);
		      cell->txt = g_strdup(url);
		      cell->is_url = 1;
		      return 0;
		    }
		    cell->all = g_strconcat("[",url,"|",txt,"]",NULL);
		    cell->url = url;
		    cell->txt = txt;
		    cell->is_url = 1;
		    return 0;
		  } else {
		    if (url) g_free(url);
		    if (txt) g_free(txt);
		  }
		}
	      }
	    }
	  }
	}
      }
      //return gnm_cell_get_entered_text(cell);
    }
  }

  GnmStyle const *style = sheet_style_get((Sheet*)sheet,x,y);
  GnmHLink* hlink = gnm_style_get_hlink (style);
  const guchar* hlink_target = NULL;
  if (hlink && IS_GNM_HLINK_URL (hlink)) {
    hlink_target = gnm_hlink_get_target (hlink);
    if (hlink_target) {
      //char *str = value_get_as_string(value);
      //if (!str) return str;
      //const char *str2 = " ";
      //char *result = g_strconcat(str,str2,hlink_target);
      //g_free(str);
      //return result;
      cell->is_url = 1;
      cell->all = g_strdup(hlink_target);
      cell->url = g_strdup(hlink_target);
      cell->txt = g_strdup(hlink_target);
      return 0;
    }
  }

  cell->all = value_get_as_string(value);
  return 0;
}
Exemplo n.º 4
0
/**
 * validation_eval:
 * @wbc :
 * @mstyle :
 * @sheet :
 *
 * validation set in the GnmStyle if applicable.
 **/
ValidationStatus
validation_eval (WorkbookControl *wbc, GnmStyle const *mstyle,
		 Sheet *sheet, GnmCellPos const *pos, gboolean *showed_dialog)
{
	GnmValidation const *v;
	GnmCell *cell;
	GnmValue *val;
	gnm_float x;
	int nok, i;
	GnmEvalPos ep;

	if (showed_dialog) *showed_dialog = FALSE;

	v = gnm_style_get_validation (mstyle);
	if (v == NULL)
		return VALIDATION_STATUS_VALID;

	if (v->type == VALIDATION_TYPE_ANY)
		return VALIDATION_STATUS_VALID;

	cell = sheet_cell_get (sheet, pos->col, pos->row);
	if (cell != NULL)
		gnm_cell_eval (cell);

	if (gnm_cell_is_empty (cell)) {
		if (v->allow_blank)
			return VALIDATION_STATUS_VALID;
		BARF (g_strdup_printf (_("Cell %s is not permitted to be blank"),
				       cell_name (cell)));
	}

	val = cell->value;
	switch (val->type) {
	case VALUE_ERROR:
		if (typeinfo[v->type].errors_not_allowed)
			BARF (g_strdup_printf (_("Cell %s is not permitted to contain error values"),
					       cell_name (cell)));
		break;

	case VALUE_BOOLEAN:
		if (typeinfo[v->type].bool_always_ok)
			return VALIDATION_STATUS_VALID;
		break;

	case VALUE_STRING:
		if (typeinfo[v->type].strings_not_allowed)
			BARF (g_strdup_printf (_("Cell %s is not permitted to contain strings"),
					       cell_name (cell)));
		break;

	default:
		break;
	}

	eval_pos_init_cell (&ep, cell);

	switch (v->type) {
	case VALIDATION_TYPE_AS_INT:
		x = value_get_as_float (val);
		if (gnm_fake_floor (x) == gnm_fake_ceil (x))
			break;
		else
			BARF (g_strdup_printf (_("'%s' is not an integer"),
					       value_peek_string (val)));

	case VALIDATION_TYPE_AS_NUMBER:
		x = value_get_as_float (val);
		break;

	case VALIDATION_TYPE_AS_DATE: /* What the hell does this do?  */
		x = value_get_as_float (val);
		if (x < 0)
			BARF (g_strdup_printf (_("'%s' is not a valid date"),
					       value_peek_string (val)));
		break;


	case VALIDATION_TYPE_AS_TIME: /* What the hell does this do?  */
		x = value_get_as_float (val);
		break;

	case VALIDATION_TYPE_IN_LIST:
		if (NULL != v->texpr[0]) {
			GnmValue *list = gnm_expr_top_eval (v->texpr[0], &ep,
				 GNM_EXPR_EVAL_PERMIT_NON_SCALAR | GNM_EXPR_EVAL_PERMIT_EMPTY);
			GnmValue *res = value_area_foreach (list, &ep, CELL_ITER_IGNORE_BLANK,
				 (GnmValueIterFunc) cb_validate_custom, val);
			value_release (list);
			if (res == NULL) {
				GnmParsePos pp;
				char *expr_str = gnm_expr_top_as_string
					(v->texpr[0],
					 parse_pos_init_evalpos (&pp, &ep),
					 ep.sheet->convs);
				char *msg = g_strdup_printf (_("%s does not contain the new value."), expr_str);
				g_free (expr_str);
				BARF (msg);
			}
		}
		return VALIDATION_STATUS_VALID;

	case VALIDATION_TYPE_TEXT_LENGTH:
		/* XL appears to use a very basic value->string mapping that
		 * ignores formatting.
		 * eg len (12/13/01) == len (37238) = 5
		 * This seems wrong for
		 */
		x = g_utf8_strlen (value_peek_string (val), -1);
		break;

	case VALIDATION_TYPE_CUSTOM: {
		gboolean valid;

		if (v->texpr[0] == NULL)
			return VALIDATION_STATUS_VALID;

		val = gnm_expr_top_eval (v->texpr[0], &ep, GNM_EXPR_EVAL_SCALAR_NON_EMPTY);
		valid = value_get_as_bool (val, NULL);
		value_release (val);

		if (valid)
			return VALIDATION_STATUS_VALID;
		else {
			GnmParsePos pp;
			char *expr_str = gnm_expr_top_as_string
				(v->texpr[0],
				 parse_pos_init_evalpos (&pp, &ep),
				 ep.sheet->convs);
			char *msg = g_strdup_printf (_("%s is not true."), expr_str);
			g_free (expr_str);
			BARF (msg);
		}
	}

	default:
		g_assert_not_reached ();
		return VALIDATION_STATUS_VALID;
	}

	if (v->op == VALIDATION_OP_NONE)
		return VALIDATION_STATUS_VALID;

	nok = 0;
	for (i = 0; i < opinfo[v->op].nops; i++) {
		GnmExprTop const *texpr_i = v->texpr[i];
		GnmExprTop const *texpr;
		GnmValue *cres;

		if (!texpr_i) {
			nok++;
			continue;
		}

		texpr = gnm_expr_top_new
			(gnm_expr_new_binary
			 (gnm_expr_new_constant (value_new_float (x)),
			  opinfo[v->op].ops[i],
			  gnm_expr_copy (texpr_i->expr)));
		cres = gnm_expr_top_eval
			(texpr, &ep, GNM_EXPR_EVAL_SCALAR_NON_EMPTY);
		if (value_get_as_bool (cres, NULL))
			nok++;
		value_release (cres);
		gnm_expr_top_unref (texpr);
	}

	if (nok < opinfo[v->op].ntrue)
		BARF (g_strdup_printf (_("%s is out of permitted range"),
				       value_peek_string (val)));

	return VALIDATION_STATUS_VALID;
}