/** * parse_criteria: * @crit_val: #GnmValue * @date_conv: #GODateConventions * * Returns: (transfer full): GnmCriteria which caller must free. * * ">=value" * "<=value" * "<>value" * "<value" * ">value" * "=value" * "pattern" **/ GnmCriteria * parse_criteria (GnmValue const *crit_val, GODateConventions const *date_conv, gboolean anchor_end) { int len; char const *criteria; GnmCriteria *res = g_new0 (GnmCriteria, 1); GnmValue *empty; res->iter_flags = CELL_ITER_IGNORE_BLANK; res->date_conv = date_conv; if (VALUE_IS_NUMBER (crit_val)) { res->fun = criteria_test_equal; res->x = value_dup (crit_val); return res; } criteria = value_peek_string (crit_val); if (strncmp (criteria, "<=", 2) == 0) { res->fun = criteria_test_less_or_equal; len = 2; } else if (strncmp (criteria, ">=", 2) == 0) { res->fun = criteria_test_greater_or_equal; len = 2; } else if (strncmp (criteria, "<>", 2) == 0) { /* "<>" by itself is special: */ res->fun = (criteria[2] == 0) ? criteria_test_nonempty : criteria_test_unequal; len = 2; } else if (*criteria == '<') { res->fun = criteria_test_less; len = 1; } else if (*criteria == '=') { /* "=" by itself is special: */ res->fun = (criteria[1] == 0) ? criteria_test_empty : criteria_test_equal; len = 1; } else if (*criteria == '>') { res->fun = criteria_test_greater; len = 1; } else { res->fun = criteria_test_match; res->has_rx = (gnm_regcomp_XL (&res->rx, criteria, GO_REG_ICASE, TRUE, anchor_end) == GO_REG_OK); len = 0; } res->x = format_match_number (criteria + len, NULL, date_conv); if (res->x == NULL) res->x = value_new_string (criteria + len); else if (len == 0 && VALUE_IS_NUMBER (res->x)) res->fun = criteria_test_equal; empty = value_new_empty (); if (res->fun (empty, res)) res->iter_flags &= ~CELL_ITER_IGNORE_BLANK; value_release (empty); res->ref_count = 1; return res; }
static void gnm_preview_grid_init (GnmPreviewGrid *pg) { pg->sheet = g_object_new (GNM_SHEET_TYPE, "rows", 256, "columns", 256, NULL); pg->gridlines = FALSE; pg->defaults.col_width = 64; pg->defaults.row_height = 17; pg->defaults.style = gnm_style_new_default (); pg->defaults.value = value_new_empty (); }
static GnmValue * value_new_from_psi_cell(const psiconv_sheet_cell psi_cell) { switch (psi_cell->type) { case psiconv_cell_int : return value_new_int(psi_cell->data.dat_int); case psiconv_cell_float : return value_new_float(psi_cell->data.dat_float); case psiconv_cell_string : return psi_new_string(psi_cell->data.dat_string); case psiconv_cell_bool : return value_new_bool(psi_cell->data.dat_bool); case psiconv_cell_blank : return value_new_empty(); case psiconv_cell_error : /* TODO: value_new_error */ return value_new_empty(); default : /* TODO: value_new_error */ return value_new_empty(); } return NULL; }
/** * find_rows_that_match: * @sheet: #Sheet * @first_col: first column. * @first_row: first row. * @last_col: last column. * @last_row: laset row. * @criterias: (element-type GnmDBCriteria): the criteria to use. * @unique_only: * * Finds the rows from the given database that match the criteria. * Returns: (element-type int) (transfer full): the list of matching rows. **/ GSList * find_rows_that_match (Sheet *sheet, int first_col, int first_row, int last_col, int last_row, GSList *criterias, gboolean unique_only) { GSList *rows = NULL; GSList const *crit_ptr, *cond_ptr; int row; gboolean add_flag; char const *t1, *t2; GnmCell *test_cell; GnmValue const *empty = value_new_empty (); for (row = first_row; row <= last_row; row++) { add_flag = TRUE; for (crit_ptr = criterias; crit_ptr; crit_ptr = crit_ptr->next) { GnmDBCriteria const *crit = crit_ptr->data; add_flag = TRUE; for (cond_ptr = crit->conditions; cond_ptr != NULL ; cond_ptr = cond_ptr->next) { GnmCriteria *cond = cond_ptr->data; test_cell = sheet_cell_get (sheet, cond->column, row); if (test_cell != NULL) gnm_cell_eval (test_cell); if (!cond->fun (test_cell ? test_cell->value : empty, cond)) { add_flag = FALSE; break; } } if (add_flag) break; } if (add_flag) { gint *p; if (unique_only) { GSList *c; GnmCell *cell; gint i, trow; for (c = rows; c != NULL; c = c->next) { trow = *((gint *) c->data); for (i = first_col; i <= last_col; i++) { test_cell = sheet_cell_get (sheet, i, trow); cell = sheet_cell_get (sheet, i, row); /* FIXME: this is probably not right, but crashing is more wrong. */ if (test_cell == NULL || cell == NULL) continue; t1 = cell->value ? value_peek_string (cell->value) : ""; t2 = test_cell->value ? value_peek_string (test_cell->value) : ""; if (strcmp (t1, t2) != 0) goto row_ok; } goto filter_row; row_ok: ; } } p = g_new (gint, 1); *p = row; rows = g_slist_prepend (rows, (gpointer) p); filter_row: ; } } return g_slist_reverse (rows); }
static GODataCache * build_cache(void) { Workbook *wb; Sheet *sheet; GODataCache *cache; GnmRange *range; int row, col, numRows = 60, numCols = 5; wb = workbook_new(); sheet = workbook_sheet_add (wb, -1, 1024, 1024); for (row = 0; row < numRows; row++) { for (col = 0; col < numCols; col++) { GnmCell * tempCell = sheet_cell_create(sheet, col, row); GnmValue * tempVal; if (col == 0) { if (row%4 == 0) { tempVal = value_new_string_nocopy((char *)"A"); } else if (row%4 == 1) { tempVal = value_new_string_nocopy((char *)"B"); } else if (row%4 == 2) { tempVal = value_new_string_nocopy((char *)"C"); } else { tempVal = value_new_string_nocopy((char *)"D"); } } else if (col == 1) { tempVal = value_new_int(row); } else if (col == 2) { if (row%5 == 0) { tempVal = value_new_float(14.4); } else if (row%5 == 1) { tempVal = value_new_float(18.8); } else if (row%5 == 2) { tempVal = value_new_float(7.6); } else if (row%5 == 3) { tempVal = value_new_float(3.3); } else { tempVal = value_new_float(11.6); } } else if (col == 3) { tempVal = value_new_int(row % 10); } else if (col == 4) { if (row == 0) { GnmEvalPos *pos = g_new(GnmEvalPos, 1); pos = eval_pos_init(pos, sheet, col, row); tempVal = value_new_error_DIV0(pos); } else if (row == 1) { GnmEvalPos *pos = g_new(GnmEvalPos, 1); pos = eval_pos_init(pos, sheet, col, row); tempVal = value_new_error_NA(pos); } else if (row == 2) { GnmEvalPos *pos = g_new(GnmEvalPos, 1); pos = eval_pos_init(pos, sheet, col, row); tempVal = value_new_error_REF(pos); } else if (row == 3) { tempVal = value_new_bool(TRUE); } else if (row == 4) { tempVal = value_new_bool(FALSE); } else if (row == 5) { tempVal = value_new_empty(); } else { if (row%5 == 1) { tempVal = value_new_string_nocopy((char *)"a"); } else if (row%5 == 2) { tempVal = value_new_string_nocopy((char *)"b"); } else if (row%5 == 3) { tempVal = value_new_string_nocopy((char *)"c"); } else if (row%5 == 4) { tempVal = value_new_string_nocopy((char *)"d"); } else { tempVal = value_new_string_nocopy((char *)"e"); } } } sheet_cell_set_value(tempCell, tempVal); } } cache = g_object_new(GO_DATA_CACHE_TYPE, NULL); range = g_new(GnmRange, 1); range = range_init(range, 0, 0, numCols - 1, numRows - 1); go_data_cache_build_cache(cache, sheet, range); g_object_unref (wb); return cache; }
static GnmValue * new_gnm_value_from_xloper (const XLOPER*x) { GnmValue * g = NULL; if (NULL != x) { switch (x->xltype & xltypeType) { case xltypeNum: g = value_new_float (x->val.num); break; case xltypeStr: { char *o = NULL; const char *s = x->val.str; if (NULL != s) { guint m = ((unsigned char)s[0]) + 1U; o = g_new (char, m); g_strlcpy (o, s + 1, m); } g = value_new_string_nocopy (o); break; } case xltypeBool: g = value_new_bool (x->val.boolean); break; case xltypeRef: unsupported_xloper_type (x); break; case xltypeErr: g = value_new_error_std (NULL, gnm_value_error_from_xloper (x)); break; case xltypeFlow: unsupported_xloper_type (x); break; case xltypeMulti: { guint m = x->val.array.columns; guint n = x->val.array.rows; if (m > 0 && n > 0) { guint i; g = value_new_array_empty (m,n); for (i = 0; i < m; ++i) { guint j; for (j = 0; j < n; ++j) { g->v_array.vals[i][j] = new_gnm_value_from_xloper (x->val.array.lparray + i + j * m); } } } else { g = value_new_error_std (NULL, GNM_ERROR_VALUE); } break; } case xltypeMissing: break; case xltypeNil: g = value_new_empty (); break; case xltypeSRef: unsupported_xloper_type (x); break; case xltypeInt: g = value_new_int (x->val.w); break; default: unsupported_xloper_type (x); } } else {
/** * value_area_get_x_y: * @v: const #GnmValue * * @x: column * @y: row * @ep: const #GnmEvalPos * * * An internal routine to get a cell from an array or range. * Ensures that elements of CELLRANGE are evaluated * * If any problems occur a NULL is returned. **/ GnmValue const * value_area_get_x_y (GnmValue const *v, int x, int y, GnmEvalPos const *ep) { g_return_val_if_fail (v, NULL); if (VALUE_IS_ARRAY (v)){ g_return_val_if_fail (x < v->v_array.x && y < v->v_array.y, NULL); return v->v_array.vals [x][y]; } else if (VALUE_IS_CELLRANGE (v)) { GnmCellRef const * const a = &v->v_range.cell.a; GnmCellRef const * const b = &v->v_range.cell.b; int a_col = a->col; int a_row = a->row; int b_col = b->col; int b_row = b->row; GnmCell *cell; Sheet *sheet; /* Handle relative references */ if (a->col_relative) a_col += ep->eval.col; if (a->row_relative) a_row += ep->eval.row; if (b->col_relative) b_col += ep->eval.col; if (b->row_relative) b_row += ep->eval.row; /* Handle inverted references */ if (a_row > b_row) { int tmp = a_row; a_row = b_row; b_row = tmp; } if (a_col > b_col) { int tmp = a_col; a_col = b_col; b_col = tmp; } a_col += x; a_row += y; /* * FIXME FIXME FIXME * This should return NA but some of the math functions may * rely on this for now. */ g_return_val_if_fail (a_row<=b_row, NULL); g_return_val_if_fail (a_col<=b_col, NULL); sheet = eval_sheet (a->sheet, ep->sheet); g_return_val_if_fail (IS_SHEET (sheet), NULL); /* Speedup */ if (sheet->cols.max_used < a_col || sheet->rows.max_used < a_row) return value_new_empty (); cell = sheet_cell_get (sheet, a_col, a_row); if (cell != NULL) { gnm_cell_eval (cell); return cell->value; } return value_new_empty (); } else return v; return NULL; }