xmloff/qa/unit/data/theme.odp   |binary
 xmloff/qa/unit/draw.cxx         |   24 ++++++
 xmloff/source/draw/ximpstyl.cxx |  146 ++++++++++++++++++++++++++++++++++++++++
 3 files changed, 170 insertions(+)

New commits:
commit 3d210f998928cb00e6989d9c2ad64ef1fa699175
Author:     Miklos Vajna <vmik...@collabora.com>
AuthorDate: Wed Dec 8 08:42:18 2021 +0100
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Tue Jun 28 08:24:38 2022 +0200

    ODP import: handle theme of master pages
    
    This is just the theme itself, we don't refer to this theme from e.g.
    shape text color yet.
    
    (cherry picked from commit 26c8e266e1ae267fd15878057a92340078136140)
    
    Change-Id: I0d8f4b06217fb491e47d775628fde742d8ff104d
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/136496
    Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com>
    Reviewed-by: Miklos Vajna <vmik...@collabora.com>

diff --git a/xmloff/qa/unit/data/theme.odp b/xmloff/qa/unit/data/theme.odp
new file mode 100644
index 000000000000..da8d189753f0
Binary files /dev/null and b/xmloff/qa/unit/data/theme.odp differ
diff --git a/xmloff/qa/unit/draw.cxx b/xmloff/qa/unit/draw.cxx
index fd32c59d90b8..f3bab2a69996 100644
--- a/xmloff/qa/unit/draw.cxx
+++ b/xmloff/qa/unit/draw.cxx
@@ -155,6 +155,30 @@ CPPUNIT_TEST_FIXTURE(XmloffDrawTest, testThemeExport)
     assertXPath(pXmlDoc, 
"//style:master-page/loext:theme/loext:color-table/loext:color", 12);
 }
 
+CPPUNIT_TEST_FIXTURE(XmloffDrawTest, testThemeImport)
+{
+    // Given a document that has a master page with a theme associated:
+    OUString aURL = m_directories.getURLFromSrc(DATA_DIRECTORY) + "theme.odp";
+
+    // When loading that document:
+    getComponent() = loadFromDesktop(aURL);
+
+    // Then make sure the doc model has a master page with a theme:
+    uno::Reference<drawing::XDrawPagesSupplier> 
xDrawPagesSupplier(getComponent(), uno::UNO_QUERY);
+    uno::Reference<drawing::XMasterPageTarget> xDrawPage(
+        xDrawPagesSupplier->getDrawPages()->getByIndex(0), uno::UNO_QUERY);
+    uno::Reference<beans::XPropertySet> 
xMasterpage(xDrawPage->getMasterPage(), uno::UNO_QUERY);
+    comphelper::SequenceAsHashMap aMap(xMasterpage->getPropertyValue("Theme"));
+    // Without the accompanying fix in place, this test would have failed with:
+    // Cannot extract an Any(void) to string!
+    // i.e. the master page had no theme.
+    CPPUNIT_ASSERT_EQUAL(OUString("Office Theme"), 
aMap["Name"].get<OUString>());
+    CPPUNIT_ASSERT_EQUAL(OUString("Office"), 
aMap["ColorSchemeName"].get<OUString>());
+    auto aColorScheme = aMap["ColorScheme"].get<uno::Sequence<util::Color>>();
+    CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(12), aColorScheme.getLength());
+    CPPUNIT_ASSERT_EQUAL(static_cast<util::Color>(0x954F72), aColorScheme[11]);
+}
+
 CPPUNIT_PLUGIN_IMPLEMENT();
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/xmloff/source/draw/ximpstyl.cxx b/xmloff/source/draw/ximpstyl.cxx
index 4f3805e39ddd..e6d41e3cf003 100644
--- a/xmloff/source/draw/ximpstyl.cxx
+++ b/xmloff/source/draw/ximpstyl.cxx
@@ -40,6 +40,7 @@
 #include <com/sun/star/beans/XPropertySet.hpp>
 #include <com/sun/star/beans/XPropertyState.hpp>
 #include <com/sun/star/presentation/XHandoutMasterSupplier.hpp>
+#include <com/sun/star/util/Color.hpp>
 #include <comphelper/namecontainer.hxx>
 #include <xmloff/autolayout.hxx>
 #include <xmloff/xmlprcon.hxx>
@@ -53,6 +54,9 @@
 #include <unotools/configmgr.hxx>
 #include <xmloff/xmlerror.hxx>
 #include <xmloff/table/XMLTableImport.hxx>
+#include <comphelper/sequenceashashmap.hxx>
+#include <sax/tools/converter.hxx>
+#include <comphelper/sequence.hxx>
 
 using namespace ::com::sun::star;
 using namespace ::com::sun::star::uno;
@@ -78,6 +82,46 @@ public:
         const XMLPropertyState& rProp ) override;
 };
 
