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

Miklos Vajna vmiklos at collabora.co.uk
Thu May 14 02:48:22 PDT 2015


 sw/inc/doc.hxx                                          |    2 -
 sw/inc/ndtxt.hxx                                        |    6 +++-
 sw/qa/extras/uiwriter/data/tdf86639.rtf                 |    3 ++
 sw/qa/extras/uiwriter/uiwriter.cxx                      |   14 ++++++++++
 sw/source/core/doc/DocumentContentOperationsManager.cxx |    4 +-
 sw/source/core/doc/docfmt.cxx                           |    3 +-
 sw/source/core/edit/edfcol.cxx                          |   10 +++++++
 sw/source/core/inc/DocumentContentOperationsManager.hxx |    3 ++
 sw/source/core/txtnode/txtedt.cxx                       |   22 ++++++++++++++--
 9 files changed, 60 insertions(+), 7 deletions(-)

New commits:
commit 3c0805e1f4f4d14e92c7e655d59c87de5c207e48
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date:   Thu May 14 11:34:33 2015 +0200

    tdf#86639 SwEditShell: when setting para style, reset char attrs if needed
    
    The old internal RTF filter used to call SwTxtNode::SetAttr() without
    setting SetAttrMode::NOFORMATATTR, so character attributes which cover
    the whole node got converted to paragraph attributes.  The new UNO
    filter goes through SwXText::insertTextPortion(), which sets
    SetAttrMode::NOFORMATATTR, so this doesn't happen. The result of this is
    that when the UI sets a new paragraph style on the text node, then such
    character attributes are no longer removed.
    
    Given that in RTF you can't really have character properties on a
    paragraph, going back to the document model produced by the old internal
    filter doesn't sound like the good direction -- not to mention that
    changing SwXText::insertTextPortion() this way would be an implicit API
    change.
    
    Fix the problem by tweaking SwEditShell::SetTxtFmtColl() instead, so
    that it removes these full-text-node character attributes, too. The
    logic in SwTxtNode::RstTxtAttr() can be extended later if necessary to
    delete more attributes, but to be on the safe side, just handle the bare
    minimum necessary to fix the problem for now.
    
    Change-Id: I5faa3226fc0f9c18e005da185fe0830d8c393256

diff --git a/sw/inc/doc.hxx b/sw/inc/doc.hxx
index 546e2db..9cc929c 100644
--- a/sw/inc/doc.hxx
+++ b/sw/inc/doc.hxx
@@ -763,7 +763,7 @@ public:
                      bool bTxtAttr = true,
                      const std::set<sal_uInt16> &rAttrs = std::set<sal_uInt16>(),
                      const bool bSendDataChangedEvents = true );
-    void RstTxtAttrs(const SwPaM &rRg, bool bInclRefToxMark = false );
+    void RstTxtAttrs(const SwPaM &rRg, bool bInclRefToxMark = false, bool bExactRange = false );
 
     /** Set attribute in given format.1y
      *  If Undo is enabled, the old values is added to the Undo history. */
diff --git a/sw/inc/ndtxt.hxx b/sw/inc/ndtxt.hxx
index e186da7..87a29ec 100644
--- a/sw/inc/ndtxt.hxx
+++ b/sw/inc/ndtxt.hxx
@@ -266,13 +266,17 @@ public:
         @param bInclRefToxMark
             refmarks, toxmarks, and metas will be ignored unless this is true
         ATTENTION: setting bInclRefToxMark is only allowed from UNDO!
+        @param bExactRange From the attributes included in the range, delete
+        only the ones which have exactly same range. Don't delete the ones
+        which are simply included in the range.
      */
     void RstTxtAttr(
         const SwIndex &rIdx,
         const sal_Int32 nLen,
         const sal_uInt16 nWhich = 0,
         const SfxItemSet* pSet = 0,
-        const bool bInclRefToxMark = false );
+        const bool bInclRefToxMark = false,
+        const bool bExactRange = false );
     void    GCAttr();
 
     // Delete text attribute (needs to be deregistered at Pool!)
diff --git a/sw/qa/extras/uiwriter/data/tdf86639.rtf b/sw/qa/extras/uiwriter/data/tdf86639.rtf
new file mode 100644
index 0000000..cdf0be7
--- /dev/null
+++ b/sw/qa/extras/uiwriter/data/tdf86639.rtf
@@ -0,0 +1,3 @@
+{\rtf1\ansi\ansicpg1252\deff0\deflang1035{\fonttbl{\f0\fnil\fcharset0 Calibri;}}
+{\*\generator Msftedit 5.41.21.2510;}\viewkind4\uc1\pard\sa200\sl276\slmult1\lang11\f0\fs22 testiiii\par
+}
diff --git a/sw/qa/extras/uiwriter/uiwriter.cxx b/sw/qa/extras/uiwriter/uiwriter.cxx
index f0a1449..3a47b8d 100644
--- a/sw/qa/extras/uiwriter/uiwriter.cxx
+++ b/sw/qa/extras/uiwriter/uiwriter.cxx
@@ -28,6 +28,7 @@
 #include <swacorr.hxx>
 #include <swmodule.hxx>
 #include <modcfg.hxx>
+#include <charatr.hxx>
 #include <editeng/acorrcfg.hxx>
 #include <unotools/streamwrap.hxx>
 #include <test/mtfxmldump.hxx>
@@ -90,6 +91,7 @@ public:
     void testSearchWithTransliterate();
     void testTdf90362();
     void testUndoCharAttribute();
+    void testTdf86639();
 
     CPPUNIT_TEST_SUITE(SwUiWriterTest);
     CPPUNIT_TEST(testReplaceForward);
@@ -125,6 +127,7 @@ public:
     CPPUNIT_TEST(testSearchWithTransliterate);
     CPPUNIT_TEST(testTdf90362);
     CPPUNIT_TEST(testUndoCharAttribute);
+    CPPUNIT_TEST(testTdf86639);
 
     CPPUNIT_TEST_SUITE_END();
 
@@ -948,6 +951,17 @@ void SwUiWriterTest::testUndoCharAttribute()
     CPPUNIT_ASSERT_EQUAL((*aPoolItem == ampPoolItem), false);
 }
 
+void SwUiWriterTest::testTdf86639()
+{
+    SwDoc* pDoc = createDoc("tdf86639.rtf");
+    SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
+    SwTxtFmtColl* pColl = pDoc->FindTxtFmtCollByName("Heading");
+    pWrtShell->SetTxtFmtColl(pColl);
+    OUString aExpected = pColl->GetAttrSet().GetFont().GetFamilyName();
+    // This was Calibri, should be Liberation Sans.
+    CPPUNIT_ASSERT_EQUAL(aExpected, getProperty<OUString>(getRun(getParagraph(1), 1), "CharFontName"));
+}
+
 CPPUNIT_TEST_SUITE_REGISTRATION(SwUiWriterTest);
 CPPUNIT_PLUGIN_IMPLEMENT();
 
diff --git a/sw/source/core/doc/DocumentContentOperationsManager.cxx b/sw/source/core/doc/DocumentContentOperationsManager.cxx
index 970d2bc..349e457 100644
--- a/sw/source/core/doc/DocumentContentOperationsManager.cxx
+++ b/sw/source/core/doc/DocumentContentOperationsManager.cxx
@@ -3453,13 +3453,13 @@ bool DocumentContentOperationsManager::lcl_RstTxtAttr( const SwNodePtr& rpNd, vo
             SwRegHistory aRHst( *pTxtNode, pPara->pHistory );
             pTxtNode->GetpSwpHints()->Register( &aRHst );
             pTxtNode->RstTxtAttr( aSt, nEnd - aSt.GetIndex(), pPara->nWhich,
-                                  pPara->pDelSet, pPara->bInclRefToxMark );
+                                  pPara->pDelSet, pPara->bInclRefToxMark, pPara->bExactRange );
             if( pTxtNode->GetpSwpHints() )
                 pTxtNode->GetpSwpHints()->DeRegister();
         }
         else
             pTxtNode->RstTxtAttr( aSt, nEnd - aSt.GetIndex(), pPara->nWhich,
-                                  pPara->pDelSet, pPara->bInclRefToxMark );
+                                  pPara->pDelSet, pPara->bInclRefToxMark, pPara->bExactRange );
     }
     return true;
 }
diff --git a/sw/source/core/doc/docfmt.cxx b/sw/source/core/doc/docfmt.cxx
index 4ba534c..c69872b 100644
--- a/sw/source/core/doc/docfmt.cxx
+++ b/sw/source/core/doc/docfmt.cxx
@@ -219,7 +219,7 @@ static bool lcl_RstAttr( const SwNodePtr& rpNd, void* pArgs )
     return true;
 }
 
-void SwDoc::RstTxtAttrs(const SwPaM &rRg, bool bInclRefToxMark )
+void SwDoc::RstTxtAttrs(const SwPaM &rRg, bool bInclRefToxMark, bool bExactRange )
 {
     SwHistory* pHst = 0;
     SwDataChanged aTmp( rRg );
@@ -232,6 +232,7 @@ void SwDoc::RstTxtAttrs(const SwPaM &rRg, bool bInclRefToxMark )
     const SwPosition *pStt = rRg.Start(), *pEnd = rRg.End();
     sw::DocumentContentOperationsManager::ParaRstFmt aPara( pStt, pEnd, pHst );
     aPara.bInclRefToxMark = bInclRefToxMark;
+    aPara.bExactRange = bExactRange;
     GetNodes().ForEach( pStt->nNode.GetIndex(), pEnd->nNode.GetIndex()+1,
                         sw::DocumentContentOperationsManager::lcl_RstTxtAttr, &aPara );
     getIDocumentState().SetModified();
diff --git a/sw/source/core/edit/edfcol.cxx b/sw/source/core/edit/edfcol.cxx
index 72b90b3..0f1dd33 100644
--- a/sw/source/core/edit/edfcol.cxx
+++ b/sw/source/core/edit/edfcol.cxx
@@ -63,7 +63,17 @@ void SwEditShell::SetTxtFmtColl(SwTxtFmtColl *pFmt,
 
         if ( !rPaM.HasReadonlySel( GetViewOptions()->IsFormView() ) )
         {
+            // Change the paragraph style to pLocal and remove all direct paragraph formatting.
             GetDoc()->SetTxtFmtColl( rPaM, pLocal, true, bResetListAttrs );
+
+            // If there are hints on the nodes which cover the whole node, then remove those, too.
+            SwPaM aPaM(*rPaM.Start(), *rPaM.End());
+            if (SwTxtNode* pEndTxtNode = aPaM.End()->nNode.GetNode().GetTxtNode())
+            {
+                aPaM.Start()->nContent = 0;
+                aPaM.End()->nContent = pEndTxtNode->GetTxt().getLength();
+            }
+            GetDoc()->RstTxtAttrs(aPaM, /*bInclRefToxMark=*/false, /*bExactRange=*/true);
         }
 
     }
diff --git a/sw/source/core/inc/DocumentContentOperationsManager.hxx b/sw/source/core/inc/DocumentContentOperationsManager.hxx
index f2ad52b..d912278 100644
--- a/sw/source/core/inc/DocumentContentOperationsManager.hxx
+++ b/sw/source/core/inc/DocumentContentOperationsManager.hxx
@@ -127,6 +127,8 @@ public:
         bool bResetListAttrs; // #i62575#
         bool bResetAll;
         bool bInclRefToxMark;
+        /// From the attributes included in the range, delete only the ones which have exactly same range. Don't delete the ones which are simply included in the range.
+        bool bExactRange;
 
         ParaRstFmt(const SwPosition* pStt, const SwPosition* pEnd,
                    SwHistory* pHst, sal_uInt16 nWhch = 0, const SfxItemSet* pSet = 0)
@@ -140,6 +142,7 @@ public:
             , bResetListAttrs(false)
             , bResetAll(true)
             , bInclRefToxMark(false)
+            , bExactRange(false)
         {
         }
     };
diff --git a/sw/source/core/txtnode/txtedt.cxx b/sw/source/core/txtnode/txtedt.cxx
index 9c8ea97..06ebf9d 100644
--- a/sw/source/core/txtnode/txtedt.cxx
+++ b/sw/source/core/txtnode/txtedt.cxx
@@ -376,7 +376,8 @@ void SwTxtNode::RstTxtAttr(
     const sal_Int32 nLen,
     const sal_uInt16 nWhich,
     const SfxItemSet* pSet,
-    const bool bInclRefToxMark )
+    const bool bInclRefToxMark,
+    const bool bExactRange )
 {
     if ( !GetpSwpHints() )
         return;
@@ -421,7 +422,7 @@ void SwTxtNode::RstTxtAttr(
     SwTxtAttr *pHt = NULL;
     while ( (i < m_pSwpHints->Count())
             && ( ( ( nAttrStart = (*m_pSwpHints)[i]->GetStart()) < nEnd )
-                 || nLen==0 ) )
+                 || nLen==0 ) && !bExactRange)
     {
         pHt = m_pSwpHints->GetTextHint(i);
 
@@ -599,6 +600,23 @@ void SwTxtNode::RstTxtAttr(
         ++i;
     }
 
+    if (bExactRange)
+    {
+        // Only delete the hints which start at nStt and end at nEnd.
+        for (i = 0; i < m_pSwpHints->Count(); ++i)
+        {
+            SwTxtAttr* pHint = m_pSwpHints->GetTextHint(i);
+            if (pHint->GetStart() != nStt)
+                continue;
+
+            const sal_Int32* pHintEnd = pHint->GetEnd();
+            if (!pHintEnd || *pHintEnd != nEnd)
+                continue;
+
+            delAttributes.push_back(pHint);
+        }
+    }
+
     if (bChanged && !delAttributes.empty())
     {   // Delete() calls GetStartOf() - requires sorted hints!
         m_pSwpHints->Resort();


More information about the Libreoffice-commits mailing list