diff options
-rw-r--r-- | xmloff/qa/unit/data/theme.odp | bin | 0 -> 13253 bytes | |||
-rw-r--r-- | xmloff/qa/unit/draw.cxx | 24 | ||||
-rw-r--r-- | xmloff/source/draw/ximpstyl.cxx | 146 |
3 files changed, 170 insertions, 0 deletions
diff --git a/xmloff/qa/unit/data/theme.odp b/xmloff/qa/unit/data/theme.odp Binary files differnew file mode 100644 index 000000000000..da8d189753f0 --- /dev/null +++ b/xmloff/qa/unit/data/theme.odp diff --git a/xmloff/qa/unit/draw.cxx b/xmloff/qa/unit/draw.cxx index 5d3854844ce9..cd991e691d7c 100644 --- a/xmloff/qa/unit/draw.cxx +++ b/xmloff/qa/unit/draw.cxx @@ -153,6 +153,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( |