/* -*- 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 "drawingml/customshapeproperties.hxx" #include #include "oox/token/tokenmap.hxx" #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(std::vector& rAdjustmentValues, const OString& rValue) { sal_Int32 nIndex = 0; drawing::EnhancedCustomShapeAdjustmentValue aAdjustmentValue; do { OString aToken = rValue.getToken(0, ',', nIndex).trim(); static const char aNamePrefix[] = "Name = \""; static const char aValuePrefix[] = "Value = (any) { (long) "; if (aToken.startsWith(aNamePrefix)) { OString aName = aToken.copy(strlen(aNamePrefix), aToken.getLength() - strlen(aNamePrefix) - strlen("\"")); aAdjustmentValue.Name = OUString::fromUtf8(aName); } else if (aToken.startsWith(aValuePrefix)) { OString aValue = aToken.copy(strlen(aValuePrefix), aToken.getLength() - strlen(aValuePrefix) - strlen(" }")); aAdjustmentValue.Value <<= 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(std::vector& 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 following here: First.Value, First.Type, Second.Value, Second.Type static const char aExpectedFVPrefix[] = "First = (com.sun.star.drawing.EnhancedCustomShapeParameter) { Value = (any) { (long) "; assert(aToken.startsWith(aExpectedFVPrefix)); sal_Int32 nIndex = strlen(aExpectedFVPrefix); aPair.First.Value <<= static_cast(aToken.getToken(0, '}', nIndex).toInt32()); static const char aExpectedFTPrefix[] = ", Type = (short) "; aToken = aToken.copy(nIndex); assert(aToken.startsWith(aExpectedFTPrefix)); nIndex = strlen(aExpectedFTPrefix); aPair.First.Type = static_cast(aToken.getToken(0, '}', nIndex).toInt32()); static const char aExpectedSVPrefix[] = ", Second = (com.sun.star.drawing.EnhancedCustomShapeParameter) { Value = (any) { (long) "; aToken = aToken.copy(nIndex); assert(aToken.startsWith(aExpectedSVPrefix)); nIndex = strlen(aExpectedSVPrefix); aPair.Second.Value <<= static_cast(aToken.getToken(0, '}', nIndex).toInt32()); static const char aExpectedSTPrefix[] = ", Type = (short) "; aToken = aToken.copy(nIndex); assert(aToken.startsWith(aExpectedSTPrefix)); nIndex = strlen(aExpectedSTPrefix); 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 following here: Command, Count static const char aExpectedCommandPrefix[] = "Command = (short) "; assert(aToken.startsWith(aExpectedCommandPrefix)); sal_Int32 nIndex = strlen(aExpectedCommandPrefix); aSegment.Command = static_cast(aToken.getToken(0, ',', nIndex).toInt32()); static const char aExpectedCountPrefix[] = " Count = (short) "; aToken = aToken.copy(nIndex); assert(aToken.startsWith(aExpectedCountPrefix)); nIndex = strlen(aExpectedCountPrefix); 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 following here: X, Y, Width, Height static const char aExpectedXPrefix[] = "X = (long) "; assert(aToken.startsWith(aExpectedXPrefix)); sal_Int32 nIndex = strlen(aExpectedXPrefix); aRectangle.X = aToken.getToken(0, ',', nIndex).toInt32(); static const char aExpectedYPrefix[] = " Y = (long) "; aToken = aToken.copy(nIndex); assert(aToken.startsWith(aExpectedYPrefix)); nIndex = strlen(aExpectedYPrefix); aRectangle.Y = aToken.getToken(0, ',', nIndex).toInt32(); static const char aExpectedWidthPrefix[] = " Width = (long) "; aToken = aToken.copy(nIndex); assert(aToken.startsWith(aExpectedWidthPrefix)); nIndex = strlen(aExpectedWidthPrefix); aRectangle.Width = aToken.getToken(0, ',', nIndex).toInt32(); static const char aExpectedHeightPrefix[] = " Height = (long) "; aToken = aToken.copy(nIndex); assert(aToken.startsWith(aExpectedHeightPrefix)); nIndex = strlen(aExpectedHeightPrefix); aRectangle.Height = aToken.copy(nIndex).toInt32(); return aRectangle; } awt::Size lcl_parseSize(const OString& rValue) { awt::Size aSize; OString aToken = rValue; // We expect the following here: Width, Height static const char aExpectedWidthPrefix[] = "Width = (long) "; assert(aToken.startsWith(aExpectedWidthPrefix)); sal_Int32 nIndex = strlen(aExpectedWidthPrefix); aSize.Width = aToken.getToken(0, ',', nIndex).toInt32(); static const char aExpectedHeightPrefix[] = " Height = (long) "; aToken = aToken.copy(nIndex); assert(aToken.startsWith(aExpectedHeightPrefix)); nIndex = strlen(aExpectedHeightPrefix); aSize.Height = 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 char aExpectedPrefix[] = "TopLeft = (com.sun.star.drawing.EnhancedCustomShapeParameterPair) { "; if (aToken.startsWith(aExpectedPrefix)) { aToken = aToken.copy(strlen(aExpectedPrefix), aToken.getLength() - strlen(aExpectedPrefix) - strlen(" }")); aTextFrame.TopLeft = lcl_parseEnhancedCustomShapeParameterPair(aToken); } else SAL_WARN("oox", "lcl_parseEnhancedCustomShapeTextFrame: unexpected token: " << aToken); nStart = i + strlen(", "); } } OString aToken = rValue.copy(nStart); static const char aExpectedPrefix[] = "BottomRight = (com.sun.star.drawing.EnhancedCustomShapeParameterPair) { "; if (aToken.startsWith(aExpectedPrefix)) { aToken = aToken.copy(strlen(aExpectedPrefix), aToken.getLength() - strlen(aExpectedPrefix) - 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(std::vector& 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 char aExpectedPrefix[] = "Value = (any) { (com.sun.star.drawing.EnhancedCustomShapeParameterPair) { "; if (aToken.startsWith(aExpectedPrefix)) { aToken = aToken.copy(strlen(aExpectedPrefix), aToken.getLength() - strlen(aExpectedPrefix) - strlen(" } }")); beans::PropertyValue aPropertyValue; aPropertyValue.Name = "Position"; aPropertyValue.Value <<= 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(std::vector& 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 char aExpectedPrefix[] = "Value = (any) { (com.sun.star.drawing.EnhancedCustomShapeParameter) { "; if (aToken.startsWith(aExpectedPrefix)) { drawing::EnhancedCustomShapeParameter aParameter; aToken = aToken.copy(strlen(aExpectedPrefix), aToken.getLength() - strlen(aExpectedPrefix) - strlen(" } }")); // We expect the following here: Value and Type static const char aExpectedVPrefix[] = "Value = (any) { (long) "; assert(aToken.startsWith(aExpectedVPrefix)); sal_Int32 nIndex = strlen(aExpectedVPrefix); aParameter.Value <<= aToken.getToken(0, '}', nIndex).toInt32(); static const char aExpectedTPrefix[] = ", Type = (short) "; aToken = aToken.copy(nIndex); assert(aToken.startsWith(aExpectedTPrefix)); nIndex = strlen(aExpectedTPrefix); aParameter.Type = static_cast(aToken.getToken(0, '}', nIndex).toInt32()); beans::PropertyValue aPropertyValue; aPropertyValue.Name = rName; aPropertyValue.Value <<= 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(std::vector& rHandle, const OString& rValue, const OUString& rName) { static const char aPrefix[] = "\", Handle = (long) 0, Value = (any) { (long) "; const sal_Int32 nCheck= SAL_N_ELEMENTS(aPrefix) - 1; const sal_Int32 nStart= SAL_N_ELEMENTS("Name = \"") - 1 + rName.getLength(); if (rValue.copy(nStart, nCheck).equalsL(aPrefix, nCheck)) { sal_Int32 nIndex = nStart + nCheck; beans::PropertyValue aPropertyValue; aPropertyValue.Name = rName; // We only expect a Value here aPropertyValue.Value <<= 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) { std::vector 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 if (aToken.startsWith("Name = \"RefR\"")) lcl_parseHandleRef(aRet, aToken, "RefR"); else if (aToken.startsWith("Name = \"RefAngle\"")) lcl_parseHandleRef(aRet, aToken, "RefAngle"); else SAL_WARN("oox", "lcl_parseHandle: unexpected token: " << aToken); } } } return comphelper::containerToSequence(aRet); } void lcl_parseHandles(std::vector< 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(std::vector& 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(OUString::fromUtf8(rValue.copy(nStart + strlen("\""), i - nStart - strlen("\"")))); } } } void lcl_parsePathCoordinateValues(std::vector& rPath, const OString& rValue) { std::vector 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 <<= comphelper::containerToSequence(aPairs); 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(std::vector& 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 char aExpectedPrefix[] = "Value = (any) { ([]com.sun.star.drawing.EnhancedCustomShapeParameterPair) { "; if (aToken.startsWith(aExpectedPrefix)) { aToken = aToken.copy(strlen(aExpectedPrefix), aToken.getLength() - strlen(aExpectedPrefix) - 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(std::vector& rPath, const OString& rValue) { std::vector 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 <<= comphelper::containerToSequence(aSegments); 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(std::vector& 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 char aExpectedPrefix[] = "Value = (any) { ([]com.sun.star.drawing.EnhancedCustomShapeSegment) { "; if (aToken.startsWith(aExpectedPrefix)) { aToken = aToken.copy(strlen(aExpectedPrefix), aToken.getLength() - strlen(aExpectedPrefix) - 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(std::vector& rPath, const OString& rValue) { std::vector 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 <<= comphelper::containerToSequence(aTextFrames); 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(std::vector& 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 char aExpectedPrefix[] = "Value = (any) { ([]com.sun.star.drawing.EnhancedCustomShapeTextFrame) { "; if (aToken.startsWith(aExpectedPrefix)) { aToken = aToken.copy(strlen(aExpectedPrefix), aToken.getLength() - strlen(aExpectedPrefix) - 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(std::vector& rPath, const OString& rValue) { std::vector 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 <<= comphelper::containerToSequence(aSizes); rPath.push_back(aPropertyValue); } void lcl_parsePathSubViewSize(std::vector& 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 char aExpectedPrefix[] = "Value = (any) { ([]com.sun.star.awt.Size) { "; if (aToken.startsWith(aExpectedPrefix)) { aToken = aToken.copy(strlen(aExpectedPrefix), aToken.getLength() - strlen(aExpectedPrefix) - 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(std::vector& 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, StreamMode::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 char aCommentPrefix[] = "/* "; if (aLine.startsWith(aCommentPrefix)) { if (bFirst) bFirst = false; else maPresetDataMap[TokenMap::getTokenFromUnicode(aName)] = aPropertyMap; aName = OUString::fromUtf8(aLine.copy(strlen(aCommentPrefix), aLine.getLength() - strlen(aCommentPrefix) - strlen(" */"))); } else { if (aLine == "AdjustmentValues") { aStream.ReadLine(aLine); if (aLine != "([]com.sun.star.drawing.EnhancedCustomShapeAdjustmentValue) {}") { std::vector 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, comphelper::containerToSequence(aAdjustmentValues)); } else aPropertyMap.setProperty(PROP_AdjustmentValues, uno::Sequence(0)); } else if (aLine == "Equations") { aStream.ReadLine(aLine); if (aLine != "([]string) {}") { std::vector 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, comphelper::containerToSequence(aEquations)); } else aPropertyMap.setProperty(PROP_Equations, uno::Sequence(0)); } else if (aLine == "Handles") { aStream.ReadLine(aLine); if (aLine != "([][]com.sun.star.beans.PropertyValue) {}") { std::vector< 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, comphelper::containerToSequence(aHandles)); } 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)); std::vector aPathValue; OString aValue = aLine.copy(aExpectedPrefix.getLength(), aLine.getLength() - aExpectedPrefix.getLength() - strlen(" }")); lcl_parsePath(aPathValue, aValue); aPropertyMap.setProperty(PROP_Path, comphelper::containerToSequence(aPathValue)); } 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[TokenMap::getTokenFromUnicode(aName)] = aPropertyMap; } } } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */