diff options
Diffstat (limited to 'xmloff')
-rw-r--r-- | xmloff/qa/unit/draw.cxx | 52 | ||||
-rw-r--r-- | xmloff/source/core/xmltoken.cxx | 2 | ||||
-rw-r--r-- | xmloff/source/draw/sdxmlexp.cxx | 85 | ||||
-rw-r--r-- | xmloff/source/draw/sdxmlexp_impl.hxx | 1 | ||||
-rw-r--r-- | xmloff/source/token/tokens.txt | 1 |
5 files changed, 136 insertions, 5 deletions
diff --git a/xmloff/qa/unit/draw.cxx b/xmloff/qa/unit/draw.cxx index 3b0cda0f0383..5d3854844ce9 100644 --- a/xmloff/qa/unit/draw.cxx +++ b/xmloff/qa/unit/draw.cxx @@ -16,6 +16,9 @@ #include <com/sun/star/frame/Desktop.hpp> #include <com/sun/star/frame/XStorable.hpp> #include <com/sun/star/packages/zip/ZipFileAccess.hpp> +#include <com/sun/star/drawing/XDrawPagesSupplier.hpp> +#include <com/sun/star/drawing/XMasterPageTarget.hpp> +#include <com/sun/star/util/Color.hpp> #include <unotools/mediadescriptor.hxx> #include <unotools/tempfile.hxx> @@ -38,6 +41,7 @@ public: void tearDown() override; void registerNamespaces(xmlXPathContextPtr& pXmlXpathCtx) override; uno::Reference<lang::XComponent>& getComponent() { return mxComponent; } + void save(const OUString& rFilterName, utl::TempFile& rTempFile); }; void XmloffDrawTest::setUp() @@ -60,6 +64,16 @@ void XmloffDrawTest::registerNamespaces(xmlXPathContextPtr& pXmlXpathCtx) XmlTestTools::registerODFNamespaces(pXmlXpathCtx); } +void XmloffDrawTest::save(const OUString& rFilterName, utl::TempFile& rTempFile) +{ + uno::Reference<frame::XStorable> xStorable(mxComponent, uno::UNO_QUERY); + utl::MediaDescriptor aMediaDescriptor; + aMediaDescriptor["FilterName"] <<= rFilterName; + rTempFile.EnableKillingFile(); + xStorable->storeToURL(rTempFile.GetURL(), aMediaDescriptor.getAsConstPropertyValueList()); + validate(rTempFile.GetFileName(), test::ODF); +} + CPPUNIT_TEST_FIXTURE(XmloffDrawTest, testTextBoxLoss) { // Load a document that has a shape with a textbox in it. Save it to ODF and reload. @@ -93,12 +107,8 @@ CPPUNIT_TEST_FIXTURE(XmloffDrawTest, testTdf141301_Extrusion_Angle) getComponent() = loadFromDesktop(aURL, "com.sun.star.comp.drawing.DrawingDocument"); // Prepare use of XPath - uno::Reference<frame::XStorable> xStorable(getComponent(), uno::UNO_QUERY); utl::TempFile aTempFile; - aTempFile.EnableKillingFile(); - utl::MediaDescriptor aMediaDescriptor; - aMediaDescriptor["FilterName"] <<= OUString("draw8"); - xStorable->storeAsURL(aTempFile.GetURL(), aMediaDescriptor.getAsConstPropertyValueList()); + save("draw8", aTempFile); uno::Reference<packages::zip::XZipFileAccess2> xNameAccess = packages::zip::ZipFileAccess::createWithURL(mxComponentContext, aTempFile.GetURL()); uno::Reference<io::XInputStream> xInputStream(xNameAccess->getByName("content.xml"), @@ -111,6 +121,38 @@ CPPUNIT_TEST_FIXTURE(XmloffDrawTest, testTdf141301_Extrusion_Angle) assertXPath(pXmlDoc, "//draw:enhanced-geometry", "extrusion-skew", "50 -135"); } +CPPUNIT_TEST_FIXTURE(XmloffDrawTest, testThemeExport) +{ + // Create an Impress document which has a master page which has a theme associated with it. + getComponent() = loadFromDesktop("private:factory/simpress"); + 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; + aMap["Name"] <<= OUString("mytheme"); + aMap["ColorSchemeName"] <<= OUString("mycolorscheme"); + uno::Sequence<util::Color> aColorScheme + = { 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb }; + aMap["ColorScheme"] <<= aColorScheme; + uno::Any aTheme = uno::makeAny(aMap.getAsConstPropertyValueList()); + xMasterPage->setPropertyValue("Theme", aTheme); + + // Export to ODP: + utl::TempFile aTempFile; + save("impress8", aTempFile); + + // Check if the 12 colors are written in the XML: + std::unique_ptr<SvStream> pStream = parseExportStream(aTempFile, "styles.xml"); + xmlDocUniquePtr pXmlDoc = parseXmlStream(pStream.get()); + // Without the accompanying fix in place, this test would have failed with: + // - Expected: 12 + // - Actual : 0 + // - XPath '//style:master-page/loext:theme/loext:color-table/loext:color' number of nodes is incorrect + // i.e. the theme was lost on exporting to ODF. + assertXPath(pXmlDoc, "//style:master-page/loext:theme/loext:color-table/loext:color", 12); +} + CPPUNIT_PLUGIN_IMPLEMENT(); /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/xmloff/source/core/xmltoken.cxx b/xmloff/source/core/xmltoken.cxx index 704f374a5026..caf15a395e03 100644 --- a/xmloff/source/core/xmltoken.cxx +++ b/xmloff/source/core/xmltoken.cxx @@ -3443,6 +3443,8 @@ namespace xmloff::token { TOKEN("linked-style-name", XML_LINKED_STYLE_NAME ), + TOKEN("theme", XML_THEME ), + #if OSL_DEBUG_LEVEL > 0 { 0, nullptr, std::nullopt, XML_TOKEN_END } diff --git a/xmloff/source/draw/sdxmlexp.cxx b/xmloff/source/draw/sdxmlexp.cxx index d02a5731ad25..9388cedb25e4 100644 --- a/xmloff/source/draw/sdxmlexp.cxx +++ b/xmloff/source/draw/sdxmlexp.cxx @@ -72,6 +72,9 @@ #include <com/sun/star/document/XDocumentProperties.hpp> #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp> +#include <com/sun/star/util/Color.hpp> + +#include <comphelper/sequenceashashmap.hxx> using namespace ::com::sun::star; using namespace ::com::sun::star::uno; @@ -2299,6 +2302,12 @@ void SdXMLExport::ExportMasterStyles_() // write optional office:forms exportFormsElement( xMasterPage ); + // write optional loext:theme + if (IsImpress()) + { + ExportThemeElement(xMasterPage); + } + // write graphic objects on this master page (if any) if(xMasterPage.is() && xMasterPage->getCount()) GetShapeExport()->exportShapes( xMasterPage ); @@ -2354,6 +2363,82 @@ void SdXMLExport::exportFormsElement( const Reference< XDrawPage >& xDrawPage ) } } +void SdXMLExport::ExportThemeElement(const uno::Reference<drawing::XDrawPage>& xDrawPage) +{ + uno::Reference<beans::XPropertySet> xPropertySet(xDrawPage, uno::UNO_QUERY); + if (!xPropertySet.is()) + return; + + comphelper::SequenceAsHashMap aMap(xPropertySet->getPropertyValue("Theme")); + if (aMap.empty()) + { + return; + } + + if ((getSaneDefaultVersion() & SvtSaveOptions::ODFSVER_EXTENDED) == 0) + { + // Do not export in standard ODF 1.3 or older. + return; + } + + auto it = aMap.find("Name"); + if (it != aMap.end()) + { + OUString aName; + it->second >>= aName; + AddAttribute(XML_NAMESPACE_LO_EXT, XML_NAME, aName); + } + SvXMLElementExport aTheme(*this, XML_NAMESPACE_LO_EXT, XML_THEME, true, true); + + uno::Sequence<util::Color> aColors; + it = aMap.find("ColorScheme"); + if (it != aMap.end()) + { + it->second >>= aColors; + } + if (!aColors.hasElements()) + { + return; + } + + it = aMap.find("ColorSchemeName"); + if (it != aMap.end()) + { + OUString aName; + it->second >>= aName; + AddAttribute(XML_NAMESPACE_LO_EXT, XML_NAME, aName); + } + SvXMLElementExport aColorTable(*this, XML_NAMESPACE_LO_EXT, XML_COLOR_TABLE, true, true); + + static const std::u16string_view aColorNames[] = { + u"dk1", // Background 1 + u"lt1", // Text 1 + u"dk2", // Background 2 + u"lt2", // Text 2 + u"accent1", // Accent 1 + u"accent2", // Accent 2 + u"accent3", // Accent 3 + u"accent4", // Accent 4 + u"accent5", // Accent 5 + u"accent6", // Accent 6 + u"hlink", // Hyperlink + u"folHlink", // Followed hyperlink + }; + for (size_t nColor = 0; nColor < aColors.size(); ++nColor) + { + // Import goes via svx::Theme::FromAny(), which sanitizes user input. + assert(nColor < SAL_N_ELEMENTS(aColorNames)); + + AddAttribute(XML_NAMESPACE_LO_EXT, XML_NAME, OUString(aColorNames[nColor])); + + OUStringBuffer sValue; + sax::Converter::convertColor(sValue, aColors[nColor]); + AddAttribute(XML_NAMESPACE_LO_EXT, XML_COLOR, sValue.makeStringAndClear()); + + SvXMLElementExport aColor(*this, XML_NAMESPACE_LO_EXT, XML_COLOR, true, true); + } +} + void SdXMLExport::GetViewSettings(uno::Sequence<beans::PropertyValue>& rProps) { Reference< beans::XPropertySet > xPropSet( GetModel(), UNO_QUERY ); diff --git a/xmloff/source/draw/sdxmlexp_impl.hxx b/xmloff/source/draw/sdxmlexp_impl.hxx index 799767f990b1..9808c738120e 100644 --- a/xmloff/source/draw/sdxmlexp_impl.hxx +++ b/xmloff/source/draw/sdxmlexp_impl.hxx @@ -135,6 +135,7 @@ class SdXMLExport : public SvXMLExport void ImplExportHeaderFooterDeclAttributes( const HeaderFooterPageSettingsImpl& aSettings ); void exportFormsElement( const css::uno::Reference< css::drawing::XDrawPage >& xDrawPage ); + void ExportThemeElement(const css::uno::Reference<css::drawing::XDrawPage>& xDrawPage); void exportPresentationSettings(); // #82003# helper function for recursive object count diff --git a/xmloff/source/token/tokens.txt b/xmloff/source/token/tokens.txt index 6e34ec554fab..abc66bd73034 100644 --- a/xmloff/source/token/tokens.txt +++ b/xmloff/source/token/tokens.txt @@ -3187,4 +3187,5 @@ rspace rtl symmetric linked-style-name +theme TOKEN_END_DUMMY |