Version 24.2.2.2, tag libreoffice-24.2.2.2
[LibreOffice.git] / svx / source / unodraw / unoshape.cxx
blobb6ef17b866164a65c718d751ca4b122f380bc01e
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
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 .
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/interfacecontainer3.hxx>
33 #include <comphelper/scopeguard.hxx>
34 #include <comphelper/servicehelper.hxx>
35 #include <comphelper/multiinterfacecontainer4.hxx>
36 #include <toolkit/helper/vclunohelper.hxx>
37 #include <vcl/gfxlink.hxx>
38 #include <vcl/virdev.hxx>
39 #include <svx/sdangitm.hxx>
40 #include <svx/svdlayer.hxx>
41 #include <svx/svdopage.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>
81 #include <svx/lathe3d.hxx>
82 #include <extrud3d.hxx>
83 #include <svx/sdr/contact/viewcontact.hxx>
84 #include <drawinglayer/converters.hxx>
85 #include <drawinglayer/geometry/viewinformation2d.hxx>
86 #include <drawinglayer/primitive2d/transformprimitive2d.hxx>
88 #include <vcl/gdimtf.hxx>
89 #include <vcl/wmf.hxx>
90 #include <svx/sdtfsitm.hxx>
91 #include <svx/svdopath.hxx>
92 #include <svx/SvxXTextColumns.hxx>
93 #include <svx/xflclit.hxx>
94 #include <editeng/frmdiritem.hxx>
96 #include <memory>
97 #include <optional>
98 #include <vector>
99 #include <iostream>
101 #include <bitmaps.hlst>
103 using namespace ::osl;
104 using namespace ::cppu;
105 using namespace ::com::sun::star;
106 using namespace ::com::sun::star::uno;
107 using namespace ::com::sun::star::lang;
108 using namespace ::com::sun::star::container;
110 class GDIMetaFile;
112 struct SvxShapeImpl
114 std::optional<SfxItemSet> moItemSet;
115 SdrObjKind mnObjId;
116 SvxShapeMaster* mpMaster;
117 bool mbDisposing;
119 /** CL, OD 2005-07-19 #i52126# - this is initially 0 and set when
120 * a SvxShape::Create() call is executed. It is then set to the created
121 * SdrObject so a multiple call to SvxShape::Create() with same SdrObject
122 * is prohibited.
124 ::unotools::WeakReference< SdrObject > mxCreatedObj;
126 // for xComponent
127 ::comphelper::OInterfaceContainerHelper4<css::lang::XEventListener> maDisposeListeners;
128 ::comphelper::OMultiTypeInterfaceContainerHelperVar4<OUString, css::beans::XPropertyChangeListener> maPropertyChangeListeners;
130 SvxShapeImpl()
131 :mnObjId( SdrObjKind::NONE )
132 ,mpMaster( nullptr )
133 ,mbDisposing( false )
138 namespace {
141 /// Calculates what scaling factor will be used for autofit text scaling of this shape.
142 double GetTextFitToSizeScale(SdrObject* pObject)
144 SdrTextObj* pTextObj = DynCastSdrTextObj(pObject);
145 if (!pTextObj)
147 return 0;
150 const SfxItemSet& rTextObjSet = pTextObj->GetMergedItemSet();
151 if (rTextObjSet.GetItem<SdrTextFitToSizeTypeItem>(SDRATTR_TEXT_FITTOSIZE)->GetValue()
152 != drawing::TextFitToSizeType_AUTOFIT)
154 return 0;
157 return pTextObj->GetFontScale();
161 SvxShape::SvxShape( SdrObject* pObject )
162 : maSize(100,100)
163 , mpImpl( new SvxShapeImpl )
164 , mbIsMultiPropertyCall(false)
165 , mpPropSet(getSvxMapProvider().GetPropertySet(SVXMAP_SHAPE, SdrObject::GetGlobalDrawObjectItemPool()))
166 , maPropMapEntries(getSvxMapProvider().GetMap(SVXMAP_SHAPE))
167 , mxSdrObject(pObject)
168 , mnLockCount(0)
170 impl_construct();
174 SvxShape::SvxShape( SdrObject* pObject, std::span<const SfxItemPropertyMapEntry> pEntries, const SvxItemPropertySet* pPropertySet )
175 : maSize(100,100)
176 , mpImpl( new SvxShapeImpl )
177 , mbIsMultiPropertyCall(false)
178 , mpPropSet(pPropertySet)
179 , maPropMapEntries(pEntries)
180 , mxSdrObject(pObject)
181 , mnLockCount(0)
183 impl_construct();
187 SvxShape::~SvxShape() noexcept
189 ::SolarMutexGuard aGuard;
191 DBG_ASSERT( mnLockCount == 0, "Locked shape was disposed!" );
193 if ( mpImpl->mpMaster )
194 mpImpl->mpMaster->dispose();
196 if ( mxSdrObject )
198 EndListening(mxSdrObject->getSdrModelFromSdrObject());
199 mxSdrObject->setUnoShape(nullptr);
200 mxSdrObject.clear();
203 EndListeningAll(); // call explicitly within SolarMutexGuard
207 void SvxShape::InvalidateSdrObject()
209 if(mxSdrObject)
211 EndListening(mxSdrObject->getSdrModelFromSdrObject());
212 mxSdrObject.clear();
216 void SvxShape::setShapeKind( SdrObjKind nKind )
218 mpImpl->mnObjId = nKind;
222 SdrObjKind SvxShape::getShapeKind() const
224 return mpImpl->mnObjId;
228 void SvxShape::setMaster( SvxShapeMaster* pMaster )
230 mpImpl->mpMaster = pMaster;
234 uno::Any SAL_CALL SvxShape::queryAggregation( const uno::Type& rType )
236 if( mpImpl->mpMaster )
238 uno::Any aAny;
239 if( mpImpl->mpMaster->queryAggregation( rType, aAny ) )
240 return aAny;
243 return SvxShape_UnoImplHelper::queryAggregation(rType);
246 const css::uno::Sequence< sal_Int8 > & SvxShape::getUnoTunnelId() noexcept
248 static const comphelper::UnoIdInit theSvxShapeUnoTunnelId;
249 return theSvxShapeUnoTunnelId.getSeq();
252 sal_Int64 SAL_CALL SvxShape::getSomething( const css::uno::Sequence< sal_Int8 >& rId )
254 return comphelper::getSomethingImpl(rId, this);
258 void SvxShape::notifyPropertyChange(const OUString& rPropName)
260 std::unique_lock g(m_aMutex);
261 comphelper::OInterfaceContainerHelper4<beans::XPropertyChangeListener>* pPropListeners =
262 mpImpl->maPropertyChangeListeners.getContainer( g, rPropName );
263 comphelper::OInterfaceContainerHelper4<beans::XPropertyChangeListener>* pAllListeners =
264 mpImpl->maPropertyChangeListeners.getContainer( g, OUString() );
265 if (pPropListeners || pAllListeners)
269 // Handle/OldValue not supported
270 beans::PropertyChangeEvent aEvt;
271 aEvt.Source = static_cast<cppu::OWeakObject*>(this);
272 aEvt.PropertyName = rPropName;
273 aEvt.NewValue = getPropertyValue(rPropName);
274 if (pPropListeners)
275 pPropListeners->notifyEach( g, &beans::XPropertyChangeListener::propertyChange, aEvt );
276 if (pAllListeners)
277 pAllListeners->notifyEach( g, &beans::XPropertyChangeListener::propertyChange, aEvt );
279 catch( const Exception& )
281 DBG_UNHANDLED_EXCEPTION("svx");
287 void SvxShape::impl_construct()
289 if ( HasSdrObject() )
291 StartListening(GetSdrObject()->getSdrModelFromSdrObject());
292 impl_initFromSdrObject();
297 void SvxShape::impl_initFromSdrObject()
299 DBG_TESTSOLARMUTEX();
300 OSL_PRECOND( HasSdrObject(), "SvxShape::impl_initFromSdrObject: not to be called without SdrObject!" );
301 if ( !HasSdrObject() )
302 return;
304 osl_atomic_increment( &m_refCount );
306 GetSdrObject()->setUnoShape(this);
308 osl_atomic_decrement( &m_refCount );
310 // #i40944#
311 // Do not simply return when no model but do the type corrections
312 // following below.
313 const SdrInventor nInventor = GetSdrObject()->GetObjInventor();
315 // is it one of ours (svx) ?
316 if( !(nInventor == SdrInventor::Default || nInventor == SdrInventor::E3d || nInventor == SdrInventor::FmForm) )
317 return;
319 if(nInventor == SdrInventor::FmForm)
321 mpImpl->mnObjId = SdrObjKind::UNO;
323 else
325 mpImpl->mnObjId = GetSdrObject()->GetObjIdentifier();
328 switch(mpImpl->mnObjId)
330 case SdrObjKind::CircleCut: // segment of circle
331 case SdrObjKind::CircleArc: // arc of circle
332 case SdrObjKind::CircleSection: // sector
333 mpImpl->mnObjId = SdrObjKind::CircleOrEllipse;
334 break;
335 default: ;
340 void SvxShape::Create( SdrObject* pNewObj, SvxDrawPage* /*pNewPage*/ )
342 DBG_TESTSOLARMUTEX();
344 assert( pNewObj && "SvxShape::Create: invalid new object!" );
345 if ( !pNewObj )
346 return;
348 rtl::Reference<SdrObject> pCreatedObj = mpImpl->mxCreatedObj.get();
349 assert( ( !pCreatedObj || ( pCreatedObj == pNewObj ) ) &&
350 "SvxShape::Create: the same shape used for two different objects?! Strange ..." );
352 // Correct condition (#i52126#)
353 if ( pCreatedObj == pNewObj )
354 return;
356 // Correct condition (#i52126#)
357 mpImpl->mxCreatedObj = pNewObj;
359 if( HasSdrObject() )
361 EndListening( GetSdrObject()->getSdrModelFromSdrObject() );
364 mxSdrObject = pNewObj;
366 if( HasSdrObject() )
368 StartListening( GetSdrObject()->getSdrModelFromSdrObject() );
371 OSL_ENSURE( !mbIsMultiPropertyCall, "SvxShape::Create: hmm?" );
372 // this was previously set in impl_initFromSdrObject, but I think it was superfluous
373 // (it definitely was in the other context where it was called, but I strongly suppose
374 // it was also superfluous when called from here)
375 impl_initFromSdrObject();
377 ObtainSettingsFromPropertySet( *mpPropSet );
379 // save user call
380 SdrObjUserCall* pUser = GetSdrObject()->GetUserCall();
381 GetSdrObject()->SetUserCall(nullptr);
383 setPosition( maPosition );
384 setSize( maSize );
386 // restore user call after we set the initial size
387 GetSdrObject()->SetUserCall( pUser );
389 // if this shape was already named, use this name
390 if( !maShapeName.isEmpty() )
392 GetSdrObject()->SetName( maShapeName );
393 maShapeName.clear();
397 void SvxShape::ForceMetricToItemPoolMetric(Pair& rPoint) const noexcept
399 DBG_TESTSOLARMUTEX();
400 if(!HasSdrObject())
401 return;
403 MapUnit eMapUnit(GetSdrObject()->getSdrModelFromSdrObject().GetItemPool().GetMetric(0));
404 if(eMapUnit == MapUnit::Map100thMM)
405 return;
407 if (const auto eTo = MapToO3tlLength(eMapUnit); eTo != o3tl::Length::invalid)
409 rPoint.A() = o3tl::convert(rPoint.A(), o3tl::Length::mm100, eTo);
410 rPoint.B() = o3tl::convert(rPoint.B(), o3tl::Length::mm100, eTo);
412 else
414 OSL_FAIL("AW: Missing unit translation to PoolMetric!");
418 void SvxShape::ForceMetricToItemPoolMetric(basegfx::B2DPolyPolygon& rPolyPolygon) const noexcept
420 DBG_TESTSOLARMUTEX();
421 if(!HasSdrObject())
422 return;
424 GetSdrObject()->ForceMetricToItemPoolMetric(rPolyPolygon);
427 void SvxShape::ForceMetricToItemPoolMetric(basegfx::B2DHomMatrix& rB2DHomMatrix) const noexcept
429 DBG_TESTSOLARMUTEX();
430 if(!HasSdrObject())
431 return;
433 MapUnit eMapUnit(GetSdrObject()->getSdrModelFromSdrObject().GetItemPool().GetMetric(0));
434 if(eMapUnit == MapUnit::Map100thMM)
435 return;
437 if (const auto eTo = MapToO3tlLength(eMapUnit); eTo != o3tl::Length::invalid)
439 const double fConvert(o3tl::convert(1.0, o3tl::Length::mm100, eTo));
440 const basegfx::utils::B2DHomMatrixBufferedDecompose aDecomposedTransform(rB2DHomMatrix);
441 rB2DHomMatrix = basegfx::utils::createScaleShearXRotateTranslateB2DHomMatrix(
442 aDecomposedTransform.getScale() * fConvert,
443 aDecomposedTransform.getShearX(),
444 aDecomposedTransform.getRotate(),
445 aDecomposedTransform.getTranslate() * fConvert);
447 else
449 OSL_FAIL("Missing unit translation to PoolMetric!");
453 void SvxShape::ForceMetricTo100th_mm(Pair& rPoint) const noexcept
455 DBG_TESTSOLARMUTEX();
456 if(!HasSdrObject())
457 return;
459 MapUnit eMapUnit = GetSdrObject()->getSdrModelFromSdrObject().GetItemPool().GetMetric(0);
460 if(eMapUnit == MapUnit::Map100thMM)
461 return;
463 if (const auto eFrom = MapToO3tlLength(eMapUnit); eFrom != o3tl::Length::invalid)
465 rPoint.A() = o3tl::convert(rPoint.A(), eFrom, o3tl::Length::mm100);
466 rPoint.B() = o3tl::convert(rPoint.B(), eFrom, o3tl::Length::mm100);
468 else
470 OSL_FAIL("AW: Missing unit translation to 100th mm!");
474 void SvxShape::ForceMetricTo100th_mm(basegfx::B2DPolyPolygon& rPolyPolygon) const noexcept
476 DBG_TESTSOLARMUTEX();
477 if(!HasSdrObject())
478 return;
480 MapUnit eMapUnit = GetSdrObject()->getSdrModelFromSdrObject().GetItemPool().GetMetric(0);
481 if(eMapUnit == MapUnit::Map100thMM)
482 return;
484 if (const auto eFrom = MapToO3tlLength(eMapUnit); eFrom != o3tl::Length::invalid)
486 const double fConvert(o3tl::convert(1.0, eFrom, o3tl::Length::mm100));
487 rPolyPolygon.transform(basegfx::utils::createScaleB2DHomMatrix(fConvert, fConvert));
489 else
491 OSL_FAIL("Missing unit translation to 100th mm!");
495 void SvxShape::ForceMetricTo100th_mm(basegfx::B2DHomMatrix& rB2DHomMatrix) const noexcept
497 DBG_TESTSOLARMUTEX();
498 if(!HasSdrObject())
499 return;
501 MapUnit eMapUnit = GetSdrObject()->getSdrModelFromSdrObject().GetItemPool().GetMetric(0);
502 if(eMapUnit == MapUnit::Map100thMM)
503 return;
505 if (const auto eFrom = MapToO3tlLength(eMapUnit); eFrom != o3tl::Length::invalid)
507 const double fConvert(o3tl::convert(1.0, eFrom, o3tl::Length::mm100));
508 const basegfx::utils::B2DHomMatrixBufferedDecompose aDecomposedTransform(rB2DHomMatrix);
509 rB2DHomMatrix = basegfx::utils::createScaleShearXRotateTranslateB2DHomMatrix(
510 aDecomposedTransform.getScale() * fConvert,
511 aDecomposedTransform.getShearX(),
512 aDecomposedTransform.getRotate(),
513 aDecomposedTransform.getTranslate() * fConvert);
515 else
517 OSL_FAIL("Missing unit translation to 100th mm!");
521 static void SvxItemPropertySet_ObtainSettingsFromPropertySet(const SvxItemPropertySet& rPropSet, SvxItemPropertySetUsrAnys& rAnys,
522 SfxItemSet& rSet, const uno::Reference< beans::XPropertySet >& xSet, const SfxItemPropertyMap* pMap )
524 if(!rAnys.AreThereOwnUsrAnys())
525 return;
527 const SfxItemPropertyMap& rSrc = rPropSet.getPropertyMap();
529 for(const SfxItemPropertyMapEntry* pSrcProp : rSrc.getPropertyEntries())
531 const sal_uInt16 nWID = pSrcProp->nWID;
532 if(SfxItemPool::IsWhich(nWID)
533 && (nWID < OWN_ATTR_VALUE_START || nWID > OWN_ATTR_VALUE_END)
534 && rAnys.GetUsrAnyForID(*pSrcProp))
535 rSet.Put(rSet.GetPool()->GetDefaultItem(nWID));
538 for(const SfxItemPropertyMapEntry* pSrcProp : rSrc.getPropertyEntries())
540 if(pSrcProp->nWID)
542 uno::Any* pUsrAny = rAnys.GetUsrAnyForID(*pSrcProp);
543 if(pUsrAny)
545 // search for equivalent entry in pDst
546 const SfxItemPropertyMapEntry* pEntry = pMap->getByName( pSrcProp->aName );
547 if(pEntry)
549 // entry found
550 if(pEntry->nWID >= OWN_ATTR_VALUE_START && pEntry->nWID <= OWN_ATTR_VALUE_END)
552 // special ID in PropertySet, can only be set
553 // directly at the object
554 xSet->setPropertyValue( pSrcProp->aName, *pUsrAny);
556 else
558 SvxItemPropertySet_setPropertyValue(pEntry, *pUsrAny, rSet);
564 rAnys.ClearAllUsrAny();
568 void SvxShape::ObtainSettingsFromPropertySet(const SvxItemPropertySet& rPropSet)
570 DBG_TESTSOLARMUTEX();
571 if(HasSdrObject() && maUrsAnys.AreThereOwnUsrAnys())
573 SfxItemSetFixed<SDRATTR_START, SDRATTR_END> aSet( GetSdrObject()->getSdrModelFromSdrObject().GetItemPool() );
574 Reference< beans::XPropertySet > xShape(this);
575 SvxItemPropertySet_ObtainSettingsFromPropertySet(rPropSet, maUrsAnys, aSet, xShape, &mpPropSet->getPropertyMap() );
577 GetSdrObject()->SetMergedItemSetAndBroadcast(aSet);
579 GetSdrObject()->ApplyNotPersistAttr( aSet );
583 uno::Any SvxShape::GetBitmap( bool bMetaFile /* = false */ ) const
585 DBG_TESTSOLARMUTEX();
586 uno::Any aAny;
588 if(!HasSdrObject() || nullptr == GetSdrObject()->getSdrPageFromSdrObject())
590 return aAny;
593 // tdf#118662 Emulate old behaviour of XclObjComment (see there)
594 const SdrCaptionObj* pSdrCaptionObj(dynamic_cast<SdrCaptionObj*>(GetSdrObject()));
595 if(nullptr != pSdrCaptionObj && pSdrCaptionObj->isSuppressGetBitmap())
597 return aAny;
600 // tdf#119180 If we do not ask for Metafile and we access a SdrGrafObj,
601 // and content exists and is a Bitmap, take the shortcut.
602 // Do *not* do this for Metafile - as can be seen, requested in that case
603 // is a byte-sequence of a saved WMF format file (see below)
604 if(!bMetaFile)
606 const SdrGrafObj* pSdrGrafObj(dynamic_cast<SdrGrafObj*>(GetSdrObject()));
608 if(nullptr != pSdrGrafObj)
610 const Graphic& rGraphic(pSdrGrafObj->GetGraphic());
612 if(GraphicType::Bitmap == rGraphic.GetType())
614 Reference< awt::XBitmap > xBmp( rGraphic.GetXGraphic(), UNO_QUERY );
615 aAny <<= xBmp;
617 return aAny;
622 // tdf#118662 instead of creating an E3dView instance every time to paint
623 // a single SdrObject, use the existing SdrObject::SingleObjectPainter to
624 // use less resources and runtime
625 if(bMetaFile)
627 ScopedVclPtrInstance< VirtualDevice > pVDev;
628 const tools::Rectangle aBoundRect(GetSdrObject()->GetCurrentBoundRect());
629 GDIMetaFile aMtf;
631 pVDev->SetMapMode(MapMode(MapUnit::Map100thMM));
632 pVDev->EnableOutput(false);
633 aMtf.Record(pVDev);
634 GetSdrObject()->SingleObjectPainter(*pVDev);
635 aMtf.Stop();
636 aMtf.WindStart();
637 aMtf.Move(-aBoundRect.Left(), -aBoundRect.Top());
638 aMtf.SetPrefMapMode(MapMode(MapUnit::Map100thMM));
639 aMtf.SetPrefSize(aBoundRect.GetSize());
641 SvMemoryStream aDestStrm(65535, 65535);
643 ConvertGDIMetaFileToWMF(
644 aMtf,
645 aDestStrm,
646 nullptr,
647 false);
649 const uno::Sequence<sal_Int8> aSeq(
650 static_cast< const sal_Int8* >(aDestStrm.GetData()),
651 aDestStrm.GetEndOfData());
653 aAny <<= aSeq;
655 else
657 drawinglayer::primitive2d::Primitive2DContainer xPrimitives;
658 GetSdrObject()->GetViewContact().getViewIndependentPrimitive2DContainer(xPrimitives);
660 if(!xPrimitives.empty())
662 const drawinglayer::geometry::ViewInformation2D aViewInformation2D;
663 basegfx::B2DRange aRange(
664 xPrimitives.getB2DRange(aViewInformation2D));
666 if(!aRange.isEmpty())
668 const MapUnit aSourceMapUnit(GetSdrObject()->getSdrModelFromSdrObject().GetScaleUnit());
670 if(MapUnit::Map100thMM != aSourceMapUnit)
672 // tdf#119180 This is UNO API and thus works in 100th_mm,
673 // so if the MapMode from the used SdrModel is *not* equal
674 // to Map100thMM we need to embed the primitives to an adapting
675 // homogen transformation for correct values
676 const basegfx::B2DHomMatrix aMapTransform(
677 OutputDevice::LogicToLogic(
678 MapMode(aSourceMapUnit),
679 MapMode(MapUnit::Map100thMM)));
681 // Embed primitives to get them in 100th mm
682 drawinglayer::primitive2d::Primitive2DReference xEmbedRef(
683 new drawinglayer::primitive2d::TransformPrimitive2D(
684 aMapTransform,
685 std::move(xPrimitives)));
687 xPrimitives = drawinglayer::primitive2d::Primitive2DContainer { xEmbedRef };
689 // Update basegfx::B2DRange aRange, too. Here we have the
690 // choice of transforming the existing value or get newly by
691 // again using 'xPrimitives.getB2DRange(aViewInformation2D)'
692 aRange.transform(aMapTransform);
695 const BitmapEx aBmp(
696 drawinglayer::convertPrimitive2DContainerToBitmapEx(
697 std::move(xPrimitives),
698 aRange));
700 Graphic aGraph(aBmp);
702 aGraph.SetPrefSize(aBmp.GetPrefSize());
703 aGraph.SetPrefMapMode(aBmp.GetPrefMapMode());
705 Reference< awt::XBitmap > xBmp( aGraph.GetXGraphic(), UNO_QUERY );
706 aAny <<= xBmp;
711 return aAny;
714 uno::Sequence< uno::Type > SAL_CALL SvxShape::getTypes()
716 if( mpImpl->mpMaster )
718 return mpImpl->mpMaster->getTypes();
720 else
722 return _getTypes();
727 uno::Sequence< uno::Type > const & SvxShape::_getTypes()
729 switch( mpImpl->mnObjId )
731 // shapes without text
732 case SdrObjKind::Page:
733 case SdrObjKind::OLEPluginFrame:
734 case SdrObjKind::OLE2Plugin:
735 case SdrObjKind::OLE2Applet:
736 case SdrObjKind::E3D_Cube:
737 case SdrObjKind::E3D_Sphere:
738 case SdrObjKind::E3D_Lathe:
739 case SdrObjKind::E3D_Extrusion:
740 case SdrObjKind::E3D_Polygon:
741 case SdrObjKind::Media:
742 case SdrObjKind::Table:
744 static uno::Sequence<uno::Type> aTypeSequence{
745 cppu::UnoType<drawing::XShape>::get(),
746 cppu::UnoType<lang::XComponent>::get(),
747 cppu::UnoType<beans::XPropertySet>::get(),
748 cppu::UnoType<beans::XMultiPropertySet>::get(),
749 cppu::UnoType<beans::XPropertyState>::get(),
750 cppu::UnoType<beans::XMultiPropertyStates>::get(),
751 cppu::UnoType<drawing::XGluePointsSupplier>::get(),
752 cppu::UnoType<container::XChild>::get(),
753 cppu::UnoType<lang::XServiceInfo>::get(),
754 cppu::UnoType<lang::XTypeProvider>::get(),
755 cppu::UnoType<lang::XUnoTunnel>::get(),
756 cppu::UnoType<container::XNamed>::get(),
759 return aTypeSequence;
761 // group shape
762 case SdrObjKind::Group:
764 static uno::Sequence<uno::Type> aTypeSequence{
765 cppu::UnoType<drawing::XShape>::get(),
766 cppu::UnoType<lang::XComponent>::get(),
767 cppu::UnoType<beans::XPropertySet>::get(),
768 cppu::UnoType<beans::XMultiPropertySet>::get(),
769 cppu::UnoType<beans::XPropertyState>::get(),
770 cppu::UnoType<beans::XMultiPropertyStates>::get(),
771 cppu::UnoType<drawing::XGluePointsSupplier>::get(),
772 cppu::UnoType<container::XChild>::get(),
773 cppu::UnoType<lang::XServiceInfo>::get(),
774 cppu::UnoType<lang::XTypeProvider>::get(),
775 cppu::UnoType<lang::XUnoTunnel>::get(),
776 cppu::UnoType<container::XNamed>::get(),
777 cppu::UnoType<drawing::XShapes>::get(),
778 cppu::UnoType<drawing::XShapeGroup>::get(),
781 return aTypeSequence;
783 // connector shape
784 case SdrObjKind::Edge:
786 static uno::Sequence<uno::Type> aTypeSequence{
787 cppu::UnoType<drawing::XShape>::get(),
788 cppu::UnoType<lang::XComponent>::get(),
789 cppu::UnoType<beans::XPropertySet>::get(),
790 cppu::UnoType<beans::XMultiPropertySet>::get(),
791 cppu::UnoType<beans::XPropertyState>::get(),
792 cppu::UnoType<beans::XMultiPropertyStates>::get(),
793 cppu::UnoType<drawing::XGluePointsSupplier>::get(),
794 cppu::UnoType<container::XChild>::get(),
795 cppu::UnoType<lang::XServiceInfo>::get(),
796 cppu::UnoType<lang::XTypeProvider>::get(),
797 cppu::UnoType<lang::XUnoTunnel>::get(),
798 cppu::UnoType<container::XNamed>::get(),
799 cppu::UnoType<drawing::XConnectorShape>::get(),
800 // from SvxUnoTextBase::getTypes()
801 cppu::UnoType<text::XTextAppend>::get(),
802 cppu::UnoType<text::XTextCopy>::get(),
803 cppu::UnoType<container::XEnumerationAccess>::get(),
804 cppu::UnoType<text::XTextRangeMover>::get(),
807 return aTypeSequence;
809 // control shape
810 case SdrObjKind::UNO:
812 static uno::Sequence<uno::Type> aTypeSequence{
813 cppu::UnoType<drawing::XShape>::get(),
814 cppu::UnoType<lang::XComponent>::get(),
815 cppu::UnoType<beans::XPropertySet>::get(),
816 cppu::UnoType<beans::XMultiPropertySet>::get(),
817 cppu::UnoType<beans::XPropertyState>::get(),
818 cppu::UnoType<beans::XMultiPropertyStates>::get(),
819 cppu::UnoType<drawing::XGluePointsSupplier>::get(),
820 cppu::UnoType<container::XChild>::get(),
821 cppu::UnoType<lang::XServiceInfo>::get(),
822 cppu::UnoType<lang::XTypeProvider>::get(),
823 cppu::UnoType<lang::XUnoTunnel>::get(),
824 cppu::UnoType<container::XNamed>::get(),
825 cppu::UnoType<drawing::XControlShape>::get(),
828 return aTypeSequence;
830 // 3d scene shape
831 case SdrObjKind::E3D_Scene:
833 static uno::Sequence<uno::Type> aTypeSequence{
834 cppu::UnoType<drawing::XShape>::get(),
835 cppu::UnoType<lang::XComponent>::get(),
836 cppu::UnoType<beans::XPropertySet>::get(),
837 cppu::UnoType<beans::XMultiPropertySet>::get(),
838 cppu::UnoType<beans::XPropertyState>::get(),
839 cppu::UnoType<beans::XMultiPropertyStates>::get(),
840 cppu::UnoType<drawing::XGluePointsSupplier>::get(),
841 cppu::UnoType<container::XChild>::get(),
842 cppu::UnoType<lang::XServiceInfo>::get(),
843 cppu::UnoType<lang::XTypeProvider>::get(),
844 cppu::UnoType<lang::XUnoTunnel>::get(),
845 cppu::UnoType<container::XNamed>::get(),
846 cppu::UnoType<drawing::XShapes>::get(),
849 return aTypeSequence;
851 case SdrObjKind::CustomShape:
853 static uno::Sequence<uno::Type> aTypeSequence{
854 cppu::UnoType<drawing::XShape>::get(),
855 cppu::UnoType<lang::XComponent>::get(),
856 cppu::UnoType<beans::XPropertySet>::get(),
857 cppu::UnoType<beans::XMultiPropertySet>::get(),
858 cppu::UnoType<beans::XPropertyState>::get(),
859 cppu::UnoType<beans::XMultiPropertyStates>::get(),
860 cppu::UnoType<drawing::XGluePointsSupplier>::get(),
861 cppu::UnoType<container::XChild>::get(),
862 cppu::UnoType<lang::XServiceInfo>::get(),
863 cppu::UnoType<lang::XTypeProvider>::get(),
864 cppu::UnoType<lang::XUnoTunnel>::get(),
865 cppu::UnoType<container::XNamed>::get(),
866 // from SvxUnoTextBase::getTypes()
867 cppu::UnoType<text::XText>::get(),
868 cppu::UnoType<container::XEnumerationAccess>::get(),
869 cppu::UnoType<text::XTextRangeMover>::get(),
870 cppu::UnoType<drawing::XEnhancedCustomShapeDefaulter>::get(),
873 return aTypeSequence;
875 // shapes with text
876 case SdrObjKind::Rectangle:
877 case SdrObjKind::CircleOrEllipse:
878 case SdrObjKind::Measure:
879 case SdrObjKind::Line:
880 case SdrObjKind::Polygon:
881 case SdrObjKind::PolyLine:
882 case SdrObjKind::PathLine:
883 case SdrObjKind::PathFill:
884 case SdrObjKind::FreehandLine:
885 case SdrObjKind::FreehandFill:
886 case SdrObjKind::PathPoly:
887 case SdrObjKind::PathPolyLine:
888 case SdrObjKind::Graphic:
889 case SdrObjKind::Text:
890 case SdrObjKind::Caption:
891 case SdrObjKind::OLE2: // #i118485# Moved to shapes with text
892 default:
894 static uno::Sequence<uno::Type> aTypeSequence{
895 cppu::UnoType<drawing::XShape>::get(),
896 cppu::UnoType<lang::XComponent>::get(),
897 cppu::UnoType<beans::XPropertySet>::get(),
898 cppu::UnoType<beans::XMultiPropertySet>::get(),
899 cppu::UnoType<beans::XPropertyState>::get(),
900 cppu::UnoType<beans::XMultiPropertyStates>::get(),
901 cppu::UnoType<drawing::XGluePointsSupplier>::get(),
902 cppu::UnoType<container::XChild>::get(),
903 cppu::UnoType<lang::XServiceInfo>::get(),
904 cppu::UnoType<lang::XTypeProvider>::get(),
905 cppu::UnoType<lang::XUnoTunnel>::get(),
906 cppu::UnoType<container::XNamed>::get(),
907 // from SvxUnoTextBase::getTypes()
908 cppu::UnoType<text::XTextAppend>::get(),
909 cppu::UnoType<text::XTextCopy>::get(),
910 cppu::UnoType<container::XEnumerationAccess>::get(),
911 cppu::UnoType<text::XTextRangeMover>::get(),
914 return aTypeSequence;
920 uno::Sequence< sal_Int8 > SAL_CALL SvxShape::getImplementationId()
922 return css::uno::Sequence<sal_Int8>();
925 void SvxShape::Notify( SfxBroadcaster&, const SfxHint& rHint ) noexcept
927 DBG_TESTSOLARMUTEX();
929 // do cheap checks first, this method is hot
930 if (rHint.GetId() != SfxHintId::ThisIsAnSdrHint)
931 return;
932 if( !mxSdrObject )
933 return;
934 const SdrHint* pSdrHint = static_cast<const SdrHint*>(&rHint);
935 // #i55919# SdrHintKind::ObjectChange is only interesting if it's for this object
936 if ((pSdrHint->GetKind() != SdrHintKind::ModelCleared) &&
937 (pSdrHint->GetKind() != SdrHintKind::ObjectChange || pSdrHint->GetObject() != mxSdrObject.get() ))
938 return;
940 // prevent object being deleted from under us
941 rtl::Reference<SdrObject> xSdrSelf(mxSdrObject);
942 uno::Reference< uno::XInterface > xSelf( mxSdrObject->getWeakUnoShape() );
943 if( !xSelf.is() )
945 EndListening(mxSdrObject->getSdrModelFromSdrObject());
946 mxSdrObject.clear();
947 return;
950 if (pSdrHint->GetKind() == SdrHintKind::ObjectChange)
952 updateShapeKind();
954 else // (pSdrHint->GetKind() == SdrHintKind::ModelCleared)
956 EndListening(mxSdrObject->getSdrModelFromSdrObject());
957 mxSdrObject->setUnoShape(nullptr);
958 mxSdrObject.clear();
960 if(!mpImpl->mbDisposing)
961 dispose();
965 // XShape
968 // The "*LogicRectHack" functions also existed in sch, and those
969 // duplicate symbols cause Bad Things To Happen (TM) #i9462#.
970 // Prefixing with 'svx' and marking static to make sure name collisions
971 // do not occur.
973 static bool svx_needLogicRectHack( SdrObject const * pObj )
975 if( pObj->GetObjInventor() == SdrInventor::Default)
977 switch(pObj->GetObjIdentifier())
979 case SdrObjKind::Group:
980 case SdrObjKind::Line:
981 case SdrObjKind::Polygon:
982 case SdrObjKind::PolyLine:
983 case SdrObjKind::PathLine:
984 case SdrObjKind::PathFill:
985 case SdrObjKind::FreehandLine:
986 case SdrObjKind::FreehandFill:
987 case SdrObjKind::Edge:
988 case SdrObjKind::PathPoly:
989 case SdrObjKind::PathPolyLine:
990 case SdrObjKind::Measure:
991 return true;
992 default:
993 break;
996 return false;
1000 static tools::Rectangle svx_getLogicRectHack( SdrObject const * pObj )
1002 if(svx_needLogicRectHack(pObj))
1004 return pObj->GetSnapRect();
1006 else
1008 return pObj->GetLogicRect();
1013 static void svx_setLogicRectHack( SdrObject* pObj, const tools::Rectangle& rRect )
1015 if(svx_needLogicRectHack(pObj))
1017 pObj->SetSnapRect( rRect );
1019 else
1021 pObj->SetLogicRect( rRect );
1026 awt::Point SAL_CALL SvxShape::getPosition()
1028 ::SolarMutexGuard aGuard;
1030 if(HasSdrObject())
1032 tools::Rectangle aRect( svx_getLogicRectHack(GetSdrObject()) );
1033 Point aPt( aRect.Left(), aRect.Top() );
1035 // Position is relative to anchor, so recalc to absolute position
1036 if( GetSdrObject()->getSdrModelFromSdrObject().IsWriter() )
1037 aPt -= GetSdrObject()->GetAnchorPos();
1039 ForceMetricTo100th_mm(aPt);
1040 return css::awt::Point( aPt.X(), aPt.Y() );
1042 else
1044 return maPosition;
1049 void SAL_CALL SvxShape::setPosition( const awt::Point& Position )
1051 ::SolarMutexGuard aGuard;
1053 if(HasSdrObject())
1055 // do NOT move 3D objects, this would change the homogen
1056 // transformation matrix
1057 if(dynamic_cast<const E3dCompoundObject* >(GetSdrObject()) == nullptr)
1059 tools::Rectangle aRect( svx_getLogicRectHack(GetSdrObject()) );
1060 Point aLocalPos( Position.X, Position.Y );
1061 ForceMetricToItemPoolMetric(aLocalPos);
1063 // Position is absolute, so recalc to position relative to anchor
1064 if( GetSdrObject()->getSdrModelFromSdrObject().IsWriter() )
1065 aLocalPos += GetSdrObject()->GetAnchorPos();
1067 tools::Long nDX = aLocalPos.X() - aRect.Left();
1068 tools::Long nDY = aLocalPos.Y() - aRect.Top();
1070 GetSdrObject()->Move( Size( nDX, nDY ) );
1071 GetSdrObject()->getSdrModelFromSdrObject().SetChanged();
1075 maPosition = Position;
1079 awt::Size SAL_CALL SvxShape::getSize()
1081 ::SolarMutexGuard aGuard;
1083 if(HasSdrObject())
1085 tools::Rectangle aRect( svx_getLogicRectHack(GetSdrObject()) );
1086 Size aObjSize( aRect.getOpenWidth(), aRect.getOpenHeight() );
1087 ForceMetricTo100th_mm(aObjSize);
1088 return css::awt::Size( aObjSize.getWidth(), aObjSize.getHeight() );
1090 else
1091 return maSize;
1095 void SAL_CALL SvxShape::setSize( const awt::Size& rSize )
1097 ::SolarMutexGuard aGuard;
1099 if(HasSdrObject())
1101 tools::Rectangle aRect( svx_getLogicRectHack(GetSdrObject()) );
1102 Size aLocalSize( rSize.Width, rSize.Height );
1103 ForceMetricToItemPoolMetric(aLocalSize);
1105 if(GetSdrObject()->GetObjInventor() == SdrInventor::Default && GetSdrObject()->GetObjIdentifier() == SdrObjKind::Measure )
1107 Fraction aWdt(aLocalSize.Width(),aRect.Right()-aRect.Left());
1108 Fraction aHgt(aLocalSize.Height(),aRect.Bottom()-aRect.Top());
1109 Point aPt = GetSdrObject()->GetSnapRect().TopLeft();
1110 GetSdrObject()->Resize(aPt,aWdt,aHgt);
1112 else
1114 //aRect.SetSize(aLocalSize); // this call subtract 1 // https://bz.apache.org/ooo/show_bug.cgi?id=83193
1115 if ( !aLocalSize.Width() )
1117 aRect.SetWidthEmpty();
1119 else
1120 aRect.setWidth(aLocalSize.Width());
1121 if ( !aLocalSize.Height() )
1123 aRect.SetHeightEmpty();
1125 else
1126 aRect.setHeight(aLocalSize.Height());
1128 svx_setLogicRectHack( GetSdrObject(), aRect );
1131 GetSdrObject()->getSdrModelFromSdrObject().SetChanged();
1133 maSize = rSize;
1137 // XNamed
1138 OUString SAL_CALL SvxShape::getName( )
1140 ::SolarMutexGuard aGuard;
1141 if( HasSdrObject() )
1143 return GetSdrObject()->GetName();
1145 else
1147 return maShapeName;
1152 void SAL_CALL SvxShape::setName( const OUString& aName )
1154 ::SolarMutexGuard aGuard;
1155 if( HasSdrObject() )
1157 GetSdrObject()->SetName( aName );
1159 else
1161 maShapeName = aName;
1165 // XShapeDescriptor
1168 OUString SAL_CALL SvxShape::getShapeType()
1170 if( !maShapeType.getLength() )
1171 return UHashMap::getNameFromId( mpImpl->mnObjId );
1172 else
1173 return maShapeType;
1176 // XComponent
1179 void SAL_CALL SvxShape::dispose()
1181 std::unique_lock g(m_aMutex);
1183 if( mpImpl->mbDisposing )
1184 return; // caught a recursion
1186 mpImpl->mbDisposing = true;
1188 lang::EventObject aEvt;
1189 aEvt.Source = *static_cast<OWeakAggObject*>(this);
1190 mpImpl->maDisposeListeners.disposeAndClear(g, aEvt);
1191 mpImpl->maPropertyChangeListeners.disposeAndClear(g, aEvt);
1193 rtl::Reference<SdrObject> pObject = mxSdrObject;
1194 if (!pObject)
1195 return;
1197 EndListening( pObject->getSdrModelFromSdrObject() );
1199 if ( pObject->IsInserted() && pObject->getSdrPageFromSdrObject() )
1201 SdrPage* pPage = pObject->getSdrPageFromSdrObject();
1202 // delete the SdrObject from the page
1203 const size_t nCount = pPage->GetObjCount();
1204 for ( size_t nNum = 0; nNum < nCount; ++nNum )
1206 if ( pPage->GetObj( nNum ) == pObject.get() )
1208 OSL_VERIFY( pPage->RemoveObject( nNum ) == pObject );
1209 break;
1214 mxSdrObject.clear();
1215 pObject->setUnoShape(nullptr);
1219 void SAL_CALL SvxShape::addEventListener( const Reference< lang::XEventListener >& xListener )
1221 std::unique_lock g(m_aMutex);
1222 mpImpl->maDisposeListeners.addInterface(g, xListener);
1226 void SAL_CALL SvxShape::removeEventListener( const Reference< lang::XEventListener >& aListener )
1228 std::unique_lock g(m_aMutex);
1229 mpImpl->maDisposeListeners.removeInterface(g, aListener);
1232 // XPropertySet
1235 Reference< beans::XPropertySetInfo > SAL_CALL
1236 SvxShape::getPropertySetInfo()
1238 if( mpImpl->mpMaster )
1240 return mpImpl->mpMaster->getPropertySetInfo();
1242 else
1244 return _getPropertySetInfo();
1248 Reference< beans::XPropertySetInfo > const &
1249 SvxShape::_getPropertySetInfo()
1251 return mpPropSet->getPropertySetInfo();
1255 void SAL_CALL SvxShape::addPropertyChangeListener( const OUString& _propertyName, const Reference< beans::XPropertyChangeListener >& _listener )
1257 std::unique_lock g(m_aMutex);
1258 mpImpl->maPropertyChangeListeners.addInterface( g, _propertyName, _listener );
1262 void SAL_CALL SvxShape::removePropertyChangeListener( const OUString& _propertyName, const Reference< beans::XPropertyChangeListener >& _listener )
1264 std::unique_lock g(m_aMutex);
1265 mpImpl->maPropertyChangeListeners.removeInterface( g, _propertyName, _listener );
1269 void SAL_CALL SvxShape::addVetoableChangeListener( const OUString& , const Reference< beans::XVetoableChangeListener >& )
1271 OSL_FAIL( "SvxShape::addVetoableChangeListener: don't have any vetoable properties, so why ...?" );
1275 void SAL_CALL SvxShape::removeVetoableChangeListener( const OUString& , const Reference< beans::XVetoableChangeListener >& )
1277 OSL_FAIL( "SvxShape::removeVetoableChangeListener: don't have any vetoable properties, so why ...?" );
1281 bool SvxShape::SetFillAttribute( sal_uInt16 nWID, const OUString& rName )
1283 if(HasSdrObject())
1285 SfxItemSet aSet( GetSdrObject()->getSdrModelFromSdrObject().GetItemPool(), nWID, nWID );
1287 if( SetFillAttribute( nWID, rName, aSet, &GetSdrObject()->getSdrModelFromSdrObject() ) )
1289 //GetSdrObject()->SetItemSetAndBroadcast(aSet);
1290 GetSdrObject()->SetMergedItemSetAndBroadcast(aSet);
1292 return true;
1296 return false;
1300 bool SvxShape::SetFillAttribute( sal_uInt16 nWID, const OUString& rName, SfxItemSet& rSet, SdrModel const * pModel )
1302 // check if an item with the given name and which id is inside the models
1303 // pool or the stylesheet pool, if found it's put in the itemset
1304 if( !SetFillAttribute( nWID, rName, rSet ) )
1306 // we did not find such item in one of the pools, so we check
1307 // the property lists that are loaded for the model for items
1308 // that support such.
1309 OUString aStrName = SvxUnogetInternalNameForItem(nWID, rName);
1311 switch( nWID )
1313 case XATTR_FILLBITMAP:
1315 XBitmapListRef pBitmapList = pModel->GetBitmapList();
1317 if( !pBitmapList.is() )
1318 return false;
1320 tools::Long nPos = pBitmapList->GetIndex(aStrName);
1321 if( nPos == -1 )
1322 return false;
1324 const XBitmapEntry* pEntry = pBitmapList->GetBitmap(nPos);
1325 XFillBitmapItem aBmpItem(rName, pEntry->GetGraphicObject());
1326 rSet.Put(aBmpItem);
1327 break;
1329 case XATTR_FILLGRADIENT:
1331 XGradientListRef pGradientList = pModel->GetGradientList();
1333 if( !pGradientList.is() )
1334 return false;
1336 tools::Long nPos = pGradientList->GetIndex(aStrName);
1337 if( nPos == -1 )
1338 return false;
1340 const XGradientEntry* pEntry = pGradientList->GetGradient(nPos);
1341 XFillGradientItem aGrdItem(rName, pEntry->GetGradient());
1342 rSet.Put( aGrdItem );
1343 break;
1345 case XATTR_FILLHATCH:
1347 XHatchListRef pHatchList = pModel->GetHatchList();
1349 if( !pHatchList.is() )
1350 return false;
1352 tools::Long nPos = pHatchList->GetIndex(aStrName);
1353 if( nPos == -1 )
1354 return false;
1356 const XHatchEntry* pEntry = pHatchList->GetHatch( nPos );
1357 XFillHatchItem aHatchItem(rName, pEntry->GetHatch());
1358 rSet.Put( aHatchItem );
1359 break;
1361 case XATTR_LINEEND:
1362 case XATTR_LINESTART:
1364 XLineEndListRef pLineEndList = pModel->GetLineEndList();
1366 if( !pLineEndList.is() )
1367 return false;
1369 tools::Long nPos = pLineEndList->GetIndex(aStrName);
1370 if( nPos == -1 )
1371 return false;
1373 const XLineEndEntry* pEntry = pLineEndList->GetLineEnd(nPos);
1374 if( sal_uInt16(XATTR_LINEEND) == nWID )
1376 XLineEndItem aLEItem(rName, pEntry->GetLineEnd());
1377 rSet.Put( aLEItem );
1379 else
1381 XLineStartItem aLSItem(rName, pEntry->GetLineEnd());
1382 rSet.Put( aLSItem );
1385 break;
1387 case XATTR_LINEDASH:
1389 XDashListRef pDashList = pModel->GetDashList();
1391 if( !pDashList.is() )
1392 return false;
1394 tools::Long nPos = pDashList->GetIndex(aStrName);
1395 if( nPos == -1 )
1396 return false;
1398 const XDashEntry* pEntry = pDashList->GetDash(nPos);
1399 XLineDashItem aDashItem(rName, pEntry->GetDash());
1400 rSet.Put( aDashItem );
1401 break;
1403 default:
1404 return false;
1408 return true;
1412 bool SvxShape::SetFillAttribute( sal_uInt16 nWID, const OUString& rName, SfxItemSet& rSet )
1414 OUString aName = SvxUnogetInternalNameForItem(nWID, rName);
1416 if (aName.isEmpty())
1418 switch( nWID )
1420 case XATTR_LINEEND:
1421 case XATTR_LINESTART:
1423 const basegfx::B2DPolyPolygon aEmptyPoly;
1424 if( nWID == sal_uInt16(XATTR_LINEEND) )
1425 rSet.Put( XLineEndItem( "", aEmptyPoly ) );
1426 else
1427 rSet.Put( XLineStartItem( "", aEmptyPoly ) );
1429 return true;
1431 case XATTR_FILLFLOATTRANSPARENCE:
1433 // #85953# Set a disabled XFillFloatTransparenceItem
1434 rSet.Put(XFillFloatTransparenceItem());
1436 return true;
1440 return false;
1443 for (const SfxPoolItem* p : rSet.GetPool()->GetItemSurrogates(nWID))
1445 const NameOrIndex* pItem = static_cast<const NameOrIndex*>(p);
1446 if( pItem->GetName() == aName )
1448 rSet.Put( *pItem );
1449 return true;
1453 return false;
1457 void SAL_CALL SvxShape::setPropertyValue( const OUString& rPropertyName, const uno::Any& rVal )
1459 if( mpImpl->mpMaster )
1461 mpImpl->mpMaster->setPropertyValue( rPropertyName, rVal );
1463 else
1465 _setPropertyValue( rPropertyName, rVal );
1469 void SvxShape::_setPropertyValue( const OUString& rPropertyName, const uno::Any& rVal )
1471 ::SolarMutexGuard aGuard;
1473 const SfxItemPropertyMapEntry* pMap = mpPropSet->getPropertyMapEntry(rPropertyName);
1475 if (!HasSdrObject())
1477 // Since we have no actual sdr object right now, remember all
1478 // properties in a list. These properties will be set when the sdr
1479 // object is created.
1481 if (pMap && pMap->nWID)
1483 // FIXME: We should throw a UnknownPropertyException here.
1484 // But since this class is aggregated from classes that
1485 // support additional properties that we don't know here we
1486 // silently store *all* properties, even if they may be not
1487 // supported after creation.
1488 SvxItemPropertySet::setPropertyValue( pMap, rVal, maUrsAnys );
1491 return;
1494 if (rPropertyName == "HandlePathObjScale")
1496 auto pPathObj = dynamic_cast<SdrPathObj*>(GetSdrObject());
1497 if (pPathObj)
1499 bool bHandleScale{};
1500 if (rVal >>= bHandleScale)
1502 pPathObj->SetHandleScale(bHandleScale);
1505 return;
1508 if (!pMap)
1509 throw beans::UnknownPropertyException( rPropertyName, getXWeak());
1511 if ((pMap->nFlags & beans::PropertyAttribute::READONLY) != 0)
1512 throw beans::PropertyVetoException(
1513 "Readonly property can't be set: " + rPropertyName,
1514 uno::Reference<drawing::XShape>(this));
1516 GetSdrObject()->getSdrModelFromSdrObject().SetChanged();
1518 if (setPropertyValueImpl(rPropertyName, pMap, rVal))
1519 return;
1521 DBG_ASSERT( pMap->nWID == SDRATTR_TEXTDIRECTION || pMap->nWID < SDRATTR_NOTPERSIST_FIRST || pMap->nWID > SDRATTR_NOTPERSIST_LAST, "Not persist item not handled!" );
1522 DBG_ASSERT( pMap->nWID < OWN_ATTR_VALUE_START || pMap->nWID > OWN_ATTR_VALUE_END, "Not item property not handled!" );
1524 bool bIsNotPersist = pMap->nWID >= SDRATTR_NOTPERSIST_FIRST && pMap->nWID <= SDRATTR_NOTPERSIST_LAST && pMap->nWID != SDRATTR_TEXTDIRECTION;
1526 if( pMap->nWID == SDRATTR_CORNER_RADIUS )
1528 sal_Int32 nCornerRadius = 0;
1529 if( !(rVal >>= nCornerRadius) || (nCornerRadius < 0) || (nCornerRadius > 5000000))
1530 throw IllegalArgumentException();
1533 std::optional<SfxItemSet> xLocalSet;
1534 SfxItemSet* pSet;
1535 if( mbIsMultiPropertyCall && !bIsNotPersist )
1537 if( !mpImpl->moItemSet )
1539 mpImpl->moItemSet.emplace( GetSdrObject()->GetProperties().CreateObjectSpecificItemSet( GetSdrObject()->getSdrModelFromSdrObject().GetItemPool() ) );
1541 pSet = &*mpImpl->moItemSet;
1543 else
1545 xLocalSet.emplace( GetSdrObject()->getSdrModelFromSdrObject().GetItemPool(), pMap->nWID, pMap->nWID);
1546 pSet = &*xLocalSet;
1549 if( pSet->GetItemState( pMap->nWID ) != SfxItemState::SET )
1550 pSet->Put(GetSdrObject()->GetMergedItem(pMap->nWID));
1552 if( !SvxUnoTextRangeBase::SetPropertyValueHelper( pMap, rVal, *pSet ))
1554 if( pSet->GetItemState( pMap->nWID ) != SfxItemState::SET )
1556 if(bIsNotPersist)
1558 // not-persistent attribute, get those extra
1559 GetSdrObject()->TakeNotPersistAttr(*pSet);
1563 if( pSet->GetItemState( pMap->nWID ) != SfxItemState::SET )
1565 // get default from ItemPool
1566 if(SfxItemPool::IsWhich(pMap->nWID))
1567 pSet->Put(GetSdrObject()->getSdrModelFromSdrObject().GetItemPool().GetDefaultItem(pMap->nWID));
1570 if( pSet->GetItemState( pMap->nWID ) == SfxItemState::SET )
1572 SvxItemPropertySet_setPropertyValue( pMap, rVal, *pSet );
1576 if(bIsNotPersist)
1578 // set not-persistent attribute extra
1579 GetSdrObject()->ApplyNotPersistAttr( *pSet );
1581 else
1583 // if we have a XMultiProperty call then the item set
1584 // will be set in setPropertyValues later
1585 if( !mbIsMultiPropertyCall )
1586 GetSdrObject()->SetMergedItemSetAndBroadcast( *pSet );
1591 uno::Any SAL_CALL SvxShape::getPropertyValue( const OUString& PropertyName )
1593 if ( mpImpl->mpMaster )
1594 return mpImpl->mpMaster->getPropertyValue( PropertyName );
1595 else
1596 return _getPropertyValue( PropertyName );
1600 uno::Any SvxShape::_getPropertyValue( const OUString& PropertyName )
1602 ::SolarMutexGuard aGuard;
1604 const SfxItemPropertyMapEntry* pMap = mpPropSet->getPropertyMapEntry(PropertyName);
1606 uno::Any aAny;
1607 if(HasSdrObject())
1609 if(pMap == nullptr )
1610 throw beans::UnknownPropertyException( PropertyName, getXWeak());
1612 if( !getPropertyValueImpl( PropertyName, pMap, aAny ) )
1614 DBG_ASSERT( pMap->nWID == SDRATTR_TEXTDIRECTION || (pMap->nWID < SDRATTR_NOTPERSIST_FIRST || pMap->nWID > SDRATTR_NOTPERSIST_LAST), "Not persist item not handled!" );
1615 DBG_ASSERT( pMap->nWID < OWN_ATTR_VALUE_START || pMap->nWID > OWN_ATTR_VALUE_END, "Not item property not handled!" );
1617 SfxItemSet aSet( GetSdrObject()->getSdrModelFromSdrObject().GetItemPool(), pMap->nWID, pMap->nWID );
1618 aSet.Put(GetSdrObject()->GetMergedItem(pMap->nWID));
1620 if(SvxUnoTextRangeBase::GetPropertyValueHelper( aSet, pMap, aAny ))
1621 return aAny;
1623 if(!aSet.Count())
1625 if(pMap->nWID >= SDRATTR_NOTPERSIST_FIRST && pMap->nWID <= SDRATTR_NOTPERSIST_LAST)
1627 // not-persistent attribute, get those extra
1628 GetSdrObject()->TakeNotPersistAttr(aSet);
1632 if(!aSet.Count())
1634 // get default from ItemPool
1635 if(SfxItemPool::IsWhich(pMap->nWID))
1636 aSet.Put(GetSdrObject()->getSdrModelFromSdrObject().GetItemPool().GetDefaultItem(pMap->nWID));
1639 if(aSet.Count())
1640 aAny = GetAnyForItem( aSet, pMap );
1643 else
1646 // Fixme: we should return default values for OWN_ATTR !
1648 if(pMap && pMap->nWID)
1649 // FixMe: see setPropertyValue
1650 aAny = mpPropSet->getPropertyValue( pMap, maUrsAnys );
1653 return aAny;
1657 // XMultiPropertySet
1658 void SAL_CALL SvxShape::setPropertyValues( const css::uno::Sequence< OUString >& aPropertyNames, const css::uno::Sequence< css::uno::Any >& aValues )
1660 ::SolarMutexGuard aSolarGuard;
1662 const sal_Int32 nCount = aPropertyNames.getLength();
1663 if (nCount != aValues.getLength())
1664 throw css::lang::IllegalArgumentException("lengths do not match",
1665 getXWeak(), -1);
1667 const OUString* pNames = aPropertyNames.getConstArray();
1668 const uno::Any* pValues = aValues.getConstArray();
1670 // make sure mbIsMultiPropertyCall and mpImpl->mpItemSet are
1671 // reset even when an exception is thrown
1672 const ::comphelper::ScopeGuard aGuard( [this] () { return this->endSetPropertyValues(); } );
1674 mbIsMultiPropertyCall = true;
1676 if( mpImpl->mpMaster )
1678 for( sal_Int32 nIdx = 0; nIdx < nCount; nIdx++, pNames++, pValues++ )
1682 setPropertyValue( *pNames, *pValues );
1684 catch (beans::UnknownPropertyException&)
1686 // ignore, various code likes to opportunisticly set properties on objects that don't support those properties
1688 catch (uno::Exception&)
1690 DBG_UNHANDLED_EXCEPTION("svx");
1694 else
1696 uno::Reference< beans::XPropertySet > xSet;
1697 queryInterface( cppu::UnoType<beans::XPropertySet>::get()) >>= xSet;
1699 for( sal_Int32 nIdx = 0; nIdx < nCount; nIdx++, pNames++, pValues++ )
1703 xSet->setPropertyValue( *pNames, *pValues );
1705 catch (beans::UnknownPropertyException&)
1707 DBG_UNHANDLED_EXCEPTION("svx");
1709 catch (uno::Exception&)
1711 DBG_UNHANDLED_EXCEPTION("svx");
1716 if( mpImpl->moItemSet && HasSdrObject() )
1717 GetSdrObject()->SetMergedItemSetAndBroadcast( *mpImpl->moItemSet );
1721 void SvxShape::endSetPropertyValues()
1723 mbIsMultiPropertyCall = false;
1724 mpImpl->moItemSet.reset();
1728 css::uno::Sequence< css::uno::Any > SAL_CALL SvxShape::getPropertyValues( const css::uno::Sequence< OUString >& aPropertyNames )
1730 const sal_Int32 nCount = aPropertyNames.getLength();
1731 const OUString* pNames = aPropertyNames.getConstArray();
1733 uno::Sequence< uno::Any > aRet( nCount );
1734 uno::Any* pValue = aRet.getArray();
1736 if( mpImpl->mpMaster )
1738 for( sal_Int32 nIdx = 0; nIdx < nCount; nIdx++, pValue++, pNames++ )
1742 *pValue = getPropertyValue( *pNames );
1744 catch( uno::Exception& )
1746 OSL_FAIL( "SvxShape::getPropertyValues, unknown property asked" );
1750 else
1752 uno::Reference< beans::XPropertySet > xSet;
1753 queryInterface( cppu::UnoType<beans::XPropertySet>::get()) >>= xSet;
1755 for( sal_Int32 nIdx = 0; nIdx < nCount; nIdx++, pValue++, pNames++ )
1759 *pValue = xSet->getPropertyValue( *pNames );
1761 catch( uno::Exception& )
1763 OSL_FAIL( "SvxShape::getPropertyValues, unknown property asked" );
1768 return aRet;
1771 void SAL_CALL SvxShape::addPropertiesChangeListener( const css::uno::Sequence< OUString >& , const css::uno::Reference< css::beans::XPropertiesChangeListener >& )
1775 void SAL_CALL SvxShape::removePropertiesChangeListener( const css::uno::Reference< css::beans::XPropertiesChangeListener >& )
1779 void SAL_CALL SvxShape::firePropertiesChangeEvent( const css::uno::Sequence< OUString >& , const css::uno::Reference< css::beans::XPropertiesChangeListener >& )
1784 uno::Any SvxShape::GetAnyForItem( SfxItemSet const & aSet, const SfxItemPropertyMapEntry* pMap ) const
1786 DBG_TESTSOLARMUTEX();
1787 uno::Any aAny;
1789 switch(pMap->nWID)
1791 case SDRATTR_CIRCSTARTANGLE:
1793 if(const SdrAngleItem* pPoolItem = aSet.GetItemIfSet(SDRATTR_CIRCSTARTANGLE,false))
1795 Degree100 nAngle = pPoolItem->GetValue();
1796 aAny <<= nAngle.get();
1798 break;
1801 case SDRATTR_CIRCENDANGLE:
1803 if (const SdrAngleItem* pPoolItem = aSet.GetItemIfSet(SDRATTR_CIRCENDANGLE,false))
1805 Degree100 nAngle = pPoolItem->GetValue();
1806 aAny <<= nAngle.get();
1808 break;
1811 case SDRATTR_CIRCKIND:
1813 if( GetSdrObject()->GetObjInventor() == SdrInventor::Default)
1815 drawing::CircleKind eKind;
1816 switch(GetSdrObject()->GetObjIdentifier())
1818 case SdrObjKind::CircleOrEllipse: // circle, ellipse
1819 eKind = drawing::CircleKind_FULL;
1820 break;
1821 case SdrObjKind::CircleCut: // segment of circle
1822 eKind = drawing::CircleKind_CUT;
1823 break;
1824 case SdrObjKind::CircleArc: // arc of circle
1825 eKind = drawing::CircleKind_ARC;
1826 break;
1827 case SdrObjKind::CircleSection: // sector
1828 eKind = drawing::CircleKind_SECTION;
1829 break;
1830 default:
1831 break;
1833 aAny <<= eKind;
1835 break;
1837 default:
1839 // get value from ItemSet
1840 aAny = SvxItemPropertySet_getPropertyValue( pMap, aSet );
1842 if( pMap->aType != aAny.getValueType() )
1844 // since the sfx uint16 item now exports a sal_Int32, we may have to fix this here
1845 if( ( pMap->aType == ::cppu::UnoType<sal_Int16>::get()) && aAny.getValueType() == ::cppu::UnoType<sal_Int32>::get() )
1847 sal_Int32 nValue = 0;
1848 aAny >>= nValue;
1849 aAny <<= static_cast<sal_Int16>(nValue);
1851 else
1853 SAL_WARN("svx", "SvxShape::GetAnyForItem() Return value has wrong Type, " << pMap->aType << " != " << aAny.getValueType());
1860 return aAny;
1864 // XPropertyState
1865 beans::PropertyState SAL_CALL SvxShape::getPropertyState( const OUString& PropertyName )
1867 if( mpImpl->mpMaster )
1869 return mpImpl->mpMaster->getPropertyState( PropertyName );
1871 else
1873 return _getPropertyState( PropertyName );
1877 beans::PropertyState SvxShape::_getPropertyState( const OUString& PropertyName )
1879 ::SolarMutexGuard aGuard;
1881 const SfxItemPropertyMapEntry* pMap = mpPropSet->getPropertyMapEntry(PropertyName);
1883 if( !HasSdrObject() || pMap == nullptr )
1884 throw beans::UnknownPropertyException( PropertyName, getXWeak());
1886 beans::PropertyState eState;
1887 if( !getPropertyStateImpl( pMap, eState ) )
1889 const SfxItemSet& rSet = GetSdrObject()->GetMergedItemSet();
1891 switch( rSet.GetItemState( pMap->nWID, false ) )
1893 case SfxItemState::SET:
1894 eState = beans::PropertyState_DIRECT_VALUE;
1895 break;
1896 case SfxItemState::DEFAULT:
1897 eState = beans::PropertyState_DEFAULT_VALUE;
1898 break;
1899 default:
1900 eState = beans::PropertyState_AMBIGUOUS_VALUE;
1901 break;
1904 // if an item is set, this doesn't mean we want it :)
1905 if( beans::PropertyState_DIRECT_VALUE == eState )
1907 switch( pMap->nWID )
1909 // the following items are disabled by changing the
1910 // fill style or the line style. so there is no need
1911 // to export items without names which should be empty
1912 case XATTR_FILLBITMAP:
1913 case XATTR_FILLGRADIENT:
1914 case XATTR_FILLHATCH:
1915 case XATTR_LINEDASH:
1917 const NameOrIndex* pItem = rSet.GetItem<NameOrIndex>(pMap->nWID);
1918 if( ( pItem == nullptr ) || pItem->GetName().isEmpty() )
1919 eState = beans::PropertyState_DEFAULT_VALUE;
1921 break;
1923 // #i36115#
1924 // If e.g. the LineStart is on NONE and thus the string has length 0, it still
1925 // may be a hard attribute covering the set LineStart of the parent (Style).
1926 // #i37644#
1927 // same is for fill float transparency
1928 case XATTR_LINEEND:
1929 case XATTR_LINESTART:
1930 case XATTR_FILLFLOATTRANSPARENCE:
1932 const NameOrIndex* pItem = rSet.GetItem<NameOrIndex>(pMap->nWID);
1933 if ( pItem == nullptr )
1934 eState = beans::PropertyState_DEFAULT_VALUE;
1936 break;
1937 case XATTR_FILLCOLOR:
1938 if (pMap->nMemberId == MID_COLOR_THEME_INDEX)
1940 const XFillColorItem* pColor = rSet.GetItem<XFillColorItem>(pMap->nWID);
1941 if (!pColor->getComplexColor().isValidThemeType())
1943 eState = beans::PropertyState_DEFAULT_VALUE;
1946 else if (pMap->nMemberId == MID_COLOR_LUM_MOD)
1948 const XFillColorItem* pColor = rSet.GetItem<XFillColorItem>(pMap->nWID);
1949 sal_Int16 nLumMod = 10000;
1950 for (auto const& rTransform : pColor->getComplexColor().getTransformations())
1952 if (rTransform.meType == model::TransformationType::LumMod)
1953 nLumMod = rTransform.mnValue;
1955 if (nLumMod == 10000)
1957 eState = beans::PropertyState_DEFAULT_VALUE;
1960 else if (pMap->nMemberId == MID_COLOR_LUM_OFF)
1962 const XFillColorItem* pColor = rSet.GetItem<XFillColorItem>(pMap->nWID);
1963 sal_Int16 nLumOff = 0;
1964 for (auto const& rTransform : pColor->getComplexColor().getTransformations())
1966 if (rTransform.meType == model::TransformationType::LumOff)
1967 nLumOff = rTransform.mnValue;
1969 if (nLumOff == 0)
1971 eState = beans::PropertyState_DEFAULT_VALUE;
1974 else if (pMap->nMemberId == MID_COMPLEX_COLOR)
1976 auto const* pColor = rSet.GetItem<XFillColorItem>(pMap->nWID);
1977 if (pColor->getComplexColor().getType() == model::ColorType::Unused)
1979 eState = beans::PropertyState_DEFAULT_VALUE;
1982 break;
1983 case XATTR_LINECOLOR:
1984 if (pMap->nMemberId == MID_COMPLEX_COLOR)
1986 auto const* pColor = rSet.GetItem<XLineColorItem>(pMap->nWID);
1987 if (pColor->getComplexColor().getType() == model::ColorType::Unused)
1989 eState = beans::PropertyState_DEFAULT_VALUE;
1992 break;
1996 return eState;
1999 bool SvxShape::setPropertyValueImpl( const OUString&, const SfxItemPropertyMapEntry* pProperty, const css::uno::Any& rValue )
2001 rtl::Reference<SdrObject> pSdrObject = GetSdrObject();
2002 switch( pProperty->nWID )
2004 case OWN_ATTR_CAPTION_POINT:
2006 awt::Point aPnt;
2007 if( rValue >>= aPnt )
2009 Point aVclPoint( aPnt.X, aPnt.Y );
2011 // tdf#117145 metric of SdrModel is app-specific, metric of UNO API is 100thmm
2012 // Need to adapt aVclPoint from 100thmm to app-specific
2013 ForceMetricToItemPoolMetric(aVclPoint);
2015 // #90763# position is relative to top left, make it absolute
2016 basegfx::B2DPolyPolygon aNewPolyPolygon;
2017 basegfx::B2DHomMatrix aNewHomogenMatrix;
2018 pSdrObject->TRGetBaseGeometry(aNewHomogenMatrix, aNewPolyPolygon);
2020 aVclPoint.AdjustX(basegfx::fround(aNewHomogenMatrix.get(0, 2)) );
2021 aVclPoint.AdjustY(basegfx::fround(aNewHomogenMatrix.get(1, 2)) );
2023 // #88491# position relative to anchor
2024 if( pSdrObject->getSdrModelFromSdrObject().IsWriter() )
2026 aVclPoint += pSdrObject->GetAnchorPos();
2029 static_cast<SdrCaptionObj*>(pSdrObject.get())->SetTailPos(aVclPoint);
2031 return true;
2033 break;
2035 case OWN_ATTR_TRANSFORMATION:
2037 drawing::HomogenMatrix3 aMatrix;
2038 if(rValue >>= aMatrix)
2040 basegfx::B2DPolyPolygon aNewPolyPolygon;
2041 basegfx::B2DHomMatrix aNewHomogenMatrix;
2043 // tdf#117145 SdrModel data is app-specific
2044 pSdrObject->TRGetBaseGeometry(aNewHomogenMatrix, aNewPolyPolygon);
2046 aNewHomogenMatrix.set(0, 0, aMatrix.Line1.Column1);
2047 aNewHomogenMatrix.set(0, 1, aMatrix.Line1.Column2);
2048 aNewHomogenMatrix.set(0, 2, aMatrix.Line1.Column3);
2049 aNewHomogenMatrix.set(1, 0, aMatrix.Line2.Column1);
2050 aNewHomogenMatrix.set(1, 1, aMatrix.Line2.Column2);
2051 aNewHomogenMatrix.set(1, 2, aMatrix.Line2.Column3);
2052 // For this to be a valid 2D transform matrix, the last row must be [0,0,1]
2053 assert( aMatrix.Line3.Column1 == 0 );
2054 assert( aMatrix.Line3.Column2 == 0 );
2055 assert( aMatrix.Line3.Column3 == 1 );
2057 // tdf#117145 metric of SdrModel is app-specific, metric of UNO API is 100thmm
2058 // Need to adapt aNewHomogenMatrix from 100thmm to app-specific
2059 ForceMetricToItemPoolMetric(aNewHomogenMatrix);
2061 pSdrObject->TRSetBaseGeometry(aNewHomogenMatrix, aNewPolyPolygon);
2062 return true;
2064 break;
2067 case OWN_ATTR_ZORDER:
2069 sal_Int32 nNewOrdNum = 0;
2070 if(rValue >>= nNewOrdNum)
2072 SdrObjList* pObjList = pSdrObject->getParentSdrObjListFromSdrObject();
2073 if( pObjList )
2074 pObjList->SetExistingObjectOrdNum( pSdrObject.get(), static_cast<size_t>(nNewOrdNum) );
2075 return true;
2077 break;
2079 case OWN_ATTR_FRAMERECT:
2081 awt::Rectangle aUnoRect;
2082 if(rValue >>= aUnoRect)
2084 Point aTopLeft( aUnoRect.X, aUnoRect.Y );
2085 Size aObjSize( aUnoRect.Width, aUnoRect.Height );
2086 ForceMetricToItemPoolMetric(aTopLeft);
2087 ForceMetricToItemPoolMetric(aObjSize);
2088 tools::Rectangle aRect(aTopLeft, aObjSize);
2089 pSdrObject->SetSnapRect(aRect);
2090 return true;
2092 break;
2094 case OWN_ATTR_MIRRORED:
2096 bool bMirror;
2097 if(rValue >>= bMirror )
2099 SdrGrafObj* pObj = dynamic_cast< SdrGrafObj* >( pSdrObject.get() );
2100 if( pObj )
2101 pObj->SetMirrored(bMirror);
2102 return true;
2104 break;
2106 case OWN_ATTR_EDGE_START_OBJ:
2107 case OWN_ATTR_EDGE_END_OBJ:
2108 case OWN_ATTR_GLUEID_HEAD:
2109 case OWN_ATTR_GLUEID_TAIL:
2110 case OWN_ATTR_EDGE_START_POS:
2111 case OWN_ATTR_EDGE_END_POS:
2112 case OWN_ATTR_EDGE_POLYPOLYGONBEZIER:
2114 SdrEdgeObj* pEdgeObj = dynamic_cast< SdrEdgeObj* >(pSdrObject.get());
2115 if(pEdgeObj)
2117 switch(pProperty->nWID)
2119 case OWN_ATTR_EDGE_START_OBJ:
2120 case OWN_ATTR_EDGE_END_OBJ:
2122 Reference< drawing::XShape > xShape;
2123 if( rValue >>= xShape )
2125 SdrObject* pNode = SdrObject::getSdrObjectFromXShape(xShape);
2126 if( pNode )
2128 pEdgeObj->ConnectToNode( pProperty->nWID == OWN_ATTR_EDGE_START_OBJ, pNode );
2129 pEdgeObj->setGluePointIndex( pProperty->nWID == OWN_ATTR_EDGE_START_OBJ );
2130 return true;
2133 break;
2136 case OWN_ATTR_EDGE_START_POS:
2137 case OWN_ATTR_EDGE_END_POS:
2139 awt::Point aUnoPoint;
2140 if( rValue >>= aUnoPoint )
2142 Point aPoint( aUnoPoint.X, aUnoPoint.Y );
2144 // Reintroduction of fix for issue i59051 (#i108851#)
2145 // perform metric change before applying anchor position,
2146 // because the anchor position is in pool metric.
2147 ForceMetricToItemPoolMetric( aPoint );
2148 if( pSdrObject->getSdrModelFromSdrObject().IsWriter() )
2149 aPoint += pSdrObject->GetAnchorPos();
2151 pEdgeObj->SetTailPoint( pProperty->nWID == OWN_ATTR_EDGE_START_POS, aPoint );
2152 return true;
2154 break;
2157 case OWN_ATTR_GLUEID_HEAD:
2158 case OWN_ATTR_GLUEID_TAIL:
2160 sal_Int32 nId = 0;
2161 if( rValue >>= nId )
2163 pEdgeObj->setGluePointIndex( pProperty->nWID == OWN_ATTR_GLUEID_HEAD, nId );
2164 return true;
2166 break;
2168 case OWN_ATTR_EDGE_POLYPOLYGONBEZIER:
2170 basegfx::B2DPolyPolygon aNewPolyPolygon;
2172 // #123616# be a little bit more flexible regarding the data type used
2173 if( auto s = o3tl::tryAccess<drawing::PointSequenceSequence>(rValue) )
2175 // get polygpon data from PointSequenceSequence
2176 aNewPolyPolygon = basegfx::utils::UnoPointSequenceSequenceToB2DPolyPolygon(
2177 *s);
2179 else if( auto cs = o3tl::tryAccess<drawing::PolyPolygonBezierCoords>(rValue) )
2181 // get polygpon data from PolyPolygonBezierCoords
2182 aNewPolyPolygon = basegfx::utils::UnoPolyPolygonBezierCoordsToB2DPolyPolygon(
2183 *cs);
2186 if(aNewPolyPolygon.count())
2188 // Reintroduction of fix for issue i59051 (#i108851#)
2189 ForceMetricToItemPoolMetric( aNewPolyPolygon );
2190 if( pSdrObject->getSdrModelFromSdrObject().IsWriter() )
2192 Point aPoint( pSdrObject->GetAnchorPos() );
2193 aNewPolyPolygon.transform(basegfx::utils::createTranslateB2DHomMatrix(aPoint.X(), aPoint.Y()));
2195 pEdgeObj->SetEdgeTrackPath( aNewPolyPolygon );
2196 return true;
2201 break;
2203 case OWN_ATTR_MEASURE_START_POS:
2204 case OWN_ATTR_MEASURE_END_POS:
2206 SdrMeasureObj* pMeasureObj = dynamic_cast< SdrMeasureObj* >(pSdrObject.get());
2207 awt::Point aUnoPoint;
2208 if(pMeasureObj && ( rValue >>= aUnoPoint ) )
2210 Point aPoint( aUnoPoint.X, aUnoPoint.Y );
2212 // Reintroduction of fix for issue #i59051# (#i108851#)
2213 ForceMetricToItemPoolMetric( aPoint );
2214 if( pSdrObject->getSdrModelFromSdrObject().IsWriter() )
2215 aPoint += pSdrObject->GetAnchorPos();
2217 pMeasureObj->NbcSetPoint( aPoint, pProperty->nWID == OWN_ATTR_MEASURE_START_POS ? 0 : 1 );
2218 pMeasureObj->SetChanged();
2219 pMeasureObj->BroadcastObjectChange();
2220 return true;
2222 break;
2224 case OWN_ATTR_FILLBMP_MODE:
2226 drawing::BitmapMode eMode;
2227 if(!(rValue >>= eMode) )
2229 sal_Int32 nMode = 0;
2230 if(!(rValue >>= nMode))
2231 break;
2233 eMode = static_cast<drawing::BitmapMode>(nMode);
2235 pSdrObject->SetMergedItem( XFillBmpStretchItem( eMode == drawing::BitmapMode_STRETCH ) );
2236 pSdrObject->SetMergedItem( XFillBmpTileItem( eMode == drawing::BitmapMode_REPEAT ) );
2237 return true;
2240 case SDRATTR_LAYERID:
2242 sal_Int16 nLayerId = sal_Int16();
2243 if( rValue >>= nLayerId )
2245 SdrLayer* pLayer = pSdrObject->getSdrModelFromSdrObject().GetLayerAdmin().GetLayerPerID(SdrLayerID(nLayerId));
2246 if( pLayer )
2248 pSdrObject->SetLayer(SdrLayerID(nLayerId));
2249 return true;
2252 break;
2255 case SDRATTR_LAYERNAME:
2257 OUString aLayerName;
2258 if( rValue >>= aLayerName )
2260 const SdrLayer* pLayer = pSdrObject->getSdrModelFromSdrObject().GetLayerAdmin().GetLayer(aLayerName);
2261 if( pLayer != nullptr )
2263 pSdrObject->SetLayer( pLayer->GetID() );
2264 return true;
2267 break;
2269 case SDRATTR_ROTATEANGLE:
2271 sal_Int32 nTmp = 0;
2272 if( rValue >>= nTmp )
2274 Degree100 nAngle(nTmp);
2275 Point aRef1(pSdrObject->GetSnapRect().Center());
2276 nAngle -= pSdrObject->GetRotateAngle();
2277 if (nAngle)
2279 double nSin = sin(toRadians(nAngle));
2280 double nCos = cos(toRadians(nAngle));
2281 pSdrObject->Rotate(aRef1,nAngle,nSin,nCos);
2283 return true;
2286 break;
2289 case SDRATTR_SHEARANGLE:
2291 sal_Int32 nTmp = 0;
2292 if( rValue >>= nTmp )
2294 Degree100 nShear(nTmp);
2295 nShear -= pSdrObject->GetShearAngle();
2296 if(nShear)
2298 Point aRef1(pSdrObject->GetSnapRect().Center());
2299 double nTan = tan(toRadians(nShear));
2300 pSdrObject->Shear(aRef1,nShear,nTan,false);
2301 return true;
2305 break;
2308 case OWN_ATTR_INTEROPGRABBAG:
2310 pSdrObject->SetGrabBagItem(rValue);
2311 return true;
2314 case SDRATTR_OBJMOVEPROTECT:
2316 bool bMoveProtect;
2317 if( rValue >>= bMoveProtect )
2319 pSdrObject->SetMoveProtect(bMoveProtect);
2320 return true;
2322 break;
2324 case SDRATTR_OBJECTNAME:
2326 OUString aName;
2327 if( rValue >>= aName )
2329 pSdrObject->SetName( aName );
2330 return true;
2332 break;
2335 case OWN_ATTR_TEXTFITTOSIZESCALE:
2337 double nMaxScale = 0.0;
2338 if (rValue >>= nMaxScale)
2340 SdrTextFitToSizeTypeItem aItem(pSdrObject->GetMergedItem(SDRATTR_TEXT_FITTOSIZE));
2341 aItem.SetMaxScale(nMaxScale);
2342 pSdrObject->SetMergedItem(aItem);
2343 return true;
2345 break;
2348 // #i68101#
2349 case OWN_ATTR_MISC_OBJ_TITLE:
2351 OUString aTitle;
2352 if( rValue >>= aTitle )
2354 pSdrObject->SetTitle( aTitle );
2355 return true;
2357 break;
2359 case OWN_ATTR_MISC_OBJ_DESCRIPTION:
2361 OUString aDescription;
2362 if( rValue >>= aDescription )
2364 pSdrObject->SetDescription( aDescription );
2365 return true;
2367 break;
2369 case OWN_ATTR_MISC_OBJ_DECORATIVE:
2371 bool isDecorative;
2372 if (rValue >>= isDecorative)
2374 pSdrObject->SetDecorative(isDecorative);
2375 return true;
2377 break;
2380 case SDRATTR_OBJPRINTABLE:
2382 bool bPrintable;
2383 if( rValue >>= bPrintable )
2385 pSdrObject->SetPrintable(bPrintable);
2386 return true;
2388 break;
2390 case SDRATTR_OBJVISIBLE:
2392 bool bVisible;
2393 if( rValue >>= bVisible )
2395 pSdrObject->SetVisible(bVisible);
2396 return true;
2398 break;
2400 case SDRATTR_OBJSIZEPROTECT:
2402 bool bResizeProtect;
2403 if( rValue >>= bResizeProtect )
2405 pSdrObject->SetResizeProtect(bResizeProtect);
2406 return true;
2408 break;
2410 case OWN_ATTR_PAGE_NUMBER:
2412 sal_Int32 nPageNum = 0;
2413 if( (rValue >>= nPageNum) && ( nPageNum >= 0 ) && ( nPageNum <= 0xffff ) )
2415 SdrPageObj* pPageObj = dynamic_cast< SdrPageObj* >(pSdrObject.get());
2416 if( pPageObj )
2418 SdrModel& rModel(pPageObj->getSdrModelFromSdrObject());
2419 SdrPage* pNewPage = nullptr;
2420 const sal_uInt16 nDestinationPageNum(static_cast<sal_uInt16>((nPageNum << 1) - 1));
2422 if(nDestinationPageNum < rModel.GetPageCount())
2424 pNewPage = rModel.GetPage(nDestinationPageNum);
2427 pPageObj->SetReferencedPage(pNewPage);
2430 return true;
2432 break;
2434 case XATTR_FILLBITMAP:
2435 case XATTR_FILLGRADIENT:
2436 case XATTR_FILLHATCH:
2437 case XATTR_FILLFLOATTRANSPARENCE:
2438 case XATTR_LINEEND:
2439 case XATTR_LINESTART:
2440 case XATTR_LINEDASH:
2442 if( pProperty->nMemberId == MID_NAME )
2444 OUString aApiName;
2445 if( rValue >>= aApiName )
2447 if( SetFillAttribute( pProperty->nWID, aApiName ) )
2448 return true;
2450 break;
2452 else
2454 return false;
2458 case OWN_ATTR_TEXTCOLUMNS:
2460 if (auto pTextObj = DynCastSdrTextObj(pSdrObject.get()))
2462 css::uno::Reference<css::text::XTextColumns> xTextColumns;
2463 if (rValue >>= xTextColumns)
2465 pTextObj->SetTextColumnsNumber(xTextColumns->getColumnCount());
2466 if (css::uno::Reference<css::beans::XPropertySet> xPropSet{ xTextColumns,
2467 css::uno::UNO_QUERY })
2469 auto aVal = xPropSet->getPropertyValue("AutomaticDistance");
2470 if (sal_Int32 nSpacing; aVal >>= nSpacing)
2471 pTextObj->SetTextColumnsSpacing(nSpacing);
2475 return true;
2478 case OWN_ATTR_HYPERLINK:
2480 OUString sHyperlink;
2481 if (rValue >>= sHyperlink)
2483 pSdrObject->setHyperlink(sHyperlink);
2484 return true;
2486 break;
2489 case SDRATTR_WRITINGMODE2:
2491 SvxFrameDirectionItem aItem(SvxFrameDirection::Environment, SDRATTR_WRITINGMODE2);
2492 aItem.PutValue(rValue, 0);
2493 GetSdrObject()->SetMergedItem(aItem);
2494 return true;
2495 break;
2498 default:
2500 return false;
2504 OUString sExceptionMessage(
2505 "IllegalArgumentException in SvxShape::setPropertyValueImpl."
2506 " Property Type: "
2507 + pProperty->aType.getTypeName() + " Property Name: " + pProperty->aName
2508 + " Property nWID: " + OUString::number(pProperty->nWID)
2509 + " Value Type: " + (rValue.hasValue() ? rValue.getValueTypeName() : "void (no value)"));
2511 throw lang::IllegalArgumentException(sExceptionMessage, nullptr, 1);
2515 bool SvxShape::getPropertyValueImpl( const OUString&, const SfxItemPropertyMapEntry* pProperty, css::uno::Any& rValue )
2517 switch( pProperty->nWID )
2519 case OWN_ATTR_CAPTION_POINT:
2521 Point aVclPoint = static_cast<SdrCaptionObj*>(GetSdrObject())->GetTailPos();
2523 // #88491# make pos relative to anchor
2524 if( GetSdrObject()->getSdrModelFromSdrObject().IsWriter() )
2526 aVclPoint -= GetSdrObject()->GetAnchorPos();
2529 // #90763# pos is absolute, make it relative to top left
2530 basegfx::B2DPolyPolygon aNewPolyPolygon;
2531 basegfx::B2DHomMatrix aNewHomogenMatrix;
2532 GetSdrObject()->TRGetBaseGeometry(aNewHomogenMatrix, aNewPolyPolygon);
2534 aVclPoint.AdjustX( -(basegfx::fround(aNewHomogenMatrix.get(0, 2))) );
2535 aVclPoint.AdjustY( -(basegfx::fround(aNewHomogenMatrix.get(1, 2))) );
2537 // tdf#117145 metric of SdrModel is app-specific, metric of UNO API is 100thmm
2538 // Need to adapt aVclPoint from app-specific to 100thmm
2539 ForceMetricTo100th_mm(aVclPoint);
2541 awt::Point aPnt( aVclPoint.X(), aVclPoint.Y() );
2542 rValue <<= aPnt;
2543 break;
2546 case OWN_ATTR_TRANSFORMATION:
2548 basegfx::B2DPolyPolygon aNewPolyPolygon;
2549 basegfx::B2DHomMatrix aNewHomogenMatrix;
2550 GetSdrObject()->TRGetBaseGeometry(aNewHomogenMatrix, aNewPolyPolygon);
2551 drawing::HomogenMatrix3 aMatrix;
2553 // tdf#117145 metric of SdrModel is app-specific, metric of UNO API is 100thmm
2554 // Need to adapt aNewHomogenMatrix from app-specific to 100thmm
2555 ForceMetricTo100th_mm(aNewHomogenMatrix);
2557 aMatrix.Line1.Column1 = aNewHomogenMatrix.get(0, 0);
2558 aMatrix.Line1.Column2 = aNewHomogenMatrix.get(0, 1);
2559 aMatrix.Line1.Column3 = aNewHomogenMatrix.get(0, 2);
2560 aMatrix.Line2.Column1 = aNewHomogenMatrix.get(1, 0);
2561 aMatrix.Line2.Column2 = aNewHomogenMatrix.get(1, 1);
2562 aMatrix.Line2.Column3 = aNewHomogenMatrix.get(1, 2);
2563 aMatrix.Line3.Column1 = 0;
2564 aMatrix.Line3.Column2 = 0;
2565 aMatrix.Line3.Column3 = 1;
2567 rValue <<= aMatrix;
2569 break;
2572 case OWN_ATTR_ZORDER:
2574 rValue <<= static_cast<sal_Int32>(GetSdrObject()->GetOrdNum());
2575 break;
2578 case OWN_ATTR_BITMAP:
2580 rValue = GetBitmap();
2581 if(!rValue.hasValue())
2582 throw uno::RuntimeException();
2584 break;
2587 case OWN_ATTR_ISFONTWORK:
2589 bool bIsFontwork = false;
2590 if (const SdrTextObj* pTextObj = DynCastSdrTextObj(GetSdrObject()))
2591 bIsFontwork = pTextObj->IsFontwork();
2592 rValue <<= bIsFontwork;
2593 break;
2596 case OWN_ATTR_FRAMERECT:
2598 tools::Rectangle aRect( GetSdrObject()->GetSnapRect() );
2599 Point aTopLeft( aRect.TopLeft() );
2600 Size aObjSize( aRect.GetWidth(), aRect.GetHeight() );
2601 ForceMetricTo100th_mm(aTopLeft);
2602 ForceMetricTo100th_mm(aObjSize);
2603 css::awt::Rectangle aUnoRect(
2604 aTopLeft.X(), aTopLeft.Y(),
2605 aObjSize.getWidth(), aObjSize.getHeight() );
2606 rValue <<= aUnoRect;
2607 break;
2610 case OWN_ATTR_BOUNDRECT:
2612 tools::Rectangle aRect( GetSdrObject()->GetCurrentBoundRect() );
2613 Point aTopLeft( aRect.TopLeft() );
2614 Size aObjSize( aRect.GetWidth(), aRect.GetHeight() );
2615 ForceMetricTo100th_mm(aTopLeft);
2616 ForceMetricTo100th_mm(aObjSize);
2617 css::awt::Rectangle aUnoRect(
2618 aTopLeft.X(), aTopLeft.Y(),
2619 aObjSize.getWidth(), aObjSize.getHeight() );
2620 rValue <<= aUnoRect;
2621 break;
2624 case OWN_ATTR_LDNAME:
2626 OUString aName( GetSdrObject()->GetName() );
2627 rValue <<= aName;
2628 break;
2631 case OWN_ATTR_LDBITMAP:
2633 OUString sId;
2634 if( GetSdrObject()->GetObjInventor() == SdrInventor::Default && GetSdrObject()->GetObjIdentifier() == SdrObjKind::OLE2 )
2636 sId = RID_UNODRAW_OLE2;
2638 else if( GetSdrObject()->GetObjInventor() == SdrInventor::Default && GetSdrObject()->GetObjIdentifier() == SdrObjKind::Graphic )
2640 sId = RID_UNODRAW_GRAPHICS;
2642 else
2644 sId = RID_UNODRAW_OBJECTS;
2647 BitmapEx aBmp(sId);
2648 Reference<awt::XBitmap> xBmp(VCLUnoHelper::CreateBitmap(aBmp));
2650 rValue <<= xBmp;
2651 break;
2654 case OWN_ATTR_MIRRORED:
2656 bool bMirror = false;
2657 if( HasSdrObject() )
2658 if (auto pGrafObj = dynamic_cast<SdrGrafObj*>(GetSdrObject()) )
2659 bMirror = pGrafObj->IsMirrored();
2661 rValue <<= bMirror;
2662 break;
2665 case OWN_ATTR_EDGE_START_OBJ:
2666 case OWN_ATTR_EDGE_START_POS:
2667 case OWN_ATTR_EDGE_END_POS:
2668 case OWN_ATTR_EDGE_END_OBJ:
2669 case OWN_ATTR_GLUEID_HEAD:
2670 case OWN_ATTR_GLUEID_TAIL:
2671 case OWN_ATTR_EDGE_POLYPOLYGONBEZIER:
2673 SdrEdgeObj* pEdgeObj = dynamic_cast<SdrEdgeObj*>(GetSdrObject());
2674 if(pEdgeObj)
2676 switch(pProperty->nWID)
2678 case OWN_ATTR_EDGE_START_OBJ:
2679 case OWN_ATTR_EDGE_END_OBJ:
2681 SdrObject* pNode = pEdgeObj->GetConnectedNode(pProperty->nWID == OWN_ATTR_EDGE_START_OBJ);
2682 if(pNode)
2684 Reference< drawing::XShape > xShape( GetXShapeForSdrObject( pNode ) );
2685 if(xShape.is())
2686 rValue <<= xShape;
2689 break;
2692 case OWN_ATTR_EDGE_START_POS:
2693 case OWN_ATTR_EDGE_END_POS:
2695 Point aPoint( pEdgeObj->GetTailPoint( pProperty->nWID == OWN_ATTR_EDGE_START_POS ) );
2696 if( GetSdrObject()->getSdrModelFromSdrObject().IsWriter() )
2697 aPoint -= GetSdrObject()->GetAnchorPos();
2699 ForceMetricTo100th_mm( aPoint );
2700 awt::Point aUnoPoint( aPoint.X(), aPoint.Y() );
2702 rValue <<= aUnoPoint;
2703 break;
2705 case OWN_ATTR_GLUEID_HEAD:
2706 case OWN_ATTR_GLUEID_TAIL:
2708 rValue <<= pEdgeObj->getGluePointIndex( pProperty->nWID == OWN_ATTR_GLUEID_HEAD );
2709 break;
2711 case OWN_ATTR_EDGE_POLYPOLYGONBEZIER:
2713 basegfx::B2DPolyPolygon aPolyPoly( pEdgeObj->GetEdgeTrackPath() );
2714 if( GetSdrObject()->getSdrModelFromSdrObject().IsWriter() )
2716 Point aPoint( GetSdrObject()->GetAnchorPos() );
2717 aPolyPoly.transform(basegfx::utils::createTranslateB2DHomMatrix(-aPoint.X(), -aPoint.Y()));
2719 // Reintroduction of fix for issue #i59051# (#i108851#)
2720 ForceMetricTo100th_mm( aPolyPoly );
2721 drawing::PolyPolygonBezierCoords aRetval;
2722 basegfx::utils::B2DPolyPolygonToUnoPolyPolygonBezierCoords( aPolyPoly, aRetval);
2723 rValue <<= aRetval;
2724 break;
2728 break;
2731 case OWN_ATTR_MEASURE_START_POS:
2732 case OWN_ATTR_MEASURE_END_POS:
2734 SdrMeasureObj* pMeasureObj = dynamic_cast<SdrMeasureObj*>(GetSdrObject());
2735 if(pMeasureObj)
2737 Point aPoint( pMeasureObj->GetPoint( pProperty->nWID == OWN_ATTR_MEASURE_START_POS ? 0 : 1 ) );
2738 if( GetSdrObject()->getSdrModelFromSdrObject().IsWriter() )
2739 aPoint -= GetSdrObject()->GetAnchorPos();
2741 // Reintroduction of fix for issue #i59051# (#i108851#)
2742 ForceMetricTo100th_mm( aPoint );
2743 awt::Point aUnoPoint( aPoint.X(), aPoint.Y() );
2745 rValue <<= aUnoPoint;
2746 break;
2748 break;
2751 case OWN_ATTR_FILLBMP_MODE:
2753 const SfxItemSet& rObjItemSet = GetSdrObject()->GetMergedItemSet();
2755 if (rObjItemSet.Get(XATTR_FILLBMP_TILE).GetValue())
2757 rValue <<= drawing::BitmapMode_REPEAT;
2759 else if (rObjItemSet.Get(XATTR_FILLBMP_STRETCH).GetValue())
2761 rValue <<= drawing::BitmapMode_STRETCH;
2763 else
2765 rValue <<= drawing::BitmapMode_NO_REPEAT;
2767 break;
2769 case SDRATTR_LAYERID:
2770 rValue <<= GetSdrObject()->GetLayer().get();
2771 break;
2773 case SDRATTR_LAYERNAME:
2775 SdrLayer* pLayer = GetSdrObject()->getSdrModelFromSdrObject().GetLayerAdmin().GetLayerPerID(GetSdrObject()->GetLayer());
2776 if( pLayer )
2778 rValue <<= pLayer->GetName();
2780 break;
2783 case SDRATTR_ROTATEANGLE:
2784 rValue <<= static_cast<sal_Int32>(GetSdrObject()->GetRotateAngle());
2785 break;
2787 case SDRATTR_SHEARANGLE:
2788 rValue <<= static_cast<sal_Int32>(GetSdrObject()->GetShearAngle());
2789 break;
2791 case OWN_ATTR_INTEROPGRABBAG:
2793 GetSdrObject()->GetGrabBagItem(rValue);
2794 break;
2797 case SDRATTR_OBJMOVEPROTECT:
2798 rValue <<= GetSdrObject()->IsMoveProtect();
2799 break;
2801 case SDRATTR_OBJECTNAME:
2803 OUString aName( GetSdrObject()->GetName() );
2804 rValue <<= aName;
2805 break;
2808 // #i68101#
2809 case OWN_ATTR_MISC_OBJ_TITLE:
2811 OUString aTitle( GetSdrObject()->GetTitle() );
2812 rValue <<= aTitle;
2813 break;
2816 case OWN_ATTR_MISC_OBJ_DESCRIPTION:
2818 OUString aDescription( GetSdrObject()->GetDescription() );
2819 rValue <<= aDescription;
2820 break;
2823 case OWN_ATTR_MISC_OBJ_DECORATIVE:
2825 bool const isDecorative(GetSdrObject()->IsDecorative());
2826 rValue <<= isDecorative;
2827 break;
2830 case SDRATTR_OBJPRINTABLE:
2831 rValue <<= GetSdrObject()->IsPrintable();
2832 break;
2834 case SDRATTR_OBJVISIBLE:
2835 rValue <<= GetSdrObject()->IsVisible();
2836 break;
2838 case SDRATTR_OBJSIZEPROTECT:
2839 rValue <<= GetSdrObject()->IsResizeProtect();
2840 break;
2842 case OWN_ATTR_PAGE_NUMBER:
2844 SdrPageObj* pPageObj = dynamic_cast<SdrPageObj*>(GetSdrObject());
2845 if(pPageObj)
2847 SdrPage* pPage = pPageObj->GetReferencedPage();
2848 sal_Int32 nPageNumber = pPage ? pPage->GetPageNum() : 0;
2849 nPageNumber++;
2850 nPageNumber >>= 1;
2851 rValue <<= nPageNumber;
2853 break;
2856 case OWN_ATTR_UINAME_SINGULAR:
2858 rValue <<= GetSdrObject()->TakeObjNameSingul();
2859 break;
2862 case OWN_ATTR_TEXTFITTOSIZESCALE:
2864 double nScale = GetTextFitToSizeScale(GetSdrObject());
2865 rValue <<= nScale;
2866 break;
2869 case OWN_ATTR_UINAME_PLURAL:
2871 rValue <<= GetSdrObject()->TakeObjNamePlural();
2872 break;
2874 case OWN_ATTR_METAFILE:
2876 SdrOle2Obj* pObj = dynamic_cast<SdrOle2Obj*>(GetSdrObject());
2877 if( pObj )
2879 const Graphic* pGraphic = pObj->GetGraphic();
2880 if( pGraphic )
2882 bool bIsWMF = false;
2883 if ( pGraphic->IsGfxLink() )
2885 GfxLink aLnk = pGraphic->GetGfxLink();
2886 if ( aLnk.GetType() == GfxLinkType::NativeWmf )
2888 bIsWMF = true;
2889 uno::Sequence<sal_Int8> aSeq(reinterpret_cast<sal_Int8 const *>(aLnk.GetData()), static_cast<sal_Int32>(aLnk.GetDataSize()));
2890 rValue <<= aSeq;
2893 if ( !bIsWMF )
2895 // #119735# just use GetGDIMetaFile, it will create a buffered version of contained bitmap now automatically
2896 GDIMetaFile aMtf(pObj->GetGraphic()->GetGDIMetaFile());
2897 SvMemoryStream aDestStrm( 65535, 65535 );
2898 ConvertGDIMetaFileToWMF( aMtf, aDestStrm, nullptr, false );
2899 const uno::Sequence<sal_Int8> aSeq(
2900 static_cast< const sal_Int8* >(aDestStrm.GetData()),
2901 aDestStrm.GetEndOfData());
2902 rValue <<= aSeq;
2906 else
2908 rValue = GetBitmap( true );
2910 break;
2913 case OWN_ATTR_TEXTCOLUMNS:
2915 if (auto pTextObj = DynCastSdrTextObj(GetSdrObject()))
2917 if (pTextObj->HasTextColumnsNumber() || pTextObj->HasTextColumnsSpacing())
2919 auto xIf = SvxXTextColumns_createInstance();
2920 css::uno::Reference<css::text::XTextColumns> xCols(xIf, css::uno::UNO_QUERY_THROW);
2921 xCols->setColumnCount(pTextObj->GetTextColumnsNumber());
2922 css::uno::Reference<css::beans::XPropertySet> xProp(xIf, css::uno::UNO_QUERY_THROW);
2923 xProp->setPropertyValue("AutomaticDistance",
2924 css::uno::Any(pTextObj->GetTextColumnsSpacing()));
2925 rValue <<= xIf;
2928 break;
2931 case OWN_ATTR_HYPERLINK:
2933 rValue <<= GetSdrObject()->getHyperlink();
2934 break;
2937 default:
2938 return false;
2940 return true;
2944 bool SvxShape::getPropertyStateImpl( const SfxItemPropertyMapEntry* pProperty, css::beans::PropertyState& rState )
2946 if( pProperty->nWID == OWN_ATTR_FILLBMP_MODE )
2948 const SfxItemSet& rSet = GetSdrObject()->GetMergedItemSet();
2950 if( rSet.GetItemState( XATTR_FILLBMP_STRETCH, false ) == SfxItemState::SET ||
2951 rSet.GetItemState( XATTR_FILLBMP_TILE, false ) == SfxItemState::SET )
2953 rState = beans::PropertyState_DIRECT_VALUE;
2955 else
2957 rState = beans::PropertyState_AMBIGUOUS_VALUE;
2960 else if((( pProperty->nWID >= OWN_ATTR_VALUE_START && pProperty->nWID <= OWN_ATTR_VALUE_END ) ||
2961 ( pProperty->nWID >= SDRATTR_NOTPERSIST_FIRST && pProperty->nWID <= SDRATTR_NOTPERSIST_LAST )) && ( pProperty->nWID != SDRATTR_TEXTDIRECTION ) )
2963 rState = beans::PropertyState_DIRECT_VALUE;
2965 else
2967 return false;
2970 return true;
2974 bool SvxShape::setPropertyToDefaultImpl( const SfxItemPropertyMapEntry* pProperty )
2976 if( pProperty->nWID == OWN_ATTR_FILLBMP_MODE )
2978 GetSdrObject()->ClearMergedItem( XATTR_FILLBMP_STRETCH );
2979 GetSdrObject()->ClearMergedItem( XATTR_FILLBMP_TILE );
2980 return true;
2982 else if((pProperty->nWID >= OWN_ATTR_VALUE_START && pProperty->nWID <= OWN_ATTR_VALUE_END ) ||
2983 ( pProperty->nWID >= SDRATTR_NOTPERSIST_FIRST && pProperty->nWID <= SDRATTR_NOTPERSIST_LAST ))
2985 return true;
2987 else
2989 return false;
2994 uno::Sequence< beans::PropertyState > SAL_CALL SvxShape::getPropertyStates( const uno::Sequence< OUString >& aPropertyName )
2996 const sal_Int32 nCount = aPropertyName.getLength();
2997 uno::Sequence< beans::PropertyState > aRet( nCount );
2999 std::transform(aPropertyName.begin(), aPropertyName.end(), aRet.getArray(),
3000 [this](const OUString& rName) -> beans::PropertyState { return getPropertyState(rName); });
3002 return aRet;
3006 void SAL_CALL SvxShape::setPropertyToDefault( const OUString& PropertyName )
3008 if( mpImpl->mpMaster )
3010 mpImpl->mpMaster->setPropertyToDefault( PropertyName );
3012 else
3014 _setPropertyToDefault( PropertyName );
3018 void SvxShape::_setPropertyToDefault( const OUString& PropertyName )
3020 ::SolarMutexGuard aGuard;
3022 const SfxItemPropertyMapEntry* pProperty = mpPropSet->getPropertyMapEntry(PropertyName);
3024 if( !HasSdrObject() || pProperty == nullptr )
3025 throw beans::UnknownPropertyException( PropertyName, getXWeak());
3027 if( !setPropertyToDefaultImpl( pProperty ) )
3029 GetSdrObject()->ClearMergedItem( pProperty->nWID );
3032 GetSdrObject()->getSdrModelFromSdrObject().SetChanged();
3036 uno::Any SAL_CALL SvxShape::getPropertyDefault( const OUString& aPropertyName )
3038 if( mpImpl->mpMaster )
3040 return mpImpl->mpMaster->getPropertyDefault( aPropertyName );
3042 else
3044 return _getPropertyDefault( aPropertyName );
3048 uno::Any SvxShape::_getPropertyDefault( const OUString& aPropertyName )
3050 ::SolarMutexGuard aGuard;
3052 const SfxItemPropertyMapEntry* pMap = mpPropSet->getPropertyMapEntry(aPropertyName);
3054 if( !HasSdrObject() || pMap == nullptr )
3055 throw beans::UnknownPropertyException( aPropertyName, getXWeak());
3057 if(( pMap->nWID >= OWN_ATTR_VALUE_START && pMap->nWID <= OWN_ATTR_VALUE_END ) ||
3058 ( pMap->nWID >= SDRATTR_NOTPERSIST_FIRST && pMap->nWID <= SDRATTR_NOTPERSIST_LAST ))
3060 return getPropertyValue( aPropertyName );
3063 // get default from ItemPool
3064 if(!SfxItemPool::IsWhich(pMap->nWID))
3065 throw beans::UnknownPropertyException( "No WhichID " + OUString::number(pMap->nWID) + " for " + aPropertyName, getXWeak());
3067 SfxItemSet aSet( GetSdrObject()->getSdrModelFromSdrObject().GetItemPool(), pMap->nWID, pMap->nWID );
3068 aSet.Put(GetSdrObject()->getSdrModelFromSdrObject().GetItemPool().GetDefaultItem(pMap->nWID));
3070 return GetAnyForItem( aSet, pMap );
3073 // XMultiPropertyStates
3074 void SvxShape::setAllPropertiesToDefault()
3076 ::SolarMutexGuard aGuard;
3078 SdrObject* pSdrObj = GetSdrObject();
3079 if( !pSdrObj )
3080 throw lang::DisposedException();
3081 pSdrObj->ClearMergedItem(); // nWhich == 0 => all
3083 const SdrObjKind nObjId = pSdrObj->GetObjIdentifier();
3084 if(nObjId == SdrObjKind::Graphic) // SdrGrafObj
3086 // defaults for graphic objects have changed:
3087 pSdrObj->SetMergedItem( XFillStyleItem( drawing::FillStyle_NONE ) );
3088 pSdrObj->SetMergedItem( XLineStyleItem( drawing::LineStyle_NONE ) );
3091 // #i68523# special handling for Svx3DCharacterModeItem, this is not saved
3092 // but needs to be sal_True in svx, pool default (false) in sch. Since sch
3093 // does not load lathe or extrude objects, it is possible to set the items
3094 // here.
3095 // For other solution possibilities, see task description.
3096 if( nObjId == SdrObjKind::E3D_Lathe /*E3dLatheObj*/ || nObjId == SdrObjKind::E3D_Extrusion /*E3dExtrudeObj*/ )
3098 pSdrObj->SetMergedItem(Svx3DCharacterModeItem(true));
3101 pSdrObj->getSdrModelFromSdrObject().SetChanged();
3104 void SvxShape::setPropertiesToDefault(
3105 const uno::Sequence<OUString>& aPropertyNames )
3107 for ( const auto& rPropertyName : aPropertyNames )
3108 setPropertyToDefault( rPropertyName );
3111 uno::Sequence<uno::Any> SvxShape::getPropertyDefaults(
3112 const uno::Sequence<OUString>& aPropertyNames )
3114 ::std::vector<uno::Any> ret;
3115 ret.reserve(aPropertyNames.getLength());
3116 std::transform(aPropertyNames.begin(), aPropertyNames.end(), std::back_inserter(ret),
3117 [this](const OUString& rName) -> uno::Any { return getPropertyDefault(rName); });
3118 return uno::Sequence<uno::Any>( ret.data(), ret.size() );
3122 // XServiceInfo
3124 OUString SAL_CALL SvxShape::getImplementationName()
3126 return "SvxShape";
3129 constexpr OUString sUNO_service_style_ParagraphProperties = u"com.sun.star.style.ParagraphProperties"_ustr;
3130 constexpr OUString sUNO_service_style_ParagraphPropertiesComplex = u"com.sun.star.style.ParagraphPropertiesComplex"_ustr;
3131 constexpr OUString sUNO_service_style_ParagraphPropertiesAsian = u"com.sun.star.style.ParagraphPropertiesAsian"_ustr;
3132 constexpr OUString sUNO_service_style_CharacterProperties = u"com.sun.star.style.CharacterProperties"_ustr;
3133 constexpr OUString sUNO_service_style_CharacterPropertiesComplex = u"com.sun.star.style.CharacterPropertiesComplex"_ustr;
3134 constexpr OUString sUNO_service_style_CharacterPropertiesAsian = u"com.sun.star.style.CharacterPropertiesAsian"_ustr;
3136 constexpr OUString sUNO_service_drawing_FillProperties = u"com.sun.star.drawing.FillProperties"_ustr;
3137 constexpr OUString sUNO_service_drawing_TextProperties = u"com.sun.star.drawing.TextProperties"_ustr;
3138 constexpr OUString sUNO_service_drawing_LineProperties = u"com.sun.star.drawing.LineProperties"_ustr;
3139 constexpr OUString sUNO_service_drawing_ConnectorProperties = u"com.sun.star.drawing.ConnectorProperties"_ustr;
3140 constexpr OUString sUNO_service_drawing_MeasureProperties = u"com.sun.star.drawing.MeasureProperties"_ustr;
3141 constexpr OUString sUNO_service_drawing_ShadowProperties = u"com.sun.star.drawing.ShadowProperties"_ustr;
3143 constexpr OUString sUNO_service_drawing_RotationDescriptor = u"com.sun.star.drawing.RotationDescriptor"_ustr;
3145 constexpr OUString sUNO_service_drawing_Text = u"com.sun.star.drawing.Text"_ustr;
3146 constexpr OUString sUNO_service_drawing_GroupShape = u"com.sun.star.drawing.GroupShape"_ustr;
3148 constexpr OUString sUNO_service_drawing_CustomShapeProperties = u"com.sun.star.drawing.CustomShapeProperties"_ustr;
3149 constexpr OUString sUNO_service_drawing_CustomShape = u"com.sun.star.drawing.CustomShape"_ustr;
3151 constexpr OUString sUNO_service_drawing_PolyPolygonDescriptor = u"com.sun.star.drawing.PolyPolygonDescriptor"_ustr;
3152 constexpr OUString sUNO_service_drawing_PolyPolygonBezierDescriptor= u"com.sun.star.drawing.PolyPolygonBezierDescriptor"_ustr;
3154 constexpr OUString sUNO_service_drawing_LineShape = u"com.sun.star.drawing.LineShape"_ustr;
3155 constexpr OUString sUNO_service_drawing_Shape = u"com.sun.star.drawing.Shape"_ustr;
3156 constexpr OUString sUNO_service_drawing_RectangleShape = u"com.sun.star.drawing.RectangleShape"_ustr;
3157 constexpr OUString sUNO_service_drawing_EllipseShape = u"com.sun.star.drawing.EllipseShape"_ustr;
3158 constexpr OUString sUNO_service_drawing_PolyPolygonShape = u"com.sun.star.drawing.PolyPolygonShape"_ustr;
3159 constexpr OUString sUNO_service_drawing_PolyLineShape = u"com.sun.star.drawing.PolyLineShape"_ustr;
3160 constexpr OUString sUNO_service_drawing_OpenBezierShape = u"com.sun.star.drawing.OpenBezierShape"_ustr;
3161 constexpr OUString sUNO_service_drawing_ClosedBezierShape = u"com.sun.star.drawing.ClosedBezierShape"_ustr;
3162 constexpr OUString sUNO_service_drawing_TextShape = u"com.sun.star.drawing.TextShape"_ustr;
3163 constexpr OUString sUNO_service_drawing_GraphicObjectShape = u"com.sun.star.drawing.GraphicObjectShape"_ustr;
3164 constexpr OUString sUNO_service_drawing_OLE2Shape = u"com.sun.star.drawing.OLE2Shape"_ustr;
3165 constexpr OUString sUNO_service_drawing_PageShape = u"com.sun.star.drawing.PageShape"_ustr;
3166 constexpr OUString sUNO_service_drawing_CaptionShape = u"com.sun.star.drawing.CaptionShape"_ustr;
3167 constexpr OUString sUNO_service_drawing_MeasureShape = u"com.sun.star.drawing.MeasureShape"_ustr;
3168 constexpr OUString sUNO_service_drawing_FrameShape = u"com.sun.star.drawing.FrameShape"_ustr;
3169 constexpr OUString sUNO_service_drawing_ControlShape = u"com.sun.star.drawing.ControlShape"_ustr;
3170 constexpr OUString sUNO_service_drawing_ConnectorShape = u"com.sun.star.drawing.ConnectorShape"_ustr;
3171 constexpr OUString sUNO_service_drawing_MediaShape = u"com.sun.star.drawing.MediaShape"_ustr;
3174 uno::Sequence< OUString > SAL_CALL SvxShape::getSupportedServiceNames()
3176 if( mpImpl->mpMaster )
3178 return mpImpl->mpMaster->getSupportedServiceNames();
3180 else
3182 return _getSupportedServiceNames();
3186 uno::Sequence< OUString > SvxShape::_getSupportedServiceNames()
3188 ::SolarMutexGuard aGuard;
3190 if( HasSdrObject() && GetSdrObject()->GetObjInventor() == SdrInventor::Default)
3192 const SdrObjKind nIdent = GetSdrObject()->GetObjIdentifier();
3194 switch(nIdent)
3196 case SdrObjKind::Group:
3198 static const uno::Sequence<OUString> aSvxShape_GroupServices
3199 = { sUNO_service_drawing_GroupShape,
3200 sUNO_service_drawing_Shape };
3201 return aSvxShape_GroupServices;
3203 case SdrObjKind::CustomShape:
3205 static const uno::Sequence<OUString> aSvxShape_CustomShapeServices
3206 = { sUNO_service_drawing_CustomShape,
3207 sUNO_service_drawing_Shape,
3208 sUNO_service_drawing_CustomShapeProperties,
3209 sUNO_service_drawing_FillProperties,
3210 sUNO_service_drawing_LineProperties,
3211 sUNO_service_drawing_Text,
3212 sUNO_service_drawing_TextProperties,
3213 sUNO_service_style_ParagraphProperties,
3214 sUNO_service_style_ParagraphPropertiesComplex,
3215 sUNO_service_style_ParagraphPropertiesAsian,
3216 sUNO_service_style_CharacterProperties,
3217 sUNO_service_style_CharacterPropertiesComplex,
3218 sUNO_service_style_CharacterPropertiesAsian,
3219 sUNO_service_drawing_ShadowProperties,
3220 sUNO_service_drawing_RotationDescriptor };
3221 return aSvxShape_CustomShapeServices;
3223 case SdrObjKind::Line:
3225 static const uno::Sequence<OUString> aSvxShape_LineServices
3226 = { sUNO_service_drawing_LineShape,
3228 sUNO_service_drawing_Shape,
3229 sUNO_service_drawing_LineProperties,
3231 sUNO_service_drawing_Text,
3232 sUNO_service_drawing_TextProperties,
3233 sUNO_service_style_ParagraphProperties,
3234 sUNO_service_style_ParagraphPropertiesComplex,
3235 sUNO_service_style_ParagraphPropertiesAsian,
3236 sUNO_service_style_CharacterProperties,
3237 sUNO_service_style_CharacterPropertiesComplex,
3238 sUNO_service_style_CharacterPropertiesAsian,
3240 sUNO_service_drawing_PolyPolygonDescriptor,
3241 sUNO_service_drawing_ShadowProperties,
3242 sUNO_service_drawing_RotationDescriptor };
3243 return aSvxShape_LineServices;
3246 case SdrObjKind::Rectangle:
3248 static const uno::Sequence<OUString> aSvxShape_RectServices
3249 = { sUNO_service_drawing_RectangleShape,
3251 sUNO_service_drawing_Shape,
3252 sUNO_service_drawing_FillProperties,
3253 sUNO_service_drawing_LineProperties,
3254 sUNO_service_drawing_Text,
3255 sUNO_service_drawing_TextProperties,
3256 sUNO_service_style_ParagraphProperties,
3257 sUNO_service_style_ParagraphPropertiesComplex,
3258 sUNO_service_style_ParagraphPropertiesAsian,
3259 sUNO_service_style_CharacterProperties,
3260 sUNO_service_style_CharacterPropertiesComplex,
3261 sUNO_service_style_CharacterPropertiesAsian,
3263 sUNO_service_drawing_ShadowProperties,
3264 sUNO_service_drawing_RotationDescriptor };
3265 return aSvxShape_RectServices;
3268 case SdrObjKind::CircleOrEllipse:
3269 case SdrObjKind::CircleSection:
3270 case SdrObjKind::CircleArc:
3271 case SdrObjKind::CircleCut:
3273 static const uno::Sequence<OUString> aSvxShape_CircServices
3274 = { sUNO_service_drawing_EllipseShape,
3276 sUNO_service_drawing_Shape,
3277 sUNO_service_drawing_FillProperties,
3278 sUNO_service_drawing_LineProperties,
3280 sUNO_service_drawing_Text,
3281 sUNO_service_drawing_TextProperties,
3282 sUNO_service_style_ParagraphProperties,
3283 sUNO_service_style_ParagraphPropertiesComplex,
3284 sUNO_service_style_ParagraphPropertiesAsian,
3285 sUNO_service_style_CharacterProperties,
3286 sUNO_service_style_CharacterPropertiesComplex,
3287 sUNO_service_style_CharacterPropertiesAsian,
3289 sUNO_service_drawing_ShadowProperties,
3290 sUNO_service_drawing_RotationDescriptor };
3291 return aSvxShape_CircServices;
3294 case SdrObjKind::PathPolyLine:
3295 case SdrObjKind::PolyLine:
3297 static const uno::Sequence<OUString> aSvxShape_PathServices
3298 = { sUNO_service_drawing_PolyLineShape,
3300 sUNO_service_drawing_Shape,
3301 sUNO_service_drawing_LineProperties,
3303 sUNO_service_drawing_PolyPolygonDescriptor,
3305 sUNO_service_drawing_Text,
3306 sUNO_service_drawing_TextProperties,
3307 sUNO_service_style_ParagraphProperties,
3308 sUNO_service_style_ParagraphPropertiesComplex,
3309 sUNO_service_style_ParagraphPropertiesAsian,
3310 sUNO_service_style_CharacterProperties,
3311 sUNO_service_style_CharacterPropertiesComplex,
3312 sUNO_service_style_CharacterPropertiesAsian,
3314 sUNO_service_drawing_ShadowProperties,
3315 sUNO_service_drawing_RotationDescriptor };
3316 return aSvxShape_PathServices;
3319 case SdrObjKind::PathPoly:
3320 case SdrObjKind::Polygon:
3322 static const uno::Sequence<OUString> aSvxShape_PolyServices
3323 = { sUNO_service_drawing_PolyPolygonShape,
3325 sUNO_service_drawing_Shape,
3326 sUNO_service_drawing_LineProperties,
3327 sUNO_service_drawing_FillProperties,
3329 sUNO_service_drawing_PolyPolygonDescriptor,
3331 sUNO_service_drawing_Text,
3332 sUNO_service_drawing_TextProperties,
3333 sUNO_service_style_ParagraphProperties,
3334 sUNO_service_style_ParagraphPropertiesComplex,
3335 sUNO_service_style_ParagraphPropertiesAsian,
3336 sUNO_service_style_CharacterProperties,
3337 sUNO_service_style_CharacterPropertiesComplex,
3338 sUNO_service_style_CharacterPropertiesAsian,
3340 sUNO_service_drawing_ShadowProperties,
3341 sUNO_service_drawing_RotationDescriptor };
3342 return aSvxShape_PolyServices;
3345 case SdrObjKind::FreehandLine:
3346 case SdrObjKind::PathLine:
3348 static const uno::Sequence<OUString> aSvxShape_FreeLineServices
3349 = { sUNO_service_drawing_OpenBezierShape,
3351 sUNO_service_drawing_Shape,
3352 sUNO_service_drawing_LineProperties,
3353 sUNO_service_drawing_FillProperties,
3355 sUNO_service_drawing_PolyPolygonBezierDescriptor,
3357 sUNO_service_drawing_Text,
3358 sUNO_service_drawing_TextProperties,
3359 sUNO_service_style_ParagraphProperties,
3360 sUNO_service_style_ParagraphPropertiesComplex,
3361 sUNO_service_style_ParagraphPropertiesAsian,
3362 sUNO_service_style_CharacterProperties,
3363 sUNO_service_style_CharacterPropertiesComplex,
3364 sUNO_service_style_CharacterPropertiesAsian,
3366 sUNO_service_drawing_ShadowProperties,
3367 sUNO_service_drawing_RotationDescriptor };
3368 return aSvxShape_FreeLineServices;
3371 case SdrObjKind::FreehandFill:
3372 case SdrObjKind::PathFill:
3374 static const uno::Sequence<OUString> aSvxShape_FreeFillServices
3375 = { sUNO_service_drawing_ClosedBezierShape,
3377 sUNO_service_drawing_Shape,
3378 sUNO_service_drawing_LineProperties,
3379 sUNO_service_drawing_FillProperties,
3381 sUNO_service_drawing_PolyPolygonBezierDescriptor,
3383 sUNO_service_drawing_Text,
3384 sUNO_service_drawing_TextProperties,
3385 sUNO_service_style_ParagraphProperties,
3386 sUNO_service_style_ParagraphPropertiesComplex,
3387 sUNO_service_style_ParagraphPropertiesAsian,
3388 sUNO_service_style_CharacterProperties,
3389 sUNO_service_style_CharacterPropertiesComplex,
3390 sUNO_service_style_CharacterPropertiesAsian,
3392 sUNO_service_drawing_ShadowProperties,
3393 sUNO_service_drawing_RotationDescriptor };
3394 return aSvxShape_FreeFillServices;
3397 case SdrObjKind::OutlineText:
3398 case SdrObjKind::TitleText:
3399 case SdrObjKind::Text:
3401 static const uno::Sequence<OUString> aSvxShape_TextServices
3402 = { sUNO_service_drawing_TextShape,
3404 sUNO_service_drawing_Shape,
3405 sUNO_service_drawing_FillProperties,
3406 sUNO_service_drawing_LineProperties,
3408 sUNO_service_drawing_Text,
3409 sUNO_service_drawing_TextProperties,
3410 sUNO_service_style_ParagraphProperties,
3411 sUNO_service_style_ParagraphPropertiesComplex,
3412 sUNO_service_style_ParagraphPropertiesAsian,
3413 sUNO_service_style_CharacterProperties,
3414 sUNO_service_style_CharacterPropertiesComplex,
3415 sUNO_service_style_CharacterPropertiesAsian,
3417 sUNO_service_drawing_ShadowProperties,
3418 sUNO_service_drawing_RotationDescriptor };
3419 return aSvxShape_TextServices;
3422 case SdrObjKind::Graphic:
3424 static const uno::Sequence<OUString> aSvxShape_GrafServices
3425 = { sUNO_service_drawing_GraphicObjectShape,
3427 sUNO_service_drawing_Shape,
3429 sUNO_service_drawing_Text,
3430 sUNO_service_drawing_TextProperties,
3431 sUNO_service_style_ParagraphProperties,
3432 sUNO_service_style_ParagraphPropertiesComplex,
3433 sUNO_service_style_ParagraphPropertiesAsian,
3434 sUNO_service_style_CharacterProperties,
3435 sUNO_service_style_CharacterPropertiesComplex,
3436 sUNO_service_style_CharacterPropertiesAsian,
3438 sUNO_service_drawing_ShadowProperties,
3439 sUNO_service_drawing_RotationDescriptor};
3440 return aSvxShape_GrafServices;
3443 case SdrObjKind::OLE2:
3445 static const uno::Sequence<OUString> aSvxShape_Ole2Services
3446 = { sUNO_service_drawing_OLE2Shape,
3447 sUNO_service_drawing_Shape,
3449 // #i118485# Added Text, Shadow and Rotation
3450 sUNO_service_drawing_Text,
3451 sUNO_service_drawing_TextProperties,
3452 sUNO_service_style_ParagraphProperties,
3453 sUNO_service_style_ParagraphPropertiesComplex,
3454 sUNO_service_style_ParagraphPropertiesAsian,
3455 sUNO_service_style_CharacterProperties,
3456 sUNO_service_style_CharacterPropertiesComplex,
3457 sUNO_service_style_CharacterPropertiesAsian,
3459 sUNO_service_drawing_ShadowProperties,
3460 sUNO_service_drawing_RotationDescriptor };
3461 return aSvxShape_Ole2Services;
3464 case SdrObjKind::Caption:
3466 static const uno::Sequence<OUString> aSvxShape_CaptionServices
3467 = { sUNO_service_drawing_CaptionShape,
3469 sUNO_service_drawing_Shape,
3470 sUNO_service_drawing_FillProperties,
3471 sUNO_service_drawing_LineProperties,
3473 sUNO_service_drawing_Text,
3474 sUNO_service_drawing_TextProperties,
3475 sUNO_service_style_ParagraphProperties,
3476 sUNO_service_style_ParagraphPropertiesComplex,
3477 sUNO_service_style_ParagraphPropertiesAsian,
3478 sUNO_service_style_CharacterProperties,
3479 sUNO_service_style_CharacterPropertiesComplex,
3480 sUNO_service_style_CharacterPropertiesAsian,
3482 sUNO_service_drawing_ShadowProperties,
3483 sUNO_service_drawing_RotationDescriptor };
3484 return aSvxShape_CaptionServices;
3487 case SdrObjKind::Page:
3489 static const uno::Sequence<OUString> aSvxShape_PageServices
3490 = { sUNO_service_drawing_PageShape,
3491 sUNO_service_drawing_Shape };
3492 return aSvxShape_PageServices;
3495 case SdrObjKind::Measure:
3497 static const uno::Sequence<OUString> aSvxShape_MeasureServices
3498 = { sUNO_service_drawing_MeasureShape,
3500 sUNO_service_drawing_MeasureProperties,
3502 sUNO_service_drawing_Shape,
3503 sUNO_service_drawing_LineProperties,
3505 sUNO_service_drawing_Text,
3506 sUNO_service_drawing_TextProperties,
3507 sUNO_service_style_ParagraphProperties,
3508 sUNO_service_style_ParagraphPropertiesComplex,
3509 sUNO_service_style_ParagraphPropertiesAsian,
3510 sUNO_service_style_CharacterProperties,
3511 sUNO_service_style_CharacterPropertiesComplex,
3512 sUNO_service_style_CharacterPropertiesAsian,
3514 sUNO_service_drawing_PolyPolygonDescriptor,
3515 sUNO_service_drawing_ShadowProperties,
3516 sUNO_service_drawing_RotationDescriptor };
3517 return aSvxShape_MeasureServices;
3520 case SdrObjKind::OLEPluginFrame:
3522 static const uno::Sequence<OUString> aSvxShape_FrameServices
3523 = { sUNO_service_drawing_FrameShape,
3524 sUNO_service_drawing_Shape };
3525 return aSvxShape_FrameServices;
3528 case SdrObjKind::UNO:
3530 static const uno::Sequence<OUString> aSvxShape_UnoServices
3531 = { sUNO_service_drawing_ControlShape,
3532 sUNO_service_drawing_Shape };
3533 return aSvxShape_UnoServices;
3536 case SdrObjKind::Edge:
3538 static const uno::Sequence<OUString> aSvxShape_EdgeServices
3539 = { sUNO_service_drawing_ConnectorShape,
3540 sUNO_service_drawing_ConnectorProperties,
3542 sUNO_service_drawing_Shape,
3543 sUNO_service_drawing_LineProperties,
3545 sUNO_service_drawing_Text,
3546 sUNO_service_drawing_TextProperties,
3547 sUNO_service_style_ParagraphProperties,
3548 sUNO_service_style_ParagraphPropertiesComplex,
3549 sUNO_service_style_ParagraphPropertiesAsian,
3550 sUNO_service_style_CharacterProperties,
3551 sUNO_service_style_CharacterPropertiesComplex,
3552 sUNO_service_style_CharacterPropertiesAsian,
3554 sUNO_service_drawing_PolyPolygonDescriptor,
3555 sUNO_service_drawing_ShadowProperties,
3556 sUNO_service_drawing_RotationDescriptor };
3557 return aSvxShape_EdgeServices;
3559 case SdrObjKind::Media:
3561 static const uno::Sequence<OUString> aSvxShape_MediaServices
3562 = { sUNO_service_drawing_MediaShape,
3563 sUNO_service_drawing_Shape };
3564 return aSvxShape_MediaServices;
3566 default: ;
3569 else if( HasSdrObject() && GetSdrObject()->GetObjInventor() == SdrInventor::FmForm)
3571 #if OSL_DEBUG_LEVEL > 0
3572 const SdrObjKind nIdent = GetSdrObject()->GetObjIdentifier();
3573 OSL_ENSURE( nIdent == SdrObjKind::UNO, "SvxShape::_getSupportedServiceNames: SdrInventor::FmForm, but no UNO object?" );
3574 #endif
3575 static const uno::Sequence<OUString> aSvxShape_UnoServices
3576 = { sUNO_service_drawing_ControlShape,
3577 sUNO_service_drawing_Shape };
3578 return aSvxShape_UnoServices;
3580 OSL_FAIL( "SvxShape::_getSupportedServiceNames: could not determine object type!" );
3581 uno::Sequence< OUString > aSeq;
3582 return aSeq;
3585 sal_Bool SAL_CALL SvxShape::supportsService( const OUString& ServiceName )
3587 return cppu::supportsService(this, ServiceName);
3590 // XGluePointsSupplier
3591 uno::Reference< container::XIndexContainer > SAL_CALL SvxShape::getGluePoints()
3593 ::SolarMutexGuard aGuard;
3594 uno::Reference< container::XIndexContainer > xGluePoints( mxGluePoints );
3596 if( HasSdrObject() && !xGluePoints.is() )
3598 uno::Reference< container::XIndexContainer > xNew( SvxUnoGluePointAccess_createInstance( GetSdrObject() ), uno::UNO_QUERY );
3599 mxGluePoints = xGluePoints = xNew;
3602 return xGluePoints;
3605 // XChild
3606 uno::Reference<uno::XInterface> SAL_CALL SvxShape::getParent()
3608 ::SolarMutexGuard aGuard;
3609 const SdrObject* pSdrObject(GetSdrObject());
3611 if(nullptr != pSdrObject)
3613 const SdrObjList* pParentSdrObjList(GetSdrObject()->getParentSdrObjListFromSdrObject());
3615 if(nullptr != pParentSdrObjList)
3617 // SdrObject is member of a SdrObjList. That may be a SdrObject
3618 // (SdrObjGroup or E3dScene) or a SdrPage.
3619 // Check for SdrObject first - using getSdrPageFromSdrObjList
3620 // *will* get the SdrPage even when the SdrObject is deep buried
3621 // in a construct of SdrObjGroup.
3622 // We want to ask for the direct parent here...
3623 SdrObject* pParentSdrObject(pParentSdrObjList->getSdrObjectFromSdrObjList());
3625 if(nullptr != pParentSdrObject)
3627 // SdrObject is member of a SdrObject-based Group (SdrObjGroup or E3dScene).
3628 return pParentSdrObject->getUnoShape();
3630 else
3632 SdrPage* pParentSdrPage(pParentSdrObjList->getSdrPageFromSdrObjList());
3634 if(nullptr != pParentSdrPage)
3636 // SdrObject is inserted to a SdrPage. Since
3637 // we checked for getSdrObjectFromSdrObjList first,
3638 // we can even say that it is directly member of that
3639 // SdrPage.
3640 return pParentSdrPage->getUnoPage();
3644 // not member of any SdrObjList, no parent
3645 OSL_FAIL( "SvxShape::getParent( ): unexpected Parent SdrObjList" );
3649 // no SdrObject, no parent
3650 return uno::Reference<uno::XInterface>();
3653 void SAL_CALL SvxShape::setParent( const css::uno::Reference< css::uno::XInterface >& )
3655 throw lang::NoSupportException();
3659 /** called from the XActionLockable interface methods on initial locking */
3660 void SvxShape::lock()
3665 /** called from the XActionLockable interface methods on final unlock */
3666 void SvxShape::unlock()
3671 // XActionLockable
3672 sal_Bool SAL_CALL SvxShape::isActionLocked( )
3674 ::SolarMutexGuard aGuard;
3676 return mnLockCount != 0;
3680 void SAL_CALL SvxShape::addActionLock( )
3682 ::SolarMutexGuard aGuard;
3684 DBG_ASSERT( mnLockCount < 0xffff, "lock overflow in SvxShape!" );
3685 mnLockCount++;
3687 if( mnLockCount == 1 )
3688 lock();
3692 void SAL_CALL SvxShape::removeActionLock( )
3694 ::SolarMutexGuard aGuard;
3696 DBG_ASSERT( mnLockCount > 0, "lock underflow in SvxShape!" );
3697 mnLockCount--;
3699 if( mnLockCount == 0 )
3700 unlock();
3704 void SAL_CALL SvxShape::setActionLocks( sal_Int16 nLock )
3706 ::SolarMutexGuard aGuard;
3708 if( (mnLockCount == 0) && (nLock != 0) )
3709 unlock();
3711 if( (mnLockCount != 0) && (nLock == 0) )
3712 lock();
3714 mnLockCount = static_cast<sal_uInt16>(nLock);
3718 sal_Int16 SAL_CALL SvxShape::resetActionLocks( )
3720 ::SolarMutexGuard aGuard;
3722 if( mnLockCount != 0 )
3723 unlock();
3725 sal_Int16 nOldLocks = static_cast<sal_Int16>(mnLockCount);
3726 mnLockCount = 0;
3728 return nOldLocks;
3732 /** since polygon shapes can change their kind during editing, we have
3733 to recheck it here.
3734 Circle shapes also change their kind, but they are all treated equal
3735 so no update is necessary.
3737 void SvxShape::updateShapeKind()
3739 switch( mpImpl->mnObjId )
3741 case SdrObjKind::Line:
3742 case SdrObjKind::Polygon:
3743 case SdrObjKind::PolyLine:
3744 case SdrObjKind::PathLine:
3745 case SdrObjKind::PathFill:
3746 case SdrObjKind::FreehandLine:
3747 case SdrObjKind::FreehandFill:
3748 case SdrObjKind::PathPoly:
3749 case SdrObjKind::PathPolyLine:
3751 const SdrObjKind nId = GetSdrObject()->GetObjIdentifier();
3753 if( nId != mpImpl->mnObjId )
3755 mpImpl->mnObjId = nId;
3758 break;
3760 default: ;
3764 SvxShapeText::SvxShapeText(SdrObject* pObject)
3765 : SvxShape( pObject, getSvxMapProvider().GetMap(SVXMAP_TEXT), getSvxMapProvider().GetPropertySet(SVXMAP_TEXT, SdrObject::GetGlobalDrawObjectItemPool()) ), SvxUnoTextBase( ImplGetSvxUnoOutlinerTextCursorSvxPropertySet() )
3767 if( pObject )
3768 SetEditSource( new SvxTextEditSource( pObject, nullptr ) );
3772 SvxShapeText::SvxShapeText(SdrObject* pObject, std::span<const SfxItemPropertyMapEntry> pPropertyMap, const SvxItemPropertySet* pPropertySet)
3773 : SvxShape( pObject, pPropertyMap, pPropertySet ), SvxUnoTextBase( ImplGetSvxUnoOutlinerTextCursorSvxPropertySet() )
3775 if( pObject )
3776 SetEditSource( new SvxTextEditSource( pObject, nullptr ) );
3780 SvxShapeText::~SvxShapeText() noexcept
3782 // check if only this instance is registered at the ranges
3783 DBG_ASSERT( (nullptr == GetEditSource()) || (GetEditSource()->getRanges().size()==1),
3784 "svx::SvxShapeText::~SvxShapeText(), text shape with living text ranges destroyed!");
3787 void SvxShapeText::Create( SdrObject* pNewObj, SvxDrawPage* pNewPage )
3789 if( pNewObj && (nullptr == GetEditSource()))
3790 SetEditSource( new SvxTextEditSource( pNewObj, nullptr ) );
3791 SvxShape::Create( pNewObj, pNewPage );
3794 // XInterface
3796 uno::Any SAL_CALL SvxShapeText::queryInterface( const uno::Type & rType )
3798 return SvxShape::queryInterface( rType );
3802 uno::Any SAL_CALL SvxShapeText::queryAggregation( const uno::Type & rType )
3804 uno::Any aAny( SvxShape::queryAggregation( rType ) );
3805 if( aAny.hasValue() )
3806 return aAny;
3808 return SvxUnoTextBase::queryAggregation( rType );
3812 // XServiceInfo
3814 OUString SAL_CALL SvxShapeText::getImplementationName()
3816 return "SvxShapeText";
3820 uno::Sequence< OUString > SAL_CALL SvxShapeText::getSupportedServiceNames()
3822 return SvxShape::getSupportedServiceNames();
3826 sal_Bool SAL_CALL SvxShapeText::supportsService( const OUString& ServiceName )
3828 return cppu::supportsService(static_cast<SvxShape*>(this), ServiceName);
3831 // XTypeProvider
3833 uno::Sequence< uno::Type > SAL_CALL SvxShapeText::getTypes()
3835 return SvxShape::getTypes();
3838 sal_Int64 SAL_CALL SvxShapeText::getSomething( const css::uno::Sequence< sal_Int8 >& rId )
3840 const sal_Int64 nReturn = SvxShape::getSomething( rId );
3841 if( nReturn )
3842 return nReturn;
3844 return SvxUnoTextBase::getSomething( rId );
3848 uno::Sequence< sal_Int8 > SAL_CALL SvxShapeText::getImplementationId()
3850 return css::uno::Sequence<sal_Int8>();
3854 /** called from the XActionLockable interface methods on initial locking */
3855 void SvxShapeText::lock()
3857 SvxTextEditSource* pEditSource = static_cast<SvxTextEditSource*>(GetEditSource());
3858 if( pEditSource )
3859 pEditSource->lock();
3863 /** called from the XActionLockable interface methods on final unlock */
3864 void SvxShapeText::unlock()
3866 SvxTextEditSource* pEditSource = static_cast<SvxTextEditSource*>(GetEditSource());
3867 if( pEditSource )
3868 pEditSource->unlock();
3871 // css::text::XTextRange
3872 uno::Reference< text::XTextRange > SAL_CALL SvxShapeText::getStart()
3874 ::SolarMutexGuard aGuard;
3875 SvxTextForwarder* pForwarder = mpEditSource ? mpEditSource->GetTextForwarder() : nullptr;
3876 if( pForwarder )
3877 ::GetSelection( maSelection, pForwarder );
3878 return SvxUnoTextBase::getStart();
3882 uno::Reference< text::XTextRange > SAL_CALL SvxShapeText::getEnd()
3884 ::SolarMutexGuard aGuard;
3885 SvxTextForwarder* pForwarder = mpEditSource ? mpEditSource->GetTextForwarder() : nullptr;
3886 if( pForwarder )
3887 ::GetSelection( maSelection, pForwarder );
3888 return SvxUnoTextBase::getEnd();
3891 OUString SAL_CALL SvxShapeText::getString()
3893 ::SolarMutexGuard aGuard;
3894 SvxTextForwarder* pForwarder = mpEditSource ? mpEditSource->GetTextForwarder() : nullptr;
3895 if( pForwarder )
3896 ::GetSelection( maSelection, pForwarder );
3897 return SvxUnoTextBase::getString();
3901 void SAL_CALL SvxShapeText::setString( const OUString& aString )
3903 ::SolarMutexGuard aGuard;
3904 SvxTextForwarder* pForwarder = mpEditSource ? mpEditSource->GetTextForwarder() : nullptr;
3905 if( pForwarder )
3906 ::GetSelection( maSelection, pForwarder );
3907 SvxUnoTextBase::setString( aString );
3910 // override these for special property handling in subcasses. Return true if property is handled
3911 bool SvxShapeText::setPropertyValueImpl( const OUString& rName, const SfxItemPropertyMapEntry* pProperty, const css::uno::Any& rValue )
3913 // HACK-fix #99090#
3914 // since SdrTextObj::SetVerticalWriting exchanges
3915 // SDRATTR_TEXT_AUTOGROWWIDTH and SDRATTR_TEXT_AUTOGROWHEIGHT,
3916 // we have to set the textdirection here
3918 if( pProperty->nWID == SDRATTR_TEXTDIRECTION )
3920 SdrTextObj* pTextObj = DynCastSdrTextObj( GetSdrObject() );
3921 if( pTextObj )
3923 css::text::WritingMode eMode;
3924 if( rValue >>= eMode )
3926 pTextObj->SetVerticalWriting( eMode == css::text::WritingMode_TB_RL );
3929 return true;
3931 return SvxShape::setPropertyValueImpl( rName, pProperty, rValue );
3934 bool SvxShapeText::getPropertyValueImpl( const OUString& rName, const SfxItemPropertyMapEntry* pProperty, css::uno::Any& rValue )
3936 if( pProperty->nWID == SDRATTR_TEXTDIRECTION )
3938 SdrTextObj* pTextObj = DynCastSdrTextObj( GetSdrObject() );
3939 if( pTextObj && pTextObj->IsVerticalWriting() )
3940 rValue <<= css::text::WritingMode_TB_RL;
3941 else
3942 rValue <<= css::text::WritingMode_LR_TB;
3943 return true;
3946 return SvxShape::getPropertyValueImpl( rName, pProperty, rValue );
3949 bool SvxShapeText::getPropertyStateImpl( const SfxItemPropertyMapEntry* pProperty, css::beans::PropertyState& rState )
3951 return SvxShape::getPropertyStateImpl( pProperty, rState );
3954 bool SvxShapeText::setPropertyToDefaultImpl( const SfxItemPropertyMapEntry* pProperty )
3956 return SvxShape::setPropertyToDefaultImpl( pProperty );
3959 SvxShapeRect::SvxShapeRect(SdrObject* pObj)
3960 : SvxShapeText( pObj, getSvxMapProvider().GetMap(SVXMAP_SHAPE), getSvxMapProvider().GetPropertySet(SVXMAP_SHAPE, SdrObject::GetGlobalDrawObjectItemPool()))
3964 SvxShapeRect::~SvxShapeRect() noexcept
3968 uno::Any SAL_CALL SvxShapeRect::queryInterface( const uno::Type & rType )
3970 return SvxShapeText::queryInterface( rType );
3973 uno::Any SAL_CALL SvxShapeRect::queryAggregation( const uno::Type & rType )
3975 return SvxShapeText::queryAggregation( rType );
3978 // XServiceInfo
3980 uno::Sequence< OUString > SvxShapeRect::getSupportedServiceNames()
3982 return SvxShape::getSupportedServiceNames();
3985 /** returns a StarOffice API wrapper for the given SdrObject */
3986 uno::Reference< drawing::XShape > GetXShapeForSdrObject( SdrObject* pObj ) noexcept
3988 uno::Reference< drawing::XShape > xShape( pObj->getUnoShape(), uno::UNO_QUERY );
3989 return xShape;
3993 SdrObject* SdrObject::getSdrObjectFromXShape( const css::uno::Reference< css::uno::XInterface >& xInt )
3995 SvxShape* pSvxShape = comphelper::getFromUnoTunnel<SvxShape>( xInt );
3996 return pSvxShape ? pSvxShape->GetSdrObject() : nullptr;
3999 uno::Any SvxItemPropertySet_getPropertyValue( const SfxItemPropertyMapEntry* pMap, const SfxItemSet& rSet )
4001 if(!pMap || !pMap->nWID)
4002 return uno::Any();
4004 // Check is for items that store either metric values if they are positive or percentage if they are negative.
4005 bool bDontConvertNegativeValues = ( pMap->nWID == XATTR_FILLBMP_SIZEX || pMap->nWID == XATTR_FILLBMP_SIZEY );
4006 return SvxItemPropertySet::getPropertyValue( pMap, rSet, (pMap->nWID != SDRATTR_XMLATTRIBUTES), bDontConvertNegativeValues );
4009 void SvxItemPropertySet_setPropertyValue( const SfxItemPropertyMapEntry* pMap, const uno::Any& rVal, SfxItemSet& rSet )
4011 if(!pMap || !pMap->nWID)
4012 return;
4014 bool bDontConvertNegativeValues = ( pMap->nWID == XATTR_FILLBMP_SIZEX || pMap->nWID == XATTR_FILLBMP_SIZEY );
4015 SvxItemPropertySet::setPropertyValue( pMap, rVal, rSet, bDontConvertNegativeValues );
4018 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */