summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sw/qa/extras/rtfimport/data/tdf115242.rtf40
-rw-r--r--sw/qa/extras/rtfimport/rtfimport.cxx8
-rw-r--r--writerfilter/source/dmapper/DomainMapper.cxx24
-rw-r--r--writerfilter/source/dmapper/DomainMapper_Impl.cxx5
-rw-r--r--writerfilter/source/rtftok/rtfdispatchvalue.cxx8
-rw-r--r--writerfilter/source/rtftok/rtfdocumentimpl.cxx5
-rw-r--r--writerfilter/source/rtftok/rtfdocumentimpl.hxx3
-rw-r--r--writerfilter/source/rtftok/rtfsprm.cxx11
-rw-r--r--writerfilter/source/rtftok/rtfsprm.hxx3
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.