[gnumeric] Merged cells: fix problem with clipping due to insert.
- From: Morten Welinder <mortenw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnumeric] Merged cells: fix problem with clipping due to insert.
- Date: Sat, 12 Dec 2015 22:29:23 +0000 (UTC)
commit dd08dd638cd9bacf8269525e59eb24019adcd715
Author: Morten Welinder <terra gnome org>
Date: Sat Dec 12 17:28:25 2015 -0500
Merged cells: fix problem with clipping due to insert.
We used to drop clipped merges on the floor. That's not nice.
ChangeLog | 5 ++++
NEWS | 1 +
src/sheet-merge.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++-----
src/sheet-merge.h | 4 ++-
src/sheet.c | 4 +-
5 files changed, 68 insertions(+), 10 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 9f66e8d..7675891 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2015-12-12 Morten Welinder <terra gnome org>
+
+ * src/sheet-merge.c (gnm_sheet_merge_relocate): Handling clipping
+ when the merge partially falls off the far end.
+
2015-12-10 Morten Welinder <terra gnome org>
* src/gui-util.c (gnm_action_group_add_action): New wrapper to
diff --git a/NEWS b/NEWS
index ace042b..74a9ad1 100644
--- a/NEWS
+++ b/NEWS
@@ -13,6 +13,7 @@ Morten:
* Fix problem with R.QHYPER
* Add R.DRAYLEIGH, R.PRAYLEIGH, R.QRAYLEIGH.
* Fix GUI translation problems.
+ * Fix bug with merged cells.
--------------------------------------------------------------------------
Gnumeric 1.12.24
diff --git a/src/sheet-merge.c b/src/sheet-merge.c
index 23d6f17..c080c8f 100644
--- a/src/sheet-merge.c
+++ b/src/sheet-merge.c
@@ -301,6 +301,34 @@ gnm_sheet_merge_is_corner (Sheet const *sheet, GnmCellPos const *pos)
return g_hash_table_lookup (sheet->hash_merged, pos);
}
+static void
+cb_restore_merge (Sheet *sheet, GSList *restore)
+{
+ GSList *l;
+ for (l = restore; l; l = l->next) {
+ GnmRange const *r = l->data;
+ GnmRange const *r2 = g_hash_table_lookup (sheet->hash_merged,
+ &r->start);
+ if (r2 && range_equal (r, r2))
+ continue;
+
+ // The only reason for r2 to be different from r is that we
+ // clipped. Moving the clipped region back didn't restore
+ // the old state, so we'll have to remove the merge and
+ // create a new.
+ if (r2)
+ gnm_sheet_merge_remove (sheet, r2, NULL);
+
+ gnm_sheet_merge_add (sheet, r, FALSE, NULL);
+ }
+}
+
+static void
+cb_restore_list_free (GSList *restore)
+{
+ g_slist_free_full (restore, g_free);
+}
+
/**
* gnm_sheet_merge_relocate:
* @ri: Descriptor of what is moving.
@@ -308,9 +336,9 @@ gnm_sheet_merge_is_corner (Sheet const *sheet, GnmCellPos const *pos)
* Shifts merged regions that need to move.
*/
void
-gnm_sheet_merge_relocate (GnmExprRelocateInfo const *ri)
+gnm_sheet_merge_relocate (GnmExprRelocateInfo const *ri, GOUndo **pundo)
{
- GSList *ptr, *copy, *to_move = NULL;
+ GSList *ptr, *copy, *to_move = NULL, *restore = NULL;
GnmRange dest;
gboolean change_sheets;
@@ -337,13 +365,26 @@ gnm_sheet_merge_relocate (GnmExprRelocateInfo const *ri)
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 tmp = *r;
+ GnmRange r2 = *r;
+
+ if (pundo)
+ restore = g_slist_prepend (restore, gnm_range_dup (r));
- /* Toss any merges that would be clipped. */
+ /*
+ * 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_translate (&tmp, ri->target_sheet,
- ri->col_offset, ri->row_offset))
- to_move = g_slist_prepend (to_move, gnm_range_dup (&tmp));
+ 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));
} else if (!change_sheets &&
range_contains (&dest, r->start.col, r->start.row))
gnm_sheet_merge_remove (ri->origin_sheet, r, NULL);
@@ -357,6 +398,15 @@ gnm_sheet_merge_relocate (GnmExprRelocateInfo const *ri)
g_free (dest);
}
g_slist_free (to_move);
+
+ if (restore) {
+ GOUndo *u = go_undo_binary_new
+ (ri->origin_sheet, restore,
+ (GOUndoBinaryFunc)cb_restore_merge,
+ NULL,
+ (GFreeFunc)cb_restore_list_free);
+ *pundo = go_undo_combine (*pundo, u);
+ }
}
/**
diff --git a/src/sheet-merge.h b/src/sheet-merge.h
index a4e1275..e985c2f 100644
--- a/src/sheet-merge.h
+++ b/src/sheet-merge.h
@@ -3,6 +3,7 @@
# define _GNM_SHEET_MERGE_H_
#include "gnumeric.h"
+#include <goffice/goffice.h>
G_BEGIN_DECLS
@@ -16,7 +17,8 @@ gboolean gnm_sheet_merge_remove (Sheet *sheet,
GSList *gnm_sheet_merge_get_overlap (Sheet const *sheet, GnmRange const *r);
GnmRange const *gnm_sheet_merge_contains_pos (Sheet const *sheet, GnmCellPos const *pos);
GnmRange const *gnm_sheet_merge_is_corner (Sheet const *sheet, GnmCellPos const *pos);
-void gnm_sheet_merge_relocate (GnmExprRelocateInfo const *ri);
+void gnm_sheet_merge_relocate (GnmExprRelocateInfo const *ri,
+ GOUndo **pundo);
void gnm_sheet_merge_find_container (Sheet const *sheet,
GnmRange *r);
void gnm_sheet_merge_get_adjacent (Sheet const *sheet,
diff --git a/src/sheet.c b/src/sheet.c
index f5e139a..2707633 100644
--- a/src/sheet.c
+++ b/src/sheet.c
@@ -5076,7 +5076,7 @@ sheet_insdel_colrow (Sheet *sheet, int pos, int count,
sheet_objects_relocate (&reloc_info, FALSE, pundo);
/* 9. Move merges. */
- gnm_sheet_merge_relocate (&reloc_info);
+ gnm_sheet_merge_relocate (&reloc_info, pundo);
/* 10. Move filters. */
gnm_sheet_filter_insdel_colrow (sheet, is_cols, is_insert, pos, count, pundo);
@@ -5367,7 +5367,7 @@ sheet_move_range (GnmExprRelocateInfo const *rinfo,
/* 7. Move objects in the range */
sheet_objects_relocate (rinfo, TRUE, pundo);
- gnm_sheet_merge_relocate (rinfo);
+ gnm_sheet_merge_relocate (rinfo, pundo);
/* 8. Notify sheet of pending update */
sheet_flag_recompute_spans (rinfo->origin_sheet);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]