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

Miklos Vajna vmiklos at collabora.co.uk
Wed Sep 4 07:45:13 PDT 2013


 sw/qa/extras/ooxmlimport/data/fdo68787.docx           |binary
 sw/qa/extras/ooxmlimport/ooxmlimport.cxx              |    9 +++++++++
 writerfilter/source/dmapper/DomainMapper.cxx          |   16 ++++++++++++++++
 writerfilter/source/dmapper/DomainMapper_Impl.cxx     |    4 +++-
 writerfilter/source/dmapper/DomainMapper_Impl.hxx     |    6 ++++++
 writerfilter/source/dmapper/PropertyIds.cxx           |    1 +
 writerfilter/source/dmapper/PropertyIds.hxx           |    1 +
 writerfilter/source/dmapper/PropertyMap.cxx           |    3 +++
 writerfilter/source/ooxml/OOXMLFastContextHandler.cxx |   15 +++++++++++++--
 writerfilter/source/ooxml/OOXMLFastContextHandler.hxx |    3 +++
 writerfilter/source/ooxml/model.xml                   |    2 +-
 11 files changed, 56 insertions(+), 4 deletions(-)

New commits:
commit 330b860205c7ba69dd6603f65324d0f89ad9cd5f
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date:   Wed Sep 4 16:08:49 2013 +0200

    fdo#68787 DOCX import: handle when w:separator is missing for footnotes
    
    There were two problems here:
    
    1) OOXML has no way to explicitly disable the footnote separator, what
    is does is that it omits the <w:separator/> element in that case. We
    didn't parse that previously -- now we do, and if it's missing, the
    separator is disabled.
    
    2) The footnote stream isn't read by the importer, only when the main
    stream references the footnote one, the relevant part of it is parsed.
    At the moment we always parse the first (special, "separator") entry in
    the footnote stream, that may be optimized later if it becomes a
    bottleneck.
    
    Change-Id: Ie588270a212fc90fc41095029a362cfd832b24f8

diff --git a/sw/qa/extras/ooxmlimport/data/fdo68787.docx b/sw/qa/extras/ooxmlimport/data/fdo68787.docx
new file mode 100644
index 0000000..c47b809
Binary files /dev/null and b/sw/qa/extras/ooxmlimport/data/fdo68787.docx differ
diff --git a/sw/qa/extras/ooxmlimport/ooxmlimport.cxx b/sw/qa/extras/ooxmlimport/ooxmlimport.cxx
index 973f3b1..bfae9a3 100644
--- a/sw/qa/extras/ooxmlimport/ooxmlimport.cxx
+++ b/sw/qa/extras/ooxmlimport/ooxmlimport.cxx
@@ -131,6 +131,7 @@ public:
     void testTableStyleParprop();
     void testTablePagebreak();
     void testFdo68607();
+    void testFdo68787();
 
     CPPUNIT_TEST_SUITE(Test);
 #if !defined(MACOSX) && !defined(WNT)
@@ -228,6 +229,7 @@ void Test::run()
         {"table-style-parprop.docx", &Test::testTableStyleParprop},
         {"table-pagebreak.docx", &Test::testTablePagebreak},
         {"fdo68607.docx", &Test::testFdo68607},
+        {"fdo68787.docx", &Test::testFdo68787},
     };
     header();
     for (unsigned int i = 0; i < SAL_N_ELEMENTS(aMethods); ++i)
@@ -1540,6 +1542,13 @@ void Test::testFdo68607()
     CPPUNIT_ASSERT(getPages() > 1);
 }
 
+void Test::testFdo68787()
+{
+    uno::Reference<beans::XPropertySet> xPageStyle(getStyles("PageStyles")->getByName(DEFAULT_STYLE), uno::UNO_QUERY);
+    // This was 25, the 'lack of w:separator' <-> '0 line width' mapping was missing.
+    CPPUNIT_ASSERT_EQUAL(sal_Int32(0), getProperty<sal_Int32>(xPageStyle, "FootnoteLineRelativeWidth"));
+}
+
 CPPUNIT_TEST_SUITE_REGISTRATION(Test);
 
 CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/writerfilter/source/dmapper/DomainMapper.cxx b/writerfilter/source/dmapper/DomainMapper.cxx
index 261d99c..0dc4667 100644
--- a/writerfilter/source/dmapper/DomainMapper.cxx
+++ b/writerfilter/source/dmapper/DomainMapper.cxx
@@ -1465,6 +1465,11 @@ void DomainMapper::lcl_attribute(Id nName, Value & val)
             if (pSectionContext != NULL)
                 pSectionContext->SetPageNumber(nIntValue);
         break;
+        case NS_ooxml::LN_CT_FtnEdn_type:
+            // This is the "separator" footnote, ignore its linebreak.
+            if (static_cast<sal_uInt32>(nIntValue) == NS_ooxml::LN_Value_wordprocessingml_ST_FtnEdn_separator)
+                m_pImpl->m_bIgnoreNextPara = true;
+        break;
         default:
             {
 #if OSL_DEBUG_LEVEL > 0
@@ -3728,6 +3733,12 @@ void DomainMapper::lcl_utext(const sal_uInt8 * data_, size_t len)
         m_pImpl->m_pSdtHelper->createDateControl(sText);
         return;
     }
+    else if (len == 1 && sText[0] == 0x03)
+    {
+        // This is the uFtnEdnSep, remember that the document has a separator.
+        m_pImpl->m_bHasFtnSep = true;
+        return;
+    }
 
     try
     {
@@ -3735,6 +3746,11 @@ void DomainMapper::lcl_utext(const sal_uInt8 * data_, size_t len)
 
         if(len == 1 && (sText[0] == 0x0d || sText[0] == 0x07))
         {
+            if (m_pImpl->m_bIgnoreNextPara)
+            {
+                m_pImpl->m_bIgnoreNextPara = false;
+                return;
+            }
             PropertyMapPtr pContext = m_pImpl->GetTopContextOfType(CONTEXT_PARAGRAPH);
             if (pContext && m_pImpl->GetSettingsTable()->GetSplitPgBreakAndParaMark())
             {
diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.cxx b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
index 8a4b252..c89fdf2 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
@@ -175,7 +175,9 @@ DomainMapper_Impl::DomainMapper_Impl(
         m_bIsNewDoc(bIsNewDoc),
         m_bInTableStyleRunProps(false),
         m_pSdtHelper(0),
-        m_nTableDepth(0)
+        m_nTableDepth(0),
+        m_bHasFtnSep(false),
+        m_bIgnoreNextPara(false)
 
 {
     appendTableManager( );
diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.hxx b/writerfilter/source/dmapper/DomainMapper_Impl.hxx
index 9b1ebe1..0da21a0 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.hxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.hxx
@@ -701,6 +701,12 @@ public:
      * PFInTable SPRM or not).
      */
     sal_Int32 m_nTableDepth;
+
+    /// If the document has a footnote separator.
+    bool m_bHasFtnSep;
+
+    /// If the next newline should be ignored, used by the special footnote separator paragraph.
+    bool m_bIgnoreNextPara;
 };
 } //namespace dmapper
 } //namespace writerfilter
diff --git a/writerfilter/source/dmapper/PropertyIds.cxx b/writerfilter/source/dmapper/PropertyIds.cxx
index 34a0017..27ebabc 100644
--- a/writerfilter/source/dmapper/PropertyIds.cxx
+++ b/writerfilter/source/dmapper/PropertyIds.cxx
@@ -331,6 +331,7 @@ const OUString& PropertyNameSupplier::GetName( PropertyIds eId ) const
             case PROP_MIRROR_INDENTS : sName = "MirrorIndents"; break;
             case PROP_SURROUND_TEXT_WRAP_SMALL: sName = "SurroundTextWrapSmall"; break;
             case PROP_PARA_SHADOW_FORMAT: sName = "ParaShadowFormat"; break;
+            case PROP_FOOTNOTE_LINE_RELATIVE_WIDTH: sName = "FootnoteLineRelativeWidth"; break;
         }
         ::std::pair<PropertyNameMap_t::iterator,bool> aInsertIt =
                 m_pImpl->aNameMap.insert( PropertyNameMap_t::value_type( eId, sName ));
diff --git a/writerfilter/source/dmapper/PropertyIds.hxx b/writerfilter/source/dmapper/PropertyIds.hxx
index de53e7d..f35cdfd 100644
--- a/writerfilter/source/dmapper/PropertyIds.hxx
+++ b/writerfilter/source/dmapper/PropertyIds.hxx
@@ -302,6 +302,7 @@ enum PropertyIds
         ,PROP_MIRROR_INDENTS
         ,PROP_SURROUND_TEXT_WRAP_SMALL
         ,PROP_PARA_SHADOW_FORMAT
+        ,PROP_FOOTNOTE_LINE_RELATIVE_WIDTH
     };
 struct PropertyNameSupplier_Impl;
 class PropertyNameSupplier
diff --git a/writerfilter/source/dmapper/PropertyMap.cxx b/writerfilter/source/dmapper/PropertyMap.cxx
index d4cbbf2..91ab014 100644
--- a/writerfilter/source/dmapper/PropertyMap.cxx
+++ b/writerfilter/source/dmapper/PropertyMap.cxx
@@ -864,6 +864,9 @@ void SectionPropertyMap::HandleMarginsHeaderFooter(DomainMapper_Impl& rDM_Impl)
 
     if (rDM_Impl.m_oBackgroundColor)
         operator[](PropertyDefinition(PROP_BACK_COLOR )) = uno::makeAny(*rDM_Impl.m_oBackgroundColor);
+    if (!rDM_Impl.m_bHasFtnSep)
+        // Set footnote line width to zero, document has no footnote separator.
+        operator[](PropertyDefinition(PROP_FOOTNOTE_LINE_RELATIVE_WIDTH)) = uno::makeAny(sal_Int32(0));
 
     /*** if headers/footers are available then the top/bottom margins of the
       header/footer are copied to the top/bottom margin of the page
diff --git a/writerfilter/source/ooxml/OOXMLFastContextHandler.cxx b/writerfilter/source/ooxml/OOXMLFastContextHandler.cxx
index 8845623..e3962f5 100644
--- a/writerfilter/source/ooxml/OOXMLFastContextHandler.cxx
+++ b/writerfilter/source/ooxml/OOXMLFastContextHandler.cxx
@@ -1748,7 +1748,7 @@ void OOXMLFastContextHandlerTable::newPropertySet
 
 OOXMLFastContextHandlerXNote::OOXMLFastContextHandlerXNote
 (OOXMLFastContextHandler * pContext)
-: OOXMLFastContextHandlerProperties(pContext), mbForwardEventsSaved(false)
+: OOXMLFastContextHandlerProperties(pContext), mbForwardEventsSaved(false), mnMyXNoteType(0)
 {
 }
 
@@ -1763,7 +1763,8 @@ void OOXMLFastContextHandlerXNote::lcl_startFastElement
 {
     mbForwardEventsSaved = isForwardEvents();
 
-    if (mnMyXNoteId == getXNoteId())
+    // If this is the note we're looking for or this is the footnote separator one.
+    if (mnMyXNoteId == getXNoteId() || static_cast<sal_uInt32>(mnMyXNoteType) == NS_ooxml::LN_Value_wordprocessingml_ST_FtnEdn_separator)
         setForwardEvents(true);
     else
         setForwardEvents(false);
@@ -1794,6 +1795,16 @@ void OOXMLFastContextHandlerXNote::checkId(OOXMLValue::Pointer_t pValue)
     mnMyXNoteId = sal_Int32(pValue->getInt());
 }
 
+void OOXMLFastContextHandlerXNote::checkType(OOXMLValue::Pointer_t pValue)
+{
+#ifdef DEBUG_ELEMENT
+    debug_logger->startElement("checkType");
+    debug_logger->attribute("myType", sal_Int32(pValue->getInt()));
+    debug_logger->endElement();
+#endif
+    mnMyXNoteType = pValue->getInt();
+}
+
 /*
   class OOXMLFastContextHandlerTextTableCell
  */
diff --git a/writerfilter/source/ooxml/OOXMLFastContextHandler.hxx b/writerfilter/source/ooxml/OOXMLFastContextHandler.hxx
index 5a72be2..d26dcda7 100644
--- a/writerfilter/source/ooxml/OOXMLFastContextHandler.hxx
+++ b/writerfilter/source/ooxml/OOXMLFastContextHandler.hxx
@@ -432,11 +432,14 @@ public:
 
     void checkId(OOXMLValue::Pointer_t pValue);
 
+    void checkType(OOXMLValue::Pointer_t pValue);
+
     virtual string getType() const { return "XNote"; }
 
 private:
     bool mbForwardEventsSaved;
     sal_Int32 mnMyXNoteId;
+    sal_Int32 mnMyXNoteType;
 
     virtual void lcl_startFastElement
     (Token_t Element,
diff --git a/writerfilter/source/ooxml/model.xml b/writerfilter/source/ooxml/model.xml
index 63c182c..3f0ed5a 100644
--- a/writerfilter/source/ooxml/model.xml
+++ b/writerfilter/source/ooxml/model.xml
@@ -23120,7 +23120,7 @@
       <attribute name="id" tokenid="ooxml:CT_FtnEdnSepRef_id"/>
     </resource>
     <resource name="CT_FtnEdn" resource="XNote" tag="reference">
-      <attribute name="type" tokenid="ooxml:CT_FtnEdn_type"/>
+      <attribute name="type" tokenid="ooxml:CT_FtnEdn_type" action="checkType"/>
       <attribute name="id" tokenid="ooxml:CT_FtnEdn_id" action="checkId"/>
       <action name="start" action="propagateCharacterProperties"/>
       <action name="end" action="endSectionGroup"/>


More information about the Libreoffice-commits mailing list