sw/qa/uitest/writer_tests/trackedChanges.py |   65 ++++++++++++++++++++++++++++
 sw/source/uibase/inc/redlndlg.hxx           |    3 +
 sw/source/uibase/misc/redlndlg.cxx          |   13 +++++
 3 files changed, 80 insertions(+), 1 deletion(-)

New commits:
commit 63ddddd7157c52c945231d26192559e17e32d332
Author:     László Németh <nem...@numbertext.org>
AuthorDate: Thu Jun 22 17:33:16 2023 +0200
Commit:     László Németh <nem...@numbertext.org>
CommitDate: Tue Jun 27 10:19:23 2023 +0200

    tdf#155847 sw tracked table column: fix crash in Manage Changes
    
    In Manage Changes dialog window, accept/Reject multiple tracked
    table columns need major tree list update because of not continuous
    redline ranges in the child lists of the multiple tree list parents,
    otherwise assert/crash could occur.
    
    Follow-up to commit 4a40a42afc3ba551e6e58947fc2e44689979b629
    "tdf#155847 sw tracked table column: manage multiple changes".
    
    Change-Id: I3c7f61d35cbb433067c1f4fd28b80ad7da8ba12e
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/153464
    Tested-by: László Németh <nem...@numbertext.org>
    Reviewed-by: László Németh <nem...@numbertext.org>
    (cherry picked from commit d2b3817fd3fc44179ff0606d4234cbe0ae66e375)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/153512
    Tested-by: Jenkins

diff --git a/sw/qa/uitest/writer_tests/trackedChanges.py 
b/sw/qa/uitest/writer_tests/trackedChanges.py
index 111571881b82..14aea9bcee0d 100644
--- a/sw/qa/uitest/writer_tests/trackedChanges.py
+++ b/sw/qa/uitest/writer_tests/trackedChanges.py
@@ -597,4 +597,69 @@ class trackedchanges(UITestCase):
 
                 self.assertEqual(0, len(changesList.getChildren()))
 
+    def test_tdf155847_multiple_tracked_columns_crash(self):
+        with 
self.ui_test.load_file(get_url_for_data_file("TC-table-del-add.docx")) as 
document:
+
+            xWriterDoc = self.xUITest.getTopFocusWindow()
+            xWriterEdit = xWriterDoc.getChild("writer_edit")
+
+            # accept all changes and insert new columns with change tracking
+            self.xUITest.executeCommand(".uno:AcceptAllTrackedChanges")
+            tables = document.getTextTables()
+            self.assertEqual(2, len(tables))
+            self.assertEqual(len(tables[0].getColumns()), 3)
+            self.xUITest.executeCommand(".uno:InsertColumnsAfter")
+            self.xUITest.executeCommand(".uno:DeleteColumns")
+            self.assertEqual(len(tables[0].getColumns()), 4)
+
+            xToolkit = 
self.xContext.ServiceManager.createInstance('com.sun.star.awt.Toolkit')
+            xToolkit.processEventsToIdle()
+
+            # check and reject changes
+            with 
self.ui_test.execute_modeless_dialog_through_command(".uno:AcceptTrackedChanges",
 close_button="close") as xTrackDlg:
+                changesList = xTrackDlg.getChild("writerchanges")
+
+                # six changes, but only one visible in the Manage Changes 
dialog window
+                state = get_state_as_dict(changesList)
+                self.assertEqual(state['Children'], '6')
+
+                # This was 4 (missing handling of multiple different columns)
+                self.assertEqual(state['VisibleCount'], '2')
+                # Now: 2 changes (deleted and inserted columns)
+                self.assertEqual(2, len(changesList.getChildren()))
+
+                # select second tracked table column in tree list
+                xToolkit = 
self.xContext.ServiceManager.createInstance('com.sun.star.awt.Toolkit')
+                changesList.executeAction("TYPE", mkPropertyValues({"KEYCODE": 
"DOWN"}))
+
+                # while not empty, i.e. starts with CH_TXT_TRACKED_DUMMY_CHAR
+                while len(get_state_as_dict(xWriterEdit)["SelectedText"]):
+                    xToolkit.processEventsToIdle()
+
+                # reject column insertion
+
+                xAccBtn = xTrackDlg.getChild("reject")
+                # Without the fix in place, it would have crashed here
+                xAccBtn.executeAction("CLICK", tuple())
+
+                # inserted column is removed
+
+                self.assertEqual(len(tables[0].getColumns()), 3)
+
+                # single parent left in the dialog window
+                self.assertEqual(1, len(changesList.getChildren()))
+
+                # accept column deletion
+
+                xAccBtn = xTrackDlg.getChild("accept")
+                xAccBtn.executeAction("CLICK", tuple())
+
+                # deleted column is removed
+
+                self.assertEqual(len(tables[0].getColumns()), 2)
+
+                # no changes in the dialog window
+
+                self.assertEqual(0, len(changesList.getChildren()))
+
 # vim: set shiftwidth=4 softtabstop=4 expandtab:
