Exemplo n.º 1
0
/**
 * global_range_contained:
 * @sheet : The calling context #Sheet for references with sheet==NULL
 * @a:
 * @b:
 *
 * return true if a is contained in b
 * we do not handle 3d ranges
 **/
gboolean
global_range_contained (Sheet const *sheet, GnmValue const *a, GnmValue const *b)
{
	Sheet const *target;

	g_return_val_if_fail (a != NULL, FALSE);
	g_return_val_if_fail (b != NULL, FALSE);

	if ((a->type != VALUE_CELLRANGE) || (b->type != VALUE_CELLRANGE))
		return FALSE;

	target = eval_sheet (a->v_range.cell.a.sheet, sheet);
	if (target != eval_sheet (a->v_range.cell.b.sheet, sheet))
		return FALSE;

	if (target != eval_sheet (b->v_range.cell.a.sheet, sheet) ||
	    target != eval_sheet (b->v_range.cell.b.sheet, sheet))
		return FALSE;

	if (a->v_range.cell.a.row < b->v_range.cell.a.row)
		return FALSE;

	if (a->v_range.cell.b.row > b->v_range.cell.b.row)
		return FALSE;

	if (a->v_range.cell.a.col < b->v_range.cell.a.col)
		return FALSE;

	if (a->v_range.cell.b.col > b->v_range.cell.b.col)
		return FALSE;

	return TRUE;
}
Exemplo n.º 2
0
static void
cb_check_name (G_GNUC_UNUSED gpointer key, GnmNamedExpr *nexpr,
	       CheckName *user)
{
	GnmValue *v;

	if (nexpr->scope == NULL || nexpr->is_hidden || !nexpr->texpr)
		return;

	v = gnm_expr_top_get_range (nexpr->texpr);
	if (v != NULL) {
		if (v->type == VALUE_CELLRANGE) {
			GnmRangeRef const *ref = &v->v_range.cell;
			if (!ref->a.col_relative &&
			    !ref->b.col_relative &&
			    !ref->a.row_relative &&
			    !ref->b.row_relative &&
			    eval_sheet (ref->a.sheet, user->sheet) == user->sheet &&
			    eval_sheet (ref->b.sheet, user->sheet) == user->sheet &&
			    MIN (ref->a.col, ref->b.col) == user->r->start.col &&
			    MAX (ref->a.col, ref->b.col) == user->r->end.col &&
			    MIN (ref->a.row, ref->b.row) == user->r->start.row &&
			    MAX (ref->a.row, ref->b.row) == user->r->end.row)
				user->res = nexpr;
		}
		value_release (v);
	}
}
Exemplo n.º 3
0
/**
 * gnm_scenario_apply:
 * @sc: #GnmScenario
 *
 * Returns: (transfer full): the newly allocated #GOUndo.
 **/
GOUndo *
gnm_scenario_apply (GnmScenario *sc)
{
	GOUndo *undo = NULL;
	GSList *l;

	g_return_val_if_fail (GNM_IS_SCENARIO (sc), NULL);

	for (l = sc->items; l; l = l->next) {
		GnmScenarioItem *sci = l->data;
		GnmValue const *val = sci->value;
		GnmSheetRange sr;
		Sheet *sheet;

		if (!gnm_scenario_item_valid (sci, &sr))
			continue;
		sheet = eval_sheet (sr.sheet, sc->sheet);

		if (val) {
			/* FIXME: think about arrays.  */
			GnmCell *cell = sheet_cell_fetch
				(sheet,
				 sr.range.start.col,
				 sr.range.start.row);
			sheet_cell_set_value (cell, value_dup (val));
		} else {
			GOUndo *u = clipboard_copy_range_undo (sheet,
							       &sr.range);
			/* FIXME: Clear the range.  */
			undo = go_undo_combine (undo, u);
		}
	}

	return undo;
}
Exemplo n.º 4
0
/*
 * Finds a column index of a field.
 */
int
find_column_of_field (GnmEvalPos const *ep,
		      GnmValue const *database, GnmValue const *field)
{
        Sheet *sheet;
        GnmCell  *cell;
	gchar *field_name;
	int   begin_col, end_col, row, n, column;
	int   offset;

	// I'm not certain we should demand this, but the code clearly wants
	// it.
	if (!VALUE_IS_CELLRANGE (database))
		return -1;

	offset = database->v_range.cell.a.col;

	if (VALUE_IS_FLOAT (field))
		return value_get_as_int (field) + offset - 1;

	if (!VALUE_IS_STRING (field))
		return -1;

	sheet = eval_sheet (database->v_range.cell.a.sheet, ep->sheet);
	field_name = value_get_as_string (field);
	column = -1;

	/* find the column that is labeled after `field_name' */
	begin_col = database->v_range.cell.a.col;
	end_col = database->v_range.cell.b.col;
	row = database->v_range.cell.a.row;

	for (n = begin_col; n <= end_col; n++) {
		char const *txt;
		gboolean match;

		cell = sheet_cell_get (sheet, n, row);
		if (cell == NULL)
			continue;
		gnm_cell_eval (cell);

		txt = cell->value
			? value_peek_string (cell->value)
			: "";
		match = (g_ascii_strcasecmp (field_name, txt) == 0);
		if (match) {
			column = n;
			break;
		}
	}

	g_free (field_name);
	return column;
}
Exemplo n.º 5
0
/**
 * parse_database_criteria:
 * @ep: #GnmEvalPos
 * @database: #GnmValue
 * @criteria: #GnmValue
 *
 * Parses the criteria cell range.
 * Returns: (element-type GnmDBCriteria) (transfer full):
 */
GSList *
parse_database_criteria (GnmEvalPos const *ep, GnmValue const *database, GnmValue const *criteria)
{
	Sheet	*sheet;
	GnmCell	*cell;
        int   i;
	int   b_col, b_row, e_col, e_row;
	int   *field_ind;

	g_return_val_if_fail (VALUE_IS_CELLRANGE (criteria), NULL);

	sheet = eval_sheet (criteria->v_range.cell.a.sheet, ep->sheet);
	b_col = criteria->v_range.cell.a.col;
	b_row = criteria->v_range.cell.a.row;
	e_col = criteria->v_range.cell.b.col;
	e_row = criteria->v_range.cell.b.row;

	if (e_col < b_col) {
		int tmp = b_col;
		b_col = e_col;
		e_col = tmp;
	}

	/* Find the index numbers for the columns of criterias */
	field_ind = g_alloca (sizeof (int) * (e_col - b_col + 1));
	for (i = b_col; i <= e_col; i++) {
		cell = sheet_cell_get (sheet, i, b_row);
		if (cell == NULL)
			continue;
		gnm_cell_eval (cell);
		if (gnm_cell_is_empty (cell))
			continue;
		field_ind[i - b_col] =
			find_column_of_field (ep, database, cell->value);
		if (field_ind[i - b_col] == -1)
			return NULL;
	}

	return parse_criteria_range (sheet, b_col, b_row + 1,
				     e_col, e_row, field_ind,
				     FALSE);
}
Exemplo n.º 6
0
void
gnm_scenario_add_area (GnmScenario *sc, const GnmSheetRange *sr)
{
	GnmScenarioItem *sci;
	struct cb_save_cells data;

	g_return_if_fail (GNM_IS_SCENARIO (sc));
	g_return_if_fail (sr != NULL);

	sci = gnm_scenario_item_new (sc->sheet);
	gnm_scenario_item_set_range (sci, sr);
	sc->items = g_slist_prepend (sc->items, sci);

	data.items = NULL;
	data.sc = sc;
	sheet_foreach_cell_in_range
		(eval_sheet (sr->sheet, sc->sheet),
		 CELL_ITER_IGNORE_NONEXISTENT,
		 sr->range.start.col, sr->range.start.row,
		 sr->range.end.col, sr->range.end.row,
		 cb_save_cells, &data);
	sc->items = g_slist_concat (sc->items,
				    g_slist_reverse (data.items));
}
Exemplo n.º 7
0
/**
 * 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;
}
Exemplo n.º 8
0
void Patch::draw(SkCanvas* canvas, const SkPaint& paint, int nu, int nv,
                 bool doTextures, bool doColors) {
    if (nu < 1 || nv < 1) {
        return;
    }

    int i, npts = (nu + nv) * 2;
    SkAutoSTMalloc<16, SkPoint> storage(npts + 1);
    SkPoint* edge0 = storage.get();
    SkPoint* edge1 = edge0 + nu;
    SkPoint* edge2 = edge1 + nv;
    SkPoint* edge3 = edge2 + nu;

    // evaluate the edge points
    eval_patch_edge(fPts + 0, edge0, nu);
    eval_patch_edge(fPts + 3, edge1, nv);
    eval_patch_edge(fPts + 6, edge2, nu);
    eval_patch_edge(fPts + 9, edge3, nv);
    edge3[nv] = edge0[0];   // the last shall be first

    for (i = 0; i < npts; i++) {
//        canvas->drawLine(edge0[i].fX, edge0[i].fY, edge0[i+1].fX, edge0[i+1].fY, paint);
    }

    int row, vertCount = (nu + 1) * (nv + 1);
    SkAutoTMalloc<SkPoint>  vertStorage(vertCount);
    SkPoint* verts = vertStorage.get();

    // first row
    memcpy(verts, edge0, (nu + 1) * sizeof(SkPoint));
    // rows
    SkPoint* r = verts;
    for (row = 1; row < nv; row++) {
        r += nu + 1;
        r[0] = edge3[nv - row];
        for (int col = 1; col < nu; col++) {
            eval_sheet(edge0, nu, nv, col, row, &r[col]);
        }
        r[nu] = edge1[row];
    }
    // last row
    SkPoint* last = verts + nv * (nu + 1);
    for (i = 0; i <= nu; i++) {
        last[i] = edge2[nu - i];
    }

//    canvas->drawPoints(verts, vertCount, paint);

    int stripCount = (nu + 1) * 2;
    SkAutoTMalloc<SkPoint>  stripStorage(stripCount * 2);
    SkAutoTMalloc<SkColor>  colorStorage(stripCount);
    SkPoint* strip = stripStorage.get();
    SkPoint* tex = strip + stripCount;
    SkColor* colors = colorStorage.get();
    SkScalar t = 0;
    const SkScalar ds = SK_Scalar1 * fW / nu;
    const SkScalar dt = SK_Scalar1 * fH / nv;
    r = verts;
    for (row = 0; row < nv; row++) {
        SkPoint* upper = r;
        SkPoint* lower = r + nu + 1;
        r = lower;
        SkScalar s = 0;
        for (i = 0; i <= nu; i++)  {
            strip[i*2 + 0] = *upper++;
            strip[i*2 + 1] = *lower++;
            tex[i*2 + 0].set(s, t);
            tex[i*2 + 1].set(s, t + dt);
            colors[i*2 + 0] = make_color(s/fW, t/fH);
            colors[i*2 + 1] = make_color(s/fW, (t + dt)/fH);
            s += ds;
        }
        t += dt;
        canvas->drawVertices(SkCanvas::kTriangleStrip_VertexMode, stripCount,
                             strip, doTextures ? tex : nullptr,
                             doColors ? colors : nullptr, nullptr,
                             nullptr, 0, paint);
    }
}