Commit 33b2145b authored by Arturo Espinosa's avatar Arturo Espinosa

Work on the clipboard



Work on the clipboard
parent 1f108ba5
1998-08-11 Miguel de Icaza <miguel@nuclecu.unam.mx>
* src/item-cursor.c (item_cursor_event): Event handler for the
item_cursors.
* src/item-cursor.h: More cursor types: ITEM_CURSOR_AUTOFILL (for
the case where the small drag box is used) and ITEM_CURSOR_DRAG
(for when the item is being dragged).
* src/clipboard.c (clipboard_paste_region,
clipboard_copy_cell_range): New functions for cut and paste
support.
* src/cell.c (cell_destroy, cell_copy): New functions. Preparing
for cut and paste support.
* src/expr.c (value_copy_to): Finish implementing all cases.
(value_duplicate): New function. Duplicates a value.
* src/sheet.c (sheet_cell_remove): Implement a way to remove
cells.
* src/eval.c (workbook_recalc): New recomputation strategy: We
now keep a generation flag for determining whenever a cell value
has been recomputed for this generation. The generation variable
......
1998-08-11 Miguel de Icaza <miguel@nuclecu.unam.mx>
* src/item-cursor.c (item_cursor_event): Event handler for the
item_cursors.
* src/item-cursor.h: More cursor types: ITEM_CURSOR_AUTOFILL (for
the case where the small drag box is used) and ITEM_CURSOR_DRAG
(for when the item is being dragged).
* src/clipboard.c (clipboard_paste_region,
clipboard_copy_cell_range): New functions for cut and paste
support.
* src/cell.c (cell_destroy, cell_copy): New functions. Preparing
for cut and paste support.
* src/expr.c (value_copy_to): Finish implementing all cases.
(value_duplicate): New function. Duplicates a value.
* src/sheet.c (sheet_cell_remove): Implement a way to remove
cells.
* src/eval.c (workbook_recalc): New recomputation strategy: We
now keep a generation flag for determining whenever a cell value
has been recomputed for this generation. The generation variable
......
1998-08-11 Miguel de Icaza <miguel@nuclecu.unam.mx>
* src/item-cursor.c (item_cursor_event): Event handler for the
item_cursors.
* src/item-cursor.h: More cursor types: ITEM_CURSOR_AUTOFILL (for
the case where the small drag box is used) and ITEM_CURSOR_DRAG
(for when the item is being dragged).
* src/clipboard.c (clipboard_paste_region,
clipboard_copy_cell_range): New functions for cut and paste
support.
* src/cell.c (cell_destroy, cell_copy): New functions. Preparing
for cut and paste support.
* src/expr.c (value_copy_to): Finish implementing all cases.
(value_duplicate): New function. Duplicates a value.
* src/sheet.c (sheet_cell_remove): Implement a way to remove
cells.
* src/eval.c (workbook_recalc): New recomputation strategy: We
now keep a generation flag for determining whenever a cell value
has been recomputed for this generation. The generation variable
......
1998-08-11 Miguel de Icaza <miguel@nuclecu.unam.mx>
* src/item-cursor.c (item_cursor_event): Event handler for the
item_cursors.
* src/item-cursor.h: More cursor types: ITEM_CURSOR_AUTOFILL (for
the case where the small drag box is used) and ITEM_CURSOR_DRAG
(for when the item is being dragged).
* src/clipboard.c (clipboard_paste_region,
clipboard_copy_cell_range): New functions for cut and paste
support.
* src/cell.c (cell_destroy, cell_copy): New functions. Preparing
for cut and paste support.
* src/expr.c (value_copy_to): Finish implementing all cases.
(value_duplicate): New function. Duplicates a value.
* src/sheet.c (sheet_cell_remove): Implement a way to remove
cells.
* src/eval.c (workbook_recalc): New recomputation strategy: We
now keep a generation flag for determining whenever a cell value
has been recomputed for this generation. The generation variable
......
......@@ -138,3 +138,45 @@ cell_set_text (Cell *cell, char *text)
/* Finish setting the values for this cell */
cell->flags = 0;
}
/*
* Makes a copy of a Cell
*/
Cell *
cell_copy (Cell *cell)
{
Cell *new_cell;
g_return_val_if_fail (cell != NULL, NULL);
new_cell = g_new (Cell, 1);
/* bitmap copy first */
*new_cell = *cell;
/* now copy propertly the rest */
string_ref (new_cell->entered_text);
expr_tree_ref (new_cell->parsed_node);
string_ref (new_cell->text);
new_cell->style = style_duplicate (new_cell->style);
new_cell->value = value_duplicate (new_cell->value);
return new_cell;
}
void
cell_destroy (Cell *cell)
{
g_return_if_fail (cell != NULL);
if (cell->parsed_node){
cell_formula_unlink (cell);
expr_tree_unref (cell->parsed_node);
}
string_unref (cell->entered_text);
string_unref (cell->text);
style_destroy (cell->style);
value_release (cell->value);
}
......@@ -57,6 +57,8 @@ typedef struct {
void cell_set_text (Cell *cell, char *text);
void cell_set_formula (Cell *cell, char *text);
void cell_calc_dimensions (Cell *cell);
Cell *cell_copy (Cell *cell);
void cell_destroy (Cell *cell);
#endif /* GNUMERIC_CELL_H */
/*
* Clipboard.c: Implements the copy/paste operations
* (C) 1998 The Free Software Foundation.
*
* Author:
* MIguel de Icaza (miguel@gnu.org)
*
*/
#include <config.h>
#include <gnome.h>
#include "gnumeric.h"
#include "clipboard.h"
typedef struct {
int base_col, base_row;
CellRegion *r;
} append_cell_closure_t;
int
clipboard_append_cell (Sheet *sheet, int col, int row, Cell *cell, void *user_data)
{
append_cell_closure_t *c = user_data;
CellCopy *copy;
copy = g_new (CellCopy, 1);
copy->cell = cell_copy (cell);
copy->col_offset = col - c->base_col;
copy->row_offset = col - c->base_col;
/* Now clear the traces and dependencies on the copied Cell */
copy->cell->col = NULL;
copy->cell->row = NULL;
copy->cell->sheet = NULL;
c->r->list = g_list_prepend (c->r->list, copy);
return TRUE;
}
CellRegion *
clipboard_copy_cell_range (Sheet *sheet, int start_col, int start_row, int end_col, int end_row)
{
append_cell_closure_t c;
g_return_if_fail (sheet != NULL);
g_return_if_fail (IS_SHEET (sheet));
g_return_if_fail (start_col <= end_col);
g_return_if_fail (start_row <= end_row);
c.r = g_new (CellRegion, 1);
c.base_col = start_col;
c.base_row = start_row;
c.r->cols = end_col - start_col + 2;
c.r->rows = end_row - start_row + 2;
sheet_cell_foreach_range (
sheet, 1, start_col, start_row, end_col, end_row,
clipboard_append_cell, r);
}
void
clipboard_paste_region (CellRegion *region, Sheet *dest_sheet, int dest_col, int_dest_row)
{
sheet_clear_region (sheet,
dest_col, dest_row,
dest_col + region->cols,
dest_row + region->row);
}
#ifndef CLIPBOARD_H
#define CLIPBOARD_H
typedef struct {
int col_offset, pos_offset; /* Position of the cell */
Cell *cell;
} CellCopy;
typedef GList CellRegionList;
typedef struct {
int cols, rows;
CelLRegionList list;
} CellRegion;
CellRegion *clipboard_copy_cell_range (Sheet *sheet,
int start_col, int start_row,
int end_col, int end_row);
void clipboard_paste_region (CellRegion *region,
Sheet *dest_sheet,
int dest_col,
int dest_row);
#endif
......@@ -4,6 +4,7 @@
#include <string.h>
#include "gnumeric.h"
#include "expr.h"
#include "eval.h"
char *parser_expr;
ParseErr parser_error;
......@@ -161,11 +162,40 @@ value_copy_to (Value *dest, Value *source)
dest->v.v_float = source->v.v_float;
break;
default:
g_warning ("value_copy_to: VALUE type not yet supported\n");
case VALUE_ARRAY: {
GList *l, *new = NULL;
for (l = source->v.array; l; l = l->next){
Value *copy;
copy = value_duplicate (l->data);
new = g_list_append (new, copy);
}
dest->v.array = new;
break;
}
case VALUE_CELLRANGE:
dest->v.cell_range = source->v.cell_range;
break;
}
}
/*
* Makes a copy of a Value
*/
Value *
value_duplicate (Value *value)
{
Value *new_value;
g_return_val_if_fail (value != NULL, NULL);
new_value = g_new (Value, 1);
value_copy_to (new_value, value);
return new_value;
}
/*
* Casts a value to float if it is integer, and returns
* a new Value * if required
......
......@@ -156,7 +156,8 @@ void value_copy_to (Value *dest, Value *source);
void value_dump (Value *value);
char *value_string (Value *value);
Value *value_duplicate (Value *value);
int yyparse (void);
/* Setup of the symbol table */
......
......@@ -125,7 +125,7 @@ item_cursor_draw (GnomeCanvasItem *item, GdkDrawable *drawable, int x, int y, in
int xd, yd, dx, dy;
int cursor_width, cursor_height;
GdkPoint points [40];
int draw_external, draw_internal, draw_handle, draw_center;
int draw_external, draw_internal, draw_handle, draw_center, draw_thick;
int premove;
GdkColor *fore = NULL, *back = NULL;
......@@ -135,26 +135,32 @@ item_cursor_draw (GnomeCanvasItem *item, GdkDrawable *drawable, int x, int y, in
dx = xd - x;
dy = yd - y;
draw_external = draw_internal = draw_handle = draw_center = 0;
draw_external = 0;
draw_internal = 0;
draw_handle = 0;
draw_center = 0;
draw_thick = 0;
switch (item_cursor->style){
case ITEM_CURSOR_AUTOFILL:
case ITEM_CURSOR_DRAG:
draw_center = 1;
draw_thick = 1;
fore = &gs_black;
back = &gs_white;
break;
case ITEM_CURSOR_SELECTION:
draw_internal = 1;
draw_external = 1;
draw_center = 0;
draw_handle = 1;
break;
case ITEM_CURSOR_EDITING:
draw_internal = 0;
draw_handle = 0;
draw_center = 0;
draw_external = 1;
case ITEM_CURSOR_ANTED:
draw_internal = 0;
draw_handle = 0;
draw_center = 1;
draw_external = 0;
if (item_cursor->state){
fore = &gs_light_gray;
back = &gs_dark_gray;
......@@ -221,7 +227,7 @@ item_cursor_draw (GnomeCanvasItem *item, GdkDrawable *drawable, int x, int y, in
if (draw_center){
gdk_gc_set_foreground (item_cursor->gc, fore);
gdk_gc_set_background (item_cursor->gc, back);
gdk_gc_set_line_attributes (item_cursor->gc, 1,
gdk_gc_set_line_attributes (item_cursor->gc, draw_thick ? 3 : 1,
GDK_LINE_DOUBLE_DASH, -1, -1);
gdk_draw_rectangle (drawable, item_cursor->gc, FALSE,
dx, dy,
......@@ -311,10 +317,109 @@ item_cursor_translate (GnomeCanvasItem *item, double dx, double dy)
printf ("item_cursor_translate %g, %g\n", dx, dy);
}
#define convert(c,sx,sy,x,y) gnome_canvas_w2c (c,sx,sy,x,y)
static gint
item_cursor_selection_event (GnomeCanvasItem *item, GdkEvent *event)
{
GnomeCanvas *canvas = item->canvas;
GnomeCanvasItem *new_item;
ItemCursor *item_cursor = ITEM_CURSOR (item);
int x, y;
switch (event->type){
case GDK_BUTTON_PRESS: {
GnomeCanvasGroup *group;
int style;
printf ("cursor: got event\n");
convert (canvas, event->button.x, event->button.y, &x, &y);
group = GNOME_CANVAS_GROUP (canvas->root);
if ((x > item->x2 - 6) && (y > item->y2 - 6))
style = ITEM_CURSOR_AUTOFILL;
else
style = ITEM_CURSOR_DRAG;
new_item = gnome_canvas_item_new (
group,
item_cursor_get_type (),
"ItemCursor::Sheet", item_cursor->sheet,
"ItemCursor::Grid", item_cursor->item_grid,
"ItemCursor::Style", style,
NULL);
item_cursor_set_bounds (
ITEM_CURSOR (new_item),
item_cursor->start_col, item_cursor->start_row,
item_cursor->end_col, item_cursor->end_row);
printf ("Creating new cursor!\n");
gnome_canvas_update_now (canvas);
gnome_canvas_item_grab (
new_item,
GDK_POINTER_MOTION_MASK | GDK_BUTTON_RELEASE_MASK,
NULL,
event->button.time);
return TRUE;
}
default:
return FALSE;
}
}
static void
item_cursor_do_drop (ItemCursor *item_cursor)
{
printf ("DROP!\n");
}
static gint
item_cursor_drag_event (GnomeCanvasItem *item, GdkEvent *event)
{
ItemCursor *item_cursor = ITEM_CURSOR (item);
switch (event->type){
case GDK_BUTTON_RELEASE:
gnome_canvas_item_ungrab (item, event->button.time);
item_cursor_do_drop (item_cursor);
gtk_object_destroy (GTK_OBJECT (item));
return TRUE;
case GDK_BUTTON_PRESS:
printf ("Strange. I got a button press\n");
return TRUE;
case GDK_MOTION_NOTIFY:
printf ("Moving!\n");
return TRUE;
default:
return FALSE;
}
}
static gint
item_cursor_event (GnomeCanvasItem *item, GdkEvent *event)
{
return 0;
ItemCursor *item_cursor = ITEM_CURSOR (item);
printf ("getting events!\n");
switch (item_cursor->style){
case ITEM_CURSOR_SELECTION:
return item_cursor_selection_event (item, event);
case ITEM_CURSOR_DRAG:
return item_cursor_drag_event (item, event);
case ITEM_CURSOR_AUTOFILL:
return FALSE;
default:
return FALSE;
}
}
/*
......
......@@ -9,6 +9,8 @@ typedef enum {
ITEM_CURSOR_SELECTION,
ITEM_CURSOR_EDITING,
ITEM_CURSOR_ANTED,
ITEM_CURSOR_AUTOFILL,
ITEM_CURSOR_DRAG,
} ItemCursorStyle;
typedef struct {
......
......@@ -1335,4 +1335,41 @@ sheet_cell_new (Sheet *sheet, int col, int row)
return cell;
}
void
sheet_cell_remove (Sheet *sheet, Cell *cell)
{
CellPos cellref;
g_return_if_fail (sheet != NULL);
g_return_if_fail (cell != NULL);
g_return_if_fail (IS_SHEET (sheet));
cellref.col = cell->col->pos;
cellref.row = cell->row->pos;
g_hash_table_remove (sheet->cell_hash, &cellref);
cell->col->data = g_list_remove (cell->col->data, cell);
}
static int
clear_cell (Sheet *sheet, int col, int row, Cell *cell, void *user_data)
{
sheet_cell_remove (sheet, cell);
cell_destroy (cell);
return TRUE;
}
void
sheet_clear_region (Sheet *sheet, int start_col, int start_row, int end_col, int end_row)
{
g_return_if_fail (sheet != NULL);
g_return_if_fail (IS_SHEET (sheet));
g_return_if_fail (start_col <= end_col);
g_return_if_fail (start_row <= end_row);
sheet_cell_foreach_range (
sheet, TRUE,
start_col, start_row,end_col, end_row,
clear_cell, NULL);
}
......@@ -85,12 +85,19 @@ typedef void (*sheet_col_row_callback)(Sheet *sheet, ColRowInfo *ci,
typedef int (*sheet_cell_foreach_callback)(Sheet *sheet, int col, int row,
Cell *cell, void *user_data);
Sheet *sheet_new (Workbook *wb, char *name);
void sheet_destroy (Sheet *sheet);
void sheet_foreach_col (Sheet *sheet, sheet_col_row_callback, void *user_data);
void sheet_foreach_row (Sheet *sheet, sheet_col_row_callback, void *user_data);
void sheet_set_zoom_factor (Sheet *sheet, double factor);
void sheet_get_cell_bounds (Sheet *sheet, ColType col, RowType row, int *x, int *y, int *w, int *h);
Sheet *sheet_new (Workbook *wb, char *name);
void sheet_destroy (Sheet *sheet);
void sheet_foreach_col (Sheet *sheet,
sheet_col_row_callback callback,
void *user_data);
void sheet_foreach_row (Sheet *sheet,
sheet_col_row_callback,
void *user_data);
void sheet_set_zoom_factor (Sheet *sheet, double factor);
void sheet_get_cell_bounds (Sheet *sheet,
ColType col, RowType row,
int *x, int *y,
int *w, int *h);
/* Selection management */
void sheet_select_all (Sheet *sheet);
......@@ -99,7 +106,8 @@ void sheet_selection_extend_to (Sheet *sheet, int col, int row);
void sheet_selection_clear (Sheet *sheet);
void sheet_selection_clear_only (Sheet *sheet);
int sheet_selection_equal (SheetSelection *a, SheetSelection *b);
void sheet_selection_append_range (Sheet *sheet, int base_col, int base_row,
void sheet_selection_append_range (Sheet *sheet,
int base_col, int base_row,
int start_col, int start_row,
int end_col, int end_row);
......@@ -107,11 +115,9 @@ void sheet_selection_extend_horizontal (Sheet *sheet, int count);
void sheet_selection_extend_vertical (Sheet *sheet, int count);
int sheet_selection_is_cell_selected (Sheet *sheet, int col, int row);
/* Computation */
void sheet_compute_cell (Sheet *sheet, Cell *cell);
/* Cell management */
Cell *sheet_cell_new (Sheet *sheet, int col, int row);
void sheet_cell_remove (Sheet *sheet, Cell *cell);
int sheet_cell_foreach_range (Sheet *sheet, int only_existing,
int start_col, int start_row,
int end_col, int end_row,
......@@ -143,18 +149,27 @@ void sheet_row_add (Sheet *sheet, ColRowInfo *cp);
/* Measure distances in pixels from one col/row to another */
int sheet_col_get_distance (Sheet *sheet, int from_col, int to_col);
int sheet_row_get_distance (Sheet *sheet, int from_row, int to_row);
void sheet_clear_region (Sheet *sheet,
int start_col, int start_row,
int end_col, int end_row);
/* Sets the width/height of a column row in terms of pixels */
void sheet_col_set_width (Sheet *sheet, int col, int width);
void sheet_row_set_height (Sheet *sheet, int row, int width);
void sheet_col_set_selection (Sheet *sheet, ColRowInfo *ci, int value);
void sheet_row_set_selection (Sheet *sheet, ColRowInfo *ri, int value);
void sheet_col_set_width (Sheet *sheet,
int col, int width);
void sheet_row_set_height (Sheet *sheet,
int row, int width);
void sheet_col_set_selection (Sheet *sheet,
ColRowInfo *ci, int value);
void sheet_row_set_selection (Sheet *sheet,
ColRowInfo *ri, int value);
Style *sheet_style_compute (Sheet *sheet, int col, int row);
/* Redraw */
void sheet_redraw_cell_region (Sheet *sheet, int start_col, int start_row,
int end_col, int end_row);
void sheet_redraw_cell_region (Sheet *sheet,
int start_col, int start_row,
int end_col, int end_row);
void sheet_redraw_selection (Sheet *sheet, SheetSelection *ss);
void sheet_redraw_all (Sheet *sheet);
......
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