[Libreoffice-commits] core.git: Branch 'feature/cib_contract891c' - 4 commits - sw/qa sw/source

Serge Krot (via logerrit) logerrit at kemper.freedesktop.org
Tue Aug 17 06:36:19 UTC 2021


 sw/qa/extras/uiwriter/data/tdf113877_blank.odt                     |binary
 sw/qa/extras/uiwriter/data/tdf113877_blank_bold_off.odt            |binary
 sw/qa/extras/uiwriter/data/tdf113877_blank_bold_on.odt             |binary
 sw/qa/extras/uiwriter/data/tdf113877_blank_ownStandard.odt         |binary
 sw/qa/extras/uiwriter/data/tdf113877_insert_numbered_list.odt      |binary
 sw/qa/extras/uiwriter/data/tdf113877_insert_numbered_list_abcd.odt |binary
 sw/qa/extras/uiwriter/uiwriter.cxx                                 |  136 ++++++
 sw/source/core/txtnode/ndtxt.cxx                                   |   45 ++
 sw/source/filter/xml/xmlimp.cxx                                    |  208 ++++++++++
 sw/source/filter/xml/xmlimp.hxx                                    |    1 
 10 files changed, 389 insertions(+), 1 deletion(-)

New commits:
commit 9f1a4dfa29354155eebf589174dfeed60b7884f2
Author:     Serge Krot <Serge.Krot at cib.de>
AuthorDate: Thu Oct 8 09:01:33 2020 +0200
Commit:     Samuel Mehrbrodt <samuel.mehrbrodt at allotropia.de>
CommitDate: Mon Aug 16 13:50:23 2021 +0000

    tdf#132289 missing styles when inserting file with list
    
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/104085
    Tested-by: Jenkins
    Reviewed-by: Thorsten Behrens <Thorsten.Behrens at CIB.de>
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/104319
    Tested-by: Thorsten Behrens <Thorsten.Behrens at CIB.de>
    (cherry picked from commit 92c05bd1f8ef695a56718c4b54babbe757ab9b89)
    
    Change-Id: I444997a6cc55cfe287f4c610f538f2f54803646c

diff --git a/sw/qa/extras/uiwriter/data/tdf113877_blank_bold_off.odt b/sw/qa/extras/uiwriter/data/tdf113877_blank_bold_off.odt
new file mode 100644
index 000000000000..f4d58da53b95
Binary files /dev/null and b/sw/qa/extras/uiwriter/data/tdf113877_blank_bold_off.odt differ
diff --git a/sw/qa/extras/uiwriter/data/tdf113877_blank_bold_on.odt b/sw/qa/extras/uiwriter/data/tdf113877_blank_bold_on.odt
new file mode 100644
index 000000000000..8de77fc6161c
Binary files /dev/null and b/sw/qa/extras/uiwriter/data/tdf113877_blank_bold_on.odt differ
diff --git a/sw/qa/extras/uiwriter/uiwriter.cxx b/sw/qa/extras/uiwriter/uiwriter.cxx
index 18ce6702c239..d11cf4e2d3f8 100755
--- a/sw/qa/extras/uiwriter/uiwriter.cxx
+++ b/sw/qa/extras/uiwriter/uiwriter.cxx
@@ -248,6 +248,11 @@ public:
     void testTdf105417();
     void testTdf105625();
     void testTdf106736();
+
+    void testTdf113877_mergeDocs(const char* aDestDoc, const char* aInsertDoc);
+    void testTdf113877_blank_bold_on();
+    void testTdf113877_blank_bold_off();
+
     void testMsWordCompTrailingBlanks();
     void testCreateDocxAnnotation();
     void testTdf107976();
@@ -392,6 +397,8 @@ public:
     CPPUNIT_TEST(testTdf105417);
     CPPUNIT_TEST(testTdf105625);
     CPPUNIT_TEST(testTdf106736);
+    CPPUNIT_TEST(testTdf113877_blank_bold_on);
+    CPPUNIT_TEST(testTdf113877_blank_bold_off);
     CPPUNIT_TEST(testMsWordCompTrailingBlanks);
     CPPUNIT_TEST(testCreateDocxAnnotation);
     CPPUNIT_TEST(testTdf107976);
@@ -5040,11 +5047,9 @@ void SwUiWriterTest::testTdf113790()
     CPPUNIT_ASSERT(dynamic_cast<SwXTextDocument *>(mxComponent.get()));
 }
 
