/** * paste_cell: * @target_col: Column to put the cell into * @target_row: Row to put the cell into. * @src: A #GnmCelCopy with the content to paste * @paste_flags: Bit mask that describes the paste options. * * Pastes a cell in the spreadsheet. */ static void paste_cell (int target_col, int target_row, GnmCellCopy const *src, const struct paste_cell_data *dat) { Sheet *dst_sheet = dat->pt->sheet; int paste_flags = dat->pt->paste_flags; if (paste_flags & PASTE_OPER_MASK) paste_cell_with_operation (dst_sheet, target_col, target_row, &dat->rinfo, src, paste_flags); else { GnmCell *dst = sheet_cell_fetch (dst_sheet, target_col, target_row); if (NULL != src->texpr && (paste_flags & PASTE_CONTENTS)) { GnmExprTop const *relo = gnm_expr_top_relocate ( src->texpr, &dat->rinfo, FALSE); if (paste_flags & PASTE_TRANSPOSE) { GnmExprTop const *trelo = gnm_expr_top_transpose (relo ? relo : src->texpr); if (trelo) { if (relo) gnm_expr_top_unref (relo); relo = trelo; } } else if (!relo && gnm_expr_top_is_array_corner (src->texpr)) { /* We must not share array expressions. */ relo = gnm_expr_top_new (gnm_expr_copy (src->texpr->expr)); } gnm_cell_set_expr_and_value (dst, relo ? relo : src->texpr, value_dup (src->val), TRUE); if (NULL != relo) gnm_expr_top_unref (relo); } else { GnmValue *newval = NULL; GnmValue const *oldval = src->val; if (dat->translate_dates && oldval && VALUE_IS_FLOAT (oldval)) { GOFormat const *fmt = VALUE_FMT (oldval) ? VALUE_FMT (oldval) : gnm_style_get_format (gnm_cell_get_style (dst)); if (go_format_is_date (fmt) > 0) { gnm_float fnew = go_date_conv_translate (value_get_as_float (oldval), dat->cr->date_conv, workbook_date_conv (dst_sheet->workbook)); newval = value_new_float (fnew); value_set_fmt (newval, VALUE_FMT (oldval)); } } if (!newval) newval = value_dup (src->val); gnm_cell_set_value (dst, newval); } } }
static void set_value (GnmNlsolve *nl, int i, gnm_float x) { GnmCell *cell = g_ptr_array_index (nl->vars, i); if (cell->value && VALUE_IS_FLOAT (cell->value) && value_get_as_float (cell->value) == x) return; gnm_cell_set_value (cell, value_new_float (x)); cell_queue_recalc (cell); }
static void paste_cell_with_operation (Sheet *dst_sheet, int target_col, int target_row, GnmExprRelocateInfo const *rinfo, GnmCellCopy const *src, int paste_flags) { GnmCell *dst; GnmExprOp op; if (src->texpr == NULL && !VALUE_IS_EMPTY (src->val) && !VALUE_IS_NUMBER (src->val)) return; dst = sheet_cell_fetch (dst_sheet, target_col, target_row); if (!cell_has_expr_or_number_or_blank (dst)) return; op = paste_op_to_expr_op (paste_flags); /* FIXME : This does not handle arrays, linked cells, ranges, etc. */ if ((paste_flags & PASTE_CONTENTS) && (NULL != src->texpr || gnm_cell_has_expr (dst))) { GnmExpr const *old_expr = contents_as_expr (dst->base.texpr, dst->value); GnmExpr const *copied_expr = contents_as_expr (src->texpr, src->val); GnmExprTop const *res = gnm_expr_top_new (gnm_expr_new_binary (old_expr, op, copied_expr)); GnmExprTop const *relo = gnm_expr_top_relocate (res, rinfo, FALSE); if (relo) { gnm_cell_set_expr (dst, relo); gnm_expr_top_unref (relo); } else gnm_cell_set_expr (dst, res); gnm_expr_top_unref (res); } else { GnmValue *value; GnmEvalPos pos; GnmExpr const *expr = gnm_expr_new_binary ( gnm_expr_new_constant (value_dup (dst->value)), op, gnm_expr_new_constant (value_dup (src->val))); GnmExprTop const *texpr = gnm_expr_top_new (expr); eval_pos_init_cell (&pos, dst); pos.dep = NULL; /* no dynamic deps */ value = gnm_expr_top_eval (texpr, &pos, GNM_EXPR_EVAL_SCALAR_NON_EMPTY); gnm_expr_top_unref (texpr); gnm_cell_set_value (dst, value); } }
static void thrash_insert (Sheet *sheet) { int j; GnmStyle *style1 = gnm_style_new (); GnmStyle *style2 = gnm_style_new (); gnm_style_set_font_bold (style1, TRUE); gnm_style_set_font_italic (style1, TRUE); gnm_style_set_font_size (style2, 20.0); for (j = 0; j < INSERT_HEIGHT; j++) { GnmRange r; int i; for (i = 0; i < INSERT_WIDTH; i++) { GnmCell *cell; GnmStyle *setstyle; r.start.col = i; r.start.row = j; r.end = r.start; if (((i / 31) % 2) == 0) setstyle = style1; else setstyle = style2; gnm_style_ref (setstyle); sheet_style_attach (sheet, &r, setstyle); cell = sheet_cell_fetch (sheet, i, j); gnm_cell_set_value (cell, value_new_int (i), NULL); } r.start.col = 0; r.start.row = MAX (0, j - 1); r.end.col = gnm_sheet_get_max_cols (sheet); r.end.row = MIN (gnm_sheet_get_max_rows (sheet), j + 1); sheet_style_optimize (sheet, r); } gnm_style_unref (style1); gnm_style_unref (style2); }
static void add_cell (Sheet *sheet, const psiconv_sheet_cell psi_cell, const psiconv_formula_list psi_formulas, const GnmStyle * default_style) { GnmCell *cell; GnmValue *val; GnmExprTop const *expr = NULL; cell = sheet_cell_fetch (sheet, psi_cell->column, psi_cell->row); if (!cell) return; val = value_new_from_psi_cell (psi_cell); if (psi_cell->calculated) expr = expr_new_from_formula (psi_cell, psi_formulas); if (expr != NULL) { /* TODO : is there a notion of parse format ? * How does it store a user entered date ? */ if (val != NULL) gnm_cell_set_expr_and_value (cell, expr, val, TRUE); else gnm_cell_set_expr (cell, expr); } else if (val != NULL) { /* TODO : is there a notion of parse format ? * How does it store a user entered date ? */ gnm_cell_set_value (cell, val); } else { /* TODO : send this warning to iocontext with details of * which sheet and cell. */ g_warning ("Cell with no value or expression ?"); } if (expr) gnm_expr_top_unref (expr); /* TODO: Perhaps this must be moved above set_format */ set_style(sheet,psi_cell->row,psi_cell->column,psi_cell->layout, default_style); }
static GoalSeekStatus goal_seek_eval (gnm_float x, gnm_float *y, void *vevaldata) { GoalEvalData const *evaldata = vevaldata; GnmValue *v = value_new_float (x); if (evaldata->update_ui) { sheet_cell_set_value (evaldata->xcell, v); } else { gnm_cell_set_value (evaldata->xcell, v); cell_queue_recalc (evaldata->xcell); } workbook_recalc (evaldata->state->wb); if (evaldata->ycell->value) { *y = value_get_as_float (evaldata->ycell->value) - evaldata->ytarget; if (gnm_finite (*y)) return GOAL_SEEK_OK; } return GOAL_SEEK_ERROR; }
static GnmCell * pg_fetch_cell (GnmPreviewGrid *pg, int col, int row) { GnmPreviewGridClass *klass = GNM_PREVIEW_GRID_GET_CLASS (pg); GnmCell *cell; GnmValue *v = NULL; g_return_val_if_fail (klass != NULL, NULL); g_return_val_if_fail (pg != NULL, NULL); g_return_val_if_fail (col >= 0 && col < gnm_sheet_get_max_cols (pg->sheet), NULL); g_return_val_if_fail (row >= 0 && row < gnm_sheet_get_max_rows (pg->sheet), NULL); if (NULL != klass->get_cell_value) v = (klass->get_cell_value) (pg, col, row); if (NULL == v) v = value_dup (pg->defaults.value); cell = sheet_cell_fetch (pg->sheet, col, row); gnm_cell_set_value (cell, v); gnm_cell_render_value (cell, TRUE); return cell; }
static gboolean sylk_rtd_c_parse (SylkReader *state, char *str) { GnmValue *val = NULL; GnmExprTop const *texpr = NULL; gboolean is_array = FALSE; int r = -1, c = -1, tmp; char *next; for (; *str != '\0' ; str = next) { next = sylk_next_token (str); switch (*str) { case 'X': if (sylk_parse_int (str+1, &tmp)) state->pp.eval.col = tmp - 1; break; case 'Y': if (sylk_parse_int (str+1, &tmp)) state->pp.eval.row = tmp - 1; break; case 'K': /* ;K value: Value of the cell. */ if (val != NULL) { sylk_read_warning (state, _("Multiple values in the same cell")); value_release (val); val = NULL; } val = sylk_parse_value (state, str+1); break; case 'E': if (texpr != NULL) { sylk_read_warning (state, _("Multiple expressions in the same cell")); gnm_expr_top_unref (texpr); } texpr = sylk_parse_expr (state, str+1); break; case 'M' : /* ;M exp: Expression stored with UL corner of matrix (;R ;C defines the lower right corner). If the ;M field is supported, the ;K record is ignored. Note that no ;E field is written. */ if (texpr != NULL) { sylk_read_warning (state, _("Multiple expressions in the same cell")); gnm_expr_top_unref (texpr); } texpr = sylk_parse_expr (state, str+1); is_array = TRUE; break; case 'I' : /* ;I: Inside a matrix or table (at row ;R, col ;C) C record for UL corner must precede this record. Note that any ;K field is ignored if the ;I field is supported. No ;E field is written out. */ is_array = TRUE; break; case 'C' : sylk_parse_int (str+1, &c); break; case 'R' : sylk_parse_int (str+1, &r); break; case 'A' : /* ;Aauthor:^[ :text 1) till end of line 2) excel extension */ sylk_parse_comment (state, str+1); break; case 'G' : /* ;G: Defines shared value (may not have an ;E for this record). */ case 'D' : /* ;D: Defines shared expression. */ case 'S' : /* ;S: Shared expression/value given at row ;R, col ;C. C record for ;R, ;C must precede this one. Note that no ;E or ;K fields are written here (not allowed on Excel macro sheets). */ case 'N' : /* ;N: Cell NOT protected/locked (if ;N present in ;ID record). */ case 'P' : /* ;P: Cell protected/locked (if ;N not present in ;ID record). Note if this occurs for any cell, we protect the entire sheet. */ case 'H' : /* ;H: Cell hidden. */ case 'T' : /* ;Tref,ref: UL corner of table (;R ;C defines the lower left corner). Note that the defined rectangle is the INSIDE of the table only. Formulas and input cells are above and to the left of this rectangle. The row and column input cells are given in by the two refs (possibly only one). Note that Excel's input refs are single cells only. */ default: break; } } if (val != NULL || texpr != NULL) { GnmCell *cell = sheet_cell_fetch (state->pp.sheet, state->pp.eval.col, state->pp.eval.row); if (is_array) { if (texpr) { GnmRange rg; rg.start = state->pp.eval; rg.end.col = c - 1; rg.end.row = r - 1; gnm_cell_set_array (state->pp.sheet, &rg, texpr); gnm_expr_top_unref (texpr); } if (NULL != val) gnm_cell_assign_value (cell, val); } else if (NULL != texpr) { if (NULL != val) gnm_cell_set_expr_and_value (cell, texpr, val, TRUE); else gnm_cell_set_expr (cell, texpr); gnm_expr_top_unref (texpr); } else if (NULL != val) gnm_cell_set_value (cell, val); } return TRUE; }
G_MODULE_EXPORT void paradox_file_open (GOFileOpener const *fo, GOIOContext *io_context, WorkbookView *wb_view, GsfInput *input) { Workbook *wb; pxdoc_t *pxdoc; pxhead_t *pxh; pxfield_t *pxf; char *data; char *name; Sheet *sheet; GnmCell *cell; GnmValue *val = NULL; GOErrorInfo *open_error = NULL; guint row, i, j, offset; #ifdef PX_MEMORY_DEBUGGING PX_mp_init (); #endif #ifdef PX_MEMORY_DEBUGGING pxdoc = PX_new2 (gn_errorhandler, PX_mp_malloc, PX_mp_realloc, PX_mp_free); #else pxdoc = PX_new2 (gn_errorhandler, gn_malloc, gn_realloc, gn_free); #endif if (PX_open_gsf (pxdoc, input) < 0) { go_io_error_info_set (io_context, go_error_info_new_str_with_details ( _("Error while opening Paradox file."), open_error)); return; } pxh = pxdoc->px_head; PX_set_targetencoding (pxdoc, "UTF-8"); wb = wb_view_get_workbook (wb_view); name = workbook_sheet_get_free_name (wb, pxh->px_tablename, FALSE, TRUE); sheet = sheet_new (wb, name, 256, 65536); g_free (name); workbook_sheet_attach (wb, sheet); pxf = pxh->px_fields; for (i = 0 ; i < (guint) pxh->px_numfields; i++) { char str[30], *str2; char ctypes[26] = {'?', 'A', 'D', 'S', 'I', '$', 'N', '?', '?', 'L', '?', '?', 'M', 'B', 'F', 'O', 'G', '?', '?', '?', 'T', '@', '+', '#', 'Y', }; cell = sheet_cell_fetch (sheet, i, 0); if (pxf->px_ftype == pxfBCD) snprintf (str, 30, "%s,%c,%d", pxf->px_fname, ctypes[(int)pxf->px_ftype], pxf->px_fdc); else snprintf (str, 30, "%s,%c,%d", pxf->px_fname, ctypes[(int)pxf->px_ftype], pxf->px_flen); #if PXLIB_MAJOR_VERSION == 0 && (PXLIB_MINOR_VERION < 3 || (PXLIB_MAJOR_VERSION == 3 && PXLIB_MICRO_VERSION == 0)) /* Convert the field names to utf-8. This is actually in pxlib * responsibility, but hasn't been implemented yet. For the mean time * we *misuse* PX_get_data_alpha() */ PX_get_data_alpha (pxdoc, str, strlen (str), &str2); gnm_cell_set_text (cell, str2); pxdoc->free (pxdoc, str2); #else gnm_cell_set_text (cell, str); #endif pxf++; } { GnmRange r; GnmStyle *bold = gnm_style_new (); gnm_style_set_font_bold (bold, TRUE); sheet_style_apply_range (sheet, range_init (&r, 0, 0, pxh->px_numfields-1, 0), bold); } if ((data = (char *) pxdoc->malloc (pxdoc, pxh->px_recordsize, _("Could not allocate memory for record."))) == NULL) { go_io_error_info_set (io_context, go_error_info_new_str_with_details ( _("Error while opening Paradox file."), open_error)); return; } row = 1; for (j = 0; j < (guint)pxh->px_numrecords; j++) { pxdatablockinfo_t pxdbinfo; int isdeleted = 0; if (NULL != PX_get_record2 (pxdoc, j, data, &isdeleted, &pxdbinfo)) { offset = 0; pxf = pxh->px_fields; for (i = 0; i < (guint) pxh->px_numfields ; i++) { cell = sheet_cell_fetch (sheet, i, row); val = NULL; switch (pxf->px_ftype) { case pxfAlpha: { char *value; if (0 < PX_get_data_alpha (pxdoc, &data[offset], pxf->px_flen, &value)) { val = value_new_string_nocopy (value); /* value_set_fmt (val, field->fmt); */ } break; } case pxfShort: { short int value; if (0 < PX_get_data_short (pxdoc, &data[offset], pxf->px_flen, &value)) { val = value_new_int (value); } break; } case pxfAutoInc: case pxfLong: { long value; if (0 < PX_get_data_long (pxdoc, &data[offset], pxf->px_flen, &value)) { val = value_new_int (value); } break; } case pxfCurrency: case pxfNumber: { double value; if (0 < PX_get_data_double (pxdoc, &data[offset], pxf->px_flen, &value)) { val = value_new_float (value); if (pxf->px_ftype == pxfCurrency) value_set_fmt (val, go_format_default_money ()); } break; } case pxfTimestamp: { double value; if (0 < PX_get_data_double (pxdoc, &data[offset], pxf->px_flen, &value)) { value = value / 86400000.0; /* 693594 = number of days up to 31.12.1899 */ value -= 693594; val = value_new_float (value); value_set_fmt (val, go_format_default_date_time ()); } break; } case pxfLogical: { char value; if (0 < PX_get_data_byte (pxdoc, &data[offset], pxf->px_flen, &value)) { val = value_new_bool (value ? TRUE : FALSE); } break; } case pxfDate: { long value; int year, month, day; GDate *date; if (0 < PX_get_data_long (pxdoc, &data[offset], pxf->px_flen, &value)) { PX_SdnToGregorian (value+1721425, &year, &month, &day); date = g_date_new_dmy (day, month, year); val = value_new_int (go_date_g_to_serial (date, NULL)); value_set_fmt (val, go_format_default_date ()); g_date_free (date); } break; } case pxfTime: { long value; if (0 < PX_get_data_long (pxdoc, &data[offset], pxf->px_flen, &value)) { val = value_new_float (value/86400000.0); value_set_fmt (val, go_format_default_time ()); } break; } case pxfBCD: { char *value; if (0 < PX_get_data_bcd (pxdoc, &data[offset], pxf->px_fdc, &value)) { val = value_new_string_nocopy (value); } break; } case pxfMemoBLOb: { char *value; int size, mod_nr; if (0 < PX_get_data_blob (pxdoc, &data[offset], pxf->px_flen, &mod_nr, &size, &value)) { val = value_new_string_nocopy (value); } break; } default: val = value_new_string_nocopy ( g_strdup_printf (_("Field type %d is not supported."), pxf->px_ftype)); } if (val) gnm_cell_set_value (cell, val); offset += pxf->px_flen; pxf++; } if (pxh->px_filetype == pxfFileTypPrimIndex) { short int value; cell = sheet_cell_fetch (sheet, i++, row); if (0 < PX_get_data_short (pxdoc, &data[offset], 2, &value)) { val = value_new_int (value); gnm_cell_set_value (cell, val); } offset += 2; cell = sheet_cell_fetch (sheet, i++, row); if (0 < PX_get_data_short (pxdoc, &data[offset], 2, &value)) { val = value_new_int (value); gnm_cell_set_value (cell, val); } offset += 2; cell = sheet_cell_fetch (sheet, i++, row); if (0 < PX_get_data_short (pxdoc, &data[offset], 2, &value)) { val = value_new_int (value); gnm_cell_set_value (cell, val); } cell = sheet_cell_fetch (sheet, i++, row); val = value_new_int (pxdbinfo.number); gnm_cell_set_value (cell, val); } } row++; } pxdoc->free (pxdoc, data); PX_close (pxdoc); PX_delete (pxdoc); sheet_flag_recompute_spans (sheet); }
/* * Raturns FALSE on EOF. */ static gboolean dif_parse_data (DifInputContext *ctxt) { gboolean too_many_rows = FALSE, too_many_columns = FALSE; gint row = -1, col = 0; gint val_type; GnmCell *cell; gchar *msg; while (1) { if (!dif_get_line (ctxt)) return FALSE; val_type = atoi (ctxt->line); if (val_type == 0) { gchar const *comma = strchr (ctxt->line, ','); if (comma == NULL) go_io_warning (ctxt->io_context, _("Syntax error at line %d. Ignoring."), ctxt->line_no); else if (col > gnm_sheet_get_max_cols (ctxt->sheet)) { too_many_columns = TRUE; break; } else { gnm_float num = gnm_strto (comma+1, NULL); GnmValue *v = NULL; if (!dif_get_line (ctxt)) return FALSE; if (0 == strcmp (ctxt->line, "V")) { /* V value */ v = value_new_float (num); } else if (0 == strcmp (ctxt->line, "NA")) { /* NA not available res must be O */ v = value_new_error_NA (NULL); } else if (0 == strcmp (ctxt->line, "TRUE")) { /* TRUE bool T res must be 1 */ v = value_new_bool (TRUE); } else if (0 == strcmp (ctxt->line, "FALSE")) { /* FALSE bool F res must be O */ v = value_new_bool (TRUE); } else if (0 == strcmp (ctxt->line, "ERROR")) { /* ERROR err res must be O */ go_io_warning (ctxt->io_context, _("Unknown value type '%s' at line %d. Ignoring."), ctxt->line, ctxt->line_no); } if (NULL != v) { cell = sheet_cell_fetch (ctxt->sheet, col, row); gnm_cell_set_value (cell, v); } col++; } } else if (val_type == 1) { if (!dif_get_line (ctxt)) return FALSE; if (col > gnm_sheet_get_max_cols (ctxt->sheet)) { too_many_columns = TRUE; continue; } cell = sheet_cell_fetch (ctxt->sheet, col, row); if (ctxt->line_len >= 2 && ctxt->line[0] == '"' && ctxt->line[ctxt->line_len - 1] == '"') { ctxt->line[ctxt->line_len - 1] = '\0'; gnm_cell_set_text (cell, ctxt->line + 1); } else gnm_cell_set_text (cell, ctxt->line); col++; } else if (val_type == -1) { if (!dif_get_line (ctxt)) return FALSE; if (strcmp (ctxt->line, "BOT") == 0) { col = 0; row++; if (row > gnm_sheet_get_max_rows (ctxt->sheet)) { too_many_rows = TRUE; break; } } else if (strcmp (ctxt->line, "EOD") == 0) { break; } else { msg = g_strdup_printf ( _("Unknown data value \"%s\" at line %d. Ignoring."), ctxt->line, ctxt->line_no); g_warning ("%s", msg); g_free (msg); } } else { msg = g_strdup_printf ( _("Unknown value type %d at line %d. Ignoring."), val_type, ctxt->line_no); g_warning ("%s", msg); g_free (msg); (void) dif_get_line (ctxt); } } if (too_many_rows) { g_warning (_("DIF file has more than the maximum number of rows %d. " "Ignoring remaining rows."), gnm_sheet_get_max_rows (ctxt->sheet)); } if (too_many_columns) { g_warning (_("DIF file has more than the maximum number of columns %d. " "Ignoring remaining columns."), gnm_sheet_get_max_cols (ctxt->sheet)); } return TRUE; }