summaryrefslogtreecommitdiff
path: root/xmloff
diff options
context:
space:
mode:
Diffstat (limited to 'xmloff')
-rw-r--r--xmloff/qa/unit/draw.cxx52
-rw-r--r--xmloff/source/core/xmltoken.cxx2
-rw-r--r--xmloff/source/draw/sdxmlexp.cxx85
-rw-r--r--xmloff/source/draw/sdxmlexp_impl.hxx1
-rw-r--r--xmloff/source/token/tokens.txt1
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