Commit db6d7144 authored by Andreas J. Guelzow 's avatar Andreas J. Guelzow

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
parent 85015a0a
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
......
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]
--------------------------------------------------------------------------
......
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
......
......@@ -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;
......
......@@ -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"););
}
......
/* 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);
......
......@@ -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
}
......
......@@ -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;
......
......@@ -31,6 +31,63 @@
#include "value.h"
#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.
}
......@@ -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,
......
......@@ -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);
}
/**
......
......@@ -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,
......
......@@ -26,6 +26,9 @@ struct _SheetView {
* a normalized version of SheetView::{cursor.base_corner:move_corner}
*/