-// During insert of the document with list inside into the main document inside the list
-// we should merge both lists into one, when they have the same list properties
-void SwUiWriterTest::testTdf113877()
+void SwUiWriterTest::testTdf113877_mergeDocs(const char* aDestDoc, const char* aInsertDoc)
 {
-    load(DATA_DIRECTORY, "tdf113877_insert_numbered_list.odt");
+    load(DATA_DIRECTORY, aDestDoc);
 
     // set a page cursor into the end of the document
     uno::Reference<frame::XModel> xModel(mxComponent, uno::UNO_QUERY);
@@ -5054,10 +5059,17 @@ void SwUiWriterTest::testTdf113877()
 
     // insert the same document at current cursor position
     {
-        const OUString insertFileid = m_directories.getURLFromSrc(DATA_DIRECTORY) + "tdf113877_insert_numbered_list.odt";
+        const OUString insertFileid = m_directories.getURLFromSrc(DATA_DIRECTORY) + OUString::createFromAscii(aInsertDoc);
         uno::Sequence<beans::PropertyValue> aPropertyValues(comphelper::InitPropertySequence({ { "Name", uno::makeAny(insertFileid) } }));
         lcl_dispatchCommand(mxComponent, ".uno:InsertDoc", aPropertyValues);
     }
+}
+
+// During insert of the document with list inside into the main document inside the list
+// we should merge both lists into one, when they have the same list properties
+void SwUiWriterTest::testTdf113877()
+{
+    testTdf113877_mergeDocs("tdf113877_insert_numbered_list.odt", "tdf113877_insert_numbered_list.odt");
 
     const OUString listId1 = getProperty<OUString>(getParagraph(1), "ListId");
     const OUString listId4 = getProperty<OUString>(getParagraph(4), "ListId");
@@ -5077,20 +5089,7 @@ void SwUiWriterTest::testTdf113877()
 // The same test as testTdf113877() but merging of two list should not be performed.
 void SwUiWriterTest::testTdf113877NoMerge()
 {
-    load(DATA_DIRECTORY, "tdf113877_insert_numbered_list.odt");
-
-    // set a page cursor into the end of the document
-    uno::Reference<frame::XModel> xModel(mxComponent, uno::UNO_QUERY);
-    uno::Reference<text::XTextViewCursorSupplier> xTextViewCursorSupplier(xModel->getCurrentController(), uno::UNO_QUERY);
-    uno::Reference<text::XPageCursor> xCursor(xTextViewCursorSupplier->getViewCursor(), uno::UNO_QUERY);
-    xCursor->jumpToEndOfPage();
-
-    // insert the same document at current cursor position
-    {
-        const OUString insertFileid = m_directories.getURLFromSrc(DATA_DIRECTORY) + "tdf113877_insert_numbered_list_abcd.odt";
-        uno::Sequence<beans::PropertyValue> aPropertyValues(comphelper::InitPropertySequence({ { "Name", uno::makeAny(insertFileid) } }));
-        lcl_dispatchCommand(mxComponent, ".uno:InsertDoc", aPropertyValues);
-    }
+    testTdf113877_mergeDocs("tdf113877_insert_numbered_list.odt", "tdf113877_insert_numbered_list_abcd.odt");
 
     const OUString listId1 = getProperty<OUString>(getParagraph(1), "ListId");
     const OUString listId4 = getProperty<OUString>(getParagraph(4), "ListId");
@@ -5116,20 +5115,7 @@ void SwUiWriterTest::testTdf113877NoMerge()
 //
 void SwUiWriterTest::testTdf113877_default_style()
 {
-    load(DATA_DIRECTORY, "tdf113877_blank.odt");
-
-    // set a page cursor into the end of the document
-    uno::Reference<frame::XModel> xModel(mxComponent, uno::UNO_QUERY);
-    uno::Reference<text::XTextViewCursorSupplier> xTextViewCursorSupplier(xModel->getCurrentController(), uno::UNO_QUERY);
-    uno::Reference<text::XPageCursor> xCursor(xTextViewCursorSupplier->getViewCursor(), uno::UNO_QUERY);
-    xCursor->jumpToEndOfPage();
-
-    // insert the same document at current cursor position
-    {
-        const OUString insertFileid = m_directories.getURLFromSrc(DATA_DIRECTORY) + "tdf113877_insert_numbered_list_abcd.odt";
-        uno::Sequence<beans::PropertyValue> aPropertyValues(comphelper::InitPropertySequence({ { "Name", uno::makeAny(insertFileid) } }));
-        lcl_dispatchCommand(mxComponent, ".uno:InsertDoc", aPropertyValues);
-    }
+    testTdf113877_mergeDocs("tdf113877_blank.odt", "tdf113877_insert_numbered_list_abcd.odt");
 
     const OUString listId1 = getProperty<OUString>(getParagraph(1), "ListId");
     const OUString listId2 = getProperty<OUString>(getParagraph(2), "ListId");
@@ -5148,20 +5134,31 @@ void SwUiWriterTest::testTdf113877_default_style()
 //
 void SwUiWriterTest::testTdf113877_Standard_style()
 {
-    load(DATA_DIRECTORY, "tdf113877_blank_ownStandard.odt");
+    testTdf113877_mergeDocs("tdf113877_blank_ownStandard.odt", "tdf113877_insert_numbered_list_abcd.odt");
 
-    // set a page cursor into the end of the document
-    uno::Reference<frame::XModel> xModel(mxComponent, uno::UNO_QUERY);
-    uno::Reference<text::XTextViewCursorSupplier> xTextViewCursorSupplier(xModel->getCurrentController(), uno::UNO_QUERY);
-    uno::Reference<text::XPageCursor> xCursor(xTextViewCursorSupplier->getViewCursor(), uno::UNO_QUERY);
-    xCursor->jumpToEndOfPage();
+    const OUString listId1 = getProperty<OUString>(getParagraph(1), "ListId");
+    const OUString listId2 = getProperty<OUString>(getParagraph(2), "ListId");
+    const OUString listId3 = getProperty<OUString>(getParagraph(3), "ListId");
 
-    // insert the same document at current cursor position
-    {
-        const OUString insertFileid = m_directories.getURLFromSrc(DATA_DIRECTORY) + "tdf113877_insert_numbered_list_abcd.odt";
-        uno::Sequence<beans::PropertyValue> aPropertyValues(comphelper::InitPropertySequence({ { "Name", uno::makeAny(insertFileid) } }));
-        lcl_dispatchCommand(mxComponent, ".uno:InsertDoc", aPropertyValues);
-    }
+    CPPUNIT_ASSERT_EQUAL(listId1, listId2);
+    CPPUNIT_ASSERT_EQUAL(listId1, listId3);
+}
+
+void SwUiWriterTest::testTdf113877_blank_bold_on()
+{
+    testTdf113877_mergeDocs("tdf113877_blank_bold_on.odt", "tdf113877_insert_numbered_list_abcd.odt");
+
+    const OUString listId1 = getProperty<OUString>(getParagraph(1), "ListId");
+    const OUString listId2 = getProperty<OUString>(getParagraph(2), "ListId");
+    const OUString listId3 = getProperty<OUString>(getParagraph(3), "ListId");
+
+    CPPUNIT_ASSERT_EQUAL(listId1, listId2);
+    CPPUNIT_ASSERT_EQUAL(listId1, listId3);
+}
+
+void SwUiWriterTest::testTdf113877_blank_bold_off()
+{
+    testTdf113877_mergeDocs("tdf113877_blank_bold_off.odt", "tdf113877_insert_numbered_list_abcd.odt");
 
     const OUString listId1 = getProperty<OUString>(getParagraph(1), "ListId");
     const OUString listId2 = getProperty<OUString>(getParagraph(2), "ListId");
diff --git a/sw/source/core/txtnode/ndtxt.cxx b/sw/source/core/txtnode/ndtxt.cxx
index e370fb63702e..d86005954878 100755
--- a/sw/source/core/txtnode/ndtxt.cxx
+++ b/sw/source/core/txtnode/ndtxt.cxx
@@ -2123,11 +2123,13 @@ void SwTextNode::CutImpl( SwTextNode * const pDest, const SwIndex & rDestStart,
                 while( true )
                 {
                     // check current item
-                    sal_uInt16 nWhich = IsInvalidItem( pItem )
+                    const sal_uInt16 nWhich = IsInvalidItem( pItem )
                         ? pDest->GetpSwAttrSet()->GetWhichByPos( aIter.GetCurPos() )
                         : pItem->Which();
                     if( RES_FRMATR_STYLE_NAME != nWhich &&
                         RES_FRMATR_CONDITIONAL_STYLE_NAME != nWhich &&
+                        RES_PAGEDESC != nWhich &&
+                        RES_BREAK != nWhich &&
                         SfxItemState::SET == pDest->GetpSwAttrSet()->GetItemState( nWhich, false ) )
                     {
                         // check if parent value (original value in style) has the same value as in [pItem]
diff --git a/sw/source/filter/xml/xmlimp.cxx b/sw/source/filter/xml/xmlimp.cxx
index 02d975a69afc..8fc0a4634dd5 100644
--- a/sw/source/filter/xml/xmlimp.cxx
+++ b/sw/source/filter/xml/xmlimp.cxx
@@ -776,7 +776,10 @@ void SwXMLImport::endDocument()
                 if (!pTextNode->GetText().isEmpty())
                     pDelNd->FormatToTextAttr( pTextNode );
                 else
+                {
+                    pTextNode->ResetAttr(RES_CHRATR_BEGIN, RES_CHRATR_END);
                     pTextNode->ChgFormatColl( pDelNd->GetTextColl() );
+                }
                 pTextNode->JoinNext();
             }
         }
commit ef4afe78b4671ee6503b8d13cc77cece54bda202
Author:     Serge Krot <Serge.Krot at cib.de>
AuthorDate: Mon Jun 18 18:15:55 2018 +0200
Commit:     Samuel Mehrbrodt <samuel.mehrbrodt at allotropia.de>
CommitDate: Mon Aug 16 13:50:03 2021 +0000

    tdf#113877 Insert doc: merge list into text with specifc style
    
    When inserting document, in the current position the text could have custom
    style but really it is the same Standard style. Therefore we should not
    merge first inserted node into the insert position and just overwrite
    style in the insert position with text style from the inserted node.
    
    Reviewed-on: https://gerrit.libreoffice.org/56052
    Tested-by: Jenkins
    Reviewed-by: Thorsten Behrens <Thorsten.Behrens at CIB.de>
    Reviewed-on: https://gerrit.libreoffice.org/56408
    Tested-by: Thorsten Behrens <Thorsten.Behrens at CIB.de>
    (cherry picked from commit e78239c928de1c73a7dda5a37ff38a1407ced052)
    
    Change-Id: Ib67c56bed3d30f356f83dc0b4d4a1710def10853

diff --git a/sw/qa/extras/uiwriter/data/tdf113877_blank.odt b/sw/qa/extras/uiwriter/data/tdf113877_blank.odt
new file mode 100755
index 000000000000..741d7d5e6d0a
Binary files /dev/null and b/sw/qa/extras/uiwriter/data/tdf113877_blank.odt differ
diff --git a/sw/qa/extras/uiwriter/data/tdf113877_blank_ownStandard.odt b/sw/qa/extras/uiwriter/data/tdf113877_blank_ownStandard.odt
new file mode 100755
index 000000000000..3dbebda6f93c
Binary files /dev/null and b/sw/qa/extras/uiwriter/data/tdf113877_blank_ownStandard.odt differ
diff --git a/sw/qa/extras/uiwriter/uiwriter.cxx b/sw/qa/extras/uiwriter/uiwriter.cxx
old mode 100644
new mode 100755
index 21123886f853..18ce6702c239
--- a/sw/qa/extras/uiwriter/uiwriter.cxx
+++ b/sw/qa/extras/uiwriter/uiwriter.cxx
@@ -255,6 +255,8 @@ public:
     void testTdf114536();
     void testTdf113877();
     void testTdf113877NoMerge();
+    void testTdf113877_default_style();
+    void testTdf113877_Standard_style();
 
     CPPUNIT_TEST_SUITE(SwUiWriterTest);
     CPPUNIT_TEST(testReplaceForward);
@@ -397,6 +399,8 @@ public:
     CPPUNIT_TEST(testTdf114536);
     CPPUNIT_TEST(testTdf113877);
     CPPUNIT_TEST(testTdf113877NoMerge);
+    CPPUNIT_TEST(testTdf113877_default_style);
+    CPPUNIT_TEST(testTdf113877_Standard_style);
     CPPUNIT_TEST_SUITE_END();
 
 private:
@@ -5103,6 +5107,70 @@ void SwUiWriterTest::testTdf113877NoMerge()
     CPPUNIT_ASSERT(listId6 != listId7);
 }
 
+// Related test to testTdf113877(): Inserting into empty document a new document with list.
+// Insert position has NO its own paragraph style ("Standard" will be used).
+//
+// Resulting document should be the same for following tests:
+// - testTdf113877_default_style()
+// - testTdf113877_Standard_style()
+//
+void SwUiWriterTest::testTdf113877_default_style()
+{
+    load(DATA_DIRECTORY, "tdf113877_blank.odt");
+
+    // set a page cursor into the end of the document
+    uno::Reference<frame::XModel> xModel(mxComponent, uno::UNO_QUERY);
+    uno::Reference<text::XTextViewCursorSupplier> xTextViewCursorSupplier(xModel->getCurrentController(), uno::UNO_QUERY);
+    uno::Reference<text::XPageCursor> xCursor(xTextViewCursorSupplier->getViewCursor(), uno::UNO_QUERY);
+    xCursor->jumpToEndOfPage();
+
+    // insert the same document at current cursor position
+    {
+        const OUString insertFileid = m_directories.getURLFromSrc(DATA_DIRECTORY) + "tdf113877_insert_numbered_list_abcd.odt";
+        uno::Sequence<beans::PropertyValue> aPropertyValues(comphelper::InitPropertySequence({ { "Name", uno::makeAny(insertFileid) } }));
+        lcl_dispatchCommand(mxComponent, ".uno:InsertDoc", aPropertyValues);
+    }
+
+    const OUString listId1 = getProperty<OUString>(getParagraph(1), "ListId");
+    const OUString listId2 = getProperty<OUString>(getParagraph(2), "ListId");
+    const OUString listId3 = getProperty<OUString>(getParagraph(3), "ListId");
+
+    CPPUNIT_ASSERT_EQUAL(listId1, listId2);
+    CPPUNIT_ASSERT_EQUAL(listId1, listId3);
+}
+
+// Related test to testTdf113877(): Inserting into empty document a new document with list.
+// Insert position has its own paragraph style derived from "Standard", but this style is the same as "Standard".
+//
+// Resulting document should be the same for following tests:
+// - testTdf113877_default_style()
+// - testTdf113877_Standard_style()
+//
+void SwUiWriterTest::testTdf113877_Standard_style()
+{
+    load(DATA_DIRECTORY, "tdf113877_blank_ownStandard.odt");
+
+    // set a page cursor into the end of the document
+    uno::Reference<frame::XModel> xModel(mxComponent, uno::UNO_QUERY);
+    uno::Reference<text::XTextViewCursorSupplier> xTextViewCursorSupplier(xModel->getCurrentController(), uno::UNO_QUERY);
+    uno::Reference<text::XPageCursor> xCursor(xTextViewCursorSupplier->getViewCursor(), uno::UNO_QUERY);
+    xCursor->jumpToEndOfPage();
+
+    // insert the same document at current cursor position
+    {
+        const OUString insertFileid = m_directories.getURLFromSrc(DATA_DIRECTORY) + "tdf113877_insert_numbered_list_abcd.odt";
+        uno::Sequence<beans::PropertyValue> aPropertyValues(comphelper::InitPropertySequence({ { "Name", uno::makeAny(insertFileid) } }));
+        lcl_dispatchCommand(mxComponent, ".uno:InsertDoc", aPropertyValues);
+    }
+
+    const OUString listId1 = getProperty<OUString>(getParagraph(1), "ListId");
+    const OUString listId2 = getProperty<OUString>(getParagraph(2), "ListId");
+    const OUString listId3 = getProperty<OUString>(getParagraph(3), "ListId");
+
+    CPPUNIT_ASSERT_EQUAL(listId1, listId2);
+    CPPUNIT_ASSERT_EQUAL(listId1, listId3);
+}
+
 CPPUNIT_TEST_SUITE_REGISTRATION(SwUiWriterTest);
 CPPUNIT_PLUGIN_IMPLEMENT();
 
diff --git a/sw/source/core/txtnode/ndtxt.cxx b/sw/source/core/txtnode/ndtxt.cxx
old mode 100644
new mode 100755
index 6f9092e9295d..e370fb63702e
--- a/sw/source/core/txtnode/ndtxt.cxx
+++ b/sw/source/core/txtnode/ndtxt.cxx
@@ -2107,8 +2107,49 @@ void SwTextNode::CutImpl( SwTextNode * const pDest, const SwIndex & rDestStart,
     // copy hard attributes on whole paragraph
     if (HasSwAttrSet())
     {
+        bool hasSwAttrSet = pDest->HasSwAttrSet();
+        if (hasSwAttrSet)
+        {
+            // if we have our own property set it doesn't mean
+            // that this set defines any style different to Standard one.
+            hasSwAttrSet = false;
+
+            // so, let's check deeper if property set has defined any property
+            if (pDest->GetpSwAttrSet())
+            {
+                // check all items in the property set
+                SfxItemIter aIter( *pDest->GetpSwAttrSet() );
+                const SfxPoolItem* pItem = aIter.GetCurItem();
+                while( true )
+                {
+                    // check current item
+                    sal_uInt16 nWhich = IsInvalidItem( pItem )
+                        ? pDest->GetpSwAttrSet()->GetWhichByPos( aIter.GetCurPos() )
+                        : pItem->Which();
+                    if( RES_FRMATR_STYLE_NAME != nWhich &&
+                        RES_FRMATR_CONDITIONAL_STYLE_NAME != nWhich &&
+                        SfxItemState::SET == pDest->GetpSwAttrSet()->GetItemState( nWhich, false ) )
+                    {
+                        // check if parent value (original value in style) has the same value as in [pItem]
+                        const SfxPoolItem&  rParentItem = pDest->GetpSwAttrSet()->GetParent()->Get( nWhich, true );
+
+                        hasSwAttrSet = (rParentItem != *pItem);
+
+                        // property set is not empty => no need to make anymore checks
+                        if (hasSwAttrSet)
+                            break;
+                    }
+
+                    // let's check next item
+                    if( aIter.IsAtEnd() )
+                        break;
+                    pItem = aIter.NextItem();
+                }
+            }
+        }
+
         // all or just the Char attributes?
-        if( nInitSize || pDest->HasSwAttrSet() ||
+        if( nInitSize || hasSwAttrSet ||
             nLen != pDest->GetText().getLength())
         {
             SfxItemSet aCharSet( pDest->GetDoc()->GetAttrPool(),
commit cd1275f2edbe60d7aa3f2ec4096dbe79e633bf53
Author:     Serge Krot <Serge.Krot at cib.de>
AuthorDate: Fri Jan 12 13:55:59 2018 +0100
Commit:     Samuel Mehrbrodt <samuel.mehrbrodt at allotropia.de>
CommitDate: Mon Aug 16 13:49:36 2021 +0000

    tdf#113877 Insert document: merge two lists into one
    
    When inserting a new document into current position we need to
    concat to lists into one only when they have the same list
    properties.
    
    (cherry picked from commit 311ea730cb225bca167af2e4111445608a14a263)
    
    Reviewed-on: https://gerrit.libreoffice.org/47913
    Reviewed-by: Thorsten Behrens <Thorsten.Behrens at CIB.de>
    Tested-by: Thorsten Behrens <Thorsten.Behrens at CIB.de>
    (cherry picked from commit 1b04fae2b10d258d71e9e29ea659495b6d949367)
    
    Change-Id: I2766d5856418338fd5920968ac136899eeac7d74

diff --git a/sw/qa/extras/uiwriter/data/tdf113877_insert_numbered_list_abcd.odt b/sw/qa/extras/uiwriter/data/tdf113877_insert_numbered_list_abcd.odt
new file mode 100755
index 000000000000..47fe7e0760fe
Binary files /dev/null and b/sw/qa/extras/uiwriter/data/tdf113877_insert_numbered_list_abcd.odt differ
diff --git a/sw/qa/extras/uiwriter/uiwriter.cxx b/sw/qa/extras/uiwriter/uiwriter.cxx
index 6f7e2f23158a..21123886f853 100644
--- a/sw/qa/extras/uiwriter/uiwriter.cxx
+++ b/sw/qa/extras/uiwriter/uiwriter.cxx
@@ -254,6 +254,7 @@ public:
     void testTdf113790();
     void testTdf114536();
     void testTdf113877();
+    void testTdf113877NoMerge();
 
     CPPUNIT_TEST_SUITE(SwUiWriterTest);
     CPPUNIT_TEST(testReplaceForward);
@@ -395,6 +396,7 @@ public:
     CPPUNIT_TEST(testTdf113790);
     CPPUNIT_TEST(testTdf114536);
     CPPUNIT_TEST(testTdf113877);
+    CPPUNIT_TEST(testTdf113877NoMerge);
     CPPUNIT_TEST_SUITE_END();
 
 private:
@@ -5034,6 +5036,8 @@ void SwUiWriterTest::testTdf113790()
     CPPUNIT_ASSERT(dynamic_cast<SwXTextDocument *>(mxComponent.get()));
 }
 
+// During insert of the document with list inside into the main document inside the list
+// we should merge both lists into one, when they have the same list properties
 void SwUiWriterTest::testTdf113877()
 {
     load(DATA_DIRECTORY, "tdf113877_insert_numbered_list.odt");
@@ -5051,13 +5055,52 @@ void SwUiWriterTest::testTdf113877()
         lcl_dispatchCommand(mxComponent, ".uno:InsertDoc", aPropertyValues);
     }
 
+    const OUString listId1 = getProperty<OUString>(getParagraph(1), "ListId");
+    const OUString listId4 = getProperty<OUString>(getParagraph(4), "ListId");
+    const OUString listId5 = getProperty<OUString>(getParagraph(5), "ListId");
+    const OUString listId6 = getProperty<OUString>(getParagraph(6), "ListId");
+    const OUString listId7 = getProperty<OUString>(getParagraph(7), "ListId");
+
+    // the initial list with 4 list items
+    CPPUNIT_ASSERT_EQUAL(listId1, listId4);
+
+    // the last of the first list, and the first of the inserted list
+    CPPUNIT_ASSERT_EQUAL(listId4, listId5);
+    CPPUNIT_ASSERT_EQUAL(listId5, listId6);
+    CPPUNIT_ASSERT_EQUAL(listId6, listId7);
+}
+
+// The same test as testTdf113877() but merging of two list should not be performed.
+void SwUiWriterTest::testTdf113877NoMerge()
+{
+    load(DATA_DIRECTORY, "tdf113877_insert_numbered_list.odt");
+
+    // set a page cursor into the end of the document
+    uno::Reference<frame::XModel> xModel(mxComponent, uno::UNO_QUERY);
+    uno::Reference<text::XTextViewCursorSupplier> xTextViewCursorSupplier(xModel->getCurrentController(), uno::UNO_QUERY);
+    uno::Reference<text::XPageCursor> xCursor(xTextViewCursorSupplier->getViewCursor(), uno::UNO_QUERY);
+    xCursor->jumpToEndOfPage();
+
+    // insert the same document at current cursor position
+    {
+        const OUString insertFileid = m_directories.getURLFromSrc(DATA_DIRECTORY) + "tdf113877_insert_numbered_list_abcd.odt";
+        uno::Sequence<beans::PropertyValue> aPropertyValues(comphelper::InitPropertySequence({ { "Name", uno::makeAny(insertFileid) } }));
+        lcl_dispatchCommand(mxComponent, ".uno:InsertDoc", aPropertyValues);
+    }
+
+    const OUString listId1 = getProperty<OUString>(getParagraph(1), "ListId");
+    const OUString listId4 = getProperty<OUString>(getParagraph(4), "ListId");
+    const OUString listId5 = getProperty<OUString>(getParagraph(5), "ListId");
+    const OUString listId6 = getProperty<OUString>(getParagraph(6), "ListId");
+    const OUString listId7 = getProperty<OUString>(getParagraph(7), "ListId");
+
     // the initial list with 4 list items
-    CPPUNIT_ASSERT_EQUAL(getProperty<OUString>(getParagraph(1), "ListId"), getProperty<OUString>(getParagraph(4), "ListId"));
+    CPPUNIT_ASSERT_EQUAL(listId1, listId4);
 
     // the last of the first list, and the first of the inserted list
-    CPPUNIT_ASSERT_EQUAL(getProperty<OUString>(getParagraph(4), "ListId"), getProperty<OUString>(getParagraph(5), "ListId"));
-    CPPUNIT_ASSERT_EQUAL(getProperty<OUString>(getParagraph(5), "ListId"), getProperty<OUString>(getParagraph(6), "ListId"));
-    CPPUNIT_ASSERT_EQUAL(getProperty<OUString>(getParagraph(6), "ListId"), getProperty<OUString>(getParagraph(7), "ListId"));
+    CPPUNIT_ASSERT(listId4 != listId5);
+    CPPUNIT_ASSERT_EQUAL(listId5, listId6);
+    CPPUNIT_ASSERT(listId6 != listId7);
 }
 
 CPPUNIT_TEST_SUITE_REGISTRATION(SwUiWriterTest);
diff --git a/sw/source/filter/xml/xmlimp.cxx b/sw/source/filter/xml/xmlimp.cxx
index 2231d5f36af9..02d975a69afc 100644
--- a/sw/source/filter/xml/xmlimp.cxx
+++ b/sw/source/filter/xml/xmlimp.cxx
@@ -40,6 +40,7 @@
 #include <drawdoc.hxx>
 #include <IDocumentSettingAccess.hxx>
 #include <IDocumentDeviceAccess.hxx>
+#include <IDocumentListsAccess.hxx>
 #include <IDocumentStylePoolAccess.hxx>
 #include <IDocumentDrawModelAccess.hxx>
 #include <unofreg.hxx>
@@ -51,8 +52,11 @@
 #include <ndtxt.hxx>
 #include <editsh.hxx>
 #include <poolfmt.hrc>
+#include <svl/stritem.hxx>
 #include "xmlimp.hxx"
 #include "xmltexti.hxx"
+#include <list.hxx>
+#include <swdll.hxx>
 #include <xmloff/DocumentSettingsContext.hxx>
 #include <docsh.hxx>
 #include <editeng/unolingu.hxx>
@@ -835,7 +839,7 @@ void SwXMLImport::endDocument()
 
             // tdf#113877
             // when we insert one document with list inside into another one with list at the insert position,
-            // the resulting numbering in these lists are not consequent.
+            // the resulting numbering in these lists is not consequent.
             //
             // Main document:
             //  1. One
@@ -858,65 +862,7 @@ void SwXMLImport::endDocument()
             //  6. Three
             //  7.
             //
-            if (IsInsertMode() && m_pSttNdIdx->GetIndex())
-            {
-                sal_uLong index = 1;
-
-                // the last node of the main document where we have inserted a document
-                SwNode * p1 = pDoc->GetNodes()[m_pSttNdIdx->GetIndex() + 0];
-
-                // the first node of the inserted document
-                SwNode * p2 = pDoc->GetNodes()[m_pSttNdIdx->GetIndex() + index];
-
-                // the first node of the inserted document,
-                // which will be used to detect if inside inserted document a new list was started
-                const SfxPoolItem* listId2Initial = nullptr;
-
-                while (
-                    p1 && p2
-                    && (p1->GetNodeType() == p2->GetNodeType())
-                    && (p1->IsTextNode() == p2->IsTextNode())
-                    )
-                {
-                    SwContentNode * c1 = static_cast<SwContentNode *>(p1);
-                    SwContentNode * c2 = static_cast<SwContentNode *>(p2);
-
-                    const SfxPoolItem* listId1 = c1->GetNoCondAttr(RES_PARATR_LIST_ID, false);
-                    const SfxPoolItem* listId2 = c2->GetNoCondAttr(RES_PARATR_LIST_ID, false);
-
-                    if (!listId2Initial)
-                    {
-                        listId2Initial = listId2;
-                    }
-
-                    if (! (listId2Initial && listId2 && (*listId2Initial == *listId2)) )
-                    {
-                        // no more list items of the first list inside inserted document
-                        break;
-                    }
-
-                    if (listId1 && listId2)
-                    {
-                        c2->SetAttr(*listId1);
-                    }
-                    else
-                    {
-                        // no more appropriate list items
-                        break;
-                    }
-
-                    // get next item
-                    index++;
-                    if (index >= pDoc->GetNodes().Count())
-                    {
-                        // no more items
-                        break;
-                    }
-
-                    p2 = pDoc->GetNodes()[m_pSttNdIdx->GetIndex() + index];
-                }
-            }
-
+            MergeListsAtDocumentInsertPosition(pDoc);
         }
     }
 
@@ -991,6 +937,180 @@ void SwXMLImport::endDocument()
     ClearTextImport();
 }
 
+// tdf#113877
+// when we insert one document with list inside into another one with list at the insert position,
+// the resulting numbering in these lists is not consequent.
+//
+// CASE-1: Main document:
+//  1. One
+//  2. Two
+//  3. Three
+//  4.                      <-- insert position
+//
+// Inserted document:
+//  1. One
+//  2. Two
+//  3. Three
+//  4.
+//
+// Expected result
+//  1. One
+//  2. Two
+//  3. Three
+//  4. One
+//  5. Two
+//  6. Three
+//  7.
+//
+// CASE-2: Main document:
+//  1. One
+//  2. Two
+//  3. Three
+//  4.                      <-- insert position
+//
+// Inserted document:
+//  A) One
+//  B) Two
+//  C) Three
+//  D)
+//
+// Expected result
+//  1. One
+//  2. Two
+//  3. Three
+//  4. One
+//  A) Two
+//  B) Three
+//  5.
+//
+void SwXMLImport::MergeListsAtDocumentInsertPosition(SwDoc *pDoc)
+{
+    // 1. check enviroment
+    if (! pDoc)
+        return;
+
+    if (! IsInsertMode() || ! m_pSttNdIdx->GetIndex())
+        return;
+
+    sal_uLong index = 1;
+
+    // the last node of the main document where we have inserted a document
+    const SwNodePtr node1 = pDoc->GetNodes()[m_pSttNdIdx->GetIndex() + 0];
+
+    // the first node of the inserted document
+    SwNodePtr node2 = pDoc->GetNodes()[m_pSttNdIdx->GetIndex() + index];
+
+    if (! (node1 && node2
+        && (node1->GetNodeType() == node2->GetNodeType())
+        && (node1->IsTextNode() == node2->IsTextNode())
+        ))
+    {
+        // not a text node at insert position
+        return;
+    }
+
+    // 2. get the first node of the inserted document,
+    // which will be used to detect if inside inserted document a new list was started after the first list
+    const SfxPoolItem* pListId2Initial = nullptr;
+    {
+        SwContentNode* contentNode1 = static_cast<SwContentNode *>(node1);
+        SwContentNode* contentNode2 = static_cast<SwContentNode *>(node2);
+
+        // check if both lists have the same list properties
+        const SfxPoolItem* pListId1 = contentNode1->GetNoCondAttr( RES_PARATR_LIST_ID, false );
+        const SfxPoolItem* pListId2 = contentNode2->GetNoCondAttr( RES_PARATR_LIST_ID, false );
+
+        if (! pListId1)
+            return;
+        if (! pListId2)
+            return;
+
+        const OUString& sListId1 = dynamic_cast<const SfxStringItem*>(pListId1)->GetValue();
+        const OUString& sListId2 = dynamic_cast<const SfxStringItem*>(pListId2)->GetValue();
+
+        const SwList* pList1 = pDoc->getIDocumentListsAccess().getListByName( sListId1 );
+        const SwList* pList2 = pDoc->getIDocumentListsAccess().getListByName( sListId2 );
+
+        if (! pList1)
+            return;
+        if (! pList2)
+            return;
+
+        const OUString& sDefaultListStyleName1 = pList1->GetDefaultListStyleName();
+        const OUString& sDefaultListStyleName2 = pList2->GetDefaultListStyleName();
+
+        if (sDefaultListStyleName1 != sDefaultListStyleName2)
+        {
+            const SwNumRule* pNumRule1 = pDoc->FindNumRulePtr( sDefaultListStyleName1 );
+            const SwNumRule* pNumRule2 = pDoc->FindNumRulePtr( sDefaultListStyleName2 );
+
+            if (pNumRule1 && pNumRule2)
+            {
+                // check style of the each list level
+                for( sal_uInt8 n = 0; n < MAXLEVEL; ++n )
+                {
+                    if( !( pNumRule1->Get( n ) == pNumRule2->Get( n ) ))
+                    {
+                        return;
+                    }
+                }
+
+                // our list should be merged
+                pListId2Initial = pListId2;
+            }
+        }
+        else
+        {
+            // our list should be merged
+            pListId2Initial = pListId2;
+        }
+    }
+
+    if (! pListId2Initial)
+    {
+        // two lists have different styles => they should not be merged
+        return;
+    }
+
+    // 3. merge two lists
+    while (
+        node1 && node2
+        && (node1->GetNodeType() == node2->GetNodeType())
+        && (node1->IsTextNode() == node2->IsTextNode())
+        )
+    {
+        SwContentNode* contentNode1 = static_cast<SwContentNode *>( node1 );
+        SwContentNode* contentNode2 = static_cast<SwContentNode *>( node2 );
+
+        const SfxPoolItem* pListId1 = contentNode1->GetNoCondAttr( RES_PARATR_LIST_ID, false );
+        const SfxPoolItem* pListId2 = contentNode2->GetNoCondAttr( RES_PARATR_LIST_ID, false );
+
+        if (! pListId1)
+            return;
+        if (! pListId2)
+            return;
+
+        if (*pListId2Initial != *pListId2)
+        {
+            // no more list items of the first list inside inserted document
+            return;
+        }
+
+        // set list style to this list element
+        contentNode2->SetAttr(*pListId1);
+
+        // get next item
+        index++;
+        if (index >= pDoc->GetNodes().Count())
+        {
+            // no more items
+            return;
+        }
+
+        node2 = pDoc->GetNodes()[m_pSttNdIdx->GetIndex() + index];
+    }
+}
+
 // Locally derive XMLTextShapeImportHelper, so we can take care of the
 // form import This is Writer, but not text specific, so it should go
 // here!
diff --git a/sw/source/filter/xml/xmlimp.hxx b/sw/source/filter/xml/xmlimp.hxx
index e5f2eaa899cb..48aeef24873b 100644
--- a/sw/source/filter/xml/xmlimp.hxx
+++ b/sw/source/filter/xml/xmlimp.hxx
@@ -168,6 +168,7 @@ public:
     bool FindAutomaticStyle( sal_uInt16 nFamily,
                              const OUString& rName,
                              const SfxItemSet **ppItemSet ) const;
+    void MergeListsAtDocumentInsertPosition(SwDoc *pDoc);
 
     virtual void SetStatistics(
         const css::uno::Sequence< css::beans::NamedValue> & i_rStats) override;
commit 2f196d45af97e2e573783d603916edd9f3f9ef81
Author:     Serge Krot <Serge.Krot at cib.de>
AuthorDate: Fri Dec 22 12:56:40 2017 +0100
Commit:     Samuel Mehrbrodt <samuel.mehrbrodt at allotropia.de>
CommitDate: Mon Aug 16 13:49:09 2021 +0000

    tdf#113877 Insert document: merge two list into one
    
    When inserting a new document into current position we need to
    concat to lists into one.
    
    Added unit tests.
    
    Reviewed-on: https://gerrit.libreoffice.org/46991
    Reviewed-by: Thorsten Behrens <Thorsten.Behrens at CIB.de>
    Tested-by: Thorsten Behrens <Thorsten.Behrens at CIB.de>
    (cherry picked from commit c59e028e5337d1511dbcc678a90ffdbe92a44521)
    
    Change-Id: I10689256e0ffc5cf93722b1d45f09f610211b14a

diff --git a/sw/qa/extras/uiwriter/data/tdf113877_insert_numbered_list.odt b/sw/qa/extras/uiwriter/data/tdf113877_insert_numbered_list.odt
new file mode 100755
index 000000000000..db480edbebaf
Binary files /dev/null and b/sw/qa/extras/uiwriter/data/tdf113877_insert_numbered_list.odt differ
diff --git a/sw/qa/extras/uiwriter/uiwriter.cxx b/sw/qa/extras/uiwriter/uiwriter.cxx
index 02e8398c9618..6f7e2f23158a 100644
--- a/sw/qa/extras/uiwriter/uiwriter.cxx
+++ b/sw/qa/extras/uiwriter/uiwriter.cxx
@@ -253,6 +253,7 @@ public:
     void testTdf107976();
     void testTdf113790();
     void testTdf114536();
+    void testTdf113877();
 
     CPPUNIT_TEST_SUITE(SwUiWriterTest);
     CPPUNIT_TEST(testReplaceForward);
@@ -393,6 +394,7 @@ public:
     CPPUNIT_TEST(testTdf107976);
     CPPUNIT_TEST(testTdf113790);
     CPPUNIT_TEST(testTdf114536);
+    CPPUNIT_TEST(testTdf113877);
     CPPUNIT_TEST_SUITE_END();
 
 private:
@@ -5032,6 +5034,32 @@ void SwUiWriterTest::testTdf113790()
     CPPUNIT_ASSERT(dynamic_cast<SwXTextDocument *>(mxComponent.get()));
 }
 
+void SwUiWriterTest::testTdf113877()
+{
+    load(DATA_DIRECTORY, "tdf113877_insert_numbered_list.odt");
+
+    // set a page cursor into the end of the document
+    uno::Reference<frame::XModel> xModel(mxComponent, uno::UNO_QUERY);
+    uno::Reference<text::XTextViewCursorSupplier> xTextViewCursorSupplier(xModel->getCurrentController(), uno::UNO_QUERY);
+    uno::Reference<text::XPageCursor> xCursor(xTextViewCursorSupplier->getViewCursor(), uno::UNO_QUERY);
+    xCursor->jumpToEndOfPage();
+
+    // insert the same document at current cursor position
+    {
+        const OUString insertFileid = m_directories.getURLFromSrc(DATA_DIRECTORY) + "tdf113877_insert_numbered_list.odt";
+        uno::Sequence<beans::PropertyValue> aPropertyValues(comphelper::InitPropertySequence({ { "Name", uno::makeAny(insertFileid) } }));
+        lcl_dispatchCommand(mxComponent, ".uno:InsertDoc", aPropertyValues);
+    }
+
+    // the initial list with 4 list items
+    CPPUNIT_ASSERT_EQUAL(getProperty<OUString>(getParagraph(1), "ListId"), getProperty<OUString>(getParagraph(4), "ListId"));
+
+    // the last of the first list, and the first of the inserted list
+    CPPUNIT_ASSERT_EQUAL(getProperty<OUString>(getParagraph(4), "ListId"), getProperty<OUString>(getParagraph(5), "ListId"));
+    CPPUNIT_ASSERT_EQUAL(getProperty<OUString>(getParagraph(5), "ListId"), getProperty<OUString>(getParagraph(6), "ListId"));
+    CPPUNIT_ASSERT_EQUAL(getProperty<OUString>(getParagraph(6), "ListId"), getProperty<OUString>(getParagraph(7), "ListId"));
+}
+
 CPPUNIT_TEST_SUITE_REGISTRATION(SwUiWriterTest);
 CPPUNIT_PLUGIN_IMPLEMENT();
 
diff --git a/sw/source/filter/xml/xmlimp.cxx b/sw/source/filter/xml/xmlimp.cxx
index 51fc41249e43..2231d5f36af9 100644
--- a/sw/source/filter/xml/xmlimp.cxx
+++ b/sw/source/filter/xml/xmlimp.cxx
@@ -832,6 +832,91 @@ void SwXMLImport::endDocument()
                     pPaM->Move( fnMoveBackward );
                 }
             }
+
+            // tdf#113877
+            // when we insert one document with list inside into another one with list at the insert position,
+            // the resulting numbering in these lists are not consequent.
+            //
+            // Main document:
+            //  1. One
+            //  2. Two
+            //  3. Three
+            //  4.                      <-- insert position
+            //
+            // Inserted document:
+            //  1. One
+            //  2. Two
+            //  3. Three
+            //  4.
+            //
+            // Expected result
+            //  1. One
+            //  2. Two
+            //  3. Three
+            //  4. One
+            //  5. Two
+            //  6. Three
+            //  7.
+            //
+            if (IsInsertMode() && m_pSttNdIdx->GetIndex())
+            {
+                sal_uLong index = 1;
+
+                // the last node of the main document where we have inserted a document
+                SwNode * p1 = pDoc->GetNodes()[m_pSttNdIdx->GetIndex() + 0];
+
+                // the first node of the inserted document
+                SwNode * p2 = pDoc->GetNodes()[m_pSttNdIdx->GetIndex() + index];
+
+                // the first node of the inserted document,
+                // which will be used to detect if inside inserted document a new list was started
+                const SfxPoolItem* listId2Initial = nullptr;
+
+                while (
+                    p1 && p2
+                    && (p1->GetNodeType() == p2->GetNodeType())
+                    && (p1->IsTextNode() == p2->IsTextNode())
+                    )
+                {
+                    SwContentNode * c1 = static_cast<SwContentNode *>(p1);
+                    SwContentNode * c2 = static_cast<SwContentNode *>(p2);
+
+                    const SfxPoolItem* listId1 = c1->GetNoCondAttr(RES_PARATR_LIST_ID, false);
+                    const SfxPoolItem* listId2 = c2->GetNoCondAttr(RES_PARATR_LIST_ID, false);
+
+                    if (!listId2Initial)
+                    {
+                        listId2Initial = listId2;
+                    }
+
+                    if (! (listId2Initial && listId2 && (*listId2Initial == *listId2)) )
+                    {
+                        // no more list items of the first list inside inserted document
+                        break;
+                    }
+
+                    if (listId1 && listId2)
+                    {
+                        c2->SetAttr(*listId1);
+                    }
+                    else
+                    {
+                        // no more appropriate list items
+                        break;
+                    }
+
+                    // get next item
+                    index++;
+                    if (index >= pDoc->GetNodes().Count())
+                    {
+                        // no more items
+                        break;
+                    }
+
+                    p2 = pDoc->GetNodes()[m_pSttNdIdx->GetIndex() + index];
+                }
+            }
+
         }
     }
 


More information about the Libreoffice-commits mailing list