xref: /core/svx/source/unodraw/unoshape.cxx (revision d900a952)
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 <cppuhelper/supportsservice.hxx>
21 #include <com/sun/star/awt/XBitmap.hpp>
22 #include <com/sun/star/awt/Rectangle.hpp>
23 #include <com/sun/star/drawing/CircleKind.hpp>
24 #include <com/sun/star/lang/NoSupportException.hpp>
25 #include <vcl/svapp.hxx>
26 #include <svl/itemprop.hxx>
27 #include <o3tl/any.hxx>
28 #include <osl/mutex.hxx>
29 #include <editeng/unotext.hxx>
30 #include <svx/svdobj.hxx>
31 #include <svx/svdoole2.hxx>
32 #include <comphelper/scopeguard.hxx>
33 #include <comphelper/servicehelper.hxx>
34 #include <comphelper/multiinterfacecontainer4.hxx>
35 #include <toolkit/helper/vclunohelper.hxx>
36 #include <vcl/gfxlink.hxx>
37 #include <vcl/virdev.hxx>
38 #include <svx/sdangitm.hxx>
39 #include <svx/svdlayer.hxx>
40 #include <svx/svdopage.hxx>
41 #include <svx/svx3ditems.hxx>
42 #include <svx/xflbstit.hxx>
43 #include <svx/xflbmtit.hxx>
44 #include <svx/xlnstit.hxx>
45 #include <svx/xlnedit.hxx>
46 #include <svx/xlnclit.hxx>
47 #include <svx/svdmodel.hxx>
48 #include <svx/svdobjkind.hxx>
49 #include <svx/unopage.hxx>
50 #include <svx/unoshape.hxx>
51 #include <svx/unoshtxt.hxx>
52 #include <svx/svdpage.hxx>
53 #include <svx/unoshprp.hxx>
54 #include <svx/svdograf.hxx>
55 #include <svx/unoapi.hxx>
56 #include <svx/svdomeas.hxx>
57 #include <svx/svdpool.hxx>
58 #include <comphelper/diagnose_ex.hxx>
59 #include <tools/stream.hxx>
60 #include <tools/gen.hxx>
61 #include <tools/UnitConversion.hxx>
62 #include <svx/svdoedge.hxx>
63 #include <svx/svdocapt.hxx>
64 #include <svx/obj3d.hxx>
65 #include <svx/xflftrit.hxx>
66 #include <svx/xtable.hxx>
67 #include <svx/xbtmpit.hxx>
68 #include <svx/xfillit0.hxx>
69 #include <svx/xflgrit.hxx>
70 #include <svx/xflhtit.hxx>
71 #include <svx/xlineit0.hxx>
72 #include <svx/xlndsit.hxx>
73 #include <svx/unomaster.hxx>
74 #include <basegfx/matrix/b2dhommatrix.hxx>
75 #include <basegfx/matrix/b2dhommatrixtools.hxx>
76 #include <basegfx/polygon/b2dpolypolygontools.hxx>
77 #include "gluepts.hxx"
78 #include "shapeimpl.hxx"
79 #include <sal/log.hxx>
80 
81 #include <svx/sdr/contact/viewcontact.hxx>
82 #include <drawinglayer/converters.hxx>
83 #include <drawinglayer/geometry/viewinformation2d.hxx>
84 #include <drawinglayer/primitive2d/transformprimitive2d.hxx>
85 
86 #include <vcl/gdimtf.hxx>
87 #include <vcl/wmf.hxx>
88 #include <svx/sdtfsitm.hxx>
89 #include <svx/svdopath.hxx>
90 #include <svx/SvxXTextColumns.hxx>
91 #include <svx/xflclit.hxx>
92 #include <editeng/frmdiritem.hxx>
93 
94 #include <memory>
95 #include <optional>
96 #include <vector>
97 #include <iostream>
98 
99 #include <bitmaps.hlst>
100 
101 using namespace ::cppu;
102 using namespace ::com::sun::star;
103 using namespace ::com::sun::star::uno;
104 using namespace ::com::sun::star::lang;
105 using namespace ::com::sun::star::container;
106 
107 class GDIMetaFile;
108 
109 struct SvxShapeImpl
110 {
111     std::optional<SfxItemSet> moItemSet;
112     SdrObjKind      mnObjId;
113     SvxShapeMaster* mpMaster;
114     bool            mbDisposing;
115 
116     /** CL, OD 2005-07-19 #i52126# - this is initially 0 and set when
117      *  a SvxShape::Create() call is executed. It is then set to the created
118      *  SdrObject so a multiple call to SvxShape::Create() with same SdrObject
119      *  is prohibited.
120      */
121     ::unotools::WeakReference< SdrObject > mxCreatedObj;
122 
123     // for xComponent
124     ::comphelper::OInterfaceContainerHelper4<css::lang::XEventListener> maDisposeListeners;
125     ::comphelper::OMultiTypeInterfaceContainerHelperVar4<OUString, css::beans::XPropertyChangeListener> maPropertyChangeListeners;
126 
SvxShapeImplSvxShapeImpl127     SvxShapeImpl()
128         :mnObjId( SdrObjKind::NONE )
129         ,mpMaster( nullptr )
130         ,mbDisposing( false )
131     {
132     }
133 };
134 
135 namespace {
136 
137 
138 /// Calculates what scaling factor will be used for autofit text scaling of this shape.
getTextObjectWithFitToSize(SdrObject * pObject)139 SdrTextObj* getTextObjectWithFitToSize(SdrObject* pObject)
140 {
141     SdrTextObj* pTextObj = DynCastSdrTextObj(pObject);
142     if (!pTextObj)
143     {
144         return nullptr;
145     }
146 
147     const SfxItemSet& rTextObjSet = pTextObj->GetMergedItemSet();
148     if (rTextObjSet.GetItem<SdrTextFitToSizeTypeItem>(SDRATTR_TEXT_FITTOSIZE)->GetValue()
149         != drawing::TextFitToSizeType_AUTOFIT)
150     {
151         return nullptr;
152     }
153 
154     return pTextObj;
155 }
156 }
157 
SvxShape(SdrObject * pObject)158 SvxShape::SvxShape( SdrObject* pObject )
159 :   maSize(100,100)
160 ,   mpImpl( new SvxShapeImpl )
161 ,   mbIsMultiPropertyCall(false)
162 ,   mpPropSet(getSvxMapProvider().GetPropertySet(SVXMAP_SHAPE, SdrObject::GetGlobalDrawObjectItemPool()))
163 ,   maPropMapEntries(getSvxMapProvider().GetMap(SVXMAP_SHAPE))
164 ,   mxSdrObject(pObject)
165 ,   mnLockCount(0)
166 {
167     impl_construct();
168 }
169 
170 
SvxShape(SdrObject * pObject,std::span<const SfxItemPropertyMapEntry> pEntries,const SvxItemPropertySet * pPropertySet)171 SvxShape::SvxShape( SdrObject* pObject, std::span<const SfxItemPropertyMapEntry> pEntries, const SvxItemPropertySet* pPropertySet )
172 :   maSize(100,100)
173 ,   mpImpl( new SvxShapeImpl )
174 ,   mbIsMultiPropertyCall(false)
175 ,   mpPropSet(pPropertySet)
176 ,   maPropMapEntries(pEntries)
177 ,   mxSdrObject(pObject)
178 ,   mnLockCount(0)
179 {
180     impl_construct();
181 }
182 
183 
~SvxShape()184 SvxShape::~SvxShape() noexcept
185 {
186     ::SolarMutexGuard aGuard;
187 
188     DBG_ASSERT( mnLockCount == 0, "Locked shape was disposed!" );
189 
190     if ( mpImpl->mpMaster )
191         mpImpl->mpMaster->dispose();
192 
193     if ( mxSdrObject )
194     {
195         mxSdrObject->RemoveListener(*this);
196         mxSdrObject->setUnoShape(nullptr);
197         mxSdrObject.clear();
198     }
199 
200     EndListeningAll(); // call explicitly within SolarMutexGuard
201 }
202 
203 
InvalidateSdrObject()204 void SvxShape::InvalidateSdrObject()
205 {
206     if(mxSdrObject)
207     {
208         mxSdrObject->RemoveListener(*this);
209         mxSdrObject.clear();
210     }
211 };
212 
setShapeKind(SdrObjKind nKind)213 void SvxShape::setShapeKind( SdrObjKind nKind )
214 {
215     mpImpl->mnObjId = nKind;
216 }
217 
218 
getShapeKind() const219 SdrObjKind SvxShape::getShapeKind() const
220 {
221     return mpImpl->mnObjId;
222 }
223 
224 
setMaster(SvxShapeMaster * pMaster)225 void SvxShape::setMaster( SvxShapeMaster* pMaster )
226 {
227     mpImpl->mpMaster = pMaster;
228 }
229 
230 
queryAggregation(const uno::Type & rType)231 uno::Any SAL_CALL SvxShape::queryAggregation( const uno::Type& rType )
232 {
233     if( mpImpl->mpMaster )
234     {
235         uno::Any aAny;
236         if( mpImpl->mpMaster->queryAggregation( rType, aAny ) )
237             return aAny;
238     }
239 
240     return SvxShape_UnoImplHelper::queryAggregation(rType);
241 }
242 
getUnoTunnelId()243 const css::uno::Sequence< sal_Int8 > & SvxShape::getUnoTunnelId() noexcept
244 {
245     static const comphelper::UnoIdInit theSvxShapeUnoTunnelId;
246     return theSvxShapeUnoTunnelId.getSeq();
247 }
248 
getSomething(const css::uno::Sequence<sal_Int8> & rId)249 sal_Int64 SAL_CALL SvxShape::getSomething( const css::uno::Sequence< sal_Int8 >& rId )
250 {
251     return comphelper::getSomethingImpl(rId, this);
252 }
253 
254 
notifyPropertyChange(const OUString & rPropName)255 void SvxShape::notifyPropertyChange(const OUString& rPropName)
256 {
257     std::unique_lock g(m_aMutex);
258     comphelper::OInterfaceContainerHelper4<beans::XPropertyChangeListener>* pPropListeners =
259             mpImpl->maPropertyChangeListeners.getContainer( g, rPropName );
260     comphelper::OInterfaceContainerHelper4<beans::XPropertyChangeListener>* pAllListeners =
261             mpImpl->maPropertyChangeListeners.getContainer( g, OUString() );
262     if (pPropListeners || pAllListeners)
263     {
264         try
265         {
266             // Handle/OldValue not supported
267             beans::PropertyChangeEvent aEvt;
268             aEvt.Source = static_cast<cppu::OWeakObject*>(this);
269             aEvt.PropertyName = rPropName;
270             aEvt.NewValue = getPropertyValue(rPropName);
271             if (pPropListeners)
272                 pPropListeners->notifyEach( g, &beans::XPropertyChangeListener::propertyChange, aEvt );
273             if (pAllListeners)
274                 pAllListeners->notifyEach( g, &beans::XPropertyChangeListener::propertyChange, aEvt );
275         }
276         catch( const Exception& )
277         {
278             DBG_UNHANDLED_EXCEPTION("svx");
279         }
280 
281     }
282 }
283 
impl_construct()284 void SvxShape::impl_construct()
285 {
286     if ( HasSdrObject() )
287     {
288         GetSdrObject()->AddListener(*this);
289         impl_initFromSdrObject();
290     }
291 }
292 
293 
impl_initFromSdrObject()294 void SvxShape::impl_initFromSdrObject()
295 {
296     DBG_TESTSOLARMUTEX();
297     OSL_PRECOND( HasSdrObject(), "SvxShape::impl_initFromSdrObject: not to be called without SdrObject!" );
298     if ( !HasSdrObject() )
299         return;
300 
301     osl_atomic_increment( &m_refCount );
302     {
303         GetSdrObject()->setUnoShape(this);
304     }
305     osl_atomic_decrement( &m_refCount );
306 
307     // #i40944#
308     // Do not simply return when no model but do the type corrections
309     // following below.
310     const SdrInventor nInventor = GetSdrObject()->GetObjInventor();
311 
312     // is it one of ours (svx) ?
313     if( !(nInventor == SdrInventor::Default || nInventor == SdrInventor::E3d || nInventor == SdrInventor::FmForm) )
314         return;
315 
316     if(nInventor == SdrInventor::FmForm)
317     {
318         mpImpl->mnObjId = SdrObjKind::UNO;
319     }
320     else
321     {
322         mpImpl->mnObjId = GetSdrObject()->GetObjIdentifier();
323     }
324 
325     switch(mpImpl->mnObjId)
326     {
327     case SdrObjKind::CircleCut:          // segment of circle
328     case SdrObjKind::CircleArc:          // arc of circle
329     case SdrObjKind::CircleSection:          // sector
330         mpImpl->mnObjId = SdrObjKind::CircleOrEllipse;
331         break;
332     default: ;
333     }
334 }
335 
336 
Create(SdrObject * pNewObj,SvxDrawPage *)337 void SvxShape::Create( SdrObject* pNewObj, SvxDrawPage* /*pNewPage*/ )
338 {
339     DBG_TESTSOLARMUTEX();
340 
341     assert( pNewObj && "SvxShape::Create: invalid new object!" );
342     if ( !pNewObj )
343         return;
344 
345     rtl::Reference<SdrObject> pCreatedObj = mpImpl->mxCreatedObj.get();
346     assert( ( !pCreatedObj || ( pCreatedObj == pNewObj ) ) &&
347         "SvxShape::Create: the same shape used for two different objects?! Strange ..." );
348 
349     // Correct condition (#i52126#)
350     if ( pCreatedObj == pNewObj )
351         return;
352 
353     // Correct condition (#i52126#)
354     mpImpl->mxCreatedObj = pNewObj;
355 
356     if( HasSdrObject() )
357     {
358         GetSdrObject()->RemoveListener( *this );
359     }
360 
361     mxSdrObject = pNewObj;
362 
363     if( HasSdrObject() )
364     {
365         GetSdrObject()->AddListener( *this );
366     }
367 
368     OSL_ENSURE( !mbIsMultiPropertyCall, "SvxShape::Create: hmm?" );
369         // this was previously set in impl_initFromSdrObject, but I think it was superfluous
370         // (it definitely was in the other context where it was called, but I strongly suppose
371         // it was also superfluous when called from here)
372     impl_initFromSdrObject();
373 
374     ObtainSettingsFromPropertySet( *mpPropSet );
375 
376     // save user call
377     SdrObjUserCall* pUser = GetSdrObject()->GetUserCall();
378     GetSdrObject()->SetUserCall(nullptr);
379 
380     setPosition( maPosition );
381     setSize( maSize );
382 
383     // restore user call after we set the initial size
384     GetSdrObject()->SetUserCall( pUser );
385 
386     // if this shape was already named, use this name
387     if( !maShapeName.isEmpty() )
388     {
389         GetSdrObject()->SetName( maShapeName );
390         maShapeName.clear();
391     }
392 }
393 
ForceMetricToItemPoolMetric(Pair & rPoint) const394 void SvxShape::ForceMetricToItemPoolMetric(Pair& rPoint) const noexcept
395 {
396     DBG_TESTSOLARMUTEX();
397     if(!HasSdrObject())
398         return;
399 
400     MapUnit eMapUnit(GetSdrObject()->getSdrModelFromSdrObject().GetItemPool().GetMetric(0));
401     if(eMapUnit == MapUnit::Map100thMM)
402         return;
403 
404     if (const auto eTo = MapToO3tlLength(eMapUnit); eTo != o3tl::Length::invalid)
405     {
406         rPoint.A() = o3tl::convert(rPoint.A(), o3tl::Length::mm100, eTo);
407         rPoint.B() = o3tl::convert(rPoint.B(), o3tl::Length::mm100, eTo);
408     }
409     else
410     {
411         OSL_FAIL("AW: Missing unit translation to PoolMetric!");
412     }
413 }
414 
ForceMetricToItemPoolMetric(basegfx::B2DPolyPolygon & rPolyPolygon) const415 void SvxShape::ForceMetricToItemPoolMetric(basegfx::B2DPolyPolygon& rPolyPolygon) const noexcept
416 {
417     DBG_TESTSOLARMUTEX();
418     if(!HasSdrObject())
419         return;
420 
421     GetSdrObject()->ForceMetricToItemPoolMetric(rPolyPolygon);
422 }
423 
ForceMetricToItemPoolMetric(basegfx::B2DHomMatrix & rB2DHomMatrix) const424 void SvxShape::ForceMetricToItemPoolMetric(basegfx::B2DHomMatrix& rB2DHomMatrix) const noexcept
425 {
426     DBG_TESTSOLARMUTEX();
427     if(!HasSdrObject())
428         return;
429 
430     MapUnit eMapUnit(GetSdrObject()->getSdrModelFromSdrObject().GetItemPool().GetMetric(0));
431     if(eMapUnit == MapUnit::Map100thMM)
432         return;
433 
434     if (const auto eTo = MapToO3tlLength(eMapUnit); eTo != o3tl::Length::invalid)
435     {
436         const double fConvert(o3tl::convert(1.0, o3tl::Length::mm100, eTo));
437         const basegfx::utils::B2DHomMatrixBufferedDecompose aDecomposedTransform(rB2DHomMatrix);
438         rB2DHomMatrix = basegfx::utils::createScaleShearXRotateTranslateB2DHomMatrix(
439             aDecomposedTransform.getScale() * fConvert,
440             aDecomposedTransform.getShearX(),
441             aDecomposedTransform.getRotate(),
442             aDecomposedTransform.getTranslate() * fConvert);
443     }
444     else
445     {
446         OSL_FAIL("Missing unit translation to PoolMetric!");
447     }
448 }
449 
ForceMetricTo100th_mm(Pair & rPoint) const450 void SvxShape::ForceMetricTo100th_mm(Pair& rPoint) const noexcept
451 {
452     DBG_TESTSOLARMUTEX();
453     if(!HasSdrObject())
454         return;
455 
456     MapUnit eMapUnit = GetSdrObject()->getSdrModelFromSdrObject().GetItemPool().GetMetric(0);
457     if(eMapUnit == MapUnit::Map100thMM)
458         return;
459 
460     if (const auto eFrom = MapToO3tlLength(eMapUnit); eFrom != o3tl::Length::invalid)
461     {
462         rPoint.A() = o3tl::convert(rPoint.A(), eFrom, o3tl::Length::mm100);
463         rPoint.B() = o3tl::convert(rPoint.B(), eFrom, o3tl::Length::mm100);
464     }
465     else
466     {
467         OSL_FAIL("AW: Missing unit translation to 100th mm!");
468     }
469 }
470 
ForceMetricTo100th_mm(basegfx::B2DPolyPolygon & rPolyPolygon) const471 void SvxShape::ForceMetricTo100th_mm(basegfx::B2DPolyPolygon& rPolyPolygon) const noexcept
472 {
473     DBG_TESTSOLARMUTEX();
474     if(!HasSdrObject())
475         return;
476 
477     MapUnit eMapUnit = GetSdrObject()->getSdrModelFromSdrObject().GetItemPool().GetMetric(0);
478     if(eMapUnit == MapUnit::Map100thMM)
479         return;
480 
481     if (const auto eFrom = MapToO3tlLength(eMapUnit); eFrom != o3tl::Length::invalid)
482     {
483         const double fConvert(o3tl::convert(1.0, eFrom, o3tl::Length::mm100));
484         rPolyPolygon.transform(basegfx::utils::createScaleB2DHomMatrix(fConvert, fConvert));
485     }
486     else
487     {
488         OSL_FAIL("Missing unit translation to 100th mm!");
489     }
490 }
491 
ForceMetricTo100th_mm(basegfx::B2DHomMatrix & rB2DHomMatrix) const492 void SvxShape::ForceMetricTo100th_mm(basegfx::B2DHomMatrix& rB2DHomMatrix) const noexcept
493 {
494     DBG_TESTSOLARMUTEX();
495     if(!HasSdrObject())
496         return;
497 
498     MapUnit eMapUnit = GetSdrObject()->getSdrModelFromSdrObject().GetItemPool().GetMetric(0);
499     if(eMapUnit == MapUnit::Map100thMM)
500         return;
501 
502     if (const auto eFrom = MapToO3tlLength(eMapUnit); eFrom != o3tl::Length::invalid)
503     {
504         const double fConvert(o3tl::convert(1.0, eFrom, o3tl::Length::mm100));
505         const basegfx::utils::B2DHomMatrixBufferedDecompose aDecomposedTransform(rB2DHomMatrix);
506         rB2DHomMatrix = basegfx::utils::createScaleShearXRotateTranslateB2DHomMatrix(
507             aDecomposedTransform.getScale() * fConvert,
508             aDecomposedTransform.getShearX(),
509             aDecomposedTransform.getRotate(),
510             aDecomposedTransform.getTranslate() * fConvert);
511     }
512     else
513     {
514         OSL_FAIL("Missing unit translation to 100th mm!");
515     }
516 }
517 
SvxItemPropertySet_ObtainSettingsFromPropertySet(const SvxItemPropertySet & rPropSet,SvxItemPropertySetUsrAnys & rAnys,SfxItemSet & rSet,const uno::Reference<beans::XPropertySet> & xSet,const SfxItemPropertyMap * pMap)518 static void SvxItemPropertySet_ObtainSettingsFromPropertySet(const SvxItemPropertySet& rPropSet, SvxItemPropertySetUsrAnys& rAnys,
519   SfxItemSet& rSet, const uno::Reference< beans::XPropertySet >& xSet, const SfxItemPropertyMap* pMap )
520 {
521     if(!rAnys.AreThereOwnUsrAnys())
522         return;
523 
524     const SfxItemPropertyMap& rSrc = rPropSet.getPropertyMap();
525 
526     for(const SfxItemPropertyMapEntry* pSrcProp : rSrc.getPropertyEntries())
527     {
528         const sal_uInt16 nWID = pSrcProp->nWID;
529         if(SfxItemPool::IsWhich(nWID)
530                 && (nWID < OWN_ATTR_VALUE_START || nWID > OWN_ATTR_VALUE_END)
531                 && rAnys.GetUsrAnyForID(*pSrcProp))
532             rSet.Put(rSet.GetPool()->GetUserOrPoolDefaultItem(nWID));
533     }
534 
535     for(const SfxItemPropertyMapEntry* pSrcProp : rSrc.getPropertyEntries())
536     {
537         if(pSrcProp->nWID)
538         {
539             uno::Any* pUsrAny = rAnys.GetUsrAnyForID(*pSrcProp);
540             if(pUsrAny)
541             {
542                 // search for equivalent entry in pDst
543                 const SfxItemPropertyMapEntry* pEntry = pMap->getByName( pSrcProp->aName );
544                 if(pEntry)
545                 {
546                     // entry found
547                     if(pEntry->nWID >= OWN_ATTR_VALUE_START && pEntry->nWID <= OWN_ATTR_VALUE_END)
548                     {
549                         // special ID in PropertySet, can only be set
550                         // directly at the object
551                         xSet->setPropertyValue( pSrcProp->aName, *pUsrAny);
552                     }
553                     else
554                     {
555                         SvxItemPropertySet_setPropertyValue(pEntry, *pUsrAny, rSet);
556                     }
557                 }
558             }
559         }
560     }
561     rAnys.ClearAllUsrAny();
562 }
563 
564 
ObtainSettingsFromPropertySet(const SvxItemPropertySet & rPropSet)565 void SvxShape::ObtainSettingsFromPropertySet(const SvxItemPropertySet& rPropSet)
566 {
567     DBG_TESTSOLARMUTEX();
568     if(HasSdrObject() && maUrsAnys.AreThereOwnUsrAnys())
569     {
570         SfxItemSetFixed<SDRATTR_START, SDRATTR_END> aSet( GetSdrObject()->getSdrModelFromSdrObject().GetItemPool() );
571         Reference< beans::XPropertySet > xShape(this);
572         SvxItemPropertySet_ObtainSettingsFromPropertySet(rPropSet, maUrsAnys, aSet, xShape, &mpPropSet->getPropertyMap() );
573 
574         GetSdrObject()->SetMergedItemSetAndBroadcast(aSet);
575 
576         GetSdrObject()->ApplyNotPersistAttr( aSet );
577     }
578 }
579 
GetBitmap(bool bMetaFile) const580 uno::Any SvxShape::GetBitmap( bool bMetaFile /* = false */ ) const
581 {
582     DBG_TESTSOLARMUTEX();
583     uno::Any aAny;
584 
585     if(!HasSdrObject() || nullptr == GetSdrObject()->getSdrPageFromSdrObject())
586     {
587         return aAny;
588     }
589 
590     // tdf#118662 Emulate old behaviour of XclObjComment (see there)
591     const SdrCaptionObj* pSdrCaptionObj(dynamic_cast<SdrCaptionObj*>(GetSdrObject()));
592     if(nullptr != pSdrCaptionObj && pSdrCaptionObj->isSuppressGetBitmap())
593     {
594         return aAny;
595     }
596 
597     // tdf#119180 If we do not ask for Metafile and we access a SdrGrafObj,
598     // and content exists and is a Bitmap, take the shortcut.
599     // Do *not* do this for Metafile - as can be seen, requested in that case
600     // is a byte-sequence of a saved WMF format file (see below)
601     if(!bMetaFile)
602     {
603         const SdrGrafObj* pSdrGrafObj(dynamic_cast<SdrGrafObj*>(GetSdrObject()));
604 
605         if(nullptr != pSdrGrafObj)
606         {
607             const Graphic& rGraphic(pSdrGrafObj->GetGraphic());
608 
609             if(GraphicType::Bitmap == rGraphic.GetType())
610             {
611                 Reference< awt::XBitmap > xBmp( rGraphic.GetXGraphic(), UNO_QUERY );
612                 aAny <<= xBmp;
613 
614                 return aAny;
615             }
616         }
617     }
618 
619     // tdf#118662 instead of creating an E3dView instance every time to paint
620     // a single SdrObject, use the existing SdrObject::SingleObjectPainter to
621     // use less resources and runtime
622     if(bMetaFile)
623     {
624         ScopedVclPtrInstance< VirtualDevice > pVDev;
625         const tools::Rectangle aBoundRect(GetSdrObject()->GetCurrentBoundRect());
626         GDIMetaFile aMtf;
627 
628         pVDev->SetMapMode(MapMode(MapUnit::Map100thMM));
629         pVDev->EnableOutput(false);
630         aMtf.Record(pVDev);
631         GetSdrObject()->SingleObjectPainter(*pVDev);
632         aMtf.Stop();
633         aMtf.WindStart();
634         aMtf.Move(-aBoundRect.Left(), -aBoundRect.Top());
635         aMtf.SetPrefMapMode(MapMode(MapUnit::Map100thMM));
636         aMtf.SetPrefSize(aBoundRect.GetSize());
637 
638         SvMemoryStream aDestStrm(65535, 65535);
639 
640         ConvertGDIMetaFileToWMF(
641             aMtf,
642             aDestStrm,
643             nullptr,
644             false);
645 
646         const uno::Sequence<sal_Int8> aSeq(
647             static_cast< const sal_Int8* >(aDestStrm.GetData()),
648             aDestStrm.GetEndOfData());
649 
650         aAny <<= aSeq;
651     }
652     else
653     {
654         drawinglayer::primitive2d::Primitive2DContainer xPrimitives;
655         GetSdrObject()->GetViewContact().getViewIndependentPrimitive2DContainer(xPrimitives);
656 
657         if(!xPrimitives.empty())
658         {
659             const drawinglayer::geometry::ViewInformation2D aViewInformation2D;
660             basegfx::B2DRange aRange(
661                 xPrimitives.getB2DRange(aViewInformation2D));
662 
663             if(!aRange.isEmpty())
664             {
665                 const MapUnit aSourceMapUnit(GetSdrObject()->getSdrModelFromSdrObject().GetScaleUnit());
666 
667                 if(MapUnit::Map100thMM != aSourceMapUnit)
668                 {
669                     // tdf#119180 This is UNO API and thus works in 100th_mm,
670                     // so if the MapMode from the used SdrModel is *not* equal
671                     // to Map100thMM we need to embed the primitives to an adapting
672                     // homogen transformation for correct values
673                     const basegfx::B2DHomMatrix aMapTransform(
674                         OutputDevice::LogicToLogic(
675                             MapMode(aSourceMapUnit),
676                             MapMode(MapUnit::Map100thMM)));
677 
678                     // Embed primitives to get them in 100th mm
679                     xPrimitives = drawinglayer::primitive2d::Primitive2DContainer {
680                             new drawinglayer::primitive2d::TransformPrimitive2D(
681                                 aMapTransform,
682                                 std::move(xPrimitives))
683                     };
684 
685                     // Update basegfx::B2DRange aRange, too. Here we have the
686                     // choice of transforming the existing value or get newly by
687                     // again using 'xPrimitives.getB2DRange(aViewInformation2D)'
688                     aRange.transform(aMapTransform);
689                 }
690 
691                 const BitmapEx aBmp(
692                     drawinglayer::convertPrimitive2DContainerToBitmapEx(
693                         std::move(xPrimitives),
694                         aRange));
695 
696                 Graphic aGraph(aBmp);
697 
698                 aGraph.SetPrefSize(aBmp.GetPrefSize());
699                 aGraph.SetPrefMapMode(aBmp.GetPrefMapMode());
700 
701                 Reference< awt::XBitmap > xBmp( aGraph.GetXGraphic(), UNO_QUERY );
702                 aAny <<= xBmp;
703             }
704         }
705     }
706 
707     return aAny;
708 }
709 
getTypes()710 uno::Sequence< uno::Type > SAL_CALL SvxShape::getTypes()
711 {
712     if( mpImpl->mpMaster )
713     {
714         return mpImpl->mpMaster->getTypes();
715     }
716     else
717     {
718         return _getTypes();
719     }
720 }
721 
722 
_getTypes()723 uno::Sequence< uno::Type > const & SvxShape::_getTypes()
724 {
725     switch( mpImpl->mnObjId )
726     {
727     // shapes without text
728     case SdrObjKind::Page:
729     case SdrObjKind::OLEPluginFrame:
730     case SdrObjKind::OLE2Plugin:
731     case SdrObjKind::OLE2Applet:
732     case SdrObjKind::E3D_Cube:
733     case SdrObjKind::E3D_Sphere:
734     case SdrObjKind::E3D_Lathe:
735     case SdrObjKind::E3D_Extrusion:
736     case SdrObjKind::E3D_Polygon:
737     case SdrObjKind::Media:
738     case SdrObjKind::Table:
739         {
740             static uno::Sequence<uno::Type> aTypeSequence{
741                 cppu::UnoType<drawing::XShape>::get(),
742                 cppu::UnoType<lang::XComponent>::get(),
743                 cppu::UnoType<beans::XPropertySet>::get(),
744                 cppu::UnoType<beans::XMultiPropertySet>::get(),
745                 cppu::UnoType<beans::XPropertyState>::get(),
746                 cppu::UnoType<beans::XMultiPropertyStates>::get(),
747                 cppu::UnoType<drawing::XGluePointsSupplier>::get(),
748                 cppu::UnoType<container::XChild>::get(),
749                 cppu::UnoType<lang::XServiceInfo>::get(),
750                 cppu::UnoType<lang::XTypeProvider>::get(),
751                 cppu::UnoType<lang::XUnoTunnel>::get(),
752                 cppu::UnoType<container::XNamed>::get(),
753             };
754 
755             return aTypeSequence;
756         }
757     // group shape
758     case SdrObjKind::Group:
759         {
760             static uno::Sequence<uno::Type> aTypeSequence{
761                 cppu::UnoType<drawing::XShape>::get(),
762                 cppu::UnoType<lang::XComponent>::get(),
763                 cppu::UnoType<beans::XPropertySet>::get(),
764                 cppu::UnoType<beans::XMultiPropertySet>::get(),
765                 cppu::UnoType<beans::XPropertyState>::get(),
766                 cppu::UnoType<beans::XMultiPropertyStates>::get(),
767                 cppu::UnoType<drawing::XGluePointsSupplier>::get(),
768                 cppu::UnoType<container::XChild>::get(),
769                 cppu::UnoType<lang::XServiceInfo>::get(),
770                 cppu::UnoType<lang::XTypeProvider>::get(),
771                 cppu::UnoType<lang::XUnoTunnel>::get(),
772                 cppu::UnoType<container::XNamed>::get(),
773                 cppu::UnoType<drawing::XShapes>::get(),
774                 cppu::UnoType<drawing::XShapeGroup>::get(),
775             };
776 
777             return aTypeSequence;
778         }
779     // connector shape
780     case SdrObjKind::Edge:
781         {
782             static uno::Sequence<uno::Type> aTypeSequence{
783                 cppu::UnoType<drawing::XShape>::get(),
784                 cppu::UnoType<lang::XComponent>::get(),
785                 cppu::UnoType<beans::XPropertySet>::get(),
786                 cppu::UnoType<beans::XMultiPropertySet>::get(),
787                 cppu::UnoType<beans::XPropertyState>::get(),
788                 cppu::UnoType<beans::XMultiPropertyStates>::get(),
789                 cppu::UnoType<drawing::XGluePointsSupplier>::get(),
790                 cppu::UnoType<container::XChild>::get(),
791                 cppu::UnoType<lang::XServiceInfo>::get(),
792                 cppu::UnoType<lang::XTypeProvider>::get(),
793                 cppu::UnoType<lang::XUnoTunnel>::get(),
794                 cppu::UnoType<container::XNamed>::get(),
795                 cppu::UnoType<drawing::XConnectorShape>::get(),
796                 // from SvxUnoTextBase::getTypes()
797                 cppu::UnoType<text::XTextAppend>::get(),
798                 cppu::UnoType<text::XTextCopy>::get(),
799                 cppu::UnoType<container::XEnumerationAccess>::get(),
800                 cppu::UnoType<text::XTextRangeMover>::get(),
801             };
802 
803             return aTypeSequence;
804         }
805     // control shape
806     case SdrObjKind::UNO:
807         {
808             static uno::Sequence<uno::Type> aTypeSequence{
809                 cppu::UnoType<drawing::XShape>::get(),
810                 cppu::UnoType<lang::XComponent>::get(),
811                 cppu::UnoType<beans::XPropertySet>::get(),
812                 cppu::UnoType<beans::XMultiPropertySet>::get(),
813                 cppu::UnoType<beans::XPropertyState>::get(),
814                 cppu::UnoType<beans::XMultiPropertyStates>::get(),
815                 cppu::UnoType<drawing::XGluePointsSupplier>::get(),
816                 cppu::UnoType<container::XChild>::get(),
817                 cppu::UnoType<lang::XServiceInfo>::get(),
818                 cppu::UnoType<lang::XTypeProvider>::get(),
819                 cppu::UnoType<lang::XUnoTunnel>::get(),
820                 cppu::UnoType<container::XNamed>::get(),
821                 cppu::UnoType<drawing::XControlShape>::get(),
822             };
823 
824             return aTypeSequence;
825         }
826     // 3d scene shape
827     case SdrObjKind::E3D_Scene:
828         {
829             static uno::Sequence<uno::Type> aTypeSequence{
830                 cppu::UnoType<drawing::XShape>::get(),
831                 cppu::UnoType<lang::XComponent>::get(),
832                 cppu::UnoType<beans::XPropertySet>::get(),
833                 cppu::UnoType<beans::XMultiPropertySet>::get(),
834                 cppu::UnoType<beans::XPropertyState>::get(),
835                 cppu::UnoType<beans::XMultiPropertyStates>::get(),
836                 cppu::UnoType<drawing::XGluePointsSupplier>::get(),
837                 cppu::UnoType<container::XChild>::get(),
838                 cppu::UnoType<lang::XServiceInfo>::get(),
839                 cppu::UnoType<lang::XTypeProvider>::get(),
840                 cppu::UnoType<lang::XUnoTunnel>::get(),
841                 cppu::UnoType<container::XNamed>::get(),
842                 cppu::UnoType<drawing::XShapes>::get(),
843             };
844 
845             return aTypeSequence;
846         }
847     case SdrObjKind::CustomShape:
848         {
849             static uno::Sequence<uno::Type> aTypeSequence{
850                 cppu::UnoType<drawing::XShape>::get(),
851                 cppu::UnoType<lang::XComponent>::get(),
852                 cppu::UnoType<beans::XPropertySet>::get(),
853                 cppu::UnoType<beans::XMultiPropertySet>::get(),
854                 cppu::UnoType<beans::XPropertyState>::get(),
855                 cppu::UnoType<beans::XMultiPropertyStates>::get(),
856                 cppu::UnoType<drawing::XGluePointsSupplier>::get(),
857                 cppu::UnoType<container::XChild>::get(),
858                 cppu::UnoType<lang::XServiceInfo>::get(),
859                 cppu::UnoType<lang::XTypeProvider>::get(),
860                 cppu::UnoType<lang::XUnoTunnel>::get(),
861                 cppu::UnoType<container::XNamed>::get(),
862                 // from SvxUnoTextBase::getTypes()
863                 cppu::UnoType<text::XText>::get(),
864                 cppu::UnoType<container::XEnumerationAccess>::get(),
865                 cppu::UnoType<text::XTextRangeMover>::get(),
866                 cppu::UnoType<drawing::XEnhancedCustomShapeDefaulter>::get(),
867             };
868 
869             return aTypeSequence;
870         }
871     // shapes with text
872     case SdrObjKind::Rectangle:
873     case SdrObjKind::CircleOrEllipse:
874     case SdrObjKind::Measure:
875     case SdrObjKind::Line:
876     case SdrObjKind::Polygon:
877     case SdrObjKind::PolyLine:
878     case SdrObjKind::PathLine:
879     case SdrObjKind::PathFill:
880     case SdrObjKind::FreehandLine:
881     case SdrObjKind::FreehandFill:
882     case SdrObjKind::PathPoly:
883     case SdrObjKind::PathPolyLine:
884     case SdrObjKind::Graphic:
885     case SdrObjKind::Text:
886     case SdrObjKind::Caption:
887     case SdrObjKind::OLE2: // #i118485# Moved to shapes with text
888     default:
889         {
890             static uno::Sequence<uno::Type> aTypeSequence{
891                 cppu::UnoType<drawing::XShape>::get(),
892                 cppu::UnoType<lang::XComponent>::get(),
893                 cppu::UnoType<beans::XPropertySet>::get(),
894                 cppu::UnoType<beans::XMultiPropertySet>::get(),
895                 cppu::UnoType<beans::XPropertyState>::get(),
896                 cppu::UnoType<beans::XMultiPropertyStates>::get(),
897                 cppu::UnoType<drawing::XGluePointsSupplier>::get(),
898                 cppu::UnoType<container::XChild>::get(),
899                 cppu::UnoType<lang::XServiceInfo>::get(),
900                 cppu::UnoType<lang::XTypeProvider>::get(),
901                 cppu::UnoType<lang::XUnoTunnel>::get(),
902                 cppu::UnoType<container::XNamed>::get(),
903                 // from SvxUnoTextBase::getTypes()
904                 cppu::UnoType<text::XTextAppend>::get(),
905                 cppu::UnoType<text::XTextCopy>::get(),
906                 cppu::UnoType<container::XEnumerationAccess>::get(),
907                 cppu::UnoType<text::XTextRangeMover>::get(),
908             };
909 
910             return aTypeSequence;
911         }
912     }
913 }
914 
915 
getImplementationId()916 uno::Sequence< sal_Int8 > SAL_CALL SvxShape::getImplementationId()
917 {
918     return css::uno::Sequence<sal_Int8>();
919 }
920 
Notify(SfxBroadcaster &,const SfxHint & rHint)921 void SvxShape::Notify( SfxBroadcaster&, const SfxHint& rHint ) noexcept
922 {
923     DBG_TESTSOLARMUTEX();
924 
925     // do cheap checks first, this method is hot
926     if (rHint.GetId() != SfxHintId::ThisIsAnSdrHint)
927         return;
928     if( !mxSdrObject )
929         return;
930     const SdrHint* pSdrHint = static_cast<const SdrHint*>(&rHint);
931     // #i55919# SdrHintKind::ObjectChange is only interesting if it's for this object
932     if (pSdrHint->GetKind() != SdrHintKind::ObjectChange || pSdrHint->GetObject() != mxSdrObject.get())
933         return;
934 
935     // prevent object being deleted from under us
936     rtl::Reference<SdrObject> xSdrSelf(mxSdrObject);
937     uno::Reference< uno::XInterface > xSelf( mxSdrObject->getWeakUnoShape() );
938     if( !xSelf.is() )
939     {
940         mxSdrObject->RemoveListener(*this);
941         mxSdrObject.clear();
942         return;
943     }
944 
945     updateShapeKind();
946 }
947 
948 // XShape
949 
950 
951 // The "*LogicRectHack" functions also existed in sch, and those
952 // duplicate symbols cause Bad Things To Happen (TM)  #i9462#.
953 // Prefixing with 'svx' and marking static to make sure name collisions
954 // do not occur.
955 
svx_needLogicRectHack(SdrObject const * pObj)956 static bool svx_needLogicRectHack( SdrObject const * pObj )
957 {
958     if( pObj->GetObjInventor() == SdrInventor::Default)
959     {
960         switch(pObj->GetObjIdentifier())
961         {
962         case SdrObjKind::Group:
963         case SdrObjKind::Line:
964         case SdrObjKind::Polygon:
965         case SdrObjKind::PolyLine:
966         case SdrObjKind::PathLine:
967         case SdrObjKind::PathFill:
968         case SdrObjKind::FreehandLine:
969         case SdrObjKind::FreehandFill:
970         case SdrObjKind::Edge:
971         case SdrObjKind::PathPoly:
972         case SdrObjKind::PathPolyLine:
973         case SdrObjKind::Measure:
974             return true;
975         default:
976             break;
977         }
978     }
979     return false;
980 }
981 
982 
svx_getLogicRectHack(SdrObject const * pObj)983 static tools::Rectangle svx_getLogicRectHack( SdrObject const * pObj )
984 {
985     if(svx_needLogicRectHack(pObj))
986     {
987         return pObj->GetSnapRect();
988     }
989     else
990     {
991         return pObj->GetLogicRect();
992     }
993 }
994 
995 
svx_setLogicRectHack(SdrObject * pObj,const tools::Rectangle & rRect)996 static void svx_setLogicRectHack( SdrObject* pObj, const tools::Rectangle& rRect )
997 {
998     if(svx_needLogicRectHack(pObj))
999     {
1000         pObj->SetSnapRect( rRect );
1001     }
1002     else
1003     {
1004         pObj->SetLogicRect( rRect );
1005     }
1006 }
1007 
1008 
getPosition()1009 awt::Point SAL_CALL SvxShape::getPosition()
1010 {
1011     ::SolarMutexGuard aGuard;
1012 
1013     if(HasSdrObject())
1014     {
1015         tools::Rectangle aRect( svx_getLogicRectHack(GetSdrObject()) );
1016         Point aPt( aRect.Left(), aRect.Top() );
1017 
1018         // Position is relative to anchor, so recalc to absolute position
1019         if( GetSdrObject()->getSdrModelFromSdrObject().IsWriter() )
1020             aPt -= GetSdrObject()->GetAnchorPos();
1021 
1022         ForceMetricTo100th_mm(aPt);
1023         return css::awt::Point( aPt.X(), aPt.Y() );
1024     }
1025     else
1026     {
1027         return maPosition;
1028     }
1029 }
1030 
1031 
setPosition(const awt::Point & Position)1032 void SAL_CALL SvxShape::setPosition( const awt::Point& Position )
1033 {
1034     ::SolarMutexGuard aGuard;
1035 
1036     if(HasSdrObject())
1037     {
1038         // do NOT move 3D objects, this would change the homogen
1039         // transformation matrix
1040         if(dynamic_cast<const E3dCompoundObject* >(GetSdrObject()) == nullptr)
1041         {
1042             tools::Rectangle aRect( svx_getLogicRectHack(GetSdrObject()) );
1043             Point aLocalPos( Position.X, Position.Y );
1044             ForceMetricToItemPoolMetric(aLocalPos);
1045 
1046             // Position is absolute, so recalc to position relative to anchor
1047             if( GetSdrObject()->getSdrModelFromSdrObject().IsWriter() )
1048                 aLocalPos += GetSdrObject()->GetAnchorPos();
1049 
1050             tools::Long nDX = aLocalPos.X() - aRect.Left();
1051             tools::Long nDY = aLocalPos.Y() - aRect.Top();
1052 
1053             GetSdrObject()->Move( Size( nDX, nDY ) );
1054             GetSdrObject()->getSdrModelFromSdrObject().SetChanged();
1055         }
1056     }
1057 
1058     maPosition = Position;
1059 }
1060 
1061 
getSize()1062 awt::Size SAL_CALL SvxShape::getSize()
1063 {
1064     ::SolarMutexGuard aGuard;
1065 
1066     if(HasSdrObject())
1067     {
1068         tools::Rectangle aRect( svx_getLogicRectHack(GetSdrObject()) );
1069         Size aObjSize( aRect.getOpenWidth(), aRect.getOpenHeight() );
1070         ForceMetricTo100th_mm(aObjSize);
1071         return css::awt::Size( aObjSize.getWidth(), aObjSize.getHeight() );
1072     }
1073     else
1074         return maSize;
1075 }
1076 
1077 
setSize(const awt::Size & rSize)1078 void SAL_CALL SvxShape::setSize( const awt::Size& rSize )
1079 {
1080     ::SolarMutexGuard aGuard;
1081 
1082     if(HasSdrObject())
1083     {
1084         tools::Rectangle aRect( svx_getLogicRectHack(GetSdrObject()) );
1085         Size aLocalSize( rSize.Width, rSize.Height );
1086         ForceMetricToItemPoolMetric(aLocalSize);
1087 
1088         if(GetSdrObject()->GetObjInventor() == SdrInventor::Default && GetSdrObject()->GetObjIdentifier() == SdrObjKind::Measure )
1089         {
1090             Fraction aWdt(aLocalSize.Width(),aRect.Right()-aRect.Left());
1091             Fraction aHgt(aLocalSize.Height(),aRect.Bottom()-aRect.Top());
1092             Point aPt = GetSdrObject()->GetSnapRect().TopLeft();
1093             GetSdrObject()->Resize(aPt,aWdt,aHgt);
1094         }
1095         else
1096         {
1097             //aRect.SetSize(aLocalSize); // this call subtract 1 // https://bz.apache.org/ooo/show_bug.cgi?id=83193
1098             if ( !aLocalSize.Width() )
1099             {
1100                 aRect.SetWidthEmpty();
1101             }
1102             else
1103                 aRect.setWidth(aLocalSize.Width());
1104             if ( !aLocalSize.Height() )
1105             {
1106                 aRect.SetHeightEmpty();
1107             }
1108             else
1109                 aRect.setHeight(aLocalSize.Height());
1110 
1111             svx_setLogicRectHack( GetSdrObject(), aRect );
1112         }
1113 
1114         GetSdrObject()->getSdrModelFromSdrObject().SetChanged();
1115     }
1116     maSize = rSize;
1117 }
1118 
1119 
1120 // XNamed
getName()1121 OUString SAL_CALL SvxShape::getName(  )
1122 {
1123     ::SolarMutexGuard aGuard;
1124     if( HasSdrObject() )
1125     {
1126         return GetSdrObject()->GetName();
1127     }
1128     else
1129     {
1130         return maShapeName;
1131     }
1132 }
1133 
1134 
setName(const OUString & aName)1135 void SAL_CALL SvxShape::setName( const OUString& aName )
1136 {
1137     ::SolarMutexGuard aGuard;
1138     if( HasSdrObject() )
1139     {
1140         GetSdrObject()->SetName( aName );
1141     }
1142     else
1143     {
1144         maShapeName = aName;
1145     }
1146 }
1147 
1148 // XShapeDescriptor
1149 
1150 
getShapeType()1151 OUString SAL_CALL SvxShape::getShapeType()
1152 {
1153     if( !maShapeType.getLength() )
1154         return UHashMap::getNameFromId( mpImpl->mnObjId );
1155     else
1156         return maShapeType;
1157 }
1158 
1159 // XComponent
1160 
1161 
dispose()1162 void SAL_CALL SvxShape::dispose()
1163 {
1164     std::unique_lock g(m_aMutex);
1165 
1166     if( mpImpl->mbDisposing )
1167         return; // caught a recursion
1168 
1169     mpImpl->mbDisposing = true;
1170 
1171     lang::EventObject aEvt;
1172     aEvt.Source = *static_cast<OWeakAggObject*>(this);
1173     mpImpl->maDisposeListeners.disposeAndClear(g, aEvt);
1174     mpImpl->maPropertyChangeListeners.disposeAndClear(g, aEvt);
1175 
1176     rtl::Reference<SdrObject> pObject = mxSdrObject;
1177     if (!pObject)
1178         return;
1179 
1180     pObject->RemoveListener( *this );
1181 
1182     if ( pObject->IsInserted() && pObject->getSdrPageFromSdrObject() )
1183     {
1184         SdrPage* pPage = pObject->getSdrPageFromSdrObject();
1185         // delete the SdrObject from the page
1186         const size_t nCount = pPage->GetObjCount();
1187         for ( size_t nNum = 0; nNum < nCount; ++nNum )
1188         {
1189             if ( pPage->GetObj( nNum ) == pObject.get() )
1190             {
1191                 OSL_VERIFY( pPage->RemoveObject( nNum ) == pObject );
1192                 break;
1193             }
1194         }
1195     }
1196 
1197     mxSdrObject.clear();
1198     pObject->setUnoShape(nullptr);
1199 }
1200 
1201 
addEventListener(const Reference<lang::XEventListener> & xListener)1202 void SAL_CALL SvxShape::addEventListener( const Reference< lang::XEventListener >& xListener )
1203 {
1204     std::unique_lock g(m_aMutex);
1205     mpImpl->maDisposeListeners.addInterface(g, xListener);
1206 }
1207 
1208 
removeEventListener(const Reference<lang::XEventListener> & aListener)1209 void SAL_CALL SvxShape::removeEventListener( const Reference< lang::XEventListener >& aListener )
1210 {
1211     std::unique_lock g(m_aMutex);
1212     mpImpl->maDisposeListeners.removeInterface(g, aListener);
1213 }
1214 
1215 // XPropertySet
1216 
1217 
1218 Reference< beans::XPropertySetInfo > SAL_CALL
getPropertySetInfo()1219     SvxShape::getPropertySetInfo()
1220 {
1221     if( mpImpl->mpMaster )
1222     {
1223         return mpImpl->mpMaster->getPropertySetInfo();
1224     }
1225     else
1226     {
1227         return _getPropertySetInfo();
1228     }
1229 }
1230 
1231 Reference< beans::XPropertySetInfo > const &
_getPropertySetInfo()1232     SvxShape::_getPropertySetInfo()
1233 {
1234     return mpPropSet->getPropertySetInfo();
1235 }
1236 
1237 
addPropertyChangeListener(const OUString & _propertyName,const Reference<beans::XPropertyChangeListener> & _listener)1238 void SAL_CALL SvxShape::addPropertyChangeListener( const OUString& _propertyName, const Reference< beans::XPropertyChangeListener >& _listener  )
1239 {
1240     std::unique_lock g(m_aMutex);
1241     mpImpl->maPropertyChangeListeners.addInterface( g, _propertyName, _listener );
1242 }
1243 
1244 
removePropertyChangeListener(const OUString & _propertyName,const Reference<beans::XPropertyChangeListener> & _listener)1245 void SAL_CALL SvxShape::removePropertyChangeListener( const OUString& _propertyName, const Reference< beans::XPropertyChangeListener >& _listener  )
1246 {
1247     std::unique_lock g(m_aMutex);
1248     mpImpl->maPropertyChangeListeners.removeInterface( g, _propertyName, _listener );
1249 }
1250 
1251 
addVetoableChangeListener(const OUString &,const Reference<beans::XVetoableChangeListener> &)1252 void SAL_CALL SvxShape::addVetoableChangeListener( const OUString& , const Reference< beans::XVetoableChangeListener >&  )
1253 {
1254     OSL_FAIL( "SvxShape::addVetoableChangeListener: don't have any vetoable properties, so why ...?" );
1255 }
1256 
1257 
removeVetoableChangeListener(const OUString &,const Reference<beans::XVetoableChangeListener> &)1258 void SAL_CALL SvxShape::removeVetoableChangeListener( const OUString& , const Reference< beans::XVetoableChangeListener >&  )
1259 {
1260     OSL_FAIL( "SvxShape::removeVetoableChangeListener: don't have any vetoable properties, so why ...?" );
1261 }
1262 
1263 
SetFillAttribute(sal_uInt16 nWID,const OUString & rName)1264 bool SvxShape::SetFillAttribute( sal_uInt16 nWID, const OUString& rName )
1265 {
1266     if(HasSdrObject())
1267     {
1268         SfxItemSet aSet( GetSdrObject()->getSdrModelFromSdrObject().GetItemPool(), nWID, nWID );
1269 
1270         if( SetFillAttribute( nWID, rName, aSet, &GetSdrObject()->getSdrModelFromSdrObject() ) )
1271         {
1272             //GetSdrObject()->SetItemSetAndBroadcast(aSet);
1273             GetSdrObject()->SetMergedItemSetAndBroadcast(aSet);
1274 
1275             return true;
1276         }
1277     }
1278 
1279     return false;
1280 }
1281 
1282 
SetFillAttribute(sal_uInt16 nWID,const OUString & rName,SfxItemSet & rSet,SdrModel const * pModel)1283 bool SvxShape::SetFillAttribute( sal_uInt16 nWID, const OUString& rName, SfxItemSet& rSet, SdrModel const * pModel )
1284 {
1285     // check if an item with the given name and which id is inside the models
1286     // pool or the stylesheet pool, if found it's put in the itemset
1287     if( !SetFillAttribute( nWID, rName, rSet ) )
1288     {
1289         // we did not find such item in one of the pools, so we check
1290         // the property lists that are loaded for the model for items
1291         // that support such.
1292         OUString aStrName = SvxUnogetInternalNameForItem(nWID, rName);
1293 
1294         switch( nWID )
1295         {
1296         case XATTR_FILLBITMAP:
1297         {
1298             XBitmapListRef pBitmapList = pModel->GetBitmapList();
1299 
1300             if( !pBitmapList.is() )
1301                 return false;
1302 
1303             tools::Long nPos = pBitmapList->GetIndex(aStrName);
1304             if( nPos == -1 )
1305                 return false;
1306 
1307             const XBitmapEntry* pEntry = pBitmapList->GetBitmap(nPos);
1308             XFillBitmapItem aBmpItem(rName, pEntry->GetGraphicObject());
1309             rSet.Put(aBmpItem);
1310             break;
1311         }
1312         case XATTR_FILLGRADIENT:
1313         {
1314             XGradientListRef pGradientList = pModel->GetGradientList();
1315 
1316             if( !pGradientList.is() )
1317                 return false;
1318 
1319             tools::Long nPos = pGradientList->GetIndex(aStrName);
1320             if( nPos == -1 )
1321                 return false;
1322 
1323             const XGradientEntry* pEntry = pGradientList->GetGradient(nPos);
1324             XFillGradientItem aGrdItem(rName, pEntry->GetGradient());
1325             rSet.Put( aGrdItem );
1326             break;
1327         }
1328         case XATTR_FILLHATCH:
1329         {
1330             XHatchListRef pHatchList = pModel->GetHatchList();
1331 
1332             if( !pHatchList.is() )
1333                 return false;
1334 
1335             tools::Long nPos = pHatchList->GetIndex(aStrName);
1336             if( nPos == -1 )
1337                 return false;
1338 
1339             const XHatchEntry* pEntry = pHatchList->GetHatch( nPos );
1340             XFillHatchItem aHatchItem(rName, pEntry->GetHatch());
1341             rSet.Put( aHatchItem );
1342             break;
1343         }
1344         case XATTR_LINEEND:
1345         case XATTR_LINESTART:
1346         {
1347             XLineEndListRef pLineEndList = pModel->GetLineEndList();
1348 
1349             if( !pLineEndList.is() )
1350                 return false;
1351 
1352             tools::Long nPos = pLineEndList->GetIndex(aStrName);
1353             if( nPos == -1 )
1354                 return false;
1355 
1356             const XLineEndEntry* pEntry = pLineEndList->GetLineEnd(nPos);
1357             if( sal_uInt16(XATTR_LINEEND) == nWID )
1358             {
1359                 XLineEndItem aLEItem(rName, pEntry->GetLineEnd());
1360                 rSet.Put( aLEItem );
1361             }
1362             else
1363             {
1364                 XLineStartItem aLSItem(rName, pEntry->GetLineEnd());
1365                 rSet.Put( aLSItem );
1366             }
1367 
1368             break;
1369         }
1370         case XATTR_LINEDASH:
1371         {
1372             XDashListRef pDashList = pModel->GetDashList();
1373 
1374             if( !pDashList.is() )
1375                 return false;
1376 
1377             tools::Long nPos = pDashList->GetIndex(aStrName);
1378             if( nPos == -1 )
1379                 return false;
1380 
1381             const XDashEntry* pEntry = pDashList->GetDash(nPos);
1382             XLineDashItem aDashItem(rName, pEntry->GetDash());
1383             rSet.Put( aDashItem );
1384             break;
1385         }
1386         default:
1387             return false;
1388         }
1389     }
1390 
1391     return true;
1392 }
1393 
1394 
SetFillAttribute(sal_uInt16 nWID,const OUString & rName,SfxItemSet & rSet)1395 bool SvxShape::SetFillAttribute( sal_uInt16 nWID, const OUString& rName, SfxItemSet& rSet )
1396 {
1397     OUString aName = SvxUnogetInternalNameForItem(nWID, rName);
1398 
1399     if (aName.isEmpty())
1400     {
1401         switch( nWID )
1402         {
1403         case XATTR_LINEEND:
1404         case XATTR_LINESTART:
1405             {
1406                 const basegfx::B2DPolyPolygon aEmptyPoly;
1407                 if( nWID == sal_uInt16(XATTR_LINEEND) )
1408                     rSet.Put( XLineEndItem( u""_ustr, aEmptyPoly ) );
1409                 else
1410                     rSet.Put( XLineStartItem( u""_ustr, aEmptyPoly ) );
1411 
1412                 return true;
1413             }
1414         case XATTR_FILLFLOATTRANSPARENCE:
1415             {
1416                 // #85953# Set a disabled XFillFloatTransparenceItem
1417                 rSet.Put(XFillFloatTransparenceItem());
1418 
1419                 return true;
1420             }
1421         }
1422 
1423         return false;
1424     }
1425 
1426     ItemSurrogates aSurrogates;
1427     rSet.GetPool()->GetItemSurrogates(aSurrogates, nWID);
1428     for (const SfxPoolItem* p : aSurrogates)
1429     {
1430         const NameOrIndex* pItem = static_cast<const NameOrIndex*>(p);
1431         if( pItem->GetName() == aName )
1432         {
1433             rSet.Put( *pItem );
1434             return true;
1435         }
1436     }
1437 
1438     return false;
1439 }
1440 
1441 
setPropertyValue(const OUString & rPropertyName,const uno::Any & rVal)1442 void SAL_CALL SvxShape::setPropertyValue( const OUString& rPropertyName, const uno::Any& rVal )
1443 {
1444     if( mpImpl->mpMaster )
1445     {
1446         mpImpl->mpMaster->setPropertyValue( rPropertyName, rVal );
1447     }
1448     else
1449     {
1450         _setPropertyValue( rPropertyName, rVal );
1451     }
1452 }
1453 
_setPropertyValue(const OUString & rPropertyName,const uno::Any & rVal)1454 void SvxShape::_setPropertyValue( const OUString& rPropertyName, const uno::Any& rVal )
1455 {
1456     ::SolarMutexGuard aGuard;
1457 
1458     const SfxItemPropertyMapEntry* pMap = mpPropSet->getPropertyMapEntry(rPropertyName);
1459 
1460     if (!HasSdrObject())
1461     {
1462         // Since we have no actual sdr object right now, remember all
1463         // properties in a list. These properties will be set when the sdr
1464         // object is created.
1465 
1466         if (pMap && pMap->nWID)
1467         {
1468             // FIXME: We should throw a UnknownPropertyException here.
1469             //        But since this class is aggregated from classes that
1470             //        support additional properties that we don't know here we
1471             //        silently store *all* properties, even if they may be not
1472             //        supported after creation.
1473             SvxItemPropertySet::setPropertyValue( pMap, rVal, maUrsAnys );
1474         }
1475 
1476         return;
1477     }
1478 
1479     if (rPropertyName == "HandlePathObjScale")
1480     {
1481         auto pPathObj = dynamic_cast<SdrPathObj*>(GetSdrObject());
1482         if (pPathObj)
1483         {
1484             bool bHandleScale{};
1485             if (rVal >>= bHandleScale)
1486             {
1487                 pPathObj->SetHandleScale(bHandleScale);
1488             }
1489         }
1490         return;
1491     }
1492 
1493     if (!pMap)
1494         throw beans::UnknownPropertyException( rPropertyName, getXWeak());
1495 
1496     if ((pMap->nFlags & beans::PropertyAttribute::READONLY) != 0)
1497         throw beans::PropertyVetoException(
1498             "Readonly property can't be set: " + rPropertyName,
1499             uno::Reference<drawing::XShape>(this));
1500 
1501     GetSdrObject()->getSdrModelFromSdrObject().SetChanged();
1502 
1503     if (setPropertyValueImpl(rPropertyName, pMap, rVal))
1504         return;
1505 
1506     DBG_ASSERT( pMap->nWID == SDRATTR_TEXTDIRECTION || pMap->nWID < SDRATTR_NOTPERSIST_FIRST || pMap->nWID > SDRATTR_NOTPERSIST_LAST, "Not persist item not handled!" );
1507     DBG_ASSERT( pMap->nWID < OWN_ATTR_VALUE_START || pMap->nWID > OWN_ATTR_VALUE_END, "Not item property not handled!" );
1508 
1509     bool bIsNotPersist = pMap->nWID >= SDRATTR_NOTPERSIST_FIRST && pMap->nWID <= SDRATTR_NOTPERSIST_LAST && pMap->nWID != SDRATTR_TEXTDIRECTION;
1510 
1511     if( pMap->nWID == SDRATTR_CORNER_RADIUS )
1512     {
1513         sal_Int32 nCornerRadius = 0;
1514         if( !(rVal >>= nCornerRadius) || (nCornerRadius < 0) || (nCornerRadius > 5000000))
1515             throw IllegalArgumentException();
1516     }
1517 
1518     std::optional<SfxItemSet> xLocalSet;
1519     SfxItemSet* pSet;
1520     if( mbIsMultiPropertyCall && !bIsNotPersist )
1521     {
1522         if( !mpImpl->moItemSet )
1523         {
1524             mpImpl->moItemSet.emplace( GetSdrObject()->GetProperties().CreateObjectSpecificItemSet( GetSdrObject()->getSdrModelFromSdrObject().GetItemPool() ) );
1525         }
1526         pSet = &*mpImpl->moItemSet;
1527     }
1528     else
1529     {
1530         xLocalSet.emplace( GetSdrObject()->getSdrModelFromSdrObject().GetItemPool(), pMap->nWID, pMap->nWID);
1531         pSet = &*xLocalSet;
1532     }
1533 
1534     if( pSet->GetItemState( pMap->nWID ) != SfxItemState::SET )
1535         pSet->Put(GetSdrObject()->GetMergedItem(pMap->nWID));
1536 
1537     if( !SvxUnoTextRangeBase::SetPropertyValueHelper( pMap, rVal, *pSet ))
1538     {
1539         if( pSet->GetItemState( pMap->nWID ) != SfxItemState::SET )
1540         {
1541             if(bIsNotPersist)
1542             {
1543                 // not-persistent attribute, get those extra
1544                 GetSdrObject()->TakeNotPersistAttr(*pSet);
1545             }
1546         }
1547 
1548         if( pSet->GetItemState( pMap->nWID ) != SfxItemState::SET )
1549         {
1550             // get default from ItemPool
1551             if(SfxItemPool::IsWhich(pMap->nWID))
1552                 pSet->Put(GetSdrObject()->getSdrModelFromSdrObject().GetItemPool().GetUserOrPoolDefaultItem(pMap->nWID));
1553         }
1554 
1555         if( pSet->GetItemState( pMap->nWID ) == SfxItemState::SET )
1556         {
1557             SvxItemPropertySet_setPropertyValue( pMap, rVal, *pSet );
1558         }
1559     }
1560 
1561     if(bIsNotPersist)
1562     {
1563         // set not-persistent attribute extra
1564         GetSdrObject()->ApplyNotPersistAttr( *pSet );
1565     }
1566     else
1567     {
1568         // if we have a XMultiProperty call then the item set
1569         // will be set in setPropertyValues later
1570         if( !mbIsMultiPropertyCall )
1571             GetSdrObject()->SetMergedItemSetAndBroadcast( *pSet );
1572     }
1573 }
1574 
1575 
getPropertyValue(const OUString & PropertyName)1576 uno::Any SAL_CALL SvxShape::getPropertyValue( const OUString& PropertyName )
1577 {
1578     if ( mpImpl->mpMaster )
1579         return mpImpl->mpMaster->getPropertyValue( PropertyName );
1580     else
1581         return _getPropertyValue( PropertyName );
1582 }
1583 
1584 
_getPropertyValue(const OUString & PropertyName)1585 uno::Any SvxShape::_getPropertyValue( const OUString& PropertyName )
1586 {
1587     ::SolarMutexGuard aGuard;
1588 
1589     const SfxItemPropertyMapEntry* pMap = mpPropSet->getPropertyMapEntry(PropertyName);
1590 
1591     uno::Any aAny;
1592     if(HasSdrObject())
1593     {
1594         if(pMap == nullptr )
1595             throw beans::UnknownPropertyException( PropertyName, getXWeak());
1596 
1597         if( !getPropertyValueImpl( PropertyName, pMap, aAny ) )
1598         {
1599             DBG_ASSERT( pMap->nWID == SDRATTR_TEXTDIRECTION || (pMap->nWID < SDRATTR_NOTPERSIST_FIRST || pMap->nWID > SDRATTR_NOTPERSIST_LAST), "Not persist item not handled!" );
1600             DBG_ASSERT( pMap->nWID < OWN_ATTR_VALUE_START || pMap->nWID > OWN_ATTR_VALUE_END, "Not item property not handled!" );
1601 
1602             SfxItemSet aSet( GetSdrObject()->getSdrModelFromSdrObject().GetItemPool(), pMap->nWID, pMap->nWID );
1603             aSet.Put(GetSdrObject()->GetMergedItem(pMap->nWID));
1604 
1605             if(SvxUnoTextRangeBase::GetPropertyValueHelper(  aSet, pMap, aAny ))
1606                 return aAny;
1607 
1608             if(!aSet.Count())
1609             {
1610                 if(pMap->nWID >= SDRATTR_NOTPERSIST_FIRST && pMap->nWID <= SDRATTR_NOTPERSIST_LAST)
1611                 {
1612                     // not-persistent attribute, get those extra
1613                     GetSdrObject()->TakeNotPersistAttr(aSet);
1614                 }
1615             }
1616 
1617             if(!aSet.Count())
1618             {
1619                 // get default from ItemPool
1620                 if(SfxItemPool::IsWhich(pMap->nWID))
1621                     aSet.Put(GetSdrObject()->getSdrModelFromSdrObject().GetItemPool().GetUserOrPoolDefaultItem(pMap->nWID));
1622             }
1623 
1624             if(aSet.Count())
1625                 aAny = GetAnyForItem( aSet, pMap );
1626         }
1627     }
1628     else
1629     {
1630 
1631 // Fixme: we should return default values for OWN_ATTR !
1632 
1633         if(pMap && pMap->nWID)
1634 //      FixMe: see setPropertyValue
1635             aAny = mpPropSet->getPropertyValue( pMap, maUrsAnys );
1636 
1637     }
1638     return aAny;
1639 }
1640 
1641 
1642 // XMultiPropertySet
setPropertyValues(const css::uno::Sequence<OUString> & aPropertyNames,const css::uno::Sequence<css::uno::Any> & aValues)1643 void SAL_CALL SvxShape::setPropertyValues( const css::uno::Sequence< OUString >& aPropertyNames, const css::uno::Sequence< css::uno::Any >& aValues )
1644 {
1645     ::SolarMutexGuard aSolarGuard;
1646 
1647     const sal_Int32 nCount = aPropertyNames.getLength();
1648     if (nCount != aValues.getLength())
1649         throw css::lang::IllegalArgumentException(u"lengths do not match"_ustr,
1650                                                   getXWeak(), -1);
1651 
1652     const OUString* pNames = aPropertyNames.getConstArray();
1653     const uno::Any* pValues = aValues.getConstArray();
1654 
1655     // make sure mbIsMultiPropertyCall and mpImpl->mpItemSet are
1656     // reset even when an exception is thrown
1657     const ::comphelper::ScopeGuard aGuard( [this] () { return this->endSetPropertyValues(); } );
1658 
1659     mbIsMultiPropertyCall = true;
1660 
1661     if( mpImpl->mpMaster )
1662     {
1663         for( sal_Int32 nIdx = 0; nIdx < nCount; nIdx++, pNames++, pValues++ )
1664         {
1665             try
1666             {
1667                 setPropertyValue( *pNames, *pValues );
1668             }
1669             catch (beans::UnknownPropertyException&)
1670             {
1671                 // ignore, various code likes to opportunistically set properties on objects that don't support those properties
1672             }
1673             catch (uno::Exception&)
1674             {
1675                 DBG_UNHANDLED_EXCEPTION("svx");
1676             }
1677         }
1678     }
1679     else
1680     {
1681         uno::Reference< beans::XPropertySet > xSet;
1682         queryInterface( cppu::UnoType<beans::XPropertySet>::get()) >>= xSet;
1683 
1684         for( sal_Int32 nIdx = 0; nIdx < nCount; nIdx++, pNames++, pValues++ )
1685         {
1686             try
1687             {
1688                 xSet->setPropertyValue( *pNames, *pValues );
1689             }
1690             catch (beans::UnknownPropertyException&)
1691             {
1692                 DBG_UNHANDLED_EXCEPTION("svx");
1693             }
1694             catch (uno::Exception&)
1695             {
1696                 DBG_UNHANDLED_EXCEPTION("svx");
1697             }
1698         }
1699     }
1700 
1701     if( mpImpl->moItemSet && HasSdrObject() )
1702         GetSdrObject()->SetMergedItemSetAndBroadcast( *mpImpl->moItemSet );
1703 }
1704 
1705 
endSetPropertyValues()1706 void SvxShape::endSetPropertyValues()
1707 {
1708     mbIsMultiPropertyCall = false;
1709     mpImpl->moItemSet.reset();
1710 }
1711 
1712 
getPropertyValues(const css::uno::Sequence<OUString> & aPropertyNames)1713 css::uno::Sequence< css::uno::Any > SAL_CALL SvxShape::getPropertyValues( const css::uno::Sequence< OUString >& aPropertyNames )
1714 {
1715     const sal_Int32 nCount = aPropertyNames.getLength();
1716     const OUString* pNames = aPropertyNames.getConstArray();
1717 
1718     uno::Sequence< uno::Any > aRet( nCount );
1719     uno::Any* pValue = aRet.getArray();
1720 
1721     if( mpImpl->mpMaster )
1722     {
1723         for( sal_Int32 nIdx = 0; nIdx < nCount; nIdx++, pValue++, pNames++ )
1724         {
1725             try
1726             {
1727                 *pValue = getPropertyValue( *pNames );
1728             }
1729             catch( uno::Exception& )
1730             {
1731                 OSL_FAIL( "SvxShape::getPropertyValues, unknown property asked" );
1732             }
1733         }
1734     }
1735     else
1736     {
1737         uno::Reference< beans::XPropertySet > xSet;
1738         queryInterface( cppu::UnoType<beans::XPropertySet>::get()) >>= xSet;
1739 
1740         for( sal_Int32 nIdx = 0; nIdx < nCount; nIdx++, pValue++, pNames++ )
1741         {
1742             try
1743             {
1744                 *pValue = xSet->getPropertyValue( *pNames );
1745             }
1746             catch( uno::Exception& )
1747             {
1748                 OSL_FAIL( "SvxShape::getPropertyValues, unknown property asked" );
1749             }
1750         }
1751     }
1752 
1753     return aRet;
1754 }
1755 
addPropertiesChangeListener(const css::uno::Sequence<OUString> &,const css::uno::Reference<css::beans::XPropertiesChangeListener> &)1756 void SAL_CALL SvxShape::addPropertiesChangeListener( const css::uno::Sequence< OUString >& , const css::uno::Reference< css::beans::XPropertiesChangeListener >&  )
1757 {
1758 }
1759 
removePropertiesChangeListener(const css::uno::Reference<css::beans::XPropertiesChangeListener> &)1760 void SAL_CALL SvxShape::removePropertiesChangeListener( const css::uno::Reference< css::beans::XPropertiesChangeListener >&  )
1761 {
1762 }
1763 
firePropertiesChangeEvent(const css::uno::Sequence<OUString> &,const css::uno::Reference<css::beans::XPropertiesChangeListener> &)1764 void SAL_CALL SvxShape::firePropertiesChangeEvent( const css::uno::Sequence< OUString >& , const css::uno::Reference< css::beans::XPropertiesChangeListener >&  )
1765 {
1766 }
1767 
1768 
GetAnyForItem(SfxItemSet const & aSet,const SfxItemPropertyMapEntry * pMap) const1769 uno::Any SvxShape::GetAnyForItem( SfxItemSet const & aSet, const SfxItemPropertyMapEntry* pMap ) const
1770 {
1771     DBG_TESTSOLARMUTEX();
1772     uno::Any aAny;
1773 
1774     switch(pMap->nWID)
1775     {
1776     case SDRATTR_CIRCSTARTANGLE:
1777     {
1778         if(const SdrAngleItem* pPoolItem = aSet.GetItemIfSet(SDRATTR_CIRCSTARTANGLE,false))
1779         {
1780             Degree100 nAngle = pPoolItem->GetValue();
1781             aAny <<= nAngle.get();
1782         }
1783         break;
1784     }
1785 
1786     case SDRATTR_CIRCENDANGLE:
1787     {
1788         if (const SdrAngleItem* pPoolItem = aSet.GetItemIfSet(SDRATTR_CIRCENDANGLE,false))
1789         {
1790             Degree100 nAngle = pPoolItem->GetValue();
1791             aAny <<= nAngle.get();
1792         }
1793         break;
1794     }
1795 
1796     case SDRATTR_CIRCKIND:
1797     {
1798         if( GetSdrObject()->GetObjInventor() == SdrInventor::Default)
1799         {
1800             drawing::CircleKind eKind;
1801             switch(GetSdrObject()->GetObjIdentifier())
1802             {
1803             case SdrObjKind::CircleOrEllipse:          // circle, ellipse
1804                 eKind = drawing::CircleKind_FULL;
1805                 break;
1806             case SdrObjKind::CircleCut:          // segment of circle
1807                 eKind = drawing::CircleKind_CUT;
1808                 break;
1809             case SdrObjKind::CircleArc:          // arc of circle
1810                 eKind = drawing::CircleKind_ARC;
1811                 break;
1812             case SdrObjKind::CircleSection:          // sector
1813                 eKind = drawing::CircleKind_SECTION;
1814                 break;
1815             default:
1816                 break;
1817             }
1818             aAny <<= eKind;
1819         }
1820         break;
1821     }
1822     default:
1823     {
1824         // get value from ItemSet
1825         aAny = SvxItemPropertySet_getPropertyValue( pMap, aSet );
1826 
1827         if( pMap->aType != aAny.getValueType() )
1828         {
1829             // since the sfx uint16 item now exports a sal_Int32, we may have to fix this here
1830             if( ( pMap->aType == ::cppu::UnoType<sal_Int16>::get()) && aAny.getValueType() == ::cppu::UnoType<sal_Int32>::get() )
1831             {
1832                 sal_Int32 nValue = 0;
1833                 aAny >>= nValue;
1834                 aAny <<= static_cast<sal_Int16>(nValue);
1835             }
1836             else
1837             {
1838                 SAL_WARN("svx", "SvxShape::GetAnyForItem() Return value has wrong Type, " << pMap->aType << " != " << aAny.getValueType());
1839             }
1840         }
1841 
1842     }
1843     }
1844 
1845     return aAny;
1846 }
1847 
1848 
1849 // XPropertyState
getPropertyState(const OUString & PropertyName)1850 beans::PropertyState SAL_CALL SvxShape::getPropertyState( const OUString& PropertyName )
1851 {
1852     if( mpImpl->mpMaster )
1853     {
1854         return mpImpl->mpMaster->getPropertyState( PropertyName );
1855     }
1856     else
1857     {
1858         return _getPropertyState( PropertyName );
1859     }
1860 }
1861 
_getPropertyState(const OUString & PropertyName)1862 beans::PropertyState SvxShape::_getPropertyState( const OUString& PropertyName )
1863 {
1864     ::SolarMutexGuard aGuard;
1865 
1866     const SfxItemPropertyMapEntry* pMap = mpPropSet->getPropertyMapEntry(PropertyName);
1867 
1868     if( !HasSdrObject() || pMap == nullptr )
1869         throw beans::UnknownPropertyException( PropertyName, getXWeak());
1870 
1871     beans::PropertyState eState;
1872     if( !getPropertyStateImpl( pMap, eState ) )
1873     {
1874         const SfxItemSet& rSet = GetSdrObject()->GetMergedItemSet();
1875 
1876         switch( rSet.GetItemState( pMap->nWID, false ) )
1877         {
1878         case SfxItemState::SET:
1879             eState = beans::PropertyState_DIRECT_VALUE;
1880             break;
1881         case SfxItemState::DEFAULT:
1882             eState = beans::PropertyState_DEFAULT_VALUE;
1883             break;
1884         default:
1885             eState = beans::PropertyState_AMBIGUOUS_VALUE;
1886             break;
1887         }
1888 
1889         // if an item is set, this doesn't mean we want it :)
1890         if( beans::PropertyState_DIRECT_VALUE == eState )
1891         {
1892             switch( pMap->nWID )
1893             {
1894             // the following items are disabled by changing the
1895             // fill style or the line style. so there is no need
1896             // to export items without names which should be empty
1897             case XATTR_FILLBITMAP:
1898             case XATTR_FILLGRADIENT:
1899             case XATTR_FILLHATCH:
1900             case XATTR_LINEDASH:
1901                 {
1902                     const NameOrIndex* pItem = rSet.GetItem<NameOrIndex>(pMap->nWID);
1903                     if( ( pItem == nullptr ) || pItem->GetName().isEmpty() )
1904                         eState = beans::PropertyState_DEFAULT_VALUE;
1905                 }
1906                 break;
1907 
1908             // #i36115#
1909             // If e.g. the LineStart is on NONE and thus the string has length 0, it still
1910             // may be a hard attribute covering the set LineStart of the parent (Style).
1911             // #i37644#
1912             // same is for fill float transparency
1913             case XATTR_LINEEND:
1914             case XATTR_LINESTART:
1915             case XATTR_FILLFLOATTRANSPARENCE:
1916                 {
1917                     const NameOrIndex* pItem = rSet.GetItem<NameOrIndex>(pMap->nWID);
1918                     if ( pItem == nullptr )
1919                         eState = beans::PropertyState_DEFAULT_VALUE;
1920                 }
1921                 break;
1922             case XATTR_FILLCOLOR:
1923                 if (pMap->nMemberId == MID_COLOR_THEME_INDEX)
1924                 {
1925                     const XFillColorItem* pColor = rSet.GetItem<XFillColorItem>(pMap->nWID);
1926                     if (!pColor->getComplexColor().isValidThemeType())
1927                     {
1928                         eState = beans::PropertyState_DEFAULT_VALUE;
1929                     }
1930                 }
1931                 else if (pMap->nMemberId == MID_COLOR_LUM_MOD)
1932                 {
1933                     const XFillColorItem* pColor = rSet.GetItem<XFillColorItem>(pMap->nWID);
1934                     sal_Int16 nLumMod = 10000;
1935                     for (auto const& rTransform : pColor->getComplexColor().getTransformations())
1936                     {
1937                         if (rTransform.meType == model::TransformationType::LumMod)
1938                             nLumMod = rTransform.mnValue;
1939                     }
1940                     if (nLumMod == 10000)
1941                     {
1942                         eState = beans::PropertyState_DEFAULT_VALUE;
1943                     }
1944                 }
1945                 else if (pMap->nMemberId == MID_COLOR_LUM_OFF)
1946                 {
1947                     const XFillColorItem* pColor = rSet.GetItem<XFillColorItem>(pMap->nWID);
1948                     sal_Int16 nLumOff = 0;
1949                     for (auto const& rTransform : pColor->getComplexColor().getTransformations())
1950                     {
1951                         if (rTransform.meType == model::TransformationType::LumOff)
1952                             nLumOff = rTransform.mnValue;
1953                     }
1954                     if (nLumOff == 0)
1955                     {
1956                         eState = beans::PropertyState_DEFAULT_VALUE;
1957                     }
1958                 }
1959                 else if (pMap->nMemberId == MID_COMPLEX_COLOR)
1960                 {
1961                     auto const* pColor = rSet.GetItem<XFillColorItem>(pMap->nWID);
1962                     if (pColor->getComplexColor().getType() == model::ColorType::Unused)
1963                     {
1964                         eState = beans::PropertyState_DEFAULT_VALUE;
1965                     }
1966                 }
1967                 break;
1968             case XATTR_LINECOLOR:
1969                 if (pMap->nMemberId == MID_COMPLEX_COLOR)
1970                 {
1971                     auto const* pColor = rSet.GetItem<XLineColorItem>(pMap->nWID);
1972                     if (pColor->getComplexColor().getType() == model::ColorType::Unused)
1973                     {
1974                         eState = beans::PropertyState_DEFAULT_VALUE;
1975                     }
1976                 }
1977                 break;
1978             }
1979         }
1980     }
1981     return eState;
1982 }
1983 
setPropertyValueImpl(const OUString &,const SfxItemPropertyMapEntry * pProperty,const css::uno::Any & rValue)1984 bool SvxShape::setPropertyValueImpl( const OUString&, const SfxItemPropertyMapEntry* pProperty, const css::uno::Any& rValue )
1985 {
1986     rtl::Reference<SdrObject> pSdrObject = GetSdrObject();
1987     switch( pProperty->nWID )
1988     {
1989     case OWN_ATTR_CAPTION_POINT:
1990     {
1991         awt::Point aPnt;
1992         if( rValue >>= aPnt )
1993         {
1994             Point aVclPoint( aPnt.X, aPnt.Y );
1995 
1996             // tdf#117145 metric of SdrModel is app-specific, metric of UNO API is 100thmm
1997             // Need to adapt aVclPoint from 100thmm to app-specific
1998             ForceMetricToItemPoolMetric(aVclPoint);
1999 
2000             // #90763# position is relative to top left, make it absolute
2001             basegfx::B2DPolyPolygon aNewPolyPolygon;
2002             basegfx::B2DHomMatrix aNewHomogenMatrix;
2003             pSdrObject->TRGetBaseGeometry(aNewHomogenMatrix, aNewPolyPolygon);
2004 
2005             aVclPoint.AdjustX(basegfx::fround<tools::Long>(aNewHomogenMatrix.get(0, 2)) );
2006             aVclPoint.AdjustY(basegfx::fround<tools::Long>(aNewHomogenMatrix.get(1, 2)) );
2007 
2008             // #88491# position relative to anchor
2009             if( pSdrObject->getSdrModelFromSdrObject().IsWriter() )
2010             {
2011                 aVclPoint += pSdrObject->GetAnchorPos();
2012             }
2013 
2014             static_cast<SdrCaptionObj*>(pSdrObject.get())->SetTailPos(aVclPoint);
2015 
2016             return true;
2017         }
2018         break;
2019     }
2020     case OWN_ATTR_TRANSFORMATION:
2021     {
2022         drawing::HomogenMatrix3 aMatrix;
2023         if(rValue >>= aMatrix)
2024         {
2025             basegfx::B2DPolyPolygon aNewPolyPolygon;
2026             basegfx::B2DHomMatrix aNewHomogenMatrix;
2027 
2028             // tdf#117145 SdrModel data is app-specific
2029             pSdrObject->TRGetBaseGeometry(aNewHomogenMatrix, aNewPolyPolygon);
2030 
2031             aNewHomogenMatrix.set(0, 0, aMatrix.Line1.Column1);
2032             aNewHomogenMatrix.set(0, 1, aMatrix.Line1.Column2);
2033             aNewHomogenMatrix.set(0, 2, aMatrix.Line1.Column3);
2034             aNewHomogenMatrix.set(1, 0, aMatrix.Line2.Column1);
2035             aNewHomogenMatrix.set(1, 1, aMatrix.Line2.Column2);
2036             aNewHomogenMatrix.set(1, 2, aMatrix.Line2.Column3);
2037             // For this to be a valid 2D transform matrix, the last row must be [0,0,1]
2038             assert( aMatrix.Line3.Column1 == 0 );
2039             assert( aMatrix.Line3.Column2 == 0 );
2040             assert( aMatrix.Line3.Column3 == 1 );
2041 
2042             // tdf#117145 metric of SdrModel is app-specific, metric of UNO API is 100thmm
2043             // Need to adapt aNewHomogenMatrix from 100thmm to app-specific
2044             ForceMetricToItemPoolMetric(aNewHomogenMatrix);
2045 
2046             pSdrObject->TRSetBaseGeometry(aNewHomogenMatrix, aNewPolyPolygon);
2047             return true;
2048         }
2049         break;
2050     }
2051 
2052     case OWN_ATTR_ZORDER:
2053     {
2054         sal_Int32 nNewOrdNum = 0;
2055         if(rValue >>= nNewOrdNum)
2056         {
2057             SdrObjList* pObjList = pSdrObject->getParentSdrObjListFromSdrObject();
2058             if( pObjList )
2059                 pObjList->SetExistingObjectOrdNum( pSdrObject.get(), static_cast<size_t>(nNewOrdNum) );
2060             return true;
2061         }
2062         break;
2063     }
2064     case OWN_ATTR_FRAMERECT:
2065     {
2066         awt::Rectangle aUnoRect;
2067         if(rValue >>= aUnoRect)
2068         {
2069             Point aTopLeft( aUnoRect.X, aUnoRect.Y );
2070             Size aObjSize( aUnoRect.Width, aUnoRect.Height );
2071             ForceMetricToItemPoolMetric(aTopLeft);
2072             ForceMetricToItemPoolMetric(aObjSize);
2073             tools::Rectangle aRect(aTopLeft, aObjSize);
2074             pSdrObject->SetSnapRect(aRect);
2075             return true;
2076         }
2077         break;
2078     }
2079     case OWN_ATTR_MIRRORED:
2080     {
2081         bool bMirror;
2082         if(rValue >>= bMirror )
2083         {
2084             SdrGrafObj* pObj = dynamic_cast< SdrGrafObj* >( pSdrObject.get() );
2085             if( pObj )
2086                 pObj->SetMirrored(bMirror);
2087             return true;
2088         }
2089         break;
2090     }
2091     case OWN_ATTR_EDGE_START_OBJ:
2092     case OWN_ATTR_EDGE_END_OBJ:
2093     case OWN_ATTR_GLUEID_HEAD:
2094     case OWN_ATTR_GLUEID_TAIL:
2095     case OWN_ATTR_EDGE_START_POS:
2096     case OWN_ATTR_EDGE_END_POS:
2097     case OWN_ATTR_EDGE_POLYPOLYGONBEZIER:
2098     {
2099         SdrEdgeObj* pEdgeObj = dynamic_cast< SdrEdgeObj* >(pSdrObject.get());
2100         if(pEdgeObj)
2101         {
2102             switch(pProperty->nWID)
2103             {
2104             case OWN_ATTR_EDGE_START_OBJ:
2105             case OWN_ATTR_EDGE_END_OBJ:
2106                 {
2107                     Reference< drawing::XShape > xShape;
2108                     if( rValue >>= xShape )
2109                     {
2110                         SdrObject* pNode = SdrObject::getSdrObjectFromXShape(xShape);
2111                         if( pNode )
2112                         {
2113                             pEdgeObj->ConnectToNode( pProperty->nWID == OWN_ATTR_EDGE_START_OBJ, pNode );
2114                             pEdgeObj->setGluePointIndex( pProperty->nWID == OWN_ATTR_EDGE_START_OBJ );
2115                             return true;
2116                         }
2117                     }
2118                     break;
2119                 }
2120 
2121             case OWN_ATTR_EDGE_START_POS:
2122             case OWN_ATTR_EDGE_END_POS:
2123                 {
2124                     awt::Point aUnoPoint;
2125                     if( rValue >>= aUnoPoint )
2126                     {
2127                         Point aPoint( aUnoPoint.X, aUnoPoint.Y );
2128 
2129                         // Reintroduction of fix for issue i59051 (#i108851#)
2130                         // perform metric change before applying anchor position,
2131                         // because the anchor position is in pool metric.
2132                         ForceMetricToItemPoolMetric( aPoint );
2133                         if( pSdrObject->getSdrModelFromSdrObject().IsWriter() )
2134                             aPoint += pSdrObject->GetAnchorPos();
2135 
2136                         pEdgeObj->SetTailPoint( pProperty->nWID == OWN_ATTR_EDGE_START_POS, aPoint );
2137                         return true;
2138                     }
2139                     break;
2140                 }
2141 
2142             case OWN_ATTR_GLUEID_HEAD:
2143             case OWN_ATTR_GLUEID_TAIL:
2144                 {
2145                     sal_Int32 nId = 0;
2146                     if( rValue >>= nId )
2147                     {
2148                         pEdgeObj->setGluePointIndex( pProperty->nWID == OWN_ATTR_GLUEID_HEAD, nId );
2149                         return true;
2150                     }
2151                     break;
2152                 }
2153             case OWN_ATTR_EDGE_POLYPOLYGONBEZIER:
2154                 {
2155                     basegfx::B2DPolyPolygon aNewPolyPolygon;
2156 
2157                     // #123616# be a little bit more flexible regarding the data type used
2158                     if( auto s = o3tl::tryAccess<drawing::PointSequenceSequence>(rValue) )
2159                     {
2160                         // get polygpon data from PointSequenceSequence
2161                         aNewPolyPolygon = basegfx::utils::UnoPointSequenceSequenceToB2DPolyPolygon(
2162                             *s);
2163                     }
2164                     else if( auto cs = o3tl::tryAccess<drawing::PolyPolygonBezierCoords>(rValue) )
2165                     {
2166                         // get polygpon data from PolyPolygonBezierCoords
2167                         aNewPolyPolygon = basegfx::utils::UnoPolyPolygonBezierCoordsToB2DPolyPolygon(
2168                             *cs);
2169                     }
2170 
2171                     if(aNewPolyPolygon.count())
2172                     {
2173                         // Reintroduction of fix for issue i59051 (#i108851#)
2174                         ForceMetricToItemPoolMetric( aNewPolyPolygon );
2175                         if( pSdrObject->getSdrModelFromSdrObject().IsWriter() )
2176                         {
2177                             Point aPoint( pSdrObject->GetAnchorPos() );
2178                             aNewPolyPolygon.transform(basegfx::utils::createTranslateB2DHomMatrix(aPoint.X(), aPoint.Y()));
2179                         }
2180                         pEdgeObj->SetEdgeTrackPath( aNewPolyPolygon );
2181                         return true;
2182                     }
2183                 }
2184             }
2185         }
2186         break;
2187     }
2188     case OWN_ATTR_MEASURE_START_POS:
2189     case OWN_ATTR_MEASURE_END_POS:
2190     {
2191         SdrMeasureObj* pMeasureObj = dynamic_cast< SdrMeasureObj* >(pSdrObject.get());
2192         awt::Point aUnoPoint;
2193         if(pMeasureObj && ( rValue >>= aUnoPoint ) )
2194         {
2195             Point aPoint( aUnoPoint.X, aUnoPoint.Y );
2196 
2197             // Reintroduction of fix for issue #i59051# (#i108851#)
2198             ForceMetricToItemPoolMetric( aPoint );
2199             if( pSdrObject->getSdrModelFromSdrObject().IsWriter() )
2200                 aPoint += pSdrObject->GetAnchorPos();
2201 
2202             pMeasureObj->NbcSetPoint( aPoint, pProperty->nWID == OWN_ATTR_MEASURE_START_POS ? 0 : 1 );
2203             pMeasureObj->SetChanged();
2204             pMeasureObj->BroadcastObjectChange();
2205             return true;
2206         }
2207         break;
2208     }
2209     case OWN_ATTR_FILLBMP_MODE:
2210         {
2211             drawing::BitmapMode eMode;
2212             if(!(rValue >>= eMode) )
2213             {
2214                 sal_Int32 nMode = 0;
2215                 if(!(rValue >>= nMode))
2216                     break;
2217 
2218                 eMode = static_cast<drawing::BitmapMode>(nMode);
2219             }
2220             pSdrObject->SetMergedItem( XFillBmpStretchItem( eMode == drawing::BitmapMode_STRETCH ) );
2221             pSdrObject->SetMergedItem( XFillBmpTileItem( eMode == drawing::BitmapMode_REPEAT ) );
2222             return true;
2223         }
2224 
2225     case SDRATTR_LAYERID:
2226     {
2227         sal_Int16 nLayerId = sal_Int16();
2228         if( rValue >>= nLayerId )
2229         {
2230             SdrLayer* pLayer = pSdrObject->getSdrModelFromSdrObject().GetLayerAdmin().GetLayerPerID(SdrLayerID(nLayerId));
2231             if( pLayer )
2232             {
2233                 pSdrObject->SetLayer(SdrLayerID(nLayerId));
2234                 return true;
2235             }
2236         }
2237         break;
2238     }
2239 
2240     case SDRATTR_LAYERNAME:
2241     {
2242         OUString aLayerName;
2243         if( rValue >>= aLayerName )
2244         {
2245             const SdrLayer* pLayer = pSdrObject->getSdrModelFromSdrObject().GetLayerAdmin().GetLayer(aLayerName);
2246             if( pLayer != nullptr )
2247             {
2248                 pSdrObject->SetLayer( pLayer->GetID() );
2249                 return true;
2250             }
2251         }
2252         break;
2253     }
2254     case SDRATTR_ROTATEANGLE:
2255     {
2256         sal_Int32 nTmp = 0;
2257         if( rValue >>= nTmp )
2258         {
2259             Degree100 nAngle(nTmp);
2260             Point aRef1(pSdrObject->GetSnapRect().Center());
2261             nAngle -= pSdrObject->GetRotateAngle();
2262             if (nAngle)
2263             {
2264                 double nSin = sin(toRadians(nAngle));
2265                 double nCos = cos(toRadians(nAngle));
2266                 pSdrObject->Rotate(aRef1,nAngle,nSin,nCos);
2267             }
2268             return true;
2269         }
2270 
2271         break;
2272     }
2273 
2274     case SDRATTR_SHEARANGLE:
2275     {
2276         sal_Int32 nTmp = 0;
2277         if( rValue >>= nTmp )
2278         {
2279             Degree100 nShear(nTmp);
2280             nShear -= pSdrObject->GetShearAngle();
2281             if(nShear)
2282             {
2283                 Point aRef1(pSdrObject->GetSnapRect().Center());
2284                 double nTan = tan(toRadians(nShear));
2285                 pSdrObject->Shear(aRef1,nShear,nTan,false);
2286                 return true;
2287             }
2288         }
2289 
2290         break;
2291     }
2292 
2293     case OWN_ATTR_INTEROPGRABBAG:
2294     {
2295         pSdrObject->SetGrabBagItem(rValue);
2296         return true;
2297     }
2298 
2299     case SDRATTR_OBJMOVEPROTECT:
2300     {
2301         bool bMoveProtect;
2302         if( rValue >>= bMoveProtect )
2303         {
2304             pSdrObject->SetMoveProtect(bMoveProtect);
2305             return true;
2306         }
2307         break;
2308     }
2309     case SDRATTR_OBJECTNAME:
2310     {
2311         OUString aName;
2312         if( rValue >>= aName )
2313         {
2314             pSdrObject->SetName( aName );
2315             return true;
2316         }
2317         break;
2318     }
2319 
2320     case OWN_ATTR_TEXTFITTOSIZE_FONT_SCALE:
2321     {
2322         double fScale = 0.0;
2323         if (rValue >>= fScale)
2324         {
2325             SdrTextFitToSizeTypeItem aItem(pSdrObject->GetMergedItem(SDRATTR_TEXT_FITTOSIZE));
2326             aItem.setFontScale(fScale / 100.0);
2327             pSdrObject->SetMergedItem(aItem);
2328             return true;
2329         }
2330         break;
2331     }
2332 
2333     case OWN_ATTR_TEXTFITTOSIZE_SPACING_SCALE:
2334     {
2335         double fScale = 0.0;
2336         if (rValue >>= fScale)
2337         {
2338             SdrTextFitToSizeTypeItem aItem(pSdrObject->GetMergedItem(SDRATTR_TEXT_FITTOSIZE));
2339             aItem.setSpacingScale(fScale / 100.0);
2340             pSdrObject->SetMergedItem(aItem);
2341             return true;
2342         }
2343         break;
2344     }
2345 
2346     // #i68101#
2347     case OWN_ATTR_MISC_OBJ_TITLE:
2348     {
2349         OUString aTitle;
2350         if( rValue >>= aTitle )
2351         {
2352             pSdrObject->SetTitle( aTitle );
2353             return true;
2354         }
2355         break;
2356     }
2357     case OWN_ATTR_MISC_OBJ_DESCRIPTION:
2358     {
2359         OUString aDescription;
2360         if( rValue >>= aDescription )
2361         {
2362             pSdrObject->SetDescription( aDescription );
2363             return true;
2364         }
2365         break;
2366     }
2367     case OWN_ATTR_MISC_OBJ_DECORATIVE:
2368     {
2369         bool isDecorative;
2370         if (rValue >>= isDecorative)
2371         {
2372             pSdrObject->SetDecorative(isDecorative);
2373             return true;
2374         }
2375         break;
2376     }
2377 
2378     case SDRATTR_OBJPRINTABLE:
2379     {
2380         bool bPrintable;
2381         if( rValue >>= bPrintable )
2382         {
2383             pSdrObject->SetPrintable(bPrintable);
2384             return true;
2385         }
2386         break;
2387     }
2388     case SDRATTR_OBJVISIBLE:
2389     {
2390         bool bVisible;
2391         if( rValue >>= bVisible )
2392         {
2393             pSdrObject->SetVisible(bVisible);
2394             return true;
2395         }
2396         break;
2397     }
2398     case SDRATTR_OBJSIZEPROTECT:
2399     {
2400         bool bResizeProtect;
2401         if( rValue >>= bResizeProtect )
2402         {
2403             pSdrObject->SetResizeProtect(bResizeProtect);
2404             return true;
2405         }
2406         break;
2407     }
2408     case OWN_ATTR_PAGE_NUMBER:
2409     {
2410         sal_Int32 nPageNum = 0;
2411         if( (rValue >>= nPageNum) && ( nPageNum >= 0 ) && ( nPageNum <= 0xffff ) )
2412         {
2413             SdrPageObj* pPageObj = dynamic_cast< SdrPageObj* >(pSdrObject.get());
2414             if( pPageObj )
2415             {
2416                 SdrModel& rModel(pPageObj->getSdrModelFromSdrObject());
2417                 SdrPage* pNewPage = nullptr;
2418                 const sal_uInt16 nDestinationPageNum(static_cast<sal_uInt16>((nPageNum << 1) - 1));
2419 
2420                 if(nDestinationPageNum < rModel.GetPageCount())
2421                 {
2422                     pNewPage = rModel.GetPage(nDestinationPageNum);
2423                 }
2424 
2425                 pPageObj->SetReferencedPage(pNewPage);
2426             }
2427 
2428             return true;
2429         }
2430         break;
2431     }
2432     case XATTR_FILLBITMAP:
2433     case XATTR_FILLGRADIENT:
2434     case XATTR_FILLHATCH:
2435     case XATTR_FILLFLOATTRANSPARENCE:
2436     case XATTR_LINEEND:
2437     case XATTR_LINESTART:
2438     case XATTR_LINEDASH:
2439     {
2440         if( pProperty->nMemberId == MID_NAME )
2441         {
2442             OUString aApiName;
2443             if( rValue >>= aApiName )
2444             {
2445                 if( SetFillAttribute( pProperty->nWID, aApiName ) )
2446                     return true;
2447             }
2448             break;
2449         }
2450         else
2451         {
2452             return false;
2453         }
2454     }
2455 
2456     case OWN_ATTR_TEXTCOLUMNS:
2457     {
2458         if (auto pTextObj = DynCastSdrTextObj(pSdrObject.get()))
2459         {
2460             css::uno::Reference<css::text::XTextColumns> xTextColumns;
2461             if (rValue >>= xTextColumns)
2462             {
2463                 pTextObj->SetTextColumnsNumber(xTextColumns->getColumnCount());
2464                 if (css::uno::Reference<css::beans::XPropertySet> xPropSet{ xTextColumns,
2465                                                                             css::uno::UNO_QUERY })
2466                 {
2467                     auto aVal = xPropSet->getPropertyValue(u"AutomaticDistance"_ustr);
2468                     if (sal_Int32 nSpacing; aVal >>= nSpacing)
2469                         pTextObj->SetTextColumnsSpacing(nSpacing);
2470                 }
2471             }
2472         }
2473         return true;
2474     }
2475 
2476     case OWN_ATTR_HYPERLINK:
2477     {
2478         OUString sHyperlink;
2479         if (rValue >>= sHyperlink)
2480         {
2481             pSdrObject->setHyperlink(sHyperlink);
2482             return true;
2483         }
2484         break;
2485     }
2486 
2487     case SDRATTR_WRITINGMODE2:
2488     {
2489         SvxFrameDirectionItem aItem(SvxFrameDirection::Environment, SDRATTR_WRITINGMODE2);
2490         aItem.PutValue(rValue, 0);
2491         GetSdrObject()->SetMergedItem(aItem);
2492         return true;
2493         break;
2494     }
2495 
2496     default:
2497     {
2498         return false;
2499     }
2500     }
2501 
2502     OUString sExceptionMessage(
2503         "IllegalArgumentException in SvxShape::setPropertyValueImpl."
2504         " Property Type: "
2505         + pProperty->aType.getTypeName() + " Property Name: " + pProperty->aName
2506         + " Property nWID: " + OUString::number(pProperty->nWID)
2507         + " Value Type: " + (rValue.hasValue() ? rValue.getValueTypeName() : u"void (no value)"_ustr));
2508 
2509     throw lang::IllegalArgumentException(sExceptionMessage, nullptr, 1);
2510 }
2511 
2512 
getPropertyValueImpl(const OUString &,const SfxItemPropertyMapEntry * pProperty,css::uno::Any & rValue)2513 bool SvxShape::getPropertyValueImpl( const OUString&, const SfxItemPropertyMapEntry* pProperty, css::uno::Any& rValue )
2514 {
2515     switch( pProperty->nWID )
2516     {
2517     case OWN_ATTR_CAPTION_POINT:
2518     {
2519         Point aVclPoint = static_cast<SdrCaptionObj*>(GetSdrObject())->GetTailPos();
2520 
2521         // #88491# make pos relative to anchor
2522         if( GetSdrObject()->getSdrModelFromSdrObject().IsWriter() )
2523         {
2524             aVclPoint -= GetSdrObject()->GetAnchorPos();
2525         }
2526 
2527         // #90763# pos is absolute, make it relative to top left
2528         basegfx::B2DPolyPolygon aNewPolyPolygon;
2529         basegfx::B2DHomMatrix aNewHomogenMatrix;
2530         GetSdrObject()->TRGetBaseGeometry(aNewHomogenMatrix, aNewPolyPolygon);
2531 
2532         aVclPoint.AdjustX( -(basegfx::fround<tools::Long>(aNewHomogenMatrix.get(0, 2))) );
2533         aVclPoint.AdjustY( -(basegfx::fround<tools::Long>(aNewHomogenMatrix.get(1, 2))) );
2534 
2535         // tdf#117145 metric of SdrModel is app-specific, metric of UNO API is 100thmm
2536         // Need to adapt aVclPoint from app-specific to 100thmm
2537         ForceMetricTo100th_mm(aVclPoint);
2538 
2539         awt::Point aPnt( aVclPoint.X(), aVclPoint.Y() );
2540         rValue <<= aPnt;
2541         break;
2542     }
2543 
2544     case OWN_ATTR_TRANSFORMATION:
2545     {
2546         basegfx::B2DPolyPolygon aNewPolyPolygon;
2547         basegfx::B2DHomMatrix aNewHomogenMatrix;
2548         GetSdrObject()->TRGetBaseGeometry(aNewHomogenMatrix, aNewPolyPolygon);
2549         drawing::HomogenMatrix3 aMatrix;
2550 
2551         // tdf#117145 metric of SdrModel is app-specific, metric of UNO API is 100thmm
2552         // Need to adapt aNewHomogenMatrix from app-specific to 100thmm
2553         ForceMetricTo100th_mm(aNewHomogenMatrix);
2554 
2555         aMatrix.Line1.Column1 = aNewHomogenMatrix.get(0, 0);
2556         aMatrix.Line1.Column2 = aNewHomogenMatrix.get(0, 1);
2557         aMatrix.Line1.Column3 = aNewHomogenMatrix.get(0, 2);
2558         aMatrix.Line2.Column1 = aNewHomogenMatrix.get(1, 0);
2559         aMatrix.Line2.Column2 = aNewHomogenMatrix.get(1, 1);
2560         aMatrix.Line2.Column3 = aNewHomogenMatrix.get(1, 2);
2561         aMatrix.Line3.Column1 = 0;
2562         aMatrix.Line3.Column2 = 0;
2563         aMatrix.Line3.Column3 = 1;
2564 
2565         rValue <<= aMatrix;
2566 
2567         break;
2568     }
2569 
2570     case OWN_ATTR_ZORDER:
2571     {
2572         rValue <<= static_cast<sal_Int32>(GetSdrObject()->GetOrdNum());
2573         break;
2574     }
2575 
2576     case OWN_ATTR_BITMAP:
2577     {
2578         rValue = GetBitmap();
2579         if(!rValue.hasValue())
2580             throw uno::RuntimeException();
2581 
2582         break;
2583     }
2584 
2585     case OWN_ATTR_ISFONTWORK:
2586     {
2587         bool bIsFontwork = false;
2588         if (const SdrTextObj* pTextObj = DynCastSdrTextObj(GetSdrObject()))
2589             bIsFontwork = pTextObj->IsFontwork();
2590         rValue <<= bIsFontwork;
2591         break;
2592     }
2593 
2594     case OWN_ATTR_FRAMERECT:
2595     {
2596         tools::Rectangle aRect( GetSdrObject()->GetSnapRect() );
2597         Point aTopLeft( aRect.TopLeft() );
2598         Size aObjSize( aRect.GetWidth(), aRect.GetHeight() );
2599         ForceMetricTo100th_mm(aTopLeft);
2600         ForceMetricTo100th_mm(aObjSize);
2601         css::awt::Rectangle aUnoRect(
2602             aTopLeft.X(), aTopLeft.Y(),
2603             aObjSize.getWidth(), aObjSize.getHeight() );
2604         rValue <<= aUnoRect;
2605         break;
2606     }
2607 
2608     case OWN_ATTR_BOUNDRECT:
2609     {
2610         tools::Rectangle aRect( GetSdrObject()->GetCurrentBoundRect() );
2611         Point aTopLeft( aRect.TopLeft() );
2612         Size aObjSize( aRect.GetWidth(), aRect.GetHeight() );
2613         ForceMetricTo100th_mm(aTopLeft);
2614         ForceMetricTo100th_mm(aObjSize);
2615         css::awt::Rectangle aUnoRect(
2616             aTopLeft.X(), aTopLeft.Y(),
2617             aObjSize.getWidth(), aObjSize.getHeight() );
2618         rValue <<= aUnoRect;
2619         break;
2620     }
2621 
2622     case OWN_ATTR_LDNAME:
2623     {
2624         OUString aName( GetSdrObject()->GetName() );
2625         rValue <<= aName;
2626         break;
2627     }
2628 
2629     case OWN_ATTR_LDBITMAP:
2630     {
2631         OUString sId;
2632         if( GetSdrObject()->GetObjInventor() == SdrInventor::Default && GetSdrObject()->GetObjIdentifier() == SdrObjKind::OLE2 )
2633         {
2634             sId = RID_UNODRAW_OLE2;
2635         }
2636         else if( GetSdrObject()->GetObjInventor() == SdrInventor::Default && GetSdrObject()->GetObjIdentifier() == SdrObjKind::Graphic )
2637         {
2638             sId = RID_UNODRAW_GRAPHICS;
2639         }
2640         else
2641         {
2642             sId = RID_UNODRAW_OBJECTS;
2643         }
2644 
2645         BitmapEx aBmp(sId);
2646         Reference<awt::XBitmap> xBmp(VCLUnoHelper::CreateBitmap(aBmp));
2647 
2648         rValue <<= xBmp;
2649         break;
2650     }
2651 
2652     case OWN_ATTR_MIRRORED:
2653     {
2654         bool bMirror = false;
2655         if( HasSdrObject() )
2656             if (auto pGrafObj = dynamic_cast<SdrGrafObj*>(GetSdrObject()) )
2657                 bMirror = pGrafObj->IsMirrored();
2658 
2659         rValue <<= bMirror;
2660         break;
2661     }
2662 
2663     case OWN_ATTR_EDGE_START_OBJ:
2664     case OWN_ATTR_EDGE_START_POS:
2665     case OWN_ATTR_EDGE_END_POS:
2666     case OWN_ATTR_EDGE_END_OBJ:
2667     case OWN_ATTR_GLUEID_HEAD:
2668     case OWN_ATTR_GLUEID_TAIL:
2669     case OWN_ATTR_EDGE_POLYPOLYGONBEZIER:
2670     {
2671         SdrEdgeObj* pEdgeObj = dynamic_cast<SdrEdgeObj*>(GetSdrObject());
2672         if(pEdgeObj)
2673         {
2674             switch(pProperty->nWID)
2675             {
2676             case OWN_ATTR_EDGE_START_OBJ:
2677             case OWN_ATTR_EDGE_END_OBJ:
2678                 {
2679                     SdrObject* pNode = pEdgeObj->GetConnectedNode(pProperty->nWID == OWN_ATTR_EDGE_START_OBJ);
2680                     if(pNode)
2681                     {
2682                         Reference< drawing::XShape > xShape( GetXShapeForSdrObject( pNode ) );
2683                         if(xShape.is())
2684                             rValue <<= xShape;
2685 
2686                     }
2687                     break;
2688                 }
2689 
2690             case OWN_ATTR_EDGE_START_POS:
2691             case OWN_ATTR_EDGE_END_POS:
2692                 {
2693                     Point aPoint( pEdgeObj->GetTailPoint( pProperty->nWID == OWN_ATTR_EDGE_START_POS ) );
2694                     if( GetSdrObject()->getSdrModelFromSdrObject().IsWriter() )
2695                         aPoint -= GetSdrObject()->GetAnchorPos();
2696 
2697                     ForceMetricTo100th_mm( aPoint );
2698                     awt::Point aUnoPoint( aPoint.X(), aPoint.Y() );
2699 
2700                     rValue <<= aUnoPoint;
2701                     break;
2702                 }
2703             case OWN_ATTR_GLUEID_HEAD:
2704             case OWN_ATTR_GLUEID_TAIL:
2705                 {
2706                     rValue <<= pEdgeObj->getGluePointIndex( pProperty->nWID == OWN_ATTR_GLUEID_HEAD );
2707                     break;
2708                 }
2709             case OWN_ATTR_EDGE_POLYPOLYGONBEZIER:
2710                 {
2711                     basegfx::B2DPolyPolygon aPolyPoly( pEdgeObj->GetEdgeTrackPath() );
2712                     if( GetSdrObject()->getSdrModelFromSdrObject().IsWriter() )
2713                     {
2714                         Point aPoint( GetSdrObject()->GetAnchorPos() );
2715                         aPolyPoly.transform(basegfx::utils::createTranslateB2DHomMatrix(-aPoint.X(), -aPoint.Y()));
2716                     }
2717                     // Reintroduction of fix for issue #i59051# (#i108851#)
2718                     ForceMetricTo100th_mm( aPolyPoly );
2719                     drawing::PolyPolygonBezierCoords aRetval;
2720                     basegfx::utils::B2DPolyPolygonToUnoPolyPolygonBezierCoords( aPolyPoly, aRetval);
2721                     rValue <<= aRetval;
2722                     break;
2723                 }
2724             }
2725         }
2726         break;
2727     }
2728 
2729     case OWN_ATTR_MEASURE_START_POS:
2730     case OWN_ATTR_MEASURE_END_POS:
2731     {
2732         SdrMeasureObj* pMeasureObj = dynamic_cast<SdrMeasureObj*>(GetSdrObject());
2733         if(pMeasureObj)
2734         {
2735             Point aPoint( pMeasureObj->GetPoint( pProperty->nWID == OWN_ATTR_MEASURE_START_POS ? 0 : 1 ) );
2736             if( GetSdrObject()->getSdrModelFromSdrObject().IsWriter() )
2737                 aPoint -= GetSdrObject()->GetAnchorPos();
2738 
2739             // Reintroduction of fix for issue #i59051# (#i108851#)
2740             ForceMetricTo100th_mm( aPoint );
2741             awt::Point aUnoPoint( aPoint.X(), aPoint.Y() );
2742 
2743             rValue <<= aUnoPoint;
2744             break;
2745         }
2746         break;
2747     }
2748 
2749     case OWN_ATTR_FILLBMP_MODE:
2750     {
2751         const SfxItemSet& rObjItemSet = GetSdrObject()->GetMergedItemSet();
2752 
2753         if (rObjItemSet.Get(XATTR_FILLBMP_TILE).GetValue())
2754         {
2755             rValue <<= drawing::BitmapMode_REPEAT;
2756         }
2757         else if (rObjItemSet.Get(XATTR_FILLBMP_STRETCH).GetValue())
2758         {
2759             rValue <<= drawing::BitmapMode_STRETCH;
2760         }
2761         else
2762         {
2763             rValue <<= drawing::BitmapMode_NO_REPEAT;
2764         }
2765         break;
2766     }
2767     case SDRATTR_LAYERID:
2768         rValue <<= GetSdrObject()->GetLayer().get();
2769         break;
2770 
2771     case SDRATTR_LAYERNAME:
2772     {
2773         SdrLayer* pLayer = GetSdrObject()->getSdrModelFromSdrObject().GetLayerAdmin().GetLayerPerID(GetSdrObject()->GetLayer());
2774         if( pLayer )
2775         {
2776             rValue <<= pLayer->GetName();
2777         }
2778         break;
2779     }
2780 
2781     case SDRATTR_ROTATEANGLE:
2782         rValue <<= static_cast<sal_Int32>(GetSdrObject()->GetRotateAngle());
2783         break;
2784 
2785     case SDRATTR_SHEARANGLE:
2786         rValue <<= static_cast<sal_Int32>(GetSdrObject()->GetShearAngle());
2787         break;
2788 
2789     case OWN_ATTR_INTEROPGRABBAG:
2790     {
2791         GetSdrObject()->GetGrabBagItem(rValue);
2792         break;
2793     }
2794 
2795     case SDRATTR_OBJMOVEPROTECT:
2796         rValue <<= GetSdrObject()->IsMoveProtect();
2797         break;
2798 
2799     case SDRATTR_OBJECTNAME:
2800     {
2801         OUString aName( GetSdrObject()->GetName() );
2802         rValue <<= aName;
2803         break;
2804     }
2805 
2806     // #i68101#
2807     case OWN_ATTR_MISC_OBJ_TITLE:
2808     {
2809         OUString aTitle( GetSdrObject()->GetTitle() );
2810         rValue <<= aTitle;
2811         break;
2812     }
2813 
2814     case OWN_ATTR_MISC_OBJ_DESCRIPTION:
2815     {
2816         OUString aDescription( GetSdrObject()->GetDescription() );
2817         rValue <<= aDescription;
2818         break;
2819     }
2820 
2821     case OWN_ATTR_MISC_OBJ_DECORATIVE:
2822     {
2823         bool const isDecorative(GetSdrObject()->IsDecorative());
2824         rValue <<= isDecorative;
2825         break;
2826     }
2827 
2828     case SDRATTR_OBJPRINTABLE:
2829         rValue <<= GetSdrObject()->IsPrintable();
2830         break;
2831 
2832     case SDRATTR_OBJVISIBLE:
2833         rValue <<= GetSdrObject()->IsVisible();
2834         break;
2835 
2836     case SDRATTR_OBJSIZEPROTECT:
2837         rValue <<= GetSdrObject()->IsResizeProtect();
2838         break;
2839 
2840     case OWN_ATTR_PAGE_NUMBER:
2841     {
2842         SdrPageObj* pPageObj = dynamic_cast<SdrPageObj*>(GetSdrObject());
2843         if(pPageObj)
2844         {
2845             SdrPage* pPage = pPageObj->GetReferencedPage();
2846             sal_Int32 nPageNumber = pPage ? pPage->GetPageNum() : 0;
2847             nPageNumber++;
2848             nPageNumber >>= 1;
2849             rValue <<= nPageNumber;
2850         }
2851         break;
2852     }
2853 
2854     case OWN_ATTR_UINAME_SINGULAR:
2855     {
2856         rValue <<= GetSdrObject()->TakeObjNameSingul();
2857         break;
2858     }
2859 
2860     case OWN_ATTR_TEXTFITTOSIZE_FONT_SCALE:
2861     {
2862         auto* pTextObject = getTextObjectWithFitToSize(GetSdrObject());
2863         if (pTextObject)
2864         {
2865             rValue <<= pTextObject->GetFontScale() * 100.0;
2866         }
2867         break;
2868     }
2869 
2870     case OWN_ATTR_TEXTFITTOSIZE_SPACING_SCALE:
2871     {
2872         auto* pTextObject = getTextObjectWithFitToSize(GetSdrObject());
2873         if (pTextObject)
2874         {
2875             rValue <<= pTextObject->GetSpacingScale() * 100.0;
2876         }
2877         break;
2878     }
2879 
2880     case OWN_ATTR_UINAME_PLURAL:
2881     {
2882         rValue <<= GetSdrObject()->TakeObjNamePlural();
2883         break;
2884     }
2885     case OWN_ATTR_METAFILE:
2886     {
2887         SdrOle2Obj* pObj = dynamic_cast<SdrOle2Obj*>(GetSdrObject());
2888         if( pObj )
2889         {
2890             const Graphic* pGraphic = pObj->GetGraphic();
2891             if( pGraphic )
2892             {
2893                 bool bIsWMF = false;
2894                 if ( pGraphic->IsGfxLink() )
2895                 {
2896                     GfxLink aLnk = pGraphic->GetGfxLink();
2897                     if ( aLnk.GetType() == GfxLinkType::NativeWmf )
2898                     {
2899                         bIsWMF = true;
2900                         uno::Sequence<sal_Int8> aSeq(reinterpret_cast<sal_Int8 const *>(aLnk.GetData()), static_cast<sal_Int32>(aLnk.GetDataSize()));
2901                         rValue <<= aSeq;
2902                     }
2903                 }
2904                 if ( !bIsWMF )
2905                 {
2906                     // #119735# just use GetGDIMetaFile, it will create a buffered version of contained bitmap now automatically
2907                     GDIMetaFile aMtf(pObj->GetGraphic()->GetGDIMetaFile());
2908                     SvMemoryStream aDestStrm( 65535, 65535 );
2909                     ConvertGDIMetaFileToWMF( aMtf, aDestStrm, nullptr, false );
2910                     const uno::Sequence<sal_Int8> aSeq(
2911                         static_cast< const sal_Int8* >(aDestStrm.GetData()),
2912                         aDestStrm.GetEndOfData());
2913                     rValue <<= aSeq;
2914                 }
2915             }
2916         }
2917         else
2918         {
2919             rValue = GetBitmap( true );
2920         }
2921         break;
2922     }
2923 
2924     case OWN_ATTR_TEXTCOLUMNS:
2925     {
2926         if (auto pTextObj = DynCastSdrTextObj(GetSdrObject()))
2927         {
2928             if (pTextObj->HasTextColumnsNumber() || pTextObj->HasTextColumnsSpacing())
2929             {
2930                 auto xIf = SvxXTextColumns_createInstance();
2931                 css::uno::Reference<css::text::XTextColumns> xCols(xIf, css::uno::UNO_QUERY_THROW);
2932                 xCols->setColumnCount(pTextObj->GetTextColumnsNumber());
2933                 css::uno::Reference<css::beans::XPropertySet> xProp(xIf, css::uno::UNO_QUERY_THROW);
2934                 xProp->setPropertyValue(u"AutomaticDistance"_ustr,
2935                                         css::uno::Any(pTextObj->GetTextColumnsSpacing()));
2936                 rValue <<= xIf;
2937             }
2938         }
2939         break;
2940     }
2941 
2942     case OWN_ATTR_HYPERLINK:
2943     {
2944         rValue <<= GetSdrObject()->getHyperlink();
2945         break;
2946     }
2947 
2948     default:
2949         return false;
2950     }
2951     return true;
2952 }
2953 
2954 
getPropertyStateImpl(const SfxItemPropertyMapEntry * pProperty,css::beans::PropertyState & rState)2955 bool SvxShape::getPropertyStateImpl( const SfxItemPropertyMapEntry* pProperty, css::beans::PropertyState& rState )
2956 {
2957     if( pProperty->nWID == OWN_ATTR_FILLBMP_MODE )
2958     {
2959         const SfxItemSet& rSet = GetSdrObject()->GetMergedItemSet();
2960 
2961         if( rSet.GetItemState( XATTR_FILLBMP_STRETCH, false ) == SfxItemState::SET ||
2962             rSet.GetItemState( XATTR_FILLBMP_TILE, false ) == SfxItemState::SET )
2963         {
2964             rState = beans::PropertyState_DIRECT_VALUE;
2965         }
2966         else
2967         {
2968             rState = beans::PropertyState_AMBIGUOUS_VALUE;
2969         }
2970     }
2971     else if((( pProperty->nWID >= OWN_ATTR_VALUE_START && pProperty->nWID <= OWN_ATTR_VALUE_END ) ||
2972        ( pProperty->nWID >= SDRATTR_NOTPERSIST_FIRST && pProperty->nWID <= SDRATTR_NOTPERSIST_LAST )) && ( pProperty->nWID != SDRATTR_TEXTDIRECTION ) )
2973     {
2974         rState = beans::PropertyState_DIRECT_VALUE;
2975     }
2976     else
2977     {
2978         return false;
2979     }
2980 
2981     return true;
2982 }
2983 
2984 
setPropertyToDefaultImpl(const SfxItemPropertyMapEntry * pProperty)2985 bool SvxShape::setPropertyToDefaultImpl( const SfxItemPropertyMapEntry* pProperty )
2986 {
2987     if( pProperty->nWID == OWN_ATTR_FILLBMP_MODE )
2988     {
2989         GetSdrObject()->ClearMergedItem( XATTR_FILLBMP_STRETCH );
2990         GetSdrObject()->ClearMergedItem( XATTR_FILLBMP_TILE );
2991         return true;
2992     }
2993     else if((pProperty->nWID >= OWN_ATTR_VALUE_START && pProperty->nWID <= OWN_ATTR_VALUE_END ) ||
2994        ( pProperty->nWID >= SDRATTR_NOTPERSIST_FIRST && pProperty->nWID <= SDRATTR_NOTPERSIST_LAST ))
2995     {
2996         return true;
2997     }
2998     else
2999     {
3000         return false;
3001     }
3002 }
3003 
3004 
getPropertyStates(const uno::Sequence<OUString> & aPropertyName)3005 uno::Sequence< beans::PropertyState > SAL_CALL SvxShape::getPropertyStates( const uno::Sequence< OUString >& aPropertyName )
3006 {
3007     const sal_Int32 nCount = aPropertyName.getLength();
3008     uno::Sequence< beans::PropertyState > aRet( nCount );
3009 
3010     std::transform(aPropertyName.begin(), aPropertyName.end(), aRet.getArray(),
3011         [this](const OUString& rName) -> beans::PropertyState { return getPropertyState(rName); });
3012 
3013     return aRet;
3014 }
3015 
3016 
setPropertyToDefault(const OUString & PropertyName)3017 void SAL_CALL SvxShape::setPropertyToDefault( const OUString& PropertyName )
3018 {
3019     if( mpImpl->mpMaster )
3020     {
3021         mpImpl->mpMaster->setPropertyToDefault( PropertyName );
3022     }
3023     else
3024     {
3025         _setPropertyToDefault( PropertyName );
3026     }
3027 }
3028 
_setPropertyToDefault(const OUString & PropertyName)3029 void SvxShape::_setPropertyToDefault( const OUString& PropertyName )
3030 {
3031     ::SolarMutexGuard aGuard;
3032 
3033     const SfxItemPropertyMapEntry* pProperty = mpPropSet->getPropertyMapEntry(PropertyName);
3034 
3035     if( !HasSdrObject() || pProperty == nullptr )
3036         throw beans::UnknownPropertyException( PropertyName, getXWeak());
3037 
3038     if( !setPropertyToDefaultImpl( pProperty ) )
3039     {
3040         GetSdrObject()->ClearMergedItem( pProperty->nWID );
3041     }
3042 
3043     GetSdrObject()->getSdrModelFromSdrObject().SetChanged();
3044 }
3045 
3046 
getPropertyDefault(const OUString & aPropertyName)3047 uno::Any SAL_CALL SvxShape::getPropertyDefault( const OUString& aPropertyName )
3048 {
3049     if( mpImpl->mpMaster )
3050     {
3051         return mpImpl->mpMaster->getPropertyDefault( aPropertyName );
3052     }
3053     else
3054     {
3055         return _getPropertyDefault( aPropertyName );
3056     }
3057 }
3058 
_getPropertyDefault(const OUString & aPropertyName)3059 uno::Any SvxShape::_getPropertyDefault( const OUString& aPropertyName )
3060 {
3061     ::SolarMutexGuard aGuard;
3062 
3063     const SfxItemPropertyMapEntry* pMap = mpPropSet->getPropertyMapEntry(aPropertyName);
3064 
3065     if( !HasSdrObject() || pMap == nullptr )
3066         throw beans::UnknownPropertyException( aPropertyName, getXWeak());
3067 
3068     if(( pMap->nWID >= OWN_ATTR_VALUE_START && pMap->nWID <= OWN_ATTR_VALUE_END ) ||
3069        ( pMap->nWID >= SDRATTR_NOTPERSIST_FIRST && pMap->nWID <= SDRATTR_NOTPERSIST_LAST ))
3070     {
3071         return getPropertyValue( aPropertyName );
3072     }
3073 
3074     // get default from ItemPool
3075     if(!SfxItemPool::IsWhich(pMap->nWID))
3076         throw beans::UnknownPropertyException( "No WhichID " + OUString::number(pMap->nWID) + " for " + aPropertyName, getXWeak());
3077 
3078     SfxItemSet aSet( GetSdrObject()->getSdrModelFromSdrObject().GetItemPool(), pMap->nWID, pMap->nWID );
3079     aSet.Put(GetSdrObject()->getSdrModelFromSdrObject().GetItemPool().GetUserOrPoolDefaultItem(pMap->nWID));
3080 
3081     return GetAnyForItem( aSet, pMap );
3082 }
3083 
3084 // XMultiPropertyStates
setAllPropertiesToDefault()3085 void SvxShape::setAllPropertiesToDefault()
3086 {
3087     ::SolarMutexGuard aGuard;
3088 
3089     SdrObject* pSdrObj = GetSdrObject();
3090     if( !pSdrObj )
3091         throw lang::DisposedException();
3092     pSdrObj->ClearMergedItem(); // nWhich == 0 => all
3093 
3094     const SdrObjKind nObjId = pSdrObj->GetObjIdentifier();
3095     if(nObjId == SdrObjKind::Graphic) // SdrGrafObj
3096     {
3097         // defaults for graphic objects have changed:
3098         pSdrObj->SetMergedItem( XFillStyleItem( drawing::FillStyle_NONE ) );
3099         pSdrObj->SetMergedItem( XLineStyleItem( drawing::LineStyle_NONE ) );
3100     }
3101 
3102     // #i68523# special handling for Svx3DCharacterModeItem, this is not saved
3103     // but needs to be sal_True in svx, pool default (false) in sch. Since sch
3104     // does not load lathe or extrude objects, it is possible to set the items
3105     // here.
3106     // For other solution possibilities, see task description.
3107     if( nObjId == SdrObjKind::E3D_Lathe /*E3dLatheObj*/ || nObjId == SdrObjKind::E3D_Extrusion /*E3dExtrudeObj*/ )
3108     {
3109         pSdrObj->SetMergedItem(Svx3DCharacterModeItem(true));
3110     }
3111 
3112     pSdrObj->getSdrModelFromSdrObject().SetChanged();
3113 }
3114 
setPropertiesToDefault(const uno::Sequence<OUString> & aPropertyNames)3115 void SvxShape::setPropertiesToDefault(
3116     const uno::Sequence<OUString>& aPropertyNames )
3117 {
3118     for ( const auto& rPropertyName : aPropertyNames )
3119         setPropertyToDefault( rPropertyName );
3120 }
3121 
getPropertyDefaults(const uno::Sequence<OUString> & aPropertyNames)3122 uno::Sequence<uno::Any> SvxShape::getPropertyDefaults(
3123     const uno::Sequence<OUString>& aPropertyNames )
3124 {
3125     ::std::vector<uno::Any> ret;
3126     ret.reserve(aPropertyNames.getLength());
3127     std::transform(aPropertyNames.begin(), aPropertyNames.end(), std::back_inserter(ret),
3128         [this](const OUString& rName) -> uno::Any { return getPropertyDefault(rName); });
3129     return uno::Sequence<uno::Any>( ret.data(), ret.size() );
3130 }
3131 
3132 
3133 // XServiceInfo
3134 
getImplementationName()3135 OUString SAL_CALL SvxShape::getImplementationName()
3136 {
3137     return u"SvxShape"_ustr;
3138 }
3139 
3140 constexpr OUString sUNO_service_style_ParagraphProperties = u"com.sun.star.style.ParagraphProperties"_ustr;
3141 constexpr OUString sUNO_service_style_ParagraphPropertiesComplex = u"com.sun.star.style.ParagraphPropertiesComplex"_ustr;
3142 constexpr OUString sUNO_service_style_ParagraphPropertiesAsian = u"com.sun.star.style.ParagraphPropertiesAsian"_ustr;
3143 constexpr OUString sUNO_service_style_CharacterProperties = u"com.sun.star.style.CharacterProperties"_ustr;
3144 constexpr OUString sUNO_service_style_CharacterPropertiesComplex = u"com.sun.star.style.CharacterPropertiesComplex"_ustr;
3145 constexpr OUString sUNO_service_style_CharacterPropertiesAsian = u"com.sun.star.style.CharacterPropertiesAsian"_ustr;
3146 
3147 constexpr OUString sUNO_service_drawing_FillProperties    = u"com.sun.star.drawing.FillProperties"_ustr;
3148 constexpr OUString sUNO_service_drawing_TextProperties    = u"com.sun.star.drawing.TextProperties"_ustr;
3149 constexpr OUString sUNO_service_drawing_LineProperties    = u"com.sun.star.drawing.LineProperties"_ustr;
3150 constexpr OUString sUNO_service_drawing_ConnectorProperties = u"com.sun.star.drawing.ConnectorProperties"_ustr;
3151 constexpr OUString sUNO_service_drawing_MeasureProperties = u"com.sun.star.drawing.MeasureProperties"_ustr;
3152 constexpr OUString sUNO_service_drawing_ShadowProperties  = u"com.sun.star.drawing.ShadowProperties"_ustr;
3153 
3154 constexpr OUString sUNO_service_drawing_RotationDescriptor = u"com.sun.star.drawing.RotationDescriptor"_ustr;
3155 
3156 constexpr OUString sUNO_service_drawing_Text              = u"com.sun.star.drawing.Text"_ustr;
3157 constexpr OUString sUNO_service_drawing_GroupShape        = u"com.sun.star.drawing.GroupShape"_ustr;
3158 
3159 constexpr OUString sUNO_service_drawing_CustomShapeProperties = u"com.sun.star.drawing.CustomShapeProperties"_ustr;
3160 constexpr OUString sUNO_service_drawing_CustomShape       = u"com.sun.star.drawing.CustomShape"_ustr;
3161 
3162 constexpr OUString sUNO_service_drawing_PolyPolygonDescriptor = u"com.sun.star.drawing.PolyPolygonDescriptor"_ustr;
3163 constexpr OUString sUNO_service_drawing_PolyPolygonBezierDescriptor= u"com.sun.star.drawing.PolyPolygonBezierDescriptor"_ustr;
3164 
3165 constexpr OUString sUNO_service_drawing_LineShape         = u"com.sun.star.drawing.LineShape"_ustr;
3166 constexpr OUString sUNO_service_drawing_Shape             = u"com.sun.star.drawing.Shape"_ustr;
3167 constexpr OUString sUNO_service_drawing_RectangleShape    = u"com.sun.star.drawing.RectangleShape"_ustr;
3168 constexpr OUString sUNO_service_drawing_EllipseShape      = u"com.sun.star.drawing.EllipseShape"_ustr;
3169 constexpr OUString sUNO_service_drawing_PolyPolygonShape  = u"com.sun.star.drawing.PolyPolygonShape"_ustr;
3170 constexpr OUString sUNO_service_drawing_PolyLineShape     = u"com.sun.star.drawing.PolyLineShape"_ustr;
3171 constexpr OUString sUNO_service_drawing_OpenBezierShape   = u"com.sun.star.drawing.OpenBezierShape"_ustr;
3172 constexpr OUString sUNO_service_drawing_ClosedBezierShape = u"com.sun.star.drawing.ClosedBezierShape"_ustr;
3173 constexpr OUString sUNO_service_drawing_TextShape         = u"com.sun.star.drawing.TextShape"_ustr;
3174 constexpr OUString sUNO_service_drawing_AnnotationShape   = u"com.sun.star.drawing.AnnotationShape"_ustr;
3175 constexpr OUString sUNO_service_drawing_GraphicObjectShape = u"com.sun.star.drawing.GraphicObjectShape"_ustr;
3176 constexpr OUString sUNO_service_drawing_OLE2Shape         = u"com.sun.star.drawing.OLE2Shape"_ustr;
3177 constexpr OUString sUNO_service_drawing_PageShape         = u"com.sun.star.drawing.PageShape"_ustr;
3178 constexpr OUString sUNO_service_drawing_CaptionShape      = u"com.sun.star.drawing.CaptionShape"_ustr;
3179 constexpr OUString sUNO_service_drawing_MeasureShape      = u"com.sun.star.drawing.MeasureShape"_ustr;
3180 constexpr OUString sUNO_service_drawing_FrameShape        = u"com.sun.star.drawing.FrameShape"_ustr;
3181 constexpr OUString sUNO_service_drawing_ControlShape      = u"com.sun.star.drawing.ControlShape"_ustr;
3182 constexpr OUString sUNO_service_drawing_ConnectorShape    = u"com.sun.star.drawing.ConnectorShape"_ustr;
3183 constexpr OUString sUNO_service_drawing_MediaShape        = u"com.sun.star.drawing.MediaShape"_ustr;
3184 
3185 
getSupportedServiceNames()3186 uno::Sequence< OUString > SAL_CALL SvxShape::getSupportedServiceNames()
3187 {
3188     if( mpImpl->mpMaster )
3189     {
3190         return mpImpl->mpMaster->getSupportedServiceNames();
3191     }
3192     else
3193     {
3194         return _getSupportedServiceNames();
3195     }
3196 }
3197 
_getSupportedServiceNames()3198 uno::Sequence< OUString > SvxShape::_getSupportedServiceNames()
3199 {
3200     ::SolarMutexGuard aGuard;
3201 
3202     if( HasSdrObject() && GetSdrObject()->GetObjInventor() == SdrInventor::Default)
3203     {
3204         const SdrObjKind nIdent = GetSdrObject()->GetObjIdentifier();
3205 
3206         switch(nIdent)
3207         {
3208         case SdrObjKind::Group:
3209             {
3210                 static const uno::Sequence<OUString> aSvxShape_GroupServices
3211                         = { sUNO_service_drawing_GroupShape,
3212                             sUNO_service_drawing_Shape };
3213                 return aSvxShape_GroupServices;
3214             }
3215         case SdrObjKind::CustomShape:
3216             {
3217                 static const uno::Sequence<OUString> aSvxShape_CustomShapeServices
3218                         = { sUNO_service_drawing_CustomShape,
3219                             sUNO_service_drawing_Shape,
3220                             sUNO_service_drawing_CustomShapeProperties,
3221                             sUNO_service_drawing_FillProperties,
3222                             sUNO_service_drawing_LineProperties,
3223                             sUNO_service_drawing_Text,
3224                             sUNO_service_drawing_TextProperties,
3225                             sUNO_service_style_ParagraphProperties,
3226                             sUNO_service_style_ParagraphPropertiesComplex,
3227                             sUNO_service_style_ParagraphPropertiesAsian,
3228                             sUNO_service_style_CharacterProperties,
3229                             sUNO_service_style_CharacterPropertiesComplex,
3230                             sUNO_service_style_CharacterPropertiesAsian,
3231                             sUNO_service_drawing_ShadowProperties,
3232                             sUNO_service_drawing_RotationDescriptor };
3233                 return aSvxShape_CustomShapeServices;
3234             }
3235         case SdrObjKind::Line:
3236             {
3237                 static const uno::Sequence<OUString> aSvxShape_LineServices
3238                         = { sUNO_service_drawing_LineShape,
3239 
3240                             sUNO_service_drawing_Shape,
3241                             sUNO_service_drawing_LineProperties,
3242 
3243                             sUNO_service_drawing_Text,
3244                             sUNO_service_drawing_TextProperties,
3245                             sUNO_service_style_ParagraphProperties,
3246                             sUNO_service_style_ParagraphPropertiesComplex,
3247                             sUNO_service_style_ParagraphPropertiesAsian,
3248                             sUNO_service_style_CharacterProperties,
3249                             sUNO_service_style_CharacterPropertiesComplex,
3250                             sUNO_service_style_CharacterPropertiesAsian,
3251 
3252                             sUNO_service_drawing_PolyPolygonDescriptor,
3253                             sUNO_service_drawing_ShadowProperties,
3254                             sUNO_service_drawing_RotationDescriptor };
3255                 return aSvxShape_LineServices;
3256             }
3257 
3258         case SdrObjKind::Rectangle:
3259             {
3260                 static const uno::Sequence<OUString> aSvxShape_RectServices
3261                         = { sUNO_service_drawing_RectangleShape,
3262 
3263                             sUNO_service_drawing_Shape,
3264                             sUNO_service_drawing_FillProperties,
3265                             sUNO_service_drawing_LineProperties,
3266                             sUNO_service_drawing_Text,
3267                             sUNO_service_drawing_TextProperties,
3268                             sUNO_service_style_ParagraphProperties,
3269                             sUNO_service_style_ParagraphPropertiesComplex,
3270                             sUNO_service_style_ParagraphPropertiesAsian,
3271                             sUNO_service_style_CharacterProperties,
3272                             sUNO_service_style_CharacterPropertiesComplex,
3273                             sUNO_service_style_CharacterPropertiesAsian,
3274 
3275                             sUNO_service_drawing_ShadowProperties,
3276                             sUNO_service_drawing_RotationDescriptor };
3277                 return aSvxShape_RectServices;
3278             }
3279 
3280         case SdrObjKind::CircleOrEllipse:
3281         case SdrObjKind::CircleSection:
3282         case SdrObjKind::CircleArc:
3283         case SdrObjKind::CircleCut:
3284             {
3285                 static const uno::Sequence<OUString> aSvxShape_CircServices
3286                         = { sUNO_service_drawing_EllipseShape,
3287 
3288                             sUNO_service_drawing_Shape,
3289                             sUNO_service_drawing_FillProperties,
3290                             sUNO_service_drawing_LineProperties,
3291 
3292                             sUNO_service_drawing_Text,
3293                             sUNO_service_drawing_TextProperties,
3294                             sUNO_service_style_ParagraphProperties,
3295                             sUNO_service_style_ParagraphPropertiesComplex,
3296                             sUNO_service_style_ParagraphPropertiesAsian,
3297                             sUNO_service_style_CharacterProperties,
3298                             sUNO_service_style_CharacterPropertiesComplex,
3299                             sUNO_service_style_CharacterPropertiesAsian,
3300 
3301                             sUNO_service_drawing_ShadowProperties,
3302                             sUNO_service_drawing_RotationDescriptor };
3303                 return aSvxShape_CircServices;
3304             }
3305 
3306         case SdrObjKind::PathPolyLine:
3307         case SdrObjKind::PolyLine:
3308             {
3309                 static const uno::Sequence<OUString> aSvxShape_PathServices
3310                         = { sUNO_service_drawing_PolyLineShape,
3311 
3312                             sUNO_service_drawing_Shape,
3313                             sUNO_service_drawing_LineProperties,
3314 
3315                             sUNO_service_drawing_PolyPolygonDescriptor,
3316 
3317                             sUNO_service_drawing_Text,
3318                             sUNO_service_drawing_TextProperties,
3319                             sUNO_service_style_ParagraphProperties,
3320                             sUNO_service_style_ParagraphPropertiesComplex,
3321                             sUNO_service_style_ParagraphPropertiesAsian,
3322                             sUNO_service_style_CharacterProperties,
3323                             sUNO_service_style_CharacterPropertiesComplex,
3324                             sUNO_service_style_CharacterPropertiesAsian,
3325 
3326                             sUNO_service_drawing_ShadowProperties,
3327                             sUNO_service_drawing_RotationDescriptor };
3328                 return aSvxShape_PathServices;
3329             }
3330 
3331         case SdrObjKind::PathPoly:
3332         case SdrObjKind::Polygon:
3333             {
3334                 static const uno::Sequence<OUString> aSvxShape_PolyServices
3335                         = { sUNO_service_drawing_PolyPolygonShape,
3336 
3337                             sUNO_service_drawing_Shape,
3338                             sUNO_service_drawing_LineProperties,
3339                             sUNO_service_drawing_FillProperties,
3340 
3341                             sUNO_service_drawing_PolyPolygonDescriptor,
3342 
3343                             sUNO_service_drawing_Text,
3344                             sUNO_service_drawing_TextProperties,
3345                             sUNO_service_style_ParagraphProperties,
3346                             sUNO_service_style_ParagraphPropertiesComplex,
3347                             sUNO_service_style_ParagraphPropertiesAsian,
3348                             sUNO_service_style_CharacterProperties,
3349                             sUNO_service_style_CharacterPropertiesComplex,
3350                             sUNO_service_style_CharacterPropertiesAsian,
3351 
3352                             sUNO_service_drawing_ShadowProperties,
3353                             sUNO_service_drawing_RotationDescriptor };
3354                 return aSvxShape_PolyServices;
3355             }
3356 
3357         case SdrObjKind::FreehandLine:
3358         case SdrObjKind::PathLine:
3359             {
3360                 static const uno::Sequence<OUString> aSvxShape_FreeLineServices
3361                         = { sUNO_service_drawing_OpenBezierShape,
3362 
3363                             sUNO_service_drawing_Shape,
3364                             sUNO_service_drawing_LineProperties,
3365                             sUNO_service_drawing_FillProperties,
3366 
3367                             sUNO_service_drawing_PolyPolygonBezierDescriptor,
3368 
3369                             sUNO_service_drawing_Text,
3370                             sUNO_service_drawing_TextProperties,
3371                             sUNO_service_style_ParagraphProperties,
3372                             sUNO_service_style_ParagraphPropertiesComplex,
3373                             sUNO_service_style_ParagraphPropertiesAsian,
3374                             sUNO_service_style_CharacterProperties,
3375                             sUNO_service_style_CharacterPropertiesComplex,
3376                             sUNO_service_style_CharacterPropertiesAsian,
3377 
3378                             sUNO_service_drawing_ShadowProperties,
3379                             sUNO_service_drawing_RotationDescriptor };
3380                 return aSvxShape_FreeLineServices;
3381             }
3382 
3383         case SdrObjKind::FreehandFill:
3384         case SdrObjKind::PathFill:
3385             {
3386                 static const uno::Sequence<OUString> aSvxShape_FreeFillServices
3387                         = { sUNO_service_drawing_ClosedBezierShape,
3388 
3389                             sUNO_service_drawing_Shape,
3390                             sUNO_service_drawing_LineProperties,
3391                             sUNO_service_drawing_FillProperties,
3392 
3393                             sUNO_service_drawing_PolyPolygonBezierDescriptor,
3394 
3395                             sUNO_service_drawing_Text,
3396                             sUNO_service_drawing_TextProperties,
3397                             sUNO_service_style_ParagraphProperties,
3398                             sUNO_service_style_ParagraphPropertiesComplex,
3399                             sUNO_service_style_ParagraphPropertiesAsian,
3400                             sUNO_service_style_CharacterProperties,
3401                             sUNO_service_style_CharacterPropertiesComplex,
3402                             sUNO_service_style_CharacterPropertiesAsian,
3403 
3404                             sUNO_service_drawing_ShadowProperties,
3405                             sUNO_service_drawing_RotationDescriptor };
3406                 return aSvxShape_FreeFillServices;
3407             }
3408 
3409         case SdrObjKind::OutlineText:
3410         case SdrObjKind::TitleText:
3411         case SdrObjKind::Text:
3412             {
3413                 static const uno::Sequence<OUString> aSvxShape_TextServices
3414                         = { sUNO_service_drawing_TextShape,
3415 
3416                             sUNO_service_drawing_Shape,
3417                             sUNO_service_drawing_FillProperties,
3418                             sUNO_service_drawing_LineProperties,
3419 
3420                             sUNO_service_drawing_Text,
3421                             sUNO_service_drawing_TextProperties,
3422                             sUNO_service_style_ParagraphProperties,
3423                             sUNO_service_style_ParagraphPropertiesComplex,
3424                             sUNO_service_style_ParagraphPropertiesAsian,
3425                             sUNO_service_style_CharacterProperties,
3426                             sUNO_service_style_CharacterPropertiesComplex,
3427                             sUNO_service_style_CharacterPropertiesAsian,
3428 
3429                             sUNO_service_drawing_ShadowProperties,
3430                             sUNO_service_drawing_RotationDescriptor };
3431                 return aSvxShape_TextServices;
3432             }
3433         case SdrObjKind::Annotation:
3434             {
3435                 static const uno::Sequence<OUString> aSvxShape_AnnotationServices = {
3436                             sUNO_service_drawing_AnnotationShape,
3437 
3438                             sUNO_service_drawing_Shape,
3439                             sUNO_service_drawing_FillProperties,
3440                             sUNO_service_drawing_LineProperties,
3441 
3442                             sUNO_service_drawing_Text,
3443                             sUNO_service_drawing_TextProperties,
3444                             sUNO_service_style_ParagraphProperties,
3445                             sUNO_service_style_ParagraphPropertiesComplex,
3446                             sUNO_service_style_ParagraphPropertiesAsian,
3447                             sUNO_service_style_CharacterProperties,
3448                             sUNO_service_style_CharacterPropertiesComplex,
3449                             sUNO_service_style_CharacterPropertiesAsian,
3450 
3451                             sUNO_service_drawing_ShadowProperties,
3452                             sUNO_service_drawing_RotationDescriptor
3453                 };
3454                 return aSvxShape_AnnotationServices;
3455             }
3456 
3457         case SdrObjKind::Graphic:
3458             {
3459                 static const uno::Sequence<OUString> aSvxShape_GrafServices
3460                         = { sUNO_service_drawing_GraphicObjectShape,
3461 
3462                             sUNO_service_drawing_Shape,
3463 
3464                             sUNO_service_drawing_Text,
3465                             sUNO_service_drawing_TextProperties,
3466                             sUNO_service_style_ParagraphProperties,
3467                             sUNO_service_style_ParagraphPropertiesComplex,
3468                             sUNO_service_style_ParagraphPropertiesAsian,
3469                             sUNO_service_style_CharacterProperties,
3470                             sUNO_service_style_CharacterPropertiesComplex,
3471                             sUNO_service_style_CharacterPropertiesAsian,
3472 
3473                             sUNO_service_drawing_ShadowProperties,
3474                             sUNO_service_drawing_RotationDescriptor};
3475                 return aSvxShape_GrafServices;
3476             }
3477 
3478         case SdrObjKind::OLE2:
3479             {
3480                 static const uno::Sequence<OUString> aSvxShape_Ole2Services
3481                         = { sUNO_service_drawing_OLE2Shape,
3482                             sUNO_service_drawing_Shape,
3483 
3484                             // #i118485# Added Text, Shadow and Rotation
3485                             sUNO_service_drawing_Text,
3486                             sUNO_service_drawing_TextProperties,
3487                             sUNO_service_style_ParagraphProperties,
3488                             sUNO_service_style_ParagraphPropertiesComplex,
3489                             sUNO_service_style_ParagraphPropertiesAsian,
3490                             sUNO_service_style_CharacterProperties,
3491                             sUNO_service_style_CharacterPropertiesComplex,
3492                             sUNO_service_style_CharacterPropertiesAsian,
3493 
3494                             sUNO_service_drawing_ShadowProperties,
3495                             sUNO_service_drawing_RotationDescriptor };
3496                 return aSvxShape_Ole2Services;
3497             }
3498 
3499         case SdrObjKind::Caption:
3500             {
3501                 static const uno::Sequence<OUString> aSvxShape_CaptionServices
3502                         = { sUNO_service_drawing_CaptionShape,
3503 
3504                             sUNO_service_drawing_Shape,
3505                             sUNO_service_drawing_FillProperties,
3506                             sUNO_service_drawing_LineProperties,
3507 
3508                             sUNO_service_drawing_Text,
3509                             sUNO_service_drawing_TextProperties,
3510                             sUNO_service_style_ParagraphProperties,
3511                             sUNO_service_style_ParagraphPropertiesComplex,
3512                             sUNO_service_style_ParagraphPropertiesAsian,
3513                             sUNO_service_style_CharacterProperties,
3514                             sUNO_service_style_CharacterPropertiesComplex,
3515                             sUNO_service_style_CharacterPropertiesAsian,
3516 
3517                             sUNO_service_drawing_ShadowProperties,
3518                             sUNO_service_drawing_RotationDescriptor };
3519                 return aSvxShape_CaptionServices;
3520             }
3521 
3522         case SdrObjKind::Page:
3523             {
3524                 static const uno::Sequence<OUString> aSvxShape_PageServices
3525                         = { sUNO_service_drawing_PageShape,
3526                             sUNO_service_drawing_Shape };
3527                 return aSvxShape_PageServices;
3528             }
3529 
3530         case SdrObjKind::Measure:
3531             {
3532                 static const uno::Sequence<OUString> aSvxShape_MeasureServices
3533                         = { sUNO_service_drawing_MeasureShape,
3534 
3535                             sUNO_service_drawing_MeasureProperties,
3536 
3537                             sUNO_service_drawing_Shape,
3538                             sUNO_service_drawing_LineProperties,
3539 
3540                             sUNO_service_drawing_Text,
3541                             sUNO_service_drawing_TextProperties,
3542                             sUNO_service_style_ParagraphProperties,
3543                             sUNO_service_style_ParagraphPropertiesComplex,
3544                             sUNO_service_style_ParagraphPropertiesAsian,
3545                             sUNO_service_style_CharacterProperties,
3546                             sUNO_service_style_CharacterPropertiesComplex,
3547                             sUNO_service_style_CharacterPropertiesAsian,
3548 
3549                             sUNO_service_drawing_PolyPolygonDescriptor,
3550                             sUNO_service_drawing_ShadowProperties,
3551                             sUNO_service_drawing_RotationDescriptor };
3552                 return aSvxShape_MeasureServices;
3553             }
3554 
3555         case SdrObjKind::OLEPluginFrame:
3556             {
3557                 static const uno::Sequence<OUString> aSvxShape_FrameServices
3558                         = { sUNO_service_drawing_FrameShape,
3559                             sUNO_service_drawing_Shape };
3560                 return aSvxShape_FrameServices;
3561             }
3562 
3563         case SdrObjKind::UNO:
3564             {
3565                 static const uno::Sequence<OUString> aSvxShape_UnoServices
3566                         = { sUNO_service_drawing_ControlShape,
3567                             sUNO_service_drawing_Shape };
3568                 return aSvxShape_UnoServices;
3569             }
3570 
3571         case SdrObjKind::Edge:
3572             {
3573                 static const uno::Sequence<OUString> aSvxShape_EdgeServices
3574                         = { sUNO_service_drawing_ConnectorShape,
3575                             sUNO_service_drawing_ConnectorProperties,
3576 
3577                             sUNO_service_drawing_Shape,
3578                             sUNO_service_drawing_LineProperties,
3579 
3580                             sUNO_service_drawing_Text,
3581                             sUNO_service_drawing_TextProperties,
3582                             sUNO_service_style_ParagraphProperties,
3583                             sUNO_service_style_ParagraphPropertiesComplex,
3584                             sUNO_service_style_ParagraphPropertiesAsian,
3585                             sUNO_service_style_CharacterProperties,
3586                             sUNO_service_style_CharacterPropertiesComplex,
3587                             sUNO_service_style_CharacterPropertiesAsian,
3588 
3589                             sUNO_service_drawing_PolyPolygonDescriptor,
3590                             sUNO_service_drawing_ShadowProperties,
3591                             sUNO_service_drawing_RotationDescriptor };
3592                 return aSvxShape_EdgeServices;
3593             }
3594         case SdrObjKind::Media:
3595             {
3596                 static const uno::Sequence<OUString> aSvxShape_MediaServices
3597                         = { sUNO_service_drawing_MediaShape,
3598                             sUNO_service_drawing_Shape };
3599                 return aSvxShape_MediaServices;
3600             }
3601         default: ;
3602         }
3603     }
3604     else if( HasSdrObject() && GetSdrObject()->GetObjInventor() == SdrInventor::FmForm)
3605     {
3606 #if OSL_DEBUG_LEVEL > 0
3607         const SdrObjKind nIdent = GetSdrObject()->GetObjIdentifier();
3608         OSL_ENSURE( nIdent == SdrObjKind::UNO, "SvxShape::_getSupportedServiceNames: SdrInventor::FmForm, but no UNO object?" );
3609 #endif
3610         static const uno::Sequence<OUString> aSvxShape_UnoServices
3611                 = { sUNO_service_drawing_ControlShape,
3612                     sUNO_service_drawing_Shape };
3613         return aSvxShape_UnoServices;
3614     }
3615     OSL_FAIL( "SvxShape::_getSupportedServiceNames: could not determine object type!" );
3616     uno::Sequence< OUString > aSeq;
3617     return aSeq;
3618 }
3619 
supportsService(const OUString & ServiceName)3620 sal_Bool SAL_CALL SvxShape::supportsService( const OUString& ServiceName )
3621 {
3622     return cppu::supportsService(this, ServiceName);
3623 }
3624 
3625 // XGluePointsSupplier
getGluePoints()3626 uno::Reference< container::XIndexContainer > SAL_CALL SvxShape::getGluePoints()
3627 {
3628     ::SolarMutexGuard aGuard;
3629     uno::Reference< container::XIndexContainer > xGluePoints( mxGluePoints );
3630 
3631     if( HasSdrObject() && !xGluePoints.is() )
3632     {
3633         xGluePoints.set(SvxUnoGluePointAccess_createInstance(GetSdrObject()), uno::UNO_QUERY);
3634         mxGluePoints = xGluePoints;
3635     }
3636 
3637     return xGluePoints;
3638 }
3639 
3640 // XChild
getParent()3641 uno::Reference<uno::XInterface> SAL_CALL SvxShape::getParent()
3642 {
3643     ::SolarMutexGuard aGuard;
3644     const SdrObject* pSdrObject(GetSdrObject());
3645 
3646     if(nullptr != pSdrObject)
3647     {
3648         const SdrObjList* pParentSdrObjList(GetSdrObject()->getParentSdrObjListFromSdrObject());
3649 
3650         if(nullptr != pParentSdrObjList)
3651         {
3652             // SdrObject is member of a SdrObjList. That may be a SdrObject
3653             // (SdrObjGroup or E3dScene) or a SdrPage.
3654             // Check for SdrObject first - using getSdrPageFromSdrObjList
3655             // *will* get the SdrPage even when the SdrObject is deep buried
3656             // in a construct of SdrObjGroup.
3657             // We want to ask for the direct parent here...
3658             SdrObject* pParentSdrObject(pParentSdrObjList->getSdrObjectFromSdrObjList());
3659 
3660             if(nullptr != pParentSdrObject)
3661             {
3662                 // SdrObject is member of a SdrObject-based Group (SdrObjGroup or E3dScene).
3663                 return pParentSdrObject->getUnoShape();
3664             }
3665             else
3666             {
3667                 SdrPage* pParentSdrPage(pParentSdrObjList->getSdrPageFromSdrObjList());
3668 
3669                 if(nullptr != pParentSdrPage)
3670                 {
3671                     // SdrObject is inserted to a SdrPage. Since
3672                     // we checked for getSdrObjectFromSdrObjList first,
3673                     // we can even say that it is directly member of that
3674                     // SdrPage.
3675                     return pParentSdrPage->getUnoPage();
3676                 }
3677             }
3678 
3679             // not member of any SdrObjList, no parent
3680             OSL_FAIL( "SvxShape::getParent(  ): unexpected Parent SdrObjList" );
3681         }
3682     }
3683 
3684     // no SdrObject, no parent
3685     return uno::Reference<uno::XInterface>();
3686 }
3687 
setParent(const css::uno::Reference<css::uno::XInterface> &)3688 void SAL_CALL SvxShape::setParent( const css::uno::Reference< css::uno::XInterface >& )
3689 {
3690     throw lang::NoSupportException();
3691 }
3692 
3693 
3694 /** called from the XActionLockable interface methods on initial locking */
lock()3695 void SvxShape::lock()
3696 {
3697 }
3698 
3699 
3700 /** called from the XActionLockable interface methods on final unlock */
unlock()3701 void SvxShape::unlock()
3702 {
3703 }
3704 
3705 
3706 // XActionLockable
isActionLocked()3707 sal_Bool SAL_CALL SvxShape::isActionLocked(  )
3708 {
3709     ::SolarMutexGuard aGuard;
3710 
3711     return mnLockCount != 0;
3712 }
3713 
3714 
addActionLock()3715 void SAL_CALL SvxShape::addActionLock(  )
3716 {
3717     ::SolarMutexGuard aGuard;
3718 
3719     DBG_ASSERT( mnLockCount < 0xffff, "lock overflow in SvxShape!" );
3720     mnLockCount++;
3721 
3722     if( mnLockCount == 1 )
3723         lock();
3724 }
3725 
3726 
removeActionLock()3727 void SAL_CALL SvxShape::removeActionLock(  )
3728 {
3729     ::SolarMutexGuard aGuard;
3730 
3731     DBG_ASSERT( mnLockCount > 0, "lock underflow in SvxShape!" );
3732     mnLockCount--;
3733 
3734     if( mnLockCount == 0 )
3735         unlock();
3736 }
3737 
3738 
setActionLocks(sal_Int16 nLock)3739 void SAL_CALL SvxShape::setActionLocks( sal_Int16 nLock )
3740 {
3741     ::SolarMutexGuard aGuard;
3742 
3743     if( (mnLockCount == 0) && (nLock != 0) )
3744         unlock();
3745 
3746     if( (mnLockCount != 0) && (nLock == 0) )
3747         lock();
3748 
3749     mnLockCount = static_cast<sal_uInt16>(nLock);
3750 }
3751 
3752 
resetActionLocks()3753 sal_Int16 SAL_CALL SvxShape::resetActionLocks(  )
3754 {
3755     ::SolarMutexGuard aGuard;
3756 
3757     if( mnLockCount != 0 )
3758         unlock();
3759 
3760     sal_Int16 nOldLocks = static_cast<sal_Int16>(mnLockCount);
3761     mnLockCount = 0;
3762 
3763     return nOldLocks;
3764 }
3765 
3766 
3767 /** since polygon shapes can change their kind during editing, we have
3768     to recheck it here.
3769     Circle shapes also change their kind, but they are all treated equal
3770     so no update is necessary.
3771 */
updateShapeKind()3772 void SvxShape::updateShapeKind()
3773 {
3774     switch( mpImpl->mnObjId )
3775     {
3776         case SdrObjKind::Line:
3777         case SdrObjKind::Polygon:
3778         case SdrObjKind::PolyLine:
3779         case SdrObjKind::PathLine:
3780         case SdrObjKind::PathFill:
3781         case SdrObjKind::FreehandLine:
3782         case SdrObjKind::FreehandFill:
3783         case SdrObjKind::PathPoly:
3784         case SdrObjKind::PathPolyLine:
3785         {
3786             const SdrObjKind nId = GetSdrObject()->GetObjIdentifier();
3787 
3788             if( nId != mpImpl->mnObjId )
3789             {
3790                 mpImpl->mnObjId = nId;
3791 
3792             }
3793             break;
3794         }
3795         default: ;
3796     }
3797 }
3798 
SvxShapeText(SdrObject * pObject)3799 SvxShapeText::SvxShapeText(SdrObject* pObject)
3800 : SvxShape( pObject, getSvxMapProvider().GetMap(SVXMAP_TEXT), getSvxMapProvider().GetPropertySet(SVXMAP_TEXT, SdrObject::GetGlobalDrawObjectItemPool()) ), SvxUnoTextBase( ImplGetSvxUnoOutlinerTextCursorSvxPropertySet() )
3801 {
3802     if( pObject )
3803         SetEditSource( new SvxTextEditSource( pObject, nullptr ) );
3804 }
3805 
3806 
SvxShapeText(SdrObject * pObject,std::span<const SfxItemPropertyMapEntry> pPropertyMap,const SvxItemPropertySet * pPropertySet)3807 SvxShapeText::SvxShapeText(SdrObject* pObject, std::span<const SfxItemPropertyMapEntry> pPropertyMap, const SvxItemPropertySet* pPropertySet)
3808 : SvxShape( pObject, pPropertyMap, pPropertySet ), SvxUnoTextBase( ImplGetSvxUnoOutlinerTextCursorSvxPropertySet() )
3809 {
3810     if( pObject )
3811         SetEditSource( new SvxTextEditSource( pObject, nullptr ) );
3812 }
3813 
3814 
~SvxShapeText()3815 SvxShapeText::~SvxShapeText() noexcept
3816 {
3817     // check if only this instance is registered at the ranges
3818     DBG_ASSERT( (nullptr == GetEditSource()) || (GetEditSource()->getRanges().size()==1),
3819         "svx::SvxShapeText::~SvxShapeText(), text shape with living text ranges destroyed!");
3820 }
3821 
Create(SdrObject * pNewObj,SvxDrawPage * pNewPage)3822 void SvxShapeText::Create( SdrObject* pNewObj, SvxDrawPage* pNewPage )
3823 {
3824     if( pNewObj && (nullptr == GetEditSource()))
3825         SetEditSource( new SvxTextEditSource( pNewObj, nullptr ) );
3826     SvxShape::Create( pNewObj, pNewPage );
3827 }
3828 
3829 // XInterface
3830 
queryInterface(const uno::Type & rType)3831 uno::Any SAL_CALL SvxShapeText::queryInterface( const uno::Type & rType )
3832 {
3833     return SvxShape::queryInterface( rType );
3834 }
3835 
3836 
queryAggregation(const uno::Type & rType)3837 uno::Any SAL_CALL SvxShapeText::queryAggregation( const uno::Type & rType )
3838 {
3839     uno::Any aAny( SvxShape::queryAggregation( rType ) );
3840     if( aAny.hasValue() )
3841         return aAny;
3842 
3843     return SvxUnoTextBase::queryAggregation( rType );
3844 }
3845 
3846 
3847 // XServiceInfo
3848 
getImplementationName()3849 OUString SAL_CALL SvxShapeText::getImplementationName()
3850 {
3851     return u"SvxShapeText"_ustr;
3852 }
3853 
3854 
getSupportedServiceNames()3855 uno::Sequence< OUString > SAL_CALL SvxShapeText::getSupportedServiceNames()
3856 {
3857     return SvxShape::getSupportedServiceNames();
3858 }
3859 
3860 
supportsService(const OUString & ServiceName)3861 sal_Bool SAL_CALL SvxShapeText::supportsService( const OUString& ServiceName )
3862 {
3863     return cppu::supportsService(static_cast<SvxShape*>(this), ServiceName);
3864 }
3865 
3866     // XTypeProvider
3867 
getTypes()3868 uno::Sequence< uno::Type > SAL_CALL SvxShapeText::getTypes()
3869 {
3870     return SvxShape::getTypes();
3871 }
3872 
getSomething(const css::uno::Sequence<sal_Int8> & rId)3873 sal_Int64 SAL_CALL SvxShapeText::getSomething( const css::uno::Sequence< sal_Int8 >& rId )
3874 {
3875     const sal_Int64 nReturn = SvxShape::getSomething( rId );
3876     if( nReturn )
3877         return nReturn;
3878 
3879     return SvxUnoTextBase::getSomething( rId );
3880 }
3881 
3882 
getImplementationId()3883 uno::Sequence< sal_Int8 > SAL_CALL SvxShapeText::getImplementationId()
3884 {
3885     return css::uno::Sequence<sal_Int8>();
3886 }
3887 
3888 
3889 /** called from the XActionLockable interface methods on initial locking */
lock()3890 void SvxShapeText::lock()
3891 {
3892     SvxTextEditSource* pEditSource = static_cast<SvxTextEditSource*>(GetEditSource());
3893     if( pEditSource )
3894         pEditSource->lock();
3895 }
3896 
3897 
3898 /** called from the XActionLockable interface methods on final unlock */
unlock()3899 void SvxShapeText::unlock()
3900 {
3901     SvxTextEditSource* pEditSource = static_cast<SvxTextEditSource*>(GetEditSource());
3902     if( pEditSource )
3903         pEditSource->unlock();
3904 }
3905 
3906 // css::text::XTextRange
getStart()3907 uno::Reference< text::XTextRange > SAL_CALL SvxShapeText::getStart()
3908 {
3909     ::SolarMutexGuard aGuard;
3910     SvxTextForwarder* pForwarder = mpEditSource ? mpEditSource->GetTextForwarder() : nullptr;
3911     if( pForwarder )
3912         ::GetSelection( maSelection, pForwarder );
3913     return SvxUnoTextBase::getStart();
3914 
3915 }
3916 
getEnd()3917 uno::Reference< text::XTextRange > SAL_CALL SvxShapeText::getEnd()
3918 {
3919     ::SolarMutexGuard aGuard;
3920     SvxTextForwarder* pForwarder = mpEditSource ? mpEditSource->GetTextForwarder() : nullptr;
3921     if( pForwarder )
3922         ::GetSelection( maSelection, pForwarder );
3923     return SvxUnoTextBase::getEnd();
3924 }
3925 
getString()3926 OUString SAL_CALL SvxShapeText::getString()
3927 {
3928     ::SolarMutexGuard aGuard;
3929     SvxTextForwarder* pForwarder = mpEditSource ? mpEditSource->GetTextForwarder() : nullptr;
3930     if( pForwarder )
3931         ::GetSelection( maSelection, pForwarder );
3932     return SvxUnoTextBase::getString();
3933 }
3934 
3935 
setString(const OUString & aString)3936 void SAL_CALL SvxShapeText::setString( const OUString& aString )
3937 {
3938     ::SolarMutexGuard aGuard;
3939     SvxTextForwarder* pForwarder = mpEditSource ? mpEditSource->GetTextForwarder() : nullptr;
3940     if( pForwarder )
3941         ::GetSelection( maSelection, pForwarder );
3942     SvxUnoTextBase::setString( aString );
3943 }
3944 
3945 // override these for special property handling in subcasses. Return true if property is handled
setPropertyValueImpl(const OUString & rName,const SfxItemPropertyMapEntry * pProperty,const css::uno::Any & rValue)3946 bool SvxShapeText::setPropertyValueImpl( const OUString& rName, const SfxItemPropertyMapEntry* pProperty, const css::uno::Any& rValue )
3947 {
3948     // HACK-fix #99090#
3949     // since SdrTextObj::SetVerticalWriting exchanges
3950     // SDRATTR_TEXT_AUTOGROWWIDTH and SDRATTR_TEXT_AUTOGROWHEIGHT,
3951     // we have to set the textdirection here
3952 
3953     if( pProperty->nWID == SDRATTR_TEXTDIRECTION )
3954     {
3955         SdrTextObj* pTextObj = DynCastSdrTextObj( GetSdrObject() );
3956         if( pTextObj )
3957         {
3958             css::text::WritingMode eMode;
3959             if( rValue >>= eMode )
3960             {
3961                 pTextObj->SetVerticalWriting( eMode == css::text::WritingMode_TB_RL );
3962             }
3963         }
3964         return true;
3965     }
3966     return SvxShape::setPropertyValueImpl( rName, pProperty, rValue );
3967 }
3968 
getPropertyValueImpl(const OUString & rName,const SfxItemPropertyMapEntry * pProperty,css::uno::Any & rValue)3969 bool SvxShapeText::getPropertyValueImpl( const OUString& rName, const SfxItemPropertyMapEntry* pProperty, css::uno::Any& rValue )
3970 {
3971     if( pProperty->nWID == SDRATTR_TEXTDIRECTION )
3972     {
3973         SdrTextObj* pTextObj = DynCastSdrTextObj( GetSdrObject() );
3974         if( pTextObj && pTextObj->IsVerticalWriting() )
3975             rValue <<= css::text::WritingMode_TB_RL;
3976         else
3977             rValue <<= css::text::WritingMode_LR_TB;
3978         return true;
3979     }
3980 
3981     return SvxShape::getPropertyValueImpl( rName, pProperty, rValue );
3982 }
3983 
getPropertyStateImpl(const SfxItemPropertyMapEntry * pProperty,css::beans::PropertyState & rState)3984 bool SvxShapeText::getPropertyStateImpl( const SfxItemPropertyMapEntry* pProperty, css::beans::PropertyState& rState )
3985 {
3986     return SvxShape::getPropertyStateImpl( pProperty, rState );
3987 }
3988 
setPropertyToDefaultImpl(const SfxItemPropertyMapEntry * pProperty)3989 bool SvxShapeText::setPropertyToDefaultImpl( const SfxItemPropertyMapEntry* pProperty )
3990 {
3991     return SvxShape::setPropertyToDefaultImpl( pProperty );
3992 }
3993 
SvxShapeRect(SdrObject * pObj)3994 SvxShapeRect::SvxShapeRect(SdrObject* pObj)
3995 : SvxShapeText( pObj, getSvxMapProvider().GetMap(SVXMAP_SHAPE), getSvxMapProvider().GetPropertySet(SVXMAP_SHAPE, SdrObject::GetGlobalDrawObjectItemPool()))
3996 {
3997 }
3998 
~SvxShapeRect()3999 SvxShapeRect::~SvxShapeRect() noexcept
4000 {
4001 }
4002 
queryInterface(const uno::Type & rType)4003 uno::Any SAL_CALL SvxShapeRect::queryInterface( const uno::Type & rType )
4004 {
4005     return SvxShapeText::queryInterface( rType );
4006 }
4007 
queryAggregation(const uno::Type & rType)4008 uno::Any SAL_CALL SvxShapeRect::queryAggregation( const uno::Type & rType )
4009 {
4010     return SvxShapeText::queryAggregation( rType );
4011 }
4012 
4013 // XServiceInfo
4014 
getSupportedServiceNames()4015 uno::Sequence< OUString > SvxShapeRect::getSupportedServiceNames()
4016 {
4017     return SvxShape::getSupportedServiceNames();
4018 }
4019 
4020 /** returns a StarOffice API wrapper for the given SdrObject */
GetXShapeForSdrObject(SdrObject * pObj)4021 uno::Reference< drawing::XShape > GetXShapeForSdrObject( SdrObject* pObj ) noexcept
4022 {
4023     uno::Reference< drawing::XShape > xShape( pObj->getUnoShape(), uno::UNO_QUERY );
4024     return xShape;
4025 }
4026 
4027 
getSdrObjectFromXShape(const css::uno::Reference<css::uno::XInterface> & xInt)4028 SdrObject* SdrObject::getSdrObjectFromXShape( const css::uno::Reference< css::uno::XInterface >& xInt )
4029 {
4030     SvxShape* pSvxShape = comphelper::getFromUnoTunnel<SvxShape>( xInt );
4031     return pSvxShape ? pSvxShape->GetSdrObject() : nullptr;
4032 }
4033 
SvxItemPropertySet_getPropertyValue(const SfxItemPropertyMapEntry * pMap,const SfxItemSet & rSet)4034 uno::Any SvxItemPropertySet_getPropertyValue( const SfxItemPropertyMapEntry* pMap, const SfxItemSet& rSet )
4035 {
4036     if(!pMap || !pMap->nWID)
4037         return uno::Any();
4038 
4039     // Check is for items that store either metric values if they are positive or percentage if they are negative.
4040     bool bDontConvertNegativeValues = ( pMap->nWID == XATTR_FILLBMP_SIZEX || pMap->nWID == XATTR_FILLBMP_SIZEY );
4041     return SvxItemPropertySet::getPropertyValue( pMap, rSet, (pMap->nWID != SDRATTR_XMLATTRIBUTES), bDontConvertNegativeValues );
4042 }
4043 
SvxItemPropertySet_setPropertyValue(const SfxItemPropertyMapEntry * pMap,const uno::Any & rVal,SfxItemSet & rSet)4044 void SvxItemPropertySet_setPropertyValue( const SfxItemPropertyMapEntry* pMap, const uno::Any& rVal, SfxItemSet& rSet )
4045 {
4046     if(!pMap || !pMap->nWID)
4047         return;
4048 
4049     bool bDontConvertNegativeValues = ( pMap->nWID == XATTR_FILLBMP_SIZEX || pMap->nWID == XATTR_FILLBMP_SIZEY );
4050     SvxItemPropertySet::setPropertyValue( pMap, rVal, rSet, bDontConvertNegativeValues );
4051 }
4052 
4053 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
4054