+/// Imports <loext:theme>.
+class XMLThemeContext : public SvXMLImportContext
+{
+    uno::Reference<beans::XPropertySet> m_xMasterPage;
+    comphelper::SequenceAsHashMap m_aTheme;
+
+public:
+    XMLThemeContext(SvXMLImport& rImport,
+                    const uno::Reference<xml::sax::XFastAttributeList>& 
xAttrList,
+                    const uno::Reference<beans::XPropertySet>& xMasterPage);
+    ~XMLThemeContext();
+
+    uno::Reference<xml::sax::XFastContextHandler> SAL_CALL 
createFastChildContext(
+        sal_Int32 nElement, const 
uno::Reference<xml::sax::XFastAttributeList>& xAttribs) override;
+};
+
+/// Imports <loext:color-table> inside <loext:theme>.
+class XMLColorTableContext : public SvXMLImportContext
+{
+    comphelper::SequenceAsHashMap& m_rTheme;
+    std::vector<util::Color> m_aColorScheme;
+
+public:
+    XMLColorTableContext(SvXMLImport& rImport,
+                         const uno::Reference<xml::sax::XFastAttributeList>& 
xAttrList,
+                         comphelper::SequenceAsHashMap& rTheme);
+    ~XMLColorTableContext();
+
+    uno::Reference<xml::sax::XFastContextHandler> SAL_CALL 
createFastChildContext(
+        sal_Int32 nElement, const 
uno::Reference<xml::sax::XFastAttributeList>& xAttribs) override;
+};
+
+/// Imports <loext:color> inside <loext:color-table>.
+class XMLColorContext : public SvXMLImportContext
+{
+public:
+    XMLColorContext(SvXMLImport& rImport,
+                    const uno::Reference<xml::sax::XFastAttributeList>& 
xAttrList,
+                    std::vector<util::Color>& rColorScheme);
+};
 }
 
 SdXMLDrawingPagePropertySetContext::SdXMLDrawingPagePropertySetContext(
@@ -827,6 +871,17 @@ css::uno::Reference< css::xml::sax::XFastContextHandler > 
SdXMLMasterPageContext
                     }
                 }
             }
+            break;
+        }
+        case XML_ELEMENT(LO_EXT, XML_THEME):
+        {
+            if (GetSdImport().IsImpress())
+            {
+                uno::Reference<beans::XPropertySet> 
xMasterPage(GetLocalShapesContext(),
+                                                                
uno::UNO_QUERY);
+                return new XMLThemeContext(GetSdImport(), xAttrList, 
xMasterPage);
+            }
+            break;
         }
     }
     return SdXMLGenericPageContext::createFastChildContext(nElement, 
xAttrList);
@@ -1431,6 +1486,97 @@ void SdXMLHeaderFooterDeclContext::characters( const 
OUString& rChars )
     maStrText += rChars;
 }
 
+XMLThemeContext::XMLThemeContext(SvXMLImport& rImport,
+                                 const 
uno::Reference<xml::sax::XFastAttributeList>& xAttrList,
+                                 const uno::Reference<beans::XPropertySet>& 
xMasterPage)
+    : SvXMLImportContext(rImport)
+    , m_xMasterPage(xMasterPage)
+{
+    for (const auto& rAttribute : 
sax_fastparser::castToFastAttributeList(xAttrList))
+    {
+        switch (rAttribute.getToken())
+        {
+            case XML_ELEMENT(LO_EXT, XML_NAME):
+            {
+                m_aTheme["Name"] <<= rAttribute.toString();
+                break;
+            }
+        }
+    }
+}
+
+XMLThemeContext::~XMLThemeContext()
+{
+    uno::Any aTheme = uno::makeAny(m_aTheme.getAsConstPropertyValueList());
+    m_xMasterPage->setPropertyValue("Theme", aTheme);
+}
+
+uno::Reference<xml::sax::XFastContextHandler> SAL_CALL 
XMLThemeContext::createFastChildContext(
+    sal_Int32 nElement, const uno::Reference<xml::sax::XFastAttributeList>& 
xAttribs)
+{
+    if (nElement == XML_ELEMENT(LO_EXT, XML_COLOR_TABLE))
+    {
+        return new XMLColorTableContext(GetImport(), xAttribs, m_aTheme);
+    }
+
+    return nullptr;
+}
+
+XMLColorTableContext::XMLColorTableContext(
+    SvXMLImport& rImport, const uno::Reference<xml::sax::XFastAttributeList>& 
xAttrList,
+    comphelper::SequenceAsHashMap& rTheme)
+    : SvXMLImportContext(rImport)
+    , m_rTheme(rTheme)
+{
+    for (const auto& rAttribute : 
sax_fastparser::castToFastAttributeList(xAttrList))
+    {
+        switch (rAttribute.getToken())
+        {
+            case XML_ELEMENT(LO_EXT, XML_NAME):
+            {
+                m_rTheme["ColorSchemeName"] <<= rAttribute.toString();
+                break;
+            }
+        }
+    }
+}
+
+XMLColorTableContext::~XMLColorTableContext()
+{
+    m_rTheme["ColorScheme"] <<= 
comphelper::containerToSequence(m_aColorScheme);
+}
+
+uno::Reference<xml::sax::XFastContextHandler> SAL_CALL 
XMLColorTableContext::createFastChildContext(
+    sal_Int32 nElement, const uno::Reference<xml::sax::XFastAttributeList>& 
xAttribs)
+{
+    if (nElement == XML_ELEMENT(LO_EXT, XML_COLOR))
+    {
+        return new XMLColorContext(GetImport(), xAttribs, m_aColorScheme);
+    }
+
+    return nullptr;
+}
+
+XMLColorContext::XMLColorContext(SvXMLImport& rImport,
+                                 const 
uno::Reference<xml::sax::XFastAttributeList>& xAttrList,
+                                 std::vector<util::Color>& rColorScheme)
+    : SvXMLImportContext(rImport)
+{
+    for (const auto& rAttribute : 
sax_fastparser::castToFastAttributeList(xAttrList))
+    {
+        switch (rAttribute.getToken())
+        {
+            case XML_ELEMENT(LO_EXT, XML_COLOR):
+            {
+                util::Color nColor;
+                sax::Converter::convertColor(nColor, rAttribute.toView());
+                rColorScheme.push_back(nColor);
+                break;
+            }
+        }
+    }
+}
+
 namespace xmloff {
 
 bool IsIgnoreFillStyleNamedItem(

Reply via email to