diff options
author | Tomaž Vajngerl <tomaz.vajngerl@collabora.co.uk> | 2022-12-31 20:59:03 +0900 |
---|---|---|
committer | Tomaž Vajngerl <quikee@gmail.com> | 2023-01-17 06:34:53 +0000 |
commit | 573b7f756505632af0df4ac9de234d16ac1d71d9 (patch) | |
tree | a179f60a958a7f93c40d9af0b8826c6954c5f7b5 /xmloff/qa/unit | |
parent | 4e8869bc504805c033df9266583ab88491dc41cb (diff) |
xmloff: use XThemeColor in ODF, change the format for themes
Change the xmloff filter to use XThemeColor and the associated
proprties (CharColorThemeReference and FillColorThemeReference).
Change the ODF format for referencing a theme color - make it an
element instead a series of attributes on the *-properties style
element.
Change-Id: I0fa7d8ebffecc02897b7fe9824d6f1776ef36380
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/144923
Tested-by: Jenkins
Reviewed-by: Tomaž Vajngerl <quikee@gmail.com>
(cherry picked from commit 3eb53d327fb5d9689b799ff991a6c53c05eff496)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/145572
Tested-by: Tomaž Vajngerl <quikee@gmail.com>
Diffstat (limited to 'xmloff/qa/unit')
-rw-r--r-- | xmloff/qa/unit/data/Reference-ThemeColors-TextAndFill.pptx | bin | 0 -> 34341 bytes | |||
-rw-r--r-- | xmloff/qa/unit/data/ReferenceShapeFill.pptx | bin | 0 -> 14310 bytes | |||
-rw-r--r-- | xmloff/qa/unit/data/refer-to-theme.odp | bin | 20677 -> 0 bytes | |||
-rw-r--r-- | xmloff/qa/unit/draw.cxx | 295 |
4 files changed, 239 insertions, 56 deletions
diff --git a/xmloff/qa/unit/data/Reference-ThemeColors-TextAndFill.pptx b/xmloff/qa/unit/data/Reference-ThemeColors-TextAndFill.pptx Binary files differnew file mode 100644 index 000000000000..b2319fe6ea9c --- /dev/null +++ b/xmloff/qa/unit/data/Reference-ThemeColors-TextAndFill.pptx diff --git a/xmloff/qa/unit/data/ReferenceShapeFill.pptx b/xmloff/qa/unit/data/ReferenceShapeFill.pptx Binary files differnew file mode 100644 index 000000000000..782a54d7b2c1 --- /dev/null +++ b/xmloff/qa/unit/data/ReferenceShapeFill.pptx diff --git a/xmloff/qa/unit/data/refer-to-theme.odp b/xmloff/qa/unit/data/refer-to-theme.odp Binary files differdeleted file mode 100644 index 2c413ef766f9..000000000000 --- a/xmloff/qa/unit/data/refer-to-theme.odp +++ /dev/null diff --git a/xmloff/qa/unit/draw.cxx b/xmloff/qa/unit/draw.cxx index a31c98be5a02..3f80c1770900 100644 --- a/xmloff/qa/unit/draw.cxx +++ b/xmloff/qa/unit/draw.cxx @@ -29,6 +29,7 @@ #include <svx/unopage.hxx> #include <svx/svdpage.hxx> #include <svx/svdomedia.hxx> +#include <docmodel/uno/UnoThemeColor.hxx> using namespace ::com::sun::star; @@ -48,6 +49,35 @@ public: void registerNamespaces(xmlXPathContextPtr& pXmlXpathCtx) override; uno::Reference<lang::XComponent>& getComponent() { return mxComponent; } void save(const OUString& rFilterName, utl::TempFile& rTempFile); + + uno::Reference<drawing::XShape> getShape(sal_uInt8 nShapeIndex); + + uno::Reference<beans::XPropertySet> + getShapeTextPortion(sal_uInt32 nIndex, uno::Reference<drawing::XShape> const& xShape) + { + uno::Reference<beans::XPropertySet> xPortion; + + uno::Reference<container::XEnumerationAccess> xEnumAccess(xShape, uno::UNO_QUERY); + if (!xEnumAccess->hasElements()) + return xPortion; + uno::Reference<container::XEnumeration> xEnum(xEnumAccess->createEnumeration()); + uno::Reference<text::XTextContent> xTextContent; + xEnum->nextElement() >>= xTextContent; + if (!xTextContent.is()) + return xPortion; + + uno::Reference<container::XEnumerationAccess> xParaEnumAccess(xTextContent, uno::UNO_QUERY); + uno::Reference<container::XEnumeration> xParaEnum(xParaEnumAccess->createEnumeration()); + sal_uInt32 nCurrent = 0; + xPortion = uno::Reference<beans::XPropertySet>(xParaEnum->nextElement(), uno::UNO_QUERY); + while (nIndex != nCurrent) + { + ++nCurrent; + xPortion + = uno::Reference<beans::XPropertySet>(xParaEnum->nextElement(), uno::UNO_QUERY); + } + return xPortion; + } }; void XmloffDrawTest::setUp() @@ -70,6 +100,17 @@ void XmloffDrawTest::registerNamespaces(xmlXPathContextPtr& pXmlXpathCtx) XmlTestTools::registerODFNamespaces(pXmlXpathCtx); } +uno::Reference<drawing::XShape> XmloffDrawTest::getShape(sal_uInt8 nShapeIndex) +{ + uno::Reference<drawing::XDrawPagesSupplier> xDrawPagesSupplier(mxComponent, + uno::UNO_QUERY_THROW); + uno::Reference<drawing::XDrawPages> xDrawPages(xDrawPagesSupplier->getDrawPages()); + uno::Reference<drawing::XDrawPage> xDrawPage(xDrawPages->getByIndex(0), uno::UNO_QUERY_THROW); + uno::Reference<drawing::XShape> xShape(xDrawPage->getByIndex(nShapeIndex), + uno::UNO_QUERY_THROW); + return xShape; +} + void XmloffDrawTest::save(const OUString& rFilterName, utl::TempFile& rTempFile) { uno::Reference<frame::XStorable> xStorable(mxComponent, uno::UNO_QUERY); @@ -229,70 +270,212 @@ CPPUNIT_TEST_FIXTURE(XmloffDrawTest, testThemeImport) CPPUNIT_ASSERT_EQUAL(static_cast<util::Color>(0x954F72), aColorScheme[11]); } -CPPUNIT_TEST_FIXTURE(XmloffDrawTest, testReferToTheme) +CPPUNIT_TEST_FIXTURE(XmloffDrawTest, testThemeColorExportImport) { // Given a document that refers to a theme color: - OUString aURL = m_directories.getURLFromSrc(DATA_DIRECTORY) + "refer-to-theme.odp"; - - // When loading and saving that document: + OUString aURL + = m_directories.getURLFromSrc(DATA_DIRECTORY) + "Reference-ThemeColors-TextAndFill.pptx"; getComponent() = loadFromDesktop(aURL); utl::TempFile aTempFile; save("impress8", aTempFile); // Make sure the export result has the theme reference: - std::unique_ptr<SvStream> pStream = parseExportStream(aTempFile, "content.xml"); - xmlDocUniquePtr pXmlDoc = parseXmlStream(pStream.get()); - // Without the accompanying fix in place, this test would have failed with: - // - XPath '//style:style[@style:name='T1']/style:text-properties' no attribute 'theme-color' exist - // i.e. only the direct color was written, but not the theme reference. - assertXPath(pXmlDoc, "//style:style[@style:name='T1']/style:text-properties", "theme-color", - "accent1"); - assertXPathNoAttribute(pXmlDoc, "//style:style[@style:name='T1']/style:text-properties", - "color-lum-mod"); - assertXPathNoAttribute(pXmlDoc, "//style:style[@style:name='T1']/style:text-properties", - "color-lum-off"); - - assertXPath(pXmlDoc, "//style:style[@style:name='T2']/style:text-properties", "theme-color", - "accent1"); - // Without the accompanying fix in place, this test would have failed with: - // - XPath '//style:style[@style:name='T2']/style:text-properties' no attribute 'color-lum-mod' exist - // i.e. effects on a referenced theme color were lost. - assertXPath(pXmlDoc, "//style:style[@style:name='T2']/style:text-properties", "color-lum-mod", - "40%"); - assertXPath(pXmlDoc, "//style:style[@style:name='T2']/style:text-properties", "color-lum-off", - "60%"); - - assertXPath(pXmlDoc, "//style:style[@style:name='T3']/style:text-properties", "theme-color", - "accent1"); - assertXPath(pXmlDoc, "//style:style[@style:name='T3']/style:text-properties", "color-lum-mod", - "75%"); - assertXPathNoAttribute(pXmlDoc, "//style:style[@style:name='T3']/style:text-properties", - "color-lum-off"); + { + std::unique_ptr<SvStream> pStream = parseExportStream(aTempFile, "content.xml"); + xmlDocUniquePtr pXmlDoc = parseXmlStream(pStream.get()); + + // Text color + OString aStyle1("//style:style[@style:name='T2']/style:text-properties/" + "loext:char-color-theme-reference"); + assertXPath(pXmlDoc, aStyle1, "type", "accent3"); + assertXPath(pXmlDoc, aStyle1 + "/loext:transformation[1]", "type", "lummod"); + assertXPath(pXmlDoc, aStyle1 + "/loext:transformation[1]", "value", "2000"); + assertXPath(pXmlDoc, aStyle1 + "/loext:transformation[2]", "type", "lumoff"); + assertXPath(pXmlDoc, aStyle1 + "/loext:transformation[2]", "value", "8000"); + + OString aStyle2("//style:style[@style:name='T3']/style:text-properties/" + "loext:char-color-theme-reference"); + assertXPath(pXmlDoc, aStyle2, "type", "accent3"); + assertXPath(pXmlDoc, aStyle2 + "/loext:transformation[1]", "type", "lummod"); + assertXPath(pXmlDoc, aStyle2 + "/loext:transformation[1]", "value", "6000"); + assertXPath(pXmlDoc, aStyle2 + "/loext:transformation[2]", "type", "lumoff"); + assertXPath(pXmlDoc, aStyle2 + "/loext:transformation[2]", "value", "4000"); + + OString aStyle3("//style:style[@style:name='T4']/style:text-properties/" + "loext:char-color-theme-reference"); + assertXPath(pXmlDoc, aStyle3, "type", "accent3"); + assertXPath(pXmlDoc, aStyle3 + "/loext:transformation[1]", "type", "lummod"); + assertXPath(pXmlDoc, aStyle3 + "/loext:transformation[1]", "value", "5000"); + + // Shapes fill color + OString aShape1("//style:style[@style:name='gr1']/style:graphic-properties/" + "loext:fill-color-theme-reference"); + assertXPath(pXmlDoc, aShape1, "type", "accent2"); + assertXPath(pXmlDoc, aShape1 + "/loext:transformation[1]", "type", "lummod"); + assertXPath(pXmlDoc, aShape1 + "/loext:transformation[1]", "value", "2000"); + assertXPath(pXmlDoc, aShape1 + "/loext:transformation[2]", "type", "lumoff"); + assertXPath(pXmlDoc, aShape1 + "/loext:transformation[2]", "value", "8000"); + + OString aShape2("//style:style[@style:name='gr2']/style:graphic-properties/" + "loext:fill-color-theme-reference"); + assertXPath(pXmlDoc, aShape2, "type", "accent2"); + assertXPath(pXmlDoc, aShape2 + "/loext:transformation[1]", "type", "lummod"); + assertXPath(pXmlDoc, aShape2 + "/loext:transformation[1]", "value", "6000"); + assertXPath(pXmlDoc, aShape2 + "/loext:transformation[2]", "type", "lumoff"); + assertXPath(pXmlDoc, aShape2 + "/loext:transformation[2]", "value", "4000"); + + OString aShape3("//style:style[@style:name='gr3']/style:graphic-properties/" + "loext:fill-color-theme-reference"); + assertXPath(pXmlDoc, aShape3, "type", "accent2"); + assertXPath(pXmlDoc, aShape3 + "/loext:transformation[1]", "type", "lummod"); + assertXPath(pXmlDoc, aShape3 + "/loext:transformation[1]", "value", "5000"); + } + + // reload + getComponent()->dispose(); + getComponent() = loadFromDesktop(aURL); - // Without the accompanying fix in place, this test would have failed with: - // - XPath '//style:style[@style:name='gr2']/style:graphic-properties' no attribute 'fill-theme-color' exist - // i.e. only the direct color was written, but not the theme reference. - assertXPath(pXmlDoc, "//style:style[@style:name='gr2']/style:graphic-properties", - "fill-theme-color", "accent1"); - - // Shape fill, 60% lighter. - assertXPath(pXmlDoc, "//style:style[@style:name='gr3']/style:graphic-properties", - "fill-theme-color", "accent1"); - // Without the accompanying fix in place, this test would have failed with: - // - XPath '//style:style[@style:name='gr3']/style:graphic-properties' no attribute 'fill-color-lum-mod' exist - // i.e. the themed color was fine, but its effects were lost. - assertXPath(pXmlDoc, "//style:style[@style:name='gr3']/style:graphic-properties", - "fill-color-lum-mod", "40%"); - assertXPath(pXmlDoc, "//style:style[@style:name='gr3']/style:graphic-properties", - "fill-color-lum-off", "60%"); - - // Shape fill, 25% darker. - assertXPath(pXmlDoc, "//style:style[@style:name='gr4']/style:graphic-properties", - "fill-theme-color", "accent1"); - assertXPath(pXmlDoc, "//style:style[@style:name='gr4']/style:graphic-properties", - "fill-color-lum-mod", "75%"); - assertXPathNoAttribute(pXmlDoc, "//style:style[@style:name='gr4']/style:graphic-properties", - "fill-color-lum-off"); + // check fill color theme + { + uno::Reference<drawing::XShape> xShape(getShape(0)); + CPPUNIT_ASSERT(xShape.is()); + uno::Reference<beans::XPropertySet> xShapeProperties(xShape, uno::UNO_QUERY); + uno::Reference<util::XThemeColor> xThemeColor; + xShapeProperties->getPropertyValue("FillColorThemeReference") >>= xThemeColor; + CPPUNIT_ASSERT(xThemeColor.is()); + model::ThemeColor aThemeColor; + model::theme::setFromXThemeColor(aThemeColor, xThemeColor); + CPPUNIT_ASSERT_EQUAL(model::ThemeColorType::Accent2, aThemeColor.getType()); + CPPUNIT_ASSERT_EQUAL(size_t(2), aThemeColor.getTransformations().size()); + auto const& rTrans1 = aThemeColor.getTransformations()[0]; + CPPUNIT_ASSERT_EQUAL(model::TransformationType::LumMod, rTrans1.meType); + CPPUNIT_ASSERT_EQUAL(sal_Int16(2000), rTrans1.mnValue); + auto const& rTrans2 = aThemeColor.getTransformations()[1]; + CPPUNIT_ASSERT_EQUAL(model::TransformationType::LumOff, rTrans2.meType); + CPPUNIT_ASSERT_EQUAL(sal_Int16(8000), rTrans2.mnValue); + } + { + uno::Reference<drawing::XShape> xShape(getShape(1)); + CPPUNIT_ASSERT(xShape.is()); + uno::Reference<beans::XPropertySet> xShapeProperties(xShape, uno::UNO_QUERY); + uno::Reference<util::XThemeColor> xThemeColor; + xShapeProperties->getPropertyValue("FillColorThemeReference") >>= xThemeColor; + CPPUNIT_ASSERT(xThemeColor.is()); + model::ThemeColor aThemeColor; + model::theme::setFromXThemeColor(aThemeColor, xThemeColor); + CPPUNIT_ASSERT_EQUAL(model::ThemeColorType::Accent2, aThemeColor.getType()); + CPPUNIT_ASSERT_EQUAL(size_t(2), aThemeColor.getTransformations().size()); + auto const& rTrans1 = aThemeColor.getTransformations()[0]; + CPPUNIT_ASSERT_EQUAL(model::TransformationType::LumMod, rTrans1.meType); + CPPUNIT_ASSERT_EQUAL(sal_Int16(6000), rTrans1.mnValue); + auto const& rTrans2 = aThemeColor.getTransformations()[1]; + CPPUNIT_ASSERT_EQUAL(model::TransformationType::LumOff, rTrans2.meType); + CPPUNIT_ASSERT_EQUAL(sal_Int16(4000), rTrans2.mnValue); + } + { + uno::Reference<drawing::XShape> xShape(getShape(2)); + CPPUNIT_ASSERT(xShape.is()); + uno::Reference<beans::XPropertySet> xShapeProperties(xShape, uno::UNO_QUERY); + uno::Reference<util::XThemeColor> xThemeColor; + xShapeProperties->getPropertyValue("FillColorThemeReference") >>= xThemeColor; + CPPUNIT_ASSERT(xThemeColor.is()); + model::ThemeColor aThemeColor; + model::theme::setFromXThemeColor(aThemeColor, xThemeColor); + CPPUNIT_ASSERT_EQUAL(model::ThemeColorType::Accent2, aThemeColor.getType()); + CPPUNIT_ASSERT_EQUAL(size_t(1), aThemeColor.getTransformations().size()); + auto const& rTrans1 = aThemeColor.getTransformations()[0]; + CPPUNIT_ASSERT_EQUAL(model::TransformationType::LumMod, rTrans1.meType); + CPPUNIT_ASSERT_EQUAL(sal_Int16(5000), rTrans1.mnValue); + } + + // Char color theme + // Shape 4 + { + // Check the first text portion properties + uno::Reference<drawing::XShape> xShape(getShape(3)); + CPPUNIT_ASSERT(xShape.is()); + uno::Reference<beans::XPropertySet> xPortion = getShapeTextPortion(0, xShape); + CPPUNIT_ASSERT(xPortion.is()); + uno::Reference<util::XThemeColor> xThemeColor; + xPortion->getPropertyValue("CharColorThemeReference") >>= xThemeColor; + CPPUNIT_ASSERT(xThemeColor.is()); + model::ThemeColor aThemeColor; + model::theme::setFromXThemeColor(aThemeColor, xThemeColor); + CPPUNIT_ASSERT_EQUAL(model::ThemeColorType::Accent3, aThemeColor.getType()); + CPPUNIT_ASSERT_EQUAL(size_t(2), aThemeColor.getTransformations().size()); + auto const& rTrans1 = aThemeColor.getTransformations()[0]; + CPPUNIT_ASSERT_EQUAL(model::TransformationType::LumMod, rTrans1.meType); + CPPUNIT_ASSERT_EQUAL(sal_Int16(2000), rTrans1.mnValue); + auto const& rTrans2 = aThemeColor.getTransformations()[1]; + CPPUNIT_ASSERT_EQUAL(model::TransformationType::LumOff, rTrans2.meType); + CPPUNIT_ASSERT_EQUAL(sal_Int16(8000), rTrans2.mnValue); + } + // Shape 5 + { + // Check the first text portion properties + uno::Reference<drawing::XShape> xShape(getShape(4)); + CPPUNIT_ASSERT(xShape.is()); + uno::Reference<beans::XPropertySet> xPortion = getShapeTextPortion(0, xShape); + CPPUNIT_ASSERT(xPortion.is()); + uno::Reference<util::XThemeColor> xThemeColor; + xPortion->getPropertyValue("CharColorThemeReference") >>= xThemeColor; + CPPUNIT_ASSERT(xThemeColor.is()); + model::ThemeColor aThemeColor; + model::theme::setFromXThemeColor(aThemeColor, xThemeColor); + CPPUNIT_ASSERT_EQUAL(model::ThemeColorType::Accent3, aThemeColor.getType()); + CPPUNIT_ASSERT_EQUAL(size_t(2), aThemeColor.getTransformations().size()); + auto const& rTrans1 = aThemeColor.getTransformations()[0]; + CPPUNIT_ASSERT_EQUAL(model::TransformationType::LumMod, rTrans1.meType); + CPPUNIT_ASSERT_EQUAL(sal_Int16(6000), rTrans1.mnValue); + auto const& rTrans2 = aThemeColor.getTransformations()[1]; + CPPUNIT_ASSERT_EQUAL(model::TransformationType::LumOff, rTrans2.meType); + CPPUNIT_ASSERT_EQUAL(sal_Int16(4000), rTrans2.mnValue); + } + // Shape 6 + { + // Check the first text portion properties + uno::Reference<drawing::XShape> xShape(getShape(5)); + CPPUNIT_ASSERT(xShape.is()); + uno::Reference<beans::XPropertySet> xPortion = getShapeTextPortion(0, xShape); + CPPUNIT_ASSERT(xPortion.is()); + uno::Reference<util::XThemeColor> xThemeColor; + xPortion->getPropertyValue("CharColorThemeReference") >>= xThemeColor; + CPPUNIT_ASSERT(xThemeColor.is()); + model::ThemeColor aThemeColor; + model::theme::setFromXThemeColor(aThemeColor, xThemeColor); + CPPUNIT_ASSERT_EQUAL(model::ThemeColorType::Accent3, aThemeColor.getType()); + CPPUNIT_ASSERT_EQUAL(size_t(1), aThemeColor.getTransformations().size()); + auto const& rTrans1 = aThemeColor.getTransformations()[0]; + CPPUNIT_ASSERT_EQUAL(model::TransformationType::LumMod, rTrans1.meType); + CPPUNIT_ASSERT_EQUAL(sal_Int16(5000), rTrans1.mnValue); + } +} + +CPPUNIT_TEST_FIXTURE(XmloffDrawTest, testThemeColor_ShapeFill) +{ + OUString aURL = m_directories.getURLFromSrc(DATA_DIRECTORY) + "ReferenceShapeFill.pptx"; + getComponent() = loadFromDesktop(aURL); + utl::TempFile aTempFile; + save("impress8", aTempFile); + + // reload + getComponent()->dispose(); + getComponent() = loadFromDesktop(aURL); + + // check fill color theme + uno::Reference<drawing::XShape> xShape(getShape(0)); + CPPUNIT_ASSERT(xShape.is()); + uno::Reference<beans::XPropertySet> xShapeProperties(xShape, uno::UNO_QUERY); + uno::Reference<util::XThemeColor> xThemeColor; + xShapeProperties->getPropertyValue("FillColorThemeReference") >>= xThemeColor; + CPPUNIT_ASSERT(xThemeColor.is()); + model::ThemeColor aThemeColor; + model::theme::setFromXThemeColor(aThemeColor, xThemeColor); + CPPUNIT_ASSERT_EQUAL(model::ThemeColorType::Accent6, aThemeColor.getType()); + CPPUNIT_ASSERT_EQUAL(size_t(1), aThemeColor.getTransformations().size()); + CPPUNIT_ASSERT_EQUAL(model::TransformationType::LumMod, + aThemeColor.getTransformations()[0].meType); + CPPUNIT_ASSERT_EQUAL(sal_Int16(7500), aThemeColor.getTransformations()[0].mnValue); } CPPUNIT_PLUGIN_IMPLEMENT(); |