commit 1a43b5d8b6253d31eb30ed777d9531363d9abea1
Author: Juergen Spitzmueller <[email protected]>
Date: Sat Oct 24 09:18:46 2026 +0200
Fix handling of multirows on row insertion (#13377)
When inserting a row in the midst of a multirow, this produced
orphaned "part of multirow" cells, which lead to crashes.
We now prolong the multirow in those cases (as we do for multicols
already)
(cherry picked from commit 64141cf0e7a073e1226ec168d317618537ba0fab)
---
src/insets/InsetTabular.cpp | 38 +++++++++++++++++++++++++++++++++-----
src/insets/InsetTabular.h | 2 +-
status.25x | 3 +++
3 files changed, 37 insertions(+), 6 deletions(-)
diff --git a/src/insets/InsetTabular.cpp b/src/insets/InsetTabular.cpp
index 6b5882ef70..c4363422fa 100644
--- a/src/insets/InsetTabular.cpp
+++ b/src/insets/InsetTabular.cpp
@@ -868,6 +868,13 @@ void Tabular::appendRow(row_type row)
void Tabular::insertRow(row_type const row, bool copy)
{
+ // record end cells of multirows before the new
+ // row is inserted
+ map<col_type, bool> mr_ends;
+ for (col_type c = 0; c < ncols(); ++c)
+ mr_ends[c] = cell_info[row][c].multirow == CELL_PART_OF_MULTIROW
+ && !isEndOfMultiRow(row,c);
+
row_info.insert(row_info.begin() + row + 1, row_info[row]);
cell_info.insert(cell_info.begin() + row + 1,
cell_vector(0, CellData(buffer_)));
@@ -875,13 +882,13 @@ void Tabular::insertRow(row_type const row, bool copy)
for (col_type c = 0; c < ncols(); ++c) {
cell_info[row + 1].insert(cell_info[row + 1].begin() + c,
copy ? cell_info[row][c] : CellData(buffer_));
- if (cell_info[row][c].multirow == CELL_BEGIN_OF_MULTIROW)
+ if (cell_info[row][c].multirow == CELL_BEGIN_OF_MULTIROW ||
mr_ends[c])
cell_info[row + 1][c].multirow = CELL_PART_OF_MULTIROW;
}
updateIndexes();
for (col_type c = 0; c < ncols(); ++c) {
- if (isPartOfMultiRow(row, c))
+ if (isPartOfMultiRow(row + 1, c))
continue;
// inherit line settings
idx_type const i = cellIndex(row + 1, c);
@@ -1095,7 +1102,7 @@ void Tabular::updateIndexes()
if (!isPartOfMultiColumn(row, column)
&& !isPartOfMultiRow(row, column))
++numberofcells;
- if (isPartOfMultiRow(row, column)) {
+ if (isPartOfMultiRow(row, column, true)) {
LATTEST(row > 0);
cell_info[row][column].cellno = cell_info[row -
1][column].cellno;
} else
@@ -2831,11 +2838,32 @@ bool Tabular::isPartOfMultiColumn(row_type row,
col_type column) const
}
-bool Tabular::isPartOfMultiRow(row_type row, col_type column) const
+bool Tabular::isPartOfMultiRow(row_type row, col_type column, bool const
realcheck) const
{
LASSERT(row < nrows(), return false);
LASSERT(column < ncols(), return false);
- return cell_info[row][column].multirow == CELL_PART_OF_MULTIROW;
+ if (cell_info[row][column].multirow != CELL_PART_OF_MULTIROW)
+ return false;
+ if (!realcheck)
+ return cell_info[row][column].multirow == CELL_PART_OF_MULTIROW;
+
+ // Check whether this is really part of a multirow
+ // (earlier versions of LyX produced orphaned multirow
+ // parts through row insertion [#13377] and we want to
+ // exclude those here).
+ // So check for the preceding rows and whether the sequence
+ // really has a multirow begin.
+ row_type const fr = getFirstRow(!buffer().params().output_changes);
+ for (row_type r = row; r-- > 0 ;) {
+ if (cell_info[r][column].multirow == CELL_BEGIN_OF_MULTIROW)
+ // we have a multirow begin in sequence
+ return true;
+ else if (cell_info[r][column].multirow != CELL_PART_OF_MULTIROW
|| r == fr)
+ // a non-multirow cell or the first row in table
+ // (which is not multirow begin): no real multirow part
+ return false;
+ }
+ return false;
}
diff --git a/src/insets/InsetTabular.h b/src/insets/InsetTabular.h
index ffb489c1f2..8a7ffaf97a 100644
--- a/src/insets/InsetTabular.h
+++ b/src/insets/InsetTabular.h
@@ -700,7 +700,7 @@ public:
///
bool isPartOfMultiColumn(row_type row, col_type column) const;
///
- bool isPartOfMultiRow(row_type row, col_type column) const;
+ bool isPartOfMultiRow(row_type row, col_type column, bool const
realcheck = false) const;
///
bool isEndOfMultiRow(row_type row, col_type column) const;
///
diff --git a/status.25x b/status.25x
index bb2ce4fd0a..e1d61e4e3f 100644
--- a/status.25x
+++ b/status.25x
@@ -65,6 +65,9 @@ What's new
- Avoid crash when one manages to set cursor inset info inset (bug 12808).
+- Fix handling of multirows on row insertion and handle dangling multirow
+ cells produced by previous handling that could lead to crashes (bug 13377).
+
- Restore "Paste as PDF" on macOS which used to work in 2.4.
- Fix disabling of LFUN_FONT_* lfuns with multi-cell table selection.
--
lyx-cvs mailing list
[email protected]
https://lists.lyx.org/mailman/listinfo/lyx-cvs