diff options
-rw-r--r-- | sw/qa/extras/rtfimport/data/tdf115242.rtf | 40 | ||||
-rw-r--r-- | sw/qa/extras/rtfimport/rtfimport.cxx | 8 | ||||
-rw-r--r-- | writerfilter/source/dmapper/DomainMapper.cxx | 24 | ||||
-rw-r--r-- | writerfilter/source/dmapper/DomainMapper_Impl.cxx | 5 | ||||
-rw-r--r-- | writerfilter/source/rtftok/rtfdispatchvalue.cxx | 8 | ||||
-rw-r--r-- | writerfilter/source/rtftok/rtfdocumentimpl.cxx | 5 | ||||
-rw-r--r-- | writerfilter/source/rtftok/rtfdocumentimpl.hxx | 3 | ||||
-rw-r--r-- | writerfilter/source/rtftok/rtfsprm.cxx | 11 | ||||
-rw-r--r-- | writerfilter/source/rtftok/rtfsprm.hxx | 3 |
9 files changed, 96 insertions, 11 deletions
diff --git a/sw/qa/extras/rtfimport/data/tdf115242.rtf b/sw/qa/extras/rtfimport/data/tdf115242.rtf new file mode 100644 index 000000000000..f79a0ed9a642 --- /dev/null +++ b/sw/qa/extras/rtfimport/data/tdf115242.rtf @@ -0,0 +1,40 @@ +{\rtf1\adeflang1037\ansi\ansicpg1252\uc1\adeff1\deff0\stshfdbch0\stshfloch1\stshfhich1\stshfbi1\deflang1033\deflangfe1033\themelang1033\themelangfe2052\themelangcs1025 +{\*\listtable +{\list\listtemplateid-454920584 +{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0 +{\leveltext\'02\'00.;} +{\levelnumbers\'01;} +\rtlch\fcs1 \af0\afs26 \ltrch\fcs0 \fs26 } +{\listlevel\levelnfc4\levelnfcn4\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0 +{\leveltext\'02\'01.;} +{\levelnumbers\'01;} +\rtlch\fcs1 \af0\afs26 \ltrch\fcs0 \fs26 } +{\listname ;} +\listid1} +} +{\*\listoverridetable +{\listoverride\listid1\listoverridecount0\ls1} +} +\paperw12240\paperh15840\margl1440\margr1440\margt1440\margb1440\gutter0\ltrsect +\widowctrl\ftnbj\aenddoc\trackmoves0\trackformatting1\donotembedsysfont0\relyonvml0\donotembedlingdata1\grfdocevents0\validatexml0\showplaceholdtext0\ignoremixedcontent0\saveinvalidxml0\showxmlerrors0\noxlattoyen +\noultrlspc\dntblnsbdb\nospaceforul\horzdoc\dgmargin\dghspace120\dgvspace181\dghorigin1440\dgvorigin1440\dghshow2\dgvshow1 +\jcompress\viewkind1\viewscale100\splytwnine\ftnlytwnine\htmautsp\nolnhtadjtbl\useltbaln\alntblind\lytcalctblwd\lyttblrtgr\lnbrkrule\nobrkwrptbl\snaptogridincell\allowfieldendsel\wrppunct\asianbrkrule\rsidroot5451531 +\newtblstyruls\nogrowautofit\viewbksp1\usenormstyforlist\noindnmbrts\felnbrelev\nocxsptable\indrlsweleven\noafcnsttbl\afelev\utinl\hwelev\spltpgpar\notcvasp\notbrkcnstfrctbl\notvatxbx\krnprsnet\cachedcolbal \nouicompat \fet0 +{\*\wgrffmtfilter 2450} +\nofeaturethrottle1\ilfomacatclnup0 +\ltrpar \sectd \ltrsect\linex0\headery735\footery893\sectlinegrid360\sectdefaultcl\sectrsid1254981\sftnbj +\pard\plain \ltrpar\s57\ql \fi-720\li1580\ri0\sl-421\slmult0\widctlpar +\tx2264\wrapdefault\aspalpha\aspnum\faauto\ls1\adjustright\rin0\lin1580\itap0\pararsid1254981 \rtlch\fcs1 \af1\afs26\alang1025 \ltrch\fcs0 \f1\fs26\lang1033\langfe2052\cgrid\langnp1033\langfenp2052 +{\rtlch\fcs1 \af1 \ltrch\fcs0 +\lang1033\langfe1033\langfenp1033\insrsid10637256 This is \'931\'94} +{\rtlch\fcs1 \af1 \ltrch\fcs0 \insrsid4026340 +\par +{\listtext\pard\plain\ltrpar \s56 \rtlch\fcs1 \af0\afs26\alang1025 \ltrch\fcs0 \f1\fs26\insrsid10637256 \hich\af1\dbch\af0\loch\f1 a.\tab} +} +\pard\plain \ltrpar\s56\ql \li1580\ri0\sl-421\slmult0\widctlpar +\tx2293\wrapdefault\aspalpha\aspnum\faauto\ls1\ilvl1\adjustright\rin0\lin1580\itap0\pararsid10637256 \rtlch\fcs1 \af1\afs26\alang1025 \ltrch\fcs0 \f1\fs26\lang1033\langfe2052\cgrid\langnp1033\langfenp2052 +{\rtlch\fcs1 \af1 \ltrch\fcs0 +\lang1033\langfe1033\langfenp1033\insrsid10637256 This is \'93a\'94, \'93a\'94 starts at the above \'93This\'94} +{\rtlch\fcs1 \af1 \ltrch\fcs0 \insrsid4026340 +\par } +} diff --git a/sw/qa/extras/rtfimport/rtfimport.cxx b/sw/qa/extras/rtfimport/rtfimport.cxx index 6621626e662a..0c63379ccfbe 100644 --- a/sw/qa/extras/rtfimport/rtfimport.cxx +++ b/sw/qa/extras/rtfimport/rtfimport.cxx @@ -1390,6 +1390,14 @@ DECLARE_RTFIMPORT_TEST(testTdf104016, "tdf104016.rtf") xParagraph->getPropertyState("ParaLeftMargin")); } +DECLARE_RTFIMPORT_TEST(testTdf115242, "tdf115242.rtf") +{ + // This was 0, overriden left margin was lost by too aggressive style + // deduplication. + CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(2787), + getProperty<sal_Int32>(getParagraph(1), "ParaLeftMargin")); +} + DECLARE_RTFIMPORT_TEST(testDefaultValues, "default-values.rtf") { // tdf#105910: control words without values must be treated as having default values, diff --git a/writerfilter/source/dmapper/DomainMapper.cxx b/writerfilter/source/dmapper/DomainMapper.cxx index 5ae0bdc612ab..068c08554559 100644 --- a/writerfilter/source/dmapper/DomainMapper.cxx +++ b/writerfilter/source/dmapper/DomainMapper.cxx @@ -510,12 +510,19 @@ void DomainMapper::lcl_attribute(Id nName, Value & val) // Word inherits FirstLineIndent property of the numbering, even if ParaLeftMargin is set, Writer does not. // So copy it explicitly, if necessary. sal_Int32 nFirstLineIndent = m_pImpl->getCurrentNumberingProperty("FirstLineIndent"); + sal_Int32 nIndentAt = m_pImpl->getCurrentNumberingProperty("IndentAt"); + + sal_Int32 nParaLeftMargin = ConversionHelper::convertTwipToMM100(nIntValue); + if (nParaLeftMargin != 0 && nIndentAt == nParaLeftMargin) + // Avoid direct left margin when it's the same as from the + // numbering. + break; if (nFirstLineIndent != 0) m_pImpl->GetTopContext()->Insert(PROP_PARA_FIRST_LINE_INDENT, uno::makeAny(nFirstLineIndent), /*bOverwrite=*/false); - m_pImpl->GetTopContext()->Insert( - PROP_PARA_LEFT_MARGIN, uno::makeAny( ConversionHelper::convertTwipToMM100(nIntValue ) )); + m_pImpl->GetTopContext()->Insert(PROP_PARA_LEFT_MARGIN, + uno::makeAny(nParaLeftMargin)); } break; case NS_ooxml::LN_CT_Ind_end: @@ -552,8 +559,17 @@ void DomainMapper::lcl_attribute(Id nName, Value & val) break; case NS_ooxml::LN_CT_Ind_firstLine: if (m_pImpl->GetTopContext()) - m_pImpl->GetTopContext()->Insert( - PROP_PARA_FIRST_LINE_INDENT, uno::makeAny( ConversionHelper::convertTwipToMM100(nIntValue ) )); + { + sal_Int32 nFirstLineIndent + = m_pImpl->getCurrentNumberingProperty("FirstLineIndent"); + sal_Int32 nParaFirstLineIndent = ConversionHelper::convertTwipToMM100(nIntValue); + if (nParaFirstLineIndent != 0 && nFirstLineIndent == nParaFirstLineIndent) + // Avoid direct first margin when it's the same as from the + // numbering. + break; + m_pImpl->GetTopContext()->Insert(PROP_PARA_FIRST_LINE_INDENT, + uno::makeAny(nParaFirstLineIndent)); + } break; case NS_ooxml::LN_CT_Ind_rightChars: m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "rightChars", OUString::number(nIntValue)); diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.cxx b/writerfilter/source/dmapper/DomainMapper_Impl.cxx index 69147cd3b33c..142171247a89 100644 --- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx +++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx @@ -5661,10 +5661,11 @@ sal_Int32 DomainMapper_Impl::getCurrentNumberingProperty(const OUString& aProp) if (pProp) xNumberingRules.set(pProp->second, uno::UNO_QUERY); pProp = m_pTopContext->getProperty(PROP_NUMBERING_LEVEL); - sal_Int32 nNumberingLevel = -1; + // Default numbering level is the first one. + sal_Int32 nNumberingLevel = 0; if (pProp) pProp->second >>= nNumberingLevel; - if (xNumberingRules.is() && nNumberingLevel != -1) + if (xNumberingRules.is()) { uno::Sequence<beans::PropertyValue> aProps; xNumberingRules->getByIndex(nNumberingLevel) >>= aProps; diff --git a/writerfilter/source/rtftok/rtfdispatchvalue.cxx b/writerfilter/source/rtftok/rtfdispatchvalue.cxx index 615476e42ee2..b44d48a997e0 100644 --- a/writerfilter/source/rtftok/rtfdispatchvalue.cxx +++ b/writerfilter/source/rtftok/rtfdispatchvalue.cxx @@ -671,8 +671,14 @@ RTFError RTFDocumentImpl::dispatchValue(RTFKeyword nKeyword, int nParam) if (m_aStates.top().eDestination == Destination::LISTOVERRIDEENTRY) m_aStates.top().aTableAttributes.set(NS_ooxml::LN_CT_AbstractNum_nsid, pIntValue); else + { + // Insert at the start, so properties inherited from the list + // can be overriden by direct formatting. But still allow the + // case when old-style paragraph numbering is already + // tokenized. putNestedSprm(m_aStates.top().aParagraphSprms, NS_ooxml::LN_CT_PPrBase_numPr, - NS_ooxml::LN_CT_NumPr_numId, pIntValue); + NS_ooxml::LN_CT_NumPr_numId, pIntValue, RTFOverwrite::YES_PREPEND); + } } break; case RTF_UC: diff --git a/writerfilter/source/rtftok/rtfdocumentimpl.cxx b/writerfilter/source/rtftok/rtfdocumentimpl.cxx index 0bc42bb73eee..d1f09ec42564 100644 --- a/writerfilter/source/rtftok/rtfdocumentimpl.cxx +++ b/writerfilter/source/rtftok/rtfdocumentimpl.cxx @@ -97,9 +97,10 @@ void putNestedAttribute(RTFSprms& rSprms, Id nParent, Id nId, const RTFValue::Po rAttributes.set(nId, pValue, eOverwrite); } -void putNestedSprm(RTFSprms& rSprms, Id nParent, Id nId, const RTFValue::Pointer_t& pValue) +void putNestedSprm(RTFSprms& rSprms, Id nParent, Id nId, const RTFValue::Pointer_t& pValue, + RTFOverwrite eOverwrite) { - putNestedAttribute(rSprms, nParent, nId, pValue, RTFOverwrite::NO_APPEND, false); + putNestedAttribute(rSprms, nParent, nId, pValue, eOverwrite, false); } static RTFValue::Pointer_t lcl_getNestedAttribute(RTFSprms& rSprms, Id nParent, Id nId) diff --git a/writerfilter/source/rtftok/rtfdocumentimpl.hxx b/writerfilter/source/rtftok/rtfdocumentimpl.hxx index 9d162490a8d1..38fbad18a1c8 100644 --- a/writerfilter/source/rtftok/rtfdocumentimpl.hxx +++ b/writerfilter/source/rtftok/rtfdocumentimpl.hxx @@ -387,7 +387,8 @@ public: }; void putBorderProperty(RTFStack& aStates, Id nId, const RTFValue::Pointer_t& pValue); -void putNestedSprm(RTFSprms& rSprms, Id nParent, Id nId, const RTFValue::Pointer_t& pValue); +void putNestedSprm(RTFSprms& rSprms, Id nParent, Id nId, const RTFValue::Pointer_t& pValue, + RTFOverwrite eOverwrite = RTFOverwrite::NO_APPEND); Id getParagraphBorder(sal_uInt32 nIndex); void putNestedAttribute(RTFSprms& rSprms, Id nParent, Id nId, const RTFValue::Pointer_t& pValue, RTFOverwrite eOverwrite = RTFOverwrite::YES, bool bAttribute = true); diff --git a/writerfilter/source/rtftok/rtfsprm.cxx b/writerfilter/source/rtftok/rtfsprm.cxx index 113feecf5f53..e021feee623c 100644 --- a/writerfilter/source/rtftok/rtfsprm.cxx +++ b/writerfilter/source/rtftok/rtfsprm.cxx @@ -78,6 +78,17 @@ RTFValue::Pointer_t RTFSprms::find(Id nKeyword, bool bFirst, bool bForWrite) void RTFSprms::set(Id nKeyword, RTFValue::Pointer_t pValue, RTFOverwrite eOverwrite) { ensureCopyBeforeWrite(); + + if (eOverwrite == RTFOverwrite::YES_PREPEND) + { + auto it = std::remove_if( + m_pSprms->begin(), m_pSprms->end(), + [nKeyword](const RTFSprms::Entry_t& rSprm) { return rSprm.first == nKeyword; }); + m_pSprms->erase(it, m_pSprms->end()); + m_pSprms->insert(m_pSprms->begin(), std::make_pair(nKeyword, pValue)); + return; + } + bool bFound = false; if (eOverwrite == RTFOverwrite::YES || eOverwrite == RTFOverwrite::NO_IGNORE) { diff --git a/writerfilter/source/rtftok/rtfsprm.hxx b/writerfilter/source/rtftok/rtfsprm.hxx index 04367ea28921..7839682343b8 100644 --- a/writerfilter/source/rtftok/rtfsprm.hxx +++ b/writerfilter/source/rtftok/rtfsprm.hxx @@ -41,7 +41,8 @@ enum class RTFOverwrite { YES, ///< Yes, if an existing key is found, overwrite it. NO_APPEND, ///< No, always append the value to the end of the list. - NO_IGNORE ///< No, if the key is already in the list, then ignore, otherwise append. + NO_IGNORE, ///< No, if the key is already in the list, then ignore, otherwise append. + YES_PREPEND ///< Yes, always prepend the value to the start of the list and remove existing entries. }; /// A list of RTFSprm with a copy constructor that performs a deep copy. |