diff --git a/sw/source/uibase/inc/redlndlg.hxx 
b/sw/source/uibase/inc/redlndlg.hxx
index 7337f1fadce4..c8cfd8cc8262 100644
--- a/sw/source/uibase/inc/redlndlg.hxx
+++ b/sw/source/uibase/inc/redlndlg.hxx
@@ -77,6 +77,9 @@ class SW_DLLPUBLIC SwRedlineAcceptDlg final
     // prevent update dialog data during longer operations (cf #102657#)
     bool                    m_bInhibitActivate;
 
+    // table column changes have not continuous redline ranges: it needs major 
tree list update
+    bool                    m_bHasTrackedColumn;
+
     std::unique_ptr<SvxAcceptChgCtr> m_xTabPagesCTRL;
     std::unique_ptr<weld::Menu> m_xPopup, m_xSortMenu;
     SvxTPView* m_pTPView;
diff --git a/sw/source/uibase/misc/redlndlg.cxx 
b/sw/source/uibase/misc/redlndlg.cxx
index 35a15fa940e3..1a9d168bee61 100644
--- a/sw/source/uibase/misc/redlndlg.cxx
+++ b/sw/source/uibase/misc/redlndlg.cxx
@@ -153,6 +153,7 @@ 
SwRedlineAcceptDlg::SwRedlineAcceptDlg(std::shared_ptr<weld::Window> xParent, we
     , m_bOnlyFormatedRedlines(false)
     , m_bRedlnAutoFormat(bAutoFormat)
     , m_bInhibitActivate(false)
+    , m_bHasTrackedColumn(false)
     , m_xTabPagesCTRL(new SvxAcceptChgCtr(pContentArea))
     , m_xPopup(pBuilder->weld_menu("writermenu"))
     , m_xSortMenu(pBuilder->weld_menu("writersortmenu"))
@@ -489,7 +490,7 @@ void SwRedlineAcceptDlg::Activate()
 
 SwRedlineTable::size_type 
SwRedlineAcceptDlg::CalcDiff(SwRedlineTable::size_type nStart, bool bChild)
 {
-    if (!nStart)
+    if (!nStart || m_bHasTrackedColumn)
     {
         Init();
         return SwRedlineTable::npos;
@@ -767,6 +768,10 @@ void 
SwRedlineAcceptDlg::InsertParents(SwRedlineTable::size_type nStart, SwRedli
     SwRedlineTable::size_type nCount = pSh->GetRedlineCount();
     nEnd = std::min(nEnd, (nCount - 1)); // also treats 
nEnd=SwRedlineTable::npos (until the end)
 
+    // reset m_bHasTrackedColumn before searching tracked column again
+    if ( m_bHasTrackedColumn && nStart == 0 )
+        m_bHasTrackedColumn = false;
+
     if (nEnd == SwRedlineTable::npos)
         return;     // no redlines in the document
 
@@ -872,6 +877,12 @@ void 
SwRedlineAcceptDlg::InsertParents(SwRedlineTable::size_type nStart, SwRedli
                     // table redline didn't fit in the stored ones, create new 
parent
                     aTableParents.push_back(i);
                 }
+
+                // it needs major tree update later because of tracked table 
columns
+                if ( !m_bHasTrackedColumn && !bRowChange )
+                {
+                    m_bHasTrackedColumn = true;
+                }
             }
             else
             {

Reply via email to