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/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
;
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
)
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
);
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
)
60 for (sal_Int32 i
= 0; i
< rValue
.getLength(); ++i
)
68 else if (rValue
[i
] == '}')
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());
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());
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();
158 awt::Size
lcl_parseSize(const OString
& rValue
)
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();
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
] == '{')
191 else if (rValue
[i
] == '}')
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
);
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
);
220 SAL_WARN("oox", "lcl_parseEnhancedCustomShapeTextFrame: unexpected token at the end: " << aToken
);
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
] == '{')
240 else if (rValue
[i
] == '}')
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
] == '{')
281 else if (rValue
[i
] == '}')
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
);
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
] == '{')
353 else if (rValue
[i
] == '}')
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");
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
] == '{')
401 else if (rValue
[i
] == '}')
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
)
424 else if (rValue
[i
] == '"' && bInString
)
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
] == '{')
445 else if (rValue
[i
] == '}')
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
] == '{')
474 else if (rValue
[i
] == '}')
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
] == '{')
509 else if (rValue
[i
] == '}')
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
] == '{')
538 else if (rValue
[i
] == '}')
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
] == '{')
573 else if (rValue
[i
] == '}')
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
] == '{')
602 else if (rValue
[i
] == '}')
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
] == '{')
637 else if (rValue
[i
] == '}')
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
] == '{')
664 else if (rValue
[i
] == '}')
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
] == '{')
698 else if (rValue
[i
] == '}')
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
);
713 SAL_WARN("oox", "lcl_parsePath: unexpected token: " << aToken
);
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");
735 bool bNotDone
= aStream
.ReadLine(aLine
);
736 PropertyMap aPropertyMap
;
740 static const char aCommentPrefix
[] = "/* ";
741 if (aLine
.startsWith(aCommentPrefix
))
746 maPresetDataMap
[TokenMap::getTokenFromUnicode(aName
)] = aPropertyMap
;
747 aName
= OUString::fromUtf8(aLine
.copy(strlen(aCommentPrefix
), aLine
.getLength() - strlen(aCommentPrefix
) - strlen(" */")));
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
));
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
));
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
));
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");
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");
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
));
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: */