commit 64141cf0e7a073e1226ec168d317618537ba0fab
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)
---
 src/insets/InsetTabular.cpp | 38 +++++++++++++++++++++++++++++++++-----
 src/insets/InsetTabular.h   |  2 +-
 2 files changed, 34 insertions(+), 6 deletions(-)

diff --git a/src/insets/InsetTabular.cpp b/src/insets/InsetTabular.cpp
index 71fd6d07b8..a291fd036b 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 72b13c002a..19414ab88b 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;
        ///
-- 
lyx-cvs mailing list
[email protected]
https://lists.lyx.org/mailman/listinfo/lyx-cvs

Reply via email to