Commit 9b935b6c authored by Arturo Espinosa's avatar Arturo Espinosa

Today: 1. First pass at selections (multiple selections are allowed). 2.



Today:
	1. First pass at selections (multiple selections are allowed).
	2. Cursor selection works.  Do not try to drag outside the
	   window though, there is a little bug to be fixed and it will
	   keep a pointer grab.
	3. Started to add destructors all over the place, better to
	   keep an eye on those memory leaks since the beginning.

Miguel.
parent daa8afdc
......@@ -56,6 +56,13 @@ gnumeric_sheet_create (Sheet *sheet, GtkWidget *entry)
return gsheet;
}
void
gnumeric_sheet_cursor_set (GnumericSheet *sheet, int col, int row)
{
sheet->cursor_col = col;
sheet->cursor_row = row;
}
static void
gnumeric_sheet_accept_pending_output (GnumericSheet *sheet)
{
......@@ -96,10 +103,11 @@ gnumeric_sheet_move_cursor_horizontal (GnumericSheet *sheet, int count)
new_left = 0;
gnumeric_sheet_accept_pending_output (sheet);
sheet->cursor_col = new_left;
gnumeric_sheet_cursor_set (sheet, new_left, sheet->cursor_row);
item_cursor_set_bounds (item_cursor,
new_left, item_cursor->end_col + count,
item_cursor->start_row, item_cursor->end_row);
new_left, item_cursor->start_row,
new_left, item_cursor->start_row);
gnumeric_sheet_load_new_cell (sheet);
}
......@@ -120,13 +128,27 @@ gnumeric_sheet_move_cursor_vertical (GnumericSheet *sheet, int count)
}
gnumeric_sheet_accept_pending_output (sheet);
sheet->cursor_row = new_top;
gnumeric_sheet_cursor_set (sheet, sheet->cursor_col, new_top);
item_cursor_set_bounds (item_cursor,
item_cursor->start_col, item_cursor->end_col,
new_top, item_cursor->end_row + count);
item_cursor->start_col, new_top,
item_cursor->start_col, new_top);
gnumeric_sheet_load_new_cell (sheet);
}
void
gnumeric_sheet_set_selection (GnumericSheet *sheet, int start_col, int start_row, int end_col, int end_row)
{
g_return_if_fail (sheet != NULL);
g_return_if_fail (start_row <= end_row);
g_return_if_fail (start_col <= end_col);
g_return_if_fail (GNUMERIC_IS_SHEET (sheet));
gnumeric_sheet_cursor_set (sheet, start_col, start_row);
item_cursor_set_bounds (sheet->item_cursor,
start_col, start_row,
end_col, end_row);
}
static void
start_editing_at_cursor (GnumericSheet *sheet, GtkWidget *entry)
{
......
......@@ -29,7 +29,10 @@ typedef struct {
GtkType gnumeric_sheet_get_type (void);
GtkWidget *gnumeric_sheet_new (Sheet *sheet);
GtkWidget *gnumeric_sheet_new (Sheet *sheet);
void gnumeric_sheet_set_selection (GnumericSheet *sheet,
int start_col, int start_row,
int end_col, int end_row);
typedef struct {
GnomeCanvasClass parent_class;
......
......@@ -56,6 +56,13 @@ gnumeric_sheet_create (Sheet *sheet, GtkWidget *entry)
return gsheet;
}
void
gnumeric_sheet_cursor_set (GnumericSheet *sheet, int col, int row)
{
sheet->cursor_col = col;
sheet->cursor_row = row;
}
static void
gnumeric_sheet_accept_pending_output (GnumericSheet *sheet)
{
......@@ -96,10 +103,11 @@ gnumeric_sheet_move_cursor_horizontal (GnumericSheet *sheet, int count)
new_left = 0;
gnumeric_sheet_accept_pending_output (sheet);
sheet->cursor_col = new_left;
gnumeric_sheet_cursor_set (sheet, new_left, sheet->cursor_row);
item_cursor_set_bounds (item_cursor,
new_left, item_cursor->end_col + count,
item_cursor->start_row, item_cursor->end_row);
new_left, item_cursor->start_row,
new_left, item_cursor->start_row);
gnumeric_sheet_load_new_cell (sheet);
}
......@@ -120,13 +128,27 @@ gnumeric_sheet_move_cursor_vertical (GnumericSheet *sheet, int count)
}
gnumeric_sheet_accept_pending_output (sheet);
sheet->cursor_row = new_top;
gnumeric_sheet_cursor_set (sheet, sheet->cursor_col, new_top);
item_cursor_set_bounds (item_cursor,
item_cursor->start_col, item_cursor->end_col,
new_top, item_cursor->end_row + count);
item_cursor->start_col, new_top,
item_cursor->start_col, new_top);
gnumeric_sheet_load_new_cell (sheet);
}
void
gnumeric_sheet_set_selection (GnumericSheet *sheet, int start_col, int start_row, int end_col, int end_row)
{
g_return_if_fail (sheet != NULL);
g_return_if_fail (start_row <= end_row);
g_return_if_fail (start_col <= end_col);
g_return_if_fail (GNUMERIC_IS_SHEET (sheet));
gnumeric_sheet_cursor_set (sheet, start_col, start_row);
item_cursor_set_bounds (sheet->item_cursor,
start_col, start_row,
end_col, end_row);
}
static void
start_editing_at_cursor (GnumericSheet *sheet, GtkWidget *entry)
{
......
......@@ -29,7 +29,10 @@ typedef struct {
GtkType gnumeric_sheet_get_type (void);
GtkWidget *gnumeric_sheet_new (Sheet *sheet);
GtkWidget *gnumeric_sheet_new (Sheet *sheet);
void gnumeric_sheet_set_selection (GnumericSheet *sheet,
int start_col, int start_row,
int end_col, int end_row);
typedef struct {
GnomeCanvasClass parent_class;
......
......@@ -85,8 +85,8 @@ item_cursor_get_pixel_coords (ItemCursor *item_cursor, int *x, int *y, int *w, i
*x = sheet_col_get_distance (sheet, item_grid->left_col, item_cursor->start_col);
*y = sheet_row_get_distance (sheet, item_grid->top_row, item_cursor->start_row);
*w = sheet_col_get_distance (sheet, item_cursor->start_col, item_cursor->end_col);
*h = sheet_row_get_distance (sheet, item_cursor->start_row, item_cursor->end_row);
*w = sheet_col_get_distance (sheet, item_cursor->start_col, item_cursor->end_col+1);
*h = sheet_row_get_distance (sheet, item_cursor->start_row, item_cursor->end_row+1);
}
static void
......@@ -189,14 +189,14 @@ item_cursor_request_redraw (ItemCursor *item_cursor)
}
void
item_cursor_set_bounds (ItemCursor *item_cursor, int c1, int c2, int r1, int r2)
item_cursor_set_bounds (ItemCursor *item_cursor, int start_col, int start_row, int end_col, int end_row)
{
item_cursor_request_redraw (item_cursor);
item_cursor->start_col = c1;
item_cursor->end_col = c2;
item_cursor->start_row = r1;
item_cursor->end_row = r2;
item_cursor->start_col = start_col;
item_cursor->end_col = end_col;
item_cursor->start_row = start_row;
item_cursor->end_row = end_row;
item_cursor_request_redraw (item_cursor);
}
......@@ -236,9 +236,9 @@ item_cursor_init (ItemCursor *item_cursor)
item->y2 = 1;
item_cursor->start_col = 0;
item_cursor->end_col = 1;
item_cursor->end_col = 0;
item_cursor->start_row = 0;
item_cursor->end_row = 1;
item_cursor->end_row = 0;
item_cursor->start_row = ITEM_CURSOR_SELECTION;
}
......
......@@ -16,10 +16,9 @@
/* The signals we emit */
enum {
ITEM_GRID_TEST,
ITEM_GRID_LAST_SIGNAL
LAST_SIGNAL
};
static guint item_grid_signals [ITEM_GRID_LAST_SIGNAL] = { 0 };
static guint item_grid_signals [LAST_SIGNAL] = { 0 };
static GnomeCanvasItem *item_grid_parent_class;
......@@ -107,17 +106,18 @@ item_grid_reconfigure (GnomeCanvasItem *item)
*/
static void
item_grid_draw_cell (GdkDrawable *drawable, ItemGrid *item_grid,
int x1, int y1, int x2, int y2)
int x1, int y1, int width, int height, int col, int row)
{
GdkGC *grid_gc = item_grid->grid_gc;
gdk_draw_rectangle (drawable, item_grid->fill_gc, TRUE,
x1+1, y1+1, x2-x1-2, y2-y1-2);
gdk_draw_line (drawable, grid_gc, x1, y1, x2, y1);
gdk_draw_line (drawable, grid_gc, x2, y1, x2, y2);
gdk_draw_line (drawable, grid_gc, x2, y2, x1, y2);
gdk_draw_line (drawable, grid_gc, x1, y1, x1, y2);
GnomeCanvas *canvas = GNOME_CANVAS_ITEM (item_grid)->canvas;
GdkGC *black_gc = GTK_WIDGET (canvas)->style->black_gc;
Cell *cell;
if (sheet_selection_is_cell_selected (item_grid->sheet, col, row)){
gdk_draw_rectangle (drawable, black_gc,
TRUE,
x1+1, y1+1, width - 2, height - 2);
}
}
/*
......@@ -224,6 +224,7 @@ item_grid_draw (GnomeCanvasItem *item, GdkDrawable *drawable, int x, int y, int
y_paint += ri->pixels;
}
col = paint_col;
for (x_paint = -diff_x; x_paint < end_x; col++){
ColRowInfo *ci;
......@@ -234,16 +235,11 @@ item_grid_draw (GnomeCanvasItem *item, GdkDrawable *drawable, int x, int y, int
ColRowInfo *ri;
ri = sheet_row_get_info (sheet, row);
#if 0
item_debug_cross (drawable, item_grid->grid_gc,
x_paint, y_paint,
x_paint + ci->pixels,
y_paint + ri->pixels);
item_grid_draw_cell (drawable, item_grid,
x_paint, y_paint,
x_paint + ci->pixels,
y_paint + ri->pixels);
#endif
ci->pixels,
ri->pixels,
col, row);
y_paint += ri->pixels;
}
......@@ -270,13 +266,53 @@ item_grid_translate (GnomeCanvasItem *item, double dx, double dy)
printf ("item_grid_translate %g, %g\n", dx, dy);
}
/*
* Handle the selection
*/
static gint
item_grid_event (GnomeCanvasItem *item, GdkEvent *event)
{
#if 0
printf ("Event\n");
#endif
return 0;
ItemGrid *item_grid = ITEM_GRID (item);
Sheet *sheet = item_grid->sheet;
int col, row;
switch (event->type){
case GDK_BUTTON_RELEASE:
item_grid->selecting = 0;
gnome_canvas_item_ungrab (item, event->button.time);
return 1;
case GDK_MOTION_NOTIFY:
if (!item_grid->selecting)
return 1;
col = find_col (item_grid, event->motion.x, NULL);
row = find_row (item_grid, event->motion.y, NULL);
sheet_selection_extend_to (sheet, col, row);
return 1;
case GDK_BUTTON_PRESS:
col = find_col (item_grid, event->button.x, NULL);
row = find_row (item_grid, event->button.y, NULL);
if (!(event->button.state & GDK_SHIFT_MASK)){
if (sheet_selection_is_cell_selected (sheet, col, row))
return 1;
sheet_selection_clear (sheet);
}
item_grid->selecting = 1;
sheet_selection_append (sheet, col, row);
printf ("ItemGrab:%d\n", gnome_canvas_item_grab (item,
GDK_POINTER_MOTION_MASK |
GDK_BUTTON_RELEASE_MASK,
NULL,
event->button.time));
return 1;
default:
return 0;
}
}
/*
......@@ -296,6 +332,7 @@ item_grid_init (ItemGrid *item_grid)
item_grid->top_row = 0;
item_grid->top_offset = 0;
item_grid->left_offset = 0;
item_grid->selecting = 0;
}
static void
......
......@@ -14,6 +14,8 @@ typedef struct {
ColType left_col;
RowType top_row;
int selecting;
/* Offset from spreadsheet origin in units */
long top_offset;
long left_offset;
......
......@@ -50,7 +50,7 @@ sheet_init_dummy_stuff (Sheet *sheet)
rp = sheet_row_new (sheet);
rp->pos = y;
rp->units = (20 * (y + 1));
rp->selected = 1;
rp->selected = 0;
sheet_row_add (sheet, rp);
}
}
......@@ -116,13 +116,18 @@ Sheet *
sheet_new (Workbook *wb, char *name)
{
Sheet *sheet;
int rows_shown, cols_shown;
rows_shown = cols_shown = 40;
sheet = g_new0 (Sheet, 1);
sheet->parent_workbook = wb;
sheet->name = g_strdup (name);
sheet->last_zoom_factor_used = -1.0;
sheet->toplevel = gtk_table_new (0, 0, 0);
sheet->max_col_used = cols_shown;
sheet->max_row_used = rows_shown;
sheet_init_default_styles (sheet);
/* Dummy initialization */
......@@ -158,11 +163,44 @@ sheet_new (Workbook *wb, char *name)
gtk_signal_connect (GTK_OBJECT (sheet->row_item), "size_changed",
GTK_SIGNAL_FUNC (sheet_row_size_changed),
sheet);
/* Scroll bars and their adjustments */
sheet->va = gtk_adjustment_new (0.0, 0.0, sheet->max_row_used, 1.0, rows_shown, 1.0);
sheet->ha = gtk_adjustment_new (0.0, 0.0, sheet->max_col_used, 1.0, cols_shown, 1.0);
sheet->hs = gtk_hscrollbar_new (GTK_ADJUSTMENT (sheet->ha));
sheet->vs = gtk_vscrollbar_new (GTK_ADJUSTMENT (sheet->va));
/* Attach the horizontal scroll */
gtk_table_attach (GTK_TABLE (sheet->toplevel), sheet->hs,
1, 2, 2, 3,
GTK_FILL | GTK_EXPAND, 0, 0, 0);
/* Attach the vertical scroll */
gtk_table_attach (GTK_TABLE (sheet->toplevel), sheet->vs,
2, 3, 1, 2,
0, GTK_FILL | GTK_EXPAND, 0, 0);
sheet_set_zoom_factor (sheet, 1.0);
return sheet;
}
void
sheet_destroy (Sheet *sheet)
{
g_assert (sheet != NULL);
sheet_selection_clear (sheet);
g_free (sheet->name);
style_destroy (sheet->default_row_style.style);
style_destroy (sheet->default_col_style.style);
gtk_widget_destroy (sheet->toplevel);
g_free (sheet);
}
void
sheet_foreach_col (Sheet *sheet, sheet_col_row_callback callback, void *user_data)
{
......@@ -401,3 +439,86 @@ sheet_get_cell_bounds (Sheet *sheet, ColType col, RowType row, int *x, int *y, i
*w = sheet_col_get_distance (sheet, col, col + 1);
*h = sheet_row_get_distance (sheet, row, row + 1);
}
void
sheet_selection_append (Sheet *sheet, int col, int row)
{
SheetSelection *ss;
ss = g_new0 (SheetSelection, 1);
ss->base_col = col;
ss->base_row = row;
ss->start_col = col;
ss->end_col = col;
ss->start_row = row;
ss->end_row = row;
sheet->selections = g_list_prepend (sheet->selections, ss);
gnumeric_sheet_set_selection (GNUMERIC_SHEET (sheet->sheet_view),
col, row, col, row);
sheet_redraw_all (sheet);
}
void
sheet_selection_extend_to (Sheet *sheet, int col, int row)
{
SheetSelection *ss;
g_assert (sheet->selections);
ss = (SheetSelection *) sheet->selections->data;
if (col < ss->base_col){
ss->start_col = col;
ss->end_col = ss->base_col;
} else {
ss->start_col = ss->base_col;
ss->end_col = col;
}
if (row < ss->base_row){
ss->end_row = ss->base_row;
ss->start_row = row;
} else {
ss->end_row = row;
ss->start_row = ss->base_row;
}
gnumeric_sheet_set_selection (GNUMERIC_SHEET (sheet->sheet_view),
ss->start_col, ss->start_row,
ss->end_col, ss->end_row);
sheet_redraw_all (sheet);
}
void
sheet_selection_clear (Sheet *sheet)
{
GList *list = sheet->selections;
for (list = sheet->selections; list; list = list->next){
SheetSelection *ss = list->data;
g_free (ss);
}
g_list_free (sheet->selections);
sheet->selections = NULL;
sheet_redraw_all (sheet);
}
int
sheet_selection_is_cell_selected (Sheet *sheet, int col, int row)
{
GList *list = sheet->selections;
for (list = sheet->selections; list; list = list->next){
SheetSelection *ss = list->data;
if ((ss->start_col <= col) && (col <= ss->end_col) &&
(ss->start_row <= row) && (row <= ss->end_row))
return 1;
}
return 0;
}
......@@ -19,6 +19,12 @@ typedef struct {
GHashTable *sheets; /* keeps a list of the Sheets on this workbook */
} Workbook;
typedef struct {
int base_col, base_row;
int start_col, start_row;
int end_col, end_row;
} SheetSelection;
typedef struct {
Workbook *parent_workbook;
GtkWidget *toplevel, *col_canvas, *row_canvas;
......@@ -36,47 +42,64 @@ typedef struct {
ColRowInfo default_row_style;
GList *rows_info;
void *contents;
GList *selections;
/* Scrolling information */
GtkWidget *vs, *hs; /* The scrollbars */
GtkObject *va, *ha; /* The adjustments */
int max_col_used;
int max_row_used;
} Sheet;
typedef void (*sheet_col_row_callback)(Sheet *sheet, ColRowInfo *ci, void *user_data);
Sheet *sheet_new (Workbook *wb, char *name);
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, 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_selection_append (Sheet *sheet, int col, int row);
void sheet_selection_extend_to (Sheet *sheet, int col, int row);
void sheet_selection_clear (Sheet *sheet);
int sheet_selection_is_cell_selected (Sheet *sheet, int col, int row);
/* Create new ColRowInfos from the default sheet style */
ColRowInfo *sheet_col_new (Sheet *sheet);
ColRowInfo *sheet_row_new (Sheet *sheet);
ColRowInfo *sheet_col_new (Sheet *sheet);
ColRowInfo *sheet_row_new (Sheet *sheet);
/* Duplicates the information of a col/row */
ColRowInfo *sheet_duplicate_colrow (ColRowInfo *original);
ColRowInfo *sheet_duplicate_colrow (ColRowInfo *original);
/* Retrieve information from a col/row */
ColRowInfo *sheet_col_get_info (Sheet *sheet, int col);
ColRowInfo *sheet_row_get_info (Sheet *sheet, int row);
ColRowInfo *sheet_col_get_info (Sheet *sheet, int col);
ColRowInfo *sheet_row_get_info (Sheet *sheet, int row);
/* Add a ColRowInfo to the Sheet */
void sheet_col_add (Sheet *sheet, ColRowInfo *cp);
void sheet_row_add (Sheet *sheet, ColRowInfo *cp);
void sheet_col_add (Sheet *sheet, ColRowInfo *cp);
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);
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);
/* 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_width (Sheet *sheet, int col, int width);
void sheet_row_set_height (Sheet *sheet, int row, int width);
Workbook *workbook_new (void);
Workbook *workbook_new_with_sheets (int sheet_count);
void workbook_attach_sheet (Workbook *, Sheet *);
Workbook *workbook_new (void);
Workbook *workbook_new_with_sheets (int sheet_count);
void workbook_attach_sheet (Workbook *, Sheet *);
/*
* Callback routine: invoked when the first view ItemGrid
* is realized to allocate the default styles
*/
void workbook_realized (Workbook *, GdkWindow *);
void workbook_realized (Workbook *, GdkWindow *);
#endif
......@@ -182,6 +182,22 @@ style_new (void)
return style;
}
void
style_destroy (Style *style)
{
g_return_if_fail (style != NULL);
g_return_if_fail (style->format != NULL);
g_return_if_fail (style->font != NULL);
g_return_if_fail (style->border != NULL);
style_format_unref (style->format);
style_font_unref (style->font);
style_border_unref (style->border);
g_free (style);
}
Style *
style_duplicate (Style *original)
{
......
......@@ -81,6 +81,7 @@ typedef struct {
void style_init (void);
Style *style_new (void);
Style *style_duplicate (Style *style);
void style_destroy (Style *style);
StyleFormat *style_format_new (char *name);
void style_format_ref (StyleFormat *sf);
......