[Libreoffice-commits] core.git: Branch 'libreoffice-6-0' - sw/qa writerfilter/source

Miklos Vajna vmiklos at collabora.co.uk
Fri Feb 9 15:01:25 UTC 2018


 sw/qa/extras/rtfimport/data/tdf115242.rtf         |   40 ++++++++++++++++++++++
 sw/qa/extras/rtfimport/rtfimport.cxx              |    8 ++++
 writerfilter/source/dmapper/DomainMapper.cxx      |   24 +++++++++++--
 writerfilter/source/dmapper/DomainMapper_Impl.cxx |    5 +-
 writerfilter/source/rtftok/rtfdispatchvalue.cxx   |    8 +++-
 writerfilter/source/rtftok/rtfdocumentimpl.cxx    |    5 +-
 writerfilter/source/rtftok/rtfdocumentimpl.hxx    |    3 +
 writerfilter/source/rtftok/rtfsprm.cxx            |   11 ++++++
 writerfilter/source/rtftok/rtfsprm.hxx            |    3 +
 9 files changed, 96 insertions(+), 11 deletions(-)

New commits:
commit ecff2a84e2766dd93bd028e065d9ea3d833b369b
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date:   Mon Feb 5 16:02:19 2018 +0100

    tdf#115242 RTF import: order numPr before other paragraph properties
    
    So that paragraph properties inherited from numbering properties can be
    properly overwritten with direct formatting, even when we have to take
    style deduplication into account.
    
    The OOXML tokenizer already did this,
    writerfilter::dmapper::DomainMapper::sprmWithProps()'s
    NS_ooxml::LN_CT_NumPr_numId depends on this, so adapt the RTF tokenizer
    accordingly.
    
    (cherry picked from commit 03cee02464f230a2efa67d131c137f32fe540052)
    
    Conflicts:
            sw/qa/extras/rtfimport/rtfimport.cxx
    
    Change-Id: Iec6026d146f08a9d06266763d01ed626a2d1f3d1
    Reviewed-on: https://gerrit.libreoffice.org/49355
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Caolán McNamara <caolanm at redhat.com>
    Tested-by: Caolán McNamara <caolanm at redhat.com>

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 030fccae1aab..2ae659ae8351 100644
--- a/sw/qa/extras/rtfimport/rtfimport.cxx
+++ b/sw/qa/extras/rtfimport/rtfimport.cxx
@@ -1397,6 +1397,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"));
+}
+
 // tests should only be added to rtfIMPORT *if* they fail round-tripping in rtfEXPORT
 
 CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/writerfilter/source/dmapper/DomainMapper.cxx b/writerfilter/source/dmapper/DomainMapper.cxx
index 8b2020e300ff..83698f4553de 100644
--- a/writerfilter/source/dmapper/DomainMapper.cxx
+++ b/writerfilter/source/dmapper/DomainMapper.cxx
@@ -509,12 +509,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:
@@ -551,8 +558,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 e5eee0325289..115bdb002688 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
@@ -5535,10 +5535,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 399be66da0a6..416f35204f19 100644
--- a/writerfilter/source/rtftok/rtfdispatchvalue.cxx
+++ b/writerfilter/source/rtftok/rtfdispatchvalue.cxx
@@ -670,8 +670,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 9f53f85f0a07..bfb40c83b8be 100644
--- a/writerfilter/source/rtftok/rtfdocumentimpl.cxx
+++ b/writerfilter/source/rtftok/rtfdocumentimpl.cxx
@@ -108,9 +108,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 5988e03d6c63..5fbfb9a46975 100644
--- a/writerfilter/source/rtftok/rtfdocumentimpl.hxx
+++ b/writerfilter/source/rtftok/rtfdocumentimpl.hxx
@@ -365,7 +365,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.


More information about the Libreoffice-commits mailing list