[gnumeric] Insert/delete col/row: fix handing of ranges that go to the end of the sheet.



commit 3f2de7c4a8b89660ad918fc931d950ece3180c15
Author: Morten Welinder <terra gnome org>
Date:   Fri Apr 24 23:13:13 2009 -0400

    Insert/delete col/row: fix handing of ranges that go to the end of the sheet.
---
 ChangeLog    |   15 +++++++++++++++
 src/expr.c   |   36 ++++++++++++++++++++++++++----------
 src/expr.h   |    6 ++++++
 src/ranges.c |   17 -----------------
 src/ranges.h |    2 --
 src/sheet.c  |   35 +++++++++++++++++++++++++++++++++--
 6 files changed, 80 insertions(+), 31 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 78a1065..2f5d399 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,20 @@
 2009-04-24  Morten Welinder  <terra gnome org>
 
+	* src/sheet.c (sheet_delete_cols, sheet_delete_rows): If count
+	sends us beyond the end of the sheet, take that as a hint not to
+	make ranges that go to the end of the sheet sticky.
+	(gnm_sheet_resize_main): Supply such a hint.
+
+	* src/expr.h (struct _GnmExprRelocateInfo): Add extra sticky_end
+	field for col/row insert/delete.
+
+	* src/expr.c (reloc_cellrange): Take extra sticky_end argument and
+	only make end-of-sheet stick if that is set.  Fix logic to ignore
+	beginning of such ranges.  All callers changed.
+	(gnm_expr_relocate): Avoid using "default:" for reloc_type.
+
+	* src/ranges.c (range_make_full): Remove.  No longer used.
+
 	* src/validation.c (validation_barf): Ignore the problem if
 	VALIDATION_STYLE_NONE is used.  Fixes #580157.
 
