[Libreoffice-commits] core.git: include/oox oox/source sd/qa sd/source
Szymon Kłos
szymon.klos at collabora.com
Thu Oct 19 19:02:33 UTC 2017
include/oox/drawingml/clrscheme.hxx | 33 ++++
include/oox/export/utils.hxx | 2
include/oox/ppt/presentationfragmenthandler.hxx | 1
oox/source/export/drawingml.cxx | 2
oox/source/ppt/presentationfragmenthandler.cxx | 76 +++++++++
sd/qa/unit/data/pptx/accent-color.pptx |binary
sd/qa/unit/export-tests-ooxml2.cxx | 19 ++
sd/source/filter/eppt/epptooxml.hxx | 4
sd/source/filter/eppt/pptx-epptooxml.cxx | 193 ++++++++++++++++++------
9 files changed, 285 insertions(+), 45 deletions(-)
New commits:
commit 98133504fde1e1b235c39e4bb3b72bb2ee0b7819
Author: Szymon Kłos <szymon.klos at collabora.com>
Date: Tue Oct 17 22:14:38 2017 +0200
PPTX export: remember color schemes in theme
Remember color scheme from loaded pptx file
or use default values.
Change-Id: Icb69c51603afc5f332c20c75e4ed5f659f4b5614
Reviewed-on: https://gerrit.libreoffice.org/43470
Tested-by: Jenkins <ci at libreoffice.org>
Reviewed-by: Szymon Kłos <szymon.klos at collabora.com>
diff --git a/include/oox/drawingml/clrscheme.hxx b/include/oox/drawingml/clrscheme.hxx
index ccb1517e44eb..ccf918d7ba74 100644
--- a/include/oox/drawingml/clrscheme.hxx
+++ b/include/oox/drawingml/clrscheme.hxx
@@ -28,9 +28,42 @@
#include <oox/dllapi.h>
#include <sal/types.h>
+#include <rtl/ustring.hxx>
namespace oox { namespace drawingml {
+enum PredefinedClrSchemeId {
+ //dk1,
+ //lt1,
+ dk2 = 0,
+ lt2,
+ accent1,
+ accent2,
+ accent3,
+ accent4,
+ accent5,
+ accent6,
+ hlink,
+ folHlink,
+ Count
+};
+
+static std::map<PredefinedClrSchemeId, rtl::OUString> PredefinedClrNames =
+{
+ //{ dk1, "dk1" },
+ //{ lt1, "lt1" },
+ { dk2, "dk2" },
+ { lt2, "lt2" },
+ { accent1, "accent1" },
+ { accent2, "accent2" },
+ { accent3, "accent3" },
+ { accent4, "accent4" },
+ { accent5, "accent5" },
+ { accent6, "accent6" },
+ { hlink, "hlink" },
+ { folHlink, "folHlink" }
+};
+
class ClrMap
{
std::map < sal_Int32, sal_Int32 > maClrMap;
diff --git a/include/oox/export/utils.hxx b/include/oox/export/utils.hxx
index 6bca2edcbd16..74e78a37da33 100644
--- a/include/oox/export/utils.hxx
+++ b/include/oox/export/utils.hxx
@@ -28,7 +28,7 @@ inline OString I32S_(sal_Int32 x) { return OString::number(x); }
inline OString I32SHEX_(sal_Int32 x)
{
OString aStr = OString::number(x, 16);
- if (aStr.getLength() % 2 != 0)
+ while (aStr.getLength() < 6)
aStr = OString("0") + aStr;
return aStr.getStr();
}
diff --git a/include/oox/ppt/presentationfragmenthandler.hxx b/include/oox/ppt/presentationfragmenthandler.hxx
index aeda119cd2f1..637e70643be7 100644
--- a/include/oox/ppt/presentationfragmenthandler.hxx
+++ b/include/oox/ppt/presentationfragmenthandler.hxx
@@ -53,6 +53,7 @@ protected:
private:
void importSlide(sal_uInt32 nSlide, bool bFirstSlide, bool bImportNotes);
+ void saveThemeToGrabBag(oox::drawingml::ThemePtr pThemePtr, const OUString& sTheme);
std::vector< OUString > maSlideMasterVector;
std::vector< OUString > maSlidesVector;
diff --git a/oox/source/export/drawingml.cxx b/oox/source/export/drawingml.cxx
index 306e884fc0f3..953c16467596 100644
--- a/oox/source/export/drawingml.cxx
+++ b/oox/source/export/drawingml.cxx
@@ -2943,7 +2943,7 @@ void DrawingML::WriteStyleProperties( sal_Int32 nTokenId, const Sequence< Proper
aProperties[i].Value >>= aTransformations;
}
mpFS->startElementNS( XML_a, nTokenId, XML_idx, I32S( nIdx ), FSEND );
- WriteColor( sSchemeClr, aTransformations );
+ WriteColor(sSchemeClr, aTransformations);
mpFS->endElementNS( XML_a, nTokenId );
}
else
diff --git a/oox/source/ppt/presentationfragmenthandler.cxx b/oox/source/ppt/presentationfragmenthandler.cxx
index 07433617b612..f78e75c1bc00 100644
--- a/oox/source/ppt/presentationfragmenthandler.cxx
+++ b/oox/source/ppt/presentationfragmenthandler.cxx
@@ -64,6 +64,22 @@ using namespace ::com::sun::star::xml::sax;
namespace oox { namespace ppt {
+static std::map<PredefinedClrSchemeId, sal_Int32> PredefinedClrTokens =
+{
+ //{ dk1, XML_dk1 },
+ //{ lt1, XML_lt1 },
+ { dk2, XML_dk2 },
+ { lt2, XML_lt2 },
+ { accent1, XML_accent1 },
+ { accent2, XML_accent2 },
+ { accent3, XML_accent3 },
+ { accent4, XML_accent4 },
+ { accent5, XML_accent5 },
+ { accent6, XML_accent6 },
+ { hlink, XML_hlink },
+ { folHlink, XML_folHlink }
+};
+
PresentationFragmentHandler::PresentationFragmentHandler( XmlFilterBase& rFilter, const OUString& rFragmentPath ) throw()
: FragmentHandler2( rFilter, rFragmentPath )
, mpTextListStyle( new TextListStyle )
@@ -143,6 +159,65 @@ void ResolveTextFields( XmlFilterBase const & rFilter )
}
}
+void PresentationFragmentHandler::saveThemeToGrabBag(oox::drawingml::ThemePtr pThemePtr, const OUString& sTheme)
+{
+ if (!pThemePtr)
+ return;
+
+ try
+ {
+ uno::Reference<beans::XPropertySet> xDocProps(getFilter().getModel(), uno::UNO_QUERY);
+ if (xDocProps.is())
+ {
+ uno::Reference<beans::XPropertySetInfo> xPropsInfo = xDocProps->getPropertySetInfo();
+
+ const OUString aGrabBagPropName = "InteropGrabBag";
+ if (xPropsInfo.is() && xPropsInfo->hasPropertyByName(aGrabBagPropName))
+ {
+ // get existing grab bag
+ comphelper::SequenceAsHashMap aGrabBag(xDocProps->getPropertyValue(aGrabBagPropName));
+
+ uno::Sequence<beans::PropertyValue> aTheme(1);
+ comphelper::SequenceAsHashMap aThemesHashMap;
+
+ // create current theme
+ uno::Sequence<beans::PropertyValue> aCurrentTheme(PredefinedClrSchemeId::Count);
+
+ ClrScheme rClrScheme = pThemePtr->getClrScheme();
+ for (int nId = PredefinedClrSchemeId::dk2; nId != PredefinedClrSchemeId::Count; nId++)
+ {
+ sal_uInt32 nToken = PredefinedClrTokens[static_cast<PredefinedClrSchemeId>(nId)];
+ const OUString& sName = PredefinedClrNames[static_cast<PredefinedClrSchemeId>(nId)];
+ sal_Int32 nColor = 0;
+
+ rClrScheme.getColor(nToken, nColor);
+ const uno::Any& rColor = uno::makeAny(nColor);
+
+ aCurrentTheme[nId].Name = sName;
+ aCurrentTheme[nId].Value = rColor;
+ }
+
+ // add new theme to the sequence
+ aTheme[0].Name = sTheme;
+ const uno::Any& rCurrentTheme = makeAny(aCurrentTheme);
+ aTheme[0].Value = rCurrentTheme;
+
+ aThemesHashMap << aTheme;
+
+ // put the new items
+ aGrabBag.update(aThemesHashMap);
+
+ // put it back to the document
+ xDocProps->setPropertyValue(aGrabBagPropName, uno::Any(aGrabBag.getAsConstPropertyValueList()));
+ }
+ }
+ }
+ catch (const uno::Exception&)
+ {
+ SAL_WARN("oox", "oox::ppt::PresentationFragmentHandler::saveThemeToGrabBag, Failed to save grab bag");
+ }
+}
+
void PresentationFragmentHandler::importSlide(sal_uInt32 nSlide, bool bFirstPage, bool bImportNotesPage)
{
PowerPointImport& rFilter = dynamic_cast< PowerPointImport& >( getFilter() );
@@ -232,6 +307,7 @@ void PresentationFragmentHandler::importSlide(sal_uInt32 nSlide, bool bFirstPage
UNO_QUERY_THROW));
rThemes[ aThemeFragmentPath ] = pThemePtr;
pThemePtr->setFragment(xDoc);
+ saveThemeToGrabBag(pThemePtr, aThemeFragmentPath);
}
else
{
diff --git a/sd/qa/unit/data/pptx/accent-color.pptx b/sd/qa/unit/data/pptx/accent-color.pptx
new file mode 100755
index 000000000000..59591606e546
Binary files /dev/null and b/sd/qa/unit/data/pptx/accent-color.pptx differ
diff --git a/sd/qa/unit/export-tests-ooxml2.cxx b/sd/qa/unit/export-tests-ooxml2.cxx
index 25a1963c8e75..586700e39863 100644
--- a/sd/qa/unit/export-tests-ooxml2.cxx
+++ b/sd/qa/unit/export-tests-ooxml2.cxx
@@ -120,6 +120,7 @@ public:
void testGroupRotation();
void testTdf104788();
void testSmartartRotation2();
+ void testAccentColor();
CPPUNIT_TEST_SUITE(SdOOXMLExportTest2);
@@ -165,6 +166,7 @@ public:
CPPUNIT_TEST(testGroupRotation);
CPPUNIT_TEST(testTdf104788);
CPPUNIT_TEST(testSmartartRotation2);
+ CPPUNIT_TEST(testAccentColor);
CPPUNIT_TEST_SUITE_END();
@@ -1255,6 +1257,23 @@ void SdOOXMLExportTest2::testSmartartRotation2()
assertXPath(pXmlDocContent, "/p:sld/p:cSld/p:spTree/p:grpSp/p:sp[1]/p:spPr/a:xfrm/a:off", "y", "719640");
}
+void SdOOXMLExportTest2::testAccentColor()
+{
+ ::sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("sd/qa/unit/data/pptx/accent-color.pptx"), PPTX);
+ utl::TempFile tempFile;
+ xDocShRef = saveAndReload(xDocShRef.get(), PPTX, &tempFile);
+ xDocShRef->DoClose();
+
+ xmlDocPtr pXmlDocContent1 = parseExport(tempFile, "ppt/slides/slide1.xml");
+ assertXPath(pXmlDocContent1, "/p:sld/p:cSld/p:spTree/p:sp/p:style/a:fillRef/a:schemeClr", "val", "accent6");
+ xmlDocPtr pXmlDocContent2 = parseExport(tempFile, "ppt/slides/slide2.xml");
+ assertXPath(pXmlDocContent2, "/p:sld/p:cSld/p:spTree/p:sp/p:style/a:fillRef/a:schemeClr", "val", "accent6");
+ xmlDocPtr pXmlDocTheme1 = parseExport(tempFile, "ppt/theme/theme1.xml");
+ assertXPath(pXmlDocTheme1, "/a:theme/a:themeElements/a:clrScheme/a:accent6/a:srgbClr", "val", "70ad47");
+ xmlDocPtr pXmlDocTheme2 = parseExport(tempFile, "ppt/theme/theme2.xml");
+ assertXPath(pXmlDocTheme2, "/a:theme/a:themeElements/a:clrScheme/a:accent6/a:srgbClr", "val", "deb340");
+}
+
CPPUNIT_TEST_SUITE_REGISTRATION(SdOOXMLExportTest2);
CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/sd/source/filter/eppt/epptooxml.hxx b/sd/source/filter/eppt/epptooxml.hxx
index 1d98b541a688..05a9bd2d3bbc 100644
--- a/sd/source/filter/eppt/epptooxml.hxx
+++ b/sd/source/filter/eppt/epptooxml.hxx
@@ -26,6 +26,8 @@
#include <oox/export/shapes.hxx>
#include "epptbase.hxx"
+using ::sax_fastparser::FSHelperPtr;
+
namespace com { namespace sun { namespace star {
namespace animations {
class XAnimate;
@@ -90,6 +92,8 @@ protected:
virtual void ImplWriteSlideMaster( sal_uInt32 nPageNum, css::uno::Reference< css::beans::XPropertySet > const & aXBackgroundPropSet ) override;
virtual void ImplWriteLayout( sal_Int32 nOffset, sal_uInt32 nMasterNum ) override;
void ImplWritePPTXLayout( sal_Int32 nOffset, sal_uInt32 nMasterNum );
+ bool WriteColorSchemes(FSHelperPtr pFS, const OUString& rThemePath);
+ void WriteDefaultColorSchemes(FSHelperPtr pFS);
void WriteTheme( sal_Int32 nThemeNum );
virtual bool ImplCreateDocument() override;
diff --git a/sd/source/filter/eppt/pptx-epptooxml.cxx b/sd/source/filter/eppt/pptx-epptooxml.cxx
index a1bd8619fd88..ae8a631003ab 100644
--- a/sd/source/filter/eppt/pptx-epptooxml.cxx
+++ b/sd/source/filter/eppt/pptx-epptooxml.cxx
@@ -20,6 +20,7 @@
#include <stdio.h>
#include <o3tl/any.hxx>
#include <oox/drawingml/chart/chartconverter.hxx>
+#include <oox/drawingml/clrscheme.hxx>
#include <oox/token/namespaces.hxx>
#include <oox/token/tokens.hxx>
#include <oox/token/relationship.hxx>
@@ -2341,46 +2342,14 @@ ShapeExport& PowerPointShapeExport::WritePlaceholderShape(const Reference< XShap
return *this;
}
-#define MINIMAL_THEME " <a:themeElements>\
- <a:clrScheme name=\"Office\">\
- <a:dk1>\
+#define SYS_COLOR_SCHEMES " <a:dk1>\
<a:sysClr val=\"windowText\" lastClr=\"000000\"/>\
</a:dk1>\
<a:lt1>\
<a:sysClr val=\"window\" lastClr=\"FFFFFF\"/>\
- </a:lt1>\
- <a:dk2>\
- <a:srgbClr val=\"1F497D\"/>\
- </a:dk2>\
- <a:lt2>\
- <a:srgbClr val=\"EEECE1\"/>\
- </a:lt2>\
- <a:accent1>\
- <a:srgbClr val=\"4F81BD\"/>\
- </a:accent1>\
- <a:accent2>\
- <a:srgbClr val=\"C0504D\"/>\
- </a:accent2>\
- <a:accent3>\
- <a:srgbClr val=\"9BBB59\"/>\
- </a:accent3>\
- <a:accent4>\
- <a:srgbClr val=\"8064A2\"/>\
- </a:accent4>\
- <a:accent5>\
- <a:srgbClr val=\"4BACC6\"/>\
- </a:accent5>\
- <a:accent6>\
- <a:srgbClr val=\"F79646\"/>\
- </a:accent6>\
- <a:hlink>\
- <a:srgbClr val=\"0000FF\"/>\
- </a:hlink>\
- <a:folHlink>\
- <a:srgbClr val=\"800080\"/>\
- </a:folHlink>\
- </a:clrScheme>\
- <a:fontScheme name=\"Office\">\
+ </a:lt1>"
+
+#define MINIMAL_THEME " <a:fontScheme name=\"Office\">\
<a:majorFont>\
<a:latin typeface=\"Arial\"/>\
<a:ea typeface=\"DejaVu Sans\"/>\
@@ -2557,16 +2526,138 @@ ShapeExport& PowerPointShapeExport::WritePlaceholderShape(const Reference< XShap
</a:path>\
</a:gradFill>\
</a:bgFillStyleLst>\
- </a:fmtScheme>\
- </a:themeElements>"
+ </a:fmtScheme>"
+
+void PowerPointExport::WriteDefaultColorSchemes(FSHelperPtr pFS)
+{
+ for (int nId = PredefinedClrSchemeId::dk2; nId != PredefinedClrSchemeId::Count; nId++)
+ {
+ OUString sName = PredefinedClrNames[static_cast<PredefinedClrSchemeId>(nId)];
+ sal_Int32 nColor = 0;
+
+ switch (nId)
+ {
+ case PredefinedClrSchemeId::dk2:
+ nColor = 0x1F497D;
+ break;
+ case PredefinedClrSchemeId::lt2:
+ nColor = 0xEEECE1;
+ break;
+ case PredefinedClrSchemeId::accent1:
+ nColor = 0x4F81BD;
+ break;
+ case PredefinedClrSchemeId::accent2:
+ nColor = 0xC0504D;
+ break;
+ case PredefinedClrSchemeId::accent3:
+ nColor = 0x9BBB59;
+ break;
+ case PredefinedClrSchemeId::accent4:
+ nColor = 0x8064A2;
+ break;
+ case PredefinedClrSchemeId::accent5:
+ nColor = 0x4BACC6;
+ break;
+ case PredefinedClrSchemeId::accent6:
+ nColor = 0xF79646;
+ break;
+ case PredefinedClrSchemeId::hlink:
+ nColor = 0x0000FF;
+ break;
+ case PredefinedClrSchemeId::folHlink:
+ nColor = 0x800080;
+ break;
+ }
+
+ OUString sOpenColorScheme = OUStringBuffer()
+ .append("<a:")
+ .append(sName)
+ .append(">")
+ .makeStringAndClear();
+ pFS->write(sOpenColorScheme);
+
+ pFS->singleElementNS(XML_a, XML_srgbClr, XML_val, I32SHEX(nColor), FSEND);
+
+ OUString sCloseColorScheme = OUStringBuffer()
+ .append("</a:")
+ .append(sName)
+ .append(">")
+ .makeStringAndClear();
+ pFS->write(sCloseColorScheme);
+ }
+}
+
+bool PowerPointExport::WriteColorSchemes(FSHelperPtr pFS, const OUString& rThemePath)
+{
+ try
+ {
+ uno::Reference<beans::XPropertySet> xDocProps(getModel(), uno::UNO_QUERY);
+ if (xDocProps.is())
+ {
+ uno::Reference<beans::XPropertySetInfo> xPropsInfo = xDocProps->getPropertySetInfo();
+
+ const OUString aGrabBagPropName = "InteropGrabBag";
+ if (xPropsInfo.is() && xPropsInfo->hasPropertyByName(aGrabBagPropName))
+ {
+ comphelper::SequenceAsHashMap aGrabBag(xDocProps->getPropertyValue(aGrabBagPropName));
+ uno::Sequence<beans::PropertyValue> aCurrentTheme;
+
+ aGrabBag.getValue(rThemePath) >>= aCurrentTheme;
+
+ // Order is important
+ for (int nId = PredefinedClrSchemeId::dk2; nId != PredefinedClrSchemeId::Count; nId++)
+ {
+ OUString sName = PredefinedClrNames[static_cast<PredefinedClrSchemeId>(nId)];
+ sal_Int32 nColor = 0;
+
+ for (auto aIt = aCurrentTheme.begin(); aIt != aCurrentTheme.end(); aIt++)
+ {
+ if (aIt->Name == sName)
+ {
+ aIt->Value >>= nColor;
+ break;
+ }
+ }
+
+ OUString sOpenColorScheme = OUStringBuffer()
+ .append("<a:")
+ .append(sName)
+ .append(">")
+ .makeStringAndClear();
+ pFS->write(sOpenColorScheme);
+
+ pFS->singleElementNS(XML_a, XML_srgbClr, XML_val, I32SHEX(nColor), FSEND);
+
+ OUString sCloseColorScheme = OUStringBuffer()
+ .append("</a:")
+ .append(sName)
+ .append(">")
+ .makeStringAndClear();
+ pFS->write(sCloseColorScheme);
+ }
+
+ // TODO: write complete color schemes & only if successful, protection against partial export
+ return true;
+ }
+ }
+ }
+ catch (const uno::Exception&)
+ {
+ SAL_WARN("writerfilter", "Failed to save documents grab bag");
+ }
+
+ return false;
+}
void PowerPointExport::WriteTheme(sal_Int32 nThemeNum)
{
- FSHelperPtr pFS = openFragmentStreamWithSerializer(OUStringBuffer()
- .append("ppt/theme/theme")
- .append(nThemeNum + 1)
- .append(".xml")
- .makeStringAndClear(),
+ OUString sThemePath = OUStringBuffer()
+ .append("ppt/theme/theme")
+ .append(nThemeNum + 1)
+ .append(".xml")
+ .makeStringAndClear();
+
+ FSHelperPtr pFS = openFragmentStreamWithSerializer(sThemePath,
"application/vnd.openxmlformats-officedocument.theme+xml");
pFS->startElementNS(XML_a, XML_theme,
@@ -2574,7 +2665,23 @@ void PowerPointExport::WriteTheme(sal_Int32 nThemeNum)
XML_name, "Office Theme",
FSEND);
+ pFS->startElementNS(XML_a, XML_themeElements, FSEND);
+ pFS->startElementNS(XML_a, XML_clrScheme, XML_name, "Office", FSEND);
+
+ pFS->write(SYS_COLOR_SCHEMES);
+
+ if (!WriteColorSchemes(pFS, sThemePath))
+ {
+ // color schemes are required - use default values
+ WriteDefaultColorSchemes(pFS);
+ }
+
+ pFS->endElementNS(XML_a, XML_clrScheme);
+
+ // export remaining part
pFS->write(MINIMAL_THEME);
+
+ pFS->endElementNS(XML_a, XML_themeElements);
pFS->endElementNS(XML_a, XML_theme);
}
More information about the Libreoffice-commits
mailing list