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); }
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 } }
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; }
/** * 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; }