Version 5.4.3.2, tag libreoffice-5.4.3.2
[LibreOffice.git] / oox / source / drawingml / customshapepresetdata.cxx
blobe2b0a5816236aaeb3a28a713e07d9a0331e15926
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 <tools/stream.hxx>
13 #include <comphelper/sequence.hxx>
15 #include "drawingml/customshapeproperties.hxx"
16 #include <oox/token/properties.hxx>
17 #include "oox/token/tokenmap.hxx"
18 #include <com/sun/star/awt/Rectangle.hpp>
19 #include <com/sun/star/beans/PropertyValues.hpp>
20 #include <com/sun/star/drawing/EnhancedCustomShapeTextFrame.hpp>
21 #include <com/sun/star/drawing/EnhancedCustomShapeAdjustmentValue.hpp>
23 using namespace ::com::sun::star;
25 namespace
28 // Parses a string like: Value = (any) { (long) 19098 }, State = (com.sun.star.beans.PropertyState) DIRECT_VALUE, Name = "adj"
29 void lcl_parseAdjustmentValue(std::vector<drawing::EnhancedCustomShapeAdjustmentValue>& rAdjustmentValues, const OString& rValue)
31 sal_Int32 nIndex = 0;
32 drawing::EnhancedCustomShapeAdjustmentValue aAdjustmentValue;
35 OString aToken = rValue.getToken(0, ',', nIndex).trim();
36 static const char aNamePrefix[] = "Name = \"";
37 static const char aValuePrefix[] = "Value = (any) { (long) ";
38 if (aToken.startsWith(aNamePrefix))
40 OString aName = aToken.copy(strlen(aNamePrefix), aToken.getLength() - strlen(aNamePrefix) - strlen("\""));
41 aAdjustmentValue.Name = OUString::fromUtf8(aName);
43 else if (aToken.startsWith(aValuePrefix))
45 OString aValue = aToken.copy(strlen(aValuePrefix), aToken.getLength() - strlen(aValuePrefix) - strlen(" }"));
46 aAdjustmentValue.Value <<= aValue.toInt32();
48 else if (!aToken.startsWith("State = "))
49 SAL_WARN("oox", "lcl_parseAdjustmentValue: unexpected prefix: " << aToken);
51 while (nIndex >= 0);
52 rAdjustmentValues.push_back(aAdjustmentValue);
55 // Parses a string like: { Value = (any) { (long) 19098 }, State = (com.sun.star.beans.PropertyState) DIRECT_VALUE, Name = "adj" }, { Value = ..., State = ..., Name = ... }
56 void lcl_parseAdjustmentValues(std::vector<drawing::EnhancedCustomShapeAdjustmentValue>& rAdjustmentValues, const OString& rValue)
58 sal_Int32 nLevel = 0;
59 sal_Int32 nStart = 0;
60 for (sal_Int32 i = 0; i < rValue.getLength(); ++i)
62 if (rValue[i] == '{')
64 if (!nLevel)
65 nStart = i;
66 nLevel++;
68 else if (rValue[i] == '}')
70 nLevel--;
71 if (!nLevel)
73 lcl_parseAdjustmentValue(rAdjustmentValues, rValue.copy(nStart + strlen("{ "), i - nStart - strlen(" },")));
79 drawing::EnhancedCustomShapeParameterPair lcl_parseEnhancedCustomShapeParameterPair(const OString& rValue)
81 drawing::EnhancedCustomShapeParameterPair aPair;
82 OString aToken = rValue;
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(aToken.startsWith(aExpectedFVPrefix));
86 sal_Int32 nIndex = strlen(aExpectedFVPrefix);
87 aPair.First.Value <<= static_cast<sal_uInt32>(aToken.getToken(0, '}', nIndex).toInt32());
89 static const char aExpectedFTPrefix[] = ", Type = (short) ";
90 aToken = aToken.copy(nIndex);
91 assert(aToken.startsWith(aExpectedFTPrefix));
92 nIndex = strlen(aExpectedFTPrefix);
93 aPair.First.Type = static_cast<sal_uInt16>(aToken.getToken(0, '}', nIndex).toInt32());
95 static const char aExpectedSVPrefix[] = ", Second = (com.sun.star.drawing.EnhancedCustomShapeParameter) { Value = (any) { (long) ";
96 aToken = aToken.copy(nIndex);
97 assert(aToken.startsWith(aExpectedSVPrefix));
98 nIndex = strlen(aExpectedSVPrefix);
99 aPair.Second.Value <<= static_cast<sal_uInt32>(aToken.getToken(0, '}', nIndex).toInt32());
101 static const char aExpectedSTPrefix[] = ", Type = (short) ";
102 aToken = aToken.copy(nIndex);
103 assert(aToken.startsWith(aExpectedSTPrefix));
104 nIndex = strlen(aExpectedSTPrefix);
105 aPair.Second.Type = static_cast<sal_uInt16>(aToken.getToken(0, '}', nIndex).toInt32());
106 return aPair;
109 drawing::EnhancedCustomShapeSegment lcl_parseEnhancedCustomShapeSegment(const OString& rValue)
111 drawing::EnhancedCustomShapeSegment aSegment;
112 OString aToken = rValue;
113 // We expect the following here: Command, Count
114 static const char aExpectedCommandPrefix[] = "Command = (short) ";
115 assert(aToken.startsWith(aExpectedCommandPrefix));
116 sal_Int32 nIndex = strlen(aExpectedCommandPrefix);
117 aSegment.Command = static_cast<sal_Int16>(aToken.getToken(0, ',', nIndex).toInt32());
119 static const char aExpectedCountPrefix[] = " Count = (short) ";
120 aToken = aToken.copy(nIndex);
121 assert(aToken.startsWith(aExpectedCountPrefix));
122 nIndex = strlen(aExpectedCountPrefix);
123 aSegment.Count = static_cast<sal_Int16>(aToken.getToken(0, '}', nIndex).toInt32());
124 return aSegment;
127 awt::Rectangle lcl_parseRectangle(const OString& rValue)
129 awt::Rectangle aRectangle;
130 OString aToken = rValue;
131 // We expect the following here: X, Y, Width, Height
132 static const char aExpectedXPrefix[] = "X = (long) ";
133 assert(aToken.startsWith(aExpectedXPrefix));
134 sal_Int32 nIndex = strlen(aExpectedXPrefix);
135 aRectangle.X = aToken.getToken(0, ',', nIndex).toInt32();
137 static const char aExpectedYPrefix[] = " Y = (long) ";
138 aToken = aToken.copy(nIndex);
139 assert(aToken.startsWith(aExpectedYPrefix));
140 nIndex = strlen(aExpectedYPrefix);
141 aRectangle.Y = aToken.getToken(0, ',', nIndex).toInt32();
143 static const char aExpectedWidthPrefix[] = " Width = (long) ";
144 aToken = aToken.copy(nIndex);
145 assert(aToken.startsWith(aExpectedWidthPrefix));
146 nIndex = strlen(aExpectedWidthPrefix);
147 aRectangle.Width = aToken.getToken(0, ',', nIndex).toInt32();
149 static const char aExpectedHeightPrefix[] = " Height = (long) ";
150 aToken = aToken.copy(nIndex);
151 assert(aToken.startsWith(aExpectedHeightPrefix));
152 nIndex = strlen(aExpectedHeightPrefix);
153 aRectangle.Height = aToken.copy(nIndex).toInt32();
155 return aRectangle;
158 awt::Size lcl_parseSize(const OString& rValue)
160 awt::Size aSize;
161 OString aToken = rValue;
162 // We expect the following here: Width, Height
163 static const char aExpectedWidthPrefix[] = "Width = (long) ";
164 assert(aToken.startsWith(aExpectedWidthPrefix));
165 sal_Int32 nIndex = strlen(aExpectedWidthPrefix);
166 aSize.Width = aToken.getToken(0, ',', nIndex).toInt32();
168 static const char aExpectedHeightPrefix[] = " Height = (long) ";
169 aToken = aToken.copy(nIndex);
170 assert(aToken.startsWith(aExpectedHeightPrefix));
171 nIndex = strlen(aExpectedHeightPrefix);
172 aSize.Height = aToken.copy(nIndex).toInt32();
174 return aSize;
177 drawing::EnhancedCustomShapeTextFrame lcl_parseEnhancedCustomShapeTextFrame(const OString& rValue)
179 drawing::EnhancedCustomShapeTextFrame aTextFrame;
180 sal_Int32 nLevel = 0;
181 bool bIgnore = false;
182 sal_Int32 nStart = 0;
183 for (sal_Int32 i = 0; i < rValue.getLength(); ++i)
185 if (rValue[i] == '{')
187 if (!nLevel)
188 bIgnore = true;
189 nLevel++;
191 else if (rValue[i] == '}')
193 nLevel--;
194 if (!nLevel)
195 bIgnore = false;
197 else if (rValue[i] == ',' && !bIgnore)
199 OString aToken = rValue.copy(nStart, i - nStart);
200 static const char aExpectedPrefix[] = "TopLeft = (com.sun.star.drawing.EnhancedCustomShapeParameterPair) { ";
201 if (aToken.startsWith(aExpectedPrefix))
203 aToken = aToken.copy(strlen(aExpectedPrefix), aToken.getLength() - strlen(aExpectedPrefix) - strlen(" }"));
204 aTextFrame.TopLeft = lcl_parseEnhancedCustomShapeParameterPair(aToken);
206 else
207 SAL_WARN("oox", "lcl_parseEnhancedCustomShapeTextFrame: unexpected token: " << aToken);
208 nStart = i + strlen(", ");
212 OString aToken = rValue.copy(nStart, rValue.getLength() - nStart);
213 static const char aExpectedPrefix[] = "BottomRight = (com.sun.star.drawing.EnhancedCustomShapeParameterPair) { ";
214 if (aToken.startsWith(aExpectedPrefix))
216 aToken = aToken.copy(strlen(aExpectedPrefix), aToken.getLength() - strlen(aExpectedPrefix) - strlen(" }"));
217 aTextFrame.BottomRight = lcl_parseEnhancedCustomShapeParameterPair(aToken);
219 else
220 SAL_WARN("oox", "lcl_parseEnhancedCustomShapeTextFrame: unexpected token at the end: " << aToken);
222 return aTextFrame;
225 // Parses a string like: Name = "Position", Handle = (long) 0, Value = (any) { ... }, State = (com.sun.star.beans.PropertyState) DIRECT_VALUE
226 // where "{ ... }" may contain "," as well.
227 void lcl_parseHandlePosition(std::vector<beans::PropertyValue>& rHandle, const OString& rValue)
229 sal_Int32 nLevel = 0;
230 bool bIgnore = false;
231 sal_Int32 nStart = 0;
232 for (sal_Int32 i = 0; i < rValue.getLength(); ++i)
234 if (rValue[i] == '{')
236 if (!nLevel)
237 bIgnore = true;
238 nLevel++;
240 else if (rValue[i] == '}')
242 nLevel--;
243 if (!nLevel)
244 bIgnore = false;
246 else if (rValue[i] == ',' && !bIgnore)
248 OString aToken = rValue.copy(nStart, i - nStart);
249 static const char aExpectedPrefix[] = "Value = (any) { (com.sun.star.drawing.EnhancedCustomShapeParameterPair) { ";
250 if (aToken.startsWith(aExpectedPrefix))
252 aToken = aToken.copy(strlen(aExpectedPrefix), aToken.getLength() - strlen(aExpectedPrefix) - strlen(" } }"));
254 beans::PropertyValue aPropertyValue;
255 aPropertyValue.Name = "Position";
256 aPropertyValue.Value <<= lcl_parseEnhancedCustomShapeParameterPair(aToken);
257 rHandle.push_back(aPropertyValue);
259 else if (!aToken.startsWith("Name =") && !aToken.startsWith("Handle ="))
260 SAL_WARN("oox", "lcl_parseHandlePosition: unexpected token: " << aToken);
261 nStart = i + strlen(", ");
266 // Parses a string like: Name = "RangeYMaximum", Handle = (long) 0, Value = (any) { ... }, State = (com.sun.star.beans.PropertyState) DIRECT_VALUE
267 // where "{ ... }" may contain "," as well.
268 void lcl_parseHandleRange(std::vector<beans::PropertyValue>& rHandle, const OString& rValue, const OUString& rName)
270 sal_Int32 nLevel = 0;
271 bool bIgnore = false;
272 sal_Int32 nStart = 0;
273 for (sal_Int32 i = 0; i < rValue.getLength(); ++i)
275 if (rValue[i] == '{')
277 if (!nLevel)
278 bIgnore = true;
279 nLevel++;
281 else if (rValue[i] == '}')
283 nLevel--;
284 if (!nLevel)
285 bIgnore = false;
287 else if (rValue[i] == ',' && !bIgnore)
289 OString aToken = rValue.copy(nStart, i - nStart);
290 static const char aExpectedPrefix[] = "Value = (any) { (com.sun.star.drawing.EnhancedCustomShapeParameter) { ";
291 if (aToken.startsWith(aExpectedPrefix))
293 drawing::EnhancedCustomShapeParameter aParameter;
294 aToken = aToken.copy(strlen(aExpectedPrefix), aToken.getLength() - strlen(aExpectedPrefix) - strlen(" } }"));
295 // We expect the following here: Value and Type
296 static const char aExpectedVPrefix[] = "Value = (any) { (long) ";
297 assert(aToken.startsWith(aExpectedVPrefix));
298 sal_Int32 nIndex = strlen(aExpectedVPrefix);
299 aParameter.Value <<= aToken.getToken(0, '}', nIndex).toInt32();
301 static const char aExpectedTPrefix[] = ", Type = (short) ";
302 aToken = aToken.copy(nIndex);
303 assert(aToken.startsWith(aExpectedTPrefix));
304 nIndex = strlen(aExpectedTPrefix);
305 aParameter.Type = static_cast<sal_Int16>(aToken.getToken(0, '}', nIndex).toInt32());
307 beans::PropertyValue aPropertyValue;
308 aPropertyValue.Name = rName;
309 aPropertyValue.Value <<= aParameter;
310 rHandle.push_back(aPropertyValue);
313 else if (!aToken.startsWith("Name =") && !aToken.startsWith("Handle ="))
314 SAL_WARN("oox", "lcl_parseHandleRange: unexpected token: " << aToken);
315 nStart = i + strlen(", ");
320 // Parses a string like: Name = "RefY", Handle = (long) 0, Value = (any) { (long) 0 }, State = (com.sun.star.beans.PropertyState) DIRECT_VALUE
321 void lcl_parseHandleRef(std::vector<beans::PropertyValue>& rHandle, const OString& rValue, const OUString& rName)
323 static const char aPrefix[] = "\", Handle = (long) 0, Value = (any) { (long) ";
324 const sal_Int32 nCheck= SAL_N_ELEMENTS(aPrefix) - 1;
325 const sal_Int32 nStart= SAL_N_ELEMENTS("Name = \"") - 1 + rName.getLength();
327 if (rValue.copy(nStart, nCheck).equalsL(aPrefix, nCheck))
329 sal_Int32 nIndex = nStart + nCheck;
330 beans::PropertyValue aPropertyValue;
331 aPropertyValue.Name = rName;
332 // We only expect a Value here
333 aPropertyValue.Value <<= rValue.getToken(0, '}', nIndex).toInt32();
334 rHandle.push_back(aPropertyValue);
336 else
337 SAL_WARN("oox", "lcl_parseHandleRef: unexpected value: " << rValue);
340 uno::Sequence<beans::PropertyValue> lcl_parseHandle(const OString& rValue)
342 std::vector<beans::PropertyValue> aRet;
343 sal_Int32 nLevel = 0;
344 sal_Int32 nStart = 0;
345 for (sal_Int32 i = 0; i < rValue.getLength(); ++i)
347 if (rValue[i] == '{')
349 if (!nLevel)
350 nStart = i;
351 nLevel++;
353 else if (rValue[i] == '}')
355 nLevel--;
356 if (!nLevel)
358 OString aToken = rValue.copy(nStart + strlen("{ "), i - nStart - strlen(" },"));
359 if (aToken.startsWith("Name = \"Position\""))
360 lcl_parseHandlePosition(aRet, aToken);
361 else if (aToken.startsWith("Name = \"RangeXMaximum\""))
362 lcl_parseHandleRange(aRet, aToken, "RangeXMaximum");
363 else if (aToken.startsWith("Name = \"RangeXMinimum\""))
364 lcl_parseHandleRange(aRet, aToken, "RangeXMinimum");
365 else if (aToken.startsWith("Name = \"RangeYMaximum\""))
366 lcl_parseHandleRange(aRet, aToken, "RangeYMaximum");
367 else if (aToken.startsWith("Name = \"RangeYMinimum\""))
368 lcl_parseHandleRange(aRet, aToken, "RangeYMinimum");
369 else if (aToken.startsWith("Name = \"RadiusRangeMaximum\""))
370 lcl_parseHandleRange(aRet, aToken, "RadiusRangeMaximum");
371 else if (aToken.startsWith("Name = \"RadiusRangeMinimum\""))
372 lcl_parseHandleRange(aRet, aToken, "RadiusRangeMinimum");
373 else if (aToken.startsWith("Name = \"RefX\""))
374 lcl_parseHandleRef(aRet, aToken, "RefX");
375 else if (aToken.startsWith("Name = \"RefY\""))
376 lcl_parseHandleRef(aRet, aToken, "RefY");
377 else if (aToken.startsWith("Name = \"RefR\""))
378 lcl_parseHandleRef(aRet, aToken, "RefR");
379 else if (aToken.startsWith("Name = \"RefAngle\""))
380 lcl_parseHandleRef(aRet, aToken, "RefAngle");
381 else
382 SAL_WARN("oox", "lcl_parseHandle: unexpected token: " << aToken);
386 return comphelper::containerToSequence(aRet);
389 void lcl_parseHandles(std::vector< uno::Sequence<beans::PropertyValue> >& rHandles, const OString& rValue)
391 sal_Int32 nLevel = 0;
392 sal_Int32 nStart = 0;
393 for (sal_Int32 i = 0; i < rValue.getLength(); ++i)
395 if (rValue[i] == '{')
397 if (!nLevel)
398 nStart = i;
399 nLevel++;
401 else if (rValue[i] == '}')
403 nLevel--;
404 if (!nLevel)
406 uno::Sequence<beans::PropertyValue> aHandle = lcl_parseHandle(rValue.copy(nStart + strlen("{ "), i - nStart - strlen(" },")));
407 rHandles.push_back(aHandle);
413 void lcl_parseEquations(std::vector<OUString>& rEquations, const OString& rValue)
415 bool bInString = false;
416 sal_Int32 nStart = 0;
417 for (sal_Int32 i = 0; i < rValue.getLength(); ++i)
419 if (rValue[i] == '"' && !bInString)
421 nStart = i;
422 bInString = true;
424 else if (rValue[i] == '"' && bInString)
426 bInString = false;
427 rEquations.push_back(OUString::fromUtf8(rValue.copy(nStart + strlen("\""), i - nStart - strlen("\""))));
432 void lcl_parsePathCoordinateValues(std::vector<beans::PropertyValue>& rPath, const OString& rValue)
434 std::vector<drawing::EnhancedCustomShapeParameterPair> aPairs;
435 sal_Int32 nLevel = 0;
436 sal_Int32 nStart = 0;
437 for (sal_Int32 i = 0; i < rValue.getLength(); ++i)
439 if (rValue[i] == '{')
441 if (!nLevel)
442 nStart = i;
443 nLevel++;
445 else if (rValue[i] == '}')
447 nLevel--;
448 if (!nLevel)
449 aPairs.push_back(lcl_parseEnhancedCustomShapeParameterPair(rValue.copy(nStart + strlen("{ "), i - nStart - strlen(" },"))));
453 beans::PropertyValue aPropertyValue;
454 aPropertyValue.Name = "Coordinates";
455 aPropertyValue.Value <<= comphelper::containerToSequence(aPairs);
456 rPath.push_back(aPropertyValue);
459 // Parses a string like: Name = "Coordinates", Handle = (long) 0, Value = (any) { ... }, State = (com.sun.star.beans.PropertyState) DIRECT_VALUE
460 // where "{ ... }" may contain "," as well.
461 void lcl_parsePathCoordinates(std::vector<beans::PropertyValue>& rPath, const OString& rValue)
463 sal_Int32 nLevel = 0;
464 bool bIgnore = false;
465 sal_Int32 nStart = 0;
466 for (sal_Int32 i = 0; i < rValue.getLength(); ++i)
468 if (rValue[i] == '{')
470 if (!nLevel)
471 bIgnore = true;
472 nLevel++;
474 else if (rValue[i] == '}')
476 nLevel--;
477 if (!nLevel)
478 bIgnore = false;
480 else if (rValue[i] == ',' && !bIgnore)
482 OString aToken = rValue.copy(nStart, i - nStart);
483 static const char aExpectedPrefix[] = "Value = (any) { ([]com.sun.star.drawing.EnhancedCustomShapeParameterPair) { ";
484 if (aToken.startsWith(aExpectedPrefix))
486 aToken = aToken.copy(strlen(aExpectedPrefix), aToken.getLength() - strlen(aExpectedPrefix) - strlen(" } }"));
487 lcl_parsePathCoordinateValues(rPath, aToken);
489 else if (!aToken.startsWith("Name =") && !aToken.startsWith("Handle ="))
490 SAL_WARN("oox", "lcl_parsePathCoordinates: unexpected token: " << aToken);
491 nStart = i + strlen(", ");
496 void lcl_parsePathSegmentValues(std::vector<beans::PropertyValue>& rPath, const OString& rValue)
498 std::vector<drawing::EnhancedCustomShapeSegment> aSegments;
499 sal_Int32 nLevel = 0;
500 sal_Int32 nStart = 0;
501 for (sal_Int32 i = 0; i < rValue.getLength(); ++i)
503 if (rValue[i] == '{')
505 if (!nLevel)
506 nStart = i;
507 nLevel++;
509 else if (rValue[i] == '}')
511 nLevel--;
512 if (!nLevel)
513 aSegments.push_back(lcl_parseEnhancedCustomShapeSegment(rValue.copy(nStart + strlen("{ "), i - nStart - strlen(" },"))));
517 beans::PropertyValue aPropertyValue;
518 aPropertyValue.Name = "Segments";
519 aPropertyValue.Value <<= comphelper::containerToSequence(aSegments);
520 rPath.push_back(aPropertyValue);
523 // Parses a string like: Name = "Segments", Handle = (long) 0, Value = (any) { ... }, State = (com.sun.star.beans.PropertyState) DIRECT_VALUE
524 // where "{ ... }" may contain "," as well.
525 void lcl_parsePathSegments(std::vector<beans::PropertyValue>& rPath, const OString& rValue)
527 sal_Int32 nLevel = 0;
528 bool bIgnore = false;
529 sal_Int32 nStart = 0;
530 for (sal_Int32 i = 0; i < rValue.getLength(); ++i)
532 if (rValue[i] == '{')
534 if (!nLevel)
535 bIgnore = true;
536 nLevel++;
538 else if (rValue[i] == '}')
540 nLevel--;
541 if (!nLevel)
542 bIgnore = false;
544 else if (rValue[i] == ',' && !bIgnore)
546 OString aToken = rValue.copy(nStart, i - nStart);
547 static const char aExpectedPrefix[] = "Value = (any) { ([]com.sun.star.drawing.EnhancedCustomShapeSegment) { ";
548 if (aToken.startsWith(aExpectedPrefix))
550 aToken = aToken.copy(strlen(aExpectedPrefix), aToken.getLength() - strlen(aExpectedPrefix) - strlen(" } }"));
551 lcl_parsePathSegmentValues(rPath, aToken);
553 else if (!aToken.startsWith("Name =") && !aToken.startsWith("Handle ="))
554 SAL_WARN("oox", "lcl_parsePathSegments: unexpected token: " << aToken);
555 nStart = i + strlen(", ");
560 void lcl_parsePathTextFrameValues(std::vector<beans::PropertyValue>& rPath, const OString& rValue)
562 std::vector<drawing::EnhancedCustomShapeTextFrame> aTextFrames;
563 sal_Int32 nLevel = 0;
564 sal_Int32 nStart = 0;
565 for (sal_Int32 i = 0; i < rValue.getLength(); ++i)
567 if (rValue[i] == '{')
569 if (!nLevel)
570 nStart = i;
571 nLevel++;
573 else if (rValue[i] == '}')
575 nLevel--;
576 if (!nLevel)
577 aTextFrames.push_back(lcl_parseEnhancedCustomShapeTextFrame(rValue.copy(nStart + strlen("{ "), i - nStart - strlen(" },"))));
581 beans::PropertyValue aPropertyValue;
582 aPropertyValue.Name = "TextFrames";
583 aPropertyValue.Value <<= comphelper::containerToSequence(aTextFrames);
584 rPath.push_back(aPropertyValue);
587 // Parses a string like: Name = "TextFrames", Handle = (long) 0, Value = (any) { ... }, State = (com.sun.star.beans.PropertyState) DIRECT_VALUE
588 // where "{ ... }" may contain "," as well.
589 void lcl_parsePathTextFrames(std::vector<beans::PropertyValue>& rPath, const OString& rValue)
591 sal_Int32 nLevel = 0;
592 bool bIgnore = false;
593 sal_Int32 nStart = 0;
594 for (sal_Int32 i = 0; i < rValue.getLength(); ++i)
596 if (rValue[i] == '{')
598 if (!nLevel)
599 bIgnore = true;
600 nLevel++;
602 else if (rValue[i] == '}')
604 nLevel--;
605 if (!nLevel)
606 bIgnore = false;
608 else if (rValue[i] == ',' && !bIgnore)
610 OString aToken = rValue.copy(nStart, i - nStart);
611 static const char aExpectedPrefix[] = "Value = (any) { ([]com.sun.star.drawing.EnhancedCustomShapeTextFrame) { ";
612 if (aToken.startsWith(aExpectedPrefix))
614 aToken = aToken.copy(strlen(aExpectedPrefix), aToken.getLength() - strlen(aExpectedPrefix) - strlen(" } }"));
615 lcl_parsePathTextFrameValues(rPath, aToken);
617 else if (!aToken.startsWith("Name =") && !aToken.startsWith("Handle ="))
618 SAL_WARN("oox", "lcl_parsePathTextFrames: unexpected token: " << aToken);
619 nStart = i + strlen(", ");
624 void lcl_parsePathSubViewSizeValues(std::vector<beans::PropertyValue>& rPath, const OString& rValue)
626 std::vector<awt::Size> aSizes;
627 sal_Int32 nLevel = 0;
628 sal_Int32 nStart = 0;
629 for (sal_Int32 i = 0; i < rValue.getLength(); ++i)
631 if (rValue[i] == '{')
633 if (!nLevel)
634 nStart = i;
635 nLevel++;
637 else if (rValue[i] == '}')
639 nLevel--;
640 if (!nLevel)
641 aSizes.push_back(lcl_parseSize(rValue.copy(nStart + strlen("{ "), i - nStart - strlen(" },"))));
645 beans::PropertyValue aPropertyValue;
646 aPropertyValue.Name = "SubViewSize";
647 aPropertyValue.Value <<= comphelper::containerToSequence(aSizes);
648 rPath.push_back(aPropertyValue);
651 void lcl_parsePathSubViewSize(std::vector<beans::PropertyValue>& rPath, const OString& rValue)
653 sal_Int32 nLevel = 0;
654 bool bIgnore = false;
655 sal_Int32 nStart = 0;
656 for (sal_Int32 i = 0; i < rValue.getLength(); ++i)
658 if (rValue[i] == '{')
660 if (!nLevel)
661 bIgnore = true;
662 nLevel++;
664 else if (rValue[i] == '}')
666 nLevel--;
667 if (!nLevel)
668 bIgnore = false;
670 else if (rValue[i] == ',' && !bIgnore)
672 OString aToken = rValue.copy(nStart, i - nStart);
673 static const char aExpectedPrefix[] = "Value = (any) { ([]com.sun.star.awt.Size) { ";
674 if (aToken.startsWith(aExpectedPrefix))
676 aToken = aToken.copy(strlen(aExpectedPrefix), aToken.getLength() - strlen(aExpectedPrefix) - strlen(" } }"));
677 lcl_parsePathSubViewSizeValues(rPath, aToken);
679 else if (!aToken.startsWith("Name =") && !aToken.startsWith("Handle ="))
680 SAL_WARN("oox", "lcl_parsePathSubViewSize: unexpected token: " << aToken);
681 nStart = i + strlen(", ");
686 void lcl_parsePath(std::vector<beans::PropertyValue>& rPath, const OString& rValue)
688 sal_Int32 nLevel = 0;
689 sal_Int32 nStart = 0;
690 for (sal_Int32 i = 0; i < rValue.getLength(); ++i)
692 if (rValue[i] == '{')
694 if (!nLevel)
695 nStart = i;
696 nLevel++;
698 else if (rValue[i] == '}')
700 nLevel--;
701 if (!nLevel)
703 OString aToken = rValue.copy(nStart + strlen("{ "), i - nStart - strlen(" },"));
704 if (aToken.startsWith("Name = \"Coordinates\""))
705 lcl_parsePathCoordinates(rPath, aToken);
706 else if (aToken.startsWith("Name = \"Segments\""))
707 lcl_parsePathSegments(rPath, aToken);
708 else if (aToken.startsWith("Name = \"TextFrames\""))
709 lcl_parsePathTextFrames(rPath, aToken);
710 else if (aToken.startsWith("Name = \"SubViewSize\""))
711 lcl_parsePathSubViewSize(rPath, aToken);
712 else
713 SAL_WARN("oox", "lcl_parsePath: unexpected token: " << aToken);
721 namespace oox
723 namespace drawingml
726 void CustomShapeProperties::initializePresetDataMap()
728 OUString aPath("$BRAND_BASE_DIR/" LIBO_SHARE_FOLDER "/filter/oox-drawingml-cs-presets");
729 rtl::Bootstrap::expandMacros(aPath);
730 SvFileStream aStream(aPath, StreamMode::READ);
731 if (aStream.GetError() != ERRCODE_NONE)
732 SAL_WARN("oox", "failed to open oox-drawingml-cs-presets");
733 OString aLine;
734 OUString aName;
735 bool bNotDone = aStream.ReadLine(aLine);
736 PropertyMap aPropertyMap;
737 bool bFirst = true;
738 while (bNotDone)
740 static const char aCommentPrefix[] = "/* ";
741 if (aLine.startsWith(aCommentPrefix))
743 if (bFirst)
744 bFirst = false;
745 else
746 maPresetDataMap[TokenMap::getTokenFromUnicode(aName)] = aPropertyMap;
747 aName = OUString::fromUtf8(aLine.copy(strlen(aCommentPrefix), aLine.getLength() - strlen(aCommentPrefix) - strlen(" */")));
749 else
751 if (aLine == "AdjustmentValues")
753 aStream.ReadLine(aLine);
754 if (aLine != "([]com.sun.star.drawing.EnhancedCustomShapeAdjustmentValue) {}")
756 std::vector<drawing::EnhancedCustomShapeAdjustmentValue> aAdjustmentValues;
757 OString aExpectedPrefix("([]com.sun.star.drawing.EnhancedCustomShapeAdjustmentValue) { ");
758 assert(aLine.startsWith(aExpectedPrefix));
760 OString aValue = aLine.copy(aExpectedPrefix.getLength(), aLine.getLength() - aExpectedPrefix.getLength() - strlen(" }"));
761 lcl_parseAdjustmentValues(aAdjustmentValues, aValue);
762 aPropertyMap.setProperty(PROP_AdjustmentValues, comphelper::containerToSequence(aAdjustmentValues));
764 else
765 aPropertyMap.setProperty(PROP_AdjustmentValues, uno::Sequence<OUString>(0));
767 else if (aLine == "Equations")
769 aStream.ReadLine(aLine);
770 if (aLine != "([]string) {}")
772 std::vector<OUString> aEquations;
773 OString aExpectedPrefix("([]string) { ");
774 assert(aLine.startsWith(aExpectedPrefix));
776 OString aValue = aLine.copy(aExpectedPrefix.getLength(), aLine.getLength() - aExpectedPrefix.getLength() - strlen(" }"));
777 lcl_parseEquations(aEquations, aValue);
778 aPropertyMap.setProperty(PROP_Equations, comphelper::containerToSequence(aEquations));
780 else
781 aPropertyMap.setProperty(PROP_Equations, uno::Sequence<OUString>(0));
783 else if (aLine == "Handles")
785 aStream.ReadLine(aLine);
786 if (aLine != "([][]com.sun.star.beans.PropertyValue) {}")
788 std::vector< uno::Sequence<beans::PropertyValue> > aHandles;
789 OString aExpectedPrefix("([][]com.sun.star.beans.PropertyValue) { ");
790 assert(aLine.startsWith(aExpectedPrefix));
792 OString aValue = aLine.copy(aExpectedPrefix.getLength(), aLine.getLength() - aExpectedPrefix.getLength() - strlen(" }"));
793 lcl_parseHandles(aHandles, aValue);
794 aPropertyMap.setProperty(PROP_Handles, comphelper::containerToSequence(aHandles));
796 else
797 aPropertyMap.setProperty(PROP_Handles, uno::Sequence<OUString>(0));
799 else if (aLine == "MirroredX")
801 aStream.ReadLine(aLine);
802 if (aLine == "true" || aLine == "false")
804 aPropertyMap.setProperty(PROP_MirroredX, aLine == "true");
806 else
807 SAL_WARN("oox", "CustomShapeProperties::initializePresetDataMap: unexpected MirroredX parameter");
809 else if (aLine == "MirroredY")
811 aStream.ReadLine(aLine);
812 if (aLine == "true" || aLine == "false")
814 aPropertyMap.setProperty(PROP_MirroredY, aLine == "true");
816 else
817 SAL_WARN("oox", "CustomShapeProperties::initializePresetDataMap: unexpected MirroredY parameter");
819 else if (aLine == "Path")
821 aStream.ReadLine(aLine);
822 OString aExpectedPrefix("([]com.sun.star.beans.PropertyValue) { ");
823 assert(aLine.startsWith(aExpectedPrefix));
825 std::vector<beans::PropertyValue> aPathValue;
826 OString aValue = aLine.copy(aExpectedPrefix.getLength(), aLine.getLength() - aExpectedPrefix.getLength() - strlen(" }"));
827 lcl_parsePath(aPathValue, aValue);
828 aPropertyMap.setProperty(PROP_Path, comphelper::containerToSequence(aPathValue));
830 else if (aLine == "Type")
832 // Just ignore the line here, we already know the correct type.
833 aStream.ReadLine(aLine);
834 aPropertyMap.setProperty(PROP_Type, "ooxml-" + aName);
836 else if (aLine == "ViewBox")
838 aStream.ReadLine(aLine);
839 OString aExpectedPrefix("(com.sun.star.awt.Rectangle) { ");
840 assert(aLine.startsWith(aExpectedPrefix));
842 OString aValue = aLine.copy(aExpectedPrefix.getLength(), aLine.getLength() - aExpectedPrefix.getLength() - strlen(" }"));
843 aPropertyMap.setProperty(PROP_ViewBox, lcl_parseRectangle(aValue));
845 else
846 SAL_WARN("oox", "CustomShapeProperties::initializePresetDataMap: unhandled line: " << aLine);
848 bNotDone = aStream.ReadLine(aLine);
850 maPresetDataMap[TokenMap::getTokenFromUnicode(aName)] = aPropertyMap;
856 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */