Commit 9d1aa45a authored by Jody Goldberg's avatar Jody Goldberg Committed by Jody Goldberg
Browse files

Rewrite to use eval_expr. (paste_cell_with_operation) : rework to handle


2000-11-08  Jody Goldberg <jgoldberg@home.com>

	* src/clipboard.c (apply_paste_oper_to_values) : Rewrite to use
	  eval_expr.
	(paste_cell_with_operation) : rework to handle pasting as_value
	  correctly.
	(paste_link) : This is broken.  FIXME.
	(paste_cell) : Move the check for pasting content or as_value to the
	  top.

	* src/cell.c (cell_make_value) : Unlink expressions if necessary.

	* src/sheet.c (sheet_cell_set_expr) : flag that content changed.

	* src/dependent.c (dependent_queue_recalc_list) : Add some safety.

	* src/item-cursor.c (item_cursor_event) : clicking on an anted cursor
	  is almost the same as clicking on a selection cursor.

	* src/expr-name.c (expr_name_add) : It is legal to add names that are
	  available in other scopes as long as the new scope does not contiain
	  the name.
parent 04475f63
2000-11-07 Jody Goldberg <jgoldberg@home.com>
2000-11-08 Jody Goldberg <jgoldberg@home.com>
* src/clipboard.c (apply_paste_oper_to_values) : Rewrite to use
eval_expr.
(paste_cell_with_operation) : rework to handle pasting as_value
correctly.
(paste_link) : This is broken. FIXME.
(paste_cell) : Move the check for pasting content or as_value to the
top.
* src/cell.c (cell_make_value) : Unlink expressions if necessary.
* src/sheet.c (sheet_cell_set_expr) : flag that content changed.
* src/dependent.c (dependent_queue_recalc_list) : Add some safety.
* src/item-cursor.c (item_cursor_event) : clicking on an anted cursor
is almost the same as clicking on a selection cursor.
* src/expr-name.c (expr_name_add) : It is legal to add names that are
available in other scopes as long as the new scope does not contiain
......
2000-11-07 Jody Goldberg <jgoldberg@home.com>
2000-11-08 Jody Goldberg <jgoldberg@home.com>
* src/clipboard.c (apply_paste_oper_to_values) : Rewrite to use
eval_expr.
(paste_cell_with_operation) : rework to handle pasting as_value
correctly.
(paste_link) : This is broken. FIXME.
(paste_cell) : Move the check for pasting content or as_value to the
top.
* src/cell.c (cell_make_value) : Unlink expressions if necessary.
* src/sheet.c (sheet_cell_set_expr) : flag that content changed.
* src/dependent.c (dependent_queue_recalc_list) : Add some safety.
* src/item-cursor.c (item_cursor_event) : clicking on an anted cursor
is almost the same as clicking on a selection cursor.
* src/expr-name.c (expr_name_add) : It is legal to add names that are
available in other scopes as long as the new scope does not contiain
......
2000-11-07 Jody Goldberg <jgoldberg@home.com>
2000-11-08 Jody Goldberg <jgoldberg@home.com>
* src/clipboard.c (apply_paste_oper_to_values) : Rewrite to use
eval_expr.
(paste_cell_with_operation) : rework to handle pasting as_value
correctly.
(paste_link) : This is broken. FIXME.
(paste_cell) : Move the check for pasting content or as_value to the
top.
* src/cell.c (cell_make_value) : Unlink expressions if necessary.
* src/sheet.c (sheet_cell_set_expr) : flag that content changed.
* src/dependent.c (dependent_queue_recalc_list) : Add some safety.
* src/item-cursor.c (item_cursor_event) : clicking on an anted cursor
is almost the same as clicking on a selection cursor.
* src/expr-name.c (expr_name_add) : It is legal to add names that are
available in other scopes as long as the new scope does not contiain
......
2000-11-07 Jody Goldberg <jgoldberg@home.com>
2000-11-08 Jody Goldberg <jgoldberg@home.com>
* src/clipboard.c (apply_paste_oper_to_values) : Rewrite to use
eval_expr.
(paste_cell_with_operation) : rework to handle pasting as_value
correctly.
(paste_link) : This is broken. FIXME.
(paste_cell) : Move the check for pasting content or as_value to the
top.
* src/cell.c (cell_make_value) : Unlink expressions if necessary.
* src/sheet.c (sheet_cell_set_expr) : flag that content changed.
* src/dependent.c (dependent_queue_recalc_list) : Add some safety.
* src/item-cursor.c (item_cursor_event) : clicking on an anted cursor
is almost the same as clicking on a selection cursor.
* src/expr-name.c (expr_name_add) : It is legal to add names that are
available in other scopes as long as the new scope does not contiain
......
2000-11-07 Jody Goldberg <jgoldberg@home.com>
2000-11-08 Jody Goldberg <jgoldberg@home.com>
* src/clipboard.c (apply_paste_oper_to_values) : Rewrite to use
eval_expr.
(paste_cell_with_operation) : rework to handle pasting as_value
correctly.
(paste_link) : This is broken. FIXME.
(paste_cell) : Move the check for pasting content or as_value to the
top.
* src/cell.c (cell_make_value) : Unlink expressions if necessary.
* src/sheet.c (sheet_cell_set_expr) : flag that content changed.
* src/dependent.c (dependent_queue_recalc_list) : Add some safety.
* src/item-cursor.c (item_cursor_event) : clicking on an anted cursor
is almost the same as clicking on a selection cursor.
* src/expr-name.c (expr_name_add) : It is legal to add names that are
available in other scopes as long as the new scope does not contiain
......
......@@ -747,6 +747,10 @@ cell_make_value (Cell *cell)
g_return_if_fail (cell != NULL);
g_return_if_fail (cell_has_expr(cell));
/* Clipboard cells, e.g., are not attached to a sheet. */
if (cell_expr_is_linked (cell))
dependent_unlink (CELL_TO_DEP (cell), &cell->pos);
expr_tree_unref (cell->base.expression);
cell->base.expression = NULL;
cell->base.flags &= ~CELL_HAS_EXPRESSION;
......
......@@ -86,37 +86,36 @@ paste_oper_to_expr_oper (int paste_flags)
}
static Value *
apply_paste_oper_to_values (Cell const * old_cell, Cell const * copied_cell, int paste_flags)
apply_paste_oper_to_values (Cell const *old_cell, Cell const *copied_cell,
Cell const *new_cell, int paste_flags)
{
float_t old_float;
float_t copied_float;
EvalPos pos;
ExprTree expr, arg_a, arg_b;
Operation op;
g_return_val_if_fail (paste_flags & PASTE_OPER_MASK, NULL);
if (old_cell != NULL && cell_is_number (old_cell))
old_float = value_get_as_float (old_cell->value);
else
old_float = 0.0;
if (copied_cell != NULL && cell_is_number (copied_cell))
copied_float = value_get_as_float (copied_cell->value);
else
copied_float = 0.0;
if (paste_flags & PASTE_OPER_ADD)
return value_new_float (old_float + copied_float);
op = OPER_ADD;
else if (paste_flags & PASTE_OPER_SUB)
return value_new_float (old_float - copied_float);
op = OPER_SUB;
else if (paste_flags & PASTE_OPER_MULT)
return value_new_float (old_float * copied_float);
op = OPER_MULT;
else if (paste_flags & PASTE_OPER_DIV)
return (copied_float == 0.0)
? value_new_error (NULL, gnumeric_err_DIV0)
: value_new_float (old_float / copied_float);
op = OPER_DIV;
else
g_assert_not_reached ();
return NULL;
*((Operation *)&(arg_a.constant.oper)) = OPER_CONSTANT;
arg_a.constant.value = old_cell->value;
*((Operation *)&(arg_b.constant.oper)) = OPER_CONSTANT;
arg_b.constant.value = copied_cell->value;
*((Operation *)&(expr.binary.oper)) = op;
expr.binary.value_a = &arg_a;
expr.binary.value_b = &arg_b;
return eval_expr (eval_pos_init_cell (&pos, new_cell), &expr, EVAL_STRICT);
}
static void
......@@ -130,9 +129,6 @@ paste_cell_with_operation (Sheet *dest_sheet,
g_return_if_fail (paste_flags & PASTE_OPER_MASK);
if (!(paste_flags & (PASTE_FORMULAS | PASTE_VALUES)))
return;
if (!(c_copy->type == CELL_COPY_TYPE_CELL))
return;
......@@ -149,38 +145,22 @@ paste_cell_with_operation (Sheet *dest_sheet,
/* FIXME : This does not handle arrays, linked cells, ranges, etc. */
if ((c_copy->u.cell != NULL && cell_has_expr (c_copy->u.cell)) ||
(old_cell != NULL && cell_has_expr (old_cell))) {
ExprTree *new_expr;
ExprTree *old_expr;
ExprTree *copied_expr;
Operation oper;
old_expr = cell_get_contents_as_expr_tree (old_cell);
copied_expr = cell_get_contents_as_expr_tree (c_copy->u.cell);
oper = paste_oper_to_expr_oper (paste_flags);
new_expr = expr_tree_new_binary (old_expr, oper, copied_expr);
sheet_cell_set_expr (new_cell, new_expr);
if ((paste_flags & PASTE_CONTENT) &&
((c_copy->u.cell != NULL && cell_has_expr (c_copy->u.cell)) ||
(old_cell != NULL && cell_has_expr (old_cell)))) {
ExprTree *old_expr = cell_get_contents_as_expr_tree (old_cell);
ExprTree *copied_expr = cell_get_contents_as_expr_tree (c_copy->u.cell);
Operation oper = paste_oper_to_expr_oper (paste_flags);
ExprTree *new_expr = expr_tree_new_binary (old_expr, oper, copied_expr);
cell_set_expr (new_cell, new_expr, NULL);
cell_relocate (new_cell, rwinfo);
} else {
Value *new_val = apply_paste_oper_to_values (old_cell, c_copy->u.cell, paste_flags);
Value *new_val = apply_paste_oper_to_values (old_cell, c_copy->u.cell,
new_cell, paste_flags);
sheet_cell_set_value (new_cell, new_val, NULL);
cell_set_value (new_cell, new_val, NULL);
}
/* The code below was copied from paste_cell */
if (cell_has_expr (new_cell)) {
if (paste_flags & PASTE_FORMULAS)
cell_relocate (new_cell, rwinfo);
else
cell_make_value (new_cell);
} else {
g_return_if_fail (new_cell->value != NULL);
cell_render_value (new_cell);
}
sheet_cell_insert (dest_sheet, new_cell, target_col, target_row, TRUE);
}
......@@ -190,11 +170,15 @@ paste_link (Sheet *dest_sheet,
int target_col, int target_row)
{
ExprTree *expr;
Cell *new_cell;
Cell *cell;
CellRef source_cell_ref;
new_cell = sheet_cell_new (dest_sheet, target_col, target_row);
cell = sheet_cell_fetch (dest_sheet, target_col, target_row);
/* FIXME : This is broken
* 1) should be relative not absolute (add toggle ?)
* 2) this is the WRONG SHEET !
*/
source_cell_ref.sheet = dest_sheet;
source_cell_ref.col = source_col;
source_cell_ref.row = source_row;
......@@ -202,7 +186,7 @@ paste_link (Sheet *dest_sheet,
source_cell_ref.row_relative = 0;
expr = expr_tree_new_var (&source_cell_ref);
sheet_cell_set_expr (new_cell, expr);
cell_set_expr (cell, expr, NULL);
}
/**
......@@ -220,43 +204,40 @@ paste_cell (Sheet *dest_sheet,
ExprRewriteInfo *rwinfo,
CellCopy *c_copy, int paste_flags)
{
if (!(paste_flags & (PASTE_CONTENT | PASTE_AS_VALUES)))
return;
if (paste_flags & PASTE_OPER_MASK) {
paste_cell_with_operation (dest_sheet, target_col, target_row,
rwinfo, c_copy, paste_flags);
return;
}
if ((paste_flags & (PASTE_FORMULAS | PASTE_VALUES))){
if (c_copy->type == CELL_COPY_TYPE_CELL) {
Cell *new_cell = cell_copy (c_copy->u.cell);
/* Cell cannot be linked in yet, but it needs an accurate location */
new_cell->base.sheet = dest_sheet;
new_cell->pos.col = target_col;
new_cell->pos.row = target_row;
if (cell_has_expr (new_cell)) {
if (paste_flags & PASTE_FORMULAS)
cell_relocate (new_cell, rwinfo);
else
cell_make_value (new_cell);
} else {
g_return_if_fail (new_cell->value != NULL);
cell_render_value (new_cell);
}
if (c_copy->type == CELL_COPY_TYPE_CELL) {
Cell *new_cell = cell_copy (c_copy->u.cell);
/* Cell cannot be linked in yet, but it needs an accurate location */
new_cell->base.sheet = dest_sheet;
new_cell->pos.col = target_col;
new_cell->pos.row = target_row;
if (cell_has_expr (new_cell)) {
if (paste_flags & PASTE_CONTENT)
cell_relocate (new_cell, rwinfo);
else
cell_make_value (new_cell);
}
sheet_cell_insert (dest_sheet, new_cell, target_col, target_row, TRUE);
} else {
Cell *new_cell = sheet_cell_new (dest_sheet,
target_col, target_row);
sheet_cell_insert (dest_sheet, new_cell, target_col, target_row, TRUE);
} else {
Cell *new_cell = sheet_cell_new (dest_sheet,
target_col, target_row);
if (c_copy->u.text)
sheet_cell_set_text (new_cell, c_copy->u.text);
if (c_copy->u.text)
cell_set_text (new_cell, c_copy->u.text);
if (c_copy->type == CELL_COPY_TYPE_TEXT_AND_COMMENT && c_copy->comment)
cell_set_comment (new_cell, c_copy->comment);
}
if (c_copy->type == CELL_COPY_TYPE_TEXT_AND_COMMENT && c_copy->comment)
cell_set_comment (new_cell, c_copy->comment);
}
}
......@@ -285,6 +266,10 @@ clipboard_paste_region (WorkbookControl *wbc,
int src_cols = content->cols;
int src_rows = content->rows;
g_return_val_if_fail (pt != NULL, TRUE);
g_return_val_if_fail ((pt->paste_flags & PASTE_CONTENT) !=
(pt->paste_flags & PASTE_AS_VALUES), TRUE);
if (pt->paste_flags & PASTE_TRANSPOSE) {
int tmp = src_cols;
src_cols = src_rows;
......@@ -326,8 +311,8 @@ clipboard_paste_region (WorkbookControl *wbc,
tmp = 0;
/* clear the region where we will paste */
if (pt->paste_flags & (PASTE_VALUES|PASTE_FORMULAS))
tmp = CLEAR_VALUES|CLEAR_COMMENTS;
if (pt->paste_flags & (PASTE_CONTENT | PASTE_AS_VALUES))
tmp = CLEAR_VALUES | CLEAR_COMMENTS;
/* No need to clear the formats. We will paste over top of these. */
/* if (pt->paste_flags & PASTE_FORMATS) tmp |= CLEAR_FORMATS; */
......@@ -417,7 +402,7 @@ clipboard_paste_region (WorkbookControl *wbc,
sheet_style_optimize (pt->sheet, pt->range);
if (pt->paste_flags & (PASTE_FORMULAS|PASTE_VALUES)) {
if (pt->paste_flags & (PASTE_CONTENT | PASTE_AS_VALUES)) {
GList *deps = sheet_region_get_deps (pt->sheet, pt->range);
if (deps)
dependent_queue_recalc_list (deps, TRUE);
......
......@@ -2,29 +2,30 @@
#define GNUMERIC_CLIPBOARD_H
enum {
PASTE_VALUES = 1 << 0, /* At most VALUES or FORMATS can */
PASTE_FORMULAS = 1 << 1, /* be applied */
PASTE_CONTENT = 1 << 0, /* either CONTENT or AS_VALUES */
PASTE_AS_VALUES = 1 << 1, /* can be applied, not both */
PASTE_FORMATS = 1 << 2,
PASTE_COMMENTS = 1 << 3, /* FIXME : unsupported */
/* Operations that can be performed at paste time on a cell */
PASTE_OPER_ADD = 1 << 3,
PASTE_OPER_SUB = 1 << 4,
PASTE_OPER_MULT = 1 << 5,
PASTE_OPER_DIV = 1 << 6,
PASTE_OPER_ADD = 1 << 4,
PASTE_OPER_SUB = 1 << 5,
PASTE_OPER_MULT = 1 << 6,
PASTE_OPER_DIV = 1 << 7,
/* Whether the paste transposes or not */
PASTE_TRANSPOSE = 1 << 7,
PASTE_TRANSPOSE = 1 << 8,
PASTE_EXPR_RELOCATE = 1 << 8,
PASTE_EXPR_RELOCATE = 1 << 9,
PASTE_LINK = 1 << 9,
PASTE_LINK = 1 << 10,
/* If copying a range that includes blank cells, this
prevents pasting blank cells over existing data */
PASTE_SKIP_BLANKS = 1 << 10
PASTE_SKIP_BLANKS = 1 << 11
};
#define PASTE_ALL_TYPES (PASTE_FORMULAS | PASTE_VALUES | PASTE_FORMATS)
#define PASTE_ALL_TYPES (PASTE_CONTENT | PASTE_FORMATS)
#define PASTE_DEFAULT PASTE_ALL_TYPES
#define PASTE_OPER_MASK (PASTE_OPER_ADD | PASTE_OPER_SUB | PASTE_OPER_MULT | PASTE_OPER_DIV)
......
......@@ -497,7 +497,7 @@ cmd_area_set_text_undo (GnumericCommand *cmd, WorkbookControl *wbc)
c = me->old_content->data;
clipboard_paste_region (wbc,
paste_target_init (&pt, me->pos.sheet, r, PASTE_FORMULAS),
paste_target_init (&pt, me->pos.sheet, r, PASTE_CONTENT),
c);
clipboard_release (c);
me->old_content = g_slist_remove (me->old_content, c);
......@@ -1012,7 +1012,7 @@ cmd_clear_selection (WorkbookControl *wbc, Sheet *sheet, int clear_flags)
me->paste_flags = 0;
if (clear_flags & CLEAR_VALUES)
me->paste_flags |= PASTE_FORMULAS;
me->paste_flags |= PASTE_CONTENT;
if (clear_flags & CLEAR_FORMATS)
me->paste_flags |= PASTE_FORMATS;
if (clear_flags & CLEAR_COMMENTS)
......@@ -1933,7 +1933,7 @@ cmd_paste_copy_undo (GnumericCommand *cmd, WorkbookControl *wbc)
clipboard_release (me->content);
else
/* Save the content */
me->dst.paste_flags = PASTE_FORMULAS |
me->dst.paste_flags = PASTE_CONTENT |
(me->dst.paste_flags & PASTE_FORMATS);
me->content = content;
......@@ -2127,7 +2127,7 @@ cmd_autofill (WorkbookControl *wbc, Sheet *sheet,
/* Store the specs for the object */
me->content = NULL;
me->dst.sheet = sheet;
me->dst.paste_flags = PASTE_FORMULAS | PASTE_FORMATS;
me->dst.paste_flags = PASTE_CONTENT | PASTE_FORMATS;
/* FIXME : We can copy less than this */
range_init (&me->dst.range, base_col, base_row, end_col, end_row);
......
......@@ -184,6 +184,8 @@ dependent_queue_recalc_list (GList *list, gboolean freelist)
if (dep->flags & DEPENDENT_QUEUED_FOR_RECALC)
continue;
g_return_if_fail (dep->sheet != NULL);
/*
* Use the wb associated with the current dependent in case we
* have cross workbook depends
......
......@@ -22,8 +22,8 @@ static struct {
int disables_second_group;
} paste_types [] = {
{ N_("All"), 0 },
{ N_("Formulas"), 0 },
{ N_("Values"), 0 },
{ N_("Content"), 0 },
{ N_("As Value"), 0 },
{ N_("Formats"), 1 },
{ NULL, 0 }
};
......@@ -199,12 +199,12 @@ dialog_paste_special (WorkbookControlGUI *wbcg)
result = PASTE_ALL_TYPES;
break;
case 1: /* formulas */
result = PASTE_FORMULAS;
case 1: /* content */
result = PASTE_CONTENT;
break;
case 2: /* values */
result = PASTE_VALUES;
case 2: /* as values */
result = PASTE_AS_VALUES;
break;
case 3: /* formats */
......
......@@ -746,7 +746,7 @@ item_cursor_do_action (ItemCursor *item_cursor, ActionType action, guint32 time)
if (!sheet_selection_copy (WORKBOOK_CONTROL (item_cursor->sheet_view->wbcg), sheet))
break;
cmd_paste (WORKBOOK_CONTROL (item_cursor->sheet_view->wbcg),
paste_target_init (&pt, sheet, &item_cursor->pos, PASTE_VALUES),
paste_target_init (&pt, sheet, &item_cursor->pos, PASTE_AS_VALUES),
time);
break;
......@@ -1135,6 +1135,7 @@ item_cursor_event (GnomeCanvasItem *item, GdkEvent *event)
ItemCursor *item_cursor = ITEM_CURSOR (item);
switch (item_cursor->style){
case ITEM_CURSOR_ANTED:
case ITEM_CURSOR_SELECTION:
return item_cursor_selection_event (item, event);
......
......@@ -1256,6 +1256,7 @@ sheet_cell_set_expr (Cell *cell, ExprTree *expr)
{
/* No need to do anything until recalc */
cell_set_expr (cell, expr, NULL);
cell_content_changed (cell);
sheet_flag_status_update_cell (cell);
}
......
......@@ -176,7 +176,7 @@ sort_permute (WorkbookControl *context, SortData *data, const int *perm, int len
PasteTarget pt;
pt.sheet = data->sheet;
pt.paste_flags = PASTE_FORMATS | PASTE_FORMULAS | PASTE_EXPR_RELOCATE;
pt.paste_flags = PASTE_FORMATS | PASTE_CONTENT | PASTE_EXPR_RELOCATE;
#ifdef DEBUG_SORT
fprintf (stderr, "Permutation:");
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment