summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@collabora.co.uk>2014-04-17 14:49:35 +0200
committerMiklos Vajna <vmiklos@collabora.co.uk>2014-04-17 15:10:36 +0200
commitd28b9e8fefa095471d1511c7948bcaf2a3473379 (patch)
tree813708edf2feab494244da4e5d1eb299c8eb082f
parentfc7f66d00a1738ae52a1738f456f4a720740e6d7 (diff)
oox: initial customshape preset data loader
CustomShapeProperties::pushToPropSet() still uses the old generated code, though. Change-Id: I02550bdf4ac57ef54992facd7ccd144e798be1e8
-rw-r--r--include/oox/drawingml/customshapeproperties.hxx3
-rw-r--r--oox/Library_oox.mk1
-rw-r--r--oox/source/drawingml/customshapepresetdata.cxx743
-rw-r--r--oox/source/drawingml/customshapeproperties.cxx1
4 files changed, 748 insertions, 0 deletions
diff --git a/include/oox/drawingml/customshapeproperties.hxx b/include/oox/drawingml/customshapeproperties.hxx
index 8e237b26956a..29d4ba2aca9a 100644
--- a/include/oox/drawingml/customshapeproperties.hxx
+++ b/include/oox/drawingml/customshapeproperties.hxx
@@ -172,8 +172,10 @@ private:
sal_Int32 mnTextRotateAngle;
typedef boost::unordered_map< sal_Int32, CustomShapeProvider * > PresetsMap;
+ typedef boost::unordered_map< sal_Int32, PropertyMap > PresetDataMap;
static PresetsMap maPresetsMap;
+ static PresetDataMap maPresetDataMap;
static void initializePresetsMap();
static void initializePresetsMap1();
static void initializePresetsMap2();
@@ -181,6 +183,7 @@ private:
static void initializePresetsMap4();
static void initializePresetsMap5();
static void initializePresetsMap6();
+ static void initializePresetDataMap();
sal_Int32 mnArcNum;
};
diff --git a/oox/Library_oox.mk b/oox/Library_oox.mk
index 06f047782c58..f27d0fa4e596 100644
--- a/oox/Library_oox.mk
+++ b/oox/Library_oox.mk
@@ -138,6 +138,7 @@ $(eval $(call gb_Library_add_exception_objects,oox,\
oox/source/drawingml/customshapepresets4 \
oox/source/drawingml/customshapepresets5 \
oox/source/drawingml/customshapepresets6 \
+ oox/source/drawingml/customshapepresetdata \
oox/source/drawingml/customshapeproperties \
oox/source/drawingml/diagram/constraintlistcontext \
oox/source/drawingml/diagram/datamodelcontext \
diff --git a/oox/source/drawingml/customshapepresetdata.cxx b/oox/source/drawingml/customshapepresetdata.cxx
new file mode 100644
index 000000000000..4522c3cb496c
--- /dev/null
+++ b/oox/source/drawingml/customshapepresetdata.cxx
@@ -0,0 +1,743 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <config_folders.h>
+#include <rtl/bootstrap.hxx>
+#include <tools/stream.hxx>
+#include <comphelper/sequenceasvector.hxx>
+
+#include "oox/drawingml/customshapeproperties.hxx"
+#include "oox/helper/helper.hxx"
+#include "oox/helper/propertymap.hxx"
+#include "oox/helper/propertyset.hxx"
+#include "oox/token/tokenmap.hxx"
+#include <com/sun/star/awt/Rectangle.hpp>
+#include <com/sun/star/awt/Size.hpp>
+#include <com/sun/star/beans/XMultiPropertySet.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/graphic/XGraphicTransformer.hpp>
+#include <com/sun/star/drawing/XShape.hpp>
+#include <com/sun/star/drawing/XEnhancedCustomShapeDefaulter.hpp>
+#include <com/sun/star/drawing/EnhancedCustomShapeTextFrame.hpp>
+
+using namespace ::com::sun::star;
+
+namespace
+{
+
+// Parses a string like: Value = (any) { (long) 19098 }, State = (com.sun.star.beans.PropertyState) DIRECT_VALUE, Name = "adj"
+void lcl_parseAdjustmentValue(comphelper::SequenceAsVector<drawing::EnhancedCustomShapeAdjustmentValue>& rAdjustmentValues, const OString& rValue)
+{
+ sal_Int32 nIndex = 0;
+ drawing::EnhancedCustomShapeAdjustmentValue aAdjustmentValue;
+ do
+ {
+ OString aToken = rValue.getToken(0, ',', nIndex).trim();
+ static const OString aNamePrefix("Name = \"");
+ static const OString aValuePrefix("Value = (any) { (long) ");
+ if (aToken.startsWith(aNamePrefix))
+ {
+ OString aName = aToken.copy(aNamePrefix.getLength(), aToken.getLength() - aNamePrefix.getLength() - strlen("\""));
+ aAdjustmentValue.Name = OStringToOUString(aName, RTL_TEXTENCODING_UTF8);
+ }
+ else if (aToken.startsWith(aValuePrefix))
+ {
+ OString aValue = aToken.copy(aValuePrefix.getLength(), aToken.getLength() - aValuePrefix.getLength() - strlen(" }"));
+ aAdjustmentValue.Value = uno::makeAny(aValue.toInt32());
+ }
+ else if (!aToken.startsWith("State = "))
+ SAL_WARN("oox", "lcl_parseAdjustmentValue: unexpected prefix: " << aToken);
+ }
+ while (nIndex >= 0);
+ rAdjustmentValues.push_back(aAdjustmentValue);
+}
+
+// Parses a string like: { Value = (any) { (long) 19098 }, State = (com.sun.star.beans.PropertyState) DIRECT_VALUE, Name = "adj" }, { Value = ..., State = ..., Name = ... }
+void lcl_parseAdjustmentValues(comphelper::SequenceAsVector<drawing::EnhancedCustomShapeAdjustmentValue>& rAdjustmentValues, const OString& rValue)
+{
+ sal_Int32 nLevel = 0;
+ sal_Int32 nStart = 0;
+ for (sal_Int32 i = 0; i < rValue.getLength(); ++i)
+ {
+ if (rValue[i] == '{')
+ {
+ if (!nLevel)
+ nStart = i;
+ nLevel++;
+ }
+ else if (rValue[i] == '}')
+ {
+ nLevel--;
+ if (!nLevel)
+ {
+ lcl_parseAdjustmentValue(rAdjustmentValues, rValue.copy(nStart + strlen("{ "), i - nStart - strlen(" },")));
+ }
+ }
+ }
+}
+
+drawing::EnhancedCustomShapeParameterPair lcl_parseEnhancedCustomShapeParameterPair(const OString& rValue)
+{
+ drawing::EnhancedCustomShapeParameterPair aPair;
+ OString aToken = rValue;
+ // We expect the followings here: First.Value, First.Type, Second.Value, Second.Type
+ static const OString aExpectedFVPrefix = "First = (com.sun.star.drawing.EnhancedCustomShapeParameter) { Value = (any) { (long) ";
+ assert(aToken.startsWith(aExpectedFVPrefix));
+ sal_Int32 nIndex = aExpectedFVPrefix.getLength();
+ aPair.First.Value = uno::makeAny(static_cast<sal_uInt32>(aToken.getToken(0, '}', nIndex).toInt32()));
+
+ static const OString aExpectedFTPrefix = ", Type = (short) ";
+ aToken = aToken.copy(nIndex);
+ assert(aToken.startsWith(aExpectedFTPrefix));
+ nIndex = aExpectedFTPrefix.getLength();
+ aPair.First.Type = static_cast<sal_uInt16>(aToken.getToken(0, '}', nIndex).toInt32());
+
+ static const OString aExpectedSVPrefix = ", Second = (com.sun.star.drawing.EnhancedCustomShapeParameter) { Value = (any) { (long) ";
+ aToken = aToken.copy(nIndex);
+ assert(aToken.startsWith(aExpectedSVPrefix));
+ nIndex = aExpectedSVPrefix.getLength();
+ aPair.Second.Value = uno::makeAny(static_cast<sal_uInt32>(aToken.getToken(0, '}', nIndex).toInt32()));
+
+ static const OString aExpectedSTPrefix = ", Type = (short) ";
+ aToken = aToken.copy(nIndex);
+ assert(aToken.startsWith(aExpectedSTPrefix));
+ nIndex = aExpectedSTPrefix.getLength();
+ aPair.Second.Type = static_cast<sal_uInt16>(aToken.getToken(0, '}', nIndex).toInt32());
+ return aPair;
+}
+
+drawing::EnhancedCustomShapeSegment lcl_parseEnhancedCustomShapeSegment(const OString& rValue)
+{
+ drawing::EnhancedCustomShapeSegment aSegment;
+ OString aToken = rValue;
+ // We expect the followings here: Command, Count
+ static const OString aExpectedCommandPrefix = "Command = (short) ";
+ assert(aToken.startsWith(aExpectedCommandPrefix));
+ sal_Int32 nIndex = aExpectedCommandPrefix.getLength();
+ aSegment.Command = static_cast<sal_Int16>(aToken.getToken(0, ',', nIndex).toInt32());
+
+ static const OString aExpectedCountPrefix = " Count = (short) ";
+ aToken = aToken.copy(nIndex);
+ assert(aToken.startsWith(aExpectedCountPrefix));
+ nIndex = aExpectedCountPrefix.getLength();
+ aSegment.Count = static_cast<sal_Int16>(aToken.getToken(0, '}', nIndex).toInt32());
+ return aSegment;
+}
+
+awt::Rectangle lcl_parseRectangle(const OString& rValue)
+{
+ awt::Rectangle aRectangle;
+ OString aToken = rValue;
+ // We expect the followings here: X, Y, Width, Height
+ static const OString aExpectedXPrefix = "X = (long) ";
+ assert(aToken.startsWith(aExpectedXPrefix));
+ sal_Int32 nIndex = aExpectedXPrefix.getLength();
+ aRectangle.X = static_cast<sal_Int32>(aToken.getToken(0, ',', nIndex).toInt32());
+
+ static const OString aExpectedYPrefix = " Y = (long) ";
+ aToken = aToken.copy(nIndex);
+ assert(aToken.startsWith(aExpectedYPrefix));
+ nIndex = aExpectedYPrefix.getLength();
+ aRectangle.Y = static_cast<sal_Int32>(aToken.getToken(0, ',', nIndex).toInt32());
+
+ static const OString aExpectedWidthPrefix = " Width = (long) ";
+ aToken = aToken.copy(nIndex);
+ assert(aToken.startsWith(aExpectedWidthPrefix));
+ nIndex = aExpectedWidthPrefix.getLength();
+ aRectangle.Width = static_cast<sal_Int32>(aToken.getToken(0, ',', nIndex).toInt32());
+
+ static const OString aExpectedHeightPrefix = " Height = (long) ";
+ aToken = aToken.copy(nIndex);
+ assert(aToken.startsWith(aExpectedHeightPrefix));
+ nIndex = aExpectedHeightPrefix.getLength();
+ aRectangle.Width = static_cast<sal_Int32>(aToken.copy(nIndex).toInt32());
+
+ return aRectangle;
+}
+
+drawing::EnhancedCustomShapeTextFrame lcl_parseEnhancedCustomShapeTextFrame(const OString& rValue)
+{
+ drawing::EnhancedCustomShapeTextFrame aTextFrame;
+ sal_Int32 nLevel = 0;
+ bool bIgnore = false;
+ sal_Int32 nStart = 0;
+ for (sal_Int32 i = 0; i < rValue.getLength(); ++i)
+ {
+ if (rValue[i] == '{')
+ {
+ if (!nLevel)
+ bIgnore = true;
+ nLevel++;
+ }
+ else if (rValue[i] == '}')
+ {
+ nLevel--;
+ if (!nLevel)
+ bIgnore = false;
+ }
+ else if (rValue[i] == ',' && !bIgnore)
+ {
+ OString aToken = rValue.copy(nStart, i - nStart);
+ static const OString aExpectedPrefix("TopLeft = (com.sun.star.drawing.EnhancedCustomShapeParameterPair) { ");
+ if (aToken.startsWith(aExpectedPrefix))
+ {
+ aToken = aToken.copy(aExpectedPrefix.getLength(), aToken.getLength() - aExpectedPrefix.getLength() - strlen(" }"));
+ aTextFrame.TopLeft = lcl_parseEnhancedCustomShapeParameterPair(aToken);
+ }
+ else
+ SAL_WARN("oox", "lcl_parseEnhancedCustomShapeTextFrame: unexpected token: " << aToken);
+ nStart = i + strlen(", ");
+ }
+ }
+
+ OString aToken = rValue.copy(nStart, rValue.getLength() - nStart);
+ static const OString aExpectedPrefix("BottomRight = (com.sun.star.drawing.EnhancedCustomShapeParameterPair) { ");
+ if (aToken.startsWith(aExpectedPrefix))
+ {
+ aToken = aToken.copy(aExpectedPrefix.getLength(), aToken.getLength() - aExpectedPrefix.getLength() - strlen(" }"));
+ aTextFrame.BottomRight = lcl_parseEnhancedCustomShapeParameterPair(aToken);
+ }
+ else
+ SAL_WARN("oox", "lcl_parseEnhancedCustomShapeTextFrame: unexpected token at the end: " << aToken);
+
+ return aTextFrame;
+}
+
+// Parses a string like: Name = "Position", Handle = (long) 0, Value = (any) { ... }, State = (com.sun.star.beans.PropertyState) DIRECT_VALUE
+// where "{ ... }" may contain "," as well.
+void lcl_parseHandlePosition(comphelper::SequenceAsVector<beans::PropertyValue>& rHandle, const OString& rValue)
+{
+ sal_Int32 nLevel = 0;
+ bool bIgnore = false;
+ sal_Int32 nStart = 0;
+ for (sal_Int32 i = 0; i < rValue.getLength(); ++i)
+ {
+ if (rValue[i] == '{')
+ {
+ if (!nLevel)
+ bIgnore = true;
+ nLevel++;
+ }
+ else if (rValue[i] == '}')
+ {
+ nLevel--;
+ if (!nLevel)
+ bIgnore = false;
+ }
+ else if (rValue[i] == ',' && !bIgnore)
+ {
+ OString aToken = rValue.copy(nStart, i - nStart);
+ static const OString aExpectedPrefix("Value = (any) { (com.sun.star.drawing.EnhancedCustomShapeParameterPair) { ");
+ if (aToken.startsWith(aExpectedPrefix))
+ {
+ aToken = aToken.copy(aExpectedPrefix.getLength(), aToken.getLength() - aExpectedPrefix.getLength() - strlen(" } }"));
+
+ beans::PropertyValue aPropertyValue;
+ aPropertyValue.Name = "Position";
+ aPropertyValue.Value = uno::makeAny(lcl_parseEnhancedCustomShapeParameterPair(aToken));
+ rHandle.push_back(aPropertyValue);
+ }
+ else if (!aToken.startsWith("Name =") && !aToken.startsWith("Handle ="))
+ SAL_WARN("oox", "lcl_parseHandlePosition: unexpected token: " << aToken);
+ nStart = i + strlen(", ");
+ }
+ }
+}
+
+// Parses a string like: Name = "RangeYMaximum", Handle = (long) 0, Value = (any) { ... }, State = (com.sun.star.beans.PropertyState) DIRECT_VALUE
+// where "{ ... }" may contain "," as well.
+void lcl_parseHandleRange(comphelper::SequenceAsVector<beans::PropertyValue>& rHandle, const OString& rValue, const OUString& rName)
+{
+ sal_Int32 nLevel = 0;
+ bool bIgnore = false;
+ sal_Int32 nStart = 0;
+ for (sal_Int32 i = 0; i < rValue.getLength(); ++i)
+ {
+ if (rValue[i] == '{')
+ {
+ if (!nLevel)
+ bIgnore = true;
+ nLevel++;
+ }
+ else if (rValue[i] == '}')
+ {
+ nLevel--;
+ if (!nLevel)
+ bIgnore = false;
+ }
+ else if (rValue[i] == ',' && !bIgnore)
+ {
+ OString aToken = rValue.copy(nStart, i - nStart);
+ static const OString aExpectedPrefix("Value = (any) { (com.sun.star.drawing.EnhancedCustomShapeParameter) { ");
+ if (aToken.startsWith(aExpectedPrefix))
+ {
+ drawing::EnhancedCustomShapeParameter aParameter;
+ aToken = aToken.copy(aExpectedPrefix.getLength(), aToken.getLength() - aExpectedPrefix.getLength() - strlen(" } }"));
+ // We expect the followings here: Value and Type
+ static const OString aExpectedVPrefix = "Value = (any) { (long) ";
+ assert(aToken.startsWith(aExpectedVPrefix));
+ sal_Int32 nIndex = aExpectedVPrefix.getLength();
+ aParameter.Value = uno::makeAny(aToken.getToken(0, '}', nIndex).toInt32());
+
+ static const OString aExpectedTPrefix = ", Type = (short) ";
+ aToken = aToken.copy(nIndex);
+ assert(aToken.startsWith(aExpectedTPrefix));
+ nIndex = aExpectedTPrefix.getLength();
+ aParameter.Type = static_cast<sal_Int16>(aToken.getToken(0, '}', nIndex).toInt32());
+
+ beans::PropertyValue aPropertyValue;
+ aPropertyValue.Name = rName;
+ aPropertyValue.Value = uno::makeAny(aParameter);
+ rHandle.push_back(aPropertyValue);
+
+ }
+ else if (!aToken.startsWith("Name =") && !aToken.startsWith("Handle ="))
+ SAL_WARN("oox", "lcl_parseHandleRange: unexpected token: " << aToken);
+ nStart = i + strlen(", ");
+ }
+ }
+}
+
+// Parses a string like: Name = "RefY", Handle = (long) 0, Value = (any) { (long) 0 }, State = (com.sun.star.beans.PropertyState) DIRECT_VALUE
+void lcl_parseHandleRefY(comphelper::SequenceAsVector<beans::PropertyValue>& rHandle, const OString& rValue)
+{
+ static const OString aExpectedPrefix("Name = \"RefY\", Handle = (long) 0, Value = (any) { (long) ");
+ if (rValue.startsWith(aExpectedPrefix))
+ {
+ sal_Int32 nIndex = aExpectedPrefix.getLength();
+ beans::PropertyValue aPropertyValue;
+ aPropertyValue.Name = "RefY";
+ // We only expect a Value here
+ aPropertyValue.Value = uno::makeAny(rValue.getToken(0, '}', nIndex).toInt32());
+ rHandle.push_back(aPropertyValue);
+
+ }
+ else
+ SAL_WARN("oox", "lcl_parseHandleRefY: unexpected value: " << rValue);
+}
+
+uno::Sequence<beans::PropertyValue> lcl_parseHandle(const OString& rValue)
+{
+ comphelper::SequenceAsVector<beans::PropertyValue> aRet;
+ sal_Int32 nLevel = 0;
+ sal_Int32 nStart = 0;
+ for (sal_Int32 i = 0; i < rValue.getLength(); ++i)
+ {
+ if (rValue[i] == '{')
+ {
+ if (!nLevel)
+ nStart = i;
+ nLevel++;
+ }
+ else if (rValue[i] == '}')
+ {
+ nLevel--;
+ if (!nLevel)
+ {
+ OString aToken = rValue.copy(nStart + strlen("{ "), i - nStart - strlen(" },"));
+ if (aToken.startsWith("Name = \"Position\""))
+ lcl_parseHandlePosition(aRet, aToken);
+ else if (aToken.startsWith("Name = \"RangeYMaximum\""))
+ lcl_parseHandleRange(aRet, aToken, "RangeYMaximum");
+ else if (aToken.startsWith("Name = \"RangeYMinimum\""))
+ lcl_parseHandleRange(aRet, aToken, "RangeYMinimum");
+ else if (aToken.startsWith("Name = \"RefY\""))
+ lcl_parseHandleRefY(aRet, aToken);
+ else
+ SAL_WARN("oox", "lcl_parseHandle: unexpected value: " << rValue);
+ }
+ }
+ }
+ return aRet.getAsConstList();
+}
+
+void lcl_parseHandles(comphelper::SequenceAsVector< uno::Sequence<beans::PropertyValue> >& rHandles, const OString& rValue)
+{
+ sal_Int32 nLevel = 0;
+ sal_Int32 nStart = 0;
+ for (sal_Int32 i = 0; i < rValue.getLength(); ++i)
+ {
+ if (rValue[i] == '{')
+ {
+ if (!nLevel)
+ nStart = i;
+ nLevel++;
+ }
+ else if (rValue[i] == '}')
+ {
+ nLevel--;
+ if (!nLevel)
+ {
+ uno::Sequence<beans::PropertyValue> aHandle = lcl_parseHandle(rValue.copy(nStart + strlen("{ "), i - nStart - strlen(" },")));
+ rHandles.push_back(aHandle);
+ }
+ }
+ }
+}
+
+void lcl_parseEquations(comphelper::SequenceAsVector<OUString>& rEquations, const OString& rValue)
+{
+ bool bInString = false;
+ sal_Int32 nStart = 0;
+ for (sal_Int32 i = 0; i < rValue.getLength(); ++i)
+ {
+ if (rValue[i] == '"' && !bInString)
+ {
+ nStart = i;
+ bInString = true;
+ }
+ else if (rValue[i] == '"' && bInString)
+ {
+ bInString = false;
+ rEquations.push_back(OStringToOUString(rValue.copy(nStart + strlen("\""), i - nStart - strlen("\"")), RTL_TEXTENCODING_UTF8));
+ }
+ }
+}
+
+void lcl_parsePathCoordinateValues(comphelper::SequenceAsVector<beans::PropertyValue>& rPath, const OString& rValue)
+{
+ comphelper::SequenceAsVector<drawing::EnhancedCustomShapeParameterPair> aPairs;
+ sal_Int32 nLevel = 0;
+ sal_Int32 nStart = 0;
+ for (sal_Int32 i = 0; i < rValue.getLength(); ++i)
+ {
+ if (rValue[i] == '{')
+ {
+ if (!nLevel)
+ nStart = i;
+ nLevel++;
+ }
+ else if (rValue[i] == '}')
+ {
+ nLevel--;
+ if (!nLevel)
+ aPairs.push_back(lcl_parseEnhancedCustomShapeParameterPair(rValue.copy(nStart + strlen("{ "), i - nStart - strlen(" },"))));
+ }
+ }
+
+ beans::PropertyValue aPropertyValue;
+ aPropertyValue.Name = "Coordinates";
+ aPropertyValue.Value = uno::makeAny(aPairs.getAsConstList());
+ rPath.push_back(aPropertyValue);
+}
+
+// Parses a string like: Name = "Coordinates", Handle = (long) 0, Value = (any) { ... }, State = (com.sun.star.beans.PropertyState) DIRECT_VALUE
+// where "{ ... }" may contain "," as well.
+void lcl_parsePathCoordinates(comphelper::SequenceAsVector<beans::PropertyValue>& rPath, const OString& rValue)
+{
+ sal_Int32 nLevel = 0;
+ bool bIgnore = false;
+ sal_Int32 nStart = 0;
+ for (sal_Int32 i = 0; i < rValue.getLength(); ++i)
+ {
+ if (rValue[i] == '{')
+ {
+ if (!nLevel)
+ bIgnore = true;
+ nLevel++;
+ }
+ else if (rValue[i] == '}')
+ {
+ nLevel--;
+ if (!nLevel)
+ bIgnore = false;
+ }
+ else if (rValue[i] == ',' && !bIgnore)
+ {
+ OString aToken = rValue.copy(nStart, i - nStart);
+ static const OString aExpectedPrefix("Value = (any) { ([]com.sun.star.drawing.EnhancedCustomShapeParameterPair) { ");
+ if (aToken.startsWith(aExpectedPrefix))
+ {
+ aToken = aToken.copy(aExpectedPrefix.getLength(), aToken.getLength() - aExpectedPrefix.getLength() - strlen(" } }"));
+ lcl_parsePathCoordinateValues(rPath, aToken);
+ }
+ else if (!aToken.startsWith("Name =") && !aToken.startsWith("Handle ="))
+ SAL_WARN("oox", "lcl_parsePathCoordinates: unexpected token: " << aToken);
+ nStart = i + strlen(", ");
+ }
+ }
+}
+
+void lcl_parsePathSegmentValues(comphelper::SequenceAsVector<beans::PropertyValue>& rPath, const OString& rValue)
+{
+ comphelper::SequenceAsVector<drawing::EnhancedCustomShapeSegment> aSegments;
+ sal_Int32 nLevel = 0;
+ sal_Int32 nStart = 0;
+ for (sal_Int32 i = 0; i < rValue.getLength(); ++i)
+ {
+ if (rValue[i] == '{')
+ {
+ if (!nLevel)
+ nStart = i;
+ nLevel++;
+ }
+ else if (rValue[i] == '}')
+ {
+ nLevel--;
+ if (!nLevel)
+ aSegments.push_back(lcl_parseEnhancedCustomShapeSegment(rValue.copy(nStart + strlen("{ "), i - nStart - strlen(" },"))));
+ }
+ }
+
+ beans::PropertyValue aPropertyValue;
+ aPropertyValue.Name = "Segments";
+ aPropertyValue.Value = uno::makeAny(aSegments.getAsConstList());
+ rPath.push_back(aPropertyValue);
+}
+
+// Parses a string like: Name = "Segments", Handle = (long) 0, Value = (any) { ... }, State = (com.sun.star.beans.PropertyState) DIRECT_VALUE
+// where "{ ... }" may contain "," as well.
+void lcl_parsePathSegments(comphelper::SequenceAsVector<beans::PropertyValue>& rPath, const OString& rValue)
+{
+ sal_Int32 nLevel = 0;
+ bool bIgnore = false;
+ sal_Int32 nStart = 0;
+ for (sal_Int32 i = 0; i < rValue.getLength(); ++i)
+ {
+ if (rValue[i] == '{')
+ {
+ if (!nLevel)
+ bIgnore = true;
+ nLevel++;
+ }
+ else if (rValue[i] == '}')
+ {
+ nLevel--;
+ if (!nLevel)
+ bIgnore = false;
+ }
+ else if (rValue[i] == ',' && !bIgnore)
+ {
+ OString aToken = rValue.copy(nStart, i - nStart);
+ static const OString aExpectedPrefix("Value = (any) { ([]com.sun.star.drawing.EnhancedCustomShapeSegment) { ");
+ if (aToken.startsWith(aExpectedPrefix))
+ {
+ aToken = aToken.copy(aExpectedPrefix.getLength(), aToken.getLength() - aExpectedPrefix.getLength() - strlen(" } }"));
+ lcl_parsePathSegmentValues(rPath, aToken);
+ }
+ else if (!aToken.startsWith("Name =") && !aToken.startsWith("Handle ="))
+ SAL_WARN("oox", "lcl_parsePathSegments: unexpected token: " << aToken);
+ nStart = i + strlen(", ");
+ }
+ }
+}
+
+void lcl_parsePathTextFrameValues(comphelper::SequenceAsVector<beans::PropertyValue>& rPath, const OString& rValue)
+{
+ comphelper::SequenceAsVector<drawing::EnhancedCustomShapeTextFrame> aTextFrames;
+ sal_Int32 nLevel = 0;
+ sal_Int32 nStart = 0;
+ for (sal_Int32 i = 0; i < rValue.getLength(); ++i)
+ {
+ if (rValue[i] == '{')
+ {
+ if (!nLevel)
+ nStart = i;
+ nLevel++;
+ }
+ else if (rValue[i] == '}')
+ {
+ nLevel--;
+ if (!nLevel)
+ aTextFrames.push_back(lcl_parseEnhancedCustomShapeTextFrame(rValue.copy(nStart + strlen("{ "), i - nStart - strlen(" },"))));
+ }
+ }
+
+ beans::PropertyValue aPropertyValue;
+ aPropertyValue.Name = "TextFrames";
+ aPropertyValue.Value = uno::makeAny(aTextFrames.getAsConstList());
+ rPath.push_back(aPropertyValue);
+}
+
+// Parses a string like: Name = "TextFrames", Handle = (long) 0, Value = (any) { ... }, State = (com.sun.star.beans.PropertyState) DIRECT_VALUE
+// where "{ ... }" may contain "," as well.
+void lcl_parsePathTextFrames(comphelper::SequenceAsVector<beans::PropertyValue>& rPath, const OString& rValue)
+{
+ sal_Int32 nLevel = 0;
+ bool bIgnore = false;
+ sal_Int32 nStart = 0;
+ for (sal_Int32 i = 0; i < rValue.getLength(); ++i)
+ {
+ if (rValue[i] == '{')
+ {
+ if (!nLevel)
+ bIgnore = true;
+ nLevel++;
+ }
+ else if (rValue[i] == '}')
+ {
+ nLevel--;
+ if (!nLevel)
+ bIgnore = false;
+ }
+ else if (rValue[i] == ',' && !bIgnore)
+ {
+ OString aToken = rValue.copy(nStart, i - nStart);
+ static const OString aExpectedPrefix("Value = (any) { ([]com.sun.star.drawing.EnhancedCustomShapeTextFrame) { ");
+ if (aToken.startsWith(aExpectedPrefix))
+ {
+ aToken = aToken.copy(aExpectedPrefix.getLength(), aToken.getLength() - aExpectedPrefix.getLength() - strlen(" } }"));
+ lcl_parsePathTextFrameValues(rPath, aToken);
+ }
+ else if (!aToken.startsWith("Name =") && !aToken.startsWith("Handle ="))
+ SAL_WARN("oox", "lcl_parsePathTextFrames: unexpected token: " << aToken);
+ nStart = i + strlen(", ");
+ }
+ }
+}
+
+void lcl_parsePath(comphelper::SequenceAsVector<beans::PropertyValue>& rPath, const OString& rValue)
+{
+ sal_Int32 nLevel = 0;
+ sal_Int32 nStart = 0;
+ for (sal_Int32 i = 0; i < rValue.getLength(); ++i)
+ {
+ if (rValue[i] == '{')
+ {
+ if (!nLevel)
+ nStart = i;
+ nLevel++;
+ }
+ else if (rValue[i] == '}')
+ {
+ nLevel--;
+ if (!nLevel)
+ {
+ OString aToken = rValue.copy(nStart + strlen("{ "), i - nStart - strlen(" },"));
+ if (aToken.startsWith("Name = \"Coordinates\""))
+ lcl_parsePathCoordinates(rPath, aToken);
+ else if (aToken.startsWith("Name = \"Segments\""))
+ lcl_parsePathSegments(rPath, aToken);
+ else if (aToken.startsWith("Name = \"TextFrames\""))
+ lcl_parsePathTextFrames(rPath, aToken);
+ else
+ SAL_WARN("oox", "lcl_parsePath: unexpected token: " << aToken);
+ }
+ }
+ }
+}
+
+}
+
+namespace oox
+{
+namespace drawingml
+{
+
+void CustomShapeProperties::initializePresetDataMap()
+{
+ OUString aPath("$BRAND_BASE_DIR/" LIBO_SHARE_FOLDER "/filter/oox-drawingml-cs-presets");
+ rtl::Bootstrap::expandMacros(aPath);
+ SvFileStream aStream(aPath, STREAM_READ);
+ if (aStream.GetError() != ERRCODE_NONE)
+ SAL_WARN("oox", "failed to open oox-drawingml-cs-presets");
+ OString aLine;
+ OUString aName;
+ bool bNotDone = aStream.ReadLine(aLine);
+ PropertyMap aPropertyMap;
+ while (bNotDone)
+ {
+ static const OString aCommentPrefix("/* ");
+ if (aLine.startsWith(aCommentPrefix))
+ {
+ aName = OStringToOUString(aLine.copy(aCommentPrefix.getLength(), aLine.getLength() - aCommentPrefix.getLength() - strlen(" */")), RTL_TEXTENCODING_UTF8);
+ }
+ else
+ {
+ if (aLine == "AdjustmentValues")
+ {
+ aStream.ReadLine(aLine);
+ OString aExpectedPrefix("([]com.sun.star.drawing.EnhancedCustomShapeAdjustmentValue) { ");
+ assert(aLine.startsWith(aExpectedPrefix));
+
+ comphelper::SequenceAsVector<drawing::EnhancedCustomShapeAdjustmentValue> aAdjustmentValues;
+ OString aValue = aLine.copy(aExpectedPrefix.getLength(), aLine.getLength() - aExpectedPrefix.getLength() - strlen(" }"));
+ lcl_parseAdjustmentValues(aAdjustmentValues, aValue);
+ aPropertyMap.setProperty(PROP_AdjustmentValues, aAdjustmentValues.getAsConstList());
+ }
+ else if (aLine == "Equations")
+ {
+ aStream.ReadLine(aLine);
+ OString aExpectedPrefix("([]string) { ");
+ assert(aLine.startsWith(aExpectedPrefix));
+
+ comphelper::SequenceAsVector<OUString> aEquations;
+ OString aValue = aLine.copy(aExpectedPrefix.getLength(), aLine.getLength() - aExpectedPrefix.getLength() - strlen(" }"));
+ lcl_parseEquations(aEquations, aValue);
+ aPropertyMap.setProperty(PROP_Equations, aEquations.getAsConstList());
+ }
+ else if (aLine == "Handles")
+ {
+ aStream.ReadLine(aLine);
+ OString aExpectedPrefix("([][]com.sun.star.beans.PropertyValue) { ");
+ assert(aLine.startsWith(aExpectedPrefix));
+
+ comphelper::SequenceAsVector< uno::Sequence<beans::PropertyValue> > aHandles;
+ OString aValue = aLine.copy(aExpectedPrefix.getLength(), aLine.getLength() - aExpectedPrefix.getLength() - strlen(" }"));
+ lcl_parseHandles(aHandles, aValue);
+ aPropertyMap.setProperty(PROP_Handles, aHandles.getAsConstList());
+ }
+ else if (aLine == "MirroredX")
+ {
+ aStream.ReadLine(aLine);
+ if (aLine == "true" || aLine == "false")
+ {
+ aPropertyMap.setProperty(PROP_MirroredX, sal_Bool(aLine == "true" ? sal_True : sal_False));
+ }
+ else
+ SAL_WARN("oox", "CustomShapeProperties::initializePresetDataMap: unexpected MirroredX parameter");
+ }
+ else if (aLine == "MirroredY")
+ {
+ aStream.ReadLine(aLine);
+ if (aLine == "true" || aLine == "false")
+ {
+ aPropertyMap.setProperty(PROP_MirroredY, sal_Bool(aLine == "true" ? sal_True : sal_False));
+ }
+ else
+ SAL_WARN("oox", "CustomShapeProperties::initializePresetDataMap: unexpected MirroredY parameter");
+ }
+ else if (aLine == "Path")
+ {
+ aStream.ReadLine(aLine);
+ OString aExpectedPrefix("([]com.sun.star.beans.PropertyValue) { ");
+ assert(aLine.startsWith(aExpectedPrefix));
+
+ comphelper::SequenceAsVector<beans::PropertyValue> aPathValue;
+ OString aValue = aLine.copy(aExpectedPrefix.getLength(), aLine.getLength() - aExpectedPrefix.getLength() - strlen(" }"));
+ lcl_parsePath(aPathValue, aValue);
+ aPropertyMap.setProperty(PROP_Path, aPathValue.getAsConstList());
+ }
+ else if (aLine == "Type")
+ {
+ // Just ignore the line here, we already know the correct type.
+ aStream.ReadLine(aLine);
+ aPropertyMap.setProperty(PROP_Type, "ooxml-" + aName);
+ }
+ else if (aLine == "ViewBox")
+ {
+ aStream.ReadLine(aLine);
+ OString aExpectedPrefix("(com.sun.star.awt.Rectangle) { ");
+ assert(aLine.startsWith(aExpectedPrefix));
+
+ OString aValue = aLine.copy(aExpectedPrefix.getLength(), aLine.getLength() - aExpectedPrefix.getLength() - strlen(" }"));
+ aPropertyMap.setProperty(PROP_ViewBox, lcl_parseRectangle(aValue));
+ }
+ else
+ SAL_WARN("oox", "CustomShapeProperties::initializePresetDataMap: unhandled line: " << aLine);
+ }
+ bNotDone = aStream.ReadLine(aLine);
+ }
+ maPresetDataMap[StaticTokenMap::get().getTokenFromUnicode(aName)] = aPropertyMap;
+}
+
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/oox/source/drawingml/customshapeproperties.cxx b/oox/source/drawingml/customshapeproperties.cxx
index cfaec25460dd..229251ee0838 100644
--- a/oox/source/drawingml/customshapeproperties.cxx
+++ b/oox/source/drawingml/customshapeproperties.cxx
@@ -91,6 +91,7 @@ sal_Int32 CustomShapeProperties::GetCustomShapeGuideValue( const std::vector< Cu
}
CustomShapeProperties::PresetsMap CustomShapeProperties::maPresetsMap;
+CustomShapeProperties::PresetDataMap CustomShapeProperties::maPresetDataMap;
static OUString GetConnectorShapeType( sal_Int32 nType )
{