1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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/.
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
;
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
)
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
);
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
)
61 for (sal_Int32 i
= 0; i
< rValue
.getLength(); ++i
)
69 else if (rValue
[i
] == '}')
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());
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());
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();
149 awt::Size
lcl_parseSize(const OString
& rValue
)
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();
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
] == '{')
180 else if (rValue
[i
] == '}')
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
);
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
);
209 SAL_WARN("oox", "lcl_parseEnhancedCustomShapeTextFrame: unexpected token at the end: " << aToken
);
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
] == '{')
229 else if (rValue
[i
] == '}')
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
] == '{')
270 else if (rValue
[i
] == '}')
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
);
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
] == '{')
339 else if (rValue
[i
] == '}')
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");
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
] == '{')
387 else if (rValue
[i
] == '}')
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
)
410 else if (rValue
[i
] == '"' && bInString
)
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
] == '{')
431 else if (rValue
[i
] == '}')
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
] == '{')
460 else if (rValue
[i
] == '}')
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
] == '{')
495 else if (rValue
[i
] == '}')
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
] == '{')
524 else if (rValue
[i
] == '}')
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
] == '{')
559 else if (rValue
[i
] == '}')
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
] == '{')
588 else if (rValue
[i
] == '}')
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
] == '{')
623 else if (rValue
[i
] == '}')
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
] == '{')
650 else if (rValue
[i
] == '}')
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
] == '{')
684 else if (rValue
[i
] == '}')
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
);
699 SAL_WARN("oox", "lcl_parsePath: unexpected token: " << aToken
);
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");
721 bool bNotDone
= aStream
.ReadLine(aLine
);
722 PropertyMap aPropertyMap
;
726 static const char aCommentPrefix
[] = "/* ";
727 if (aLine
.startsWith(aCommentPrefix
))
732 maPresetDataMap
[TokenMap::getTokenFromUnicode(aName
)] = aPropertyMap
;
733 aName
= OUString::fromUtf8(aLine
.copy(strlen(aCommentPrefix
), aLine
.getLength() - strlen(aCommentPrefix
) - strlen(" */")));
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
));
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
));
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
));
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");
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");
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
));
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: */