diff --git a/source/worksheet/worksheet.cpp b/source/worksheet/worksheet.cpp index b51b68e6..23c9ea7c 100644 --- a/source/worksheet/worksheet.cpp +++ b/source/worksheet/worksheet.cpp @@ -878,6 +878,41 @@ void worksheet::move_cells(std::uint32_t min_index, std::uint32_t amount, row_or add_column_properties(prop.first, prop.second); } } + + // adjust merged cells + auto shift_reference = [min_index, amount, row_or_col, reverse](cell_reference &ref) + { + auto index = row_or_col == row_or_col_t::row ? + ref.row() : + ref.column_index(); + if (index >= min_index) + { + auto new_index = reverse ? index - amount : index + amount; + if (row_or_col == row_or_col_t::row) + { + ref.row(new_index); + } + else if (row_or_col == row_or_col_t::column) + { + ref.column_index(new_index); + } + } + }; + + for (auto merged_cell = d_->merged_cells_.begin(); merged_cell != d_->merged_cells_.end(); ++merged_cell) + { + cell_reference new_top_left = merged_cell->top_left(); + shift_reference(new_top_left); + + cell_reference new_bottom_right = merged_cell->bottom_right(); + shift_reference(new_bottom_right); + + range_reference new_range {new_top_left, new_bottom_right}; + if (*merged_cell != new_range) + { + *merged_cell = new_range; + } + } } bool worksheet::operator==(const worksheet &other) const diff --git a/tests/worksheet/worksheet_test_suite.cpp b/tests/worksheet/worksheet_test_suite.cpp index 8b67d676..1d9ee5d1 100644 --- a/tests/worksheet/worksheet_test_suite.cpp +++ b/tests/worksheet/worksheet_test_suite.cpp @@ -109,6 +109,7 @@ public: register_test(test_delete_rows); register_test(test_delete_columns); register_test(test_insert_too_many); + register_test(test_insert_delete_moves_merges); } void test_new_worksheet() @@ -1500,5 +1501,49 @@ public: xlnt_assert_throws(ws.insert_rows(10, 4294967290), xlnt::exception); } + + void test_insert_delete_moves_merges() + { + xlnt::workbook wb; + auto ws = wb.active_sheet(); + ws.merge_cells("A1:A2"); + ws.merge_cells("B2:B3"); + ws.merge_cells("C3:C4"); + ws.merge_cells("A5:B5"); + ws.merge_cells("B6:C6"); + ws.merge_cells("C7:D7"); + + { + ws.insert_rows(3, 3); + ws.insert_columns(3, 3); + auto merged = ws.merged_ranges(); + std::vector expected = + { + xlnt::range_reference { "A1:A2" }, // stays + xlnt::range_reference { "B2:B6" }, // expands + xlnt::range_reference { "F6:F7" }, // shifts + xlnt::range_reference { "A8:B8" }, // stays (shifted down) + xlnt::range_reference { "B9:F9" }, // expands (shifted down) + xlnt::range_reference { "F10:G10" }, // shifts (shifted down) + }; + xlnt_assert_equals(merged, expected); + } + + { + ws.delete_rows(4, 2); + ws.delete_columns(4, 2); + auto merged = ws.merged_ranges(); + std::vector expected = + { + xlnt::range_reference { "A1:A2" }, // stays + xlnt::range_reference { "B2:B4" }, // expands + xlnt::range_reference { "D4:D5" }, // shifts + xlnt::range_reference { "A6:B6" }, // stays (shifted down) + xlnt::range_reference { "B7:D7" }, // expands (shifted down) + xlnt::range_reference { "D8:E8" }, // shifts (shifted down) + }; + xlnt_assert_equals(merged, expected); + } + } }; static worksheet_test_suite x; \ No newline at end of file