diff --git a/ChangeLog-2000-02-23 b/ChangeLog-2000-02-23 index 2b1a0d1728daf0af0831015b413adb31e1d365d3..a337969a91ce93432ef0f17f216b866e7380ea15 100644 --- a/ChangeLog-2000-02-23 +++ b/ChangeLog-2000-02-23 @@ -1,3 +1,7 @@ +1999-09-08 Jody Goldberg + + * src/cell.c (cell_get_span) : Support VALUE_EMPTY. + 1999-09-08 Michael Meeks * src/sheet-view.c (filenames_dropped, sheet_view_construct): Move @@ -29,6 +33,11 @@ * src/workbook.c: changed "_Comments" to "Co_mments" as there is already "_Content" in the same menu +1999-09-07 Jody Goldberg + + * src/dialogs/dialog-function-select.c (function_definition_update, + function_categories_fill) : Const. + 1999-09-07 Miguel de Icaza * src/workbook.c: Remove sample button from the toolbar. @@ -85,6 +94,15 @@ * src/cursors.c (create_bitmap_and_mask_from_xpm): Fix bitmap loading. This code isn't exactly elegant. +1999-09-06 Jody Goldberg + + * src/sheet-view.[ch] (sheet_view_scrollbar_config) : Adjust scrollbar + increment. Split out from sheet_view_size_allocate. + + * src/gnumeric-sheet.c (gnumeric_sheet_compute_visible_ranges) : + call sheet_view_scrollbar_config, to adjust scrollbar when region + changes. + 1999-09-05 Miguel de Icaza * src/print-preview.c (preview_canvas_event): Add an event handler diff --git a/OChangeLog-2000-02-23 b/OChangeLog-2000-02-23 index 2b1a0d1728daf0af0831015b413adb31e1d365d3..a337969a91ce93432ef0f17f216b866e7380ea15 100644 --- a/OChangeLog-2000-02-23 +++ b/OChangeLog-2000-02-23 @@ -1,3 +1,7 @@ +1999-09-08 Jody Goldberg + + * src/cell.c (cell_get_span) : Support VALUE_EMPTY. + 1999-09-08 Michael Meeks * src/sheet-view.c (filenames_dropped, sheet_view_construct): Move @@ -29,6 +33,11 @@ * src/workbook.c: changed "_Comments" to "Co_mments" as there is already "_Content" in the same menu +1999-09-07 Jody Goldberg + + * src/dialogs/dialog-function-select.c (function_definition_update, + function_categories_fill) : Const. + 1999-09-07 Miguel de Icaza * src/workbook.c: Remove sample button from the toolbar. @@ -85,6 +94,15 @@ * src/cursors.c (create_bitmap_and_mask_from_xpm): Fix bitmap loading. This code isn't exactly elegant. +1999-09-06 Jody Goldberg + + * src/sheet-view.[ch] (sheet_view_scrollbar_config) : Adjust scrollbar + increment. Split out from sheet_view_size_allocate. + + * src/gnumeric-sheet.c (gnumeric_sheet_compute_visible_ranges) : + call sheet_view_scrollbar_config, to adjust scrollbar when region + changes. + 1999-09-05 Miguel de Icaza * src/print-preview.c (preview_canvas_event): Add an event handler diff --git a/src/Makefile.am b/src/Makefile.am index a6f6a8529276f2152fd4cebfc6595b6fbc62e56b..84abcefa058eea35b83cf895c9c5e61dd6db3f8b 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -119,6 +119,8 @@ GNUMERIC_BASE_SOURCES = \ regression.h \ render-ascii.c \ render-ascii.h \ + selection.c \ + selection.h \ sheet.c \ sheet.h \ sheet-autofill.c \ diff --git a/src/cell.c b/src/cell.c index 05f1837367a3320c247205833ec2797929d1c672..ddfd3fbb85b80449c2f259ae64172e018bc3c2a9 100644 --- a/src/cell.c +++ b/src/cell.c @@ -1212,7 +1212,7 @@ cell_get_span (Cell *cell, int *col1, int *col2) sibling = sheet_cell_get (sheet, pos, row); - if (sibling) + if (!cell_is_blank(sibling)) return; ci = sheet_col_get_info (sheet, pos); @@ -1240,7 +1240,7 @@ cell_get_span (Cell *cell, int *col1, int *col2) sibling = sheet_cell_get (sheet, pos, row); - if (sibling) + if (!cell_is_blank(sibling)) return; ci = sheet_col_get_info (sheet, pos); @@ -1275,7 +1275,7 @@ cell_get_span (Cell *cell, int *col1, int *col2) if (*col1 - 1 >= 0){ left_sibling = sheet_cell_get (sheet, *col1 - 1, row); - if (left_sibling) + if (!cell_is_blank(left_sibling)) left_left = 0; else { ci = sheet_col_get_info (sheet, *col1 - 1); @@ -1291,7 +1291,7 @@ cell_get_span (Cell *cell, int *col1, int *col2) if (*col2 + 1 < SHEET_MAX_COLS-1){ right_sibling = sheet_cell_get (sheet, *col2 + 1, row); - if (right_sibling) + if (!cell_is_blank(right_sibling)) left_right = 0; else { ci = sheet_col_get_info (sheet, *col2 + 1); diff --git a/src/dialogs/dialog-cell-format.c b/src/dialogs/dialog-cell-format.c index 3a746c3aeed91e87c4b861b24091d9bacc734b4b..ad291e6bcf5aefa6d65b3fdb5197c36554d40ee8 100644 --- a/src/dialogs/dialog-cell-format.c +++ b/src/dialogs/dialog-cell-format.c @@ -14,6 +14,7 @@ #include "dialogs.h" #include "format.h" #include "formats.h" +#include "selection.h" #include "pattern-selector.h" #include "widgets/widget-font-selector.h" diff --git a/src/dialogs/dialog-cell-sort.c b/src/dialogs/dialog-cell-sort.c index 1b2ab84b1623e701b53b0db29dd47406bee3dacf..052c8fd10b37dee6c4622ea3cbf408b4dbf6d432 100644 --- a/src/dialogs/dialog-cell-sort.c +++ b/src/dialogs/dialog-cell-sort.c @@ -13,6 +13,7 @@ #include "dialogs.h" #include "cell.h" #include "expr.h" +#include "selection.h" #include "utils.h" typedef struct { diff --git a/src/dialogs/dialog-delete-cells.c b/src/dialogs/dialog-delete-cells.c index 9b9c08af944c33d57fc65c393ee231ab5f8de633..1120ed26ebdd7ab41b5ea8ddf2e9b2bb386e3651 100644 --- a/src/dialogs/dialog-delete-cells.c +++ b/src/dialogs/dialog-delete-cells.c @@ -9,6 +9,7 @@ #include #include "gnumeric.h" #include "gnumeric-util.h" +#include "selection.h" #include "dialogs.h" void diff --git a/src/dialogs/dialog-function-select.c b/src/dialogs/dialog-function-select.c index 03913c74987ef744542563bdfa4d7d5bc0d525e9..590ce57a86fb0015b175305a2f3a5b847e48ac64 100644 --- a/src/dialogs/dialog-function-select.c +++ b/src/dialogs/dialog-function-select.c @@ -41,7 +41,7 @@ function_categories_fill (SelectorState *selector_state) gchar *cols [1]; fc = g_list_nth_data (selector_state->cats, i); - cols[0] = fc->name; + cols[0] = (gchar *)fc->name; /* Const cast */ gtk_clist_append (cl, cols); if (i == selector_state->selected_cat) @@ -72,7 +72,7 @@ function_definition_update (SelectorState *selector_state) gchar *cols [1]; FunctionDefinition *fn = p->data; - cols [0] = fn->name; + cols[0] = (gchar *)fn->name; /* Const cast */ gtk_clist_append (cl, cols); if (i == selector_state->selected_func) diff --git a/src/dialogs/dialog-insert-cells.c b/src/dialogs/dialog-insert-cells.c index ebf47149ac3230063ed18777e36ce20da2f24816..bf962170b380c4ab3e7c9f25c0f09b270c9fca8e 100644 --- a/src/dialogs/dialog-insert-cells.c +++ b/src/dialogs/dialog-insert-cells.c @@ -9,6 +9,7 @@ #include #include "gnumeric.h" #include "gnumeric-util.h" +#include "selection.h" #include "dialogs.h" void diff --git a/src/gnumeric-canvas.c b/src/gnumeric-canvas.c index 4307dbea84d9cf3ec750437ce07c2bea95fd0919..285628d290c51a425673e8cdf8a497b3c77159d6 100644 --- a/src/gnumeric-canvas.c +++ b/src/gnumeric-canvas.c @@ -15,6 +15,7 @@ #include "sheet-object.h" #include "color.h" #include "cursors.h" +#include "selection.h" #include "utils.h" #undef DEBUG_POSITIONS @@ -1115,6 +1116,9 @@ gnumeric_sheet_compute_visible_ranges (GnumericSheet *gsheet) pixels = cb; row++; } while (pixels < height); + + /* Update the scrollbar sizes */ + sheet_view_scrollbar_config (gsheet->sheet_view); } static int diff --git a/src/gnumeric-sheet.c b/src/gnumeric-sheet.c index 4307dbea84d9cf3ec750437ce07c2bea95fd0919..285628d290c51a425673e8cdf8a497b3c77159d6 100644 --- a/src/gnumeric-sheet.c +++ b/src/gnumeric-sheet.c @@ -15,6 +15,7 @@ #include "sheet-object.h" #include "color.h" #include "cursors.h" +#include "selection.h" #include "utils.h" #undef DEBUG_POSITIONS @@ -1115,6 +1116,9 @@ gnumeric_sheet_compute_visible_ranges (GnumericSheet *gsheet) pixels = cb; row++; } while (pixels < height); + + /* Update the scrollbar sizes */ + sheet_view_scrollbar_config (gsheet->sheet_view); } static int diff --git a/src/item-cursor.c b/src/item-cursor.c index 82630adb7e1078d882e71fa03bb17164aa542311..8ae391a5f768559b8f80ad28234d2b35d2936715 100644 --- a/src/item-cursor.c +++ b/src/item-cursor.c @@ -17,6 +17,7 @@ #include "cursors.h" #include "sheet-autofill.h" #include "clipboard.h" +#include "selection.h" static GnomeCanvasItem *item_cursor_parent_class; diff --git a/src/item-grid.c b/src/item-grid.c index 26f3590d8ef2c685068d746cb974a1d2979c5a37..0d430d3125d999a4e9e9a03b8a492cd901978010 100644 --- a/src/item-grid.c +++ b/src/item-grid.c @@ -16,6 +16,7 @@ #include "cursors.h" #include "gnumeric-util.h" #include "clipboard.h" +#include "selection.h" #include "main.h" static GnomeCanvasItem *item_grid_parent_class; diff --git a/src/selection.c b/src/selection.c new file mode 100644 index 0000000000000000000000000000000000000000..7cf67acfa887adee82ecc1a140e70610567a3fb6 --- /dev/null +++ b/src/selection.c @@ -0,0 +1,1058 @@ +/* + * selection.c: Manage selection regions. + * + * Author: + * Miguel de Icaza (miguel@gnu.org) + * + */ +#include "selection.h" +#include "gnumeric-sheet.h" +#include "utils.h" +#include "clipboard.h" +#include "gnumeric-util.h" + +/* FIXME : why do we need this ? split things better so that we can avoid it */ +#define GNUMERIC_SHEET_VIEW(p) GNUMERIC_SHEET (SHEET_VIEW(p)->sheet_view); + +#if 0 +/* +This is some of the new code to break regions into non-intesecting areas. +I will enable it after the code transfer. +*/ + +/* Quick utility routine to test intersect of line segments. + * Returns : 4 --sA--sb--eb--eA-- a contains b + * 3 --sA--sb--eA--eb-- overlap left + * 2 --sb--sA--eA--eb-- b contains a + * 1 --sb--sA--eb--eA-- overlap right + * 0 if there is no intersection. + */ +static int +segments_intersect (int const s_a, int const e_a, + int const s_b, int const e_b) +{ + /* Assume s_a <= e_a and s_b <= e_b */ + if (e_a < s_b || e_b < s_a) + return 0; + + if (s_a < s_b) + return (e_a >= e_b) ? 4 : 3; + + /* We already know that s_a <= e_b */ + return (e_a <= e_b) ? 2 : 1; +} + +static SheetSelection * +SheetSelection_copy (SheetSelection const * src) +{ + SheetSelection * res; + res = g_new (SheetSelection, 1); + + res->start_col = src->start_col; + res->end_col = src->end_col; + res->start_row = src->start_row; + res->end_row = src->end_row; + return res; +} + +static void +SheetSelection_dump (SheetSelection const * src) +{ + /* keep these as 2 print statements, because + * col_name uses a static buffer */ + fprintf (stderr, "%s%d", + col_name(src->start_col), + src->start_row + 1); + fprintf (stderr, ":%s%d\n", + col_name(src->end_col), + src->end_row + 1); +} + +void +selection_append_range (Sheet *sheet, + int start_col, int start_row, + int end_col, int end_row) +{ + SheetSelection *ss, *tmp, orig; + GList *l, *next, *proposed; + + g_return_if_fail (sheet != NULL); + g_return_if_fail (IS_SHEET (sheet)); + + ss = g_new0 (SheetSelection, 1); + + ss->start_col = start_col; + ss->end_col = end_col; + ss->start_row = start_row; + ss->end_row = end_row; + + orig = *ss; /* NOTE : copy struct */ + + fprintf (stderr, "\n%d %d %d %d\n", + start_col, start_row, end_col, end_row); + SheetSelection_dump (ss); + + fprintf(stderr, "=========================================\n "); + /* + * Run through all the selection regions to see if any of + * the proposed regions overlap + */ + proposed = g_list_prepend (NULL, ss); + for (l = sheet->selections; l != NULL; l = next) { + /* The set of regions that do not interset with b or + * its predecessors */ + GList *clear = NULL; + int i = 0; + + SheetSelection *b = l->data; + fprintf(stderr, "\nTest %d = ", ++i); + SheetSelection_dump (b); + + /* prefetch in case the element gets removed */ + next = l->next; + + + /* run through the proposed regions and handle any that + * overlap with the current selection region + */ + while (proposed != NULL) { + int row_intersect, col_intersect; + + /* pop the 1st element off the list */ + SheetSelection *a = proposed->data; + + fprintf(stderr, "proposed = "); + SheetSelection_dump (a); + + proposed = g_list_remove (proposed, a); + + col_intersect = + segments_intersect (a->start_col, a->end_col, + b->start_col, b->end_col); + + fprintf (stderr, "Col intersect = %d\n", col_intersect); + /* No intersection */ + if (col_intersect == 0) { + clear = g_list_prepend (clear, a); + continue; + } + + row_intersect = + segments_intersect (a->start_row, a->end_row, + b->start_row, b->end_row); + fprintf (stderr, "Row intersect = %d\n", row_intersect); + /* No intersection */ + if (row_intersect == 0) { + clear = g_list_prepend (clear, a); + continue; + } + + /* Cross product of intersection cases */ + switch (col_intersect) { + case 4 : /* a contains b */ + switch (row_intersect) { + case 4 : /* a contains b */ + /* Old region contained by new region */ + + /* remove old region from selection */ + sheet->selections = g_list_remove(sheet->selections, b); + break; + + case 3 : /* overlap top */ + /* Shrink existing range */ + b->end_row = a->start_row - 1; + break; + + case 2 : /* b contains a */ + /* Split existing range */ + if (b->start_col > 0) { + tmp = SheetSelection_copy (a); + tmp->end_col = b->start_col - 1; + clear = g_list_prepend (clear, tmp); + } + /* Fall through to do bottom segment */ + + case 1 : /* overlap bottom */ + /* Shrink existing range */ + a->start_col = b->end_col + 1; + break; + + default : + g_assert_not_reached(); + }; + break; + + case 3 : /* overlap left */ + switch (row_intersect) { + case 4 : /* a contains b */ + /* Shrink old region */ + b->start_col = a->end_col + 1; + break; + + case 3 : /* overlap top */ + /* Split region */ + if (b->start_row > 0) { + tmp = SheetSelection_copy (a); + tmp->start_col = b->start_col; + tmp->end_row = b->start_row - 1; + clear = g_list_prepend (clear, tmp); + } + /* fall through */ + + case 2 : /* b contains a */ + /* shrink the left segment */ + a->end_col = b->start_col - 1; + break; + + case 1 : /* overlap bottom */ + /* Split region */ + if (b->end_row < (SHEET_MAX_ROWS-1)) { + tmp = SheetSelection_copy (a); + tmp->start_col = b->start_col; + tmp->start_row = b->end_row + 1; + clear = g_list_prepend (clear, tmp); + } + + /* shrink the left segment */ + if (b->start_col == 0) { + g_free(a); + continue; + } + a->end_col = b->start_col - 1; + break; + + default : + g_assert_not_reached(); + }; + break; + + case 2 : /* b contains a */ + switch (row_intersect) { + case 4 : /* a contains b */ + /* Split region */ + tmp = SheetSelection_copy (a); + tmp->start_row = b->end_row + 1; + clear = g_list_prepend (clear, tmp); + /* fall through */ + + case 3 : /* overlap top */ + /* shrink the top segment */ + a->end_row = b->start_row - 1; + break; + + case 2 : /* b contains a */ + /* remove the selection */ + g_free (a); + continue; + + case 1 : /* overlap bottom */ + /* shrink the top segment */ + a->start_row = b->end_row + 1; + break; + + default : + g_assert_not_reached(); + }; + break; + + case 1 : /* overlap right */ + switch (row_intersect) { + case 4 : /* a contains b */ + /* Shrink old region */ + b->end_col = a->start_col - 1; + break; + + case 3 : /* overlap top */ + /* Split region */ + tmp = SheetSelection_copy (a); + tmp->end_col = b->end_col; + tmp->end_row = b->start_row - 1; + /* fall through */ + + case 2 : /* b contains a */ + /* shrink the right segment */ + a->start_col = b->end_col + 1; + break; + + case 1 : /* overlap bottom */ + /* Split region */ + tmp = SheetSelection_copy (a); + tmp->end_col = b->end_col; + tmp->start_row = b->end_row + 1; + + /* shrink the right segment */ + a->start_col = b->end_col + 1; + break; + + default : + g_assert_not_reached(); + }; + break; + + }; + /* Be careful putting code here one of the cases skips this */ + + /* continue checking the new region for intersections */ + clear = g_list_prepend (clear, a); + } + proposed = clear; + } + + /* Catch attempts to select something twice */ + if (proposed == NULL) + return; + + sheet->selections = g_list_concat (sheet->selections, proposed); + + sheet_accept_pending_input (sheet); + + for (l = sheet->sheet_views; l; l = l->next){ + GnumericSheet *gsheet = GNUMERIC_SHEET_VIEW (l->data); + + gnumeric_sheet_set_selection (gsheet, &orig); + } + sheet_redraw_selection (sheet, &orig); + + sheet_redraw_cols (sheet); + sheet_redraw_rows (sheet); + + sheet_selection_changed_hook (sheet); +} +#endif +int +sheet_selection_equal (SheetSelection *a, SheetSelection *b) +{ + if (a->start_col != b->start_col) + return 0; + if (a->start_row != b->start_row) + return 0; + + if (a->end_col != b->end_col) + return 0; + if (a->end_row != b->end_row) + return 0; + return 1; +} + +static const char * +sheet_get_selection_name (Sheet *sheet) +{ + SheetSelection *ss = sheet->selections->data; + static char buffer [10 + 2 * 4 * sizeof (int)]; + + if (ss->start_col == ss->end_col && ss->start_row == ss->end_row){ + return cell_name (ss->start_col, ss->start_row); + } else { + snprintf (buffer, sizeof (buffer), "%dLx%dC", + ss->end_row - ss->start_row + 1, + ss->end_col - ss->start_col + 1); + return buffer; + } +} + +static void +sheet_selection_changed_hook (Sheet *sheet) +{ + sheet_update_auto_expr (sheet); + sheet_update_controls (sheet); + workbook_set_region_status (sheet->workbook, sheet_get_selection_name (sheet)); +} + +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) +{ + SheetSelection *ss; + GList *l; + + g_return_if_fail (sheet != NULL); + g_return_if_fail (IS_SHEET (sheet)); + + ss = g_new0 (SheetSelection, 1); + + ss->base_col = base_col; + ss->base_row = base_row; + + ss->start_col = start_col; + ss->end_col = end_col; + ss->start_row = start_row; + ss->end_row = end_row; + + sheet->selections = g_list_prepend (sheet->selections, ss); + + sheet_accept_pending_input (sheet); + sheet_load_cell_val (sheet); + + for (l = sheet->sheet_views; l; l = l->next){ + GnumericSheet *gsheet = GNUMERIC_SHEET_VIEW (l->data); + + gnumeric_sheet_set_selection (gsheet, ss); + } + sheet_redraw_selection (sheet, ss); + + sheet_redraw_cols (sheet); + sheet_redraw_rows (sheet); + + sheet_selection_changed_hook (sheet); +} + +/** + * If returns true selection is just one range. + * If returns false, range data: indeterminate + **/ +int +sheet_selection_first_range (Sheet *sheet, + int *base_col, int *base_row, + int *start_col, int *start_row, + int *end_col, int *end_row) +{ + SheetSelection *ss; + GList *l; + + g_return_val_if_fail (sheet != NULL, 0); + g_return_val_if_fail (IS_SHEET (sheet), 0); + + if (!sheet->selections) + return 0; + + l = g_list_first (sheet->selections); + if (!l || !l->data) + return 0; + + ss = l->data; + *base_col = ss->base_col; + *base_row = ss->base_row; + *start_col = ss->start_col; + *start_row = ss->start_row; + *end_col = ss->end_col; + *end_row = ss->end_row; + + if ((l = g_list_next (l))) + return 0; + return 1; +} + +void +sheet_selection_append (Sheet *sheet, int col, int row) +{ + sheet_selection_append_range (sheet, col, row, col, row, col, row); +} + +/** + * sheet_selection_extend_to: + * @sheet: the sheet + * @col: column that gets covered + * @row: row that gets covered + * + * This extends the selection to cover col, row + */ +void +sheet_selection_extend_to (Sheet *sheet, int col, int row) +{ + SheetSelection *ss, old_selection; + GList *l; + + g_return_if_fail (sheet != NULL); + g_return_if_fail (IS_SHEET (sheet)); + + g_assert (sheet->selections); + + ss = (SheetSelection *) sheet->selections->data; + + old_selection = *ss; + + 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; + } + + for (l = sheet->sheet_views; l; l = l->next){ + GnumericSheet *gsheet = GNUMERIC_SHEET_VIEW (l->data); + + gnumeric_sheet_set_selection (gsheet, ss); + } + + sheet_selection_changed_hook (sheet); + + sheet_redraw_selection (sheet, &old_selection); + sheet_redraw_selection (sheet, ss); + + if (ss->start_col != old_selection.start_col || + ss->end_col != old_selection.end_col || + ((ss->start_row == 0 && ss->end_row == SHEET_MAX_ROWS-1) ^ + (old_selection.start_row == 0 && + old_selection.end_row == SHEET_MAX_ROWS-1))) + sheet_redraw_cols (sheet); + + if (ss->start_row != old_selection.start_row || + ss->end_row != old_selection.end_row || + ((ss->start_col == 0 && ss->end_col == SHEET_MAX_COLS-1) ^ + (old_selection.start_col == 0 && + old_selection.end_col == SHEET_MAX_COLS-1))) + sheet_redraw_rows (sheet); +} + +/** + * sheet_select_all: + * Sheet: The sheet + * + * Selects all of the cells in the sheet + */ +void +sheet_select_all (Sheet *sheet) +{ + g_return_if_fail (sheet != NULL); + g_return_if_fail (IS_SHEET (sheet)); + + sheet_selection_reset_only (sheet); + sheet_make_cell_visible (sheet, 0, 0); + sheet_cursor_move (sheet, 0, 0, FALSE, FALSE); + sheet_selection_append_range (sheet, 0, 0, 0, 0, + SHEET_MAX_COLS-1, SHEET_MAX_ROWS-1); + + /* Queue redraws for columns and rows */ + sheet_redraw_rows (sheet); + sheet_redraw_cols (sheet); +} + +int +sheet_is_all_selected (Sheet *sheet) +{ + SheetSelection *ss; + GList *l; + + g_return_val_if_fail (sheet != NULL, FALSE); + g_return_val_if_fail (IS_SHEET (sheet), FALSE); + + for (l = sheet->selections; l != NULL; l = l->next){ + ss = l->data; + + if (ss->start_col == 0 && + ss->start_row == 0 && + ss->end_col == SHEET_MAX_COLS-1 && + ss->end_row == SHEET_MAX_ROWS-1) + return TRUE; + } + return FALSE; +} + +static void +sheet_selection_change (Sheet *sheet, SheetSelection *old, SheetSelection *new) +{ + GList *l; + + if (sheet_selection_equal (old, new)) + return; + + sheet_accept_pending_input (sheet); + sheet_redraw_selection (sheet, old); + sheet_redraw_selection (sheet, new); + sheet_selection_changed_hook (sheet); + + for (l = sheet->sheet_views; l; l = l->next){ + GnumericSheet *gsheet = GNUMERIC_SHEET_VIEW (l->data); + + gnumeric_sheet_set_selection (gsheet, new); + } + + if (new->start_col != old->start_col || + new->end_col != old->end_col || + ((new->start_row == 0 && new->end_row == SHEET_MAX_ROWS-1) ^ + (old->start_row == 0 && + old->end_row == SHEET_MAX_ROWS-1))) + sheet_redraw_cols (sheet); + + if (new->start_row != old->start_row || + new->end_row != old->end_row || + ((new->start_col == 0 && new->end_col == SHEET_MAX_COLS-1) ^ + (old->start_col == 0 && + old->end_col == SHEET_MAX_COLS-1))) + sheet_redraw_rows (sheet); +} + +/** + * sheet_selection_extend_horizontal: + * + * @sheet: The Sheet * + * @count: units to extend the selection horizontally + * @jump_to_boundaries : Jump to range boundaries. + */ +void +sheet_selection_extend_horizontal (Sheet *sheet, int n, gboolean jump_to_boundaries) +{ + SheetSelection *ss; + SheetSelection old_selection; + + g_return_if_fail (sheet != NULL); + g_return_if_fail (IS_SHEET (sheet)); + + ss = (SheetSelection *)sheet->selections->data; + old_selection = *ss; + + if (ss->base_col < ss->end_col) + ss->end_col = + sheet_find_boundary_horizontal (sheet, + ss->end_col, ss->end_row, + n, jump_to_boundaries); + else if (ss->base_col > ss->start_col || n < 0) + ss->start_col = + sheet_find_boundary_horizontal (sheet, + ss->start_col, ss->start_row, + n, jump_to_boundaries); + else + ss->end_col = + sheet_find_boundary_horizontal (sheet, + ss->end_col, ss->end_row, + n, jump_to_boundaries); + + if (ss->end_col < ss->start_col) { + int const tmp = ss->start_col; + ss->start_col = ss->end_col; + ss->end_col = tmp; + } + sheet_selection_change (sheet, &old_selection, ss); +} + +/* + * sheet_selection_extend_vertical + * @sheet: The Sheet * + * @n: units to extend the selection vertically + * @jump_to_boundaries : Jump to range boundaries. + */ +void +sheet_selection_extend_vertical (Sheet *sheet, int n, gboolean jump_to_boundaries) +{ + SheetSelection *ss; + SheetSelection old_selection; + + g_return_if_fail (sheet != NULL); + g_return_if_fail (IS_SHEET (sheet)); + + ss = (SheetSelection *)sheet->selections->data; + old_selection = *ss; + + if (ss->base_row < ss->end_row) + ss->end_row = + sheet_find_boundary_vertical (sheet, + ss->end_col, ss->end_row, + n, jump_to_boundaries); + else if (ss->base_row > ss->start_row || n < 0) + ss->start_row = + sheet_find_boundary_vertical (sheet, + ss->start_col, ss->start_row, + n, jump_to_boundaries); + else + ss->end_row = + sheet_find_boundary_vertical (sheet, + ss->end_col, ss->end_row, + n, jump_to_boundaries); + + if (ss->end_row < ss->start_row) { + int const tmp = ss->start_row; + ss->start_row = ss->end_row; + ss->end_row = tmp; + } + sheet_selection_change (sheet, &old_selection, ss); +} + +void +sheet_selection_set (Sheet *sheet, int start_col, int start_row, int end_col, int end_row) +{ + SheetSelection *ss; + SheetSelection old_selection; + + g_return_if_fail (sheet != NULL); + g_return_if_fail (IS_SHEET (sheet)); + + ss = (SheetSelection *)sheet->selections->data; + old_selection = *ss; + + ss->start_row = start_row; + ss->end_row = end_row; + ss->start_col = start_col; + ss->end_col = end_col; + + sheet_selection_change (sheet, &old_selection, ss); +} + +/** + * sheet_selection_free + * @sheet: the sheet + * + * Releases the selection associated with this sheet + */ +void +sheet_selection_free (Sheet *sheet) +{ + GList *list; + + for (list = sheet->selections; list; list = list->next){ + SheetSelection *ss = list->data; + g_free (ss); + } + + g_list_free (sheet->selections); + sheet->selections = NULL; +} + +/* + * sheet_selection_reset + * sheet: The sheet + * + * Clears all of the selection ranges. + * Warning: This does not set a new selection, this should + * be taken care on the calling routine. + */ +void +sheet_selection_reset_only (Sheet *sheet) +{ + GList *list; + + g_return_if_fail (sheet != NULL); + g_return_if_fail (IS_SHEET (sheet)); + + for (list = sheet->selections; list; list = list->next){ + SheetSelection *ss = list->data; + + sheet_redraw_selection (sheet, ss); + } + sheet_selection_free (sheet); + + sheet->walk_info.current = NULL; + + /* Redraw column bar */ + sheet_redraw_cols (sheet); + + /* Redraw the row bar */ + sheet_redraw_rows (sheet); +} + +/** + * sheet_selection_reset: + * sheet: The sheet + * + * Clears all of the selection ranges and resets it to a + * selection that only covers the cursor + */ +void +sheet_selection_reset (Sheet *sheet) +{ + g_return_if_fail (sheet != NULL); + g_return_if_fail (IS_SHEET (sheet)); + + sheet_selection_reset_only (sheet); + sheet_selection_append (sheet, sheet->cursor_col, sheet->cursor_row); +} + +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; +} + +/* + * assemble_cell_list: A callback for sheet_cell_foreach_range + * intented to assemble a list of cells in a region. + * + * The closure parameter should be a pointer to a GList. + */ +static Value * +assemble_cell_list (Sheet *sheet, int col, int row, Cell *cell, void *user_data) +{ + GList **l = (GList **) user_data; + + *l = g_list_prepend (*l, cell); + return NULL; +} + +CellList * +sheet_selection_to_list (Sheet *sheet) +{ + GList *selections; + CellList *list; + + g_return_val_if_fail (sheet != NULL, NULL); + g_return_val_if_fail (IS_SHEET (sheet), NULL); + g_return_val_if_fail (sheet->selections, NULL); + + list = NULL; + for (selections = sheet->selections; selections; selections = selections->next){ + SheetSelection *ss = selections->data; + + sheet_cell_foreach_range ( + sheet, TRUE, + ss->start_col, ss->start_row, + ss->end_col, ss->end_row, + assemble_cell_list, &list); + } + + return list; +} + +static void +reference_append (GString *result_str, int col, int row) +{ + char *row_string = g_strdup_printf ("%d", row); + + g_string_append_c (result_str, '$'); + g_string_append (result_str, col_name (col)); + g_string_append_c (result_str, '$'); + g_string_append (result_str, row_string); + + g_free (row_string); +} + +char * +sheet_selection_to_string (Sheet *sheet, gboolean include_sheet_name_prefix) +{ + GString *result_str; + GList *selections; + char *result; + + g_return_val_if_fail (sheet != NULL, NULL); + g_return_val_if_fail (IS_SHEET (sheet), NULL); + g_return_val_if_fail (sheet->selections, NULL); + + result_str = g_string_new (""); + for (selections = sheet->selections; selections; selections = selections->next){ + SheetSelection *ss = selections->data; + + if (*result_str->str) + g_string_append_c (result_str, ','); + + if (include_sheet_name_prefix){ + g_string_append_c (result_str, '\''); + g_string_append (result_str, sheet->name); + g_string_append (result_str, "'!"); + } + + if ((ss->start_col != ss->end_col) || + (ss->start_row != ss->end_row)){ + reference_append (result_str, ss->start_col, ss->end_row); + g_string_append_c (result_str, ':'); + reference_append (result_str, ss->end_col, ss->end_row); + } else + reference_append (result_str, ss->start_col, ss->start_row); + } + + result = result_str->str; + g_string_free (result_str, FALSE); + return result; +} + +void +sheet_selection_clear (Sheet *sheet) +{ + GList *l; + + g_return_if_fail (sheet != NULL); + g_return_if_fail (IS_SHEET (sheet)); + + for (l = sheet->selections; l; l = l->next){ + SheetSelection *ss = l->data; + + sheet_clear_region (sheet, + ss->start_col, ss->start_row, + ss->end_col, ss->end_row); + } +} + +/** + * sheet_selection_clear_content: + * @sheet: The sheet where we operate + * + * Removes the contents of all the cells in the current selection. + **/ +void +sheet_selection_clear_content (Sheet *sheet) +{ + GList *l; + + g_return_if_fail (sheet != NULL); + g_return_if_fail (IS_SHEET (sheet)); + + for (l = sheet->selections; l; l = l->next){ + SheetSelection *ss = l->data; + + sheet_clear_region_content (sheet, + ss->start_col, ss->start_row, + ss->end_col, ss->end_row); + } +} + +/** + * sheet_selection_clear_comments: + * @sheet: The sheet where we operate + * + * Removes all of the comments on the range of selected cells. + **/ +void +sheet_selection_clear_comments (Sheet *sheet) +{ + GList *l; + + g_return_if_fail (sheet != NULL); + g_return_if_fail (IS_SHEET (sheet)); + + for (l = sheet->selections; l; l = l->next){ + SheetSelection *ss = l->data; + + sheet_clear_region_comments (sheet, + ss->start_col, ss->start_row, + ss->end_col, ss->end_row); + } +} + +void +sheet_selection_clear_formats (Sheet *sheet) +{ + GList *l; + + g_return_if_fail (sheet != NULL); + g_return_if_fail (IS_SHEET (sheet)); + + for (l = sheet->selections; l; l = l->next){ + SheetSelection *ss = l->data; + + sheet_clear_region_formats (sheet, + ss->start_col, ss->start_row, + ss->end_col, ss->end_row); + } +} + +gboolean +sheet_verify_selection_simple (Sheet *sheet, const char *command_name) +{ + char *msg; + + if (g_list_length (sheet->selections) == 1) + return TRUE; + + msg = g_strconcat ( + _("The command `"), + command_name, + _("' cannot be performed with multiple selections"), NULL); + gnumeric_notice (sheet->workbook, GNOME_MESSAGE_BOX_ERROR, msg); + g_free (msg); + + return FALSE; +} + +gboolean +sheet_selection_copy (Sheet *sheet) +{ + SheetSelection *ss; + g_return_val_if_fail (sheet != NULL, FALSE); + g_return_val_if_fail (IS_SHEET (sheet), FALSE); + g_return_val_if_fail (sheet->selections, FALSE); + + if (!sheet_verify_selection_simple (sheet, _("copy"))) + return FALSE; + + ss = sheet->selections->data; + + if (sheet->workbook->clipboard_contents) + clipboard_release (sheet->workbook->clipboard_contents); + + sheet->workbook->clipboard_contents = clipboard_copy_cell_range ( + sheet, + ss->start_col, ss->start_row, + ss->end_col, ss->end_row, FALSE); + + return TRUE; +} + +gboolean +sheet_selection_cut (Sheet *sheet) +{ + SheetSelection *ss; + + g_return_val_if_fail (sheet != NULL, FALSE); + g_return_val_if_fail (IS_SHEET (sheet), FALSE); + g_return_val_if_fail (sheet->selections, FALSE); + + if (!sheet_verify_selection_simple (sheet, _("cut"))) + return FALSE; + + ss = sheet->selections->data; + + if (sheet->workbook->clipboard_contents) + clipboard_release (sheet->workbook->clipboard_contents); + + sheet->workbook->clipboard_contents = clipboard_copy_cell_range ( + sheet, + ss->start_col, ss->start_row, + ss->end_col, ss->end_row, TRUE); + + sheet_clear_region (sheet, ss->start_col, ss->start_row, ss->end_col, ss->end_row); + + return TRUE; +} + +static gboolean +find_a_clipboard (Workbook *wb, gpointer data) +{ + CellRegion **cr = data; + + if (wb->clipboard_contents){ + *cr = wb->clipboard_contents; + return FALSE; + } + + return TRUE; +} + +static CellRegion * +find_workbook_with_clipboard (Sheet *sheet) +{ + CellRegion *cr = NULL; + + if (sheet->workbook->clipboard_contents) + return sheet->workbook->clipboard_contents; + + workbook_foreach (find_a_clipboard, &cr); + + return cr; +} + +void +sheet_selection_paste (Sheet *sheet, int dest_col, int dest_row, int paste_flags, guint32 time) +{ + CellRegion *content; + + g_return_if_fail (sheet != NULL); + g_return_if_fail (IS_SHEET (sheet)); + g_return_if_fail (sheet->selections); + + content = find_workbook_with_clipboard (sheet); + + if (content) + if (!sheet_verify_selection_simple (sheet, _("paste"))) + return; + + clipboard_paste_region (content, sheet, dest_col, dest_row, paste_flags, time); +} + diff --git a/src/selection.h b/src/selection.h new file mode 100644 index 0000000000000000000000000000000000000000..3187040215b618a5a2476f650c8ed88201e0b283 --- /dev/null +++ b/src/selection.h @@ -0,0 +1,51 @@ +#ifndef GNUMERIC_SELECTION_H +#define GNUMERIC_SELECTION_H + +#include "sheet.h" + + +/* Selection management */ +void sheet_select_all (Sheet *sheet); +int sheet_is_all_selected (Sheet *sheet); +void sheet_selection_append (Sheet *sheet, int col, int row); +void sheet_selection_extend_to (Sheet *sheet, int col, int row); +void sheet_selection_set (Sheet *sheet, + int start_col, int start_row, + int end_col, int end_row); +void sheet_selection_reset (Sheet *sheet); +void sheet_selection_reset_only (Sheet *sheet); +int sheet_selection_equal (SheetSelection *a, SheetSelection *b); +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); +int sheet_selection_first_range (Sheet *sheet, + int *base_col, int *base_row, + int *start_col, int *start_row, + int *end_col, int *end_row); +void sheet_selection_free (Sheet *sheet); +CellList *sheet_selection_to_list (Sheet *sheet); +char *sheet_selection_to_string (Sheet *sheet, gboolean include_sheet_name_prefix); + +/* Operations on the selection */ +void sheet_selection_clear (Sheet *sheet); +void sheet_selection_clear_content (Sheet *sheet); +void sheet_selection_clear_comments (Sheet *sheet); +void sheet_selection_clear_formats (Sheet *sheet); + +/* Cut/Copy/Paste on the workbook selection */ +gboolean sheet_selection_copy (Sheet *sheet); +gboolean sheet_selection_cut (Sheet *sheet); +void sheet_selection_paste (Sheet *sheet, + int dest_col, int dest_row, + int paste_flags, guint32 time32); +int sheet_selection_walk_step (Sheet *sheet, + int forward, int horizontal, + int current_col, int current_row, + int *new_col, int *new_row); +void sheet_selection_extend_horizontal (Sheet *sheet, int count, gboolean jump_to_boundaries); +void sheet_selection_extend_vertical (Sheet *sheet, int count, gboolean jump_to_boundaries); +int sheet_selection_is_cell_selected (Sheet *sheet, int col, int row); +gboolean sheet_verify_selection_simple (Sheet *sheet, const char *command_name); + +#endif /* GNUMERIC_SELECTION_H */ diff --git a/src/sheet-control-gui.c b/src/sheet-control-gui.c index 2562192c83c98c5a418c9c96842b53ef9bca3cce..fbedad49c270711326bcfce02cd8b97303580c68 100644 --- a/src/sheet-control-gui.c +++ b/src/sheet-control-gui.c @@ -185,25 +185,41 @@ new_canvas_bar (SheetView *sheet_view, GtkOrientation o, GnomeCanvasItem **itemp return GNOME_CANVAS (canvas); } -static void -sheet_view_size_allocate (GtkWidget *widget, GtkAllocation *alloc, SheetView *sheet_view) +/* Manages the scrollbar dimensions and paging parameters. */ +void +sheet_view_scrollbar_config (SheetView const *sheet_view) { GtkAdjustment *va = GTK_ADJUSTMENT (sheet_view->va); GtkAdjustment *ha = GTK_ADJUSTMENT (sheet_view->ha); GnumericSheet *gsheet = GNUMERIC_SHEET (sheet_view->sheet_view); - int last_col = gsheet->last_full_col; - int last_row = gsheet->last_full_row; + Sheet *sheet = sheet_view->sheet; + int const last_col = gsheet->last_full_col; + int const last_row = gsheet->last_full_row; - va->upper = MAX (last_row, sheet_view->sheet->max_row_used); + va->upper = MAX (MAX (last_row, + sheet_view->sheet->max_row_used), + sheet->cursor_row); va->page_size = last_row - gsheet->top_row; + va->step_increment = va->page_increment = + va->page_size / 2; - ha->upper = MAX (last_col, sheet_view->sheet->max_col_used); + ha->upper = MAX (MAX (last_col, + sheet_view->sheet->max_col_used), + sheet->cursor_col); ha->page_size = last_col - gsheet->top_col; + ha->step_increment = ha->page_increment = + ha->page_size / 2; gtk_adjustment_changed (va); gtk_adjustment_changed (ha); } +static void +sheet_view_size_allocate (GtkWidget *widget, GtkAllocation *alloc, SheetView *sheet_view) +{ + sheet_view_scrollbar_config (sheet_view); +} + static void sheet_view_col_selection_changed (ItemBar *item_bar, int column, int modifiers, SheetView *sheet_view) { @@ -557,7 +573,6 @@ sheet_view_construct (SheetView *sheet_view) GTK_SIGNAL_FUNC (button_select_all), sheet_view); /* Scroll bars and their adjustments */ - /* FIXME : The step_inc, page_inc, and page_size should be related to the page size, not 1 */ sheet_view->va = gtk_adjustment_new (0.0, 0.0, sheet->max_row_used, 1.0, 1.0, 1.0); sheet_view->ha = gtk_adjustment_new (0.0, 0.0, sheet->max_col_used, 1.0, 1.0, 1.0); sheet_view->hs = gtk_hscrollbar_new (GTK_ADJUSTMENT (sheet_view->ha)); diff --git a/src/sheet-control-gui.h b/src/sheet-control-gui.h index 0df82010833c09fb370e0960b27421af2aeb4cf9..5764caa2a33ce6a21bb97595884cabfd402a5318 100644 --- a/src/sheet-control-gui.h +++ b/src/sheet-control-gui.h @@ -73,6 +73,8 @@ void sheet_view_set_header_visibility (SheetView *sheet_view, gboolean col_headers_visible, gboolean row_headers_visible); +void sheet_view_scrollbar_config (SheetView const *sheet_view); + typedef struct { GtkTableClass parent_class; } SheetViewClass; diff --git a/src/sheet-view.c b/src/sheet-view.c index 2562192c83c98c5a418c9c96842b53ef9bca3cce..fbedad49c270711326bcfce02cd8b97303580c68 100644 --- a/src/sheet-view.c +++ b/src/sheet-view.c @@ -185,25 +185,41 @@ new_canvas_bar (SheetView *sheet_view, GtkOrientation o, GnomeCanvasItem **itemp return GNOME_CANVAS (canvas); } -static void -sheet_view_size_allocate (GtkWidget *widget, GtkAllocation *alloc, SheetView *sheet_view) +/* Manages the scrollbar dimensions and paging parameters. */ +void +sheet_view_scrollbar_config (SheetView const *sheet_view) { GtkAdjustment *va = GTK_ADJUSTMENT (sheet_view->va); GtkAdjustment *ha = GTK_ADJUSTMENT (sheet_view->ha); GnumericSheet *gsheet = GNUMERIC_SHEET (sheet_view->sheet_view); - int last_col = gsheet->last_full_col; - int last_row = gsheet->last_full_row; + Sheet *sheet = sheet_view->sheet; + int const last_col = gsheet->last_full_col; + int const last_row = gsheet->last_full_row; - va->upper = MAX (last_row, sheet_view->sheet->max_row_used); + va->upper = MAX (MAX (last_row, + sheet_view->sheet->max_row_used), + sheet->cursor_row); va->page_size = last_row - gsheet->top_row; + va->step_increment = va->page_increment = + va->page_size / 2; - ha->upper = MAX (last_col, sheet_view->sheet->max_col_used); + ha->upper = MAX (MAX (last_col, + sheet_view->sheet->max_col_used), + sheet->cursor_col); ha->page_size = last_col - gsheet->top_col; + ha->step_increment = ha->page_increment = + ha->page_size / 2; gtk_adjustment_changed (va); gtk_adjustment_changed (ha); } +static void +sheet_view_size_allocate (GtkWidget *widget, GtkAllocation *alloc, SheetView *sheet_view) +{ + sheet_view_scrollbar_config (sheet_view); +} + static void sheet_view_col_selection_changed (ItemBar *item_bar, int column, int modifiers, SheetView *sheet_view) { @@ -557,7 +573,6 @@ sheet_view_construct (SheetView *sheet_view) GTK_SIGNAL_FUNC (button_select_all), sheet_view); /* Scroll bars and their adjustments */ - /* FIXME : The step_inc, page_inc, and page_size should be related to the page size, not 1 */ sheet_view->va = gtk_adjustment_new (0.0, 0.0, sheet->max_row_used, 1.0, 1.0, 1.0); sheet_view->ha = gtk_adjustment_new (0.0, 0.0, sheet->max_col_used, 1.0, 1.0, 1.0); sheet_view->hs = gtk_hscrollbar_new (GTK_ADJUSTMENT (sheet_view->ha)); diff --git a/src/sheet-view.h b/src/sheet-view.h index 0df82010833c09fb370e0960b27421af2aeb4cf9..5764caa2a33ce6a21bb97595884cabfd402a5318 100644 --- a/src/sheet-view.h +++ b/src/sheet-view.h @@ -73,6 +73,8 @@ void sheet_view_set_header_visibility (SheetView *sheet_view, gboolean col_headers_visible, gboolean row_headers_visible); +void sheet_view_scrollbar_config (SheetView const *sheet_view); + typedef struct { GtkTableClass parent_class; } SheetViewClass; diff --git a/src/sheet.c b/src/sheet.c index 2e38f89fc701886e8088d2e313d546d315e91ab6..d63322adcae68bba8bc4e27440546e6dcf94a4b2 100644 --- a/src/sheet.c +++ b/src/sheet.c @@ -17,6 +17,7 @@ #include "number-match.h" #include "format.h" #include "clipboard.h" +#include "selection.h" #ifdef ENABLE_BONOBO # include #endif @@ -43,7 +44,7 @@ sheet_redraw_all (Sheet *sheet) } } -static void +void sheet_redraw_cols (Sheet *sheet) { GList *l; @@ -55,7 +56,7 @@ sheet_redraw_cols (Sheet *sheet) } } -static void +void sheet_redraw_rows (Sheet *sheet) { GList *l; @@ -835,20 +836,6 @@ sheet_row_get_distance (Sheet *sheet, int from_row, int to_row) return col_row_distance (sheet->rows_info, from_row, to_row, sheet->default_row_style.pixels); } -int -sheet_selection_equal (SheetSelection *a, SheetSelection *b) -{ - if (a->start_col != b->start_col) - return 0; - if (a->start_row != b->start_row) - return 0; - - if (a->end_col != b->end_col) - return 0; - if (a->end_row != b->end_row) - return 0; - return 1; -} void sheet_update_auto_expr (Sheet *sheet) @@ -878,21 +865,6 @@ sheet_update_auto_expr (Sheet *sheet) workbook_auto_expr_label_set (wb, _("Internal ERROR")); } -static const char * -sheet_get_selection_name (Sheet *sheet) -{ - SheetSelection *ss = sheet->selections->data; - static char buffer [10 + 2 * 4 * sizeof (int)]; - - if (ss->start_col == ss->end_col && ss->start_row == ss->end_row){ - return cell_name (ss->start_col, ss->start_row); - } else { - snprintf (buffer, sizeof (buffer), "%dLx%dC", - ss->end_row - ss->start_row + 1, - ss->end_col - ss->start_col + 1); - return buffer; - } -} void sheet_set_text (Sheet *sheet, int col, int row, const char *str) @@ -1102,7 +1074,7 @@ sheet_start_editing_at_cursor (Sheet *sheet, gboolean blankp, gboolean cursorp) * This routine is ran every time the selection has changed. It checks * what the status of various toolbar feedback controls should be */ -static void +void sheet_update_controls (Sheet *sheet) { GList *cells, *l; @@ -1168,204 +1140,6 @@ sheet_update_controls (Sheet *sheet) GINT_TO_POINTER(italic_first)); } -static void -sheet_selection_changed_hook (Sheet *sheet) -{ - sheet_update_auto_expr (sheet); - sheet_update_controls (sheet); - workbook_set_region_status (sheet->workbook, sheet_get_selection_name (sheet)); -} - -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) -{ - SheetSelection *ss; - GList *l; - - g_return_if_fail (sheet != NULL); - g_return_if_fail (IS_SHEET (sheet)); - - ss = g_new0 (SheetSelection, 1); - - ss->base_col = base_col; - ss->base_row = base_row; - - ss->start_col = start_col; - ss->end_col = end_col; - ss->start_row = start_row; - ss->end_row = end_row; - - sheet->selections = g_list_prepend (sheet->selections, ss); - - sheet_accept_pending_input (sheet); - sheet_load_cell_val (sheet); - - for (l = sheet->sheet_views; l; l = l->next){ - GnumericSheet *gsheet = GNUMERIC_SHEET_VIEW (l->data); - - gnumeric_sheet_set_selection (gsheet, ss); - } - sheet_redraw_selection (sheet, ss); - - sheet_redraw_cols (sheet); - sheet_redraw_rows (sheet); - - sheet_selection_changed_hook (sheet); -} - -/** - * If returns true selection is just one range. - * If returns false, range data: indeterminate - **/ -int -sheet_selection_first_range (Sheet *sheet, - int *base_col, int *base_row, - int *start_col, int *start_row, - int *end_col, int *end_row) -{ - SheetSelection *ss; - GList *l; - - g_return_val_if_fail (sheet != NULL, 0); - g_return_val_if_fail (IS_SHEET (sheet), 0); - - if (!sheet->selections) - return 0; - - l = g_list_first (sheet->selections); - if (!l || !l->data) - return 0; - - ss = l->data; - *base_col = ss->base_col; - *base_row = ss->base_row; - *start_col = ss->start_col; - *start_row = ss->start_row; - *end_col = ss->end_col; - *end_row = ss->end_row; - - if ((l = g_list_next (l))) - return 0; - return 1; -} - -void -sheet_selection_append (Sheet *sheet, int col, int row) -{ - sheet_selection_append_range (sheet, col, row, col, row, col, row); -} - -/** - * sheet_selection_extend_to: - * @sheet: the sheet - * @col: column that gets covered - * @row: row that gets covered - * - * This extends the selection to cover col, row - */ -void -sheet_selection_extend_to (Sheet *sheet, int col, int row) -{ - SheetSelection *ss, old_selection; - GList *l; - - g_return_if_fail (sheet != NULL); - g_return_if_fail (IS_SHEET (sheet)); - - g_assert (sheet->selections); - - ss = (SheetSelection *) sheet->selections->data; - - old_selection = *ss; - - 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; - } - - for (l = sheet->sheet_views; l; l = l->next){ - GnumericSheet *gsheet = GNUMERIC_SHEET_VIEW (l->data); - - gnumeric_sheet_set_selection (gsheet, ss); - } - - sheet_selection_changed_hook (sheet); - - sheet_redraw_selection (sheet, &old_selection); - sheet_redraw_selection (sheet, ss); - - if (ss->start_col != old_selection.start_col || - ss->end_col != old_selection.end_col || - ((ss->start_row == 0 && ss->end_row == SHEET_MAX_ROWS-1) ^ - (old_selection.start_row == 0 && - old_selection.end_row == SHEET_MAX_ROWS-1))) - sheet_redraw_cols (sheet); - - if (ss->start_row != old_selection.start_row || - ss->end_row != old_selection.end_row || - ((ss->start_col == 0 && ss->end_col == SHEET_MAX_COLS-1) ^ - (old_selection.start_col == 0 && - old_selection.end_col == SHEET_MAX_COLS-1))) - sheet_redraw_rows (sheet); -} - -/** - * sheet_select_all: - * Sheet: The sheet - * - * Selects all of the cells in the sheet - */ -void -sheet_select_all (Sheet *sheet) -{ - g_return_if_fail (sheet != NULL); - g_return_if_fail (IS_SHEET (sheet)); - - sheet_selection_reset_only (sheet); - sheet_make_cell_visible (sheet, 0, 0); - sheet_cursor_move (sheet, 0, 0, FALSE, FALSE); - sheet_selection_append_range (sheet, 0, 0, 0, 0, - SHEET_MAX_COLS-1, SHEET_MAX_ROWS-1); - - /* Queue redraws for columns and rows */ - sheet_redraw_rows (sheet); - sheet_redraw_cols (sheet); -} - -int -sheet_is_all_selected (Sheet *sheet) -{ - SheetSelection *ss; - GList *l; - - g_return_val_if_fail (sheet != NULL, FALSE); - g_return_val_if_fail (IS_SHEET (sheet), FALSE); - - for (l = sheet->selections; l != NULL; l = l->next){ - ss = l->data; - - if (ss->start_col == 0 && - ss->start_row == 0 && - ss->end_col == SHEET_MAX_COLS-1 && - ss->end_row == SHEET_MAX_ROWS-1) - return TRUE; - } - return FALSE; -} int sheet_col_selection_type (Sheet *sheet, int col) @@ -1670,230 +1444,6 @@ range_check_for_partial_array (Sheet *sheet, return valid; } -static void -sheet_selection_change (Sheet *sheet, SheetSelection *old, SheetSelection *new) -{ - GList *l; - - if (sheet_selection_equal (old, new)) - return; - - sheet_accept_pending_input (sheet); - sheet_redraw_selection (sheet, old); - sheet_redraw_selection (sheet, new); - sheet_selection_changed_hook (sheet); - - for (l = sheet->sheet_views; l; l = l->next){ - GnumericSheet *gsheet = GNUMERIC_SHEET_VIEW (l->data); - - gnumeric_sheet_set_selection (gsheet, new); - } - - if (new->start_col != old->start_col || - new->end_col != old->end_col || - ((new->start_row == 0 && new->end_row == SHEET_MAX_ROWS-1) ^ - (old->start_row == 0 && - old->end_row == SHEET_MAX_ROWS-1))) - sheet_redraw_cols (sheet); - - if (new->start_row != old->start_row || - new->end_row != old->end_row || - ((new->start_col == 0 && new->end_col == SHEET_MAX_COLS-1) ^ - (old->start_col == 0 && - old->end_col == SHEET_MAX_COLS-1))) - sheet_redraw_rows (sheet); -} - -/** - * sheet_selection_extend_horizontal: - * - * @sheet: The Sheet * - * @count: units to extend the selection horizontally - * @jump_to_boundaries : Jump to range boundaries. - */ -void -sheet_selection_extend_horizontal (Sheet *sheet, int n, gboolean jump_to_boundaries) -{ - SheetSelection *ss; - SheetSelection old_selection; - - g_return_if_fail (sheet != NULL); - g_return_if_fail (IS_SHEET (sheet)); - - ss = (SheetSelection *)sheet->selections->data; - old_selection = *ss; - - if (ss->base_col < ss->end_col) - ss->end_col = - sheet_find_boundary_horizontal (sheet, - ss->end_col, ss->end_row, - n, jump_to_boundaries); - else if (ss->base_col > ss->start_col || n < 0) - ss->start_col = - sheet_find_boundary_horizontal (sheet, - ss->start_col, ss->start_row, - n, jump_to_boundaries); - else - ss->end_col = - sheet_find_boundary_horizontal (sheet, - ss->end_col, ss->end_row, - n, jump_to_boundaries); - - if (ss->end_col < ss->start_col) { - int const tmp = ss->start_col; - ss->start_col = ss->end_col; - ss->end_col = tmp; - } - sheet_selection_change (sheet, &old_selection, ss); -} - -/* - * sheet_selection_extend_vertical - * @sheet: The Sheet * - * @n: units to extend the selection vertically - * @jump_to_boundaries : Jump to range boundaries. - */ -void -sheet_selection_extend_vertical (Sheet *sheet, int n, gboolean jump_to_boundaries) -{ - SheetSelection *ss; - SheetSelection old_selection; - - g_return_if_fail (sheet != NULL); - g_return_if_fail (IS_SHEET (sheet)); - - ss = (SheetSelection *)sheet->selections->data; - old_selection = *ss; - - if (ss->base_row < ss->end_row) - ss->end_row = - sheet_find_boundary_vertical (sheet, - ss->end_col, ss->end_row, - n, jump_to_boundaries); - else if (ss->base_row > ss->start_row || n < 0) - ss->start_row = - sheet_find_boundary_vertical (sheet, - ss->start_col, ss->start_row, - n, jump_to_boundaries); - else - ss->end_row = - sheet_find_boundary_vertical (sheet, - ss->end_col, ss->end_row, - n, jump_to_boundaries); - - if (ss->end_row < ss->start_row) { - int const tmp = ss->start_row; - ss->start_row = ss->end_row; - ss->end_row = tmp; - } - sheet_selection_change (sheet, &old_selection, ss); -} - -void -sheet_selection_set (Sheet *sheet, int start_col, int start_row, int end_col, int end_row) -{ - SheetSelection *ss; - SheetSelection old_selection; - - g_return_if_fail (sheet != NULL); - g_return_if_fail (IS_SHEET (sheet)); - - ss = (SheetSelection *)sheet->selections->data; - old_selection = *ss; - - ss->start_row = start_row; - ss->end_row = end_row; - ss->start_col = start_col; - ss->end_col = end_col; - - sheet_selection_change (sheet, &old_selection, ss); -} - -/** - * sheet_selections_free - * @sheet: the sheet - * - * Releases the selection associated with this sheet - */ -static void -sheet_selections_free (Sheet *sheet) -{ - GList *list; - - for (list = sheet->selections; list; list = list->next){ - SheetSelection *ss = list->data; - g_free (ss); - } - - g_list_free (sheet->selections); - sheet->selections = NULL; -} - -/* - * sheet_selection_reset - * sheet: The sheet - * - * Clears all of the selection ranges. - * Warning: This does not set a new selection, this should - * be taken care on the calling routine. - */ -void -sheet_selection_reset_only (Sheet *sheet) -{ - GList *list; - - g_return_if_fail (sheet != NULL); - g_return_if_fail (IS_SHEET (sheet)); - - for (list = sheet->selections; list; list = list->next){ - SheetSelection *ss = list->data; - - sheet_redraw_selection (sheet, ss); - } - sheet_selections_free (sheet); - - sheet->walk_info.current = NULL; - - /* Redraw column bar */ - sheet_redraw_cols (sheet); - - /* Redraw the row bar */ - sheet_redraw_rows (sheet); -} - -/** - * sheet_selection_reset: - * sheet: The sheet - * - * Clears all of the selection ranges and resets it to a - * selection that only covers the cursor - */ -void -sheet_selection_reset (Sheet *sheet) -{ - g_return_if_fail (sheet != NULL); - g_return_if_fail (IS_SHEET (sheet)); - - sheet_selection_reset_only (sheet); - sheet_selection_append (sheet, sheet->cursor_col, sheet->cursor_row); -} - -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; -} - /* * walk_boundaries: implements the decisions for walking a region * returns TRUE if the cursor left the boundary region @@ -2046,96 +1596,6 @@ sheet_selection_walk_step (Sheet *sheet, int forward, int horizontal, return TRUE; } -/* - * assemble_cell_list: A callback for sheet_cell_foreach_range - * intented to assemble a list of cells in a region. - * - * The closure parameter should be a pointer to a GList. - */ -static Value * -assemble_cell_list (Sheet *sheet, int col, int row, Cell *cell, void *user_data) -{ - GList **l = (GList **) user_data; - - *l = g_list_prepend (*l, cell); - return NULL; -} - -CellList * -sheet_selection_to_list (Sheet *sheet) -{ - GList *selections; - CellList *list; - - g_return_val_if_fail (sheet != NULL, NULL); - g_return_val_if_fail (IS_SHEET (sheet), NULL); - g_return_val_if_fail (sheet->selections, NULL); - - list = NULL; - for (selections = sheet->selections; selections; selections = selections->next){ - SheetSelection *ss = selections->data; - - sheet_cell_foreach_range ( - sheet, TRUE, - ss->start_col, ss->start_row, - ss->end_col, ss->end_row, - assemble_cell_list, &list); - } - - return list; -} - -static void -reference_append (GString *result_str, int col, int row) -{ - char *row_string = g_strdup_printf ("%d", row); - - g_string_append_c (result_str, '$'); - g_string_append (result_str, col_name (col)); - g_string_append_c (result_str, '$'); - g_string_append (result_str, row_string); - - g_free (row_string); -} - -char * -sheet_selection_to_string (Sheet *sheet, gboolean include_sheet_name_prefix) -{ - GString *result_str; - GList *selections; - char *result; - - g_return_val_if_fail (sheet != NULL, NULL); - g_return_val_if_fail (IS_SHEET (sheet), NULL); - g_return_val_if_fail (sheet->selections, NULL); - - result_str = g_string_new (""); - for (selections = sheet->selections; selections; selections = selections->next){ - SheetSelection *ss = selections->data; - - if (*result_str->str) - g_string_append_c (result_str, ','); - - if (include_sheet_name_prefix){ - g_string_append_c (result_str, '\''); - g_string_append (result_str, sheet->name); - g_string_append (result_str, "'!"); - } - - if ((ss->start_col != ss->end_col) || - (ss->start_row != ss->end_row)){ - reference_append (result_str, ss->start_col, ss->end_row); - g_string_append_c (result_str, ':'); - reference_append (result_str, ss->end_col, ss->end_row); - } else - reference_append (result_str, ss->start_col, ss->start_row); - } - - result = result_str->str; - g_string_free (result_str, FALSE); - return result; -} - /** * sheet_col_get: * @@ -2722,7 +2182,9 @@ sheet_destroy (Sheet *sheet) if (sheet->objects) { g_warning ("Reminder: need to destroy SheetObjects"); } - sheet_selections_free (sheet); + + sheet_selection_free (sheet); + g_free (sheet->name); for (l = sheet->sheet_views; l; l = l->next){ @@ -2829,23 +2291,6 @@ sheet_clear_region (Sheet *sheet, int start_col, int start_row, int end_col, int g_list_free (cb.l); } -void -sheet_selection_clear (Sheet *sheet) -{ - GList *l; - - g_return_if_fail (sheet != NULL); - g_return_if_fail (IS_SHEET (sheet)); - - for (l = sheet->selections; l; l = l->next){ - SheetSelection *ss = l->data; - - sheet_clear_region (sheet, - ss->start_col, ss->start_row, - ss->end_col, ss->end_row); - } -} - static Value * clear_cell_content (Sheet *sheet, int col, int row, Cell *cell, void *user_data) { @@ -2884,29 +2329,6 @@ sheet_clear_region_content (Sheet *sheet, int start_col, int start_row, int end_ workbook_recalc (sheet->workbook); } -/** - * sheet_selection_clear_content: - * @sheet: The sheet where we operate - * - * Removes the contents of all the cells in the current selection. - **/ -void -sheet_selection_clear_content (Sheet *sheet) -{ - GList *l; - - g_return_if_fail (sheet != NULL); - g_return_if_fail (IS_SHEET (sheet)); - - for (l = sheet->selections; l; l = l->next){ - SheetSelection *ss = l->data; - - sheet_clear_region_content (sheet, - ss->start_col, ss->start_row, - ss->end_col, ss->end_row); - } -} - static Value * clear_cell_comments (Sheet *sheet, int col, int row, Cell *cell, void *user_data) { @@ -2942,29 +2364,6 @@ sheet_clear_region_comments (Sheet *sheet, int start_col, int start_row, int end clear_cell_comments, NULL); } -/** - * sheet_selection_clear_comments: - * @sheet: The sheet where we operate - * - * Removes all of the comments on the range of selected cells. - **/ -void -sheet_selection_clear_comments (Sheet *sheet) -{ - GList *l; - - g_return_if_fail (sheet != NULL); - g_return_if_fail (IS_SHEET (sheet)); - - for (l = sheet->selections; l; l = l->next){ - SheetSelection *ss = l->data; - - sheet_clear_region_comments (sheet, - ss->start_col, ss->start_row, - ss->end_col, ss->end_row); - } -} - static Value * clear_cell_format (Sheet *sheet, int col, int row, Cell *cell, void *user_data) { @@ -2989,136 +2388,6 @@ sheet_clear_region_formats (Sheet *sheet, int start_col, int start_row, int end_ clear_cell_format, NULL); } -void -sheet_selection_clear_formats (Sheet *sheet) -{ - GList *l; - - g_return_if_fail (sheet != NULL); - g_return_if_fail (IS_SHEET (sheet)); - - for (l = sheet->selections; l; l = l->next){ - SheetSelection *ss = l->data; - - sheet_clear_region_formats (sheet, - ss->start_col, ss->start_row, - ss->end_col, ss->end_row); - } -} - -gboolean -sheet_verify_selection_simple (Sheet *sheet, const char *command_name) -{ - char *msg; - - if (g_list_length (sheet->selections) == 1) - return TRUE; - - msg = g_strconcat ( - _("The command `"), - command_name, - _("' cannot be performed with multiple selections"), NULL); - gnumeric_notice (sheet->workbook, GNOME_MESSAGE_BOX_ERROR, msg); - g_free (msg); - - return FALSE; -} - -gboolean -sheet_selection_copy (Sheet *sheet) -{ - SheetSelection *ss; - g_return_val_if_fail (sheet != NULL, FALSE); - g_return_val_if_fail (IS_SHEET (sheet), FALSE); - g_return_val_if_fail (sheet->selections, FALSE); - - if (!sheet_verify_selection_simple (sheet, _("copy"))) - return FALSE; - - ss = sheet->selections->data; - - if (sheet->workbook->clipboard_contents) - clipboard_release (sheet->workbook->clipboard_contents); - - sheet->workbook->clipboard_contents = clipboard_copy_cell_range ( - sheet, - ss->start_col, ss->start_row, - ss->end_col, ss->end_row, FALSE); - - return TRUE; -} - -gboolean -sheet_selection_cut (Sheet *sheet) -{ - SheetSelection *ss; - - g_return_val_if_fail (sheet != NULL, FALSE); - g_return_val_if_fail (IS_SHEET (sheet), FALSE); - g_return_val_if_fail (sheet->selections, FALSE); - - if (!sheet_verify_selection_simple (sheet, _("cut"))) - return FALSE; - - ss = sheet->selections->data; - - if (sheet->workbook->clipboard_contents) - clipboard_release (sheet->workbook->clipboard_contents); - - sheet->workbook->clipboard_contents = clipboard_copy_cell_range ( - sheet, - ss->start_col, ss->start_row, - ss->end_col, ss->end_row, TRUE); - - sheet_clear_region (sheet, ss->start_col, ss->start_row, ss->end_col, ss->end_row); - - return TRUE; -} - -static gboolean -find_a_clipboard (Workbook *wb, gpointer data) -{ - CellRegion **cr = data; - - if (wb->clipboard_contents){ - *cr = wb->clipboard_contents; - return FALSE; - } - - return TRUE; -} - -static CellRegion * -find_workbook_with_clipboard (Sheet *sheet) -{ - CellRegion *cr = NULL; - - if (sheet->workbook->clipboard_contents) - return sheet->workbook->clipboard_contents; - - workbook_foreach (find_a_clipboard, &cr); - - return cr; -} - -void -sheet_selection_paste (Sheet *sheet, int dest_col, int dest_row, int paste_flags, guint32 time) -{ - CellRegion *content; - - g_return_if_fail (sheet != NULL); - g_return_if_fail (IS_SHEET (sheet)); - g_return_if_fail (sheet->selections); - - content = find_workbook_with_clipboard (sheet); - - if (content) - if (!sheet_verify_selection_simple (sheet, _("paste"))) - return; - - clipboard_paste_region (content, sheet, dest_col, dest_row, paste_flags, time); -} - static void sheet_move_column (Sheet *sheet, ColRowInfo *ci, int new_column) { diff --git a/src/sheet.h b/src/sheet.h index 11f09236d37dd12c51eb7747e511959143a92bc7..feb48b7fb1ecd624a215f84a0b648e663b12b740 100644 --- a/src/sheet.h +++ b/src/sheet.h @@ -29,6 +29,12 @@ typedef struct { int row; } ParsePosition; +typedef struct { + int base_col, base_row; + int start_col, start_row; + int end_col, end_row; +} SheetSelection; + #ifdef ENABLE_BONOBO # include #endif @@ -55,12 +61,6 @@ typedef struct { Style *style; } StyleRegion; -typedef struct { - int base_col, base_row; - int start_col, start_row; - int end_col, end_row; -} SheetSelection; - typedef enum { /* Normal editing mode of the Sheet */ SHEET_MODE_SHEET, @@ -167,49 +167,6 @@ void sheet_cursor_move (Sheet *sheet, int col, int row, gboolean clear_selection, gboolean add_dest_to_selection); void sheet_make_cell_visible (Sheet *sheet, int col, int row); -/* Selection management */ -void sheet_select_all (Sheet *sheet); -int sheet_is_all_selected (Sheet *sheet); -void sheet_selection_append (Sheet *sheet, int col, int row); -void sheet_selection_extend_to (Sheet *sheet, int col, int row); -void sheet_selection_set (Sheet *sheet, - int start_col, int start_row, - int end_col, int end_row); -void sheet_selection_reset (Sheet *sheet); -void sheet_selection_reset_only (Sheet *sheet); -int sheet_selection_equal (SheetSelection *a, SheetSelection *b); -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); -int sheet_selection_first_range (Sheet *sheet, - int *base_col, int *base_row, - int *start_col, int *start_row, - int *end_col, int *end_row); -CellList *sheet_selection_to_list (Sheet *sheet); -char *sheet_selection_to_string (Sheet *sheet, gboolean include_sheet_name_prefix); - -/* Operations on the selection */ -void sheet_selection_clear (Sheet *sheet); -void sheet_selection_clear_content (Sheet *sheet); -void sheet_selection_clear_comments (Sheet *sheet); -void sheet_selection_clear_formats (Sheet *sheet); - -/* Cut/Copy/Paste on the workbook selection */ -gboolean sheet_selection_copy (Sheet *sheet); -gboolean sheet_selection_cut (Sheet *sheet); -void sheet_selection_paste (Sheet *sheet, - int dest_col, int dest_row, - int paste_flags, guint32 time32); -int sheet_selection_walk_step (Sheet *sheet, - int forward, int horizontal, - int current_col, int current_row, - int *new_col, int *new_row); -void sheet_selection_extend_horizontal (Sheet *sheet, int count, gboolean jump_to_boundaries); -void sheet_selection_extend_vertical (Sheet *sheet, int count, gboolean jump_to_boundaries); -int sheet_selection_is_cell_selected (Sheet *sheet, int col, int row); -gboolean sheet_verify_selection_simple (Sheet *sheet, const char *command_name); - /* Cell management */ void sheet_set_text (Sheet *sheet, int col, int row, const char *str); @@ -305,6 +262,8 @@ void sheet_compute_visible_ranges (Sheet *sheet); void sheet_redraw_cell_region (Sheet *sheet, int start_col, int start_row, int end_col, int end_row); +void sheet_redraw_cols (Sheet *sheet); +void sheet_redraw_rows (Sheet *sheet); void sheet_redraw_selection (Sheet *sheet, SheetSelection *ss); void sheet_redraw_all (Sheet *sheet); @@ -340,6 +299,7 @@ void sheet_style_attach (Sheet *sheet, Style *style); Sheet *sheet_lookup_by_name (Workbook *wb, const char *name); +void sheet_update_controls (Sheet *sheet); /* * Sheet visual editing */ @@ -391,4 +351,3 @@ void sheet_insert_object (Sheet *sheet, char *repoid); void sheet_corba_setup (Sheet *); void sheet_corba_shutdown (Sheet *); #endif /* GNUMERIC_SHEET_H */ - diff --git a/src/workbook.c b/src/workbook.c index 262b49c5042a48c02bfc5878a4b46a528b84b269..a02a152350e0cfb0f7d253d2fe2abc0b947de0f0 100644 --- a/src/workbook.c +++ b/src/workbook.c @@ -25,6 +25,7 @@ #include "widgets/widget-editable-label.h" #include "print-info.h" #include "ranges.h" +#include "selection.h" #ifdef ENABLE_BONOBO #include