Version 6.4.0.0.beta1, tag libreoffice-6.4.0.0.beta1
[LibreOffice.git] / oox / source / drawingml / customshapepresetdata.cxx
blob043b25cd633b88dccbfdfae653135f8200d49835
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 */
10 #include <config_folders.h>
11 #include <rtl/bootstrap.hxx>
12 #include <sal/log.hxx>
13 #include <tools/stream.hxx>
14 #include <comphelper/sequence.hxx>
16 #include <drawingml/customshapeproperties.hxx>
17 #include <oox/token/properties.hxx>
18 #include <oox/token/tokenmap.hxx>
19 #include <com/sun/star/awt/Rectangle.hpp>
20 #include <com/sun/star/beans/PropertyValue.hpp>
21 #include <com/sun/star/drawing/EnhancedCustomShapeTextFrame.hpp>
22 #include <com/sun/star/drawing/EnhancedCustomShapeAdjustmentValue.hpp>
24 using namespace ::com::sun::star;
26 namespace
29 // Parses a string like: Value = (any) { (long) 19098 }, State = (com.sun.star.beans.PropertyState) DIRECT_VALUE, Name = "adj"
30 void lcl_parseAdjustmentValue(std::vector<drawing::EnhancedCustomShapeAdjustmentValue>& rAdjustmentValues, const OString& rValue)
32 sal_Int32 nIndex = 0;
33 drawing::EnhancedCustomShapeAdjustmentValue aAdjustmentValue;
36 OString aToken = rValue.getToken(0, ',', nIndex).trim();
37 static const char aNamePrefix[] = "Name = \"";
38 static const char aValuePrefix[] = "Value = (any) { (long) ";
39 if (aToken.startsWith(aNamePrefix))
41 OString aName = aToken.copy(strlen(aNamePrefix), aToken.getLength() - strlen(aNamePrefix) - strlen("\""));
42 aAdjustmentValue.Name = OUString::fromUtf8(aName);
44 else if (aToken.startsWith(aValuePrefix))
46 OString aValue = aToken.copy(strlen(aValuePrefix), aToken.getLength() - strlen(aValuePrefix) - strlen(" }"));
47 aAdjustmentValue.Value <<= aValue.toInt32();
49 else if (!aToken.startsWith("State = "))
50 SAL_WARN("oox", "lcl_parseAdjustmentValue: unexpected prefix: " << aToken);
52 while (nIndex >= 0);
53 rAdjustmentValues.push_back(aAdjustmentValue);
56 // Parses a string like: { Value = (any) { (long) 19098 }, State = (com.sun.star.beans.PropertyState) DIRECT_VALUE, Name = "adj" }, { Value = ..., State = ..., Name = ... }
57 void lcl_parseAdjustmentValues(std::vector<drawing::EnhancedCustomShapeAdjustmentValue>& rAdjustmentValues, const OString& rValue)
59 sal_Int32 nLevel = 0;
60 sal_Int32 nStart = 0;
61 for (sal_Int32 i = 0; i < rValue.getLength(); ++i)
63 if (rValue[i] == '{')
65 if (!nLevel)
66 nStart = i;
67 nLevel++;
69 else if (rValue[i] == '}')
71 nLevel--;
72 if (!nLevel)
74 lcl_parseAdjustmentValue(rAdjustmentValues, rValue.copy(nStart + strlen("{ "), i - nStart - strlen(" },")));
80 drawing::EnhancedCustomShapeParameterPair lcl_parseEnhancedCustomShapeParameterPair(const OString& rValue)
82 drawing::EnhancedCustomShapeParameterPair aPair;
83 // We expect the following here: First.Value, First.Type, Second.Value, Second.Type
84 static const char aExpectedFVPrefix[] = "First = (com.sun.star.drawing.EnhancedCustomShapeParameter) { Value = (any) { (long) ";
85 assert(rValue.startsWith(aExpectedFVPrefix));
86 sal_Int32 nIndex = strlen(aExpectedFVPrefix);
87 aPair.First.Value <<= static_cast<sal_uInt32>(rValue.getToken(0, '}', nIndex).toInt32());
89 static const char aExpectedFTPrefix[] = ", Type = (short) ";
90 assert(nIndex>=0 && rValue.match(aExpectedFTPrefix, nIndex));
91 nIndex += strlen(aExpectedFTPrefix);
92 aPair.First.Type = static_cast<sal_uInt16>(rValue.getToken(0, '}', nIndex).toInt32());
94 static const char aExpectedSVPrefix[] = ", Second = (com.sun.star.drawing.EnhancedCustomShapeParameter) { Value = (any) { (long) ";
95 assert(nIndex>=0 && rValue.match(aExpectedSVPrefix, nIndex));
96 nIndex += strlen(aExpectedSVPrefix);
97 aPair.Second.Value <<= static_cast<sal_uInt32>(rValue.getToken(0, '}', nIndex).toInt32());
99 static const char aExpectedSTPrefix[] = ", Type = (short) ";
100 assert(nIndex>=0 && rValue.match(aExpectedSTPrefix, nIndex));
101 nIndex += strlen(aExpectedSTPrefix);
102 aPair.Second.Type = static_cast<sal_uInt16>(rValue.getToken(0, '}', nIndex).toInt32());
103 return aPair;
106 drawing::EnhancedCustomShapeSegment lcl_parseEnhancedCustomShapeSegment(const OString& rValue)
108 drawing::EnhancedCustomShapeSegment aSegment;
109 // We expect the following here: Command, Count
110 static const char aExpectedCommandPrefix[] = "Command = (short) ";
111 assert(rValue.startsWith(aExpectedCommandPrefix));
112 sal_Int32 nIndex = strlen(aExpectedCommandPrefix);
113 aSegment.Command = static_cast<sal_Int16>(rValue.getToken(0, ',', nIndex).toInt32());
115 static const char aExpectedCountPrefix[] = " Count = (short) ";
116 assert(nIndex>=0 && rValue.match(aExpectedCountPrefix, nIndex));
117 nIndex += strlen(aExpectedCountPrefix);
118 aSegment.Count = static_cast<sal_Int16>(rValue.getToken(0, '}', nIndex).toInt32());
119 return aSegment;
122 awt::Rectangle lcl_parseRectangle(const OString& rValue)
124 awt::Rectangle aRectangle;
125 // We expect the following here: X, Y, Width, Height
126 static const char aExpectedXPrefix[] = "X = (long) ";
127 assert(rValue.startsWith(aExpectedXPrefix));
128 sal_Int32 nIndex = strlen(aExpectedXPrefix);
129 aRectangle.X = rValue.getToken(0, ',', nIndex).toInt32();
131 static const char aExpectedYPrefix[] = " Y = (long) ";
132 assert(nIndex>=0 && rValue.match(aExpectedYPrefix, nIndex));
133 nIndex += strlen(aExpectedYPrefix);
134 aRectangle.Y = rValue.getToken(0, ',', nIndex).toInt32();
136 static const char aExpectedWidthPrefix[] = " Width = (long) ";
137 assert(nIndex>=0 && rValue.match(aExpectedWidthPrefix, nIndex));
138 nIndex += strlen(aExpectedWidthPrefix);
139 aRectangle.Width = rValue.getToken(0, ',', nIndex).toInt32();
141 static const char aExpectedHeightPrefix[] = " Height = (long) ";
142 assert(nIndex>=0 && rValue.match(aExpectedHeightPrefix, nIndex));
143 nIndex += strlen(aExpectedHeightPrefix);
144 aRectangle.Height = rValue.copy(nIndex).toInt32();
146 return aRectangle;
149 awt::Size lcl_parseSize(const OString& rValue)
151 awt::Size aSize;
152 // We expect the following here: Width, Height
153 static const char aExpectedWidthPrefix[] = "Width = (long) ";
154 assert(rValue.startsWith(aExpectedWidthPrefix));
155 sal_Int32 nIndex = strlen(aExpectedWidthPrefix);
156 aSize.Width = rValue.getToken(0, ',', nIndex).toInt32();
158 static const char aExpectedHeightPrefix[] = " Height = (long) ";
159 assert(nIndex>=0 && rValue.match(aExpectedHeightPrefix, nIndex));
160 nIndex += strlen(aExpectedHeightPrefix);
161 aSize.Height = rValue.copy(nIndex).toInt32();
163 return aSize;
166 drawing::EnhancedCustomShapeTextFrame lcl_parseEnhancedCustomShapeTextFrame(const OString& rValue)
168 drawing::EnhancedCustomShapeTextFrame aTextFrame;
169 sal_Int32 nLevel = 0;
170 bool bIgnore = false;
171 sal_Int32 nStart = 0;
172 for (sal_Int32 i = 0; i < rValue.getLength(); ++i)
174 if (rValue[i] == '{')
176 if (!nLevel)
177 bIgnore = true;
178 nLevel++;
180 else if (rValue[i] == '}')
182 nLevel--;
183 if (!nLevel)
184 bIgnore = false;
186 else if (rValue[i] == ',' && !bIgnore)
188 OString aToken = rValue.copy(nStart, i - nStart);
189 static const char aExpectedPrefix[] = "TopLeft = (com.sun.star.drawing.EnhancedCustomShapeParameterPair) { ";
190 if (aToken.startsWith(aExpectedPrefix))
192 aToken = aToken.copy(strlen(aExpectedPrefix), aToken.getLength() - strlen(aExpectedPrefix) - strlen(" }"));
193 aTextFrame.TopLeft = lcl_parseEnhancedCustomShapeParameterPair(aToken);
195 else
196 SAL_WARN("oox", "lcl_parseEnhancedCustomShapeTextFrame: unexpected token: " << aToken);
197 nStart = i + strlen(", ");
201 OString aToken = rValue.copy(nStart);
202 static const char aExpectedPrefix[] = "BottomRight = (com.sun.star.drawing.EnhancedCustomShapeParameterPair) { ";
203 if (aToken.startsWith(aExpectedPrefix))
205 aToken = aToken.copy(strlen(aExpectedPrefix), aToken.getLength() - strlen(aExpectedPrefix) - strlen(" }"));
206 aTextFrame.BottomRight = lcl_parseEnhancedCustomShapeParameterPair(aToken);
208 else
209 SAL_WARN("oox", "lcl_parseEnhancedCustomShapeTextFrame: unexpected token at the end: " << aToken);
211 return aTextFrame;
214 // Parses a string like: Name = "Position", Handle = (long) 0, Value = (any) { ... }, State = (com.sun.star.beans.PropertyState) DIRECT_VALUE
215 // where "{ ... }" may contain "," as well.
216 void lcl_parseHandlePosition(std::vector<beans::PropertyValue>& rHandle, const OString& rValue)
218 sal_Int32 nLevel = 0;
219 bool bIgnore = false;
220 sal_Int32 nStart = 0;
221 for (sal_Int32 i = 0; i < rValue.getLength(); ++i)
223 if (rValue[i] == '{')
225 if (!nLevel)
226 bIgnore = true;
227 nLevel++;
229 else if (rValue[i] == '}')
231 nLevel--;
232 if (!nLevel)
233 bIgnore = false;
235 else if (rValue[i] == ',' && !bIgnore)
237 OString aToken = rValue.copy(nStart, i - nStart);
238 static const char aExpectedPrefix[] = "Value = (any) { (com.sun.star.drawing.EnhancedCustomShapeParameterPair) { ";
239 if (aToken.startsWith(aExpectedPrefix))
241 aToken = aToken.copy(strlen(aExpectedPrefix), aToken.getLength() - strlen(aExpectedPrefix) - strlen(" } }"));
243 beans::PropertyValue aPropertyValue;
244 aPropertyValue.Name = "Position";
245 aPropertyValue.Value <<= lcl_parseEnhancedCustomShapeParameterPair(aToken);
246 rHandle.push_back(aPropertyValue);
248 else if (!aToken.startsWith("Name =") && !aToken.startsWith("Handle ="))
249 SAL_WARN("oox", "lcl_parseHandlePosition: unexpected token: " << aToken);
250 nStart = i + strlen(", ");
255 // Parses a string like: Name = "RangeYMaximum", Handle = (long) 0, Value = (any) { ... }, State = (com.sun.star.beans.PropertyState) DIRECT_VALUE
256 // where "{ ... }" may contain "," as well.
257 void lcl_parseHandleRange(std::vector<beans::PropertyValue>& rHandle, const OString& rValue, const OUString& rName)
259 sal_Int32 nLevel = 0;
260 bool bIgnore = false;
261 sal_Int32 nStart = 0;
262 for (sal_Int32 i = 0; i < rValue.getLength(); ++i)
264 if (rValue[i] == '{')
266 if (!nLevel)
267 bIgnore = true;
268 nLevel++;
270 else if (rValue[i] == '}')
272 nLevel--;
273 if (!nLevel)
274 bIgnore = false;
276 else if (rValue[i] == ',' && !bIgnore)
278 static const char aExpectedPrefix[] = "Value = (any) { (com.sun.star.drawing.EnhancedCustomShapeParameter) { ";
279 if (rValue.match(aExpectedPrefix, nStart))
281 drawing::EnhancedCustomShapeParameter aParameter;
282 sal_Int32 nIndex{ nStart + static_cast<sal_Int32>(strlen(aExpectedPrefix)) };
283 // We expect the following here: Value and Type
284 static const char aExpectedVPrefix[] = "Value = (any) { (long) ";
285 assert(rValue.match(aExpectedVPrefix, nIndex));
286 nIndex += strlen(aExpectedVPrefix);
287 aParameter.Value <<= rValue.getToken(0, '}', nIndex).toInt32();
289 static const char aExpectedTPrefix[] = ", Type = (short) ";
290 assert(nIndex>=0 && rValue.match(aExpectedTPrefix, nIndex));
291 nIndex += strlen(aExpectedTPrefix);
292 aParameter.Type = static_cast<sal_Int16>(rValue.getToken(0, '}', nIndex).toInt32());
294 beans::PropertyValue aPropertyValue;
295 aPropertyValue.Name = rName;
296 aPropertyValue.Value <<= aParameter;
297 rHandle.push_back(aPropertyValue);
299 else if (!rValue.match("Name =", nStart) && !rValue.match("Handle =", nStart))
300 SAL_WARN("oox", "lcl_parseHandleRange: unexpected token: " << rValue.copy(nStart, i - nStart));
301 nStart = i + strlen(", ");
306 // Parses a string like: Name = "RefY", Handle = (long) 0, Value = (any) { (long) 0 }, State = (com.sun.star.beans.PropertyState) DIRECT_VALUE
307 void lcl_parseHandleRef(std::vector<beans::PropertyValue>& rHandle, const OString& rValue, const OUString& rName)
309 static const char aPrefix[] = "\", Handle = (long) 0, Value = (any) { (long) ";
310 const sal_Int32 nCheck= SAL_N_ELEMENTS(aPrefix) - 1;
311 const sal_Int32 nStart= SAL_N_ELEMENTS("Name = \"") - 1 + rName.getLength();
313 if (rValue.copy(nStart, nCheck).equalsL(aPrefix, nCheck))
315 sal_Int32 nIndex = nStart + nCheck;
316 beans::PropertyValue aPropertyValue;
317 aPropertyValue.Name = rName;
318 // We only expect a Value here
319 aPropertyValue.Value <<= rValue.getToken(0, '}', nIndex).toInt32();
320 rHandle.push_back(aPropertyValue);
322 else
323 SAL_WARN("oox", "lcl_parseHandleRef: unexpected value: " << rValue);
326 uno::Sequence<beans::PropertyValue> lcl_parseHandle(const OString& rValue)
328 std::vector<beans::PropertyValue> aRet;
329 sal_Int32 nLevel = 0;
330 sal_Int32 nStart = 0;
331 for (sal_Int32 i = 0; i < rValue.getLength(); ++i)
333 if (rValue[i] == '{')
335 if (!nLevel)
336 nStart = i;
337 nLevel++;
339 else if (rValue[i] == '}')
341 nLevel--;
342 if (!nLevel)
344 OString aToken = rValue.copy(nStart + strlen("{ "), i - nStart - strlen(" },"));
345 if (aToken.startsWith("Name = \"Position\""))
346 lcl_parseHandlePosition(aRet, aToken);
347 else if (aToken.startsWith("Name = \"RangeXMaximum\""))
348 lcl_parseHandleRange(aRet, aToken, "RangeXMaximum");
349 else if (aToken.startsWith("Name = \"RangeXMinimum\""))
350 lcl_parseHandleRange(aRet, aToken, "RangeXMinimum");
351 else if (aToken.startsWith("Name = \"RangeYMaximum\""))
352 lcl_parseHandleRange(aRet, aToken, "RangeYMaximum");
353 else if (aToken.startsWith("Name = \"RangeYMinimum\""))
354 lcl_parseHandleRange(aRet, aToken, "RangeYMinimum");
355 else if (aToken.startsWith("Name = \"RadiusRangeMaximum\""))
356 lcl_parseHandleRange(aRet, aToken, "RadiusRangeMaximum");
357 else if (aToken.startsWith("Name = \"RadiusRangeMinimum\""))
358 lcl_parseHandleRange(aRet, aToken, "RadiusRangeMinimum");
359 else if (aToken.startsWith("Name = \"RefX\""))
360 lcl_parseHandleRef(aRet, aToken, "RefX");
361 else if (aToken.startsWith("Name = \"RefY\""))
362 lcl_parseHandleRef(aRet, aToken, "RefY");
363 else if (aToken.startsWith("Name = \"RefR\""))
364 lcl_parseHandleRef(aRet, aToken, "RefR");
365 else if (aToken.startsWith("Name = \"RefAngle\""))
366 lcl_parseHandleRef(aRet, aToken, "RefAngle");
367 else
368 SAL_WARN("oox", "lcl_parseHandle: unexpected token: " << aToken);
372 return comphelper::containerToSequence(aRet);
375 void lcl_parseHandles(std::vector< uno::Sequence<beans::PropertyValue> >& rHandles, const OString& rValue)
377 sal_Int32 nLevel = 0;
378 sal_Int32 nStart = 0;
379 for (sal_Int32 i = 0; i < rValue.getLength(); ++i)
381 if (rValue[i] == '{')
383 if (!nLevel)
384 nStart = i;
385 nLevel++;
387 else if (rValue[i] == '}')
389 nLevel--;
390 if (!nLevel)
392 uno::Sequence<beans::PropertyValue> aHandle = lcl_parseHandle(rValue.copy(nStart + strlen("{ "), i - nStart - strlen(" },")));
393 rHandles.push_back(aHandle);
399 void lcl_parseEquations(std::vector<OUString>& rEquations, const OString& rValue)
401 bool bInString = false;
402 sal_Int32 nStart = 0;
403 for (sal_Int32 i = 0; i < rValue.getLength(); ++i)
405 if (rValue[i] == '"' && !bInString)
407 nStart = i;
408 bInString = true;
410 else if (rValue[i] == '"' && bInString)
412 bInString = false;
413 rEquations.push_back(OUString::fromUtf8(rValue.copy(nStart + strlen("\""), i - nStart - strlen("\""))));
418 void lcl_parsePathCoordinateValues(std::vector<beans::PropertyValue>& rPath, const OString& rValue)
420 std::vector<drawing::EnhancedCustomShapeParameterPair> aPairs;
421 sal_Int32 nLevel = 0;
422 sal_Int32 nStart = 0;
423 for (sal_Int32 i = 0; i < rValue.getLength(); ++i)
425 if (rValue[i] == '{')
427 if (!nLevel)
428 nStart = i;
429 nLevel++;
431 else if (rValue[i] == '}')
433 nLevel--;
434 if (!nLevel)
435 aPairs.push_back(lcl_parseEnhancedCustomShapeParameterPair(rValue.copy(nStart + strlen("{ "), i - nStart - strlen(" },"))));
439 beans::PropertyValue aPropertyValue;
440 aPropertyValue.Name = "Coordinates";
441 aPropertyValue.Value <<= comphelper::containerToSequence(aPairs);
442 rPath.push_back(aPropertyValue);
445 // Parses a string like: Name = "Coordinates", Handle = (long) 0, Value = (any) { ... }, State = (com.sun.star.beans.PropertyState) DIRECT_VALUE
446 // where "{ ... }" may contain "," as well.
447 void lcl_parsePathCoordinates(std::vector<beans::PropertyValue>& rPath, const OString& rValue)
449 sal_Int32 nLevel = 0;
450 bool bIgnore = false;
451 sal_Int32 nStart = 0;
452 for (sal_Int32 i = 0; i < rValue.getLength(); ++i)
454 if (rValue[i] == '{')
456 if (!nLevel)
457 bIgnore = true;
458 nLevel++;
460 else if (rValue[i] == '}')
462 nLevel--;
463 if (!nLevel)
464 bIgnore = false;
466 else if (rValue[i] == ',' && !bIgnore)
468 OString aToken = rValue.copy(nStart, i - nStart);
469 static const char aExpectedPrefix[] = "Value = (any) { ([]com.sun.star.drawing.EnhancedCustomShapeParameterPair) { ";
470 if (aToken.startsWith(aExpectedPrefix))
472 aToken = aToken.copy(strlen(aExpectedPrefix), aToken.getLength() - strlen(aExpectedPrefix) - strlen(" } }"));
473 lcl_parsePathCoordinateValues(rPath, aToken);
475 else if (!aToken.startsWith("Name =") && !aToken.startsWith("Handle ="))
476 SAL_WARN("oox", "lcl_parsePathCoordinates: unexpected token: " << aToken);
477 nStart = i + strlen(", ");
482 void lcl_parsePathSegmentValues(std::vector<beans::PropertyValue>& rPath, const OString& rValue)
484 std::vector<drawing::EnhancedCustomShapeSegment> aSegments;
485 sal_Int32 nLevel = 0;
486 sal_Int32 nStart = 0;
487 for (sal_Int32 i = 0; i < rValue.getLength(); ++i)
489 if (rValue[i] == '{')
491 if (!nLevel)
492 nStart = i;
493 nLevel++;
495 else if (rValue[i] == '}')
497 nLevel--;
498 if (!nLevel)
499 aSegments.push_back(lcl_parseEnhancedCustomShapeSegment(rValue.copy(nStart + strlen("{ "), i - nStart - strlen(" },"))));
503 beans::PropertyValue aPropertyValue;
504 aPropertyValue.Name = "Segments";
505 aPropertyValue.Value <<= comphelper::containerToSequence(aSegments);
506 rPath.push_back(aPropertyValue);
509 // Parses a string like: Name = "Segments", Handle = (long) 0, Value = (any) { ... }, State = (com.sun.star.beans.PropertyState) DIRECT_VALUE
510 // where "{ ... }" may contain "," as well.
511 void lcl_parsePathSegments(std::vector<beans::PropertyValue>& rPath, const OString& rValue)
513 sal_Int32 nLevel = 0;
514 bool bIgnore = false;
515 sal_Int32 nStart = 0;
516 for (sal_Int32 i = 0; i < rValue.getLength(); ++i)
518 if (rValue[i] == '{')
520 if (!nLevel)
521 bIgnore = true;
522 nLevel++;
524 else if (rValue[i] == '}')
526 nLevel--;
527 if (!nLevel)
528 bIgnore = false;
530 else if (rValue[i] == ',' && !bIgnore)
532 OString aToken = rValue.copy(nStart, i - nStart);
533 static const char aExpectedPrefix[] = "Value = (any) { ([]com.sun.star.drawing.EnhancedCustomShapeSegment) { ";
534 if (aToken.startsWith(aExpectedPrefix))
536 aToken = aToken.copy(strlen(aExpectedPrefix), aToken.getLength() - strlen(aExpectedPrefix) - strlen(" } }"));
537 lcl_parsePathSegmentValues(rPath, aToken);
539 else if (!aToken.startsWith("Name =") && !aToken.startsWith("Handle ="))
540 SAL_WARN("oox", "lcl_parsePathSegments: unexpected token: " << aToken);
541 nStart = i + strlen(", ");
546 void lcl_parsePathTextFrameValues(std::vector<beans::PropertyValue>& rPath, const OString& rValue)
548 std::vector<drawing::EnhancedCustomShapeTextFrame> aTextFrames;
549 sal_Int32 nLevel = 0;
550 sal_Int32 nStart = 0;
551 for (sal_Int32 i = 0; i < rValue.getLength(); ++i)
553 if (rValue[i] == '{')
555 if (!nLevel)
556 nStart = i;
557 nLevel++;
559 else if (rValue[i] == '}')
561 nLevel--;
562 if (!nLevel)
563 aTextFrames.push_back(lcl_parseEnhancedCustomShapeTextFrame(rValue.copy(nStart + strlen("{ "), i - nStart - strlen(" },"))));
567 beans::PropertyValue aPropertyValue;
568 aPropertyValue.Name = "TextFrames";
569 aPropertyValue.Value <<= comphelper::containerToSequence(aTextFrames);
570 rPath.push_back(aPropertyValue);
573 // Parses a string like: Name = "TextFrames", Handle = (long) 0, Value = (any) { ... }, State = (com.sun.star.beans.PropertyState) DIRECT_VALUE
574 // where "{ ... }" may contain "," as well.
575 void lcl_parsePathTextFrames(std::vector<beans::PropertyValue>& rPath, const OString& rValue)
577 sal_Int32 nLevel = 0;
578 bool bIgnore = false;
579 sal_Int32 nStart = 0;
580 for (sal_Int32 i = 0; i < rValue.getLength(); ++i)
582 if (rValue[i] == '{')
584 if (!nLevel)
585 bIgnore = true;
586 nLevel++;
588 else if (rValue[i] == '}')
590 nLevel--;
591 if (!nLevel)
592 bIgnore = false;
594 else if (rValue[i] == ',' && !bIgnore)
596 OString aToken = rValue.copy(nStart, i - nStart);
597 static const char aExpectedPrefix[] = "Value = (any) { ([]com.sun.star.drawing.EnhancedCustomShapeTextFrame) { ";
598 if (aToken.startsWith(aExpectedPrefix))
600 aToken = aToken.copy(strlen(aExpectedPrefix), aToken.getLength() - strlen(aExpectedPrefix) - strlen(" } }"));
601 lcl_parsePathTextFrameValues(rPath, aToken);
603 else if (!aToken.startsWith("Name =") && !aToken.startsWith("Handle ="))
604 SAL_WARN("oox", "lcl_parsePathTextFrames: unexpected token: " << aToken);
605 nStart = i + strlen(", ");
610 void lcl_parsePathSubViewSizeValues(std::vector<beans::PropertyValue>& rPath, const OString& rValue)
612 std::vector<awt::Size> aSizes;
613 sal_Int32 nLevel = 0;
614 sal_Int32 nStart = 0;
615 for (sal_Int32 i = 0; i < rValue.getLength(); ++i)
617 if (rValue[i] == '{')
619 if (!nLevel)
620 nStart = i;
621 nLevel++;
623 else if (rValue[i] == '}')
625 nLevel--;
626 if (!nLevel)
627 aSizes.push_back(lcl_parseSize(rValue.copy(nStart + strlen("{ "), i - nStart - strlen(" },"))));
631 beans::PropertyValue aPropertyValue;
632 aPropertyValue.Name = "SubViewSize";
633 aPropertyValue.Value <<= comphelper::containerToSequence(aSizes);
634 rPath.push_back(aPropertyValue);
637 void lcl_parsePathSubViewSize(std::vector<beans::PropertyValue>& rPath, const OString& rValue)
639 sal_Int32 nLevel = 0;
640 bool bIgnore = false;
641 sal_Int32 nStart = 0;
642 for (sal_Int32 i = 0; i < rValue.getLength(); ++i)
644 if (rValue[i] == '{')
646 if (!nLevel)
647 bIgnore = true;
648 nLevel++;
650 else if (rValue[i] == '}')
652 nLevel--;
653 if (!nLevel)
654 bIgnore = false;
656 else if (rValue[i] == ',' && !bIgnore)
658 OString aToken = rValue.copy(nStart, i - nStart);
659 static const char aExpectedPrefix[] = "Value = (any) { ([]com.sun.star.awt.Size) { ";
660 if (aToken.startsWith(aExpectedPrefix))
662 aToken = aToken.copy(strlen(aExpectedPrefix), aToken.getLength() - strlen(aExpectedPrefix) - strlen(" } }"));
663 lcl_parsePathSubViewSizeValues(rPath, aToken);
665 else if (!aToken.startsWith("Name =") && !aToken.startsWith("Handle ="))
666 SAL_WARN("oox", "lcl_parsePathSubViewSize: unexpected token: " << aToken);
667 nStart = i + strlen(", ");
672 void lcl_parsePath(std::vector<beans::PropertyValue>& rPath, const OString& rValue)
674 sal_Int32 nLevel = 0;
675 sal_Int32 nStart = 0;
676 for (sal_Int32 i = 0; i < rValue.getLength(); ++i)
678 if (rValue[i] == '{')
680 if (!nLevel)
681 nStart = i;
682 nLevel++;
684 else if (rValue[i] == '}')
686 nLevel--;
687 if (!nLevel)
689 OString aToken = rValue.copy(nStart + strlen("{ "), i - nStart - strlen(" },"));
690 if (aToken.startsWith("Name = \"Coordinates\""))
691 lcl_parsePathCoordinates(rPath, aToken);
692 else if (aToken.startsWith("Name = \"Segments\""))
693 lcl_parsePathSegments(rPath, aToken);
694 else if (aToken.startsWith("Name = \"TextFrames\""))
695 lcl_parsePathTextFrames(rPath, aToken);
696 else if (aToken.startsWith("Name = \"SubViewSize\""))
697 lcl_parsePathSubViewSize(rPath, aToken);
698 else
699 SAL_WARN("oox", "lcl_parsePath: unexpected token: " << aToken);
707 namespace oox
709 namespace drawingml
712 void CustomShapeProperties::initializePresetDataMap()
714 OUString aPath("$BRAND_BASE_DIR/" LIBO_SHARE_FOLDER "/filter/oox-drawingml-cs-presets");
715 rtl::Bootstrap::expandMacros(aPath);
716 SvFileStream aStream(aPath, StreamMode::READ);
717 if (aStream.GetError() != ERRCODE_NONE)
718 SAL_WARN("oox", "failed to open oox-drawingml-cs-presets");
719 OString aLine;
720 OUString aName;
721 bool bNotDone = aStream.ReadLine(aLine);
722 PropertyMap aPropertyMap;
723 bool bFirst = true;
724 while (bNotDone)
726 static const char aCommentPrefix[] = "/* ";
727 if (aLine.startsWith(aCommentPrefix))
729 if (bFirst)
730 bFirst = false;
731 else
732 maPresetDataMap[TokenMap::getTokenFromUnicode(aName)] = aPropertyMap;
733 aName = OUString::fromUtf8(aLine.copy(strlen(aCommentPrefix), aLine.getLength() - strlen(aCommentPrefix) - strlen(" */")));
735 else
737 if (aLine == "AdjustmentValues")
739 aStream.ReadLine(aLine);
740 if (aLine != "([]com.sun.star.drawing.EnhancedCustomShapeAdjustmentValue) {}")
742 std::vector<drawing::EnhancedCustomShapeAdjustmentValue> aAdjustmentValues;
743 OString aExpectedPrefix("([]com.sun.star.drawing.EnhancedCustomShapeAdjustmentValue) { ");
744 assert(aLine.startsWith(aExpectedPrefix));
746 OString aValue = aLine.copy(aExpectedPrefix.getLength(), aLine.getLength() - aExpectedPrefix.getLength() - strlen(" }"));
747 lcl_parseAdjustmentValues(aAdjustmentValues, aValue);
748 aPropertyMap.setProperty(PROP_AdjustmentValues, comphelper::containerToSequence(aAdjustmentValues));
750 else
751 aPropertyMap.setProperty(PROP_AdjustmentValues, uno::Sequence<OUString>(0));
753 else if (aLine == "Equations")
755 aStream.ReadLine(aLine);
756 if (aLine != "([]string) {}")
758 std::vector<OUString> aEquations;
759 OString aExpectedPrefix("([]string) { ");
760 assert(aLine.startsWith(aExpectedPrefix));
762 OString aValue = aLine.copy(aExpectedPrefix.getLength(), aLine.getLength() - aExpectedPrefix.getLength() - strlen(" }"));
763 lcl_parseEquations(aEquations, aValue);
764 aPropertyMap.setProperty(PROP_Equations, comphelper::containerToSequence(aEquations));
766 else
767 aPropertyMap.setProperty(PROP_Equations, uno::Sequence<OUString>(0));
769 else if (aLine == "Handles")
771 aStream.ReadLine(aLine);
772 if (aLine != "([][]com.sun.star.beans.PropertyValue) {}")
774 std::vector< uno::Sequence<beans::PropertyValue> > aHandles;
775 OString aExpectedPrefix("([][]com.sun.star.beans.PropertyValue) { ");
776 assert(aLine.startsWith(aExpectedPrefix));
778 OString aValue = aLine.copy(aExpectedPrefix.getLength(), aLine.getLength() - aExpectedPrefix.getLength() - strlen(" }"));
779 lcl_parseHandles(aHandles, aValue);
780 aPropertyMap.setProperty(PROP_Handles, comphelper::containerToSequence(aHandles));
782 else
783 aPropertyMap.setProperty(PROP_Handles, uno::Sequence<OUString>(0));
785 else if (aLine == "MirroredX")
787 aStream.ReadLine(aLine);
788 if (aLine == "true" || aLine == "false")
790 aPropertyMap.setProperty(PROP_MirroredX, aLine == "true");
792 else
793 SAL_WARN("oox", "CustomShapeProperties::initializePresetDataMap: unexpected MirroredX parameter");
795 else if (aLine == "MirroredY")
797 aStream.ReadLine(aLine);
798 if (aLine == "true" || aLine == "false")
800 aPropertyMap.setProperty(PROP_MirroredY, aLine == "true");
802 else
803 SAL_WARN("oox", "CustomShapeProperties::initializePresetDataMap: unexpected MirroredY parameter");
805 else if (aLine == "Path")
807 aStream.ReadLine(aLine);
808 OString aExpectedPrefix("([]com.sun.star.beans.PropertyValue) { ");
809 assert(aLine.startsWith(aExpectedPrefix));
811 std::vector<beans::PropertyValue> aPathValue;
812 OString aValue = aLine.copy(aExpectedPrefix.getLength(), aLine.getLength() - aExpectedPrefix.getLength() - strlen(" }"));
813 lcl_parsePath(aPathValue, aValue);
814 aPropertyMap.setProperty(PROP_Path, comphelper::containerToSequence(aPathValue));
816 else if (aLine == "Type")
818 // Just ignore the line here, we already know the correct type.
819 aStream.ReadLine(aLine);
820 aPropertyMap.setProperty(PROP_Type, "ooxml-" + aName);
822 else if (aLine == "ViewBox")
824 aStream.ReadLine(aLine);
825 OString aExpectedPrefix("(com.sun.star.awt.Rectangle) { ");
826 assert(aLine.startsWith(aExpectedPrefix));
828 OString aValue = aLine.copy(aExpectedPrefix.getLength(), aLine.getLength() - aExpectedPrefix.getLength() - strlen(" }"));
829 aPropertyMap.setProperty(PROP_ViewBox, lcl_parseRectangle(aValue));
831 else
832 SAL_WARN("oox", "CustomShapeProperties::initializePresetDataMap: unhandled line: " << aLine);
834 bNotDone = aStream.ReadLine(aLine);
836 maPresetDataMap[TokenMap::getTokenFromUnicode(aName)] = aPropertyMap;
842 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */