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