Commit c3a522d6 authored by Arturo Espinosa's avatar Arturo Espinosa

Various little fixes here and there:



Various little fixes here and there:

	- Basic support for dragging the selection is in (still does
	  not do anything, will do the action binding later).

	- Fixes to the cell-selection-code-when-you-type-a-formula code

	- ExprTrees are now properly refcounted (instead of only
	  refcounting the root node).  This is required for the
	  Paste special/with-arithmetic operation feature.

	- Expression decoding (for pasting a formula with relative
	  references) now takes into account operator precedence to
	  avoid cluttering the pasted expression with extra paretheses.

	Other smallish fixes which I forget now.

Miguel.
parent f579db27
1998-08-15 Miguel de Icaza <miguel@nuclecu.unam.mx>
* src/item-cursor.c (item_cursor_drag_event): Make the drag cursor
actually dragable.
* src/item-grid.c (item_grid_event): Use the converted cordinates.
(item_grid_find_row, item_grid_find_col): Rename and export these
routines to be used by the ItemCursor.
* src/gnumeric-sheet.c (gnumeric_sheet_key): Do not remove the
selection string when the input has been accepted.
* src/expr.c (expr_tree_ref): Strategy change: Now every ExprTree
node is properly refcounted, as soon we will start sharing parts
of the ExprTree between cells.
(do_expr_decode_tree): Decoding an expression now takes into
account the precedence of the operators and uses paretheses only
when they are actually required.
1998-08-14 Miguel de Icaza <miguel@nuclecu.unam.mx> 1998-08-14 Miguel de Icaza <miguel@nuclecu.unam.mx>
* src/item-grid.c (item_grid_event): Implemented context sensitive
menu for the grid.
(item_grid_event): Use <control> instead of <shift> for extending
a selection
* src/clipboard.c (clipboard_paste_region): After pasting, trigger * src/clipboard.c (clipboard_paste_region): After pasting, trigger
a recalculation. a recalculation.
......
1998-08-15 Miguel de Icaza <miguel@nuclecu.unam.mx>
* src/item-cursor.c (item_cursor_drag_event): Make the drag cursor
actually dragable.
* src/item-grid.c (item_grid_event): Use the converted cordinates.
(item_grid_find_row, item_grid_find_col): Rename and export these
routines to be used by the ItemCursor.
* src/gnumeric-sheet.c (gnumeric_sheet_key): Do not remove the
selection string when the input has been accepted.
* src/expr.c (expr_tree_ref): Strategy change: Now every ExprTree
node is properly refcounted, as soon we will start sharing parts
of the ExprTree between cells.
(do_expr_decode_tree): Decoding an expression now takes into
account the precedence of the operators and uses paretheses only
when they are actually required.
1998-08-14 Miguel de Icaza <miguel@nuclecu.unam.mx> 1998-08-14 Miguel de Icaza <miguel@nuclecu.unam.mx>
* src/item-grid.c (item_grid_event): Implemented context sensitive
menu for the grid.
(item_grid_event): Use <control> instead of <shift> for extending
a selection
* src/clipboard.c (clipboard_paste_region): After pasting, trigger * src/clipboard.c (clipboard_paste_region): After pasting, trigger
a recalculation. a recalculation.
......
1998-08-15 Miguel de Icaza <miguel@nuclecu.unam.mx>
* src/item-cursor.c (item_cursor_drag_event): Make the drag cursor
actually dragable.
* src/item-grid.c (item_grid_event): Use the converted cordinates.
(item_grid_find_row, item_grid_find_col): Rename and export these
routines to be used by the ItemCursor.
* src/gnumeric-sheet.c (gnumeric_sheet_key): Do not remove the
selection string when the input has been accepted.
* src/expr.c (expr_tree_ref): Strategy change: Now every ExprTree
node is properly refcounted, as soon we will start sharing parts
of the ExprTree between cells.
(do_expr_decode_tree): Decoding an expression now takes into
account the precedence of the operators and uses paretheses only
when they are actually required.
1998-08-14 Miguel de Icaza <miguel@nuclecu.unam.mx> 1998-08-14 Miguel de Icaza <miguel@nuclecu.unam.mx>
* src/item-grid.c (item_grid_event): Implemented context sensitive
menu for the grid.
(item_grid_event): Use <control> instead of <shift> for extending
a selection
* src/clipboard.c (clipboard_paste_region): After pasting, trigger * src/clipboard.c (clipboard_paste_region): After pasting, trigger
a recalculation. a recalculation.
......
1998-08-15 Miguel de Icaza <miguel@nuclecu.unam.mx>
* src/item-cursor.c (item_cursor_drag_event): Make the drag cursor
actually dragable.
* src/item-grid.c (item_grid_event): Use the converted cordinates.
(item_grid_find_row, item_grid_find_col): Rename and export these
routines to be used by the ItemCursor.
* src/gnumeric-sheet.c (gnumeric_sheet_key): Do not remove the
selection string when the input has been accepted.
* src/expr.c (expr_tree_ref): Strategy change: Now every ExprTree
node is properly refcounted, as soon we will start sharing parts
of the ExprTree between cells.
(do_expr_decode_tree): Decoding an expression now takes into
account the precedence of the operators and uses paretheses only
when they are actually required.
1998-08-14 Miguel de Icaza <miguel@nuclecu.unam.mx> 1998-08-14 Miguel de Icaza <miguel@nuclecu.unam.mx>
* src/item-grid.c (item_grid_event): Implemented context sensitive
menu for the grid.
(item_grid_event): Use <control> instead of <shift> for extending
a selection
* src/clipboard.c (clipboard_paste_region): After pasting, trigger * src/clipboard.c (clipboard_paste_region): After pasting, trigger
a recalculation. a recalculation.
......
...@@ -397,6 +397,10 @@ workbook_next_generation (Workbook *wb) ...@@ -397,6 +397,10 @@ workbook_next_generation (Workbook *wb)
wb->generation++; wb->generation++;
} }
/*
* Computes all of the cells pending computation and
* any dependency.
*/
void void
workbook_recalc (Workbook *wb) workbook_recalc (Workbook *wb)
{ {
...@@ -422,3 +426,21 @@ workbook_recalc (Workbook *wb) ...@@ -422,3 +426,21 @@ workbook_recalc (Workbook *wb)
g_list_free (deps); g_list_free (deps);
} }
} }
/*
* Recomputes all of the formulas.
*/
void
workbook_recalc_all (Workbook *workbook)
{
GList *l;
for (l = workbook->formula_cell_list; l; l = l->next){
Cell *cell = l->data;
cell_queue_recalc (cell);
}
workbook_recalc (workbook);
}
...@@ -397,6 +397,10 @@ workbook_next_generation (Workbook *wb) ...@@ -397,6 +397,10 @@ workbook_next_generation (Workbook *wb)
wb->generation++; wb->generation++;
} }
/*
* Computes all of the cells pending computation and
* any dependency.
*/
void void
workbook_recalc (Workbook *wb) workbook_recalc (Workbook *wb)
{ {
...@@ -422,3 +426,21 @@ workbook_recalc (Workbook *wb) ...@@ -422,3 +426,21 @@ workbook_recalc (Workbook *wb)
g_list_free (deps); g_list_free (deps);
} }
} }
/*
* Recomputes all of the formulas.
*/
void
workbook_recalc_all (Workbook *workbook)
{
GList *l;
for (l = workbook->formula_cell_list; l; l = l->next){
Cell *cell = l->data;
cell_queue_recalc (cell);
}
workbook_recalc (workbook);
}
...@@ -764,6 +764,29 @@ cell_get_abs_col_row (CellRef *cell_ref, int eval_col, int eval_row, int *col, i ...@@ -764,6 +764,29 @@ cell_get_abs_col_row (CellRef *cell_ref, int eval_col, int eval_row, int *col, i
*row = cell_ref->row; *row = cell_ref->row;
} }
static int
evaluate_level (Operation x)
{
if (x == OP_EXP)
return 3;
if ((x==OP_MULT) || (x==OP_DIV))
return 2;
if ((x==OP_ADD) || (x==OP_SUB) || (x==OP_CONCAT))
return 1;
return 0;
}
static int
bigger_prec (Operation parent, Operation this)
{
int parent_level, this_level;
parent_level = evaluate_level (parent);
this_level = evaluate_level (this);
return parent_level > this_level;
}
/* /*
* Converts a parsed tree into its string representation * Converts a parsed tree into its string representation
* assuming that we are evaluating at col, row (This is * assuming that we are evaluating at col, row (This is
...@@ -773,16 +796,14 @@ cell_get_abs_col_row (CellRef *cell_ref, int eval_col, int eval_row, int *col, i ...@@ -773,16 +796,14 @@ cell_get_abs_col_row (CellRef *cell_ref, int eval_col, int eval_row, int *col, i
* This routine is pretty simple: it walks the ExprTree and * This routine is pretty simple: it walks the ExprTree and
* create a string representation. * create a string representation.
*/ */
char * static char *
expr_decode_tree (ExprTree *tree, int col, int row) do_expr_decode_tree (ExprTree *tree, int col, int row, Operation parent_op)
{ {
static const char *binary_operation_names [] = { static const char *binary_operation_names [] = {
"=", ">", "<", ">=", "<=", "<>", "=", ">", "<", ">=", "<=", "<>",
"+", "-", "*", "/", "^", "&" "+", "-", "*", "/", "^", "&"
}; };
g_return_val_if_fail (tree != NULL, NULL);
switch (tree->oper){ switch (tree->oper){
/* The binary operations */ /* The binary operations */
...@@ -801,10 +822,15 @@ expr_decode_tree (ExprTree *tree, int col, int row) ...@@ -801,10 +822,15 @@ expr_decode_tree (ExprTree *tree, int col, int row)
char *a, *b, *res; char *a, *b, *res;
char const *op; char const *op;
a = expr_decode_tree (tree->u.binary.value_a, col, row); a = do_expr_decode_tree (tree->u.binary.value_a, col, row, tree->oper);
b = expr_decode_tree (tree->u.binary.value_b, col, row); b = do_expr_decode_tree (tree->u.binary.value_b, col, row, tree->oper);
op = binary_operation_names [tree->oper]; op = binary_operation_names [tree->oper];
res = g_copy_strings ("(", a, op, b, ")", NULL);
if (bigger_prec (parent_op, tree->oper))
res = g_copy_strings ("(", a, op, b, ")", NULL);
else
res = g_copy_strings (a, op, b, NULL);
g_free (a); g_free (a);
g_free (b); g_free (b);
return res; return res;
...@@ -813,7 +839,7 @@ expr_decode_tree (ExprTree *tree, int col, int row) ...@@ -813,7 +839,7 @@ expr_decode_tree (ExprTree *tree, int col, int row)
case OP_NEG: { case OP_NEG: {
char *res, *a; char *res, *a;
a = expr_decode_tree (tree->u.value, col, row); a = do_expr_decode_tree (tree->u.value, col, row, tree->oper);
res = g_copy_strings ("-", a); res = g_copy_strings ("-", a);
g_free (a); g_free (a);
return res; return res;
...@@ -838,7 +864,7 @@ expr_decode_tree (ExprTree *tree, int col, int row) ...@@ -838,7 +864,7 @@ expr_decode_tree (ExprTree *tree, int col, int row)
for (l = arg_list; l; l = l->next){ for (l = arg_list; l; l = l->next){
ExprTree *t = l->data; ExprTree *t = l->data;
args [i] = expr_decode_tree (t, col, row); args [i] = do_expr_decode_tree (t, col, row, OP_CONSTANT);
len += strlen (args [i]) + 1; len += strlen (args [i]) + 1;
} }
len++; len++;
...@@ -889,4 +915,10 @@ expr_decode_tree (ExprTree *tree, int col, int row) ...@@ -889,4 +915,10 @@ expr_decode_tree (ExprTree *tree, int col, int row)
return g_strdup ("0"); return g_strdup ("0");
} }
char *
expr_decode_tree (ExprTree *tree, int col, int row)
{
g_return_val_if_fail (tree != NULL, NULL);
return do_expr_decode_tree (tree, col, row, OP_CONSTANT);
}
...@@ -577,7 +577,6 @@ gnumeric_sheet_key (GtkWidget *widget, GdkEventKey *event) ...@@ -577,7 +577,6 @@ gnumeric_sheet_key (GtkWidget *widget, GdkEventKey *event)
direction = (event->state & GDK_SHIFT_MASK) ? 0 : 1; direction = (event->state & GDK_SHIFT_MASK) ? 0 : 1;
horizontal = (event->keyval == GDK_Tab) ? 1 : 0; horizontal = (event->keyval == GDK_Tab) ? 1 : 0;
selection_remove_selection_string (gsheet);
walking_selection = sheet_selection_walk_step ( walking_selection = sheet_selection_walk_step (
gsheet->sheet, direction, horizontal, gsheet->sheet, direction, horizontal,
gsheet->cursor_col, gsheet->cursor_row, gsheet->cursor_col, gsheet->cursor_row,
......
...@@ -577,7 +577,6 @@ gnumeric_sheet_key (GtkWidget *widget, GdkEventKey *event) ...@@ -577,7 +577,6 @@ gnumeric_sheet_key (GtkWidget *widget, GdkEventKey *event)
direction = (event->state & GDK_SHIFT_MASK) ? 0 : 1; direction = (event->state & GDK_SHIFT_MASK) ? 0 : 1;
horizontal = (event->keyval == GDK_Tab) ? 1 : 0; horizontal = (event->keyval == GDK_Tab) ? 1 : 0;
selection_remove_selection_string (gsheet);
walking_selection = sheet_selection_walk_step ( walking_selection = sheet_selection_walk_step (
gsheet->sheet, direction, horizontal, gsheet->sheet, direction, horizontal,
gsheet->cursor_col, gsheet->cursor_row, gsheet->cursor_col, gsheet->cursor_row,
......
...@@ -138,8 +138,8 @@ item_cursor_configure_bounds (ItemCursor *item_cursor) ...@@ -138,8 +138,8 @@ item_cursor_configure_bounds (ItemCursor *item_cursor)
extra = 1; extra = 1;
else else
extra = 0; extra = 0;
item->x2 = x + w + 1 + extra; item->x2 = x + w + 2 + extra;
item->y2 = y + h + 1 + extra; item->y2 = y + h + 2 + extra;
gnome_canvas_group_child_bounds (GNOME_CANVAS_GROUP (item->parent), item); gnome_canvas_group_child_bounds (GNOME_CANVAS_GROUP (item->parent), item);
} }
...@@ -362,6 +362,10 @@ item_cursor_selection_event (GnomeCanvasItem *item, GdkEvent *event) ...@@ -362,6 +362,10 @@ item_cursor_selection_event (GnomeCanvasItem *item, GdkEvent *event)
convert (canvas, event->button.x, event->button.y, &x, &y); convert (canvas, event->button.x, event->button.y, &x, &y);
group = GNOME_CANVAS_GROUP (canvas->root); group = GNOME_CANVAS_GROUP (canvas->root);
/* determine which part of the cursor was clicked:
* the border or the handlebox
*/
if ((x > item->x2 - 6) && (y > item->y2 - 6)) if ((x > item->x2 - 6) && (y > item->y2 - 6))
style = ITEM_CURSOR_AUTOFILL; style = ITEM_CURSOR_AUTOFILL;
else else
...@@ -402,11 +406,39 @@ item_cursor_do_drop (ItemCursor *item_cursor) ...@@ -402,11 +406,39 @@ item_cursor_do_drop (ItemCursor *item_cursor)
printf ("DROP!\n"); printf ("DROP!\n");
} }
static void
item_cursor_set_bounds_visibly (ItemCursor *item_cursor,
int start_col, int start_row,
int end_col, int end_row)
{
GnomeCanvasItem *item = GNOME_CANVAS_ITEM (item_cursor);
GnumericSheet *gsheet = GNUMERIC_SHEET (item->canvas);
int watch_col, watch_row;
item_cursor_set_bounds (item_cursor, start_col, start_row, end_col, end_row);
/* Now, make the range visible as well as we can guess */
if (start_col < item_cursor->start_col)
watch_col = start_col;
else
watch_col = end_col;
if (start_row < item_cursor->start_row)
watch_row = start_row;
else
watch_row = end_row;
gnumeric_sheet_make_cell_visible (gsheet, watch_col, watch_row);
}
static gint static gint
item_cursor_drag_event (GnomeCanvasItem *item, GdkEvent *event) item_cursor_drag_event (GnomeCanvasItem *item, GdkEvent *event)
{ {
GnomeCanvas *canvas = GNOME_CANVAS_ITEM (item)->canvas;
ItemCursor *item_cursor = ITEM_CURSOR (item); ItemCursor *item_cursor = ITEM_CURSOR (item);
int x, y, w, h;
int col, row;
switch (event->type){ switch (event->type){
case GDK_BUTTON_RELEASE: case GDK_BUTTON_RELEASE:
gnome_canvas_item_ungrab (item, event->button.time); gnome_canvas_item_ungrab (item, event->button.time);
...@@ -415,11 +447,20 @@ item_cursor_drag_event (GnomeCanvasItem *item, GdkEvent *event) ...@@ -415,11 +447,20 @@ item_cursor_drag_event (GnomeCanvasItem *item, GdkEvent *event)
return TRUE; return TRUE;
case GDK_BUTTON_PRESS: case GDK_BUTTON_PRESS:
printf ("Strange. I got a button press\n"); /* We actually never get this event: this kind of
* cursor is created and grabbed
*/
return TRUE; return TRUE;
case GDK_MOTION_NOTIFY: case GDK_MOTION_NOTIFY:
printf ("Moving!\n"); convert (canvas, event->button.x, event->button.y, &x, &y);
col = item_grid_find_col (item_cursor->item_grid, x, NULL);
row = item_grid_find_row (item_cursor->item_grid, y, NULL);
w = (item_cursor->end_col - item_cursor->start_col);
h = (item_cursor->end_row - item_cursor->start_row);
item_cursor_set_bounds_visibly (item_cursor, col, row, col + w, row + h);
return TRUE; return TRUE;
default: default:
...@@ -432,7 +473,6 @@ item_cursor_event (GnomeCanvasItem *item, GdkEvent *event) ...@@ -432,7 +473,6 @@ item_cursor_event (GnomeCanvasItem *item, GdkEvent *event)
{ {
ItemCursor *item_cursor = ITEM_CURSOR (item); ItemCursor *item_cursor = ITEM_CURSOR (item);
printf ("getting events!\n");
switch (item_cursor->style){ switch (item_cursor->style){
case ITEM_CURSOR_SELECTION: case ITEM_CURSOR_SELECTION:
return item_cursor_selection_event (item, event); return item_cursor_selection_event (item, event);
...@@ -511,7 +551,7 @@ item_cursor_class_init (ItemCursorClass *item_cursor_class) ...@@ -511,7 +551,7 @@ item_cursor_class_init (ItemCursorClass *item_cursor_class)
GTK_ARG_WRITABLE, ARG_ITEM_GRID); GTK_ARG_WRITABLE, ARG_ITEM_GRID);
gtk_object_add_arg_type ("ItemCursor::Style", GTK_TYPE_INT, gtk_object_add_arg_type ("ItemCursor::Style", GTK_TYPE_INT,
GTK_ARG_WRITABLE, ARG_STYLE); GTK_ARG_WRITABLE, ARG_STYLE);
object_class->set_arg = item_cursor_set_arg; object_class->set_arg = item_cursor_set_arg;
object_class->destroy = item_cursor_destroy; object_class->destroy = item_cursor_destroy;
......
...@@ -92,10 +92,10 @@ item_grid_reconfigure (GnomeCanvasItem *item) ...@@ -92,10 +92,10 @@ item_grid_reconfigure (GnomeCanvasItem *item)
} }
/* /*
* find_col: return the column where x belongs to * item_grid_find_col: return the column where x belongs to
*/ */
static int int
find_col (ItemGrid *item_grid, int x, int *col_origin) item_grid_find_col (ItemGrid *item_grid, int x, int *col_origin)
{ {
int col = item_grid->left_col; int col = item_grid->left_col;
int pixel = item_grid->left_offset; int pixel = item_grid->left_offset;
...@@ -114,10 +114,10 @@ find_col (ItemGrid *item_grid, int x, int *col_origin) ...@@ -114,10 +114,10 @@ find_col (ItemGrid *item_grid, int x, int *col_origin)
} }
/* /*
* find_row: return the row where y belongs to * item_grid_find_row: return the row where y belongs to
*/ */
static int int
find_row (ItemGrid *item_grid, int y, int *row_origin) item_grid_find_row (ItemGrid *item_grid, int y, int *row_origin)
{ {
int row = item_grid->top_row; int row = item_grid->top_row;
int pixel = item_grid->top_offset; int pixel = item_grid->top_offset;
...@@ -150,16 +150,16 @@ static void ...@@ -150,16 +150,16 @@ static void
item_grid_draw_cell (GdkDrawable *drawable, ItemGrid *item_grid, item_grid_draw_cell (GdkDrawable *drawable, ItemGrid *item_grid,
int x1, int y1, int width, int height, int col, int row) int x1, int y1, int width, int height, int col, int row)
{ {
GnumericSheet *gsheet = GNUMERIC_SHEET (item_grid->sheet->sheet_view); GnomeCanvas *canvas = GNOME_CANVAS_ITEM (item_grid)->canvas;
GnomeCanvas *canvas = GNOME_CANVAS_ITEM (item_grid)->canvas; GnumericSheet *gsheet = GNUMERIC_SHEET (canvas);
GdkFont *font; GdkGC *white_gc = GTK_WIDGET (canvas)->style->white_gc;
GdkGC *gc = item_grid->gc; GdkGC *gc = item_grid->gc;
GdkGC *white_gc = GTK_WIDGET (canvas)->style->white_gc; Sheet *sheet = item_grid->sheet;
Sheet *sheet = item_grid->sheet; GdkFont *font;
Cell *cell, *clip_left, *clip_right; Cell *cell, *clip_left, *clip_right;
Style *style; Style *style;
int x_offset, y_offset, text_base, pixels; int x_offset, y_offset, text_base, pixels;
GdkRectangle rect; GdkRectangle rect;
#if 0 #if 0
item_debug_cross (drawable, gc, x1, y1, x1+width, y1+height); item_debug_cross (drawable, gc, x1, y1, x1+width, y1+height);
...@@ -314,8 +314,8 @@ item_grid_draw (GnomeCanvasItem *item, GdkDrawable *drawable, int x, int y, int ...@@ -314,8 +314,8 @@ item_grid_draw (GnomeCanvasItem *item, GdkDrawable *drawable, int x, int y, int
} }
max_paint_col = max_paint_row = 0; max_paint_col = max_paint_row = 0;
paint_col = find_col (item_grid, x, &x_paint); paint_col = item_grid_find_col (item_grid, x, &x_paint);
paint_row = find_row (item_grid, y, &y_paint); paint_row = item_grid_find_row (item_grid, y, &y_paint);
col = paint_col; col = paint_col;
...@@ -356,7 +356,7 @@ item_grid_draw (GnomeCanvasItem *item, GdkDrawable *drawable, int x, int y, int ...@@ -356,7 +356,7 @@ item_grid_draw (GnomeCanvasItem *item, GdkDrawable *drawable, int x, int y, int
pd.y_paint = -diff_y; pd.y_paint = -diff_y;
pd.drawable = drawable; pd.drawable = drawable;
pd.item_grid = item_grid; pd.item_grid = item_grid;
pd.gsheet = GNUMERIC_SHEET (item_grid->sheet->sheet_view); pd.gsheet = GNUMERIC_SHEET (item->canvas);
#if 0 #if 0
printf ("Painting the (%d,%d)-(%d,%d) region\n", printf ("Painting the (%d,%d)-(%d,%d) region\n",
...@@ -405,6 +405,148 @@ item_grid_translate (GnomeCanvasItem *item, double dx, double dy) ...@@ -405,6 +405,148 @@ item_grid_translate (GnomeCanvasItem *item, double dx, double dy)
printf ("item_grid_translate %g, %g\n", dx, dy); printf ("item_grid_translate %g, %g\n", dx, dy);
} }
static void
context_destroy_menu (GtkWidget *widget)
{
gtk_widget_destroy (gtk_widget_get_toplevel (widget));
}
static void
context_cut_cmd (GtkWidget *widget, ItemGrid *item_grid)
{
sheet_selection_cut (item_grid->sheet);
context_destroy_menu (widget);
}
static void
context_copy_cmd (GtkWidget *widget, ItemGrid *item_grid)
{
sheet_selection_copy (item_grid->sheet);
context_destroy_menu (widget);
}
static void
context_paste_cmd (GtkWidget *widget, ItemGrid *item_grid)
{
GnomeCanvasItem *item = GNOME_CANVAS_ITEM (item_grid);
GnumericSheet *gsheet = GNUMERIC_SHEET (item->canvas);
sheet_selection_paste (item_grid->sheet,
gsheet->cursor_col,
gsheet->cursor_row,
PASTE_DEFAULT);
context_destroy_menu (widget);
}
static void
context_paste_special_cmd (GtkWidget *widget, ItemGrid *item_grid)
{
GnomeCanvasItem *item = GNOME_CANVAS_ITEM (item_grid);
GnumericSheet *gsheet = GNUMERIC_SHEET (item->canvas);
int flags;
flags = dialog_paste_special ();
sheet_selection_paste (item_grid->sheet,
gsheet->cursor_col,
gsheet->cursor_row,
flags);
context_destroy_menu (widget);