/* -*- 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 #include #include #include #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 #include #include #include #include #include #include #include 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& 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& 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(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(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(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(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(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(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(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(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(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(aToken.copy(nIndex).toInt32()); return aRectangle; } awt::Size lcl_parseSize(const OString& rValue) { awt::Size aSize; OString aToken = rValue; // We expect the followings here: Width, Height static const OString aExpectedWidthPrefix = "Width = (long) "; assert(aToken.startsWith(aExpectedWidthPrefix)); sal_Int32 nIndex = aExpectedWidthPrefix.getLength(); aSize.Width = static_cast(aToken.getToken(0, ',', nIndex).toInt32()); static const OString aExpectedHeightPrefix = " Height = (long) "; aToken = aToken.copy(nIndex); assert(aToken.startsWith(aExpectedHeightPrefix)); nIndex = aExpectedHeightPrefix.getLength(); aSize.Height = static_cast(aToken.copy(nIndex).toInt32()); return aSize; } 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& 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& 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(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_parseHandleRef(comphelper::SequenceAsVector& rHandle, const OString& rValue, const OUString& rName) { static const OString aExpectedXPrefix("Name = \"RefX\", Handle = (long) 0, Value = (any) { (long) "); static const OString aExpectedYPrefix("Name = \"RefY\", Handle = (long) 0, Value = (any) { (long) "); if (rValue.startsWith(aExpectedXPrefix) || rValue.startsWith(aExpectedYPrefix)) { sal_Int32 nIndex = aExpectedXPrefix.getLength(); beans::PropertyValue aPropertyValue; aPropertyValue.Name = rName; // We only expect a Value here aPropertyValue.Value = uno::makeAny(rValue.getToken(0, '}', nIndex).toInt32()); rHandle.push_back(aPropertyValue); } else SAL_WARN("oox", "lcl_parseHandleRef: unexpected value: " << rValue); } uno::Sequence lcl_parseHandle(const OString& rValue) { comphelper::SequenceAsVector 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 = \"RangeXMaximum\"")) lcl_parseHandleRange(aRet, aToken, "RangeXMaximum"); else if (aToken.startsWith("Name = \"RangeXMinimum\"")) lcl_parseHandleRange(aRet, aToken, "RangeXMinimum"); 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 = \"RadiusRangeMaximum\"")) lcl_parseHandleRange(aRet, aToken, "RadiusRangeMaximum"); else if (aToken.startsWith("Name = \"RadiusRangeMinimum\"")) lcl_parseHandleRange(aRet, aToken, "RadiusRangeMinimum"); else if (aToken.startsWith("Name = \"RefX\"")) lcl_parseHandleRef(aRet, aToken, "RefX"); else if (aToken.startsWith("Name = \"RefY\"")) lcl_parseHandleRef(aRet, aToken, "RefY"); else SAL_WARN("oox", "lcl_parseHandle: unexpected token: " << aToken); } } } return aRet.getAsConstList(); } void lcl_parseHandles(comphelper::SequenceAsVector< uno::Sequence >& 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 aHandle = lcl_parseHandle(rValue.copy(nStart + strlen("{ "), i - nStart - strlen(" },"))); rHandles.push_back(aHandle); } } } } void lcl_parseEquations(comphelper::SequenceAsVector& 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& rPath, const OString& rValue) { comphelper::SequenceAsVector 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& 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& rPath, const OString& rValue) { comphelper::SequenceAsVector 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& 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& rPath, const OString& rValue) { comphelper::SequenceAsVector 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& 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_parsePathSubViewSizeValues(comphelper::SequenceAsVector& rPath, const OString& rValue) { comphelper::SequenceAsVector aSizes; 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) aSizes.push_back(lcl_parseSize(rValue.copy(nStart + strlen("{ "), i - nStart - strlen(" },")))); } } beans::PropertyValue aPropertyValue; aPropertyValue.Name = "SubViewSize"; aPropertyValue.Value = uno::makeAny(aSizes.getAsConstList()); rPath.push_back(aPropertyValue); } void lcl_parsePathSubViewSize(comphelper::SequenceAsVector& 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.awt.Size) { "); if (aToken.startsWith(aExpectedPrefix)) { aToken = aToken.copy(aExpectedPrefix.getLength(), aToken.getLength() - aExpectedPrefix.getLength() - strlen(" } }")); lcl_parsePathSubViewSizeValues(rPath, aToken); } else if (!aToken.startsWith("Name =") && !aToken.startsWith("Handle =")) SAL_WARN("oox", "lcl_parsePathSubViewSize: unexpected token: " << aToken); nStart = i + strlen(", "); } } } void lcl_parsePath(comphelper::SequenceAsVector& 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 if (aToken.startsWith("Name = \"SubViewSize\"")) lcl_parsePathSubViewSize(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; bool bFirst = true; while (bNotDone) { static const OString aCommentPrefix("/* "); if (aLine.startsWith(aCommentPrefix)) { if (bFirst) bFirst = false; else maPresetDataMap[StaticTokenMap::get().getTokenFromUnicode(aName)] = aPropertyMap; aName = OStringToOUString(aLine.copy(aCommentPrefix.getLength(), aLine.getLength() - aCommentPrefix.getLength() - strlen(" */")), RTL_TEXTENCODING_UTF8); } else { if (aLine == "AdjustmentValues") { aStream.ReadLine(aLine); if (aLine != "([]com.sun.star.drawing.EnhancedCustomShapeAdjustmentValue) {}") { comphelper::SequenceAsVector aAdjustmentValues; OString aExpectedPrefix("([]com.sun.star.drawing.EnhancedCustomShapeAdjustmentValue) { "); assert(aLine.startsWith(aExpectedPrefix)); OString aValue = aLine.copy(aExpectedPrefix.getLength(), aLine.getLength() - aExpectedPrefix.getLength() - strlen(" }")); lcl_parseAdjustmentValues(aAdjustmentValues, aValue); aPropertyMap.setProperty(PROP_AdjustmentValues, aAdjustmentValues.getAsConstList()); } else aPropertyMap.setProperty(PROP_AdjustmentValues, uno::Sequence(0)); } else if (aLine == "Equations") { aStream.ReadLine(aLine); if (aLine != "([]string) {}") { comphelper::SequenceAsVector aEquations; OString aExpectedPrefix("([]string) { "); assert(aLine.startsWith(aExpectedPrefix)); OString aValue = aLine.copy(aExpectedPrefix.getLength(), aLine.getLength() - aExpectedPrefix.getLength() - strlen(" }")); lcl_parseEquations(aEquations, aValue); aPropertyMap.setProperty(PROP_Equations, aEquations.getAsConstList()); } else aPropertyMap.setProperty(PROP_Equations, uno::Sequence(0)); } else if (aLine == "Handles") { aStream.ReadLine(aLine); if (aLine != "([][]com.sun.star.beans.PropertyValue) {}") { comphelper::SequenceAsVector< uno::Sequence > aHandles; OString aExpectedPrefix("([][]com.sun.star.beans.PropertyValue) { "); assert(aLine.startsWith(aExpectedPrefix)); OString aValue = aLine.copy(aExpectedPrefix.getLength(), aLine.getLength() - aExpectedPrefix.getLength() - strlen(" }")); lcl_parseHandles(aHandles, aValue); aPropertyMap.setProperty(PROP_Handles, aHandles.getAsConstList()); } else aPropertyMap.setProperty(PROP_Handles, uno::Sequence(0)); } else if (aLine == "MirroredX") { aStream.ReadLine(aLine); if (aLine == "true" || aLine == "false") { aPropertyMap.setProperty(PROP_MirroredX, aLine == "true"); } 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, aLine == "true"); } 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 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: */