diff options
author | Miklos Vajna <vmiklos@collabora.co.uk> | 2014-04-17 14:49:35 +0200 |
---|---|---|
committer | Miklos Vajna <vmiklos@collabora.co.uk> | 2014-04-17 15:10:36 +0200 |
commit | d28b9e8fefa095471d1511c7948bcaf2a3473379 (patch) | |
tree | 813708edf2feab494244da4e5d1eb299c8eb082f | |
parent | fc7f66d00a1738ae52a1738f456f4a720740e6d7 (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.hxx | 3 | ||||
-rw-r--r-- | oox/Library_oox.mk | 1 | ||||
-rw-r--r-- | oox/source/drawingml/customshapepresetdata.cxx | 743 | ||||
-rw-r--r-- | oox/source/drawingml/customshapeproperties.cxx | 1 |
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 ) { |