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 <tools/stream.hxx>
13 #include <comphelper/sequence.hxx>
15 #include "drawingml/customshapeproperties.hxx"
16 #include "oox/token/tokenmap.hxx"
17 #include <com/sun/star/awt/Rectangle.hpp>
19 using namespace ::com::sun::star
;
24 // Parses a string like: Value = (any) { (long) 19098 }, State = (com.sun.star.beans.PropertyState) DIRECT_VALUE, Name = "adj"
25 void lcl_parseAdjustmentValue(std::vector
<drawing::EnhancedCustomShapeAdjustmentValue
>& rAdjustmentValues
, const OString
& rValue
)
28 drawing::EnhancedCustomShapeAdjustmentValue aAdjustmentValue
;
31 OString aToken
= rValue
.getToken(0, ',', nIndex
).trim();
32 static const char aNamePrefix
[] = "Name = \"";
33 static const char aValuePrefix
[] = "Value = (any) { (long) ";
34 if (aToken
.startsWith(aNamePrefix
))
36 OString aName
= aToken
.copy(strlen(aNamePrefix
), aToken
.getLength() - strlen(aNamePrefix
) - strlen("\""));
37 aAdjustmentValue
.Name
= OUString::fromUtf8(aName
);
39 else if (aToken
.startsWith(aValuePrefix
))
41 OString aValue
= aToken
.copy(strlen(aValuePrefix
), aToken
.getLength() - strlen(aValuePrefix
) - strlen(" }"));
42 aAdjustmentValue
.Value
= uno::makeAny(aValue
.toInt32());
44 else if (!aToken
.startsWith("State = "))
45 SAL_WARN("oox", "lcl_parseAdjustmentValue: unexpected prefix: " << aToken
);
48 rAdjustmentValues
.push_back(aAdjustmentValue
);
51 // Parses a string like: { Value = (any) { (long) 19098 }, State = (com.sun.star.beans.PropertyState) DIRECT_VALUE, Name = "adj" }, { Value = ..., State = ..., Name = ... }
52 void lcl_parseAdjustmentValues(std::vector
<drawing::EnhancedCustomShapeAdjustmentValue
>& rAdjustmentValues
, const OString
& rValue
)
56 for (sal_Int32 i
= 0; i
< rValue
.getLength(); ++i
)
64 else if (rValue
[i
] == '}')
69 lcl_parseAdjustmentValue(rAdjustmentValues
, rValue
.copy(nStart
+ strlen("{ "), i
- nStart
- strlen(" },")));
75 drawing::EnhancedCustomShapeParameterPair
lcl_parseEnhancedCustomShapeParameterPair(const OString
& rValue
)
77 drawing::EnhancedCustomShapeParameterPair aPair
;
78 OString aToken
= rValue
;
79 // We expect the followings here: First.Value, First.Type, Second.Value, Second.Type
80 static const char aExpectedFVPrefix
[] = "First = (com.sun.star.drawing.EnhancedCustomShapeParameter) { Value = (any) { (long) ";
81 assert(aToken
.startsWith(aExpectedFVPrefix
));
82 sal_Int32 nIndex
= strlen(aExpectedFVPrefix
);
83 aPair
.First
.Value
= uno::makeAny(static_cast<sal_uInt32
>(aToken
.getToken(0, '}', nIndex
).toInt32()));
85 static const char aExpectedFTPrefix
[] = ", Type = (short) ";
86 aToken
= aToken
.copy(nIndex
);
87 assert(aToken
.startsWith(aExpectedFTPrefix
));
88 nIndex
= strlen(aExpectedFTPrefix
);
89 aPair
.First
.Type
= static_cast<sal_uInt16
>(aToken
.getToken(0, '}', nIndex
).toInt32());
91 static const char aExpectedSVPrefix
[] = ", Second = (com.sun.star.drawing.EnhancedCustomShapeParameter) { Value = (any) { (long) ";
92 aToken
= aToken
.copy(nIndex
);
93 assert(aToken
.startsWith(aExpectedSVPrefix
));
94 nIndex
= strlen(aExpectedSVPrefix
);
95 aPair
.Second
.Value
= uno::makeAny(static_cast<sal_uInt32
>(aToken
.getToken(0, '}', nIndex
).toInt32()));
97 static const char aExpectedSTPrefix
[] = ", Type = (short) ";
98 aToken
= aToken
.copy(nIndex
);
99 assert(aToken
.startsWith(aExpectedSTPrefix
));
100 nIndex
= strlen(aExpectedSTPrefix
);
101 aPair
.Second
.Type
= static_cast<sal_uInt16
>(aToken
.getToken(0, '}', nIndex
).toInt32());
105 drawing::EnhancedCustomShapeSegment
lcl_parseEnhancedCustomShapeSegment(const OString
& rValue
)
107 drawing::EnhancedCustomShapeSegment aSegment
;
108 OString aToken
= rValue
;
109 // We expect the followings here: Command, Count
110 static const char aExpectedCommandPrefix
[] = "Command = (short) ";
111 assert(aToken
.startsWith(aExpectedCommandPrefix
));
112 sal_Int32 nIndex
= strlen(aExpectedCommandPrefix
);
113 aSegment
.Command
= static_cast<sal_Int16
>(aToken
.getToken(0, ',', nIndex
).toInt32());
115 static const char aExpectedCountPrefix
[] = " Count = (short) ";
116 aToken
= aToken
.copy(nIndex
);
117 assert(aToken
.startsWith(aExpectedCountPrefix
));
118 nIndex
= strlen(aExpectedCountPrefix
);
119 aSegment
.Count
= static_cast<sal_Int16
>(aToken
.getToken(0, '}', nIndex
).toInt32());
123 awt::Rectangle
lcl_parseRectangle(const OString
& rValue
)
125 awt::Rectangle aRectangle
;
126 OString aToken
= rValue
;
127 // We expect the followings here: X, Y, Width, Height
128 static const char aExpectedXPrefix
[] = "X = (long) ";
129 assert(aToken
.startsWith(aExpectedXPrefix
));
130 sal_Int32 nIndex
= strlen(aExpectedXPrefix
);
131 aRectangle
.X
= static_cast<sal_Int32
>(aToken
.getToken(0, ',', nIndex
).toInt32());
133 static const char aExpectedYPrefix
[] = " Y = (long) ";
134 aToken
= aToken
.copy(nIndex
);
135 assert(aToken
.startsWith(aExpectedYPrefix
));
136 nIndex
= strlen(aExpectedYPrefix
);
137 aRectangle
.Y
= static_cast<sal_Int32
>(aToken
.getToken(0, ',', nIndex
).toInt32());
139 static const char aExpectedWidthPrefix
[] = " Width = (long) ";
140 aToken
= aToken
.copy(nIndex
);
141 assert(aToken
.startsWith(aExpectedWidthPrefix
));
142 nIndex
= strlen(aExpectedWidthPrefix
);
143 aRectangle
.Width
= static_cast<sal_Int32
>(aToken
.getToken(0, ',', nIndex
).toInt32());
145 static const char aExpectedHeightPrefix
[] = " Height = (long) ";
146 aToken
= aToken
.copy(nIndex
);
147 assert(aToken
.startsWith(aExpectedHeightPrefix
));
148 nIndex
= strlen(aExpectedHeightPrefix
);
149 aRectangle
.Height
= static_cast<sal_Int32
>(aToken
.copy(nIndex
).toInt32());
154 awt::Size
lcl_parseSize(const OString
& rValue
)
157 OString aToken
= rValue
;
158 // We expect the followings here: Width, Height
159 static const char aExpectedWidthPrefix
[] = "Width = (long) ";
160 assert(aToken
.startsWith(aExpectedWidthPrefix
));
161 sal_Int32 nIndex
= strlen(aExpectedWidthPrefix
);
162 aSize
.Width
= static_cast<sal_Int32
>(aToken
.getToken(0, ',', nIndex
).toInt32());
164 static const char aExpectedHeightPrefix
[] = " Height = (long) ";
165 aToken
= aToken
.copy(nIndex
);
166 assert(aToken
.startsWith(aExpectedHeightPrefix
));
167 nIndex
= strlen(aExpectedHeightPrefix
);
168 aSize
.Height
= static_cast<sal_Int32
>(aToken
.copy(nIndex
).toInt32());
173 drawing::EnhancedCustomShapeTextFrame
lcl_parseEnhancedCustomShapeTextFrame(const OString
& rValue
)
175 drawing::EnhancedCustomShapeTextFrame aTextFrame
;
176 sal_Int32 nLevel
= 0;
177 bool bIgnore
= false;
178 sal_Int32 nStart
= 0;
179 for (sal_Int32 i
= 0; i
< rValue
.getLength(); ++i
)
181 if (rValue
[i
] == '{')
187 else if (rValue
[i
] == '}')
193 else if (rValue
[i
] == ',' && !bIgnore
)
195 OString aToken
= rValue
.copy(nStart
, i
- nStart
);
196 static const char aExpectedPrefix
[] = "TopLeft = (com.sun.star.drawing.EnhancedCustomShapeParameterPair) { ";
197 if (aToken
.startsWith(aExpectedPrefix
))
199 aToken
= aToken
.copy(strlen(aExpectedPrefix
), aToken
.getLength() - strlen(aExpectedPrefix
) - strlen(" }"));
200 aTextFrame
.TopLeft
= lcl_parseEnhancedCustomShapeParameterPair(aToken
);
203 SAL_WARN("oox", "lcl_parseEnhancedCustomShapeTextFrame: unexpected token: " << aToken
);
204 nStart
= i
+ strlen(", ");
208 OString aToken
= rValue
.copy(nStart
, rValue
.getLength() - nStart
);
209 static const char aExpectedPrefix
[] = "BottomRight = (com.sun.star.drawing.EnhancedCustomShapeParameterPair) { ";
210 if (aToken
.startsWith(aExpectedPrefix
))
212 aToken
= aToken
.copy(strlen(aExpectedPrefix
), aToken
.getLength() - strlen(aExpectedPrefix
) - strlen(" }"));
213 aTextFrame
.BottomRight
= lcl_parseEnhancedCustomShapeParameterPair(aToken
);
216 SAL_WARN("oox", "lcl_parseEnhancedCustomShapeTextFrame: unexpected token at the end: " << aToken
);
221 // Parses a string like: Name = "Position", Handle = (long) 0, Value = (any) { ... }, State = (com.sun.star.beans.PropertyState) DIRECT_VALUE
222 // where "{ ... }" may contain "," as well.
223 void lcl_parseHandlePosition(std::vector
<beans::PropertyValue
>& rHandle
, const OString
& rValue
)
225 sal_Int32 nLevel
= 0;
226 bool bIgnore
= false;
227 sal_Int32 nStart
= 0;
228 for (sal_Int32 i
= 0; i
< rValue
.getLength(); ++i
)
230 if (rValue
[i
] == '{')
236 else if (rValue
[i
] == '}')
242 else if (rValue
[i
] == ',' && !bIgnore
)
244 OString aToken
= rValue
.copy(nStart
, i
- nStart
);
245 static const char aExpectedPrefix
[] = "Value = (any) { (com.sun.star.drawing.EnhancedCustomShapeParameterPair) { ";
246 if (aToken
.startsWith(aExpectedPrefix
))
248 aToken
= aToken
.copy(strlen(aExpectedPrefix
), aToken
.getLength() - strlen(aExpectedPrefix
) - strlen(" } }"));
250 beans::PropertyValue aPropertyValue
;
251 aPropertyValue
.Name
= "Position";
252 aPropertyValue
.Value
= uno::makeAny(lcl_parseEnhancedCustomShapeParameterPair(aToken
));
253 rHandle
.push_back(aPropertyValue
);
255 else if (!aToken
.startsWith("Name =") && !aToken
.startsWith("Handle ="))
256 SAL_WARN("oox", "lcl_parseHandlePosition: unexpected token: " << aToken
);
257 nStart
= i
+ strlen(", ");
262 // Parses a string like: Name = "RangeYMaximum", Handle = (long) 0, Value = (any) { ... }, State = (com.sun.star.beans.PropertyState) DIRECT_VALUE
263 // where "{ ... }" may contain "," as well.
264 void lcl_parseHandleRange(std::vector
<beans::PropertyValue
>& rHandle
, const OString
& rValue
, const OUString
& rName
)
266 sal_Int32 nLevel
= 0;
267 bool bIgnore
= false;
268 sal_Int32 nStart
= 0;
269 for (sal_Int32 i
= 0; i
< rValue
.getLength(); ++i
)
271 if (rValue
[i
] == '{')
277 else if (rValue
[i
] == '}')
283 else if (rValue
[i
] == ',' && !bIgnore
)
285 OString aToken
= rValue
.copy(nStart
, i
- nStart
);
286 static const char aExpectedPrefix
[] = "Value = (any) { (com.sun.star.drawing.EnhancedCustomShapeParameter) { ";
287 if (aToken
.startsWith(aExpectedPrefix
))
289 drawing::EnhancedCustomShapeParameter aParameter
;
290 aToken
= aToken
.copy(strlen(aExpectedPrefix
), aToken
.getLength() - strlen(aExpectedPrefix
) - strlen(" } }"));
291 // We expect the followings here: Value and Type
292 static const char aExpectedVPrefix
[] = "Value = (any) { (long) ";
293 assert(aToken
.startsWith(aExpectedVPrefix
));
294 sal_Int32 nIndex
= strlen(aExpectedVPrefix
);
295 aParameter
.Value
= uno::makeAny(aToken
.getToken(0, '}', nIndex
).toInt32());
297 static const char aExpectedTPrefix
[] = ", Type = (short) ";
298 aToken
= aToken
.copy(nIndex
);
299 assert(aToken
.startsWith(aExpectedTPrefix
));
300 nIndex
= strlen(aExpectedTPrefix
);
301 aParameter
.Type
= static_cast<sal_Int16
>(aToken
.getToken(0, '}', nIndex
).toInt32());
303 beans::PropertyValue aPropertyValue
;
304 aPropertyValue
.Name
= rName
;
305 aPropertyValue
.Value
= uno::makeAny(aParameter
);
306 rHandle
.push_back(aPropertyValue
);
309 else if (!aToken
.startsWith("Name =") && !aToken
.startsWith("Handle ="))
310 SAL_WARN("oox", "lcl_parseHandleRange: unexpected token: " << aToken
);
311 nStart
= i
+ strlen(", ");
316 // Parses a string like: Name = "RefY", Handle = (long) 0, Value = (any) { (long) 0 }, State = (com.sun.star.beans.PropertyState) DIRECT_VALUE
317 void lcl_parseHandleRef(std::vector
<beans::PropertyValue
>& rHandle
, const OString
& rValue
, const OUString
& rName
)
319 static const char aExpectedXPrefix
[] = "Name = \"RefX\", Handle = (long) 0, Value = (any) { (long) ";
320 static const char aExpectedYPrefix
[] = "Name = \"RefY\", Handle = (long) 0, Value = (any) { (long) ";
321 if (rValue
.startsWith(aExpectedXPrefix
) || rValue
.startsWith(aExpectedYPrefix
))
323 sal_Int32 nIndex
= strlen(aExpectedXPrefix
);
324 beans::PropertyValue aPropertyValue
;
325 aPropertyValue
.Name
= rName
;
326 // We only expect a Value here
327 aPropertyValue
.Value
= uno::makeAny(rValue
.getToken(0, '}', nIndex
).toInt32());
328 rHandle
.push_back(aPropertyValue
);
331 SAL_WARN("oox", "lcl_parseHandleRef: unexpected value: " << rValue
);
334 uno::Sequence
<beans::PropertyValue
> lcl_parseHandle(const OString
& rValue
)
336 std::vector
<beans::PropertyValue
> aRet
;
337 sal_Int32 nLevel
= 0;
338 sal_Int32 nStart
= 0;
339 for (sal_Int32 i
= 0; i
< rValue
.getLength(); ++i
)
341 if (rValue
[i
] == '{')
347 else if (rValue
[i
] == '}')
352 OString aToken
= rValue
.copy(nStart
+ strlen("{ "), i
- nStart
- strlen(" },"));
353 if (aToken
.startsWith("Name = \"Position\""))
354 lcl_parseHandlePosition(aRet
, aToken
);
355 else if (aToken
.startsWith("Name = \"RangeXMaximum\""))
356 lcl_parseHandleRange(aRet
, aToken
, "RangeXMaximum");
357 else if (aToken
.startsWith("Name = \"RangeXMinimum\""))
358 lcl_parseHandleRange(aRet
, aToken
, "RangeXMinimum");
359 else if (aToken
.startsWith("Name = \"RangeYMaximum\""))
360 lcl_parseHandleRange(aRet
, aToken
, "RangeYMaximum");
361 else if (aToken
.startsWith("Name = \"RangeYMinimum\""))
362 lcl_parseHandleRange(aRet
, aToken
, "RangeYMinimum");
363 else if (aToken
.startsWith("Name = \"RadiusRangeMaximum\""))
364 lcl_parseHandleRange(aRet
, aToken
, "RadiusRangeMaximum");
365 else if (aToken
.startsWith("Name = \"RadiusRangeMinimum\""))
366 lcl_parseHandleRange(aRet
, aToken
, "RadiusRangeMinimum");
367 else if (aToken
.startsWith("Name = \"RefX\""))
368 lcl_parseHandleRef(aRet
, aToken
, "RefX");
369 else if (aToken
.startsWith("Name = \"RefY\""))
370 lcl_parseHandleRef(aRet
, aToken
, "RefY");
372 SAL_WARN("oox", "lcl_parseHandle: unexpected token: " << aToken
);
376 return comphelper::containerToSequence(aRet
);
379 void lcl_parseHandles(std::vector
< uno::Sequence
<beans::PropertyValue
> >& rHandles
, const OString
& rValue
)
381 sal_Int32 nLevel
= 0;
382 sal_Int32 nStart
= 0;
383 for (sal_Int32 i
= 0; i
< rValue
.getLength(); ++i
)
385 if (rValue
[i
] == '{')
391 else if (rValue
[i
] == '}')
396 uno::Sequence
<beans::PropertyValue
> aHandle
= lcl_parseHandle(rValue
.copy(nStart
+ strlen("{ "), i
- nStart
- strlen(" },")));
397 rHandles
.push_back(aHandle
);
403 void lcl_parseEquations(std::vector
<OUString
>& rEquations
, const OString
& rValue
)
405 bool bInString
= false;
406 sal_Int32 nStart
= 0;
407 for (sal_Int32 i
= 0; i
< rValue
.getLength(); ++i
)
409 if (rValue
[i
] == '"' && !bInString
)
414 else if (rValue
[i
] == '"' && bInString
)
417 rEquations
.push_back(OUString::fromUtf8(rValue
.copy(nStart
+ strlen("\""), i
- nStart
- strlen("\""))));
422 void lcl_parsePathCoordinateValues(std::vector
<beans::PropertyValue
>& rPath
, const OString
& rValue
)
424 std::vector
<drawing::EnhancedCustomShapeParameterPair
> aPairs
;
425 sal_Int32 nLevel
= 0;
426 sal_Int32 nStart
= 0;
427 for (sal_Int32 i
= 0; i
< rValue
.getLength(); ++i
)
429 if (rValue
[i
] == '{')
435 else if (rValue
[i
] == '}')
439 aPairs
.push_back(lcl_parseEnhancedCustomShapeParameterPair(rValue
.copy(nStart
+ strlen("{ "), i
- nStart
- strlen(" },"))));
443 beans::PropertyValue aPropertyValue
;
444 aPropertyValue
.Name
= "Coordinates";
445 aPropertyValue
.Value
= uno::makeAny(comphelper::containerToSequence(aPairs
));
446 rPath
.push_back(aPropertyValue
);
449 // Parses a string like: Name = "Coordinates", Handle = (long) 0, Value = (any) { ... }, State = (com.sun.star.beans.PropertyState) DIRECT_VALUE
450 // where "{ ... }" may contain "," as well.
451 void lcl_parsePathCoordinates(std::vector
<beans::PropertyValue
>& rPath
, const OString
& rValue
)
453 sal_Int32 nLevel
= 0;
454 bool bIgnore
= false;
455 sal_Int32 nStart
= 0;
456 for (sal_Int32 i
= 0; i
< rValue
.getLength(); ++i
)
458 if (rValue
[i
] == '{')
464 else if (rValue
[i
] == '}')
470 else if (rValue
[i
] == ',' && !bIgnore
)
472 OString aToken
= rValue
.copy(nStart
, i
- nStart
);
473 static const char aExpectedPrefix
[] = "Value = (any) { ([]com.sun.star.drawing.EnhancedCustomShapeParameterPair) { ";
474 if (aToken
.startsWith(aExpectedPrefix
))
476 aToken
= aToken
.copy(strlen(aExpectedPrefix
), aToken
.getLength() - strlen(aExpectedPrefix
) - strlen(" } }"));
477 lcl_parsePathCoordinateValues(rPath
, aToken
);
479 else if (!aToken
.startsWith("Name =") && !aToken
.startsWith("Handle ="))
480 SAL_WARN("oox", "lcl_parsePathCoordinates: unexpected token: " << aToken
);
481 nStart
= i
+ strlen(", ");
486 void lcl_parsePathSegmentValues(std::vector
<beans::PropertyValue
>& rPath
, const OString
& rValue
)
488 std::vector
<drawing::EnhancedCustomShapeSegment
> aSegments
;
489 sal_Int32 nLevel
= 0;
490 sal_Int32 nStart
= 0;
491 for (sal_Int32 i
= 0; i
< rValue
.getLength(); ++i
)
493 if (rValue
[i
] == '{')
499 else if (rValue
[i
] == '}')
503 aSegments
.push_back(lcl_parseEnhancedCustomShapeSegment(rValue
.copy(nStart
+ strlen("{ "), i
- nStart
- strlen(" },"))));
507 beans::PropertyValue aPropertyValue
;
508 aPropertyValue
.Name
= "Segments";
509 aPropertyValue
.Value
= uno::makeAny(comphelper::containerToSequence(aSegments
));
510 rPath
.push_back(aPropertyValue
);
513 // Parses a string like: Name = "Segments", Handle = (long) 0, Value = (any) { ... }, State = (com.sun.star.beans.PropertyState) DIRECT_VALUE
514 // where "{ ... }" may contain "," as well.
515 void lcl_parsePathSegments(std::vector
<beans::PropertyValue
>& rPath
, const OString
& rValue
)
517 sal_Int32 nLevel
= 0;
518 bool bIgnore
= false;
519 sal_Int32 nStart
= 0;
520 for (sal_Int32 i
= 0; i
< rValue
.getLength(); ++i
)
522 if (rValue
[i
] == '{')
528 else if (rValue
[i
] == '}')
534 else if (rValue
[i
] == ',' && !bIgnore
)
536 OString aToken
= rValue
.copy(nStart
, i
- nStart
);
537 static const char aExpectedPrefix
[] = "Value = (any) { ([]com.sun.star.drawing.EnhancedCustomShapeSegment) { ";
538 if (aToken
.startsWith(aExpectedPrefix
))
540 aToken
= aToken
.copy(strlen(aExpectedPrefix
), aToken
.getLength() - strlen(aExpectedPrefix
) - strlen(" } }"));
541 lcl_parsePathSegmentValues(rPath
, aToken
);
543 else if (!aToken
.startsWith("Name =") && !aToken
.startsWith("Handle ="))
544 SAL_WARN("oox", "lcl_parsePathSegments: unexpected token: " << aToken
);
545 nStart
= i
+ strlen(", ");
550 void lcl_parsePathTextFrameValues(std::vector
<beans::PropertyValue
>& rPath
, const OString
& rValue
)
552 std::vector
<drawing::EnhancedCustomShapeTextFrame
> aTextFrames
;
553 sal_Int32 nLevel
= 0;
554 sal_Int32 nStart
= 0;
555 for (sal_Int32 i
= 0; i
< rValue
.getLength(); ++i
)
557 if (rValue
[i
] == '{')
563 else if (rValue
[i
] == '}')
567 aTextFrames
.push_back(lcl_parseEnhancedCustomShapeTextFrame(rValue
.copy(nStart
+ strlen("{ "), i
- nStart
- strlen(" },"))));
571 beans::PropertyValue aPropertyValue
;
572 aPropertyValue
.Name
= "TextFrames";
573 aPropertyValue
.Value
= uno::makeAny(comphelper::containerToSequence(aTextFrames
));
574 rPath
.push_back(aPropertyValue
);
577 // Parses a string like: Name = "TextFrames", Handle = (long) 0, Value = (any) { ... }, State = (com.sun.star.beans.PropertyState) DIRECT_VALUE
578 // where "{ ... }" may contain "," as well.
579 void lcl_parsePathTextFrames(std::vector
<beans::PropertyValue
>& rPath
, const OString
& rValue
)
581 sal_Int32 nLevel
= 0;
582 bool bIgnore
= false;
583 sal_Int32 nStart
= 0;
584 for (sal_Int32 i
= 0; i
< rValue
.getLength(); ++i
)
586 if (rValue
[i
] == '{')
592 else if (rValue
[i
] == '}')
598 else if (rValue
[i
] == ',' && !bIgnore
)
600 OString aToken
= rValue
.copy(nStart
, i
- nStart
);
601 static const char aExpectedPrefix
[] = "Value = (any) { ([]com.sun.star.drawing.EnhancedCustomShapeTextFrame) { ";
602 if (aToken
.startsWith(aExpectedPrefix
))
604 aToken
= aToken
.copy(strlen(aExpectedPrefix
), aToken
.getLength() - strlen(aExpectedPrefix
) - strlen(" } }"));
605 lcl_parsePathTextFrameValues(rPath
, aToken
);
607 else if (!aToken
.startsWith("Name =") && !aToken
.startsWith("Handle ="))
608 SAL_WARN("oox", "lcl_parsePathTextFrames: unexpected token: " << aToken
);
609 nStart
= i
+ strlen(", ");
614 void lcl_parsePathSubViewSizeValues(std::vector
<beans::PropertyValue
>& rPath
, const OString
& rValue
)
616 std::vector
<awt::Size
> aSizes
;
617 sal_Int32 nLevel
= 0;
618 sal_Int32 nStart
= 0;
619 for (sal_Int32 i
= 0; i
< rValue
.getLength(); ++i
)
621 if (rValue
[i
] == '{')
627 else if (rValue
[i
] == '}')
631 aSizes
.push_back(lcl_parseSize(rValue
.copy(nStart
+ strlen("{ "), i
- nStart
- strlen(" },"))));
635 beans::PropertyValue aPropertyValue
;
636 aPropertyValue
.Name
= "SubViewSize";
637 aPropertyValue
.Value
= uno::makeAny(comphelper::containerToSequence(aSizes
));
638 rPath
.push_back(aPropertyValue
);
641 void lcl_parsePathSubViewSize(std::vector
<beans::PropertyValue
>& rPath
, const OString
& rValue
)
643 sal_Int32 nLevel
= 0;
644 bool bIgnore
= false;
645 sal_Int32 nStart
= 0;
646 for (sal_Int32 i
= 0; i
< rValue
.getLength(); ++i
)
648 if (rValue
[i
] == '{')
654 else if (rValue
[i
] == '}')
660 else if (rValue
[i
] == ',' && !bIgnore
)
662 OString aToken
= rValue
.copy(nStart
, i
- nStart
);
663 static const char aExpectedPrefix
[] = "Value = (any) { ([]com.sun.star.awt.Size) { ";
664 if (aToken
.startsWith(aExpectedPrefix
))
666 aToken
= aToken
.copy(strlen(aExpectedPrefix
), aToken
.getLength() - strlen(aExpectedPrefix
) - strlen(" } }"));
667 lcl_parsePathSubViewSizeValues(rPath
, aToken
);
669 else if (!aToken
.startsWith("Name =") && !aToken
.startsWith("Handle ="))
670 SAL_WARN("oox", "lcl_parsePathSubViewSize: unexpected token: " << aToken
);
671 nStart
= i
+ strlen(", ");
676 void lcl_parsePath(std::vector
<beans::PropertyValue
>& rPath
, const OString
& rValue
)
678 sal_Int32 nLevel
= 0;
679 sal_Int32 nStart
= 0;
680 for (sal_Int32 i
= 0; i
< rValue
.getLength(); ++i
)
682 if (rValue
[i
] == '{')
688 else if (rValue
[i
] == '}')
693 OString aToken
= rValue
.copy(nStart
+ strlen("{ "), i
- nStart
- strlen(" },"));
694 if (aToken
.startsWith("Name = \"Coordinates\""))
695 lcl_parsePathCoordinates(rPath
, aToken
);
696 else if (aToken
.startsWith("Name = \"Segments\""))
697 lcl_parsePathSegments(rPath
, aToken
);
698 else if (aToken
.startsWith("Name = \"TextFrames\""))
699 lcl_parsePathTextFrames(rPath
, aToken
);
700 else if (aToken
.startsWith("Name = \"SubViewSize\""))
701 lcl_parsePathSubViewSize(rPath
, aToken
);
703 SAL_WARN("oox", "lcl_parsePath: unexpected token: " << aToken
);
716 void CustomShapeProperties::initializePresetDataMap()
718 OUString
aPath("$BRAND_BASE_DIR/" LIBO_SHARE_FOLDER
"/filter/oox-drawingml-cs-presets");
719 rtl::Bootstrap::expandMacros(aPath
);
720 SvFileStream
aStream(aPath
, StreamMode::READ
);
721 if (aStream
.GetError() != ERRCODE_NONE
)
722 SAL_WARN("oox", "failed to open oox-drawingml-cs-presets");
725 bool bNotDone
= aStream
.ReadLine(aLine
);
726 PropertyMap aPropertyMap
;
730 static const char aCommentPrefix
[] = "/* ";
731 if (aLine
.startsWith(aCommentPrefix
))
736 maPresetDataMap
[TokenMap::getTokenFromUnicode(aName
)] = aPropertyMap
;
737 aName
= OUString::fromUtf8(aLine
.copy(strlen(aCommentPrefix
), aLine
.getLength() - strlen(aCommentPrefix
) - strlen(" */")));
741 if (aLine
== "AdjustmentValues")
743 aStream
.ReadLine(aLine
);
744 if (aLine
!= "([]com.sun.star.drawing.EnhancedCustomShapeAdjustmentValue) {}")
746 std::vector
<drawing::EnhancedCustomShapeAdjustmentValue
> aAdjustmentValues
;
747 OString
aExpectedPrefix("([]com.sun.star.drawing.EnhancedCustomShapeAdjustmentValue) { ");
748 assert(aLine
.startsWith(aExpectedPrefix
));
750 OString aValue
= aLine
.copy(aExpectedPrefix
.getLength(), aLine
.getLength() - aExpectedPrefix
.getLength() - strlen(" }"));
751 lcl_parseAdjustmentValues(aAdjustmentValues
, aValue
);
752 aPropertyMap
.setProperty(PROP_AdjustmentValues
, comphelper::containerToSequence(aAdjustmentValues
));
755 aPropertyMap
.setProperty(PROP_AdjustmentValues
, uno::Sequence
<OUString
>(0));
757 else if (aLine
== "Equations")
759 aStream
.ReadLine(aLine
);
760 if (aLine
!= "([]string) {}")
762 std::vector
<OUString
> aEquations
;
763 OString
aExpectedPrefix("([]string) { ");
764 assert(aLine
.startsWith(aExpectedPrefix
));
766 OString aValue
= aLine
.copy(aExpectedPrefix
.getLength(), aLine
.getLength() - aExpectedPrefix
.getLength() - strlen(" }"));
767 lcl_parseEquations(aEquations
, aValue
);
768 aPropertyMap
.setProperty(PROP_Equations
, comphelper::containerToSequence(aEquations
));
771 aPropertyMap
.setProperty(PROP_Equations
, uno::Sequence
<OUString
>(0));
773 else if (aLine
== "Handles")
775 aStream
.ReadLine(aLine
);
776 if (aLine
!= "([][]com.sun.star.beans.PropertyValue) {}")
778 std::vector
< uno::Sequence
<beans::PropertyValue
> > aHandles
;
779 OString
aExpectedPrefix("([][]com.sun.star.beans.PropertyValue) { ");
780 assert(aLine
.startsWith(aExpectedPrefix
));
782 OString aValue
= aLine
.copy(aExpectedPrefix
.getLength(), aLine
.getLength() - aExpectedPrefix
.getLength() - strlen(" }"));
783 lcl_parseHandles(aHandles
, aValue
);
784 aPropertyMap
.setProperty(PROP_Handles
, comphelper::containerToSequence(aHandles
));
787 aPropertyMap
.setProperty(PROP_Handles
, uno::Sequence
<OUString
>(0));
789 else if (aLine
== "MirroredX")
791 aStream
.ReadLine(aLine
);
792 if (aLine
== "true" || aLine
== "false")
794 aPropertyMap
.setProperty(PROP_MirroredX
, aLine
== "true");
797 SAL_WARN("oox", "CustomShapeProperties::initializePresetDataMap: unexpected MirroredX parameter");
799 else if (aLine
== "MirroredY")
801 aStream
.ReadLine(aLine
);
802 if (aLine
== "true" || aLine
== "false")
804 aPropertyMap
.setProperty(PROP_MirroredY
, aLine
== "true");
807 SAL_WARN("oox", "CustomShapeProperties::initializePresetDataMap: unexpected MirroredY parameter");
809 else if (aLine
== "Path")
811 aStream
.ReadLine(aLine
);
812 OString
aExpectedPrefix("([]com.sun.star.beans.PropertyValue) { ");
813 assert(aLine
.startsWith(aExpectedPrefix
));
815 std::vector
<beans::PropertyValue
> aPathValue
;
816 OString aValue
= aLine
.copy(aExpectedPrefix
.getLength(), aLine
.getLength() - aExpectedPrefix
.getLength() - strlen(" }"));
817 lcl_parsePath(aPathValue
, aValue
);
818 aPropertyMap
.setProperty(PROP_Path
, comphelper::containerToSequence(aPathValue
));
820 else if (aLine
== "Type")
822 // Just ignore the line here, we already know the correct type.
823 aStream
.ReadLine(aLine
);
824 aPropertyMap
.setProperty(PROP_Type
, "ooxml-" + aName
);
826 else if (aLine
== "ViewBox")
828 aStream
.ReadLine(aLine
);
829 OString
aExpectedPrefix("(com.sun.star.awt.Rectangle) { ");
830 assert(aLine
.startsWith(aExpectedPrefix
));
832 OString aValue
= aLine
.copy(aExpectedPrefix
.getLength(), aLine
.getLength() - aExpectedPrefix
.getLength() - strlen(" }"));
833 aPropertyMap
.setProperty(PROP_ViewBox
, lcl_parseRectangle(aValue
));
836 SAL_WARN("oox", "CustomShapeProperties::initializePresetDataMap: unhandled line: " << aLine
);
838 bNotDone
= aStream
.ReadLine(aLine
);
840 maPresetDataMap
[TokenMap::getTokenFromUnicode(aName
)] = aPropertyMap
;
846 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */