summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@collabora.co.uk>2015-05-14 11:34:33 +0200
committerMiklos Vajna <vmiklos@collabora.co.uk>2015-05-14 11:39:16 +0200
commit3c0805e1f4f4d14e92c7e655d59c87de5c207e48 (patch)
treef83e033781b6724aa77a19537e035d3cfced524e
parent7e9a4944e53d95f7defb1da384b665e65b2ebc55 (diff)
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
-rw-r--r--sw/inc/doc.hxx2
-rw-r--r--sw/inc/ndtxt.hxx6
-rw-r--r--sw/qa/extras/uiwriter/data/tdf86639.rtf3
-rw-r--r--sw/qa/extras/uiwriter/uiwriter.cxx14
-rw-r--r--sw/source/core/doc/DocumentContentOperationsManager.cxx4
-rw-r--r--sw/source/core/doc/docfmt.cxx3
-rw-r--r--sw/source/core/edit/edfcol.cxx10
-rw-r--r--sw/source/core/inc/DocumentContentOperationsManager.hxx3
-rw-r--r--sw/source/core/txtnode/txtedt.cxx22
9 files changed, 60 insertions, 7 deletions
diff --git a/sw/inc/doc.hxx b/sw/inc/doc.hxx
index 546e2dbd80f0..9cc929c1b4f4 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 e186da7aaedd..87a29ec1bd7d 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 000000000000..cdf0be77f956
--- /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 f0a14494b8c5..3a47b8d8fbf1 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 970d2bc790e1..349e457de7dc 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 4ba534cb4a0f..c69872bbdb75 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 72b90b38e790..0f1dd3366d47 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 f2ad52b9c1f2..d9122780fad9 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 9c8ea97f932c..06ebf9d4aef1 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();