[Libreoffice-commits] core.git: 2 commits - external/libepubgen writerperfect/qa writerperfect/source

Miklos Vajna vmiklos at collabora.co.uk
Fri Dec 1 15:33:12 UTC 2017


 external/libepubgen/libepubgen-epub3.patch.1     |  173 +++++++++++++++++++++++
 writerperfect/qa/unit/EPUBExportTest.cxx         |   35 ++++
 writerperfect/source/writer/EPUBExportFilter.cxx |   11 +
 writerperfect/source/writer/exp/txtparai.cxx     |    7 
 writerperfect/source/writer/exp/txtstyli.cxx     |   96 ++++++++++++
 writerperfect/source/writer/exp/txtstyli.hxx     |   29 +++
 writerperfect/source/writer/exp/xmlfmt.cxx       |   27 ++-
 writerperfect/source/writer/exp/xmlfmt.hxx       |   13 +
 writerperfect/source/writer/exp/xmlimp.cxx       |   31 +++-
 writerperfect/source/writer/exp/xmlimp.hxx       |    7 
 10 files changed, 413 insertions(+), 16 deletions(-)

New commits:
commit 01283fe86cc523f1bed38bdfc5fbcb1694972169
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date:   Fri Dec 1 10:57:35 2017 +0100

    EPUB export allow requesting fixed layout from cmdline
    
    FilterData is a typed map of options, suitable for UNO API clients, also
    that's what the UI uses. OTOH the --convert-to cmdline option can only
    set a FilterOptions string, so support that way as well.
    
    --convert-to epub:EPUB:layout=fixed
    
    can be used to trigger this.
    
    Change-Id: I9f429107ae1db3dc4b6ab3b2b75665f096a1a33a
    Reviewed-on: https://gerrit.libreoffice.org/45646
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Miklos Vajna <vmiklos at collabora.co.uk>

diff --git a/writerperfect/qa/unit/EPUBExportTest.cxx b/writerperfect/qa/unit/EPUBExportTest.cxx
index a9c3db57c299..ac6e25efc2ae 100644
--- a/writerperfect/qa/unit/EPUBExportTest.cxx
+++ b/writerperfect/qa/unit/EPUBExportTest.cxx
@@ -42,6 +42,7 @@ class EPUBExportTest : public test::BootstrapFixture, public unotest::MacrosTest
     utl::TempFile maTempFile;
     xmlDocPtr mpXmlDoc = nullptr;
     uno::Reference<packages::zip::XZipFileAccess2> mxZipFile;
+    OUString maFilterOptions;
 
 public:
     void setUp() override;
@@ -58,6 +59,7 @@ public:
     void testMimetype();
     void testEPUB2();
     void testEPUBFixedLayout();
+    void testEPUBFixedLayoutOption();
     void testPageBreakSplit();
     void testSpanAutostyle();
     void testParaAutostyleCharProps();
@@ -99,6 +101,7 @@ public:
     CPPUNIT_TEST(testMimetype);
     CPPUNIT_TEST(testEPUB2);
     CPPUNIT_TEST(testEPUBFixedLayout);
+    CPPUNIT_TEST(testEPUBFixedLayoutOption);
     CPPUNIT_TEST(testPageBreakSplit);
     CPPUNIT_TEST(testSpanAutostyle);
     CPPUNIT_TEST(testParaAutostyleCharProps);
@@ -177,7 +180,10 @@ void EPUBExportTest::createDoc(const OUString &rFile, const uno::Sequence<beans:
     maTempFile.EnableKillingFile();
     utl::MediaDescriptor aMediaDescriptor;
     aMediaDescriptor["FilterName"] <<= OUString("EPUB");
-    aMediaDescriptor["FilterData"] <<= rFilterData;
+    if (maFilterOptions.isEmpty())
+        aMediaDescriptor["FilterData"] <<= rFilterData;
+    else
+        aMediaDescriptor["FilterOptions"] <<= maFilterOptions;
     xStorable->storeToURL(maTempFile.GetURL(), aMediaDescriptor.getAsConstPropertyValueList());
     mxZipFile = packages::zip::ZipFileAccess::createWithURL(mxComponentContext, maTempFile.GetURL());
 }
@@ -310,6 +316,17 @@ void EPUBExportTest::testEPUBFixedLayout()
     assertXPathContent(mpXmlDoc, "/opf:package/opf:metadata/opf:meta[@property='rendition:layout']", "pre-paginated");
 }
 
+void EPUBExportTest::testEPUBFixedLayoutOption()
+{
+    // Explicitly request fixed layout, this time via FilterOptions.
+    maFilterOptions = "layout=fixed";
+    createDoc("hello.fodt", {});
+
+    // This failed, fixed layout was only working via the FilterData map.
+    mpXmlDoc = parseExport("OEBPS/content.opf");
+    assertXPathContent(mpXmlDoc, "/opf:package/opf:metadata/opf:meta[@property='rendition:layout']", "pre-paginated");
+}
+
 void EPUBExportTest::testPageBreakSplit()
 {
     uno::Sequence<beans::PropertyValue> aFilterData(comphelper::InitPropertySequence(
diff --git a/writerperfect/source/writer/EPUBExportFilter.cxx b/writerperfect/source/writer/EPUBExportFilter.cxx
index 8ebf5994aedc..627d5a4af18f 100644
--- a/writerperfect/source/writer/EPUBExportFilter.cxx
+++ b/writerperfect/source/writer/EPUBExportFilter.cxx
@@ -63,15 +63,20 @@ sal_Bool EPUBExportFilter::filter(const uno::Sequence<beans::PropertyValue> &rDe
     sal_Int32 nSplitMethod = EPUBExportFilter::GetDefaultSplitMethod();
     sal_Int32 nLayoutMethod = EPUBExportFilter::GetDefaultLayoutMethod();
     uno::Sequence<beans::PropertyValue> aFilterData;
+    OUString aFilterOptions;
     for (sal_Int32 i = 0; i < rDescriptor.getLength(); ++i)
     {
         if (rDescriptor[i].Name == "FilterData")
-        {
             rDescriptor[i].Value >>= aFilterData;
-            break;
-        }
+        else if (rDescriptor[i].Name == "FilterOptions")
+            rDescriptor[i].Value >>= aFilterOptions;
     }
 
+#if LIBEPUBGEN_VERSION_SUPPORT
+    if (aFilterOptions == "layout=fixed")
+        nLayoutMethod = libepubgen::EPUB_LAYOUT_METHOD_FIXED;
+#endif
+
     for (sal_Int32 i = 0; i < aFilterData.getLength(); ++i)
     {
         if (aFilterData[i].Name == "EPUBVersion")
commit 89e7a00080aadeba08ee649877b2507dc312f9f8
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date:   Fri Dec 1 10:56:03 2017 +0100

    EPUB export: handle page size in fixed layout
    
    Requires parsing master pages and page layouts.
    
    Change-Id: Ia8b9e59a9355396d3776af06e8e67ec88033754b
    Reviewed-on: https://gerrit.libreoffice.org/45645
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Miklos Vajna <vmiklos at collabora.co.uk>

diff --git a/external/libepubgen/libepubgen-epub3.patch.1 b/external/libepubgen/libepubgen-epub3.patch.1
index da2b935ad816..c234ab10ec13 100644
--- a/external/libepubgen/libepubgen-epub3.patch.1
+++ b/external/libepubgen/libepubgen-epub3.patch.1
@@ -5658,3 +5658,176 @@ index 5d4e8f2..c3bc963 100644
 -- 
 2.13.6
 
+From 38aa728708641942371507b975193f0ab60f0b50 Mon Sep 17 00:00:00 2001
+From: Miklos Vajna <vmiklos at collabora.co.uk>
+Date: Wed, 29 Nov 2017 11:00:32 +0100
+Subject: [PATCH] EPUBGenerator: fixed layout implies split on page break
+
+---
+ Makefile.am                        |  3 +++
+ src/lib/EPUBGenerator.cpp          |  8 ++++++++
+ src/lib/EPUBHTMLGenerator.cpp      | 16 ++++++++++++++++
+ src/lib/EPUBHTMLGenerator.h        |  5 +++++
+ src/lib/EPUBSplitGuard.cpp         |  5 +++++
+ src/lib/EPUBSplitGuard.h           |  4 +++-
+ src/test/EPUBTextGeneratorTest.cpp | 31 +++++++++++++++++++++++++++++++
+ 7 files changed, 71 insertions(+), 1 deletion(-)
+
+diff --git a/src/lib/EPUBGenerator.cpp b/src/lib/EPUBGenerator.cpp
+index 4a62d7f..f608331 100644
+--- a/src/lib/EPUBGenerator.cpp
++++ b/src/lib/EPUBGenerator.cpp
+@@ -118,7 +118,12 @@ void EPUBGenerator::startNewHtmlFile()
+ 
+   m_splitGuard.onSplit();
+ 
++  librevenge::RVNGPropertyList pageProperties;
++  if (m_layoutMethod == EPUB_LAYOUT_METHOD_FIXED && m_currentHtml)
++    m_currentHtml->getPageProperties(pageProperties);
+   m_currentHtml = m_htmlManager.create(m_imageManager, m_fontManager, m_listStyleManager, m_paragraphStyleManager, m_spanStyleManager, m_tableStyleManager, m_stylesheetPath, m_stylesMethod, m_layoutMethod, m_version);
++  if (m_layoutMethod == EPUB_LAYOUT_METHOD_FIXED)
++    m_currentHtml->setPageProperties(pageProperties);
+ 
+   // restore state in the new file
+   m_currentHtml->startDocument(m_documentProps);
+@@ -160,6 +165,9 @@ void EPUBGenerator::setStylesMethod(EPUBStylesMethod styles)
+ void EPUBGenerator::setLayoutMethod(EPUBLayoutMethod layout)
+ {
+   m_layoutMethod = layout;
++  if (m_layoutMethod == EPUB_LAYOUT_METHOD_FIXED)
++    // Fixed layout implies split on page break.
++    m_splitGuard.setSplitMethod(EPUB_SPLIT_METHOD_PAGE_BREAK);
+ }
+ 
+ void EPUBGenerator::writeContainer()
+diff --git a/src/lib/EPUBHTMLGenerator.cpp b/src/lib/EPUBHTMLGenerator.cpp
+index 4260858..7a53ce3 100644
+--- a/src/lib/EPUBHTMLGenerator.cpp
++++ b/src/lib/EPUBHTMLGenerator.cpp
+@@ -1173,6 +1173,22 @@ void EPUBHTMLGenerator::closePopup(EPUBXMLSink &main)
+ 
+ void EPUBHTMLGenerator::insertEquation(const RVNGPropertyList & /* propList */) {}
+ 
++void EPUBHTMLGenerator::getPageProperties(librevenge::RVNGPropertyList &propList) const
++{
++  propList.clear();
++  librevenge::RVNGPropertyList::Iter i(m_impl->m_actualPageProperties);
++  for (i.rewind(); i.next();)
++    propList.insert(i.key(), i()->clone());
++}
++
++void EPUBHTMLGenerator::setPageProperties(const librevenge::RVNGPropertyList &propList)
++{
++  m_impl->m_actualPageProperties.clear();
++  librevenge::RVNGPropertyList::Iter i(propList);
++  for (i.rewind(); i.next();)
++    m_impl->m_actualPageProperties.insert(i.key(), i()->clone());
++}
++
+ }
+ 
+ /* vim:set shiftwidth=2 softtabstop=2 expandtab: */
+diff --git a/src/lib/EPUBHTMLGenerator.h b/src/lib/EPUBHTMLGenerator.h
+index 3c6577f..ef7d542 100644
+--- a/src/lib/EPUBHTMLGenerator.h
++++ b/src/lib/EPUBHTMLGenerator.h
+@@ -112,6 +112,11 @@ public:
+   void insertBinaryObject(const librevenge::RVNGPropertyList &propList) override;
+   void insertEquation(const librevenge::RVNGPropertyList &propList) override;
+ 
++  /// Gets the actual page properties into propList.
++  void getPageProperties(librevenge::RVNGPropertyList &propList) const;
++  /// Sets the actual page properties from propList.
++  void setPageProperties(const librevenge::RVNGPropertyList &propList);
++
+ private:
+   EPUBXMLSink &openPopup();
+   void closePopup(EPUBXMLSink &main);
+diff --git a/src/lib/EPUBSplitGuard.cpp b/src/lib/EPUBSplitGuard.cpp
+index 890500b..4f7531d 100644
+--- a/src/lib/EPUBSplitGuard.cpp
++++ b/src/lib/EPUBSplitGuard.cpp
+@@ -40,6 +40,11 @@ void EPUBSplitGuard::setSplitSize(const unsigned size)
+   m_size = size;
+ }
+ 
++void EPUBSplitGuard::setSplitMethod(EPUBSplitMethod method)
++{
++  m_method = method;
++}
++
+ void EPUBSplitGuard::openLevel()
+ {
+   ++m_nestingLevel;
+diff --git a/src/lib/EPUBSplitGuard.h b/src/lib/EPUBSplitGuard.h
+index 1a74079..ff55846 100644
+--- a/src/lib/EPUBSplitGuard.h
++++ b/src/lib/EPUBSplitGuard.h
+@@ -23,6 +23,8 @@ public:
+   void setSplitHeadingLevel(unsigned level);
+   void setCurrentHeadingLevel(unsigned level);
+   void setSplitSize(unsigned size);
++  /// Allows overwriting the value given in the constructor.
++  void setSplitMethod(EPUBSplitMethod method);
+ 
+   void openLevel();
+   void closeLevel();
+@@ -39,7 +41,7 @@ private:
+   bool canSplit(EPUBSplitMethod method) const;
+ 
+ private:
+-  const EPUBSplitMethod m_method;
++  EPUBSplitMethod m_method;
+   unsigned m_headingLevel;
+   unsigned m_currentHeadingLevel;
+   unsigned m_size;
+-- 
+2.13.6
+
+From d9921c47befa3eabcfc916e26e273667232be637 Mon Sep 17 00:00:00 2001
+From: Miklos Vajna <vmiklos at collabora.co.uk>
+Date: Wed, 29 Nov 2017 14:44:55 +0100
+Subject: [PATCH] EPUBTextGenerator: page-break=auto is not a page break
+
+---
+ src/lib/EPUBTextGenerator.cpp      | 14 ++++++++++++--
+ src/test/EPUBTextGeneratorTest.cpp | 21 +++++++++++++++++++++
+ 2 files changed, 33 insertions(+), 2 deletions(-)
+
+diff --git a/src/lib/EPUBTextGenerator.cpp b/src/lib/EPUBTextGenerator.cpp
+index c3bc963..02c299a 100644
+--- a/src/lib/EPUBTextGenerator.cpp
++++ b/src/lib/EPUBTextGenerator.cpp
+@@ -53,6 +53,16 @@ bool operator!=(const char *const left, const RVNGString &right)
+   return right != left;
+ }
+ 
++/// Determines if this break property a page break one.
++bool isPageBreak(const librevenge::RVNGProperty *property)
++{
++  if (!property)
++    return false;
++
++  librevenge::RVNGString str = property->getStr();
++  return str != "column" && str != "auto";
++}
++
+ }
+ 
+ struct EPUBTextGenerator::Impl : public EPUBGenerator
+@@ -259,10 +269,10 @@ void EPUBTextGenerator::defineParagraphStyle(const librevenge::RVNGPropertyList
+ void EPUBTextGenerator::openParagraph(const librevenge::RVNGPropertyList &propList)
+ {
+   const RVNGProperty *const breakBefore = propList["fo:break-before"];
+-  if (breakBefore && ("column" != breakBefore->getStr()) && m_impl->getSplitGuard().splitOnPageBreak())
++  if (isPageBreak(breakBefore) && m_impl->getSplitGuard().splitOnPageBreak())
+     m_impl->startNewHtmlFile();
+   const RVNGProperty *const breakAfter = propList["fo:break-after"];
+-  m_impl->m_breakAfterPara = breakAfter && ("column" != breakAfter->getStr());
++  m_impl->m_breakAfterPara = isPageBreak(breakAfter);
+   if (m_impl->getSplitGuard().splitOnSize())
+     m_impl->startNewHtmlFile();
+ 
+-- 
+2.13.6
+
diff --git a/writerperfect/qa/unit/EPUBExportTest.cxx b/writerperfect/qa/unit/EPUBExportTest.cxx
index a9692bc2c293..a9c3db57c299 100644
--- a/writerperfect/qa/unit/EPUBExportTest.cxx
+++ b/writerperfect/qa/unit/EPUBExportTest.cxx
@@ -92,6 +92,7 @@ public:
     void testFootnote();
     void testPopup();
     void testPopupAPI();
+    void testPageSize();
 
     CPPUNIT_TEST_SUITE(EPUBExportTest);
     CPPUNIT_TEST(testOutlineLevel);
@@ -132,6 +133,7 @@ public:
     CPPUNIT_TEST(testFootnote);
     CPPUNIT_TEST(testPopup);
     CPPUNIT_TEST(testPopupAPI);
+    CPPUNIT_TEST(testPageSize);
     CPPUNIT_TEST_SUITE_END();
 };
 
@@ -763,6 +765,20 @@ void EPUBExportTest::testPopupAPI()
     CPPUNIT_ASSERT(aAnchor != aData);
 }
 
+void EPUBExportTest::testPageSize()
+{
+    uno::Sequence<beans::PropertyValue> aFilterData(comphelper::InitPropertySequence(
+    {
+        {"EPUBLayoutMethod", uno::makeAny(static_cast<sal_Int32>(libepubgen::EPUB_LAYOUT_METHOD_FIXED))}
+    }));
+    createDoc("hello.fodt", aFilterData);
+
+    // This failed, viewport was empty, so page size was lost.
+    mpXmlDoc = parseExport("OEBPS/sections/section0001.xhtml");
+    // 21,59cm x 27.94cm (letter).
+    assertXPath(mpXmlDoc, "/xhtml:html/xhtml:head/xhtml:meta[@name='viewport']", "content", "width=816, height=1056");
+}
+
 CPPUNIT_TEST_SUITE_REGISTRATION(EPUBExportTest);
 
 }
diff --git a/writerperfect/source/writer/exp/txtparai.cxx b/writerperfect/source/writer/exp/txtparai.cxx
index 309f80ce607a..95f85d86f454 100644
--- a/writerperfect/source/writer/exp/txtparai.cxx
+++ b/writerperfect/source/writer/exp/txtparai.cxx
@@ -397,6 +397,13 @@ void XMLParaContext::startElement(const OUString &/*rName*/, const css::uno::Ref
         }
     }
 
+    if (!mrImport.IsPageSpanOpened())
+    {
+        auto it = mrImport.GetMasterPages().find("Standard");
+        if (it != mrImport.GetMasterPages().end())
+            mrImport.GetGenerator().openPageSpan(it->second);
+        mrImport.SetPageSpanOpened(true);
+    }
     mrImport.GetGenerator().openParagraph(aPropertyList);
 }
 
diff --git a/writerperfect/source/writer/exp/txtstyli.cxx b/writerperfect/source/writer/exp/txtstyli.cxx
index e8fe1a43bea0..38b32768ddf0 100644
--- a/writerperfect/source/writer/exp/txtstyli.cxx
+++ b/writerperfect/source/writer/exp/txtstyli.cxx
@@ -320,6 +320,102 @@ librevenge::RVNGPropertyList &XMLStyleContext::GetGraphicPropertyList()
     return m_aGraphicPropertyList;
 }
 
+XMLMasterPageContext::XMLMasterPageContext(XMLImport &rImport, XMLStylesContext &rStyles)
+    : XMLImportContext(rImport),
+      m_rStyles(rStyles)
+{
+    // I'll remove this in a follow-up commit.
+    (void)m_rStyles;
+}
+
+void XMLMasterPageContext::startElement(const OUString &/*rName*/, const css::uno::Reference<css::xml::sax::XAttributeList> &xAttribs)
+{
+    OUString aName;
+    OUString aPageLayoutName;
+    for (sal_Int16 i = 0; i < xAttribs->getLength(); ++i)
+    {
+        const OUString &rAttributeName = xAttribs->getNameByIndex(i);
+        const OUString &rAttributeValue = xAttribs->getValueByIndex(i);
+        if (rAttributeName == "style:name")
+            aName = rAttributeValue;
+        else if (rAttributeName == "style:page-layout-name")
+            aPageLayoutName = rAttributeValue;
+    }
+    auto it = mrImport.GetPageLayouts().find(aPageLayoutName);
+    if (it == mrImport.GetPageLayouts().end())
+        return;
+
+    librevenge::RVNGPropertyList::Iter itProp(it->second);
+    librevenge::RVNGPropertyList aPropertyList;
+    for (itProp.rewind(); itProp.next();)
+        aPropertyList.insert(itProp.key(), itProp()->clone());
+    mrImport.GetMasterPages()[aName] = aPropertyList;
+}
+
+/// Handler for <style:page-layout-properties>.
+class XMLPageLayoutPropertiesContext : public XMLImportContext
+{
+public:
+    XMLPageLayoutPropertiesContext(XMLImport &rImport, XMLPageLayoutContext &rStyle);
+
+    void SAL_CALL startElement(const OUString &rName, const css::uno::Reference<css::xml::sax::XAttributeList> &xAttribs) override;
+
+private:
+    XMLPageLayoutContext &m_rStyle;
+};
+
+XMLPageLayoutPropertiesContext::XMLPageLayoutPropertiesContext(XMLImport &rImport, XMLPageLayoutContext &rStyle)
+    : XMLImportContext(rImport)
+    , m_rStyle(rStyle)
+{
+}
+
+void XMLPageLayoutPropertiesContext::startElement(const OUString &/*rName*/, const css::uno::Reference<css::xml::sax::XAttributeList> &xAttribs)
+{
+    for (sal_Int16 i = 0; i < xAttribs->getLength(); ++i)
+    {
+        OString sName = OUStringToOString(xAttribs->getNameByIndex(i), RTL_TEXTENCODING_UTF8);
+        OString sValue = OUStringToOString(xAttribs->getValueByIndex(i), RTL_TEXTENCODING_UTF8);
+        m_rStyle.GetPropertyList().insert(sName.getStr(), sValue.getStr());
+    }
+}
+
+XMLPageLayoutContext::XMLPageLayoutContext(XMLImport &rImport, XMLStylesContext &rStyles)
+    : XMLImportContext(rImport),
+      m_rStyles(rStyles)
+{
+}
+
+void XMLPageLayoutContext::startElement(const OUString &/*rName*/, const css::uno::Reference<css::xml::sax::XAttributeList> &xAttribs)
+{
+    for (sal_Int16 i = 0; i < xAttribs->getLength(); ++i)
+    {
+        const OUString &rAttributeName = xAttribs->getNameByIndex(i);
+        const OUString &rAttributeValue = xAttribs->getValueByIndex(i);
+        if (rAttributeName == "style:name")
+            m_aName = rAttributeValue;
+    }
+}
+
+rtl::Reference<XMLImportContext> XMLPageLayoutContext::CreateChildContext(const OUString &rName, const css::uno::Reference<css::xml::sax::XAttributeList> &/*xAttribs*/)
+{
+    if (rName == "style:page-layout-properties")
+        return new XMLPageLayoutPropertiesContext(mrImport, *this);
+    return nullptr;
+}
+
+void XMLPageLayoutContext::endElement(const OUString &/*rName*/)
+{
+    if (m_aName.isEmpty())
+        return;
+
+    m_rStyles.GetCurrentPageLayouts()[m_aName] = m_aPropertyList;
+}
+
+librevenge::RVNGPropertyList &XMLPageLayoutContext::GetPropertyList()
+{
+    return m_aPropertyList;
+}
 } // namespace exp
 } // namespace writerperfect
 
diff --git a/writerperfect/source/writer/exp/txtstyli.hxx b/writerperfect/source/writer/exp/txtstyli.hxx
index f3b3b6da38c9..06ae15e503f8 100644
--- a/writerperfect/source/writer/exp/txtstyli.hxx
+++ b/writerperfect/source/writer/exp/txtstyli.hxx
@@ -52,6 +52,35 @@ private:
     XMLStylesContext &m_rStyles;
 };
 
+/// Handler for <style:master-page>.
+class XMLMasterPageContext : public XMLImportContext
+{
+public:
+    XMLMasterPageContext(XMLImport &rImport, XMLStylesContext &rStyles);
+
+    void SAL_CALL startElement(const OUString &rName, const css::uno::Reference<css::xml::sax::XAttributeList> &xAttribs) override;
+
+private:
+    XMLStylesContext &m_rStyles;
+};
+
+/// Handler for <style:page-layout>.
+class XMLPageLayoutContext : public XMLImportContext
+{
+public:
+    XMLPageLayoutContext(XMLImport &rImport, XMLStylesContext &rStyles);
+
+    rtl::Reference<XMLImportContext> CreateChildContext(const OUString &rName, const css::uno::Reference<css::xml::sax::XAttributeList> &xAttribs) override;
+    void SAL_CALL startElement(const OUString &rName, const css::uno::Reference<css::xml::sax::XAttributeList> &xAttribs) override;
+    void SAL_CALL endElement(const OUString &rName) override;
+
+    librevenge::RVNGPropertyList &GetPropertyList();
+private:
+    OUString m_aName;
+    librevenge::RVNGPropertyList m_aPropertyList;
+    XMLStylesContext &m_rStyles;
+};
+
 } // namespace exp
 } // namespace writerperfect
 
diff --git a/writerperfect/source/writer/exp/xmlfmt.cxx b/writerperfect/source/writer/exp/xmlfmt.cxx
index abd6bb9a6a72..a4b0781c73f9 100644
--- a/writerperfect/source/writer/exp/xmlfmt.cxx
+++ b/writerperfect/source/writer/exp/xmlfmt.cxx
@@ -20,15 +20,17 @@ namespace writerperfect
 namespace exp
 {
 
-XMLStylesContext::XMLStylesContext(XMLImport &rImport, bool bAutomatic)
+XMLStylesContext::XMLStylesContext(XMLImport &rImport, StyleType eType)
     : XMLImportContext(rImport),
-      m_rParagraphStyles(bAutomatic ? mrImport.GetAutomaticParagraphStyles() : mrImport.GetParagraphStyles()),
-      m_rTextStyles(bAutomatic ? mrImport.GetAutomaticTextStyles() : mrImport.GetTextStyles()),
-      m_rCellStyles(bAutomatic ? mrImport.GetAutomaticCellStyles() : mrImport.GetCellStyles()),
-      m_rColumnStyles(bAutomatic ? mrImport.GetAutomaticColumnStyles() : mrImport.GetColumnStyles()),
-      m_rRowStyles(bAutomatic ? mrImport.GetAutomaticRowStyles() : mrImport.GetRowStyles()),
-      m_rTableStyles(bAutomatic ? mrImport.GetAutomaticTableStyles() : mrImport.GetTableStyles()),
-      m_rGraphicStyles(bAutomatic ? mrImport.GetAutomaticGraphicStyles() : mrImport.GetGraphicStyles())
+      m_rParagraphStyles(eType == StyleType_AUTOMATIC ? mrImport.GetAutomaticParagraphStyles() : mrImport.GetParagraphStyles()),
+      m_rTextStyles(eType == StyleType_AUTOMATIC ? mrImport.GetAutomaticTextStyles() : mrImport.GetTextStyles()),
+      m_rCellStyles(eType == StyleType_AUTOMATIC ? mrImport.GetAutomaticCellStyles() : mrImport.GetCellStyles()),
+      m_rColumnStyles(eType == StyleType_AUTOMATIC ? mrImport.GetAutomaticColumnStyles() : mrImport.GetColumnStyles()),
+      m_rRowStyles(eType == StyleType_AUTOMATIC ? mrImport.GetAutomaticRowStyles() : mrImport.GetRowStyles()),
+      m_rTableStyles(eType == StyleType_AUTOMATIC ? mrImport.GetAutomaticTableStyles() : mrImport.GetTableStyles()),
+      m_rGraphicStyles(eType == StyleType_AUTOMATIC ? mrImport.GetAutomaticGraphicStyles() : mrImport.GetGraphicStyles()),
+      m_rPageLayouts(mrImport.GetPageLayouts()),
+      m_eType(eType)
 {
 }
 
@@ -36,6 +38,10 @@ rtl::Reference<XMLImportContext> XMLStylesContext::CreateChildContext(const OUSt
 {
     if (rName == "style:style")
         return new XMLStyleContext(mrImport, *this);
+    if (m_eType == StyleType_MASTER && rName == "style:master-page")
+        return new XMLMasterPageContext(mrImport, *this);
+    if (m_eType == StyleType_AUTOMATIC && rName == "style:page-layout")
+        return new XMLPageLayoutContext(mrImport, *this);
     return nullptr;
 }
 
@@ -74,6 +80,11 @@ std::map<OUString, librevenge::RVNGPropertyList> &XMLStylesContext::GetCurrentGr
     return m_rGraphicStyles;
 }
 
+std::map<OUString, librevenge::RVNGPropertyList> &XMLStylesContext::GetCurrentPageLayouts()
+{
+    return m_rPageLayouts;
+}
+
 /// Handler for <style:font-face>.
 class XMLFontFaceContext : public XMLImportContext
 {
diff --git a/writerperfect/source/writer/exp/xmlfmt.hxx b/writerperfect/source/writer/exp/xmlfmt.hxx
index 3f609e98b000..24ee493cd660 100644
--- a/writerperfect/source/writer/exp/xmlfmt.hxx
+++ b/writerperfect/source/writer/exp/xmlfmt.hxx
@@ -21,11 +21,17 @@ namespace writerperfect
 namespace exp
 {
 
-/// Handler for <office:automatic-styles>/<office:styles>.
+/// Handler for <office:automatic-styles>/<office:master-styles>/<office:styles>.
 class XMLStylesContext : public XMLImportContext
 {
 public:
-    XMLStylesContext(XMLImport &rImport, bool bAutomatic);
+    enum StyleType
+    {
+        StyleType_NONE,
+        StyleType_AUTOMATIC,
+        StyleType_MASTER
+    };
+    XMLStylesContext(XMLImport &rImport, StyleType eType);
 
     rtl::Reference<XMLImportContext> CreateChildContext(const OUString &rName, const css::uno::Reference<css::xml::sax::XAttributeList> &xAttribs) override;
 
@@ -36,6 +42,7 @@ public:
     std::map<OUString, librevenge::RVNGPropertyList> &GetCurrentRowStyles();
     std::map<OUString, librevenge::RVNGPropertyList> &GetCurrentTableStyles();
     std::map<OUString, librevenge::RVNGPropertyList> &GetCurrentGraphicStyles();
+    std::map<OUString, librevenge::RVNGPropertyList> &GetCurrentPageLayouts();
 private:
     std::map<OUString, librevenge::RVNGPropertyList> &m_rParagraphStyles;
     std::map<OUString, librevenge::RVNGPropertyList> &m_rTextStyles;
@@ -44,6 +51,8 @@ private:
     std::map<OUString, librevenge::RVNGPropertyList> &m_rRowStyles;
     std::map<OUString, librevenge::RVNGPropertyList> &m_rTableStyles;
     std::map<OUString, librevenge::RVNGPropertyList> &m_rGraphicStyles;
+    std::map<OUString, librevenge::RVNGPropertyList> &m_rPageLayouts;
+    StyleType m_eType;
 };
 
 /// Handler for <office:font-face-decls>.
diff --git a/writerperfect/source/writer/exp/xmlimp.cxx b/writerperfect/source/writer/exp/xmlimp.cxx
index 7b6cc2791459..1d245401aea6 100644
--- a/writerperfect/source/writer/exp/xmlimp.cxx
+++ b/writerperfect/source/writer/exp/xmlimp.cxx
@@ -246,11 +246,13 @@ rtl::Reference<XMLImportContext> XMLOfficeDocContext::CreateChildContext(const O
     else if (rName == "office:meta")
         return new XMLMetaDocumentContext(mrImport);
     else if (rName == "office:automatic-styles")
-        return new XMLStylesContext(mrImport, /*bAutomatic=*/true);
+        return new XMLStylesContext(mrImport, XMLStylesContext::StyleType_AUTOMATIC);
     else if (rName == "office:styles")
-        return new XMLStylesContext(mrImport, /*bAutomatic=*/false);
+        return new XMLStylesContext(mrImport, XMLStylesContext::StyleType_NONE);
     else if (rName == "office:font-face-decls")
         return new XMLFontFaceDeclsContext(mrImport);
+    else if (rName == "office:master-styles")
+        return new XMLStylesContext(mrImport, XMLStylesContext::StyleType_MASTER);
     return nullptr;
 }
 
@@ -339,6 +341,16 @@ bool XMLImport::FillPopupData(const OUString &rURL, librevenge::RVNGPropertyList
     return false;
 }
 
+void XMLImport::SetPageSpanOpened(bool bPageSpanOpened)
+{
+    mbPageSpanOpened = bPageSpanOpened;
+}
+
+bool XMLImport::IsPageSpanOpened() const
+{
+    return mbPageSpanOpened;
+}
+
 rtl::Reference<XMLImportContext> XMLImport::CreateContext(const OUString &rName, const css::uno::Reference<css::xml::sax::XAttributeList> &/*xAttribs*/)
 {
     if (rName == "office:document")
@@ -421,6 +433,16 @@ std::map<OUString, librevenge::RVNGPropertyList> &XMLImport::GetGraphicStyles()
     return maGraphicStyles;
 }
 
+std::map<OUString, librevenge::RVNGPropertyList> &XMLImport::GetPageLayouts()
+{
+    return maPageLayouts;
+}
+
+std::map<OUString, librevenge::RVNGPropertyList> &XMLImport::GetMasterPages()
+{
+    return maMasterPages;
+}
+
 void XMLImport::startDocument()
 {
     mrGenerator.startDocument(librevenge::RVNGPropertyList());
@@ -428,6 +450,11 @@ void XMLImport::startDocument()
 
 void XMLImport::endDocument()
 {
+    if (mbPageSpanOpened)
+    {
+        mrGenerator.closePageSpan();
+        mbPageSpanOpened = false;
+    }
     mrGenerator.endDocument();
 }
 
diff --git a/writerperfect/source/writer/exp/xmlimp.hxx b/writerperfect/source/writer/exp/xmlimp.hxx
index de9fa58d7e1f..aeec06bde727 100644
--- a/writerperfect/source/writer/exp/xmlimp.hxx
+++ b/writerperfect/source/writer/exp/xmlimp.hxx
@@ -52,12 +52,15 @@ class XMLImport : public cppu::WeakImplHelper
     std::map<OUString, librevenge::RVNGPropertyList> maTableStyles;
     std::map<OUString, librevenge::RVNGPropertyList> maAutomaticGraphicStyles;
     std::map<OUString, librevenge::RVNGPropertyList> maGraphicStyles;
+    std::map<OUString, librevenge::RVNGPropertyList> maPageLayouts;
+    std::map<OUString, librevenge::RVNGPropertyList> maMasterPages;
     librevenge::RVNGPropertyListVector maCoverImages;
     /// Author, date, etc -- overwrites what would be from the document out of the box.
     librevenge::RVNGPropertyList maMetaData;
     const css::uno::Reference<css::uno::XComponentContext> &mxContext;
     css::uno::Reference<css::uri::XUriReferenceFactory> mxUriReferenceFactory;
     OUString maMediaDir;
+    bool mbPageSpanOpened = false;
 
 public:
     XMLImport(const css::uno::Reference<css::uno::XComponentContext> &xContext, librevenge::RVNGTextInterface &rGenerator, const OUString &rURL, const css::uno::Sequence<css::beans::PropertyValue> &rDescriptor);
@@ -79,9 +82,13 @@ public:
     std::map<OUString, librevenge::RVNGPropertyList> &GetRowStyles();
     std::map<OUString, librevenge::RVNGPropertyList> &GetTableStyles();
     std::map<OUString, librevenge::RVNGPropertyList> &GetGraphicStyles();
+    std::map<OUString, librevenge::RVNGPropertyList> &GetPageLayouts();
+    std::map<OUString, librevenge::RVNGPropertyList> &GetMasterPages();
     const librevenge::RVNGPropertyListVector &GetCoverImages();
     const librevenge::RVNGPropertyList &GetMetaData();
     bool FillPopupData(const OUString &rURL, librevenge::RVNGPropertyList &rPropList);
+    void SetPageSpanOpened(bool bPageSpanOpened);
+    bool IsPageSpanOpened() const;
 
     // XDocumentHandler
     void SAL_CALL startDocument() override;


More information about the Libreoffice-commits mailing list