diff --git a/src/expr.c b/src/expr.c
index 41a249b..e7b3bd4 100644
--- a/src/expr.c
+++ b/src/expr.c
@@ -1918,7 +1918,8 @@ reloc_restore_cellref (RelocInfoInternal const *rinfo,
 
 
 static GnmExpr const *
-reloc_cellrange (RelocInfoInternal const *rinfo, GnmValueRange const *v)
+reloc_cellrange (RelocInfoInternal const *rinfo, GnmValueRange const *v,
+		 gboolean sticky_end)
 {
 	GnmRange r;
 	Sheet   *start_sheet, *end_sheet;
@@ -1935,13 +1936,18 @@ reloc_cellrange (RelocInfoInternal const *rinfo, GnmValueRange const *v)
 	if (NULL == v->cell.b.sheet)
 		end_sheet = start_sheet;
 
-	full_col = range_is_full (&r, start_sheet, FALSE);
-	full_row = range_is_full (&r, start_sheet, TRUE);
+	full_col = sticky_end && r.end.row >= gnm_sheet_get_last_row (start_sheet);
+	full_row = sticky_end && r.end.col >= gnm_sheet_get_last_col (start_sheet);
 
 	if (reloc_range (rinfo->details, start_sheet, end_sheet, &r) ||
 	    rinfo->from_inside) {
 		GnmRangeRef res = v->cell;
-		range_make_full (&r, end_sheet, full_col, full_row);
+
+		if (full_col)
+			r.end.row = gnm_sheet_get_last_row (start_sheet);
+		if (full_row)
+			r.end.col = gnm_sheet_get_last_col (start_sheet);
+
 		if (reloc_restore_cellref (rinfo, start_sheet, &r.start, &res.a) ||
 		    reloc_restore_cellref (rinfo, end_sheet,   &r.end,   &res.b))
 			return gnm_expr_new_constant (value_new_error_REF (NULL));
@@ -2108,7 +2114,9 @@ gnm_expr_relocate (GnmExpr const *expr, RelocInfoInternal const *rinfo)
 				return gnm_expr_new_constant (value_new_error_REF (NULL));
 			return NULL;
 
-		default : {
+		case GNM_EXPR_RELOCATE_MOVE_RANGE:
+		case GNM_EXPR_RELOCATE_COLS:
+		case GNM_EXPR_RELOCATE_ROWS: {
 			GnmRange r;
 			Sheet   *sheet;
 
@@ -2126,19 +2134,27 @@ gnm_expr_relocate (GnmExpr const *expr, RelocInfoInternal const *rinfo)
 			}
 			return NULL;
 		}
+
+		default:
+			g_assert_not_reached ();
 		}
+
 		return NULL;
 	}
 
 	case GNM_EXPR_OP_CONSTANT:
 		if (expr->constant.value->type == VALUE_CELLRANGE) {
+			GnmValueRange const *vr = &expr->constant.value->v_range;
 			switch (rinfo->details->reloc_type) {
 			case GNM_EXPR_RELOCATE_INVALIDATE_SHEET:
-				return invalidate_sheet_cellrange (rinfo,
-					&expr->constant.value->v_range);
-			default :
-				return reloc_cellrange (rinfo,
-					&expr->constant.value->v_range);
+				return invalidate_sheet_cellrange (rinfo, vr);
+			case GNM_EXPR_RELOCATE_MOVE_RANGE:
+				return reloc_cellrange (rinfo, vr, TRUE);
+			case GNM_EXPR_RELOCATE_COLS:
+			case GNM_EXPR_RELOCATE_ROWS:
+				return reloc_cellrange (rinfo, vr, rinfo->details->sticky_end);
+			default:
+				g_assert_not_reached ();
 			}
 		}
 		return NULL;
diff --git a/src/expr.h b/src/expr.h
index 85f248c..b33f946 100644
--- a/src/expr.h
+++ b/src/expr.h
@@ -152,6 +152,12 @@ struct _GnmExprRelocateInfo {
 		GNM_EXPR_RELOCATE_COLS,		/* ins/del col */
 		GNM_EXPR_RELOCATE_ROWS		/* ins/del row */
 	} reloc_type;
+
+	/* Valid for COLS/ROWS only.  Assumed by MOVE_RANGE.  If TRUE,
+	   ranges ending at the edge of the sheet will keep the end
+	   there.  */
+	gboolean sticky_end;
+
 };
 GnmExprTop const *gnm_expr_top_relocate	 (GnmExprTop const *texpr,
 					  GnmExprRelocateInfo const *rinfo,
diff --git a/src/ranges.c b/src/ranges.c
index 3c9d722..fbd4b53 100644
--- a/src/ranges.c
+++ b/src/ranges.c
@@ -587,23 +587,6 @@ range_is_full (GnmRange const *r, Sheet const *sheet, gboolean horiz)
 }
 
 /**
- * range_make_full:
- * @r: the range.
- * @sheet : the sheet in which @r lives
- * @full_col : Make @r a full column  ref (_row_ [0..MAX))
- * @full_row : Make @r a full row ref  (_column_ [0..MAX))
- **/
-void
-range_make_full	(GnmRange *r, Sheet const *sheet,
-		 gboolean full_col, gboolean full_row)
-{
-	if (full_col)
-		r->start.row = 0, r->end.row = gnm_sheet_get_last_row (sheet);
-	if (full_row)
-		r->start.col = 0, r->end.col = gnm_sheet_get_last_col (sheet);
-}
-
-/**
  * range_clip_to_finite :
  * @range :
  * @sheet : the sheet in which @range lives
diff --git a/src/ranges.h b/src/ranges.h
index 0330771..a3b6aae 100644
--- a/src/ranges.h
+++ b/src/ranges.h
@@ -79,8 +79,6 @@ int	    range_width		(GnmRange const *r);
 int	    range_height	(GnmRange const *r);
 gboolean    range_is_singleton  (GnmRange const *r);
 gboolean    range_is_full	(GnmRange const *r, Sheet const *sheet, gboolean horiz);
-void        range_make_full	(GnmRange *r, Sheet const *sheet,
-				 gboolean full_col, gboolean full_row);
 void        range_clip_to_finite(GnmRange *range, Sheet *sheet);
 gboolean    range_contained     (GnmRange const *a, GnmRange const *b);
 gboolean    range_intersection  (GnmRange *r,
diff --git a/src/sheet.c b/src/sheet.c
index 0d5323f..78e779b 100644
--- a/src/sheet.c
+++ b/src/sheet.c
@@ -1126,7 +1126,7 @@ gnm_sheet_resize_main (Sheet *sheet, int cols, int rows,
 		GOUndo *u = NULL;
 		gboolean err;
 
-		err = sheet_delete_cols (sheet, cols, old_cols - cols,
+		err = sheet_delete_cols (sheet, cols, G_MAXINT,
 					 pundo ? &u : NULL, cc);
 		if (pundo)
 			*pundo = go_undo_combine (*pundo, u);
@@ -1138,7 +1138,7 @@ gnm_sheet_resize_main (Sheet *sheet, int cols, int rows,
 		GOUndo *u = NULL;
 		gboolean err;
 
-		err = sheet_delete_rows (sheet, rows, old_rows - rows,
+		err = sheet_delete_rows (sheet, rows, G_MAXINT,
 					 pundo ? &u : NULL, cc);
 		if (pundo)
 			*pundo = go_undo_combine (*pundo, u);
@@ -4398,6 +4398,7 @@ sheet_insert_cols (Sheet *sheet, int col, int count,
 
 	/* 2. Fix references to and from the cells which are moving */
 	reloc_info.reloc_type = GNM_EXPR_RELOCATE_COLS;
+	reloc_info.sticky_end = TRUE;
 	reloc_info.origin.start.col = col;
 	reloc_info.origin.start.row = 0;
 	reloc_info.origin.end.col = gnm_sheet_get_last_col (sheet);
@@ -4440,10 +4441,23 @@ sheet_delete_cols (Sheet *sheet, int col, int count,
 	GnmExprRelocateInfo reloc_info;
 	int i;
 	ColRowStateList *states = NULL;
+	int max_count;
+	gboolean beyond_end;
 
 	g_return_val_if_fail (IS_SHEET (sheet), TRUE);
 	g_return_val_if_fail (count > 0, TRUE);
 
+	max_count = gnm_sheet_get_max_cols (sheet) - col;
+	beyond_end = (count > max_count);
+	if (beyond_end) {
+		/*
+		 * We're trying to delete more than we have (not just to the
+		 * very end).  We take that as a signal that ranges should
+		 * not be sticky at the end.
+		 */
+		count = max_count;
+	}
+
 	if (pundo) *pundo = NULL;
 	schedule_reapply_filters (sheet, pundo);
 
@@ -4456,6 +4470,7 @@ sheet_delete_cols (Sheet *sheet, int col, int count,
 	}
 
 	reloc_info.reloc_type = GNM_EXPR_RELOCATE_COLS;
+	reloc_info.sticky_end = !beyond_end;
 	reloc_info.origin.start.col = col;
 	reloc_info.origin.start.row = 0;
 	reloc_info.origin.end.col = col + count - 1;
@@ -4559,6 +4574,7 @@ sheet_insert_rows (Sheet *sheet, int row, int count,
 
 	/* 2. Fix references to and from the cells which are moving */
 	reloc_info.reloc_type = GNM_EXPR_RELOCATE_ROWS;
+	reloc_info.sticky_end = TRUE;
 	reloc_info.origin.start.col = 0;
 	reloc_info.origin.start.row = row;
 	reloc_info.origin.end.col = gnm_sheet_get_last_col (sheet);
@@ -4601,10 +4617,23 @@ sheet_delete_rows (Sheet *sheet, int row, int count,
 	GnmExprRelocateInfo reloc_info;
 	int i;
 	ColRowStateList *states = NULL;
+	int max_count;
+	gboolean beyond_end;
 
 	g_return_val_if_fail (IS_SHEET (sheet), TRUE);
 	g_return_val_if_fail (count > 0, TRUE);
 
+	max_count = gnm_sheet_get_max_rows (sheet) - row;
+	beyond_end = (count > max_count);
+	if (beyond_end) {
+		/*
+		 * We're trying to delete more than we have (not just to the
+		 * very end).  We take that as a signal that ranges should
+		 * not be sticky at the end.
+		 */
+		count = max_count;
+	}
+
 	if (pundo) *pundo = NULL;
 	schedule_reapply_filters (sheet, pundo);
 
@@ -4617,6 +4646,7 @@ sheet_delete_rows (Sheet *sheet, int row, int count,
 	}
 
 	reloc_info.reloc_type = GNM_EXPR_RELOCATE_ROWS;
+	reloc_info.sticky_end = !beyond_end;
 	reloc_info.origin.start.col = 0;
 	reloc_info.origin.start.row = row;
 	reloc_info.origin.end.col = gnm_sheet_get_last_col (sheet);
@@ -4738,6 +4768,7 @@ sheet_move_range (GnmExprRelocateInfo const *rinfo,
 			 * smart about partial invalidations */
 			reloc_info.col_offset = gnm_sheet_get_max_cols (rinfo->target_sheet);
 			reloc_info.row_offset = gnm_sheet_get_max_rows (rinfo->target_sheet);
+			reloc_info.sticky_end = TRUE;
 			if (rinfo->col_offset == 0) {
 				reloc_info.col_offset = 0;
 				reloc_info.reloc_type = GNM_EXPR_RELOCATE_ROWS;



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]