[gnumeric] Merged ranges: extend as needed when inserting rows/columns



commit 827f8daf6ddd6b334084700d6335b71859826fa5
Author: Morten Welinder <terra gnome org>
Date:   Sun Dec 13 17:05:06 2015 -0500

    Merged ranges: extend as needed when inserting rows/columns

 ChangeLog         |    5 +++++
 NEWS              |    2 +-
 src/sheet-merge.c |   53 +++++++++++++++++++++++++++++++++--------------------
 3 files changed, 39 insertions(+), 21 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 7675891..ae48cf9 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2015-12-13  Morten Welinder  <terra gnome org>
+
+       * src/sheet-merge.c (gnm_sheet_merge_relocate): Handle extending
+       merges on column/row insert.  Fixes #504004.
+
 2015-12-12  Morten Welinder  <terra gnome org>
 
        * src/sheet-merge.c (gnm_sheet_merge_relocate): Handling clipping
diff --git a/NEWS b/NEWS
index 74a9ad1..c160e62 100644
--- a/NEWS
+++ b/NEWS
@@ -13,7 +13,7 @@ Morten:
        * Fix problem with R.QHYPER
        * Add R.DRAYLEIGH, R.PRAYLEIGH, R.QRAYLEIGH.
        * Fix GUI translation problems.
-       * Fix bug with merged cells.
+       * Fix bugs with merged cells.  [#504004]
 
 --------------------------------------------------------------------------
 Gnumeric 1.12.24
diff --git a/src/sheet-merge.c b/src/sheet-merge.c
index c080c8f..0dc50be 100644
--- a/src/sheet-merge.c
+++ b/src/sheet-merge.c
@@ -338,7 +338,7 @@ cb_restore_list_free (GSList *restore)
 void
 gnm_sheet_merge_relocate (GnmExprRelocateInfo const *ri, GOUndo **pundo)
 {
-       GSList   *ptr, *copy, *to_move = NULL, *restore = NULL;
+       GSList   *ptr, *copy, *reapply = NULL, *restore = NULL;
        GnmRange         dest;
        gboolean change_sheets;
 
@@ -364,40 +364,53 @@ gnm_sheet_merge_relocate (GnmExprRelocateInfo const *ri, GOUndo **pundo)
        copy = g_slist_copy (ri->origin_sheet->list_merged);
        for (ptr = copy; ptr != NULL ; ptr = ptr->next ) {
                GnmRange const *r = ptr->data;
-               if (range_contains (&ri->origin, r->start.col, r->start.row)) {
-                       GnmRange r2 = *r;
-
-                       if (pundo)
-                               restore = g_slist_prepend (restore, gnm_range_dup (r));
+               GnmRange r0 = *r; // Copy because removal invalidates r
+               GnmRange r2 = *r;
+               gboolean needs_restore = FALSE;
+               gboolean needs_reapply = FALSE;
 
-                       /*
-                        * Toss any merges that would be clipped to a null
-                        * range or a single cell.
-                        */
-                       gnm_sheet_merge_remove (ri->origin_sheet, r, NULL);
+               if (range_contains (&ri->origin, r->start.col, r->start.row)) {
                        range_translate (&r2, ri->target_sheet,
                                         ri->col_offset, ri->row_offset);
                        range_ensure_sanity (&r2, ri->target_sheet);
 
-                       if (range_is_singleton (&r2) ||
-                           r2.start.col > r2.end.col ||
-                           r2.start.row > r2.end.row)
-                               continue;
-
-                       to_move = g_slist_prepend (to_move, gnm_range_dup (&r2));
+                       gnm_sheet_merge_remove (ri->origin_sheet, r, NULL);
+                       if (range_is_singleton (&r2))
+                               needs_restore = TRUE;
+                       else if (r2.start.col <= r2.end.col &&
+                                r2.start.row <= r2.end.row) {
+                               needs_restore = TRUE;
+                               needs_reapply = TRUE;
+                       } else {
+                               // Completely deleted.
+                       }
+               } else if (range_contains (&ri->origin, r->end.col, r->end.row)) {
+                       r2.end.col += ri->col_offset;
+                       r2.end.row += ri->row_offset;
+                       range_ensure_sanity (&r2, ri->target_sheet);
+                       gnm_sheet_merge_remove (ri->origin_sheet, r, NULL);
+                       needs_restore = TRUE;
+                       needs_reapply = !range_is_singleton (&r2);
                } else if (!change_sheets &&
                           range_contains (&dest, r->start.col, r->start.row))
                        gnm_sheet_merge_remove (ri->origin_sheet, r, NULL);
+
+               if (needs_reapply)
+                       reapply = g_slist_prepend (reapply,
+                                                  gnm_range_dup (&r2));
+               if (needs_restore && pundo)
+                       restore = g_slist_prepend (restore,
+                                                  gnm_range_dup (&r0));
        }
        g_slist_free (copy);
 
-       /* move the ranges after removing the previous content in case of overlap */
-       for (ptr = to_move ; ptr != NULL ; ptr = ptr->next) {
+       // Reapply surviving, changed ranges.
+       for (ptr = reapply ; ptr != NULL ; ptr = ptr->next) {
                GnmRange *dest = ptr->data;
                gnm_sheet_merge_add (ri->target_sheet, dest, TRUE, NULL);
                g_free (dest);
        }
-       g_slist_free (to_move);
+       g_slist_free (reapply);
 
        if (restore) {
                GOUndo *u = go_undo_binary_new


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