[Libreoffice-commits] core.git: sw/qa sw/source

László Németh (via logerrit) logerrit at kemper.freedesktop.org
Thu Aug 19 12:55:35 UTC 2021


 sw/qa/extras/uiwriter/uiwriter2.cxx                     |   45 ++++
 sw/source/core/doc/DocumentContentOperationsManager.cxx |  154 ++++++++--------
 2 files changed, 126 insertions(+), 73 deletions(-)

New commits:
commit 5e891c2ee82f2d7566ddb4e15b9c03cecb9fc1f8
Author:     László Németh <nemeth at numbertext.org>
AuthorDate: Thu Aug 19 11:47:53 2021 +0200
Commit:     László Németh <nemeth at numbertext.org>
CommitDate: Thu Aug 19 14:55:00 2021 +0200

    tdf#143939 sw: track format changes of the actual word
    
    If there is no text selection, character formattings
    are applied on the word under the text cursor,
    now with storing the original direct character formatting
    in a redline "extra data" for rejection of the tracked
    formatting change.
    
    Follow-up to commit ee3171adb24a3d720466fa43bec869910333f892
    "tdf#143918 sw: fix reject of multiple changes" (clean-up the
    format tracking code into the new lcl_SetRedline(), and
    applying that for the not handled case, too).
    
    Change-Id: Ie6bc4dc17dbf84cc61970cef66689aec8ddc4595
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/120707
    Tested-by: Jenkins
    Reviewed-by: László Németh <nemeth at numbertext.org>

diff --git a/sw/qa/extras/uiwriter/uiwriter2.cxx b/sw/qa/extras/uiwriter/uiwriter2.cxx
index a38fc9fb8742..a3f63a80d816 100644
--- a/sw/qa/extras/uiwriter/uiwriter2.cxx
+++ b/sw/qa/extras/uiwriter/uiwriter2.cxx
@@ -2892,6 +2892,51 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf143918)
     }
 }
 
+CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf143939)
+{
+    SwDoc* pDoc = createSwDoc(DATA_DIRECTORY, "tdf126206.docx");
+
+    SwWrtShell* const pWrtShell = pDoc->GetDocShell()->GetWrtShell();
+
+    // bold text
+    auto xText = getParagraph(1)->getText();
+    CPPUNIT_ASSERT(xText.is());
+    {
+        auto xCursor(xText->createTextCursorByRange(getRun(getParagraph(1), 1)));
+        CPPUNIT_ASSERT(xCursor.is());
+        CPPUNIT_ASSERT_EQUAL(OUString("Lorem "), xCursor->getString());
+        CPPUNIT_ASSERT_EQUAL(awt::FontWeight::BOLD, getProperty<float>(xCursor, "CharWeight"));
+    }
+
+    // positionate the text cursor inside the first word
+    pWrtShell->Right(CRSR_SKIP_CHARS, /*bSelect=*/false, 1, /*bBasicCall=*/false);
+    // remove bold formatting with change tracking without selection
+    dispatchCommand(mxComponent, ".uno:Bold", {});
+
+    xText = getParagraph(1)->getText();
+    CPPUNIT_ASSERT(xText.is());
+    {
+        auto xCursor(xText->createTextCursorByRange(getRun(getParagraph(1), 2)));
+        CPPUNIT_ASSERT(xCursor.is());
+        CPPUNIT_ASSERT_EQUAL(OUString("Lorem"), xCursor->getString());
+        CPPUNIT_ASSERT_EQUAL(awt::FontWeight::NORMAL, getProperty<float>(xCursor, "CharWeight"));
+    }
+
+    // reject tracked changes
+    dispatchCommand(mxComponent, ".uno:RejectAllTrackedChanges", {});
+
+    // bold text again
+    xText = getParagraph(1)->getText();
+    CPPUNIT_ASSERT(xText.is());
+    {
+        auto xCursor(xText->createTextCursorByRange(getRun(getParagraph(1), 1)));
+        CPPUNIT_ASSERT(xCursor.is());
+        CPPUNIT_ASSERT_EQUAL(OUString("Lorem"), xCursor->getString());
+        // This was NORMAL
+        CPPUNIT_ASSERT_EQUAL(awt::FontWeight::BOLD, getProperty<float>(xCursor, "CharWeight"));
+    }
+}
+
 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf101873)
 {
     SwDoc* pDoc = createSwDoc();
diff --git a/sw/source/core/doc/DocumentContentOperationsManager.cxx b/sw/source/core/doc/DocumentContentOperationsManager.cxx
index 29e9e372804d..e587ffd27770 100644
--- a/sw/source/core/doc/DocumentContentOperationsManager.cxx
+++ b/sw/source/core/doc/DocumentContentOperationsManager.cxx
@@ -1210,6 +1210,77 @@ namespace //local functions originally from docfmt.cxx
 
     #define DELETECHARSETS if ( bDelete ) { delete pCharSet; delete pOtherSet; }
 
+    // set format redline with extra data for lcl_InsAttr()
+    void lcl_SetRedline(
+        SwDoc& rDoc,
+        const SwPaM &rRg)
+    {
+        SwRedlineExtraData_FormatColl* pExtra = nullptr;
+
+        // check existing redline on the same range, and use its extra data, if it exists
+        SwRedlineTable::size_type nRedlPos = rDoc.getIDocumentRedlineAccess().GetRedlinePos(
+                rRg.Start()->nNode.GetNode(), RedlineType::Format );
+        if( SwRedlineTable::npos != nRedlPos )
+        {
+            const SwPosition *pRStt, *pREnd;
+            do {
+                SwRangeRedline* pTmp = rDoc.getIDocumentRedlineAccess().GetRedlineTable()[ nRedlPos ];
+                pRStt = pTmp->Start();
+                pREnd = pTmp->End();
+                SwComparePosition eCompare = ComparePosition( *rRg.Start(), *rRg.End(), *pRStt, *pREnd );
+                if ( eCompare == SwComparePosition::Inside || eCompare == SwComparePosition::Equal )
+                {
+                    if (pTmp->GetExtraData())
+                    {
+                        const SwRedlineExtraData* pExtraData = pTmp->GetExtraData();
+                        const SwRedlineExtraData_FormatColl* pFormattingChanges =
+                            dynamic_cast<const SwRedlineExtraData_FormatColl*>(pExtraData);
+                        // Check if the extra data is of type 'formatting changes'
+                        if (pFormattingChanges)
+                        {
+                            // Get the item set that holds all the changes properties
+                            const SfxItemSet *pChangesSet = pFormattingChanges->GetItemSet();
+                            pExtra = new SwRedlineExtraData_FormatColl( "", USHRT_MAX, pChangesSet );
+                            break;
+                        }
+                    }
+                }
+            } while( pRStt <= rRg.Start() && ++nRedlPos < rDoc.getIDocumentRedlineAccess().GetRedlineTable().size());
+        }
+
+        SwRangeRedline * pRedline = new SwRangeRedline( RedlineType::Format, rRg );
+        auto const result(rDoc.getIDocumentRedlineAccess().AppendRedline( pRedline, true));
+        // store original text attributes to reject formatting change
+        if (IDocumentRedlineAccess::AppendResult::IGNORED != result)
+        {
+            // no existing format redline in the range
+            if (!pExtra)
+            {
+                // Apply the first character's attributes to the ReplaceText
+                SfxItemSet aSet( rDoc.GetAttrPool(),
+                            svl::Items<RES_CHRATR_BEGIN,     RES_TXTATR_WITHEND_END - 1,
+                            RES_UNKNOWNATR_BEGIN, RES_UNKNOWNATR_END-1> );
+                SwTextNode * pNode = rRg.Start()->nNode.GetNode().GetTextNode();
+                pNode->GetParaAttr( aSet, rRg.Start()->nContent.GetIndex() + 1, rRg.End()->nContent.GetIndex() );
+
+                aSet.ClearItem( RES_TXTATR_REFMARK );
+                aSet.ClearItem( RES_TXTATR_TOXMARK );
+                aSet.ClearItem( RES_TXTATR_CJK_RUBY );
+                aSet.ClearItem( RES_TXTATR_INETFMT );
+                aSet.ClearItem( RES_TXTATR_META );
+                aSet.ClearItem( RES_TXTATR_METAFIELD );
+                pExtra = new SwRedlineExtraData_FormatColl( "", USHRT_MAX, &aSet );
+            }
+
+            if ( pExtra )
+            {
+                std::unique_ptr<SwRedlineExtraData_FormatColl> xRedlineExtraData;
+                xRedlineExtraData.reset(pExtra);
+                pRedline->SetExtraData( xRedlineExtraData.get() );
+            }
+        }
+    }
+
     /// Insert Hints according to content types;
     // Is used in SwDoc::Insert(..., SwFormatHint &rHt)
 
@@ -1615,19 +1686,22 @@ namespace //local functions originally from docfmt.cxx
                         pTextNd->RstTextAttr( aSt, nPtPos, 0, pCharSet );
                 }
 
-                // the SwRegHistory inserts the attribute into the TextNode!
-                SwRegHistory history( pNode, *pNode, pHistory );
-                bRet = history.InsertItems( *pCharSet, nMkPos, nPtPos, nFlags, /*ppNewTextAttr*/nullptr )
-                    || bRet;
-
                 if( rDoc.getIDocumentRedlineAccess().IsRedlineOn() )
                 {
                     SwPaM aPam( *pNode, nMkPos, *pNode, nPtPos );
 
                     if( pUndo )
                         pUndo->SaveRedlineData( aPam, false );
-                    rDoc.getIDocumentRedlineAccess().AppendRedline( new SwRangeRedline( RedlineType::Format, aPam ), true);
+
+                    lcl_SetRedline(rDoc, aPam);
                 }
+
+                // the SwRegHistory inserts the attribute into the TextNode!
+                SwRegHistory history( pNode, *pNode, pHistory );
+
+                bRet = history.InsertItems( *pCharSet, nMkPos, nPtPos, nFlags, /*ppNewTextAttr*/nullptr )
+                    || bRet;
+
             }
             if( pOtherSet && pOtherSet->Count() )
             {
@@ -1644,48 +1718,12 @@ namespace //local functions originally from docfmt.cxx
             return bRet;
         }
 
-        SwRangeRedline * pRedline = nullptr;
-        SwRedlineExtraData_FormatColl* pExtra = nullptr;
         if( rDoc.getIDocumentRedlineAccess().IsRedlineOn() && pCharSet && pCharSet->Count() )
         {
             if( pUndo )
                 pUndo->SaveRedlineData( rRg, false );
 
-            // check existing redline on the same range, and use its extra data, if it exists
-            SwRedlineTable::size_type nRedlPos = rDoc.getIDocumentRedlineAccess().GetRedlinePos(
-                    rRg.Start()->nNode.GetNode(), RedlineType::Format );
-            if( SwRedlineTable::npos != nRedlPos )
-            {
-                const SwPosition *pRStt, *pREnd;
-                do {
-                    SwRangeRedline* pTmp = rDoc.getIDocumentRedlineAccess().GetRedlineTable()[ nRedlPos ];
-                    pRStt = pTmp->Start();
-                    pREnd = pTmp->End();
-                    SwComparePosition eCompare = ComparePosition( *rRg.Start(), *rRg.End(), *pRStt, *pREnd );
-                    if ( eCompare == SwComparePosition::Inside || eCompare == SwComparePosition::Equal )
-                    {
-                        if (pTmp->GetExtraData())
-                        {
-                            const SwRedlineExtraData* pExtraData = pTmp->GetExtraData();
-                            const SwRedlineExtraData_FormatColl* pFormattingChanges =
-                                dynamic_cast<const SwRedlineExtraData_FormatColl*>(pExtraData);
-                            // Check if the extra data is of type 'formatting changes'
-                            if (pFormattingChanges)
-                            {
-                                // Get the item set that holds all the changes properties
-                                const SfxItemSet *pChangesSet = pFormattingChanges->GetItemSet();
-                                pExtra = new SwRedlineExtraData_FormatColl( "", USHRT_MAX, pChangesSet );
-                                break;
-                            }
-                        }
-                    }
-                } while( pRStt <= rRg.Start() && ++nRedlPos < rDoc.getIDocumentRedlineAccess().GetRedlineTable().size());
-            }
-
-            pRedline = new SwRangeRedline( RedlineType::Format, rRg );
-            auto const result(rDoc.getIDocumentRedlineAccess().AppendRedline( pRedline, true));
-            if (IDocumentRedlineAccess::AppendResult::IGNORED == result)
-                pRedline = nullptr;
+            lcl_SetRedline(rDoc, rRg);
         }
 
         /* now if range */
@@ -1707,36 +1745,6 @@ namespace //local functions originally from docfmt.cxx
                 if( pNode->IsTextNode() && pCharSet && pCharSet->Count() )
                 {
                     SwRegHistory history( pNode, *pNode, pHistory );
-
-                    // store original text attributes to reject formatting change
-                    if (pRedline)
-                    {
-                        // no existing format redline in the range
-                        if (!pExtra)
-                        {
-                            // Apply the first character's attributes to the ReplaceText
-                            SfxItemSet aSet( rDoc.GetAttrPool(),
-                                        svl::Items<RES_CHRATR_BEGIN,     RES_TXTATR_WITHEND_END - 1,
-                                        RES_UNKNOWNATR_BEGIN, RES_UNKNOWNATR_END-1> );
-                            pNode->GetTextNode()->GetParaAttr( aSet, pStt->nContent.GetIndex() + 1, aCntEnd.GetIndex() );
-
-                            aSet.ClearItem( RES_TXTATR_REFMARK );
-                            aSet.ClearItem( RES_TXTATR_TOXMARK );
-                            aSet.ClearItem( RES_TXTATR_CJK_RUBY );
-                            aSet.ClearItem( RES_TXTATR_INETFMT );
-                            aSet.ClearItem( RES_TXTATR_META );
-                            aSet.ClearItem( RES_TXTATR_METAFIELD );
-                            pExtra = new SwRedlineExtraData_FormatColl( "", USHRT_MAX, &aSet );
-                        }
-
-                        if ( pExtra )
-                        {
-                            std::unique_ptr<SwRedlineExtraData_FormatColl> xRedlineExtraData;
-                            xRedlineExtraData.reset(pExtra);
-                            pRedline->SetExtraData( xRedlineExtraData.get() );
-                        }
-                    }
-
                     bRet = history.InsertItems(*pCharSet,
                             pStt->nContent.GetIndex(), aCntEnd.GetIndex(), nFlags, /*ppNewTextAttr*/nullptr)
                         || bRet;


More information about the Libreoffice-commits mailing list