[gnumeric] Implement ctrl-click cell deselection. [#610696]
- From: Andreas J. Guelzow <guelzow src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnumeric] Implement ctrl-click cell deselection. [#610696]
- Date: Wed, 30 Nov 2011 17:07:00 +0000 (UTC)
commit db6d71442b0bf92061acdd107285e477322c17ba
Author: Andreas J Guelzow <aguelzow pyrshep ca>
Date: Wed Nov 30 10:02:40 2011 -0700
Implement ctrl-click cell deselection. [#610696]
2011-11-30 Andreas J. Guelzow <aguelzow pyrshep ca>
* src/cmd-edit.c: adjust calls to sv_selection_add_full and
sv_selection_add_pos throughout
(sv_select_cur_inputs): fix leak
* src/commands.c (cmd_colrow_hide_correct_selection): adjust
calls to sv_selection_add_full
* src/item-grid.c (item_grid_button_released): simplify selection,
adjust call to sv_selection_add_pos
* src/selection.c (sv_selection_add_pos): add argument
(sv_selection_add_full): add argument
(sv_selection_simplified_free): new
(sv_selection_simplify): new
(sv_selection_calc_simplification): new, use it throughout instead of
accessing sv->selection directly
(sheet_selection_set_internal): redraw headers if the selection mode
is not just ADD
(sv_selection_free): use g_slist_free_full
* src/selection.h (GnmSelectionMode): new
(sv_selection_add_pos): add argument
(sv_selection_add_full): add argument
(sv_selection_simplified_free): new
(sv_selection_simplify): new
* src/sheet-control-gui.c: adjust calls to sv_selection_add_full and
sv_selection_add_pos throughout
* src/sheet-view.c (sv_real_dispose): dispose of simplified selection
(sheet_view_init): initialize selection fields
* src/sheet-view.h: add fields
* src/sheet.c (gnm_sheet_resize_main): adjust call to sv_selection_add_pos
* src/test-pango.c (cb_exercise_pango): adjust call to sv_selection_add_full
* src/workbook-view.c (wb_view_selection_desc): use selection_first_range
rather than accessing the fields directly
2011-11-30 Andreas J. Guelzow <aguelzow pyrshep ca>
* excel-xml-read.c (xl_xml_selection): adjust call to
sv_selection_add_full
* ms-excel-read.c (excel_read_SELECTION): adjust calls to
sv_selection_add_full and sv_selection_add_pos
ChangeLog | 33 +++++++
NEWS | 3 +-
plugins/excel/ChangeLog | 7 ++
plugins/excel/excel-xml-read.c | 10 ++-
plugins/excel/ms-excel-read.c | 6 +-
src/cmd-edit.c | 47 ++++++-----
src/commands.c | 6 +-
src/item-grid.c | 10 ++-
src/selection.c | 185 +++++++++++++++++++++++++++++++++-------
src/selection.h | 13 +++-
src/sheet-control-gui.c | 20 +++--
src/sheet-view.c | 6 +-
src/sheet-view.h | 3 +
src/sheet.c | 6 +-
src/test-pango.c | 3 +-
src/workbook-view.c | 2 +-
16 files changed, 279 insertions(+), 81 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 819dac5..8964fc5 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,36 @@
+2011-11-30 Andreas J. Guelzow <aguelzow pyrshep ca>
+
+ * src/cmd-edit.c: adjust calls to sv_selection_add_full and
+ sv_selection_add_pos throughout
+ (sv_select_cur_inputs): fix leak
+ * src/commands.c (cmd_colrow_hide_correct_selection): adjust
+ calls to sv_selection_add_full
+ * src/item-grid.c (item_grid_button_released): simplify selection,
+ adjust call to sv_selection_add_pos
+ * src/selection.c (sv_selection_add_pos): add argument
+ (sv_selection_add_full): add argument
+ (sv_selection_simplified_free): new
+ (sv_selection_simplify): new
+ (sv_selection_calc_simplification): new, use it throughout instead of
+ accessing sv->selection directly
+ (sheet_selection_set_internal): redraw headers if the selection mode
+ is not just ADD
+ (sv_selection_free): use g_slist_free_full
+ * src/selection.h (GnmSelectionMode): new
+ (sv_selection_add_pos): add argument
+ (sv_selection_add_full): add argument
+ (sv_selection_simplified_free): new
+ (sv_selection_simplify): new
+ * src/sheet-control-gui.c: adjust calls to sv_selection_add_full and
+ sv_selection_add_pos throughout
+ * src/sheet-view.c (sv_real_dispose): dispose of simplified selection
+ (sheet_view_init): initialize selection fields
+ * src/sheet-view.h: add fields
+ * src/sheet.c (gnm_sheet_resize_main): adjust call to sv_selection_add_pos
+ * src/test-pango.c (cb_exercise_pango): adjust call to sv_selection_add_full
+ * src/workbook-view.c (wb_view_selection_desc): use selection_first_range
+ rather than accessing the fields directly
+
2011-11-28 Andreas J. Guelzow <aguelzow pyrshep ca>
* src/wbc-gtk.c (wbc_gtk_create_status_area): force auto expression
diff --git a/NEWS b/NEWS
index c72641c..13567aa 100644
--- a/NEWS
+++ b/NEWS
@@ -1,7 +1,8 @@
Gnumeric 1.11.2
Andreas:
- * Colour the range expressions to match the range cursor.
+ * Colour the range expressions to match the range cursor. [#632156]
+ * Implement ctrl-click cell deselection. [#610696]
--------------------------------------------------------------------------
diff --git a/plugins/excel/ChangeLog b/plugins/excel/ChangeLog
index f85cb2e..0608dce 100644
--- a/plugins/excel/ChangeLog
+++ b/plugins/excel/ChangeLog
@@ -1,3 +1,10 @@
+2011-11-30 Andreas J. Guelzow <aguelzow pyrshep ca>
+
+ * excel-xml-read.c (xl_xml_selection): adjust call to
+ sv_selection_add_full
+ * ms-excel-read.c (excel_read_SELECTION): adjust calls to
+ sv_selection_add_full and sv_selection_add_pos
+
2011-11-27 Morten Welinder <terra gnome org>
* Release 1.11.1
diff --git a/plugins/excel/excel-xml-read.c b/plugins/excel/excel-xml-read.c
index 71cf71b..36dde1d 100644
--- a/plugins/excel/excel-xml-read.c
+++ b/plugins/excel/excel-xml-read.c
@@ -908,10 +908,12 @@ xl_xml_selection (GsfXMLIn *xin, G_GNUC_UNUSED GsfXMLBlob *blob)
end = rangeref_parse (&rr, ptr, &pp, gnm_conventions_xls_r1c1);
if (end != ptr) {
range_init_rangeref (&r, &rr);
- sv_selection_add_full (sv,
- state->pos.col, state->pos.row,
- r.start.col, r.start.row,
- r.end.col, r.end.row);
+ sv_selection_add_full
+ (sv,
+ state->pos.col, state->pos.row,
+ r.start.col, r.start.row,
+ r.end.col, r.end.row,
+ GNM_SELECTION_MODE_ADD);
if (*end != ',')
break;
diff --git a/plugins/excel/ms-excel-read.c b/plugins/excel/ms-excel-read.c
index 07c9494..23a2a58 100644
--- a/plugins/excel/ms-excel-read.c
+++ b/plugins/excel/ms-excel-read.c
@@ -4504,12 +4504,14 @@ excel_read_SELECTION (BiffQuery *q, ExcelReadSheet *esheet)
sv_selection_add_full (sv,
tmp.col, tmp.row,
r.start.col, r.start.row,
- r.end.col, r.end.row);
+ r.end.col, r.end.row,
+ GNM_SELECTION_MODE_ADD);
}
if (sv->selections == NULL) {
/* See bug 632050 */
- sv_selection_add_pos (sv, 0, 0);
+ sv_selection_add_pos (sv, 0, 0,
+ GNM_SELECTION_MODE_ADD);
d (5, g_printerr ("No selection\n"););
}
diff --git a/src/cmd-edit.c b/src/cmd-edit.c
index 5d14a50..51d404f 100644
--- a/src/cmd-edit.c
+++ b/src/cmd-edit.c
@@ -1,4 +1,4 @@
-/* vim: set sw=8: */
+/* vim: set sw=8: -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/*
* cmd-edit.c: Various commands to be used by the edit menu.
*
@@ -55,9 +55,11 @@ sv_select_cur_row (SheetView *sv)
if (sel != NULL) {
GnmRange r = *sel;
sv_selection_reset (sv);
- sv_selection_add_full (sv,
- sv->edit_pos.col, sv->edit_pos.row,
- 0, r.start.row, gnm_sheet_get_last_col (sv->sheet), r.end.row);
+ sv_selection_add_full
+ (sv,
+ sv->edit_pos.col, sv->edit_pos.row,
+ 0, r.start.row, gnm_sheet_get_last_col (sv->sheet), r.end.row,
+ GNM_SELECTION_MODE_ADD);
sheet_update (sv->sheet);
}
}
@@ -75,9 +77,11 @@ sv_select_cur_col (SheetView *sv)
if (sel != NULL) {
GnmRange r = *sel;
sv_selection_reset (sv);
- sv_selection_add_full (sv,
- sv->edit_pos.col, sv->edit_pos.row,
- r.start.col, 0, r.end.col, gnm_sheet_get_last_row (sv->sheet));
+ sv_selection_add_full
+ (sv,
+ sv->edit_pos.col, sv->edit_pos.row,
+ r.start.col, 0, r.end.col, gnm_sheet_get_last_row (sv->sheet),
+ GNM_SELECTION_MODE_ADD);
sheet_update (sv->sheet);
}
}
@@ -101,7 +105,8 @@ sv_select_cur_array (SheetView *sv)
/* leave the edit pos where it is, select the entire array. */
sv_selection_reset (sv);
sv_selection_add_full (sv, c, r,
- a.start.col, a.start.row, a.end.col, a.end.row);
+ a.start.col, a.start.row, a.end.col, a.end.row,
+ GNM_SELECTION_MODE_ADD);
sheet_update (sv->sheet);
}
@@ -161,7 +166,8 @@ sv_select_cur_depends (SheetView *sv)
/* Short circuit */
if (g_list_length (deps) == 1) {
GnmCell *cell = deps->data;
- sv_selection_add_pos (sv, cell->pos.col, cell->pos.row);
+ sv_selection_add_pos (sv, cell->pos.col, cell->pos.row,
+ GNM_SELECTION_MODE_ADD);
} else {
GnmRange *cur = NULL;
ptr = NULL;
@@ -253,18 +259,17 @@ sv_select_cur_inputs (SheetView *sv)
GnmRangeRef const *r = value_get_rangeref (v);
#warning "FIXME: What do we do in these 3D cases?"
- if (r->a.sheet != r->b.sheet)
- continue;
- if (r->a.sheet != NULL && r->a.sheet != sv->sheet)
- continue;
-
- sv_selection_add_full (sv,
- gnm_cellref_get_col (&r->a, &ep),
- gnm_cellref_get_row (&r->a, &ep),
- gnm_cellref_get_col (&r->a, &ep),
- gnm_cellref_get_row (&r->a, &ep),
- gnm_cellref_get_col (&r->b, &ep),
- gnm_cellref_get_row (&r->b, &ep));
+ if ((r->a.sheet == r->b.sheet) &&
+ (r->a.sheet == NULL || r->a.sheet == sv->sheet)) {
+ gint row, col;
+ row = gnm_cellref_get_row (&r->a, &ep);
+ col = gnm_cellref_get_col (&r->a, &ep);
+ sv_selection_add_full
+ (sv, col, row, col, row,
+ gnm_cellref_get_col (&r->b, &ep),
+ gnm_cellref_get_row (&r->b, &ep),
+ GNM_SELECTION_MODE_ADD);
+ }
value_release (v);
}
g_slist_free (ranges);
diff --git a/src/commands.c b/src/commands.c
index 1834618..abcd85e 100644
--- a/src/commands.c
+++ b/src/commands.c
@@ -2235,10 +2235,12 @@ cmd_colrow_hide_correct_selection (CmdColRowHide *me, WorkbookControl *wbc)
sv_selection_reset (sv);
if (me->is_cols)
sv_selection_add_full (sv, y, x, y, 0,
- y, gnm_sheet_get_last_row (sheet));
+ y, gnm_sheet_get_last_row (sheet),
+ GNM_SELECTION_MODE_ADD);
else
sv_selection_add_full (sv, y, x, 0, x,
- gnm_sheet_get_last_col (sheet), x);
+ gnm_sheet_get_last_col (sheet), x,
+ GNM_SELECTION_MODE_ADD);
}
#endif
}
diff --git a/src/item-grid.c b/src/item-grid.c
index fee3c9c..fbb6b50 100644
--- a/src/item-grid.c
+++ b/src/item-grid.c
@@ -807,7 +807,7 @@ plain_draw : /* a quick hack to deal with 142267 */
}
static double
-item_grid_distance (GocItem *item, double x, double y,
+item_grid_distance (GocItem *item, G_GNUC_UNUSED double x, G_GNUC_UNUSED double y,
GocItem **actual_item)
{
*actual_item = item;
@@ -930,7 +930,10 @@ item_grid_button_pressed (GocItem *item, int button, double x_, double y_)
if (event->button != 1 || !(event->state & GDK_SHIFT_MASK) ||
sv->selections == NULL) {
- sv_selection_add_pos (sv, pos.col, pos.row);
+ sv_selection_add_pos (sv, pos.col, pos.row,
+ (already_selected && (event->state & GDK_CONTROL_MASK)) ?
+ GNM_SELECTION_MODE_REMOVE :
+ GNM_SELECTION_MODE_ADD);
sv_make_cell_visible (sv, pos.col, pos.row, FALSE);
} else if (event->button != 2)
sv_selection_extend_to (sv, pos.col, pos.row);
@@ -1099,6 +1102,7 @@ item_grid_button_released (GocItem *item, int button, G_GNUC_UNUSED double x_, G
/* sheet->edit_pos.col, sheet->edit_pos.row, FALSE); */
/* Fall through */
case ITEM_GRID_SELECTING_CELL_RANGE :
+ sv_selection_simplify (scg_view (scg));
wb_view_selection_desc (
wb_control_view (scg_wbc (scg)), TRUE, NULL);
break;
@@ -1170,7 +1174,7 @@ item_grid_init (ItemGrid *ig)
static void
item_grid_set_property (GObject *obj, guint param_id,
- GValue const *value, GParamSpec *pspec)
+ GValue const *value, G_GNUC_UNUSED GParamSpec *pspec)
{
ItemGrid *ig = ITEM_GRID (obj);
GnmRange const *r;
diff --git a/src/selection.c b/src/selection.c
index 6fc6a19..112bcff 100644
--- a/src/selection.c
+++ b/src/selection.c
@@ -32,6 +32,63 @@
#include "cell.h"
/**
+ * sv_selection_calc_simplification:
+ * @sv :
+ * @mode:
+ *
+ * Create the simplified seelction list if necessary
+ *
+ * Returns the simplified version
+ **/
+
+static GSList *
+sv_selection_calc_simplification (SheetView const *sv)
+{
+ GSList *simp = NULL, *ptr;
+ GnmRange *r_rm;
+ SheetView *sv_mod = (SheetView *)sv;
+
+ if (sv->selection_mode != GNM_SELECTION_MODE_REMOVE)
+ return sv->selections;
+ if (sv->selections_simplified != NULL)
+ return sv->selections_simplified;
+
+ g_return_val_if_fail (sv->selections != NULL &&
+ sv->selections->data != NULL,
+ sv->selections);
+
+ ptr = sv->selections->next;
+ r_rm = sv->selections->data;
+
+ for (ptr = sv->selections->next; ptr != NULL; ptr = ptr->next) {
+ GnmRange *r = ptr->data;
+ if (range_overlap (r_rm, r)) {
+ GSList *pieces;
+ if (range_contained (r, r_rm))
+ continue;
+ pieces = range_split_ranges (r_rm, r);
+ g_free (pieces->data);
+ pieces = g_slist_delete_link (pieces, pieces);
+ simp = g_slist_concat (pieces, simp);
+ } else {
+ GnmRange *r_new = g_new (GnmRange, 1);
+ *r_new = *r;
+ simp = g_slist_prepend (simp, r_new);
+ }
+ }
+
+ if (simp == NULL) {
+ GnmRange *r_new = g_new (GnmRange, 1);
+ range_init_cellpos (r_new, &sv->edit_pos);
+ simp = g_slist_prepend (simp, r_new);
+ }
+
+ sv_mod->selections_simplified = g_slist_reverse (simp);
+
+ return sv->selections_simplified;
+}
+
+/**
* sv_is_singleton_selected:
* @sv :
*
@@ -42,6 +99,7 @@
GnmCellPos const *
sv_is_singleton_selected (SheetView const *sv)
{
+#warning FIXME Should we be using the selection rather than the cursor?
if (sv->cursor.move_corner.col == sv->cursor.base_corner.col &&
sv->cursor.move_corner.row == sv->cursor.base_corner.row)
return &sv->cursor.move_corner;
@@ -62,7 +120,8 @@ sv_is_pos_selected (SheetView const *sv, int col, int row)
GSList *ptr;
GnmRange const *sr;
- for (ptr = sv->selections; ptr != NULL ; ptr = ptr->next) {
+ for (ptr = sv_selection_calc_simplification (sv);
+ ptr != NULL ; ptr = ptr->next) {
sr = ptr->data;
if (range_contains (sr, col, row))
return TRUE;
@@ -83,7 +142,8 @@ sv_is_range_selected (SheetView const *sv, GnmRange const *r)
GSList *ptr;
GnmRange const *sr;
- for (ptr = sv->selections; ptr != NULL ; ptr = ptr->next){
+ for (ptr = sv_selection_calc_simplification (sv);
+ ptr != NULL ; ptr = ptr->next){
sr = ptr->data;
if (range_overlap (sr, r))
return TRUE;
@@ -105,7 +165,8 @@ sv_is_full_range_selected (SheetView const *sv, GnmRange const *r)
GSList *ptr;
GnmRange const *sr;
- for (ptr = sv->selections; ptr != NULL ; ptr = ptr->next) {
+ for (ptr = sv_selection_calc_simplification (sv);
+ ptr != NULL ; ptr = ptr->next) {
sr = ptr->data;
if (range_contained (r, sr))
return TRUE;
@@ -131,7 +192,11 @@ gboolean
sv_is_colrow_selected (SheetView const *sv, int colrow, gboolean is_col)
{
GSList *l;
- for (l = sv->selections; l != NULL; l = l->next) {
+
+ g_return_val_if_fail (IS_SHEET_VIEW (sv), FALSE);
+
+ for (l = sv_selection_calc_simplification (sv);
+ l != NULL; l = l->next) {
GnmRange const *ss = l->data;
if (is_col) {
@@ -166,7 +231,8 @@ sv_is_full_colrow_selected (SheetView const *sv, gboolean is_cols, int index)
g_return_val_if_fail (IS_SHEET_VIEW (sv), FALSE);
- for (l = sv->selections; l != NULL; l = l->next){
+ for (l = sv_selection_calc_simplification (sv);
+ l != NULL; l = l->next){
GnmRange const *r = l->data;
if (is_cols) {
if (r->start.row > 0 || r->end.row < gnm_sheet_get_last_row (sv->sheet))
@@ -203,7 +269,8 @@ sv_selection_col_type (SheetView const *sv, int col)
if (sv->selections == NULL)
return COL_ROW_NO_SELECTION;
- for (ptr = sv->selections; ptr != NULL; ptr = ptr->next) {
+ for (ptr = sv_selection_calc_simplification (sv);
+ ptr != NULL; ptr = ptr->next) {
sr = ptr->data;
if (sr->start.col > col || sr->end.col < col)
@@ -238,7 +305,8 @@ sv_selection_row_type (SheetView const *sv, int row)
if (sv->selections == NULL)
return COL_ROW_NO_SELECTION;
- for (ptr = sv->selections; ptr != NULL; ptr = ptr->next) {
+ for (ptr = sv_selection_calc_simplification (sv);
+ ptr != NULL; ptr = ptr->next) {
sr = ptr->data;
if (sr->start.row > row || sr->end.row < row)
@@ -429,6 +497,8 @@ sheet_selection_set_internal (SheetView *sv,
if (!just_add_it && range_equal (ss, &new_sel))
return;
+ sv_selection_simplified_free (sv);
+
old_sel = *ss;
*ss = new_sel;
@@ -460,8 +530,9 @@ sheet_selection_set_internal (SheetView *sv,
}
/* Has the entire row been selected/unselected */
- if ((new_sel.start.row == 0 && new_sel.end.row == gnm_sheet_get_last_row (sv->sheet)) ^
- (old_sel.start.row == 0 && old_sel.end.row == gnm_sheet_get_last_row (sv->sheet))) {
+ if (((new_sel.start.row == 0 && new_sel.end.row == gnm_sheet_get_last_row (sv->sheet)) ^
+ (old_sel.start.row == 0 && old_sel.end.row == gnm_sheet_get_last_row (sv->sheet)))
+ || sv->selection_mode != GNM_SELECTION_MODE_ADD) {
GnmRange tmp = range_union (&new_sel, &old_sel);
sv_redraw_headers (sv, TRUE, FALSE, &tmp);
} else {
@@ -493,8 +564,9 @@ sheet_selection_set_internal (SheetView *sv,
}
/* Has the entire col been selected/unselected */
- if ((new_sel.start.col == 0 && new_sel.end.col == gnm_sheet_get_last_col (sv->sheet)) ^
- (old_sel.start.col == 0 && old_sel.end.col == gnm_sheet_get_last_col (sv->sheet))) {
+ if (((new_sel.start.col == 0 && new_sel.end.col == gnm_sheet_get_last_col (sv->sheet)) ^
+ (old_sel.start.col == 0 && old_sel.end.col == gnm_sheet_get_last_col (sv->sheet)))
+ || sv->selection_mode != GNM_SELECTION_MODE_ADD) {
GnmRange tmp = range_union (&new_sel, &old_sel);
sv_redraw_headers (sv, FALSE, TRUE, &tmp);
} else {
@@ -574,6 +646,29 @@ sv_selection_set (SheetView *sv, GnmCellPos const *edit,
move_col, move_row, FALSE);
}
+void
+sv_selection_simplify (SheetView *sv)
+{
+ switch (sv->selection_mode) {
+ case GNM_SELECTION_MODE_ADD:
+ /* already simplified */
+ return;
+ case GNM_SELECTION_MODE_REMOVE:
+ sv_selection_calc_simplification (sv);
+ if (sv->selections_simplified != NULL) {
+ sv_selection_free (sv);
+ sv->selections = sv->selections_simplified;
+ sv->selections_simplified = NULL;
+ }
+ break;
+ default:
+ case GNM_SELECTION_MODE_TOGGLE:
+ g_warning ("Selection mode %d not implemented!\n", sv->selection_mode);
+ break;
+ }
+ sv->selection_mode = GNM_SELECTION_MODE_ADD;
+}
+
/**
* sv_selection_add_full :
* @sv : #SheetView whose selection is append to.
@@ -587,16 +682,19 @@ void
sv_selection_add_full (SheetView *sv,
int edit_col, int edit_row,
int base_col, int base_row,
- int move_col, int move_row)
+ int move_col, int move_row,
+ GnmSelectionMode mode)
{
GnmRange *ss;
GnmCellPos edit;
g_return_if_fail (IS_SHEET_VIEW (sv));
+ sv_selection_simplify (sv);
/* Create and prepend new selection */
ss = g_new0 (GnmRange, 1);
sv->selections = g_slist_prepend (sv->selections, ss);
+ sv->selection_mode = mode;
edit.col = edit_col;
edit.row = edit_row;
sheet_selection_set_internal (sv, &edit,
@@ -608,12 +706,13 @@ void
sv_selection_add_range (SheetView *sv, GnmRange const *r)
{
sv_selection_add_full (sv, r->start.col, r->start.row,
- r->start.col, r->start.row, r->end.col, r->end.row);
+ r->start.col, r->start.row, r->end.col, r->end.row,
+ GNM_SELECTION_MODE_ADD);
}
void
-sv_selection_add_pos (SheetView *sv, int col, int row)
+sv_selection_add_pos (SheetView *sv, int col, int row, GnmSelectionMode mode)
{
- sv_selection_add_full (sv, col, row, col, row, col, row);
+ sv_selection_add_full (sv, col, row, col, row, col, row, mode);
}
/**
@@ -628,12 +727,23 @@ sv_selection_add_pos (SheetView *sv, int col, int row)
void
sv_selection_free (SheetView *sv)
{
- GSList *list;
-
- for (list = sv->selections; list; list = list->next)
- g_free (list->data);
- g_slist_free (sv->selections);
+ g_slist_free_full (sv->selections, g_free);
sv->selections = NULL;
+ sv->selection_mode = GNM_SELECTION_MODE_ADD;
+}
+
+/**
+ * sv_selection_simplified_free
+ * @sv: #SheetView
+ *
+ * Releases the simplified selection associated with @sv
+ *
+ **/
+void
+sv_selection_simplified_free (SheetView *sv)
+{
+ g_slist_free_full (sv->selections_simplified, g_free);
+ sv->selections_simplified = NULL;
}
/**
@@ -656,6 +766,7 @@ sv_selection_reset (SheetView *sv)
/* Empty the sheets selection */
list = sv->selections;
sv->selections = NULL;
+ sv->selection_mode = GNM_SELECTION_MODE_ADD;
/* Redraw the grid, & headers for each region */
for (tmp = list; tmp; tmp = tmp->next){
@@ -689,12 +800,14 @@ selection_get_ranges (SheetView const *sv, gboolean allow_intersection)
g_printerr ("============================\n");
#endif
+ l = sv_selection_calc_simplification (sv);
+
/*
* Run through all the selection regions to see if any of
* the proposed regions overlap. Start the search with the
* single user proposed segment and accumulate distict regions.
*/
- for (l = sv->selections; l != NULL; l = l->next) {
+ for (; l != NULL; l = l->next) {
GnmRange const *r = l->data;
/* The set of regions that do not interset with b or
@@ -969,7 +1082,9 @@ selection_get_ranges (SheetView const *sv, gboolean allow_intersection)
* Applies the specified function for all ranges in the selection. Optionally
* select whether to use the high level potentially over lapped ranges, rather
* than the smaller system created non-intersection regions.
+ *
*/
+
void
sv_selection_apply (SheetView *sv, SelectionApplyFunc const func,
gboolean allow_intersection,
@@ -981,13 +1096,14 @@ sv_selection_apply (SheetView *sv, SelectionApplyFunc const func,
g_return_if_fail (IS_SHEET_VIEW (sv));
if (allow_intersection) {
- for (l = sv->selections; l != NULL; l = l->next) {
+ for (l = sv_selection_calc_simplification (sv);
+ l != NULL; l = l->next) {
GnmRange const *ss = l->data;
(*func) (sv, ss, closure);
}
} else {
- proposed = selection_get_ranges (sv, allow_intersection);
+ proposed = selection_get_ranges (sv, FALSE);
while (proposed != NULL) {
/* pop the 1st element off the list */
GnmRange *r = proposed->data;
@@ -1039,7 +1155,7 @@ sv_selection_apply_in_order (SheetView *sv, SelectionApplyFunc const func,
g_return_if_fail (IS_SHEET_VIEW (sv));
- reverse = g_slist_copy (sv->selections);
+ reverse = g_slist_copy (sv_selection_calc_simplification (sv));
reverse = g_slist_reverse (reverse);
for (l = reverse; l != NULL; l = l->next) {
GnmRange const *ss = l->data;
@@ -1087,7 +1203,7 @@ sv_selection_foreach (SheetView *sv,
g_return_val_if_fail (IS_SHEET_VIEW (sv), FALSE);
- for (l = sv->selections; l != NULL; l = l->next) {
+ for (l = sv_selection_calc_simplification (sv); l != NULL; l = l->next) {
GnmRange *ss = l->data;
if (!range_cb (sv, ss, user_data))
return FALSE;
@@ -1221,12 +1337,15 @@ sv_selection_walk_step (SheetView *sv, gboolean forward, gboolean horizontal)
GnmCellPos destination;
GnmRange const *ss;
gboolean is_singleton = FALSE;
+ GSList *selections;
g_return_if_fail (IS_SHEET_VIEW (sv));
g_return_if_fail (sv->selections != NULL);
- ss = sv->selections->data;
- selections_count = g_slist_length (sv->selections);
+ selections = sv_selection_calc_simplification (sv);
+
+ ss = selections->data;
+ selections_count = g_slist_length (selections);
/* If there is no selection besides the cursor iterate through the
* entire sheet. Move the cursor and selection as we go. Ignore
@@ -1358,7 +1477,7 @@ characterize_vec (Sheet *sheet, GnmRange *vector,
void
sv_selection_to_plot (SheetView *sv, GogPlot *go_plot)
{
- GSList *ptr, *sels;
+ GSList *ptr, *sels, *selections;
GnmRange const *r;
int num_cols, num_rows;
@@ -1376,11 +1495,13 @@ sv_selection_to_plot (SheetView *sv, GogPlot *go_plot)
gboolean default_to_cols;
+ selections = sv_selection_calc_simplification (sv);
+
/* Use the total number of cols vs rows in all of the selected regions.
* We can not use just one in case one of the others happens to be the transpose
* eg select A1 + A:B would default_to_cols = FALSE, then produce a vector for each row */
num_cols = num_rows = 0;
- for (ptr = sv->selections; ptr != NULL ; ptr = ptr->next) {
+ for (ptr = selections; ptr != NULL ; ptr = ptr->next) {
r = ptr->data;
num_cols += range_width (r);
num_rows += range_height (r);
@@ -1403,7 +1524,7 @@ sv_selection_to_plot (SheetView *sv, GogPlot *go_plot)
to retrieve the axis data and the matrix z values. We probably should raise
an error condition if it is not the case */
/* selections are in reverse order so walk them backwards */
- GSList const *ptr = g_slist_last (sv->selections);
+ GSList const *ptr = g_slist_last (selections);
GnmRange vector = *((GnmRange const *) ptr->data);
int start_row = vector.start.row;
int start_col = vector.start.col;
@@ -1447,7 +1568,7 @@ sv_selection_to_plot (SheetView *sv, GogPlot *go_plot)
/* selections are in reverse order so walk them backwards */
cur_dim = 0;
- sels = ptr = g_slist_reverse (g_slist_copy (sv->selections));
+ sels = ptr = g_slist_reverse (g_slist_copy (selections));
for (; ptr != NULL; ptr = ptr->next) {
GnmRange vector = *((GnmRange const *)ptr->data);
@@ -1546,5 +1667,5 @@ skip :
g_slist_free (sels);
-#warning TODO is last series is incomplete try to shift data out of optional dimensions
+#warning TODO If last series is incomplete try to shift data out of optional dimensions.
}
diff --git a/src/selection.h b/src/selection.h
index ae3a463..765ae27 100644
--- a/src/selection.h
+++ b/src/selection.h
@@ -13,6 +13,12 @@ typedef enum {
COL_ROW_FULL_SELECTION
} ColRowSelectionType;
+typedef enum {
+ GNM_SELECTION_MODE_ADD = 0,
+ GNM_SELECTION_MODE_REMOVE,
+ GNM_SELECTION_MODE_TOGGLE
+} GnmSelectionMode;
+
/* Selection information */
GnmCellPos const *sv_is_singleton_selected (SheetView const *sv);
gboolean sv_is_pos_selected (SheetView const *sv, int col, int row);
@@ -36,17 +42,20 @@ void sv_selection_to_plot (SheetView *sv, GogPlot *plot);
/* Selection management */
void sv_selection_reset (SheetView *sv);
-void sv_selection_add_pos (SheetView *sv, int col, int row);
+void sv_selection_add_pos (SheetView *sv, int col, int row, GnmSelectionMode mode);
void sv_selection_add_range (SheetView *sv, GnmRange const *range);
void sv_selection_add_full (SheetView *sv,
int edit_col, int edit_row,
int base_col, int base_row,
- int move_col, int move_row);
+ int move_col, int move_row,
+ GnmSelectionMode mode);
void sv_selection_set (SheetView *sv, GnmCellPos const *edit,
int base_col, int base_row,
int move_col, int move_row);
void sv_selection_extend_to (SheetView *sv, int col, int row);
void sv_selection_free (SheetView *sv);
+void sv_selection_simplified_free (SheetView *sv);
+void sv_selection_simplify (SheetView *sv);
void sv_selection_walk_step (SheetView *sv,
gboolean forward,
diff --git a/src/sheet-control-gui.c b/src/sheet-control-gui.c
index 863a2d7..b8feb93 100644
--- a/src/sheet-control-gui.c
+++ b/src/sheet-control-gui.c
@@ -485,7 +485,9 @@ scg_select_all (SheetControlGUI *scg)
wbcg_edit_finish (scg->wbcg, WBC_EDIT_REJECT, NULL);
sv_selection_reset (sv);
sv_selection_add_full (sv, sv->edit_pos.col, sv->edit_pos.row,
- 0, 0, gnm_sheet_get_last_col (sheet), gnm_sheet_get_last_row (sheet));
+ 0, 0, gnm_sheet_get_last_col (sheet),
+ gnm_sheet_get_last_row (sheet),
+ GNM_SELECTION_MODE_ADD);
}
sheet_update (sheet);
}
@@ -528,16 +530,18 @@ scg_colrow_select (SheetControlGUI *scg, gboolean is_cols,
GnmPane *pane =
scg_pane (scg, scg->pane[3] ? 3 : 0);
sv_selection_add_full (sv,
- index, pane->first.row,
- index, 0,
- index, gnm_sheet_get_last_row (sv->sheet));
+ index, pane->first.row,
+ index, 0,
+ index, gnm_sheet_get_last_row (sv->sheet),
+ GNM_SELECTION_MODE_ADD);
} else {
GnmPane *pane =
scg_pane (scg, scg->pane[1] ? 1 : 0);
sv_selection_add_full (sv,
- pane->first.col, index,
- 0, index,
- gnm_sheet_get_last_col (sv->sheet), index);
+ pane->first.col, index,
+ 0, index,
+ gnm_sheet_get_last_col (sv->sheet), index,
+ GNM_SELECTION_MODE_ADD);
}
}
@@ -3448,7 +3452,7 @@ scg_cursor_move (SheetControlGUI *scg, int n,
sv_cursor_set (sv, &tmp,
tmp.col, tmp.row, tmp.col, tmp.row, NULL);
sv_make_cell_visible (sv, tmp.col, tmp.row, FALSE);
- sv_selection_add_pos (sv, tmp.col, tmp.row);
+ sv_selection_add_pos (sv, tmp.col, tmp.row, GNM_SELECTION_MODE_ADD);
}
/**
diff --git a/src/sheet-view.c b/src/sheet-view.c
index d30a999..4e11f98 100644
--- a/src/sheet-view.c
+++ b/src/sheet-view.c
@@ -223,6 +223,7 @@ sv_real_dispose (GObject *object)
sv_unant (sv);
sv_selection_free (sv);
+ sv_selection_simplified_free (sv);
auto_expr_timer_clear (sv);
parent_class->dispose (object);
@@ -260,7 +261,10 @@ sheet_view_init (GObject *object)
sv->unfrozen_top_left.col = sv->unfrozen_top_left.row = -1;
sv->initial_top_left.col = sv->initial_top_left.row = 0;
- sv_selection_add_pos (sv, 0, 0);
+ sv->selections = NULL;
+ sv->selection_mode = GNM_SELECTION_MODE_ADD;
+ sv->selections_simplified = NULL;
+ sv_selection_add_pos (sv, 0, 0, GNM_SELECTION_MODE_ADD);
}
GSF_CLASS (SheetView, sheet_view,
diff --git a/src/sheet-view.h b/src/sheet-view.h
index ea5d954..c9b836d 100644
--- a/src/sheet-view.h
+++ b/src/sheet-view.h
@@ -26,6 +26,9 @@ struct _SheetView {
* a normalized version of SheetView::{cursor.base_corner:move_corner}
*/
GSList *selections;
+ GSList *selections_simplified;
+ int selection_mode; /* GnmSelectionMode */
+
GnmCellPos edit_pos; /* Cell that would be edited */
GnmCellPos edit_pos_real; /* Even in the middle of a merged cell */
int first_tab_col; /* where to jump to after an Enter */
diff --git a/src/sheet.c b/src/sheet.c
index 1c8a3a8..598c7cc 100644
--- a/src/sheet.c
+++ b/src/sheet.c
@@ -1200,9 +1200,9 @@ gnm_sheet_resize_main (Sheet *sheet, int cols, int rows,
g_free (r);
}
g_slist_free (sel);
- if (!any) {
- sv_selection_add_pos (sv, 0, 0);
- }
+ if (!any)
+ sv_selection_add_pos (sv, 0, 0,
+ GNM_SELECTION_MODE_ADD);
sv_make_cell_visible (sv, vis.col, vis.row, FALSE);
});
diff --git a/src/test-pango.c b/src/test-pango.c
index d9efc4a..432e7fb 100644
--- a/src/test-pango.c
+++ b/src/test-pango.c
@@ -42,7 +42,8 @@ cb_exercise_pango (gpointer data)
if (state == 0) {
sv_selection_reset (sv);
- sv_selection_add_full(sv, 0, 0, 0, 0, 40, STEP_SIZE*TEST_STEPS);
+ sv_selection_add_full (sv, 0, 0, 0, 0, 40, STEP_SIZE*TEST_STEPS,
+ GNM_SELECTION_MODE_ADD);
cmd_area_set_text (wbc, sv, "=rand()", NULL);
} else if (state < TEST_STEPS) {
SHEET_VIEW_FOREACH_CONTROL(wb_control_cur_sheet_view (wbc),
diff --git a/src/workbook-view.c b/src/workbook-view.c
index d1b90d6..984adb9 100644
--- a/src/workbook-view.c
+++ b/src/workbook-view.c
@@ -369,7 +369,7 @@ wb_view_selection_desc (WorkbookView *wbv, gboolean use_pos,
g_return_if_fail (IS_SHEET_VIEW (sv));
g_return_if_fail (sv->selections);
- r = sv->selections->data;
+ r = selection_first_range (sv, NULL, NULL);
if (use_pos || range_is_singleton (r) ||
(NULL != (m = gnm_sheet_merge_is_corner (sv->sheet, &r->start)) &&
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]