1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
4 *
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 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20 #include <com/sun/star/drawing/PolyPolygonBezierCoords.hpp>
21 #include <com/sun/star/lang/DisposedException.hpp>
22 #include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
23 #include <com/sun/star/awt/FontSlant.hpp>
24 #include <com/sun/star/style/VerticalAlignment.hpp>
25 #include <com/sun/star/drawing/TextVerticalAdjust.hpp>
26 #include <com/sun/star/drawing/XEnhancedCustomShapeDefaulter.hpp>
27 #include <com/sun/star/awt/TextAlign.hpp>
28 #include <com/sun/star/style/ParagraphAdjust.hpp>
29 #include <com/sun/star/drawing/PointSequenceSequence.hpp>
30 #include <com/sun/star/drawing/PointSequence.hpp>
31 #include <com/sun/star/drawing/PolygonKind.hpp>
32 #include <com/sun/star/graphic/XGraphic.hpp>
33 #include <com/sun/star/drawing/QRCode.hpp>
34 #include <o3tl/any.hxx>
35 #include <o3tl/safeint.hxx>
36 #include <vcl/svapp.hxx>
37 #include <vcl/wmf.hxx>
38 #include <vcl/cvtgrf.hxx>
39 #include <vcl/GraphicLoader.hxx>
40
41 #include <svx/svdpool.hxx>
42
43 #include <editeng/unoprnms.hxx>
44 #include <svx/unoshape.hxx>
45 #include <svx/unopage.hxx>
46 #include <svx/svdobj.hxx>
47 #include <svx/svdpage.hxx>
48 #include <svx/svdmodel.hxx>
49 #include <svx/svdouno.hxx>
50 #include "shapeimpl.hxx"
51 #include <svx/unoshprp.hxx>
52 #include <svx/svdoashp.hxx>
53 #include <svx/svdviter.hxx>
54 #include <svx/svdview.hxx>
55 #include <svx/svdopath.hxx>
56 #include <basegfx/matrix/b2dhommatrix.hxx>
57 #include <basegfx/polygon/b2dpolygon.hxx>
58 #include <basegfx/point/b2dpoint.hxx>
59 #include <basegfx/polygon/b2dpolygontools.hxx>
60 #include <basegfx/polygon/b2dpolypolygontools.hxx>
61 #include <com/sun/star/awt/XBitmap.hpp>
62 #include <svx/svdograf.hxx>
63 #include <sal/log.hxx>
64 #include <cppuhelper/queryinterface.hxx>
65 #include <tools/stream.hxx>
66
67
68 #include <memory>
69
70 using namespace ::osl;
71 using namespace ::cppu;
72 using namespace ::com::sun::star;
73 using namespace ::com::sun::star::uno;
74 using namespace ::com::sun::star::lang;
75 using namespace ::com::sun::star::container;
76
77 #define QUERYINT( xint ) \
78 if( rType == cppu::UnoType<xint>::get() ) \
79 aAny <<= Reference< xint >(this)
80
SvxShapeGroup(SdrObject * pObj,SvxDrawPage * pDrawPage)81 SvxShapeGroup::SvxShapeGroup(SdrObject* pObj, SvxDrawPage* pDrawPage)
82 : SvxShape(pObj, getSvxMapProvider().GetMap(SVXMAP_GROUP), getSvxMapProvider().GetPropertySet(SVXMAP_GROUP, SdrObject::GetGlobalDrawObjectItemPool()))
83 , mxPage(pDrawPage)
84 {
85 }
86
~SvxShapeGroup()87 SvxShapeGroup::~SvxShapeGroup() noexcept
88 {
89 }
90
Create(SdrObject * pNewObj,SvxDrawPage * pNewPage)91 void SvxShapeGroup::Create( SdrObject* pNewObj, SvxDrawPage* pNewPage )
92 {
93 SvxShape::Create( pNewObj, pNewPage );
94 mxPage = pNewPage;
95 }
96
97
queryInterface(const uno::Type & rType)98 uno::Any SAL_CALL SvxShapeGroup::queryInterface( const uno::Type & rType )
99 {
100 return SvxShape::queryInterface( rType );
101 }
102
queryAggregation(const uno::Type & rType)103 uno::Any SAL_CALL SvxShapeGroup::queryAggregation( const uno::Type & rType )
104 {
105 uno::Any aAny;
106
107 QUERYINT( drawing::XShapeGroup );
108 else QUERYINT( drawing::XShapes );
109 else QUERYINT( drawing::XShapes2 );
110 else QUERYINT( container::XIndexAccess );
111 else QUERYINT( container::XElementAccess );
112 else
113 return SvxShape::queryAggregation( rType );
114
115 return aAny;
116 }
117
getImplementationId()118 uno::Sequence< sal_Int8 > SAL_CALL SvxShapeGroup::getImplementationId()
119 {
120 return css::uno::Sequence<sal_Int8>();
121 }
122
123 // css::drawing::XShape
124
125
getShapeType()126 OUString SAL_CALL SvxShapeGroup::getShapeType()
127 {
128 return SvxShape::getShapeType();
129 }
130
getPosition()131 awt::Point SAL_CALL SvxShapeGroup::getPosition()
132 {
133 return SvxShape::getPosition();
134 }
135
136
setPosition(const awt::Point & Position)137 void SAL_CALL SvxShapeGroup::setPosition( const awt::Point& Position )
138 {
139 SvxShape::setPosition(Position);
140 }
141
142
getSize()143 awt::Size SAL_CALL SvxShapeGroup::getSize()
144 {
145 return SvxShape::getSize();
146 }
147
148
setSize(const awt::Size & rSize)149 void SAL_CALL SvxShapeGroup::setSize( const awt::Size& rSize )
150 {
151 SvxShape::setSize( rSize );
152 }
153
154 // drawing::XShapeGroup
155
156
enterGroup()157 void SAL_CALL SvxShapeGroup::enterGroup( )
158 {
159 // Todo
160 // pDrView->EnterMarkedGroup();
161 }
162
163
leaveGroup()164 void SAL_CALL SvxShapeGroup::leaveGroup( )
165 {
166 // Todo
167 // pDrView->LeaveOneGroup();
168 }
169
addUnoShape(const uno::Reference<drawing::XShape> & xShape,size_t nPos)170 void SvxShapeGroup::addUnoShape( const uno::Reference< drawing::XShape >& xShape, size_t nPos )
171 {
172 if (!HasSdrObject() || !mxPage.is())
173 {
174 OSL_FAIL("could not add XShape to group shape!");
175 return;
176 }
177
178 SvxShape* pShape = comphelper::getUnoTunnelImplementation<SvxShape>( xShape );
179 if (!pShape)
180 {
181 OSL_FAIL("could not add XShape to group shape!");
182 return;
183 }
184
185 SdrObject* pSdrShape = pShape->GetSdrObject();
186 if( pSdrShape == nullptr )
187 pSdrShape = mxPage->CreateSdrObject_( xShape );
188
189 if( pSdrShape->IsInserted() )
190 pSdrShape->getParentSdrObjListFromSdrObject()->RemoveObject( pSdrShape->GetOrdNum() );
191
192 GetSdrObject()->GetSubList()->InsertObject(pSdrShape, nPos);
193 // TTTT Was created using mpModel in CreateSdrObject_ above
194 // TTTT may be good to add an assertion here for the future
195 // pSdrShape->SetModel(GetSdrObject()->GetModel());
196
197 // #85922# It makes no sense to set the layer asked
198 // from the group object since this is an iteration
199 // over the contained objects. In consequence, this
200 // statement erases all layer information from the draw
201 // objects. Layers need to be set at draw objects directly
202 // and have nothing to do with grouping at all.
203 // pSdrShape->SetLayer(pObject->GetLayer());
204
205 // Establish connection between new SdrObject and its wrapper before
206 // inserting the new shape into the group. There a new wrapper
207 // would be created when this connection would not already exist.
208 pShape->Create( pSdrShape, mxPage.get() );
209
210 GetSdrObject()->getSdrModelFromSdrObject().SetChanged();
211 }
212
213 // XShapes
add(const uno::Reference<drawing::XShape> & xShape)214 void SAL_CALL SvxShapeGroup::add( const uno::Reference< drawing::XShape >& xShape )
215 {
216 ::SolarMutexGuard aGuard;
217
218 // Add to the top of the stack (i.e. bottom of the list) by default.
219 addUnoShape(xShape, SAL_MAX_SIZE);
220 }
221
222
remove(const uno::Reference<drawing::XShape> & xShape)223 void SAL_CALL SvxShapeGroup::remove( const uno::Reference< drawing::XShape >& xShape )
224 {
225 ::SolarMutexGuard aGuard;
226
227 SdrObject* pSdrShape = SdrObject::getSdrObjectFromXShape( xShape );
228
229 if( !HasSdrObject() || pSdrShape == nullptr || pSdrShape->getParentSdrObjectFromSdrObject() != GetSdrObject() )
230 throw uno::RuntimeException();
231
232 SdrObjList& rList = *pSdrShape->getParentSdrObjListFromSdrObject();
233
234 const size_t nObjCount = rList.GetObjCount();
235 size_t nObjNum = 0;
236 while( nObjNum < nObjCount )
237 {
238 if(rList.GetObj( nObjNum ) == pSdrShape )
239 break;
240 nObjNum++;
241 }
242
243 if( nObjNum < nObjCount )
244 {
245 // #i29181#
246 // If the SdrObject which is about to be deleted is in any selection,
247 // deselect it first.
248 SdrViewIter aIter( pSdrShape );
249
250 for ( SdrView* pView = aIter.FirstView(); pView; pView = aIter.NextView() )
251 {
252 if(SAL_MAX_SIZE != pView->TryToFindMarkedObject(pSdrShape))
253 {
254 pView->MarkObj(pSdrShape, pView->GetSdrPageView(), true);
255 }
256 }
257
258 SdrObject* pObject = rList.NbcRemoveObject( nObjNum );
259 SdrObject::Free( pObject );
260 }
261 else
262 {
263 SAL_WARN( "svx", "Fatality! SdrObject is not belonging to its SdrObjList! [CL]" );
264 }
265
266 GetSdrObject()->getSdrModelFromSdrObject().SetChanged();
267 }
268
addTop(const uno::Reference<drawing::XShape> & xShape)269 void SAL_CALL SvxShapeGroup::addTop( const uno::Reference< drawing::XShape >& xShape )
270 {
271 SolarMutexGuard aGuard;
272
273 // Add to the top of the stack (i.e. bottom of the list).
274 addUnoShape(xShape, SAL_MAX_SIZE);
275 }
276
addBottom(const uno::Reference<drawing::XShape> & xShape)277 void SAL_CALL SvxShapeGroup::addBottom( const uno::Reference< drawing::XShape >& xShape )
278 {
279 SolarMutexGuard aGuard;
280
281 // Add to the bottom of the stack (i.e. top of the list).
282 addUnoShape(xShape, 0);
283 }
284
285 // XIndexAccess
286
287
getCount()288 sal_Int32 SAL_CALL SvxShapeGroup::getCount()
289 {
290 ::SolarMutexGuard aGuard;
291
292 if(!HasSdrObject() || !GetSdrObject()->GetSubList())
293 throw uno::RuntimeException();
294
295 sal_Int32 nRetval = GetSdrObject()->GetSubList()->GetObjCount();
296 return nRetval;
297 }
298
299
getByIndex(sal_Int32 Index)300 uno::Any SAL_CALL SvxShapeGroup::getByIndex( sal_Int32 Index )
301 {
302 ::SolarMutexGuard aGuard;
303
304 if( !HasSdrObject() || GetSdrObject()->GetSubList() == nullptr )
305 throw uno::RuntimeException();
306
307 if( Index<0 || GetSdrObject()->GetSubList()->GetObjCount() <= o3tl::make_unsigned(Index) )
308 throw lang::IndexOutOfBoundsException();
309
310 SdrObject* pDestObj = GetSdrObject()->GetSubList()->GetObj( Index );
311
312 if(pDestObj == nullptr)
313 throw lang::IndexOutOfBoundsException();
314
315 Reference< drawing::XShape > xShape( pDestObj->getUnoShape(), uno::UNO_QUERY );
316 return uno::makeAny( xShape );
317 }
318
319 // css::container::XElementAccess
320
321
getElementType()322 uno::Type SAL_CALL SvxShapeGroup::getElementType()
323 {
324 return cppu::UnoType<drawing::XShape>::get();
325 }
326
327
hasElements()328 sal_Bool SAL_CALL SvxShapeGroup::hasElements()
329 {
330 ::SolarMutexGuard aGuard;
331
332 return HasSdrObject() && GetSdrObject()->GetSubList() && (GetSdrObject()->GetSubList()->GetObjCount() > 0);
333 }
334
SvxShapeConnector(SdrObject * pObj)335 SvxShapeConnector::SvxShapeConnector(SdrObject* pObj)
336 : SvxShapeText( pObj, getSvxMapProvider().GetMap(SVXMAP_CONNECTOR), getSvxMapProvider().GetPropertySet(SVXMAP_CONNECTOR, SdrObject::GetGlobalDrawObjectItemPool()) )
337 {
338 }
339
340
~SvxShapeConnector()341 SvxShapeConnector::~SvxShapeConnector() noexcept
342 {
343 }
344
345
queryInterface(const uno::Type & rType)346 uno::Any SAL_CALL SvxShapeConnector::queryInterface( const uno::Type & rType )
347 {
348 return SvxShapeText::queryInterface( rType );
349 }
350
queryAggregation(const uno::Type & rType)351 uno::Any SAL_CALL SvxShapeConnector::queryAggregation( const uno::Type & rType )
352 {
353 uno::Any aAny;
354
355 QUERYINT( drawing::XConnectorShape );
356 else
357 return SvxShapeText::queryAggregation( rType );
358
359 return aAny;
360 }
361
362 // XTypeProvider
363
getTypes()364 uno::Sequence< uno::Type > SAL_CALL SvxShapeConnector::getTypes()
365 {
366 return SvxShape::getTypes();
367 }
368
getImplementationId()369 uno::Sequence< sal_Int8 > SAL_CALL SvxShapeConnector::getImplementationId()
370 {
371 return css::uno::Sequence<sal_Int8>();
372 }
373
374 // css::drawing::XShape
375
376
getShapeType()377 OUString SAL_CALL SvxShapeConnector::getShapeType()
378 {
379 return SvxShapeText::getShapeType();
380 }
381
getPosition()382 awt::Point SAL_CALL SvxShapeConnector::getPosition()
383 {
384 return SvxShapeText::getPosition();
385 }
386
387
setPosition(const awt::Point & Position)388 void SAL_CALL SvxShapeConnector::setPosition( const awt::Point& Position )
389 {
390 SvxShapeText::setPosition(Position);
391 }
392
393
getSize()394 awt::Size SAL_CALL SvxShapeConnector::getSize()
395 {
396 return SvxShapeText::getSize();
397 }
398
399
setSize(const awt::Size & rSize)400 void SAL_CALL SvxShapeConnector::setSize( const awt::Size& rSize )
401 {
402 SvxShapeText::setSize( rSize );
403 }
404
405
406 // XConnectorShape
407
connectStart(const uno::Reference<drawing::XConnectableShape> & xShape,drawing::ConnectionType)408 void SAL_CALL SvxShapeConnector::connectStart( const uno::Reference< drawing::XConnectableShape >& xShape, drawing::ConnectionType )
409 {
410 ::SolarMutexGuard aGuard;
411
412 Reference< drawing::XShape > xRef( xShape, UNO_QUERY );
413 SdrObject* pSdrObject = SdrObject::getSdrObjectFromXShape( xRef );
414
415 if( pSdrObject )
416 GetSdrObject()->ConnectToNode( true, pSdrObject );
417
418 GetSdrObject()->getSdrModelFromSdrObject().SetChanged();
419 }
420
421
connectEnd(const uno::Reference<drawing::XConnectableShape> & xShape,drawing::ConnectionType)422 void SAL_CALL SvxShapeConnector::connectEnd( const uno::Reference< drawing::XConnectableShape >& xShape, drawing::ConnectionType )
423 {
424 ::SolarMutexGuard aGuard;
425
426 Reference< drawing::XShape > xRef( xShape, UNO_QUERY );
427 SdrObject* pSdrObject = SdrObject::getSdrObjectFromXShape( xRef );
428
429 if( HasSdrObject() && pSdrObject )
430 GetSdrObject()->ConnectToNode( false, pSdrObject );
431
432 GetSdrObject()->getSdrModelFromSdrObject().SetChanged();
433 }
434
435
disconnectBegin(const uno::Reference<drawing::XConnectableShape> &)436 void SAL_CALL SvxShapeConnector::disconnectBegin( const uno::Reference< drawing::XConnectableShape >& )
437 {
438 ::SolarMutexGuard aGuard;
439
440 if(HasSdrObject())
441 GetSdrObject()->DisconnectFromNode( true );
442
443 GetSdrObject()->getSdrModelFromSdrObject().SetChanged();
444 }
445
446
disconnectEnd(const uno::Reference<drawing::XConnectableShape> &)447 void SAL_CALL SvxShapeConnector::disconnectEnd( const uno::Reference< drawing::XConnectableShape >& )
448 {
449 ::SolarMutexGuard aGuard;
450
451 if(HasSdrObject())
452 GetSdrObject()->DisconnectFromNode( false );
453
454 GetSdrObject()->getSdrModelFromSdrObject().SetChanged();
455 }
456
SvxShapeControl(SdrObject * pObj)457 SvxShapeControl::SvxShapeControl(SdrObject* pObj)
458 : SvxShapeText( pObj, getSvxMapProvider().GetMap(SVXMAP_CONTROL), getSvxMapProvider().GetPropertySet(SVXMAP_CONTROL, SdrObject::GetGlobalDrawObjectItemPool()) )
459 {
460 setShapeKind( OBJ_UNO );
461 }
462
463
~SvxShapeControl()464 SvxShapeControl::~SvxShapeControl() noexcept
465 {
466 }
467
468
queryInterface(const uno::Type & rType)469 uno::Any SAL_CALL SvxShapeControl::queryInterface( const uno::Type & rType )
470 {
471 return SvxShapeText::queryInterface( rType );
472 }
473
queryAggregation(const uno::Type & rType)474 uno::Any SAL_CALL SvxShapeControl::queryAggregation( const uno::Type & rType )
475 {
476 uno::Any aAny;
477
478 QUERYINT( drawing::XControlShape );
479 else
480 return SvxShapeText::queryAggregation( rType );
481
482 return aAny;
483 }
484
485 // XTypeProvider
486
getTypes()487 uno::Sequence< uno::Type > SAL_CALL SvxShapeControl::getTypes()
488 {
489 return SvxShape::getTypes();
490 }
491
getImplementationId()492 uno::Sequence< sal_Int8 > SAL_CALL SvxShapeControl::getImplementationId()
493 {
494 return css::uno::Sequence<sal_Int8>();
495 }
496
497 // css::drawing::XShape
498
499
getShapeType()500 OUString SAL_CALL SvxShapeControl::getShapeType()
501 {
502 return SvxShapeText::getShapeType();
503 }
504
getPosition()505 awt::Point SAL_CALL SvxShapeControl::getPosition()
506 {
507 return SvxShapeText::getPosition();
508 }
509
510
setPosition(const awt::Point & Position)511 void SAL_CALL SvxShapeControl::setPosition( const awt::Point& Position )
512 {
513 SvxShapeText::setPosition(Position);
514 }
515
516
getSize()517 awt::Size SAL_CALL SvxShapeControl::getSize()
518 {
519 return SvxShapeText::getSize();
520 }
521
522
setSize(const awt::Size & rSize)523 void SAL_CALL SvxShapeControl::setSize( const awt::Size& rSize )
524 {
525 SvxShapeText::setSize( rSize );
526 }
527
528
529 // XControlShape
530
getControl()531 Reference< awt::XControlModel > SAL_CALL SvxShapeControl::getControl()
532 {
533 ::SolarMutexGuard aGuard;
534
535 Reference< awt::XControlModel > xModel;
536
537 SdrUnoObj* pUnoObj = dynamic_cast< SdrUnoObj * >(GetSdrObject());
538 if( pUnoObj )
539 xModel = pUnoObj->GetUnoControlModel();
540
541 return xModel;
542 }
543
544
setControl(const Reference<awt::XControlModel> & xControl)545 void SAL_CALL SvxShapeControl::setControl( const Reference< awt::XControlModel >& xControl )
546 {
547 ::SolarMutexGuard aGuard;
548
549 SdrUnoObj* pUnoObj = dynamic_cast< SdrUnoObj * >(GetSdrObject());
550 if( pUnoObj )
551 pUnoObj->SetUnoControlModel( xControl );
552
553 GetSdrObject()->getSdrModelFromSdrObject().SetChanged();
554 }
555
556 struct
557 {
558 const char* mpAPIName;
559 sal_uInt16 mnAPINameLen;
560
561 const char* mpFormName;
562 sal_uInt16 mnFormNameLen;
563 }
564 const SvxShapeControlPropertyMapping[] =
565 {
566 // Warning: The first entry must be FontSlant because the any needs to be converted
567 { RTL_CONSTASCII_STRINGPARAM(UNO_NAME_EDIT_CHAR_POSTURE), RTL_CONSTASCII_STRINGPARAM("FontSlant") }, // const sal_Int16 => css::awt::FontSlant
568 { RTL_CONSTASCII_STRINGPARAM(UNO_NAME_EDIT_CHAR_FONTNAME), RTL_CONSTASCII_STRINGPARAM("FontName") },
569 { RTL_CONSTASCII_STRINGPARAM(UNO_NAME_EDIT_CHAR_FONTSTYLENAME), RTL_CONSTASCII_STRINGPARAM("FontStyleName") },
570 { RTL_CONSTASCII_STRINGPARAM(UNO_NAME_EDIT_CHAR_FONTFAMILY), RTL_CONSTASCII_STRINGPARAM("FontFamily") },
571 { RTL_CONSTASCII_STRINGPARAM(UNO_NAME_EDIT_CHAR_FONTCHARSET), RTL_CONSTASCII_STRINGPARAM("FontCharset") },
572 { RTL_CONSTASCII_STRINGPARAM(UNO_NAME_EDIT_CHAR_HEIGHT), RTL_CONSTASCII_STRINGPARAM("FontHeight") },
573 { RTL_CONSTASCII_STRINGPARAM(UNO_NAME_EDIT_CHAR_FONTPITCH), RTL_CONSTASCII_STRINGPARAM("FontPitch" ) },
574 { RTL_CONSTASCII_STRINGPARAM(UNO_NAME_EDIT_CHAR_WEIGHT), RTL_CONSTASCII_STRINGPARAM("FontWeight" ) },
575 { RTL_CONSTASCII_STRINGPARAM(UNO_NAME_EDIT_CHAR_UNDERLINE), RTL_CONSTASCII_STRINGPARAM("FontUnderline") },
576 { RTL_CONSTASCII_STRINGPARAM(UNO_NAME_EDIT_CHAR_STRIKEOUT), RTL_CONSTASCII_STRINGPARAM("FontStrikeout") },
577 { RTL_CONSTASCII_STRINGPARAM("CharKerning"), RTL_CONSTASCII_STRINGPARAM("FontKerning") },
578 { RTL_CONSTASCII_STRINGPARAM("CharWordMode"), RTL_CONSTASCII_STRINGPARAM("FontWordLineMode" ) },
579 { RTL_CONSTASCII_STRINGPARAM(UNO_NAME_EDIT_CHAR_COLOR), RTL_CONSTASCII_STRINGPARAM("TextColor") },
580 { RTL_CONSTASCII_STRINGPARAM("CharBackColor"), RTL_CONSTASCII_STRINGPARAM("CharBackColor") },
581 { RTL_CONSTASCII_STRINGPARAM("CharBackTransparent"), RTL_CONSTASCII_STRINGPARAM("CharBackTransparent") },
582 { RTL_CONSTASCII_STRINGPARAM(UNO_NAME_TEXT_CHAINNEXTNAME), RTL_CONSTASCII_STRINGPARAM(UNO_NAME_TEXT_CHAINNEXTNAME) },
583 { RTL_CONSTASCII_STRINGPARAM("CharRelief"), RTL_CONSTASCII_STRINGPARAM("FontRelief") },
584 { RTL_CONSTASCII_STRINGPARAM("CharUnderlineColor"), RTL_CONSTASCII_STRINGPARAM("TextLineColor") },
585 { RTL_CONSTASCII_STRINGPARAM(UNO_NAME_EDIT_PARA_ADJUST), RTL_CONSTASCII_STRINGPARAM("Align") },
586 { RTL_CONSTASCII_STRINGPARAM("TextVerticalAdjust"), RTL_CONSTASCII_STRINGPARAM("VerticalAlign") },
587 { RTL_CONSTASCII_STRINGPARAM("ControlBackground"), RTL_CONSTASCII_STRINGPARAM("BackgroundColor") },
588 { RTL_CONSTASCII_STRINGPARAM("ControlSymbolColor"), RTL_CONSTASCII_STRINGPARAM("SymbolColor") },
589 { RTL_CONSTASCII_STRINGPARAM("ControlBorder"), RTL_CONSTASCII_STRINGPARAM("Border") },
590 { RTL_CONSTASCII_STRINGPARAM("ControlBorderColor"), RTL_CONSTASCII_STRINGPARAM("BorderColor") },
591 { RTL_CONSTASCII_STRINGPARAM("ControlTextEmphasis"), RTL_CONSTASCII_STRINGPARAM("FontEmphasisMark") },
592 { RTL_CONSTASCII_STRINGPARAM("ImageScaleMode"), RTL_CONSTASCII_STRINGPARAM("ScaleMode") },
593 { RTL_CONSTASCII_STRINGPARAM("ControlWritingMode"), RTL_CONSTASCII_STRINGPARAM("WritingMode") },
594 //added for exporting OCX control
595 { RTL_CONSTASCII_STRINGPARAM("ControlTypeinMSO"), RTL_CONSTASCII_STRINGPARAM("ControlTypeinMSO") },
596 { RTL_CONSTASCII_STRINGPARAM("ObjIDinMSO"), RTL_CONSTASCII_STRINGPARAM("ObjIDinMSO") },
597 { RTL_CONSTASCII_STRINGPARAM("CharCaseMap"), RTL_CONSTASCII_STRINGPARAM("CharCaseMap") },
598 { nullptr,0, nullptr, 0 }
599 };
600
601 namespace
602 {
lcl_convertPropertyName(const OUString & rApiName,OUString & rInternalName)603 bool lcl_convertPropertyName( const OUString& rApiName, OUString& rInternalName )
604 {
605 sal_uInt16 i = 0;
606 while( SvxShapeControlPropertyMapping[i].mpAPIName )
607 {
608 if( rApiName.reverseCompareToAsciiL( SvxShapeControlPropertyMapping[i].mpAPIName, SvxShapeControlPropertyMapping[i].mnAPINameLen ) == 0 )
609 {
610 rInternalName = OUString( SvxShapeControlPropertyMapping[i].mpFormName, SvxShapeControlPropertyMapping[i].mnFormNameLen, RTL_TEXTENCODING_ASCII_US );
611 }
612 ++i;
613 }
614 return !rInternalName.isEmpty();
615 }
616
617 struct EnumConversionMap
618 {
619 style::ParagraphAdjust nAPIValue;
620 sal_Int16 nFormValue;
621 };
622
623 EnumConversionMap const aMapAdjustToAlign[] =
624 {
625 // note that order matters:
626 // lcl_convertTextAlignmentToParaAdjustment and lcl_convertParaAdjustmentToTextAlignment search this map from the _beginning_
627 // and use the first matching entry
628 {style::ParagraphAdjust_LEFT, sal_Int16(awt::TextAlign::LEFT)},
629 {style::ParagraphAdjust_CENTER, sal_Int16(awt::TextAlign::CENTER)},
630 {style::ParagraphAdjust_RIGHT, sal_Int16(awt::TextAlign::RIGHT)},
631 {style::ParagraphAdjust_BLOCK, sal_Int16(awt::TextAlign::RIGHT)},
632 {style::ParagraphAdjust_STRETCH, sal_Int16(awt::TextAlign::LEFT)},
633 {style::ParagraphAdjust(-1),-1}
634 };
635
lcl_convertTextAlignmentToParaAdjustment(Any & _rValue)636 void lcl_convertTextAlignmentToParaAdjustment( Any& _rValue )
637 {
638 sal_Int16 nValue = sal_Int16();
639 OSL_VERIFY( _rValue >>= nValue );
640
641 for ( auto const & rEntry : aMapAdjustToAlign )
642 if ( nValue == rEntry.nFormValue )
643 {
644 _rValue <<= static_cast<sal_uInt16>(rEntry.nAPIValue);
645 return;
646 }
647 }
648
lcl_convertParaAdjustmentToTextAlignment(Any & _rValue)649 void lcl_convertParaAdjustmentToTextAlignment( Any& _rValue )
650 {
651 sal_Int32 nValue = 0;
652 OSL_VERIFY( _rValue >>= nValue );
653
654 for ( auto const & rEntry : aMapAdjustToAlign )
655 if ( static_cast<style::ParagraphAdjust>(nValue) == rEntry.nAPIValue )
656 {
657 _rValue <<= rEntry.nFormValue;
658 return;
659 }
660 }
661
convertVerticalAdjustToVerticalAlign(Any & _rValue)662 void convertVerticalAdjustToVerticalAlign( Any& _rValue )
663 {
664 if ( !_rValue.hasValue() )
665 return;
666
667 drawing::TextVerticalAdjust eAdjust = drawing::TextVerticalAdjust_TOP;
668 style::VerticalAlignment eAlign = style::VerticalAlignment_TOP;
669 if ( !( _rValue >>= eAdjust ) )
670 throw lang::IllegalArgumentException();
671 switch ( eAdjust )
672 {
673 case drawing::TextVerticalAdjust_TOP: eAlign = style::VerticalAlignment_TOP; break;
674 case drawing::TextVerticalAdjust_BOTTOM: eAlign = style::VerticalAlignment_BOTTOM; break;
675 default: eAlign = style::VerticalAlignment_MIDDLE; break;
676 }
677 _rValue <<= eAlign;
678 }
679
convertVerticalAlignToVerticalAdjust(Any & _rValue)680 void convertVerticalAlignToVerticalAdjust( Any& _rValue )
681 {
682 if ( !_rValue.hasValue() )
683 return;
684 style::VerticalAlignment eAlign = style::VerticalAlignment_TOP;
685 drawing::TextVerticalAdjust eAdjust = drawing::TextVerticalAdjust_TOP;
686 OSL_VERIFY( _rValue >>= eAlign );
687 switch ( eAlign )
688 {
689 case style::VerticalAlignment_TOP: eAdjust = drawing::TextVerticalAdjust_TOP; break;
690 case style::VerticalAlignment_BOTTOM: eAdjust = drawing::TextVerticalAdjust_BOTTOM; break;
691 default: eAdjust = drawing::TextVerticalAdjust_CENTER; break;
692 }
693 _rValue <<= eAdjust;
694 }
695 }
696
setPropertyValue(const OUString & aPropertyName,const uno::Any & aValue)697 void SAL_CALL SvxShapeControl::setPropertyValue( const OUString& aPropertyName, const uno::Any& aValue )
698 {
699 OUString aFormsName;
700 if ( lcl_convertPropertyName( aPropertyName, aFormsName ) )
701 {
702 uno::Reference< beans::XPropertySet > xControl( getControl(), uno::UNO_QUERY );
703 if( xControl.is() )
704 {
705 uno::Reference< beans::XPropertySetInfo > xInfo( xControl->getPropertySetInfo() );
706 if( xInfo.is() && xInfo->hasPropertyByName( aFormsName ) )
707 {
708 uno::Any aConvertedValue( aValue );
709 if ( aFormsName == "FontSlant" )
710 {
711 awt::FontSlant nSlant;
712 if( !(aValue >>= nSlant ) )
713 throw lang::IllegalArgumentException();
714 aConvertedValue <<= static_cast<sal_Int16>(nSlant);
715 }
716 else if ( aFormsName == "Align" )
717 {
718 lcl_convertParaAdjustmentToTextAlignment( aConvertedValue );
719 }
720 else if ( aFormsName == "VerticalAlign" )
721 {
722 convertVerticalAdjustToVerticalAlign( aConvertedValue );
723 }
724
725 xControl->setPropertyValue( aFormsName, aConvertedValue );
726 }
727 }
728 }
729 else
730 {
731 SvxShape::setPropertyValue( aPropertyName, aValue );
732 }
733 }
734
getPropertyValue(const OUString & aPropertyName)735 uno::Any SAL_CALL SvxShapeControl::getPropertyValue( const OUString& aPropertyName )
736 {
737 OUString aFormsName;
738 if ( lcl_convertPropertyName( aPropertyName, aFormsName ) )
739 {
740 uno::Reference< beans::XPropertySet > xControl( getControl(), uno::UNO_QUERY );
741
742 uno::Any aValue;
743 if( xControl.is() )
744 {
745 uno::Reference< beans::XPropertySetInfo > xInfo( xControl->getPropertySetInfo() );
746 if( xInfo.is() && xInfo->hasPropertyByName( aFormsName ) )
747 {
748 aValue = xControl->getPropertyValue( aFormsName );
749 if ( aFormsName == "FontSlant" )
750 {
751 awt::FontSlant eSlant = awt::FontSlant_NONE;
752 sal_Int16 nSlant = sal_Int16();
753 if ( aValue >>= nSlant )
754 {
755 eSlant = static_cast<awt::FontSlant>(nSlant);
756 }
757 else
758 {
759 OSL_VERIFY( aValue >>= eSlant );
760 }
761 aValue <<= eSlant;
762 }
763 else if ( aFormsName == "Align" )
764 {
765 lcl_convertTextAlignmentToParaAdjustment( aValue );
766 }
767 else if ( aFormsName == "VerticalAlign" )
768 {
769 convertVerticalAlignToVerticalAdjust( aValue );
770 }
771 }
772 }
773
774 return aValue;
775 }
776 else
777 {
778 return SvxShape::getPropertyValue( aPropertyName );
779 }
780
781 }
782
783 // XPropertyState
getPropertyState(const OUString & PropertyName)784 beans::PropertyState SAL_CALL SvxShapeControl::getPropertyState( const OUString& PropertyName )
785 {
786 OUString aFormsName;
787 if ( lcl_convertPropertyName( PropertyName, aFormsName ) )
788 {
789 uno::Reference< beans::XPropertyState > xControl( getControl(), uno::UNO_QUERY );
790 uno::Reference< beans::XPropertySet > xPropSet( getControl(), uno::UNO_QUERY );
791
792 if( xControl.is() && xPropSet.is() )
793 {
794 uno::Reference< beans::XPropertySetInfo > xInfo( xPropSet->getPropertySetInfo() );
795 if( xInfo.is() && xInfo->hasPropertyByName( aFormsName ) )
796 {
797 return xControl->getPropertyState( aFormsName );
798 }
799 }
800
801 return beans::PropertyState_DEFAULT_VALUE;
802 }
803 else
804 {
805 return SvxShape::getPropertyState( PropertyName );
806 }
807 }
808
setPropertyToDefault(const OUString & PropertyName)809 void SAL_CALL SvxShapeControl::setPropertyToDefault( const OUString& PropertyName )
810 {
811 OUString aFormsName;
812 if ( lcl_convertPropertyName( PropertyName, aFormsName ) )
813 {
814 uno::Reference< beans::XPropertyState > xControl( getControl(), uno::UNO_QUERY );
815 uno::Reference< beans::XPropertySet > xPropSet( getControl(), uno::UNO_QUERY );
816
817 if( xControl.is() && xPropSet.is() )
818 {
819 uno::Reference< beans::XPropertySetInfo > xInfo( xPropSet->getPropertySetInfo() );
820 if( xInfo.is() && xInfo->hasPropertyByName( aFormsName ) )
821 {
822 xControl->setPropertyToDefault( aFormsName );
823 }
824 }
825 }
826 else
827 {
828 SvxShape::setPropertyToDefault( PropertyName );
829 }
830 }
831
getPropertyDefault(const OUString & aPropertyName)832 uno::Any SAL_CALL SvxShapeControl::getPropertyDefault( const OUString& aPropertyName )
833 {
834 OUString aFormsName;
835 if ( lcl_convertPropertyName( aPropertyName, aFormsName ) )
836 {
837 uno::Reference< beans::XPropertyState > xControl( getControl(), uno::UNO_QUERY );
838
839 if( xControl.is() )
840 {
841 Any aDefault( xControl->getPropertyDefault( aFormsName ) );
842 if ( aFormsName == "FontSlant" )
843 {
844 sal_Int16 nSlant( 0 );
845 aDefault >>= nSlant;
846 aDefault <<= static_cast<awt::FontSlant>(nSlant);
847 }
848 else if ( aFormsName == "Align" )
849 {
850 lcl_convertTextAlignmentToParaAdjustment( aDefault );
851 }
852 else if ( aFormsName == "VerticalAlign" )
853 {
854 convertVerticalAlignToVerticalAdjust( aDefault );
855 }
856 return aDefault;
857 }
858
859 throw beans::UnknownPropertyException( aPropertyName, static_cast<cppu::OWeakObject*>(this));
860 }
861 else
862 {
863 return SvxShape::getPropertyDefault( aPropertyName );
864 }
865 }
866
SvxShapeDimensioning(SdrObject * pObj)867 SvxShapeDimensioning::SvxShapeDimensioning(SdrObject* pObj)
868 : SvxShapeText( pObj, getSvxMapProvider().GetMap(SVXMAP_DIMENSIONING), getSvxMapProvider().GetPropertySet(SVXMAP_DIMENSIONING, SdrObject::GetGlobalDrawObjectItemPool()) )
869 {
870 }
871
~SvxShapeDimensioning()872 SvxShapeDimensioning::~SvxShapeDimensioning() noexcept
873 {
874 }
875
SvxShapeCircle(SdrObject * pObj)876 SvxShapeCircle::SvxShapeCircle(SdrObject* pObj)
877 : SvxShapeText( pObj, getSvxMapProvider().GetMap(SVXMAP_CIRCLE), getSvxMapProvider().GetPropertySet(SVXMAP_CIRCLE, SdrObject::GetGlobalDrawObjectItemPool()) )
878 {
879 }
880
~SvxShapeCircle()881 SvxShapeCircle::~SvxShapeCircle() noexcept
882 {
883 }
884
885 //////////////////////////////////////////////////////////////////////////////
886
SvxShapePolyPolygon(SdrObject * pObj)887 SvxShapePolyPolygon::SvxShapePolyPolygon(
888 SdrObject* pObj)
889 : SvxShapeText(
890 pObj,
891 getSvxMapProvider().GetMap(SVXMAP_POLYPOLYGON),
892 getSvxMapProvider().GetPropertySet(SVXMAP_POLYPOLYGON, SdrObject::GetGlobalDrawObjectItemPool()))
893 {
894 }
895
~SvxShapePolyPolygon()896 SvxShapePolyPolygon::~SvxShapePolyPolygon() noexcept
897 {
898 }
899
setPropertyValueImpl(const OUString & rName,const SfxItemPropertyMapEntry * pProperty,const css::uno::Any & rValue)900 bool SvxShapePolyPolygon::setPropertyValueImpl( const OUString& rName, const SfxItemPropertyMapEntry* pProperty, const css::uno::Any& rValue )
901 {
902 switch( pProperty->nWID )
903 {
904 case OWN_ATTR_VALUE_POLYPOLYGONBEZIER:
905 {
906 if( auto s = o3tl::tryAccess<drawing::PolyPolygonBezierCoords>(rValue) )
907 {
908 basegfx::B2DPolyPolygon aNewPolyPolygon(
909 basegfx::utils::UnoPolyPolygonBezierCoordsToB2DPolyPolygon(*s));
910
911 // tdf#117145 metric of SdrModel is app-specific, metric of UNO API is 100thmm
912 ForceMetricToItemPoolMetric(aNewPolyPolygon);
913
914 SetPolygon(aNewPolyPolygon);
915 return true;
916 }
917 break;
918 }
919 case OWN_ATTR_VALUE_POLYPOLYGON:
920 {
921 if( auto s = o3tl::tryAccess<drawing::PointSequenceSequence>(rValue) )
922 {
923 basegfx::B2DPolyPolygon aNewPolyPolygon(
924 basegfx::utils::UnoPointSequenceSequenceToB2DPolyPolygon(*s));
925
926 // tdf#117145 metric of SdrModel is app-specific, metric of UNO API is 100thmm
927 ForceMetricToItemPoolMetric(aNewPolyPolygon);
928
929 SetPolygon(aNewPolyPolygon);
930 return true;
931 }
932 break;
933 }
934 case OWN_ATTR_BASE_GEOMETRY:
935 {
936 drawing::PointSequenceSequence aPointSequenceSequence;
937 drawing::PolyPolygonBezierCoords aPolyPolygonBezierCoords;
938
939 if( rValue >>= aPointSequenceSequence)
940 {
941 if( HasSdrObject() )
942 {
943 basegfx::B2DPolyPolygon aNewPolyPolygon;
944 basegfx::B2DHomMatrix aNewHomogenMatrix;
945
946 GetSdrObject()->TRGetBaseGeometry(aNewHomogenMatrix, aNewPolyPolygon);
947 aNewPolyPolygon = basegfx::utils::UnoPointSequenceSequenceToB2DPolyPolygon(aPointSequenceSequence);
948
949 // tdf#117145 metric of SdrModel is app-specific, metric of UNO API is 100thmm
950 // Need to adapt aNewPolyPolygon from 100thmm to app-specific
951 ForceMetricToItemPoolMetric(aNewPolyPolygon);
952
953 GetSdrObject()->TRSetBaseGeometry(aNewHomogenMatrix, aNewPolyPolygon);
954 }
955 return true;
956 }
957 else if( rValue >>= aPolyPolygonBezierCoords)
958 {
959 if( HasSdrObject() )
960 {
961 basegfx::B2DPolyPolygon aNewPolyPolygon;
962 basegfx::B2DHomMatrix aNewHomogenMatrix;
963
964 GetSdrObject()->TRGetBaseGeometry(aNewHomogenMatrix, aNewPolyPolygon);
965 aNewPolyPolygon = basegfx::utils::UnoPolyPolygonBezierCoordsToB2DPolyPolygon(aPolyPolygonBezierCoords);
966
967 // tdf#117145 metric of SdrModel is app-specific, metric of UNO API is 100thmm
968 ForceMetricToItemPoolMetric(aNewPolyPolygon);
969
970 GetSdrObject()->TRSetBaseGeometry(aNewHomogenMatrix, aNewPolyPolygon);
971 }
972 return true;
973 }
974 break;
975 }
976 case OWN_ATTR_VALUE_POLYGON:
977 {
978 if( auto pSequence = o3tl::tryAccess<drawing::PointSequence>(rValue) )
979 {
980 // prepare new polygon
981 basegfx::B2DPolygon aNewPolygon;
982
983 // get pointer to arrays
984 const awt::Point* pArray = pSequence->getConstArray();
985 const awt::Point* pArrayEnd = pArray + pSequence->getLength();
986
987 for(;pArray != pArrayEnd;++pArray)
988 {
989 aNewPolygon.append(basegfx::B2DPoint(pArray->X, pArray->Y));
990 }
991
992 // check for closed state flag
993 basegfx::utils::checkClosed(aNewPolygon);
994
995 // tdf#117145 metric of SdrModel is app-specific, metric of UNO API is 100thmm
996 basegfx::B2DPolyPolygon aNewPolyPolygon(aNewPolygon);
997 ForceMetricToItemPoolMetric(aNewPolyPolygon);
998
999 // set polygon
1000 SetPolygon(aNewPolyPolygon);
1001 return true;
1002 }
1003 break;
1004 }
1005 default:
1006 return SvxShapeText::setPropertyValueImpl( rName, pProperty, rValue );
1007 }
1008
1009 throw lang::IllegalArgumentException();
1010 }
1011
getPropertyValueImpl(const OUString & rName,const SfxItemPropertyMapEntry * pProperty,css::uno::Any & rValue)1012 bool SvxShapePolyPolygon::getPropertyValueImpl( const OUString& rName, const SfxItemPropertyMapEntry* pProperty,
1013 css::uno::Any& rValue )
1014 {
1015 switch( pProperty->nWID )
1016 {
1017 case OWN_ATTR_VALUE_POLYPOLYGONBEZIER:
1018 {
1019 // pack a tools::PolyPolygon in a struct tools::PolyPolygon
1020 basegfx::B2DPolyPolygon aPolyPoly(GetPolygon());
1021
1022 // tdf#117145 metric of SdrModel is app-specific, metric of UNO API is 100thmm
1023 ForceMetricTo100th_mm(aPolyPoly);
1024
1025 drawing::PolyPolygonBezierCoords aRetval;
1026 basegfx::utils::B2DPolyPolygonToUnoPolyPolygonBezierCoords(aPolyPoly, aRetval);
1027
1028 rValue <<= aRetval;
1029 break;
1030 }
1031 case OWN_ATTR_VALUE_POLYPOLYGON:
1032 {
1033 // pack a tools::PolyPolygon in a struct tools::PolyPolygon
1034 basegfx::B2DPolyPolygon aPolyPoly(GetPolygon());
1035
1036 // tdf#117145 metric of SdrModel is app-specific, metric of UNO API is 100thmm
1037 ForceMetricTo100th_mm(aPolyPoly);
1038
1039 drawing::PointSequenceSequence aRetval( aPolyPoly.count() );
1040 basegfx::utils::B2DPolyPolygonToUnoPointSequenceSequence(aPolyPoly, aRetval);
1041
1042 rValue <<= aRetval;
1043 break;
1044 }
1045 case OWN_ATTR_BASE_GEOMETRY:
1046 {
1047 // pack a tools::PolyPolygon in struct PolyPolygon
1048 basegfx::B2DPolyPolygon aPolyPoly;
1049 basegfx::B2DHomMatrix aNewHomogenMatrix;
1050
1051 if(HasSdrObject())
1052 {
1053 GetSdrObject()->TRGetBaseGeometry(aNewHomogenMatrix, aPolyPoly);
1054
1055 // tdf#117145 metric of SdrModel is app-specific, metric of UNO API is 100thmm
1056 ForceMetricTo100th_mm(aPolyPoly);
1057 }
1058
1059 if(aPolyPoly.areControlPointsUsed())
1060 {
1061 drawing::PolyPolygonBezierCoords aRetval;
1062 basegfx::utils::B2DPolyPolygonToUnoPolyPolygonBezierCoords(aPolyPoly, aRetval);
1063 rValue <<= aRetval;
1064 }
1065 else
1066 {
1067 drawing::PointSequenceSequence aRetval(aPolyPoly.count());
1068 basegfx::utils::B2DPolyPolygonToUnoPointSequenceSequence(aPolyPoly, aRetval);
1069 rValue <<= aRetval;
1070 }
1071 break;
1072 }
1073 case OWN_ATTR_VALUE_POLYGON:
1074 {
1075 // pack a tools::PolyPolygon in a struct tools::PolyPolygon
1076 basegfx::B2DPolyPolygon aPolyPoly(GetPolygon());
1077
1078 // tdf#117145 metric of SdrModel is app-specific, metric of UNO API is 100thmm
1079 ForceMetricTo100th_mm(aPolyPoly);
1080
1081 const sal_Int32 nCount(0 == aPolyPoly.count() ? 0 : aPolyPoly.getB2DPolygon(0).count());
1082 drawing::PointSequence aRetval( nCount );
1083
1084 if( nCount > 0 )
1085 {
1086 // get single polygon
1087 const basegfx::B2DPolygon& aPoly(aPolyPoly.getB2DPolygon(0));
1088
1089 // get pointer to arrays
1090 awt::Point* pSequence = aRetval.getArray();
1091
1092 for(sal_Int32 b=0;b<nCount;b++)
1093 {
1094 const basegfx::B2DPoint aPoint(aPoly.getB2DPoint(b));
1095 *pSequence++ = awt::Point( basegfx::fround(aPoint.getX()), basegfx::fround(aPoint.getY()) );
1096 }
1097 }
1098
1099 rValue <<= aRetval;
1100 break;
1101 }
1102 case OWN_ATTR_VALUE_POLYGONKIND:
1103 {
1104 rValue <<= GetPolygonKind();
1105 break;
1106 }
1107 default:
1108 return SvxShapeText::getPropertyValueImpl( rName, pProperty, rValue );
1109 }
1110
1111 return true;
1112 }
1113
GetPolygonKind() const1114 drawing::PolygonKind SvxShapePolyPolygon::GetPolygonKind() const
1115 {
1116 ::SolarMutexGuard aGuard;
1117 drawing::PolygonKind aRetval(drawing::PolygonKind_LINE);
1118
1119 if(HasSdrObject())
1120 {
1121 switch(GetSdrObject()->GetObjIdentifier())
1122 {
1123 case OBJ_POLY: aRetval = drawing::PolygonKind_POLY; break;
1124 case OBJ_PLIN: aRetval = drawing::PolygonKind_PLIN; break;
1125 case OBJ_SPLNLINE:
1126 case OBJ_PATHLINE: aRetval = drawing::PolygonKind_PATHLINE; break;
1127 case OBJ_SPLNFILL:
1128 case OBJ_PATHFILL: aRetval = drawing::PolygonKind_PATHFILL; break;
1129 case OBJ_FREELINE: aRetval = drawing::PolygonKind_FREELINE; break;
1130 case OBJ_FREEFILL: aRetval = drawing::PolygonKind_FREEFILL; break;
1131 default: break;
1132 }
1133 }
1134
1135 return aRetval;
1136 }
1137
SetPolygon(const basegfx::B2DPolyPolygon & rNew)1138 void SvxShapePolyPolygon::SetPolygon(const basegfx::B2DPolyPolygon& rNew)
1139 {
1140 ::SolarMutexGuard aGuard;
1141
1142 if(HasSdrObject())
1143 static_cast<SdrPathObj*>(GetSdrObject())->SetPathPoly(rNew);
1144 }
1145
1146
GetPolygon() const1147 basegfx::B2DPolyPolygon SvxShapePolyPolygon::GetPolygon() const noexcept
1148 {
1149 ::SolarMutexGuard aGuard;
1150
1151 if(HasSdrObject())
1152 {
1153 return static_cast<SdrPathObj*>(GetSdrObject())->GetPathPoly();
1154 }
1155 else
1156 {
1157 return basegfx::B2DPolyPolygon();
1158 }
1159 }
1160
1161 //////////////////////////////////////////////////////////////////////////////
1162
SvxGraphicObject(SdrObject * pObj)1163 SvxGraphicObject::SvxGraphicObject(SdrObject* pObj)
1164 : SvxShapeText( pObj, getSvxMapProvider().GetMap(SVXMAP_GRAPHICOBJECT), getSvxMapProvider().GetPropertySet(SVXMAP_GRAPHICOBJECT, SdrObject::GetGlobalDrawObjectItemPool()) )
1165 {
1166 }
1167
~SvxGraphicObject()1168 SvxGraphicObject::~SvxGraphicObject() noexcept
1169 {
1170 }
1171
setPropertyValueImpl(const OUString & rName,const SfxItemPropertyMapEntry * pProperty,const css::uno::Any & rValue)1172 bool SvxGraphicObject::setPropertyValueImpl( const OUString& rName, const SfxItemPropertyMapEntry* pProperty, const css::uno::Any& rValue )
1173 {
1174 bool bOk = false;
1175 switch( pProperty->nWID )
1176 {
1177 case OWN_ATTR_VALUE_FILLBITMAP:
1178 {
1179 if( auto pSeq = o3tl::tryAccess<uno::Sequence<sal_Int8>>(rValue) )
1180 {
1181 SvMemoryStream aMemStm;
1182 Graphic aGraphic;
1183
1184 aMemStm.SetBuffer( const_cast<css::uno::Sequence<sal_Int8> *>(pSeq)->getArray(), pSeq->getLength(), pSeq->getLength() );
1185
1186 if( GraphicConverter::Import( aMemStm, aGraphic ) == ERRCODE_NONE )
1187 {
1188 static_cast<SdrGrafObj*>(GetSdrObject())->SetGraphic(aGraphic);
1189 bOk = true;
1190 }
1191 }
1192 else if (rValue.getValueType() == cppu::UnoType<graphic::XGraphic>::get())
1193 {
1194 auto xGraphic = rValue.get<uno::Reference<graphic::XGraphic>>();
1195 if (xGraphic.is())
1196 {
1197 static_cast<SdrGrafObj*>(GetSdrObject())->SetGraphic(Graphic(xGraphic));
1198 bOk = true;
1199 }
1200 }
1201 else if (rValue.getValueType() == cppu::UnoType<awt::XBitmap>::get())
1202 {
1203 auto xBitmap = rValue.get<uno::Reference<awt::XBitmap>>();
1204 if (xBitmap.is())
1205 {
1206 uno::Reference<graphic::XGraphic> xGraphic(xBitmap, uno::UNO_QUERY);
1207 Graphic aGraphic(xGraphic);
1208 static_cast<SdrGrafObj*>(GetSdrObject())->SetGraphic(aGraphic);
1209 bOk = true;
1210 }
1211 }
1212 break;
1213 }
1214
1215 case OWN_ATTR_GRAFSTREAMURL:
1216 {
1217 OUString aStreamURL;
1218
1219 if( rValue >>= aStreamURL )
1220 {
1221 if( !aStreamURL.startsWith( UNO_NAME_GRAPHOBJ_URLPKGPREFIX ) )
1222 aStreamURL.clear();
1223
1224 if( HasSdrObject() )
1225 {
1226 static_cast<SdrGrafObj*>(GetSdrObject())->SetGrafStreamURL( aStreamURL );
1227 }
1228 bOk = true;
1229 }
1230 break;
1231 }
1232
1233 case OWN_ATTR_GRAPHIC_URL:
1234 {
1235 OUString aURL;
1236 uno::Reference<awt::XBitmap> xBitmap;
1237 if (rValue >>= aURL)
1238 {
1239 Graphic aGraphic = vcl::graphic::loadFromURL(aURL);
1240 if (!aGraphic.IsNone())
1241 {
1242 static_cast<SdrGrafObj*>(GetSdrObject())->SetGraphic(aGraphic);
1243 bOk = true;
1244 }
1245 }
1246 else if (rValue >>= xBitmap)
1247 {
1248 uno::Reference<graphic::XGraphic> xGraphic(xBitmap, uno::UNO_QUERY);
1249 if (xGraphic.is())
1250 {
1251 Graphic aGraphic = xGraphic;
1252 if (!aGraphic.IsNone())
1253 {
1254 static_cast<SdrGrafObj*>(GetSdrObject())->SetGraphic(aGraphic);
1255 bOk = true;
1256 }
1257 }
1258 }
1259 break;
1260 }
1261
1262 case OWN_ATTR_VALUE_GRAPHIC:
1263 {
1264 Reference< graphic::XGraphic > xGraphic( rValue, uno::UNO_QUERY );
1265 if( xGraphic.is() )
1266 {
1267 static_cast< SdrGrafObj*>( GetSdrObject() )->SetGraphic( xGraphic );
1268 bOk = true;
1269 }
1270 break;
1271 }
1272
1273 case OWN_ATTR_IS_SIGNATURELINE:
1274 {
1275 bool bIsSignatureLine;
1276 if (rValue >>= bIsSignatureLine)
1277 {
1278 static_cast<SdrGrafObj*>(GetSdrObject())->setIsSignatureLine(bIsSignatureLine);
1279 bOk = true;
1280 }
1281 break;
1282 }
1283
1284 case OWN_ATTR_SIGNATURELINE_ID:
1285 {
1286 OUString aSignatureLineId;
1287 if (rValue >>= aSignatureLineId)
1288 {
1289 static_cast<SdrGrafObj*>(GetSdrObject())->setSignatureLineId(aSignatureLineId);
1290 bOk = true;
1291 }
1292 break;
1293 }
1294
1295 case OWN_ATTR_SIGNATURELINE_SUGGESTED_SIGNER_NAME:
1296 {
1297 OUString aSuggestedSignerName;
1298 if (rValue >>= aSuggestedSignerName)
1299 {
1300 static_cast<SdrGrafObj*>(GetSdrObject())->setSignatureLineSuggestedSignerName(aSuggestedSignerName);
1301 bOk = true;
1302 }
1303 break;
1304 }
1305
1306 case OWN_ATTR_SIGNATURELINE_SUGGESTED_SIGNER_TITLE:
1307 {
1308 OUString aSuggestedSignerTitle;
1309 if (rValue >>= aSuggestedSignerTitle)
1310 {
1311 static_cast<SdrGrafObj*>(GetSdrObject())->setSignatureLineSuggestedSignerTitle(aSuggestedSignerTitle);
1312 bOk = true;
1313 }
1314 break;
1315 }
1316
1317 case OWN_ATTR_SIGNATURELINE_SUGGESTED_SIGNER_EMAIL:
1318 {
1319 OUString aSuggestedSignerEmail;
1320 if (rValue >>= aSuggestedSignerEmail)
1321 {
1322 static_cast<SdrGrafObj*>(GetSdrObject())->setSignatureLineSuggestedSignerEmail(aSuggestedSignerEmail);
1323 bOk = true;
1324 }
1325 break;
1326 }
1327
1328 case OWN_ATTR_SIGNATURELINE_SIGNING_INSTRUCTIONS:
1329 {
1330 OUString aSigningInstructions;
1331 if (rValue >>= aSigningInstructions)
1332 {
1333 static_cast<SdrGrafObj*>(GetSdrObject())->setSignatureLineSigningInstructions(aSigningInstructions);
1334 bOk = true;
1335 }
1336 break;
1337 }
1338
1339 case OWN_ATTR_SIGNATURELINE_SHOW_SIGN_DATE:
1340 {
1341 bool bShowSignDate;
1342 if (rValue >>= bShowSignDate)
1343 {
1344 static_cast<SdrGrafObj*>(GetSdrObject())->setSignatureLineShowSignDate(bShowSignDate);
1345 bOk = true;
1346 }
1347 break;
1348 }
1349
1350 case OWN_ATTR_SIGNATURELINE_CAN_ADD_COMMENT:
1351 {
1352 bool bCanAddComment;
1353 if (rValue >>= bCanAddComment)
1354 {
1355 static_cast<SdrGrafObj*>(GetSdrObject())->setSignatureLineCanAddComment(bCanAddComment);
1356 bOk = true;
1357 }
1358 break;
1359 }
1360
1361 case OWN_ATTR_SIGNATURELINE_UNSIGNED_IMAGE:
1362 {
1363 Reference<graphic::XGraphic> xGraphic(rValue, uno::UNO_QUERY);
1364 if (xGraphic.is())
1365 {
1366 static_cast<SdrGrafObj*>(GetSdrObject())->setSignatureLineUnsignedGraphic(xGraphic);
1367 bOk = true;
1368 }
1369 break;
1370 }
1371
1372 case OWN_ATTR_SIGNATURELINE_IS_SIGNED:
1373 {
1374 bool bIsSigned;
1375 if (rValue >>= bIsSigned)
1376 {
1377 static_cast<SdrGrafObj*>(GetSdrObject())->setSignatureLineIsSigned(bIsSigned);
1378 bOk = true;
1379 }
1380 break;
1381 }
1382
1383 case OWN_ATTR_QRCODE:
1384 {
1385 css::drawing::QRCode aQrCode;
1386 if (rValue >>= aQrCode)
1387 {
1388 static_cast<SdrGrafObj*>(GetSdrObject())->setQrCode(aQrCode);
1389 bOk = true;
1390 }
1391 break;
1392 }
1393
1394 default:
1395 return SvxShapeText::setPropertyValueImpl( rName, pProperty, rValue );
1396 }
1397
1398 if( !bOk )
1399 throw lang::IllegalArgumentException();
1400
1401 GetSdrObject()->getSdrModelFromSdrObject().SetChanged();
1402
1403 return true;
1404 }
1405
getPropertyValueImpl(const OUString & rName,const SfxItemPropertyMapEntry * pProperty,css::uno::Any & rValue)1406 bool SvxGraphicObject::getPropertyValueImpl( const OUString& rName, const SfxItemPropertyMapEntry* pProperty, css::uno::Any& rValue )
1407 {
1408 switch( pProperty->nWID )
1409 {
1410 case OWN_ATTR_VALUE_FILLBITMAP:
1411 {
1412 const Graphic& rGraphic = static_cast<SdrGrafObj*>(GetSdrObject())->GetGraphic();
1413
1414 if (rGraphic.GetType() != GraphicType::GdiMetafile)
1415 {
1416 uno::Reference<awt::XBitmap> xBitmap(rGraphic.GetXGraphic(), uno::UNO_QUERY);
1417 rValue <<= xBitmap;
1418 }
1419 else
1420 {
1421 SvMemoryStream aDestStrm( 65535, 65535 );
1422
1423 ConvertGDIMetaFileToWMF( rGraphic.GetGDIMetaFile(), aDestStrm, nullptr, false );
1424 const uno::Sequence<sal_Int8> aSeq(
1425 static_cast< const sal_Int8* >(aDestStrm.GetData()),
1426 aDestStrm.GetEndOfData());
1427 rValue <<= aSeq;
1428 }
1429 break;
1430 }
1431
1432 case OWN_ATTR_REPLACEMENT_GRAPHIC:
1433 {
1434 const GraphicObject* pGrafObj = static_cast< SdrGrafObj* >(GetSdrObject())->GetReplacementGraphicObject();
1435
1436 if (pGrafObj)
1437 {
1438 rValue <<= pGrafObj->GetGraphic().GetXGraphic();
1439 }
1440
1441 break;
1442 }
1443
1444 case OWN_ATTR_GRAFSTREAMURL:
1445 {
1446 const OUString aStreamURL( static_cast<SdrGrafObj*>( GetSdrObject() )->GetGrafStreamURL() );
1447 if( !aStreamURL.isEmpty() )
1448 rValue <<= aStreamURL;
1449 break;
1450 }
1451
1452 case OWN_ATTR_GRAPHIC_URL:
1453 case OWN_ATTR_VALUE_GRAPHIC:
1454 {
1455 if (pProperty->nWID == OWN_ATTR_GRAPHIC_URL)
1456 {
1457 SAL_WARN("svx", "Getting Graphic by URL is not supported, getting it by value");
1458 }
1459
1460 Reference<graphic::XGraphic> xGraphic;
1461 auto pSdrGraphicObject = static_cast<SdrGrafObj*>(GetSdrObject());
1462 if (pSdrGraphicObject
1463 && pSdrGraphicObject->GetGraphicObject().GetType() != GraphicType::NONE)
1464 xGraphic = pSdrGraphicObject->GetGraphic().GetXGraphic();
1465 rValue <<= xGraphic;
1466 break;
1467 }
1468
1469 case OWN_ATTR_GRAPHIC_STREAM:
1470 {
1471 rValue <<= static_cast< SdrGrafObj* >( GetSdrObject() )->getInputStream();
1472 break;
1473 }
1474
1475 case OWN_ATTR_IS_SIGNATURELINE:
1476 {
1477 rValue <<= static_cast<SdrGrafObj*>(GetSdrObject())->isSignatureLine();
1478 break;
1479 }
1480
1481 case OWN_ATTR_SIGNATURELINE_ID:
1482 {
1483 rValue <<= static_cast<SdrGrafObj*>(GetSdrObject())->getSignatureLineId();
1484 break;
1485 }
1486
1487 case OWN_ATTR_SIGNATURELINE_SUGGESTED_SIGNER_NAME:
1488 {
1489 rValue <<= static_cast<SdrGrafObj*>(GetSdrObject())->getSignatureLineSuggestedSignerName();
1490 break;
1491 }
1492
1493 case OWN_ATTR_SIGNATURELINE_SUGGESTED_SIGNER_TITLE:
1494 {
1495 rValue <<= static_cast<SdrGrafObj*>(GetSdrObject())->getSignatureLineSuggestedSignerTitle();
1496 break;
1497 }
1498
1499 case OWN_ATTR_SIGNATURELINE_SUGGESTED_SIGNER_EMAIL:
1500 {
1501 rValue <<= static_cast<SdrGrafObj*>(GetSdrObject())->getSignatureLineSuggestedSignerEmail();
1502 break;
1503 }
1504
1505 case OWN_ATTR_SIGNATURELINE_SIGNING_INSTRUCTIONS:
1506 {
1507 rValue <<= static_cast<SdrGrafObj*>(GetSdrObject())->getSignatureLineSigningInstructions();
1508 break;
1509 }
1510
1511 case OWN_ATTR_SIGNATURELINE_SHOW_SIGN_DATE:
1512 {
1513 rValue <<= static_cast<SdrGrafObj*>(GetSdrObject())->isSignatureLineShowSignDate();
1514 break;
1515 }
1516
1517 case OWN_ATTR_SIGNATURELINE_CAN_ADD_COMMENT:
1518 {
1519 rValue <<= static_cast<SdrGrafObj*>(GetSdrObject())->isSignatureLineCanAddComment();
1520 break;
1521 }
1522
1523 case OWN_ATTR_SIGNATURELINE_UNSIGNED_IMAGE:
1524 {
1525 Reference<graphic::XGraphic> xGraphic(
1526 static_cast<SdrGrafObj*>(GetSdrObject())->getSignatureLineUnsignedGraphic());
1527 rValue <<= xGraphic;
1528 break;
1529 }
1530
1531 case OWN_ATTR_SIGNATURELINE_IS_SIGNED:
1532 {
1533 rValue <<= static_cast<SdrGrafObj*>(GetSdrObject())->isSignatureLineSigned();
1534 break;
1535 }
1536
1537 case OWN_ATTR_QRCODE:
1538 {
1539 css::drawing::QRCode* ptr = static_cast<SdrGrafObj*>(GetSdrObject())->getQrCode();
1540 if(ptr)
1541 {
1542 rValue <<= *ptr;
1543 }
1544 break;
1545 }
1546
1547 default:
1548 return SvxShapeText::getPropertyValueImpl(rName, pProperty,rValue);
1549 }
1550
1551 return true;
1552 }
1553
1554
SvxShapeCaption(SdrObject * pObj)1555 SvxShapeCaption::SvxShapeCaption(SdrObject* pObj)
1556 : SvxShapeText( pObj, getSvxMapProvider().GetMap(SVXMAP_CAPTION), getSvxMapProvider().GetPropertySet(SVXMAP_CAPTION, SdrObject::GetGlobalDrawObjectItemPool()) )
1557 {
1558 }
1559
~SvxShapeCaption()1560 SvxShapeCaption::~SvxShapeCaption() noexcept
1561 {
1562 }
1563
SvxCustomShape(SdrObject * pObj)1564 SvxCustomShape::SvxCustomShape(SdrObject* pObj)
1565 : SvxShapeText( pObj, getSvxMapProvider().GetMap( SVXMAP_CUSTOMSHAPE ), getSvxMapProvider().GetPropertySet(SVXMAP_CUSTOMSHAPE, SdrObject::GetGlobalDrawObjectItemPool()) )
1566 {
1567 }
1568
~SvxCustomShape()1569 SvxCustomShape::~SvxCustomShape() noexcept
1570 {
1571 }
1572
queryInterface(const uno::Type & rType)1573 uno::Any SAL_CALL SvxCustomShape::queryInterface( const uno::Type & rType )
1574 {
1575 return SvxShapeText::queryInterface( rType );
1576 }
1577
queryAggregation(const uno::Type & rType)1578 uno::Any SAL_CALL SvxCustomShape::queryAggregation( const uno::Type & rType )
1579 {
1580 css::uno::Any aReturn = SvxShapeText::queryAggregation( rType );
1581 if ( !aReturn.hasValue() )
1582 aReturn = ::cppu::queryInterface(rType, static_cast<drawing::XEnhancedCustomShapeDefaulter*>(this) );
1583 return aReturn;
1584 }
1585
getImplementationId()1586 uno::Sequence< sal_Int8 > SAL_CALL SvxCustomShape::getImplementationId()
1587 {
1588 return css::uno::Sequence<sal_Int8>();
1589 }
1590
1591 // css::drawing::XShape
1592
1593
getPosition()1594 awt::Point SAL_CALL SvxCustomShape::getPosition()
1595 {
1596 ::SolarMutexGuard aGuard;
1597 if ( HasSdrObject() )
1598 {
1599 SdrAShapeObjGeoData aCustomShapeGeoData;
1600 static_cast<SdrObjCustomShape*>(GetSdrObject())->SaveGeoData( aCustomShapeGeoData );
1601
1602 bool bMirroredX = false;
1603 bool bMirroredY = false;
1604
1605 if ( HasSdrObject() )
1606 {
1607 bMirroredX = static_cast<SdrObjCustomShape*>(GetSdrObject())->IsMirroredX();
1608 bMirroredY = static_cast<SdrObjCustomShape*>(GetSdrObject())->IsMirroredY();
1609 }
1610 // get aRect, this is the unrotated snaprect
1611 tools::Rectangle aRect(static_cast<SdrObjCustomShape*>(GetSdrObject())->GetLogicRect());
1612 tools::Rectangle aRectangle( aRect );
1613
1614 if ( bMirroredX || bMirroredY )
1615 { // we have to retrieve the unmirrored rect
1616
1617 GeoStat aNewGeo( aCustomShapeGeoData.aGeo );
1618 if ( bMirroredX )
1619 {
1620 tools::Polygon aPol( Rect2Poly( aRect, aNewGeo ) );
1621 tools::Rectangle aBoundRect( aPol.GetBoundRect() );
1622
1623 Point aRef1( ( aBoundRect.Left() + aBoundRect.Right() ) >> 1, aBoundRect.Top() );
1624 Point aRef2( aRef1.X(), aRef1.Y() + 1000 );
1625 sal_uInt16 i;
1626 sal_uInt16 nPointCount=aPol.GetSize();
1627 for (i=0; i<nPointCount; i++)
1628 {
1629 MirrorPoint(aPol[i],aRef1,aRef2);
1630 }
1631 // turn and move polygon
1632 tools::Polygon aPol0(aPol);
1633 aPol[0]=aPol0[1];
1634 aPol[1]=aPol0[0];
1635 aPol[2]=aPol0[3];
1636 aPol[3]=aPol0[2];
1637 aPol[4]=aPol0[1];
1638 Poly2Rect(aPol,aRectangle,aNewGeo);
1639 }
1640 if ( bMirroredY )
1641 {
1642 tools::Polygon aPol( Rect2Poly( aRectangle, aNewGeo ) );
1643 tools::Rectangle aBoundRect( aPol.GetBoundRect() );
1644
1645 Point aRef1( aBoundRect.Left(), ( aBoundRect.Top() + aBoundRect.Bottom() ) >> 1 );
1646 Point aRef2( aRef1.X() + 1000, aRef1.Y() );
1647 sal_uInt16 i;
1648 sal_uInt16 nPointCount=aPol.GetSize();
1649 for (i=0; i<nPointCount; i++)
1650 {
1651 MirrorPoint(aPol[i],aRef1,aRef2);
1652 }
1653 // turn and move polygon
1654 tools::Polygon aPol0(aPol);
1655 aPol[0]=aPol0[1];
1656 aPol[1]=aPol0[0];
1657 aPol[2]=aPol0[3];
1658 aPol[3]=aPol0[2];
1659 aPol[4]=aPol0[1];
1660 Poly2Rect( aPol, aRectangle, aNewGeo );
1661 }
1662 }
1663 Point aPt( aRectangle.TopLeft() );
1664
1665 if( GetSdrObject()->getSdrModelFromSdrObject().IsWriter() )
1666 aPt -= GetSdrObject()->GetAnchorPos();
1667
1668 ForceMetricTo100th_mm(aPt);
1669 return css::awt::Point( aPt.X(), aPt.Y() );
1670 }
1671 else
1672 return SvxShape::getPosition();
1673 }
1674
1675
setPropertyValue(const OUString & aPropertyName,const uno::Any & aValue)1676 void SAL_CALL SvxCustomShape::setPropertyValue( const OUString& aPropertyName, const uno::Any& aValue )
1677 {
1678 ::SolarMutexGuard aGuard;
1679
1680 SdrObject* pObject = GetSdrObject();
1681
1682 // tdf#98163 Use a custom slot to have filter code flush the UNO
1683 // API implementations of SdrObjCustomShape. Used e.g. by
1684 // ~SdXMLCustomShapeContext, see there for more information
1685 if("FlushCustomShapeUnoApiObjects" == aPropertyName)
1686 {
1687 SdrObjCustomShape* pTarget = dynamic_cast< SdrObjCustomShape* >(pObject);
1688 if(pTarget)
1689 {
1690 // Luckily, the object causing problems in tdf#93994 is not the
1691 // UNO API object, but the XCustomShapeEngine involved. This
1692 // object is on-demand replaceable and can be reset here. This
1693 // will free the involved EditEngine and VirtualDevice.
1694 pTarget->mxCustomShapeEngine.set(nullptr);
1695 }
1696 // since this case is only for the application cores
1697 // we should return from this function now
1698 return;
1699 }
1700
1701 bool bCustomShapeGeometry = pObject && aPropertyName == "CustomShapeGeometry";
1702
1703 bool bMirroredX = false;
1704 bool bMirroredY = false;
1705
1706 if ( bCustomShapeGeometry )
1707 {
1708 bMirroredX = static_cast<SdrObjCustomShape*>(pObject)->IsMirroredX();
1709 bMirroredY = static_cast<SdrObjCustomShape*>(pObject)->IsMirroredY();
1710 }
1711
1712 SvxShape::setPropertyValue( aPropertyName, aValue );
1713
1714 if ( !bCustomShapeGeometry )
1715 return;
1716
1717 static_cast<SdrObjCustomShape*>(pObject)->MergeDefaultAttributes();
1718 tools::Rectangle aRect( pObject->GetSnapRect() );
1719
1720 // #i38892#
1721 bool bNeedsMirrorX = static_cast<SdrObjCustomShape*>(pObject)->IsMirroredX() != bMirroredX;
1722 bool bNeedsMirrorY = static_cast<SdrObjCustomShape*>(pObject)->IsMirroredY() != bMirroredY;
1723
1724 std::unique_ptr< SdrGluePointList > pListCopy;
1725 if( bNeedsMirrorX || bNeedsMirrorY )
1726 {
1727 const SdrGluePointList* pList = pObject->GetGluePointList();
1728 if( pList )
1729 pListCopy.reset( new SdrGluePointList(*pList) );
1730 }
1731
1732 if ( bNeedsMirrorX )
1733 {
1734 Point aTop( ( aRect.Left() + aRect.Right() ) >> 1, aRect.Top() );
1735 Point aBottom( aTop.X(), aTop.Y() + 1000 );
1736 pObject->NbcMirror( aTop, aBottom );
1737 // NbcMirroring is flipping the current mirror state,
1738 // so we have to set the correct state again
1739 static_cast<SdrObjCustomShape*>(pObject)->SetMirroredX( !bMirroredX );
1740 }
1741 if ( bNeedsMirrorY )
1742 {
1743 Point aLeft( aRect.Left(), ( aRect.Top() + aRect.Bottom() ) >> 1 );
1744 Point aRight( aLeft.X() + 1000, aLeft.Y() );
1745 pObject->NbcMirror( aLeft, aRight );
1746 // NbcMirroring is flipping the current mirror state,
1747 // so we have to set the correct state again
1748 static_cast<SdrObjCustomShape*>(pObject)->SetMirroredY( !bMirroredY );
1749 }
1750
1751 if( pListCopy )
1752 {
1753 SdrGluePointList* pNewList = const_cast< SdrGluePointList* >( pObject->GetGluePointList() );
1754 if(pNewList)
1755 *pNewList = *pListCopy;
1756 }
1757 }
1758
getPropertyValueImpl(const OUString & rName,const SfxItemPropertyMapEntry * pProperty,css::uno::Any & rValue)1759 bool SvxCustomShape::getPropertyValueImpl( const OUString& rName, const SfxItemPropertyMapEntry* pProperty, css::uno::Any& rValue )
1760 {
1761 switch( pProperty->nWID )
1762 {
1763 case SDRATTR_ROTATEANGLE:
1764 {
1765 double fAngle = static_cast<SdrObjCustomShape*>(GetSdrObject())->GetObjectRotation();
1766 fAngle *= 100;
1767 rValue <<= static_cast<sal_Int32>(fAngle);
1768 return true;
1769 }
1770 default:
1771 return SvxShape::getPropertyValueImpl( rName, pProperty, rValue );
1772 }
1773 }
1774
createCustomShapeDefaults(const OUString & rValueType)1775 void SvxCustomShape::createCustomShapeDefaults( const OUString& rValueType )
1776 {
1777 if (!HasSdrObject())
1778 {
1779 OSL_FAIL("could not create Custom Shape Defaults!");
1780 return;
1781 }
1782
1783 static_cast<SdrObjCustomShape*>(GetSdrObject())->MergeDefaultAttributes( &rValueType );
1784 }
1785
1786 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
1787