bump product version to 5.0.4.1
[LibreOffice.git] / svx / source / svdraw / svdobj.cxx
blobb6d382745d578bb0cd8f013385553b0932aae002
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 <svx/svdobj.hxx>
21 #include <config_features.h>
23 #include "sal/config.h"
25 #include <com/sun/star/lang/XComponent.hpp>
26 #include <com/sun/star/text/RelOrientation.hpp>
28 #include "svdconv.hxx"
30 #include <basegfx/matrix/b2dhommatrix.hxx>
31 #include <basegfx/matrix/b2dhommatrixtools.hxx>
32 #include <basegfx/polygon/b2dpolygon.hxx>
33 #include <basegfx/polygon/b2dpolygontools.hxx>
34 #include <basegfx/polygon/b2dpolypolygoncutter.hxx>
35 #include <basegfx/polygon/b2dpolypolygontools.hxx>
36 #include <basegfx/range/b2drange.hxx>
37 #include <drawinglayer/processor2d/contourextractor2d.hxx>
38 #include <drawinglayer/processor2d/linegeometryextractor2d.hxx>
39 #include <editeng/editeng.hxx>
40 #include <editeng/eeitem.hxx>
41 #include <editeng/outlobj.hxx>
42 #include <math.h>
43 #include <sfx2/objface.hxx>
44 #include <sfx2/objsh.hxx>
45 #include <svl/whiter.hxx>
46 #include <svl/grabbagitem.hxx>
47 #include <svtools/colorcfg.hxx>
48 #include <tools/bigint.hxx>
49 #include <tools/diagnose_ex.h>
50 #include <tools/helpers.hxx>
51 #include <tools/line.hxx>
52 #include <vcl/graphictools.hxx>
53 #include <vcl/metaact.hxx>
54 #include <vcl/virdev.hxx>
55 #include <vector>
57 #include "svx/shapepropertynotifier.hxx"
58 #include "svdglob.hxx"
59 #include "svx/svdotable.hxx"
60 #include "svx/xlinjoit.hxx"
62 #include <svx/fmmodel.hxx>
63 #include <svx/polysc3d.hxx>
64 #include <svx/sdr/contact/displayinfo.hxx>
65 #include <svx/sdr/contact/objectcontactofobjlistpainter.hxx>
66 #include <sdr/contact/viewcontactofgraphic.hxx>
67 #include <svx/sdr/contact/viewcontactofsdrobj.hxx>
68 #include <sdr/properties/emptyproperties.hxx>
69 #include <svx/sdrhittesthelper.hxx>
70 #include <svx/sdrobjectuser.hxx>
71 #include <svx/sdrobjectfilter.hxx>
72 #include <svx/svddrag.hxx>
73 #include <svx/svdetc.hxx>
74 #include <svx/svdhdl.hxx>
75 #include <svx/svditer.hxx>
76 #include <svx/svdmodel.hxx>
77 #include <svx/svdoashp.hxx>
78 #include <svx/svdocapt.hxx>
79 #include <svx/svdocirc.hxx>
80 #include <svx/svdoedge.hxx>
81 #include <svx/svdograf.hxx>
82 #include <svx/svdogrp.hxx>
83 #include <svx/svdomeas.hxx>
84 #include <svx/svdomedia.hxx>
85 #include <svx/svdoole2.hxx>
86 #include <svx/svdopage.hxx>
87 #include <svx/svdopath.hxx>
88 #include <svx/svdorect.hxx>
89 #include <svx/svdotext.hxx>
90 #include <svx/svdouno.hxx>
91 #include <svx/svdovirt.hxx>
92 #include <svx/svdpage.hxx>
93 #include <svx/svdpool.hxx>
94 #include <svx/svdstr.hrc>
95 #include <svx/svdtrans.hxx>
96 #include <svx/svdundo.hxx>
97 #include <svx/svdview.hxx>
98 #include <sxlayitm.hxx>
99 #include <sxlogitm.hxx>
100 #include <sxmovitm.hxx>
101 #include <svx/sxmspitm.hxx>
102 #include <sxoneitm.hxx>
103 #include <sxonitm.hxx>
104 #include <sxopitm.hxx>
105 #include <sxraitm.hxx>
106 #include <sxreoitm.hxx>
107 #include <sxrooitm.hxx>
108 #include <sxsaitm.hxx>
109 #include <sxsoitm.hxx>
110 #include <sxtraitm.hxx>
111 #include <svx/unopage.hxx>
112 #include <svx/unoshape.hxx>
113 #include <svx/xbtmpit.hxx>
114 #include <svx/xenum.hxx>
115 #include <svx/xflclit.hxx>
116 #include <svx/xflftrit.hxx>
117 #include <svx/xflhtit.hxx>
118 #include <svx/xfltrit.hxx>
119 #include <svx/xgrad.hxx>
120 #include <svx/xhatch.hxx>
121 #include <svx/xlnclit.hxx>
122 #include <svx/xlndsit.hxx>
123 #include <svx/xlnedcit.hxx>
124 #include <svx/xlnedit.hxx>
125 #include <svx/xlnedwit.hxx>
126 #include <svx/xlnstcit.hxx>
127 #include <svx/xlnstit.hxx>
128 #include <svx/xlnstwit.hxx>
129 #include <svx/xlntrit.hxx>
130 #include <svx/xlnwtit.hxx>
131 #include <svx/xpoly.hxx>
132 #include <svx/svdglue.hxx>
133 #include <svx/svdsob.hxx>
134 #include <rtl/strbuf.hxx>
135 #include <svdoopengl.hxx>
136 #include <svdobjplusdata.hxx>
137 #include <svdobjuserdatalist.hxx>
139 #include <boost/scoped_ptr.hpp>
140 #include <boost/optional.hpp>
141 #include <libxml/xmlwriter.h>
143 using namespace ::com::sun::star;
147 TYPEINIT0(SdrObjUserCall);
149 SdrObjUserCall::~SdrObjUserCall()
153 void SdrObjUserCall::Changed(const SdrObject& /*rObj*/, SdrUserCallType /*eType*/, const Rectangle& /*rOldBoundRect*/)
157 SdrObjMacroHitRec::SdrObjMacroHitRec() :
158 pOut(NULL),
159 pVisiLayer(NULL),
160 pPageView(NULL),
161 nTol(0),
162 bDown(false) {}
166 TYPEINIT0(SdrObjUserData);
168 SdrObjUserData::SdrObjUserData(sal_uInt32 nInv, sal_uInt16 nId, sal_uInt16 nVer) :
169 nInventor(nInv),
170 nIdentifier(nId),
171 nVersion(nVer) {}
173 SdrObjUserData::SdrObjUserData(const SdrObjUserData& rData) :
174 nInventor(rData.nInventor),
175 nIdentifier(rData.nIdentifier),
176 nVersion(rData.nVersion) {}
178 SdrObjUserData::~SdrObjUserData() {}
180 SdrObjGeoData::SdrObjGeoData():
181 pGPL(NULL),
182 bMovProt(false),
183 bSizProt(false),
184 bNoPrint(false),
185 bClosedObj(false),
186 mbVisible(true),
187 mnLayerID(0)
191 SdrObjGeoData::~SdrObjGeoData()
193 delete pGPL;
196 SdrObjTransformInfoRec::SdrObjTransformInfoRec() :
197 bSelectAllowed(true),
198 bMoveAllowed(true),
199 bResizeFreeAllowed(true),
200 bResizePropAllowed(true),
201 bRotateFreeAllowed(true),
202 bRotate90Allowed(true),
203 bMirrorFreeAllowed(true),
204 bMirror45Allowed(true),
205 bMirror90Allowed(true),
206 bTransparenceAllowed(true),
207 bGradientAllowed(true),
208 bShearAllowed(true),
209 bEdgeRadiusAllowed(true),
210 bNoOrthoDesired(true),
211 bNoContortion(true),
212 bCanConvToPath(true),
213 bCanConvToPoly(true),
214 bCanConvToContour(false),
215 bCanConvToPathLineToArea(true),
216 bCanConvToPolyLineToArea(true) {}
218 struct SdrObject::Impl
220 sdr::ObjectUserVector maObjectUsers;
222 boost::optional<double> mnRelativeWidth;
223 sal_Int16 meRelativeWidthRelation;
224 boost::optional<double> mnRelativeHeight;
225 sal_Int16 meRelativeHeightRelation;
227 Impl() :
228 meRelativeWidthRelation(text::RelOrientation::PAGE_FRAME),
229 meRelativeHeightRelation(text::RelOrientation::PAGE_FRAME) {}
233 // BaseProperties section
235 sdr::properties::BaseProperties* SdrObject::CreateObjectSpecificProperties()
237 return new sdr::properties::EmptyProperties(*this);
240 sdr::properties::BaseProperties& SdrObject::GetProperties() const
242 if(!mpProperties)
244 const_cast< SdrObject* >(this)->mpProperties =
245 const_cast< SdrObject* >(this)->CreateObjectSpecificProperties();
248 return *mpProperties;
252 // ObjectUser section
254 void SdrObject::AddObjectUser(sdr::ObjectUser& rNewUser)
256 mpImpl->maObjectUsers.push_back(&rNewUser);
259 void SdrObject::RemoveObjectUser(sdr::ObjectUser& rOldUser)
261 const sdr::ObjectUserVector::iterator aFindResult =
262 std::find(mpImpl->maObjectUsers.begin(), mpImpl->maObjectUsers.end(), &rOldUser);
263 if (aFindResult != mpImpl->maObjectUsers.end())
265 mpImpl->maObjectUsers.erase(aFindResult);
270 // DrawContact section
272 sdr::contact::ViewContact* SdrObject::CreateObjectSpecificViewContact()
274 return new sdr::contact::ViewContactOfSdrObj(*this);
277 sdr::contact::ViewContact& SdrObject::GetViewContact() const
279 if(!mpViewContact)
281 const_cast< SdrObject* >(this)->mpViewContact =
282 const_cast< SdrObject* >(this)->CreateObjectSpecificViewContact();
285 return *mpViewContact;
288 // DrawContact support: Methods for handling Object changes
289 void SdrObject::ActionChanged() const
291 // Do necessary ViewContact actions
292 GetViewContact().ActionChanged();
297 void SdrObject::SetBoundRectDirty()
299 aOutRect = Rectangle();
304 TYPEINIT1(SdrObject,SfxListener);
306 SdrObject::SdrObject() :
307 mpImpl(new Impl),
308 mpProperties(0L)
309 ,mpViewContact(0L)
310 ,pObjList(NULL)
311 ,pPage(NULL)
312 ,pModel(NULL)
313 ,pUserCall(NULL)
314 ,pPlusData(NULL)
315 ,nOrdNum(0)
316 ,pGrabBagItem(NULL)
317 ,mnNavigationPosition(SAL_MAX_UINT32)
318 ,mnLayerID(0)
319 ,mpSvxShape( NULL )
320 ,maWeakUnoShape()
321 ,mbDoNotInsertIntoPageAutomatically(false)
323 bVirtObj =false;
324 bSnapRectDirty =true;
325 bNetLock =false;
326 bInserted =false;
327 bGrouped =false;
328 bMovProt =false;
329 bSizProt =false;
330 bNoPrint =false;
331 bEmptyPresObj =false;
332 bNotVisibleAsMaster=false;
333 bClosedObj =false;
334 mbVisible = true;
336 // #i25616#
337 mbLineIsOutsideGeometry = false;
339 // #i25616#
340 mbSupportTextIndentingOnLineWidthChange = false;
342 bNotMasterCachable=false;
343 bIsEdge=false;
344 bIs3DObj=false;
345 bMarkProt=false;
346 bIsUnoObj=false;
349 SdrObject::~SdrObject()
351 // tell all the registered ObjectUsers that the page is in destruction
352 sdr::ObjectUserVector aListCopy(mpImpl->maObjectUsers.begin(), mpImpl->maObjectUsers.end());
353 for(sdr::ObjectUserVector::iterator aIterator = aListCopy.begin(); aIterator != aListCopy.end(); ++aIterator)
355 sdr::ObjectUser* pObjectUser = *aIterator;
356 DBG_ASSERT(pObjectUser, "SdrObject::~SdrObject: corrupt ObjectUser list (!)");
357 pObjectUser->ObjectInDestruction(*this);
360 // Clear the vector. This means that user do not need to call RemoveObjectUser()
361 // when they get called from ObjectInDestruction().
362 mpImpl->maObjectUsers.clear();
366 SvxShape* pSvxShape = getSvxShape();
367 if ( pSvxShape )
369 OSL_ENSURE(!pSvxShape->HasSdrObjectOwnership(),"Please check where this call come from and replace it with SdrObject::Free");
370 pSvxShape->InvalidateSdrObject();
371 uno::Reference< lang::XComponent > xShapeComp( getWeakUnoShape(), uno::UNO_QUERY_THROW );
372 xShapeComp->dispose();
375 catch( const uno::Exception& )
377 DBG_UNHANDLED_EXCEPTION();
380 SendUserCall(SDRUSERCALL_DELETE, GetLastBoundRect());
381 delete pPlusData;
383 delete pGrabBagItem;
385 if(mpProperties)
387 delete mpProperties;
388 mpProperties = 0L;
391 if(mpViewContact)
393 delete mpViewContact;
394 mpViewContact = 0L;
397 delete mpImpl;
400 void SdrObject::Free( SdrObject*& _rpObject )
402 SdrObject* pObject = _rpObject; _rpObject = NULL;
403 if ( pObject == NULL )
404 // nothing to do
405 return;
407 SvxShape* pShape = pObject->getSvxShape();
408 if ( pShape && pShape->HasSdrObjectOwnership() )
409 // only the shape is allowed to delete me, and will reset the ownership before doing so
410 return;
412 delete pObject;
415 SdrObjPlusData* SdrObject::NewPlusData()
417 return new SdrObjPlusData;
420 void SdrObject::SetRectsDirty(bool bNotMyself)
422 if (!bNotMyself) {
423 SetBoundRectDirty();
424 bSnapRectDirty=true;
426 if (pObjList!=NULL) {
427 pObjList->SetRectsDirty();
431 void SdrObject::SetModel(SdrModel* pNewModel)
433 if(pNewModel && pPage)
435 if(pPage->GetModel() != pNewModel)
437 pPage = NULL;
441 // update listeners at possible API wrapper object
442 if( pModel != pNewModel )
444 SvxShape* pShape = getSvxShape();
445 if( pShape )
446 pShape->ChangeModel( pNewModel );
449 pModel = pNewModel;
453 void SdrObject::SetObjList(SdrObjList* pNewObjList)
455 pObjList=pNewObjList;
459 void SdrObject::SetPage(SdrPage* pNewPage)
461 SdrModel* pOldModel = pModel;
462 SdrPage* pOldPage = pPage;
464 pPage=pNewPage;
465 if (pPage!=NULL) {
466 SdrModel* pMod=pPage->GetModel();
467 if (pMod!=pModel && pMod!=NULL) {
468 SetModel(pMod);
471 // The creation of the UNO shape in SdrObject::getUnoShape is influenced
472 // by pPage, so when the page changes we need to discard the cached UNO
473 // shape so that a new one will be created.
474 // If the page is changing to another page with the same model, we
475 // assume they create compatible UNO shape objects so we shouldn't have
476 // to invalidate.
477 if (pOldPage != pPage && !(pOldPage && pPage && pOldModel == pModel))
479 SvxShape* const pShape(getSvxShape());
480 if (pShape && !pShape->HasSdrObjectOwnership())
481 setUnoShape(NULL);
486 // init global static itempool
487 SdrItemPool* SdrObject::mpGlobalItemPool = NULL;
489 SdrItemPool& SdrObject::GetGlobalDrawObjectItemPool()
491 if(!mpGlobalItemPool)
493 mpGlobalItemPool = new SdrItemPool();
494 SfxItemPool* pGlobalOutlPool = EditEngine::CreatePool();
495 mpGlobalItemPool->SetSecondaryPool(pGlobalOutlPool);
496 mpGlobalItemPool->SetDefaultMetric((SfxMapUnit)SdrEngineDefaults::GetMapUnit());
497 mpGlobalItemPool->FreezeIdRanges();
500 return *mpGlobalItemPool;
503 void SdrObject::SetRelativeWidth( double nValue )
505 mpImpl->mnRelativeWidth.reset( nValue );
508 void SdrObject::SetRelativeWidthRelation( sal_Int16 eValue )
510 mpImpl->meRelativeWidthRelation = eValue;
513 void SdrObject::SetRelativeHeight( double nValue )
515 mpImpl->mnRelativeHeight.reset( nValue );
518 void SdrObject::SetRelativeHeightRelation( sal_Int16 eValue )
520 mpImpl->meRelativeHeightRelation = eValue;
523 const double* SdrObject::GetRelativeWidth( ) const
525 if (!mpImpl->mnRelativeWidth)
526 return NULL;
528 return &mpImpl->mnRelativeWidth.get();
531 sal_Int16 SdrObject::GetRelativeWidthRelation() const
533 return mpImpl->meRelativeWidthRelation;
536 const double* SdrObject::GetRelativeHeight( ) const
538 if (!mpImpl->mnRelativeHeight)
539 return NULL;
541 return &mpImpl->mnRelativeHeight.get();
544 sal_Int16 SdrObject::GetRelativeHeightRelation() const
546 return mpImpl->meRelativeHeightRelation;
549 SfxItemPool & SdrObject::GetObjectItemPool() const
551 if(pModel)
552 return pModel->GetItemPool();
554 // use a static global default pool
555 return SdrObject::GetGlobalDrawObjectItemPool();
558 sal_uInt32 SdrObject::GetObjInventor() const
560 return SdrInventor;
563 sal_uInt16 SdrObject::GetObjIdentifier() const
565 return sal_uInt16(OBJ_NONE);
568 void SdrObject::TakeObjInfo(SdrObjTransformInfoRec& rInfo) const
570 rInfo.bRotateFreeAllowed=false;
571 rInfo.bMirrorFreeAllowed=false;
572 rInfo.bTransparenceAllowed = false;
573 rInfo.bGradientAllowed = false;
574 rInfo.bShearAllowed =false;
575 rInfo.bEdgeRadiusAllowed=false;
576 rInfo.bCanConvToPath =false;
577 rInfo.bCanConvToPoly =false;
578 rInfo.bCanConvToContour = false;
579 rInfo.bCanConvToPathLineToArea=false;
580 rInfo.bCanConvToPolyLineToArea=false;
583 SdrLayerID SdrObject::GetLayer() const
585 return mnLayerID;
588 void SdrObject::getMergedHierarchyLayerSet(SetOfByte& rSet) const
590 rSet.Set(GetLayer());
591 SdrObjList* pOL=GetSubList();
592 if (pOL!=NULL) {
593 const size_t nObjAnz = pOL->GetObjCount();
594 for (size_t nObjNum = 0; nObjNum<nObjAnz; ++nObjNum) {
595 pOL->GetObj(nObjNum)->getMergedHierarchyLayerSet(rSet);
600 void SdrObject::NbcSetLayer(SdrLayerID nLayer)
602 mnLayerID = nLayer;
605 void SdrObject::SetLayer(SdrLayerID nLayer)
607 NbcSetLayer(nLayer);
608 SetChanged();
609 BroadcastObjectChange();
612 void SdrObject::AddListener(SfxListener& rListener)
614 ImpForcePlusData();
615 if (pPlusData->pBroadcast==NULL) pPlusData->pBroadcast=new SfxBroadcaster;
616 rListener.StartListening(*pPlusData->pBroadcast);
619 void SdrObject::RemoveListener(SfxListener& rListener)
621 if (pPlusData!=NULL && pPlusData->pBroadcast!=NULL) {
622 rListener.EndListening(*pPlusData->pBroadcast);
623 if (!pPlusData->pBroadcast->HasListeners()) {
624 delete pPlusData->pBroadcast;
625 pPlusData->pBroadcast=NULL;
630 const SfxBroadcaster* SdrObject::GetBroadcaster() const
632 return pPlusData!=NULL ? pPlusData->pBroadcast : NULL;
635 void SdrObject::AddReference(SdrVirtObj& rVrtObj)
637 AddListener(rVrtObj);
640 void SdrObject::DelReference(SdrVirtObj& rVrtObj)
642 RemoveListener(rVrtObj);
645 bool SdrObject::HasRefPoint() const
647 return false;
650 Point SdrObject::GetRefPoint() const
652 return GetCurrentBoundRect().Center();
655 void SdrObject::SetRefPoint(const Point& /*rPnt*/)
659 bool SdrObject::IsGroupObject() const
661 return GetSubList()!=NULL;
664 SdrObjList* SdrObject::GetSubList() const
666 return NULL;
669 SdrObject* SdrObject::GetUpGroup() const
671 return pObjList!=NULL ? pObjList->GetOwnerObj() : NULL;
674 void SdrObject::SetName(const OUString& rStr)
676 if (!rStr.isEmpty() && !pPlusData)
678 ImpForcePlusData();
681 if(pPlusData && !pPlusData->aObjName.equals(rStr))
683 // Undo/Redo for setting object's name (#i73249#)
684 bool bUndo( false );
685 if ( GetModel() && GetModel()->IsUndoEnabled() )
687 bUndo = true;
688 SdrUndoAction* pUndoAction =
689 SdrUndoFactory::CreateUndoObjectStrAttr(
690 *this,
691 SdrUndoObjStrAttr::OBJ_NAME,
692 GetName(),
693 rStr );
694 GetModel()->BegUndo( pUndoAction->GetComment() );
695 GetModel()->AddUndo( pUndoAction );
697 pPlusData->aObjName = rStr;
698 // Undo/Redo for setting object's name (#i73249#)
699 if ( bUndo )
701 GetModel()->EndUndo();
703 SetChanged();
704 BroadcastObjectChange();
708 OUString SdrObject::GetName() const
710 if(pPlusData)
712 return pPlusData->aObjName;
715 return OUString();
718 void SdrObject::SetTitle(const OUString& rStr)
720 if (!rStr.isEmpty() && !pPlusData)
722 ImpForcePlusData();
725 if(pPlusData && pPlusData->aObjTitle != rStr)
727 // Undo/Redo for setting object's title (#i73249#)
728 bool bUndo( false );
729 if ( GetModel() && GetModel()->IsUndoEnabled() )
731 bUndo = true;
732 SdrUndoAction* pUndoAction =
733 SdrUndoFactory::CreateUndoObjectStrAttr(
734 *this,
735 SdrUndoObjStrAttr::OBJ_TITLE,
736 GetTitle(),
737 rStr );
738 GetModel()->BegUndo( pUndoAction->GetComment() );
739 GetModel()->AddUndo( pUndoAction );
741 pPlusData->aObjTitle = rStr;
742 // Undo/Redo for setting object's title (#i73249#)
743 if ( bUndo )
745 GetModel()->EndUndo();
747 SetChanged();
748 BroadcastObjectChange();
752 OUString SdrObject::GetTitle() const
754 if(pPlusData)
756 return pPlusData->aObjTitle;
759 return OUString();
762 void SdrObject::SetDescription(const OUString& rStr)
764 if (!rStr.isEmpty() && !pPlusData)
766 ImpForcePlusData();
769 if(pPlusData && !pPlusData->aObjDescription.equals(rStr))
771 // Undo/Redo for setting object's description (#i73249#)
772 bool bUndo( false );
773 if ( GetModel() && GetModel()->IsUndoEnabled() )
775 bUndo = true;
776 SdrUndoAction* pUndoAction =
777 SdrUndoFactory::CreateUndoObjectStrAttr(
778 *this,
779 SdrUndoObjStrAttr::OBJ_DESCRIPTION,
780 GetDescription(),
781 rStr );
782 GetModel()->BegUndo( pUndoAction->GetComment() );
783 GetModel()->AddUndo( pUndoAction );
785 pPlusData->aObjDescription = rStr;
786 // Undo/Redo for setting object's description (#i73249#)
787 if ( bUndo )
789 GetModel()->EndUndo();
791 SetChanged();
792 BroadcastObjectChange();
796 OUString SdrObject::GetDescription() const
798 if(pPlusData)
800 return pPlusData->aObjDescription;
803 return OUString();
806 sal_uInt32 SdrObject::GetOrdNum() const
808 if (pObjList!=NULL) {
809 if (pObjList->IsObjOrdNumsDirty()) {
810 pObjList->RecalcObjOrdNums();
812 } else const_cast<SdrObject*>(this)->nOrdNum=0;
813 return nOrdNum;
817 void SdrObject::SetOrdNum(sal_uInt32 nNum)
819 nOrdNum = nNum;
822 void SdrObject::GetGrabBagItem(com::sun::star::uno::Any& rVal) const
824 if (pGrabBagItem != NULL)
825 pGrabBagItem->QueryValue(rVal);
826 else {
827 uno::Sequence<beans::PropertyValue> aValue(0);
828 rVal = uno::makeAny(aValue);
832 void SdrObject::SetGrabBagItem(const com::sun::star::uno::Any& rVal)
834 if (pGrabBagItem == NULL)
835 pGrabBagItem = new SfxGrabBagItem;
837 pGrabBagItem->PutValue(rVal);
839 SetChanged();
840 BroadcastObjectChange();
843 sal_uInt32 SdrObject::GetNavigationPosition()
845 if (pObjList!=NULL && pObjList->RecalcNavigationPositions())
847 return mnNavigationPosition;
849 else
850 return GetOrdNum();
856 void SdrObject::SetNavigationPosition (const sal_uInt32 nNewPosition)
858 mnNavigationPosition = nNewPosition;
864 // To make clearer that this method may trigger RecalcBoundRect and thus may be
865 // expensive and sometimes problematic (inside a bigger object change you will get
866 // non-useful BoundRects sometimes) I rename that method from GetBoundRect() to
867 // GetCurrentBoundRect().
868 const Rectangle& SdrObject::GetCurrentBoundRect() const
870 if(aOutRect.IsEmpty())
872 const_cast< SdrObject* >(this)->RecalcBoundRect();
875 return aOutRect;
878 // To have a possibility to get the last calculated BoundRect e.g for producing
879 // the first rectangle for repaints (old and new need to be used) without forcing
880 // a RecalcBoundRect (which may be problematical and expensive sometimes) I add here
881 // a new method for accessing the last BoundRect.
882 const Rectangle& SdrObject::GetLastBoundRect() const
884 return aOutRect;
887 void SdrObject::RecalcBoundRect()
889 // #i101680# suppress BoundRect calculations on import(s)
890 if(pModel && pModel->isLocked())
891 return;
893 // central new method which will calculate the BoundRect using primitive geometry
894 if(aOutRect.IsEmpty())
896 const drawinglayer::primitive2d::Primitive2DSequence xPrimitives(GetViewContact().getViewIndependentPrimitive2DSequence());
898 if(xPrimitives.hasElements())
900 // use neutral ViewInformation and get the range of the primitives
901 const drawinglayer::geometry::ViewInformation2D aViewInformation2D;
902 const basegfx::B2DRange aRange(drawinglayer::primitive2d::getB2DRangeFromPrimitive2DSequence(xPrimitives, aViewInformation2D));
904 if(!aRange.isEmpty())
906 aOutRect = Rectangle(
907 static_cast<long>(floor(aRange.getMinX())),
908 static_cast<long>(floor(aRange.getMinY())),
909 static_cast<long>(ceil(aRange.getMaxX())),
910 static_cast<long>(ceil(aRange.getMaxY())));
911 aOutRect -= GetGridOffset(); // don't include grid offset
912 return;
918 void SdrObject::BroadcastObjectChange() const
920 if( pModel && pModel->isLocked() )
921 return;
923 bool bPlusDataBroadcast(pPlusData && pPlusData->pBroadcast);
924 bool bObjectChange(IsInserted() && pModel);
926 if(bPlusDataBroadcast || bObjectChange)
928 SdrHint aHint(*this);
930 if(bPlusDataBroadcast)
932 pPlusData->pBroadcast->Broadcast(aHint);
935 if(bObjectChange)
937 pModel->Broadcast(aHint);
942 void SdrObject::SetChanged()
944 // For testing purposes, use the new ViewContact for change
945 // notification now.
946 ActionChanged();
948 if(IsInserted() && pModel)
950 pModel->SetChanged();
954 // tooling for painting a single object to an OutputDevice.
955 bool SdrObject::SingleObjectPainter(OutputDevice& rOut) const
957 sdr::contact::SdrObjectVector aObjectVector;
958 aObjectVector.push_back(const_cast< SdrObject* >(this));
960 sdr::contact::ObjectContactOfObjListPainter aPainter(rOut, aObjectVector, GetPage());
961 sdr::contact::DisplayInfo aDisplayInfo;
963 aPainter.ProcessDisplay(aDisplayInfo);
965 return true;
968 bool SdrObject::LineGeometryUsageIsNecessary() const
970 drawing::LineStyle eXLS = (drawing::LineStyle)static_cast<const XLineStyleItem&>(GetMergedItem(XATTR_LINESTYLE)).GetValue();
971 return (eXLS != drawing::LineStyle_NONE);
974 SdrObject* SdrObject::Clone() const
976 return CloneHelper< SdrObject >();
979 SdrObject* SdrObject::CloneWithShellIDs( const OUString& /*rSrcShellID*/, const OUString& /*rDestShellID*/ ) const
981 return Clone();
984 SdrObject& SdrObject::operator=(const SdrObject& rObj)
986 if( this == &rObj )
987 return *this;
989 if(mpProperties)
991 delete mpProperties;
992 mpProperties = 0L;
995 if(mpViewContact)
997 delete mpViewContact;
998 mpViewContact = 0L;
1001 // The Clone() method uses the local copy constructor from the individual
1002 // sdr::properties::BaseProperties class. Since the target class maybe for another
1003 // draw object, an SdrObject needs to be provided, as in the normal constructor.
1004 mpProperties = &rObj.GetProperties().Clone(*this);
1006 pModel =rObj.pModel;
1007 pPage = rObj.pPage;
1008 aOutRect=rObj.aOutRect;
1009 mnLayerID = rObj.mnLayerID;
1010 aAnchor =rObj.aAnchor;
1011 bVirtObj=rObj.bVirtObj;
1012 bSizProt=rObj.bSizProt;
1013 bMovProt=rObj.bMovProt;
1014 bNoPrint=rObj.bNoPrint;
1015 mbVisible=rObj.mbVisible;
1016 bMarkProt=rObj.bMarkProt;
1017 bEmptyPresObj =rObj.bEmptyPresObj;
1018 bNotVisibleAsMaster=rObj.bNotVisibleAsMaster;
1019 bSnapRectDirty=true;
1020 bNotMasterCachable=rObj.bNotMasterCachable;
1021 delete pPlusData;
1022 pPlusData=NULL;
1023 if (rObj.pPlusData!=NULL) {
1024 pPlusData=rObj.pPlusData->Clone(this);
1026 if (pPlusData!=NULL && pPlusData->pBroadcast!=NULL) {
1027 delete pPlusData->pBroadcast; // broadcaster isn't copied
1028 pPlusData->pBroadcast=NULL;
1031 delete pGrabBagItem;
1032 pGrabBagItem=NULL;
1033 if (rObj.pGrabBagItem!=NULL)
1034 pGrabBagItem=static_cast< SfxGrabBagItem* >( rObj.pGrabBagItem->Clone() );
1036 aGridOffset = rObj.aGridOffset;
1037 return *this;
1040 OUString SdrObject::TakeObjNameSingul() const
1042 OUStringBuffer sName(ImpGetResStr(STR_ObjNameSingulNONE));
1044 OUString aName(GetName());
1045 if (!aName.isEmpty())
1047 sName.append(' ');
1048 sName.append('\'');
1049 sName.append(aName);
1050 sName.append('\'');
1052 return sName.makeStringAndClear();
1055 OUString SdrObject::TakeObjNamePlural() const
1057 return ImpGetResStr(STR_ObjNamePluralNONE);
1060 void SdrObject::ImpTakeDescriptionStr(sal_uInt16 nStrCacheID, OUString& rStr, sal_uInt16 nVal) const
1062 rStr = ImpGetResStr(nStrCacheID);
1063 sal_Int32 nPos = rStr.indexOf("%1");
1064 if (nPos >= 0)
1066 // Replace '%1' with the object name.
1067 OUString aObjName(TakeObjNameSingul());
1068 rStr = rStr.replaceAt(nPos, 2, aObjName);
1071 nPos = rStr.indexOf("%2");
1072 if (nPos >= 0)
1073 // Replace '%2' with the passed value.
1074 rStr = rStr.replaceAt(
1075 nPos, 2, OUString::number(nVal));
1078 void SdrObject::ImpForcePlusData()
1080 if (!pPlusData)
1081 pPlusData = NewPlusData();
1084 OUString SdrObject::GetAngleStr(long nAngle, bool bNoDegChar) const
1086 OUString aStr;
1087 if (pModel!=NULL) {
1088 SdrModel::TakeAngleStr(nAngle,aStr,bNoDegChar);
1090 return aStr;
1093 OUString SdrObject::GetMetrStr(long nVal, MapUnit /*eWantMap*/, bool bNoUnitChars) const
1095 OUString aStr;
1096 if (pModel!=NULL) {
1097 pModel->TakeMetricStr(nVal,aStr,bNoUnitChars);
1099 return aStr;
1102 basegfx::B2DPolyPolygon SdrObject::TakeXorPoly() const
1104 basegfx::B2DPolyPolygon aRetval;
1105 const Rectangle aR(GetCurrentBoundRect());
1106 const basegfx::B2DRange aRange(aR.Left(), aR.Top(), aR.Right(), aR.Bottom());
1107 aRetval.append(basegfx::tools::createPolygonFromRect(aRange));
1109 return aRetval;
1112 basegfx::B2DPolyPolygon SdrObject::TakeContour() const
1114 basegfx::B2DPolyPolygon aRetval;
1116 // create cloned object without text, but with drawing::LineStyle_SOLID,
1117 // COL_BLACK as line color and drawing::FillStyle_NONE
1118 SdrObject* pClone = Clone();
1120 if(pClone)
1122 const SdrTextObj* pTextObj = dynamic_cast< const SdrTextObj* >(this);
1124 if(pTextObj)
1126 // no text and no text animation
1127 pClone->SetMergedItem(SdrTextAniKindItem(SDRTEXTANI_NONE));
1128 pClone->SetOutlinerParaObject(0);
1131 const SdrEdgeObj* pEdgeObj = dynamic_cast< const SdrEdgeObj* >(this);
1133 if(pEdgeObj)
1135 // create connections if connector, will be cleaned up when
1136 // deleting the connector again
1137 SdrObject* pLeft = pEdgeObj->GetConnectedNode(true);
1138 SdrObject* pRight = pEdgeObj->GetConnectedNode(false);
1140 if(pLeft)
1142 pClone->ConnectToNode(true, pLeft);
1145 if(pRight)
1147 pClone->ConnectToNode(false, pRight);
1151 SfxItemSet aNewSet(GetObjectItemPool());
1153 // #i101980# ignore LineWidth; that's what the old implementation
1154 // did. With line width, the result may be huge due to fat/thick
1155 // line decompositions
1156 aNewSet.Put(XLineWidthItem(0));
1158 // solid black lines and no fill
1159 aNewSet.Put(XLineStyleItem(drawing::LineStyle_SOLID));
1160 aNewSet.Put(XLineColorItem(OUString(), Color(COL_BLACK)));
1161 aNewSet.Put(XFillStyleItem(drawing::FillStyle_NONE));
1162 pClone->SetMergedItemSet(aNewSet);
1164 // get sequence from clone
1165 const sdr::contact::ViewContact& rVC(pClone->GetViewContact());
1166 const drawinglayer::primitive2d::Primitive2DSequence xSequence(rVC.getViewIndependentPrimitive2DSequence());
1168 if(xSequence.hasElements())
1170 // use neutral ViewInformation
1171 const drawinglayer::geometry::ViewInformation2D aViewInformation2D;
1173 // create extractor, process and get result (with hairlines as opened polygons)
1174 drawinglayer::processor2d::ContourExtractor2D aExtractor(aViewInformation2D, false);
1175 aExtractor.process(xSequence);
1176 const basegfx::B2DPolyPolygonVector& rResult(aExtractor.getExtractedContour());
1177 const sal_uInt32 nSize(rResult.size());
1179 // when count is one, it is implied that the object has only its normal
1180 // contour anyways and TakeCountour() is to return an empty PolyPolygon
1181 // (see old implementation for historical reasons)
1182 if(nSize > 1)
1184 // the topology for contour is correctly a vector of PolyPolygons; for
1185 // historical reasons cut it back to a single tools::PolyPolygon here
1186 for(sal_uInt32 a(0); a < nSize; a++)
1188 aRetval.append(rResult[a]);
1193 delete pClone;
1196 return aRetval;
1199 sal_uInt32 SdrObject::GetHdlCount() const
1201 return 8L;
1204 SdrHdl* SdrObject::GetHdl(sal_uInt32 nHdlNum) const
1206 SdrHdl* pH=NULL;
1207 const Rectangle& rR=GetSnapRect();
1208 switch (nHdlNum) {
1209 case 0: pH=new SdrHdl(rR.TopLeft(), HDL_UPLFT); break;
1210 case 1: pH=new SdrHdl(rR.TopCenter(), HDL_UPPER); break;
1211 case 2: pH=new SdrHdl(rR.TopRight(), HDL_UPRGT); break;
1212 case 3: pH=new SdrHdl(rR.LeftCenter(), HDL_LEFT ); break;
1213 case 4: pH=new SdrHdl(rR.RightCenter(), HDL_RIGHT); break;
1214 case 5: pH=new SdrHdl(rR.BottomLeft(), HDL_LWLFT); break;
1215 case 6: pH=new SdrHdl(rR.BottomCenter(),HDL_LOWER); break;
1216 case 7: pH=new SdrHdl(rR.BottomRight(), HDL_LWRGT); break;
1218 return pH;
1221 sal_uInt32 SdrObject::GetPlusHdlCount(const SdrHdl& /*rHdl*/) const
1223 return 0L;
1226 SdrHdl* SdrObject::GetPlusHdl(const SdrHdl& /*rHdl*/, sal_uInt32 /*nPlNum*/) const
1228 return 0L;
1231 void SdrObject::AddToHdlList(SdrHdlList& rHdlList) const
1233 sal_uInt32 nCount=GetHdlCount();
1234 for (sal_uInt32 i=0L; i<nCount; i++) {
1235 SdrHdl* pHdl=GetHdl(i);
1236 if (pHdl!=NULL) {
1237 rHdlList.AddHdl(pHdl);
1242 void SdrObject::addCropHandles(SdrHdlList& /*rTarget*/) const
1244 // Default implementation, does nothing. Overloaded in
1245 // SdrGrafObj and SwVirtFlyDrawObj
1248 Rectangle SdrObject::ImpDragCalcRect(const SdrDragStat& rDrag) const
1250 Rectangle aTmpRect(GetSnapRect());
1251 Rectangle aRect(aTmpRect);
1252 const SdrHdl* pHdl=rDrag.GetHdl();
1253 SdrHdlKind eHdl=pHdl==NULL ? HDL_MOVE : pHdl->GetKind();
1254 bool bEcke=(eHdl==HDL_UPLFT || eHdl==HDL_UPRGT || eHdl==HDL_LWLFT || eHdl==HDL_LWRGT);
1255 bool bOrtho=rDrag.GetView()!=NULL && rDrag.GetView()->IsOrtho();
1256 bool bBigOrtho=bEcke && bOrtho && rDrag.GetView()->IsBigOrtho();
1257 Point aPos(rDrag.GetNow());
1258 bool bLft=(eHdl==HDL_UPLFT || eHdl==HDL_LEFT || eHdl==HDL_LWLFT);
1259 bool bRgt=(eHdl==HDL_UPRGT || eHdl==HDL_RIGHT || eHdl==HDL_LWRGT);
1260 bool bTop=(eHdl==HDL_UPRGT || eHdl==HDL_UPPER || eHdl==HDL_UPLFT);
1261 bool bBtm=(eHdl==HDL_LWRGT || eHdl==HDL_LOWER || eHdl==HDL_LWLFT);
1262 if (bLft) aTmpRect.Left() =aPos.X();
1263 if (bRgt) aTmpRect.Right() =aPos.X();
1264 if (bTop) aTmpRect.Top() =aPos.Y();
1265 if (bBtm) aTmpRect.Bottom()=aPos.Y();
1266 if (bOrtho) { // Ortho
1267 long nWdt0=aRect.Right() -aRect.Left();
1268 long nHgt0=aRect.Bottom()-aRect.Top();
1269 long nXMul=aTmpRect.Right() -aTmpRect.Left();
1270 long nYMul=aTmpRect.Bottom()-aTmpRect.Top();
1271 long nXDiv=nWdt0;
1272 long nYDiv=nHgt0;
1273 bool bXNeg=(nXMul<0)!=(nXDiv<0);
1274 bool bYNeg=(nYMul<0)!=(nYDiv<0);
1275 nXMul=std::abs(nXMul);
1276 nYMul=std::abs(nYMul);
1277 nXDiv=std::abs(nXDiv);
1278 nYDiv=std::abs(nYDiv);
1279 Fraction aXFact(nXMul,nXDiv); // fractions for canceling
1280 Fraction aYFact(nYMul,nYDiv); // and for comparing
1281 nXMul=aXFact.GetNumerator();
1282 nYMul=aYFact.GetNumerator();
1283 nXDiv=aXFact.GetDenominator();
1284 nYDiv=aYFact.GetDenominator();
1285 if (bEcke) { // corner point handles
1286 bool bUseX=(aXFact<aYFact) != bBigOrtho;
1287 if (bUseX) {
1288 long nNeed=long(BigInt(nHgt0)*BigInt(nXMul)/BigInt(nXDiv));
1289 if (bYNeg) nNeed=-nNeed;
1290 if (bTop) aTmpRect.Top()=aTmpRect.Bottom()-nNeed;
1291 if (bBtm) aTmpRect.Bottom()=aTmpRect.Top()+nNeed;
1292 } else {
1293 long nNeed=long(BigInt(nWdt0)*BigInt(nYMul)/BigInt(nYDiv));
1294 if (bXNeg) nNeed=-nNeed;
1295 if (bLft) aTmpRect.Left()=aTmpRect.Right()-nNeed;
1296 if (bRgt) aTmpRect.Right()=aTmpRect.Left()+nNeed;
1298 } else { // apex handles
1299 if ((bLft || bRgt) && nXDiv!=0) {
1300 long nHgt0b=aRect.Bottom()-aRect.Top();
1301 long nNeed=long(BigInt(nHgt0b)*BigInt(nXMul)/BigInt(nXDiv));
1302 aTmpRect.Top()-=(nNeed-nHgt0b)/2;
1303 aTmpRect.Bottom()=aTmpRect.Top()+nNeed;
1305 if ((bTop || bBtm) && nYDiv!=0) {
1306 long nWdt0b=aRect.Right()-aRect.Left();
1307 long nNeed=long(BigInt(nWdt0b)*BigInt(nYMul)/BigInt(nYDiv));
1308 aTmpRect.Left()-=(nNeed-nWdt0b)/2;
1309 aTmpRect.Right()=aTmpRect.Left()+nNeed;
1313 aTmpRect.Justify();
1314 return aTmpRect;
1319 bool SdrObject::hasSpecialDrag() const
1321 return false;
1324 bool SdrObject::supportsFullDrag() const
1326 return true;
1329 SdrObject* SdrObject::getFullDragClone() const
1331 // default uses simple clone
1332 return Clone();
1335 bool SdrObject::beginSpecialDrag(SdrDragStat& rDrag) const
1337 const SdrHdl* pHdl = rDrag.GetHdl();
1339 SdrHdlKind eHdl = (pHdl == NULL) ? HDL_MOVE : pHdl->GetKind();
1341 if(eHdl==HDL_UPLFT || eHdl==HDL_UPPER || eHdl==HDL_UPRGT ||
1342 eHdl==HDL_LEFT || eHdl==HDL_RIGHT || eHdl==HDL_LWLFT ||
1343 eHdl==HDL_LOWER || eHdl==HDL_LWRGT)
1345 return true;
1348 return false;
1351 bool SdrObject::applySpecialDrag(SdrDragStat& rDrag)
1353 Rectangle aNewRect(ImpDragCalcRect(rDrag));
1355 if(aNewRect != GetSnapRect())
1357 NbcSetSnapRect(aNewRect);
1360 return true;
1363 OUString SdrObject::getSpecialDragComment(const SdrDragStat& /*rDrag*/) const
1365 return OUString();
1368 basegfx::B2DPolyPolygon SdrObject::getSpecialDragPoly(const SdrDragStat& /*rDrag*/) const
1370 // default has nothing to add
1371 return basegfx::B2DPolyPolygon();
1375 // Create
1376 bool SdrObject::BegCreate(SdrDragStat& rStat)
1378 rStat.SetOrtho4Possible();
1379 Rectangle aRect1(rStat.GetStart(), rStat.GetNow());
1380 aRect1.Justify();
1381 rStat.SetActionRect(aRect1);
1382 aOutRect = aRect1;
1383 return true;
1386 bool SdrObject::MovCreate(SdrDragStat& rStat)
1388 rStat.TakeCreateRect(aOutRect);
1389 rStat.SetActionRect(aOutRect);
1390 aOutRect.Justify();
1392 return true;
1395 bool SdrObject::EndCreate(SdrDragStat& rStat, SdrCreateCmd eCmd)
1397 rStat.TakeCreateRect(aOutRect);
1398 aOutRect.Justify();
1400 return (eCmd==SDRCREATE_FORCEEND || rStat.GetPointAnz()>=2);
1403 void SdrObject::BrkCreate(SdrDragStat& /*rStat*/)
1407 bool SdrObject::BckCreate(SdrDragStat& /*rStat*/)
1409 return false;
1412 basegfx::B2DPolyPolygon SdrObject::TakeCreatePoly(const SdrDragStat& rDrag) const
1414 Rectangle aRect1;
1415 rDrag.TakeCreateRect(aRect1);
1416 aRect1.Justify();
1418 basegfx::B2DPolyPolygon aRetval;
1419 const basegfx::B2DRange aRange(aRect1.Left(), aRect1.Top(), aRect1.Right(), aRect1.Bottom());
1420 aRetval.append(basegfx::tools::createPolygonFromRect(aRange));
1421 return aRetval;
1424 Pointer SdrObject::GetCreatePointer() const
1426 return Pointer(PointerStyle::Cross);
1429 // transformations
1430 void SdrObject::NbcMove(const Size& rSiz)
1432 MoveRect(aOutRect,rSiz);
1433 SetRectsDirty();
1436 void SdrObject::NbcResize(const Point& rRef, const Fraction& xFact, const Fraction& yFact)
1438 bool bXMirr=(xFact.GetNumerator()<0) != (xFact.GetDenominator()<0);
1439 bool bYMirr=(yFact.GetNumerator()<0) != (yFact.GetDenominator()<0);
1440 if (bXMirr || bYMirr) {
1441 Point aRef1(GetSnapRect().Center());
1442 if (bXMirr) {
1443 Point aRef2(aRef1);
1444 aRef2.Y()++;
1445 NbcMirrorGluePoints(aRef1,aRef2);
1447 if (bYMirr) {
1448 Point aRef2(aRef1);
1449 aRef2.X()++;
1450 NbcMirrorGluePoints(aRef1,aRef2);
1453 ResizeRect(aOutRect,rRef,xFact,yFact);
1454 SetRectsDirty();
1457 void SdrObject::NbcRotate(const Point& rRef, long nAngle, double sn, double cs)
1459 SetGlueReallyAbsolute(true);
1460 aOutRect.Move(-rRef.X(),-rRef.Y());
1461 Rectangle R(aOutRect);
1462 if (sn==1.0 && cs==0.0) { // 90deg
1463 aOutRect.Left() =-R.Bottom();
1464 aOutRect.Right() =-R.Top();
1465 aOutRect.Top() =R.Left();
1466 aOutRect.Bottom()=R.Right();
1467 } else if (sn==0.0 && cs==-1.0) { // 180deg
1468 aOutRect.Left() =-R.Right();
1469 aOutRect.Right() =-R.Left();
1470 aOutRect.Top() =-R.Bottom();
1471 aOutRect.Bottom()=-R.Top();
1472 } else if (sn==-1.0 && cs==0.0) { // 270deg
1473 aOutRect.Left() =R.Top();
1474 aOutRect.Right() =R.Bottom();
1475 aOutRect.Top() =-R.Right();
1476 aOutRect.Bottom()=-R.Left();
1478 aOutRect.Move(rRef.X(),rRef.Y());
1479 aOutRect.Justify(); // just in case
1480 SetRectsDirty();
1481 NbcRotateGluePoints(rRef,nAngle,sn,cs);
1482 SetGlueReallyAbsolute(false);
1485 void SdrObject::NbcMirror(const Point& rRef1, const Point& rRef2)
1487 SetGlueReallyAbsolute(true);
1488 aOutRect.Move(-rRef1.X(),-rRef1.Y());
1489 Rectangle R(aOutRect);
1490 long dx=rRef2.X()-rRef1.X();
1491 long dy=rRef2.Y()-rRef1.Y();
1492 if (dx==0) { // vertical axis
1493 aOutRect.Left() =-R.Right();
1494 aOutRect.Right()=-R.Left();
1495 } else if (dy==0) { // horizontal axis
1496 aOutRect.Top() =-R.Bottom();
1497 aOutRect.Bottom()=-R.Top();
1498 } else if (dx==dy) { // 45deg axis
1499 aOutRect.Left() =R.Top();
1500 aOutRect.Right() =R.Bottom();
1501 aOutRect.Top() =R.Left();
1502 aOutRect.Bottom()=R.Right();
1503 } else if (dx==-dy) { // 45deg axis
1504 aOutRect.Left() =-R.Bottom();
1505 aOutRect.Right() =-R.Top();
1506 aOutRect.Top() =-R.Right();
1507 aOutRect.Bottom()=-R.Left();
1509 aOutRect.Move(rRef1.X(),rRef1.Y());
1510 aOutRect.Justify(); // just in case
1511 SetRectsDirty();
1512 NbcMirrorGluePoints(rRef1,rRef2);
1513 SetGlueReallyAbsolute(false);
1516 void SdrObject::NbcShear(const Point& rRef, long nAngle, double tn, bool bVShear)
1518 SetGlueReallyAbsolute(true);
1519 NbcShearGluePoints(rRef,nAngle,tn,bVShear);
1520 SetGlueReallyAbsolute(false);
1523 void SdrObject::Move(const Size& rSiz)
1525 if (rSiz.Width()!=0 || rSiz.Height()!=0) {
1526 Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect();
1527 NbcMove(rSiz);
1528 SetChanged();
1529 BroadcastObjectChange();
1530 SendUserCall(SDRUSERCALL_MOVEONLY,aBoundRect0);
1534 void SdrObject::NbcCrop(const Point& /*rRef*/, const Fraction& /*xFact*/, const Fraction& /*yFact*/) {
1535 // Default: does nothing. Real behaviour in SwVirtFlyDrawObj and SdrGrafObj
1538 void SdrObject::Resize(const Point& rRef, const Fraction& xFact, const Fraction& yFact, bool bUnsetRelative)
1540 if (xFact.GetNumerator()!=xFact.GetDenominator() || yFact.GetNumerator()!=yFact.GetDenominator()) {
1541 if (bUnsetRelative)
1543 mpImpl->mnRelativeWidth.reset();
1544 mpImpl->meRelativeWidthRelation = text::RelOrientation::PAGE_FRAME;
1545 mpImpl->meRelativeHeightRelation = text::RelOrientation::PAGE_FRAME;
1546 mpImpl->mnRelativeHeight.reset();
1548 Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect();
1549 NbcResize(rRef,xFact,yFact);
1550 SetChanged();
1551 BroadcastObjectChange();
1552 SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
1556 void SdrObject::Crop(const Point& rRef, const Fraction& xFact, const Fraction& yFact)
1558 Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect();
1559 NbcCrop(rRef, xFact, yFact);
1560 SetChanged();
1561 BroadcastObjectChange();
1562 SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
1565 void SdrObject::Rotate(const Point& rRef, long nAngle, double sn, double cs)
1567 if (nAngle!=0) {
1568 Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect();
1569 NbcRotate(rRef,nAngle,sn,cs);
1570 SetChanged();
1571 BroadcastObjectChange();
1572 SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
1576 void SdrObject::Mirror(const Point& rRef1, const Point& rRef2)
1578 Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect();
1579 NbcMirror(rRef1,rRef2);
1580 SetChanged();
1581 BroadcastObjectChange();
1582 SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
1585 void SdrObject::Shear(const Point& rRef, long nAngle, double tn, bool bVShear)
1587 if (nAngle!=0) {
1588 Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect();
1589 NbcShear(rRef,nAngle,tn,bVShear);
1590 SetChanged();
1591 BroadcastObjectChange();
1592 SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
1596 void SdrObject::NbcSetRelativePos(const Point& rPnt)
1598 Point aRelPos0(GetSnapRect().TopLeft()-aAnchor);
1599 Size aSiz(rPnt.X()-aRelPos0.X(),rPnt.Y()-aRelPos0.Y());
1600 NbcMove(aSiz); // This also calls SetRectsDirty()
1603 void SdrObject::SetRelativePos(const Point& rPnt)
1605 if (rPnt!=GetRelativePos()) {
1606 Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect();
1607 NbcSetRelativePos(rPnt);
1608 SetChanged();
1609 BroadcastObjectChange();
1610 SendUserCall(SDRUSERCALL_MOVEONLY,aBoundRect0);
1614 Point SdrObject::GetRelativePos() const
1616 return GetSnapRect().TopLeft()-aAnchor;
1619 void SdrObject::ImpSetAnchorPos(const Point& rPnt)
1621 aAnchor = rPnt;
1624 void SdrObject::NbcSetAnchorPos(const Point& rPnt)
1626 Size aSiz(rPnt.X()-aAnchor.X(),rPnt.Y()-aAnchor.Y());
1627 aAnchor=rPnt;
1628 NbcMove(aSiz); // This also calls SetRectsDirty()
1631 void SdrObject::SetAnchorPos(const Point& rPnt)
1633 if (rPnt!=aAnchor) {
1634 Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect();
1635 NbcSetAnchorPos(rPnt);
1636 SetChanged();
1637 BroadcastObjectChange();
1638 SendUserCall(SDRUSERCALL_MOVEONLY,aBoundRect0);
1642 const Point& SdrObject::GetAnchorPos() const
1644 return aAnchor;
1647 void SdrObject::RecalcSnapRect()
1651 const Rectangle& SdrObject::GetSnapRect() const
1653 return aOutRect;
1656 void SdrObject::NbcSetSnapRect(const Rectangle& rRect)
1658 aOutRect=rRect;
1661 const Rectangle& SdrObject::GetLogicRect() const
1663 return GetSnapRect();
1666 void SdrObject::NbcSetLogicRect(const Rectangle& rRect)
1668 NbcSetSnapRect(rRect);
1671 void SdrObject::AdjustToMaxRect( const Rectangle& rMaxRect, bool /* bShrinkOnly = false */ )
1673 SetLogicRect( rMaxRect );
1676 void SdrObject::SetSnapRect(const Rectangle& rRect)
1678 Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect();
1679 NbcSetSnapRect(rRect);
1680 SetChanged();
1681 BroadcastObjectChange();
1682 SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
1685 void SdrObject::SetLogicRect(const Rectangle& rRect)
1687 Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect();
1688 NbcSetLogicRect(rRect);
1689 SetChanged();
1690 BroadcastObjectChange();
1691 SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
1694 long SdrObject::GetRotateAngle() const
1696 return 0;
1699 long SdrObject::GetShearAngle(bool /*bVertical*/) const
1701 return 0;
1704 sal_uInt32 SdrObject::GetSnapPointCount() const
1706 return GetPointCount();
1709 Point SdrObject::GetSnapPoint(sal_uInt32 i) const
1711 return GetPoint(i);
1714 bool SdrObject::IsPolyObj() const
1716 return false;
1719 sal_uInt32 SdrObject::GetPointCount() const
1721 return 0L;
1724 Point SdrObject::GetPoint(sal_uInt32 /*i*/) const
1726 return Point();
1729 void SdrObject::SetPoint(const Point& rPnt, sal_uInt32 i)
1731 Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect();
1732 NbcSetPoint(rPnt, i);
1733 SetChanged();
1734 BroadcastObjectChange();
1735 SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
1738 void SdrObject::NbcSetPoint(const Point& /*rPnt*/, sal_uInt32 /*i*/)
1742 bool SdrObject::HasTextEdit() const
1744 return false;
1747 OString SdrObject::stringify() const
1749 OStringBuffer aString(100);
1750 aString.append(aAnchor.X()).
1751 append(aAnchor.Y()).
1752 append(aGridOffset.X()).
1753 append(aGridOffset.Y()).
1754 append((sal_Int32)nOrdNum).
1755 append((sal_Int32)mnNavigationPosition).
1756 append(mbSupportTextIndentingOnLineWidthChange).
1757 append(mbLineIsOutsideGeometry).
1758 append(bMarkProt).
1759 append(bIs3DObj).
1760 append(bIsEdge).
1761 append(bClosedObj).
1762 append(bNotVisibleAsMaster).
1763 append(bEmptyPresObj).
1764 append(mbVisible).
1765 append(bNoPrint).
1766 append(bSizProt).
1767 append(bMovProt).
1768 append(bGrouped).
1769 append(bInserted).
1770 append(bNetLock).
1771 append(bVirtObj).
1772 //append(maBLIPSizeRectangle).
1773 append(mnLayerID);
1775 SvMemoryStream aStream;
1776 SfxItemSet aSet(GetMergedItemSet());
1777 aSet.InvalidateDefaultItems();
1778 aSet.Store(aStream, true);
1779 aString.append(static_cast<const char *>(aStream.GetBuffer()), aStream.GetEndOfData());
1781 return aString.makeStringAndClear();
1784 void SdrObject::dumpAsXml(xmlTextWriterPtr pWriter) const
1786 xmlTextWriterStartElement(pWriter, BAD_CAST("sdrObject"));
1787 xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST("ptr"), "%p", this);
1788 xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST("symbol"), "%s", BAD_CAST(typeid(*this).name()));
1789 xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST("name"), "%s", BAD_CAST(GetName().toUtf8().getStr()));
1790 xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST("title"), "%s", BAD_CAST(GetTitle().toUtf8().getStr()));
1791 xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST("description"), "%s", BAD_CAST(GetDescription().toUtf8().getStr()));
1792 xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST("nOrdNum"), "%" SAL_PRIuUINT32, GetOrdNumDirect());
1793 xmlTextWriterWriteAttribute(pWriter, BAD_CAST("aOutRect"), BAD_CAST(aOutRect.toString().getStr()));
1795 if (const OutlinerParaObject* pOutliner = GetOutlinerParaObject())
1796 pOutliner->dumpAsXml(pWriter);
1798 xmlTextWriterEndElement(pWriter);
1801 bool SdrObject::BegTextEdit(SdrOutliner& /*rOutl*/)
1803 return false;
1806 void SdrObject::EndTextEdit(SdrOutliner& /*rOutl*/)
1810 void SdrObject::SetOutlinerParaObject(OutlinerParaObject* pTextObject)
1812 Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect();
1813 NbcSetOutlinerParaObject(pTextObject);
1814 SetChanged();
1815 BroadcastObjectChange();
1816 if (GetCurrentBoundRect()!=aBoundRect0) {
1817 SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
1821 void SdrObject::NbcSetOutlinerParaObject(OutlinerParaObject* /*pTextObject*/)
1825 OutlinerParaObject* SdrObject::GetOutlinerParaObject() const
1827 return NULL;
1830 void SdrObject::NbcReformatText()
1834 void SdrObject::ReformatText()
1836 Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect();
1837 NbcReformatText();
1838 SetChanged();
1839 BroadcastObjectChange();
1840 if (GetCurrentBoundRect()!=aBoundRect0) {
1841 SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
1845 void SdrObject::BurnInStyleSheetAttributes()
1847 GetProperties().ForceStyleToHardAttributes();
1850 bool SdrObject::HasMacro() const
1852 return false;
1855 SdrObject* SdrObject::CheckMacroHit(const SdrObjMacroHitRec& rRec) const
1857 if(rRec.pPageView)
1859 return SdrObjectPrimitiveHit(*this, rRec.aPos, rRec.nTol, *rRec.pPageView, rRec.pVisiLayer, false);
1862 return 0;
1865 Pointer SdrObject::GetMacroPointer(const SdrObjMacroHitRec&) const
1867 return Pointer(PointerStyle::RefHand);
1870 void SdrObject::PaintMacro(OutputDevice& rOut, const Rectangle& , const SdrObjMacroHitRec& ) const
1872 const RasterOp eRop(rOut.GetRasterOp());
1873 const basegfx::B2DPolyPolygon aPolyPolygon(TakeXorPoly());
1874 const sal_uInt32 nCount(aPolyPolygon.count());
1876 rOut.SetLineColor(COL_BLACK);
1877 rOut.SetFillColor();
1878 rOut.SetRasterOp(ROP_INVERT);
1880 for(sal_uInt32 a(0); a < nCount; a++)
1882 rOut.DrawPolyLine(aPolyPolygon.getB2DPolygon(a));
1885 rOut.SetRasterOp(eRop);
1888 bool SdrObject::DoMacro(const SdrObjMacroHitRec&)
1890 return false;
1893 OUString SdrObject::GetMacroPopupComment(const SdrObjMacroHitRec&) const
1895 return OUString();
1898 bool SdrObject::IsMacroHit(const SdrObjMacroHitRec& rRec) const
1900 return CheckMacroHit(rRec) != NULL;
1905 SdrObjGeoData* SdrObject::NewGeoData() const
1907 return new SdrObjGeoData;
1910 void SdrObject::SaveGeoData(SdrObjGeoData& rGeo) const
1912 rGeo.aBoundRect =GetCurrentBoundRect();
1913 rGeo.aAnchor =aAnchor ;
1914 rGeo.bMovProt =bMovProt ;
1915 rGeo.bSizProt =bSizProt ;
1916 rGeo.bNoPrint =bNoPrint ;
1917 rGeo.mbVisible =mbVisible ;
1918 rGeo.bClosedObj =bClosedObj ;
1919 rGeo.mnLayerID = mnLayerID;
1921 // user-defined glue points
1922 if (pPlusData!=NULL && pPlusData->pGluePoints!=NULL) {
1923 if (rGeo.pGPL!=NULL) {
1924 *rGeo.pGPL=*pPlusData->pGluePoints;
1925 } else {
1926 rGeo.pGPL=new SdrGluePointList(*pPlusData->pGluePoints);
1928 } else {
1929 if (rGeo.pGPL!=NULL) {
1930 delete rGeo.pGPL;
1931 rGeo.pGPL=NULL;
1936 void SdrObject::RestGeoData(const SdrObjGeoData& rGeo)
1938 SetRectsDirty();
1939 aOutRect =rGeo.aBoundRect ;
1940 aAnchor =rGeo.aAnchor ;
1941 bMovProt =rGeo.bMovProt ;
1942 bSizProt =rGeo.bSizProt ;
1943 bNoPrint =rGeo.bNoPrint ;
1944 mbVisible =rGeo.mbVisible ;
1945 bClosedObj =rGeo.bClosedObj ;
1946 mnLayerID = rGeo.mnLayerID;
1948 // user-defined glue points
1949 if (rGeo.pGPL!=NULL) {
1950 ImpForcePlusData();
1951 if (pPlusData->pGluePoints!=NULL) {
1952 *pPlusData->pGluePoints=*rGeo.pGPL;
1953 } else {
1954 pPlusData->pGluePoints=new SdrGluePointList(*rGeo.pGPL);
1956 } else {
1957 if (pPlusData!=NULL && pPlusData->pGluePoints!=NULL) {
1958 delete pPlusData->pGluePoints;
1959 pPlusData->pGluePoints=NULL;
1964 SdrObjGeoData* SdrObject::GetGeoData() const
1966 SdrObjGeoData* pGeo=NewGeoData();
1967 SaveGeoData(*pGeo);
1968 return pGeo;
1971 void SdrObject::SetGeoData(const SdrObjGeoData& rGeo)
1973 Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect();
1974 RestGeoData(rGeo);
1975 SetChanged();
1976 BroadcastObjectChange();
1977 SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
1981 // ItemSet access
1983 const SfxItemSet& SdrObject::GetObjectItemSet() const
1985 return GetProperties().GetObjectItemSet();
1988 const SfxItemSet& SdrObject::GetMergedItemSet() const
1990 return GetProperties().GetMergedItemSet();
1993 void SdrObject::SetObjectItem(const SfxPoolItem& rItem)
1995 GetProperties().SetObjectItem(rItem);
1998 void SdrObject::SetMergedItem(const SfxPoolItem& rItem)
2000 GetProperties().SetMergedItem(rItem);
2003 void SdrObject::ClearMergedItem(const sal_uInt16 nWhich)
2005 GetProperties().ClearMergedItem(nWhich);
2008 void SdrObject::SetObjectItemSet(const SfxItemSet& rSet)
2010 GetProperties().SetObjectItemSet(rSet);
2013 void SdrObject::SetMergedItemSet(const SfxItemSet& rSet, bool bClearAllItems)
2015 GetProperties().SetMergedItemSet(rSet, bClearAllItems);
2018 const SfxPoolItem& SdrObject::GetObjectItem(const sal_uInt16 nWhich) const
2020 return GetObjectItemSet().Get(nWhich);
2023 SfxMapUnit SdrObject::GetObjectMapUnit() const
2025 return GetObjectItemPool().GetMetric(0);
2028 const SfxPoolItem& SdrObject::GetMergedItem(const sal_uInt16 nWhich) const
2030 return GetMergedItemSet().Get(nWhich);
2033 void SdrObject::SetMergedItemSetAndBroadcast(const SfxItemSet& rSet, bool bClearAllItems)
2035 GetProperties().SetMergedItemSetAndBroadcast(rSet, bClearAllItems);
2038 void SdrObject::ApplyNotPersistAttr(const SfxItemSet& rAttr)
2040 Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect();
2041 NbcApplyNotPersistAttr(rAttr);
2042 SetChanged();
2043 BroadcastObjectChange();
2044 SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
2047 void SdrObject::NbcApplyNotPersistAttr(const SfxItemSet& rAttr)
2049 const Rectangle& rSnap=GetSnapRect();
2050 const Rectangle& rLogic=GetLogicRect();
2051 Point aRef1(rSnap.Center());
2052 Point aRef2(aRef1); aRef2.Y()++;
2053 const SfxPoolItem *pPoolItem=NULL;
2054 if (rAttr.GetItemState(SDRATTR_TRANSFORMREF1X,true,&pPoolItem)==SfxItemState::SET) {
2055 aRef1.X()=static_cast<const SdrTransformRef1XItem*>(pPoolItem)->GetValue();
2057 if (rAttr.GetItemState(SDRATTR_TRANSFORMREF1Y,true,&pPoolItem)==SfxItemState::SET) {
2058 aRef1.Y()=static_cast<const SdrTransformRef1YItem*>(pPoolItem)->GetValue();
2060 if (rAttr.GetItemState(SDRATTR_TRANSFORMREF2X,true,&pPoolItem)==SfxItemState::SET) {
2061 aRef2.X()=static_cast<const SdrTransformRef2XItem*>(pPoolItem)->GetValue();
2063 if (rAttr.GetItemState(SDRATTR_TRANSFORMREF2Y,true,&pPoolItem)==SfxItemState::SET) {
2064 aRef2.Y()=static_cast<const SdrTransformRef2YItem*>(pPoolItem)->GetValue();
2067 Rectangle aNewSnap(rSnap);
2068 if (rAttr.GetItemState(SDRATTR_MOVEX,true,&pPoolItem)==SfxItemState::SET) {
2069 long n=static_cast<const SdrMoveXItem*>(pPoolItem)->GetValue();
2070 aNewSnap.Move(n,0);
2072 if (rAttr.GetItemState(SDRATTR_MOVEY,true,&pPoolItem)==SfxItemState::SET) {
2073 long n=static_cast<const SdrMoveYItem*>(pPoolItem)->GetValue();
2074 aNewSnap.Move(0,n);
2076 if (rAttr.GetItemState(SDRATTR_ONEPOSITIONX,true,&pPoolItem)==SfxItemState::SET) {
2077 long n=static_cast<const SdrOnePositionXItem*>(pPoolItem)->GetValue();
2078 aNewSnap.Move(n-aNewSnap.Left(),0);
2080 if (rAttr.GetItemState(SDRATTR_ONEPOSITIONY,true,&pPoolItem)==SfxItemState::SET) {
2081 long n=static_cast<const SdrOnePositionYItem*>(pPoolItem)->GetValue();
2082 aNewSnap.Move(0,n-aNewSnap.Top());
2084 if (rAttr.GetItemState(SDRATTR_ONESIZEWIDTH,true,&pPoolItem)==SfxItemState::SET) {
2085 long n=static_cast<const SdrOneSizeWidthItem*>(pPoolItem)->GetValue();
2086 aNewSnap.Right()=aNewSnap.Left()+n;
2088 if (rAttr.GetItemState(SDRATTR_ONESIZEHEIGHT,true,&pPoolItem)==SfxItemState::SET) {
2089 long n=static_cast<const SdrOneSizeHeightItem*>(pPoolItem)->GetValue();
2090 aNewSnap.Bottom()=aNewSnap.Top()+n;
2092 if (aNewSnap!=rSnap) {
2093 if (aNewSnap.GetSize()==rSnap.GetSize()) {
2094 NbcMove(Size(aNewSnap.Left()-rSnap.Left(),aNewSnap.Top()-rSnap.Top()));
2095 } else {
2096 NbcSetSnapRect(aNewSnap);
2100 if (rAttr.GetItemState(SDRATTR_SHEARANGLE,true,&pPoolItem)==SfxItemState::SET) {
2101 long n=static_cast<const SdrShearAngleItem*>(pPoolItem)->GetValue();
2102 n-=GetShearAngle();
2103 if (n!=0) {
2104 double nTan=tan(n*nPi180);
2105 NbcShear(aRef1,n,nTan,false);
2108 if (rAttr.GetItemState(SDRATTR_ROTATEANGLE,true,&pPoolItem)==SfxItemState::SET) {
2109 long n=static_cast<const SdrAngleItem*>(pPoolItem)->GetValue();
2110 n-=GetRotateAngle();
2111 if (n!=0) {
2112 double nSin=sin(n*nPi180);
2113 double nCos=cos(n*nPi180);
2114 NbcRotate(aRef1,n,nSin,nCos);
2117 if (rAttr.GetItemState(SDRATTR_ROTATEONE,true,&pPoolItem)==SfxItemState::SET) {
2118 long n=static_cast<const SdrRotateOneItem*>(pPoolItem)->GetValue();
2119 double nSin=sin(n*nPi180);
2120 double nCos=cos(n*nPi180);
2121 NbcRotate(aRef1,n,nSin,nCos);
2123 if (rAttr.GetItemState(SDRATTR_HORZSHEARONE,true,&pPoolItem)==SfxItemState::SET) {
2124 long n=static_cast<const SdrHorzShearOneItem*>(pPoolItem)->GetValue();
2125 double nTan=tan(n*nPi180);
2126 NbcShear(aRef1,n,nTan,false);
2128 if (rAttr.GetItemState(SDRATTR_VERTSHEARONE,true,&pPoolItem)==SfxItemState::SET) {
2129 long n=static_cast<const SdrVertShearOneItem*>(pPoolItem)->GetValue();
2130 double nTan=tan(n*nPi180);
2131 NbcShear(aRef1,n,nTan,true);
2134 if (rAttr.GetItemState(SDRATTR_OBJMOVEPROTECT,true,&pPoolItem)==SfxItemState::SET) {
2135 bool b=static_cast<const SdrYesNoItem*>(pPoolItem)->GetValue();
2136 SetMoveProtect(b);
2138 if (rAttr.GetItemState(SDRATTR_OBJSIZEPROTECT,true,&pPoolItem)==SfxItemState::SET) {
2139 bool b=static_cast<const SdrYesNoItem*>(pPoolItem)->GetValue();
2140 SetResizeProtect(b);
2143 /* move protect always sets size protect */
2144 if( IsMoveProtect() )
2145 SetResizeProtect( true );
2147 if (rAttr.GetItemState(SDRATTR_OBJPRINTABLE,true,&pPoolItem)==SfxItemState::SET) {
2148 bool b=static_cast<const SdrObjPrintableItem*>(pPoolItem)->GetValue();
2149 SetPrintable(b);
2152 if (rAttr.GetItemState(SDRATTR_OBJVISIBLE,true,&pPoolItem)==SfxItemState::SET) {
2153 bool b=static_cast<const SdrObjVisibleItem*>(pPoolItem)->GetValue();
2154 SetVisible(b);
2157 SdrLayerID nLayer=SDRLAYER_NOTFOUND;
2158 if (rAttr.GetItemState(SDRATTR_LAYERID,true,&pPoolItem)==SfxItemState::SET) {
2159 nLayer=static_cast<const SdrLayerIdItem*>(pPoolItem)->GetValue();
2161 if (rAttr.GetItemState(SDRATTR_LAYERNAME,true,&pPoolItem)==SfxItemState::SET && pModel!=NULL) {
2162 OUString aLayerName=static_cast<const SdrLayerNameItem*>(pPoolItem)->GetValue();
2163 const SdrLayerAdmin* pLayAd=pPage!=NULL ? &pPage->GetLayerAdmin() : pModel!=NULL ? &pModel->GetLayerAdmin() : NULL;
2164 if (pLayAd!=NULL) {
2165 const SdrLayer* pLayer=pLayAd->GetLayer(aLayerName, true);
2166 if (pLayer!=NULL) {
2167 nLayer=pLayer->GetID();
2172 if (nLayer!=SDRLAYER_NOTFOUND) {
2173 NbcSetLayer(nLayer);
2176 if (rAttr.GetItemState(SDRATTR_OBJECTNAME,true,&pPoolItem)==SfxItemState::SET) {
2177 OUString aName=static_cast<const SfxStringItem*>(pPoolItem)->GetValue();
2178 SetName(aName);
2180 Rectangle aNewLogic(rLogic);
2181 if (rAttr.GetItemState(SDRATTR_LOGICSIZEWIDTH,true,&pPoolItem)==SfxItemState::SET) {
2182 long n=static_cast<const SdrLogicSizeWidthItem*>(pPoolItem)->GetValue();
2183 aNewLogic.Right()=aNewLogic.Left()+n;
2185 if (rAttr.GetItemState(SDRATTR_LOGICSIZEHEIGHT,true,&pPoolItem)==SfxItemState::SET) {
2186 long n=static_cast<const SdrLogicSizeHeightItem*>(pPoolItem)->GetValue();
2187 aNewLogic.Bottom()=aNewLogic.Top()+n;
2189 if (aNewLogic!=rLogic) {
2190 NbcSetLogicRect(aNewLogic);
2192 Fraction aResizeX(1,1);
2193 Fraction aResizeY(1,1);
2194 if (rAttr.GetItemState(SDRATTR_RESIZEXONE,true,&pPoolItem)==SfxItemState::SET) {
2195 aResizeX*=static_cast<const SdrResizeXOneItem*>(pPoolItem)->GetValue();
2197 if (rAttr.GetItemState(SDRATTR_RESIZEYONE,true,&pPoolItem)==SfxItemState::SET) {
2198 aResizeY*=static_cast<const SdrResizeYOneItem*>(pPoolItem)->GetValue();
2200 if (aResizeX!=Fraction(1,1) || aResizeY!=Fraction(1,1)) {
2201 NbcResize(aRef1,aResizeX,aResizeY);
2205 static void lcl_SetItem(SfxItemSet& rAttr, bool bMerge, const SfxPoolItem& rItem)
2207 if (bMerge) rAttr.MergeValue(rItem,true);
2208 else rAttr.Put(rItem);
2211 void SdrObject::TakeNotPersistAttr(SfxItemSet& rAttr, bool bMerge) const
2213 const Rectangle& rSnap=GetSnapRect();
2214 const Rectangle& rLogic=GetLogicRect();
2215 lcl_SetItem(rAttr,bMerge,makeSdrObjMoveProtectItem(IsMoveProtect()));
2216 lcl_SetItem(rAttr,bMerge,makeSdrObjSizeProtectItem(IsResizeProtect()));
2217 lcl_SetItem(rAttr,bMerge,SdrObjPrintableItem(IsPrintable()));
2218 lcl_SetItem(rAttr,bMerge,SdrObjVisibleItem(IsVisible()));
2219 lcl_SetItem(rAttr,bMerge,makeSdrRotateAngleItem(GetRotateAngle()));
2220 lcl_SetItem(rAttr,bMerge,SdrShearAngleItem(GetShearAngle()));
2221 lcl_SetItem(rAttr,bMerge,SdrOneSizeWidthItem(rSnap.GetWidth()-1));
2222 lcl_SetItem(rAttr,bMerge,SdrOneSizeHeightItem(rSnap.GetHeight()-1));
2223 lcl_SetItem(rAttr,bMerge,SdrOnePositionXItem(rSnap.Left()));
2224 lcl_SetItem(rAttr,bMerge,SdrOnePositionYItem(rSnap.Top()));
2225 if (rLogic.GetWidth()!=rSnap.GetWidth()) {
2226 lcl_SetItem(rAttr,bMerge,SdrLogicSizeWidthItem(rLogic.GetWidth()-1));
2228 if (rLogic.GetHeight()!=rSnap.GetHeight()) {
2229 lcl_SetItem(rAttr,bMerge,SdrLogicSizeHeightItem(rLogic.GetHeight()-1));
2231 OUString aName(GetName());
2233 if (!aName.isEmpty())
2235 lcl_SetItem(rAttr, bMerge, makeSdrObjectNameItem(aName));
2238 lcl_SetItem(rAttr,bMerge,SdrLayerIdItem(GetLayer()));
2239 const SdrLayerAdmin* pLayAd=pPage!=NULL ? &pPage->GetLayerAdmin() : pModel!=NULL ? &pModel->GetLayerAdmin() : NULL;
2240 if (pLayAd!=NULL) {
2241 const SdrLayer* pLayer=pLayAd->GetLayerPerID(GetLayer());
2242 if (pLayer!=NULL) {
2243 lcl_SetItem(rAttr,bMerge,SdrLayerNameItem(pLayer->GetName()));
2246 Point aRef1(rSnap.Center());
2247 Point aRef2(aRef1); aRef2.Y()++;
2248 lcl_SetItem(rAttr,bMerge,SdrTransformRef1XItem(aRef1.X()));
2249 lcl_SetItem(rAttr,bMerge,SdrTransformRef1YItem(aRef1.Y()));
2250 lcl_SetItem(rAttr,bMerge,SdrTransformRef2XItem(aRef2.X()));
2251 lcl_SetItem(rAttr,bMerge,SdrTransformRef2YItem(aRef2.Y()));
2254 SfxStyleSheet* SdrObject::GetStyleSheet() const
2256 return GetProperties().GetStyleSheet();
2259 void SdrObject::SetStyleSheet(SfxStyleSheet* pNewStyleSheet, bool bDontRemoveHardAttr)
2261 Rectangle aBoundRect0;
2263 if(pUserCall)
2264 aBoundRect0 = GetLastBoundRect();
2266 NbcSetStyleSheet(pNewStyleSheet, bDontRemoveHardAttr);
2267 SetChanged();
2268 BroadcastObjectChange();
2269 SendUserCall(SDRUSERCALL_CHGATTR, aBoundRect0);
2272 void SdrObject::NbcSetStyleSheet(SfxStyleSheet* pNewStyleSheet, bool bDontRemoveHardAttr)
2274 // only allow graphic and presentation styles for shapes
2275 if( pNewStyleSheet && (pNewStyleSheet->GetFamily() == SFX_STYLE_FAMILY_PARA) && (pNewStyleSheet->GetFamily() == SFX_STYLE_FAMILY_PAGE) )
2276 return;
2278 GetProperties().SetStyleSheet(pNewStyleSheet, bDontRemoveHardAttr);
2281 // Broadcasting while setting attributes is managed by the AttrObj.
2284 bool SdrObject::IsNode() const
2286 return true;
2289 SdrGluePoint SdrObject::GetVertexGluePoint(sal_uInt16 nPosNum) const
2291 // #i41936# Use SnapRect for default GluePoints
2292 const Rectangle aR(GetSnapRect());
2293 Point aPt;
2295 switch(nPosNum)
2297 case 0 : aPt = aR.TopCenter(); break;
2298 case 1 : aPt = aR.RightCenter(); break;
2299 case 2 : aPt = aR.BottomCenter(); break;
2300 case 3 : aPt = aR.LeftCenter(); break;
2303 aPt -= aR.Center();
2304 SdrGluePoint aGP(aPt);
2305 aGP.SetPercent(false);
2307 return aGP;
2310 SdrGluePoint SdrObject::GetCornerGluePoint(sal_uInt16 nPosNum) const
2312 Rectangle aR(GetCurrentBoundRect());
2313 Point aPt;
2314 switch (nPosNum) {
2315 case 0 : aPt=aR.TopLeft(); break;
2316 case 1 : aPt=aR.TopRight(); break;
2317 case 2 : aPt=aR.BottomRight(); break;
2318 case 3 : aPt=aR.BottomLeft(); break;
2320 aPt-=GetSnapRect().Center();
2321 SdrGluePoint aGP(aPt);
2322 aGP.SetPercent(false);
2323 return aGP;
2326 const SdrGluePointList* SdrObject::GetGluePointList() const
2328 if (pPlusData!=NULL) return pPlusData->pGluePoints;
2329 return NULL;
2333 SdrGluePointList* SdrObject::ForceGluePointList()
2335 ImpForcePlusData();
2336 if (pPlusData->pGluePoints==NULL) {
2337 pPlusData->pGluePoints=new SdrGluePointList;
2339 return pPlusData->pGluePoints;
2342 void SdrObject::SetGlueReallyAbsolute(bool bOn)
2344 // First a const call to see whether there are any glue points.
2345 // Force const call!
2346 if (GetGluePointList()!=NULL) {
2347 SdrGluePointList* pGPL=ForceGluePointList();
2348 pGPL->SetReallyAbsolute(bOn,*this);
2352 void SdrObject::NbcRotateGluePoints(const Point& rRef, long nAngle, double sn, double cs)
2354 // First a const call to see whether there are any glue points.
2355 // Force const call!
2356 if (GetGluePointList()!=NULL) {
2357 SdrGluePointList* pGPL=ForceGluePointList();
2358 pGPL->Rotate(rRef,nAngle,sn,cs,this);
2362 void SdrObject::NbcMirrorGluePoints(const Point& rRef1, const Point& rRef2)
2364 // First a const call to see whether there are any glue points.
2365 // Force const call!
2366 if (GetGluePointList()!=NULL) {
2367 SdrGluePointList* pGPL=ForceGluePointList();
2368 pGPL->Mirror(rRef1,rRef2,this);
2372 void SdrObject::NbcShearGluePoints(const Point& rRef, long nAngle, double tn, bool bVShear)
2374 // First a const call to see whether there are any glue points.
2375 // Force const call!
2376 if (GetGluePointList()!=NULL) {
2377 SdrGluePointList* pGPL=ForceGluePointList();
2378 pGPL->Shear(rRef,nAngle,tn,bVShear,this);
2382 bool SdrObject::IsEdge() const
2384 return false;
2387 void SdrObject::ConnectToNode(bool /*bTail1*/, SdrObject* /*pObj*/)
2391 void SdrObject::DisconnectFromNode(bool /*bTail1*/)
2395 SdrObject* SdrObject::GetConnectedNode(bool /*bTail1*/) const
2397 return NULL;
2402 void extractLineContourFromPrimitive2DSequence(
2403 const drawinglayer::primitive2d::Primitive2DSequence& rxSequence,
2404 basegfx::B2DPolygonVector& rExtractedHairlines,
2405 basegfx::B2DPolyPolygonVector& rExtractedLineFills)
2407 rExtractedHairlines.clear();
2408 rExtractedLineFills.clear();
2410 if(rxSequence.hasElements())
2412 // use neutral ViewInformation
2413 const drawinglayer::geometry::ViewInformation2D aViewInformation2D;
2415 // create extractor, process and get result
2416 drawinglayer::processor2d::LineGeometryExtractor2D aExtractor(aViewInformation2D);
2417 aExtractor.process(rxSequence);
2419 // copy line results
2420 rExtractedHairlines = aExtractor.getExtractedHairlines();
2422 // copy fill rsults
2423 rExtractedLineFills = aExtractor.getExtractedLineFills();
2429 SdrObject* SdrObject::ImpConvertToContourObj(SdrObject* pRet, bool bForceLineDash)
2431 bool bNoChange(true);
2433 if(pRet->LineGeometryUsageIsNecessary())
2435 basegfx::B2DPolyPolygon aMergedLineFillPolyPolygon;
2436 basegfx::B2DPolyPolygon aMergedHairlinePolyPolygon;
2437 const drawinglayer::primitive2d::Primitive2DSequence xSequence(pRet->GetViewContact().getViewIndependentPrimitive2DSequence());
2439 if(xSequence.hasElements())
2441 basegfx::B2DPolygonVector aExtractedHairlines;
2442 basegfx::B2DPolyPolygonVector aExtractedLineFills;
2444 extractLineContourFromPrimitive2DSequence(xSequence, aExtractedHairlines, aExtractedLineFills);
2446 if(!aExtractedHairlines.empty())
2448 // for SdrObject creation, just copy all to a single Hairline-PolyPolygon
2449 for(sal_uInt32 a(0); a < aExtractedHairlines.size(); a++)
2451 aMergedHairlinePolyPolygon.append(aExtractedHairlines[a]);
2455 // check for fill rsults
2456 if(!aExtractedLineFills.empty())
2458 // merge to a single tools::PolyPolygon (OR)
2459 aMergedLineFillPolyPolygon = basegfx::tools::mergeToSinglePolyPolygon(aExtractedLineFills);
2463 if(aMergedLineFillPolyPolygon.count() || (bForceLineDash && aMergedHairlinePolyPolygon.count()))
2465 SfxItemSet aSet(pRet->GetMergedItemSet());
2466 drawing::FillStyle eOldFillStyle = static_cast<const XFillStyleItem&>(aSet.Get(XATTR_FILLSTYLE)).GetValue();
2467 SdrPathObj* aLinePolygonPart = NULL;
2468 SdrPathObj* aLineHairlinePart = NULL;
2469 bool bBuildGroup(false);
2471 if(aMergedLineFillPolyPolygon.count())
2473 // create SdrObject for filled line geometry
2474 aLinePolygonPart = new SdrPathObj(OBJ_PATHFILL, aMergedLineFillPolyPolygon);
2475 aLinePolygonPart->SetModel(pRet->GetModel());
2477 // correct item properties
2478 aSet.Put(XLineWidthItem(0L));
2479 aSet.Put(XLineStyleItem(drawing::LineStyle_NONE));
2480 Color aColorLine = static_cast<const XLineColorItem&>(aSet.Get(XATTR_LINECOLOR)).GetColorValue();
2481 sal_uInt16 nTransLine = static_cast<const XLineTransparenceItem&>(aSet.Get(XATTR_LINETRANSPARENCE)).GetValue();
2482 aSet.Put(XFillColorItem(OUString(), aColorLine));
2483 aSet.Put(XFillStyleItem(drawing::FillStyle_SOLID));
2484 aSet.Put(XFillTransparenceItem(nTransLine));
2486 aLinePolygonPart->SetMergedItemSet(aSet);
2489 if(aMergedHairlinePolyPolygon.count())
2491 // create SdrObject for hairline geometry
2492 // OBJ_PATHLINE is necessary here, not OBJ_PATHFILL. This is intended
2493 // to get a non-filled object. If the poly is closed, the PathObj takes care for
2494 // the correct closed state.
2495 aLineHairlinePart = new SdrPathObj(OBJ_PATHLINE, aMergedHairlinePolyPolygon);
2496 aLineHairlinePart->SetModel(pRet->GetModel());
2498 aSet.Put(XLineWidthItem(0L));
2499 aSet.Put(XFillStyleItem(drawing::FillStyle_NONE));
2500 aSet.Put(XLineStyleItem(drawing::LineStyle_SOLID));
2502 // it is also necessary to switch off line start and ends here
2503 aSet.Put(XLineStartWidthItem(0));
2504 aSet.Put(XLineEndWidthItem(0));
2506 aLineHairlinePart->SetMergedItemSet(aSet);
2508 if(aLinePolygonPart)
2510 bBuildGroup = true;
2514 // check if original geometry should be added (e.g. filled and closed)
2515 bool bAddOriginalGeometry(false);
2516 SdrPathObj* pPath = PTR_CAST(SdrPathObj, pRet);
2518 if(pPath && pPath->IsClosed())
2520 if(eOldFillStyle != drawing::FillStyle_NONE)
2522 bAddOriginalGeometry = true;
2526 // do we need a group?
2527 if(bBuildGroup || bAddOriginalGeometry)
2529 SdrObject* pGroup = new SdrObjGroup;
2530 pGroup->SetModel(pRet->GetModel());
2532 if(bAddOriginalGeometry)
2534 // Add a clone of the original geometry.
2535 aSet.ClearItem();
2536 aSet.Put(pRet->GetMergedItemSet());
2537 aSet.Put(XLineStyleItem(drawing::LineStyle_NONE));
2538 aSet.Put(XLineWidthItem(0L));
2540 SdrObject* pClone = pRet->Clone();
2542 pClone->SetModel(pRet->GetModel());
2543 pClone->SetMergedItemSet(aSet);
2545 pGroup->GetSubList()->NbcInsertObject(pClone);
2548 if(aLinePolygonPart)
2550 pGroup->GetSubList()->NbcInsertObject(aLinePolygonPart);
2553 if(aLineHairlinePart)
2555 pGroup->GetSubList()->NbcInsertObject(aLineHairlinePart);
2558 pRet = pGroup;
2560 // be more careful with the state describing bool
2561 bNoChange = false;
2563 else
2565 if(aLinePolygonPart)
2567 pRet = aLinePolygonPart;
2568 // be more careful with the state describing bool
2569 bNoChange = false;
2571 else if(aLineHairlinePart)
2573 pRet = aLineHairlinePart;
2574 // be more careful with the state describing bool
2575 bNoChange = false;
2581 if(bNoChange)
2583 // due to current method usage, create and return a clone when nothing has changed
2584 SdrObject* pClone = pRet->Clone();
2585 pClone->SetModel(pRet->GetModel());
2586 pRet = pClone;
2589 return pRet;
2597 void SdrObject::SetMarkProtect(bool bProt)
2599 bMarkProt = bProt;
2608 void SdrObject::SetEmptyPresObj(bool bEpt)
2610 bEmptyPresObj = bEpt;
2614 void SdrObject::SetNotVisibleAsMaster(bool bFlg)
2616 bNotVisibleAsMaster=bFlg;
2622 // convert this path object to contour object, even when it is a group
2623 SdrObject* SdrObject::ConvertToContourObj(SdrObject* pRet, bool bForceLineDash) const
2625 if(pRet->ISA(SdrObjGroup))
2627 SdrObjList* pObjList2 = pRet->GetSubList();
2628 SdrObject* pGroup = new SdrObjGroup;
2629 pGroup->SetModel(pRet->GetModel());
2631 for(size_t a=0; a<pObjList2->GetObjCount(); ++a)
2633 SdrObject* pIterObj = pObjList2->GetObj(a);
2634 pGroup->GetSubList()->NbcInsertObject(ConvertToContourObj(pIterObj, bForceLineDash));
2637 pRet = pGroup;
2639 else
2641 if(pRet && pRet->ISA(SdrPathObj))
2643 SdrPathObj* pPathObj = static_cast<SdrPathObj*>(pRet);
2645 // bezier geometry got created, even for straight edges since the given
2646 // object is a result of DoConvertToPolyObj. For conversion to contour
2647 // this is not really needed and can be reduced again AFAP
2648 pPathObj->SetPathPoly(basegfx::tools::simplifyCurveSegments(pPathObj->GetPathPoly()));
2651 pRet = ImpConvertToContourObj(pRet, bForceLineDash);
2654 // #i73441# preserve LayerID
2655 if(pRet && pRet->GetLayer() != GetLayer())
2657 pRet->SetLayer(GetLayer());
2660 return pRet;
2665 SdrObject* SdrObject::ConvertToPolyObj(bool bBezier, bool bLineToArea) const
2667 SdrObject* pRet = DoConvertToPolyObj(bBezier, true);
2669 if(pRet && bLineToArea)
2671 SdrObject* pNewRet = ConvertToContourObj(pRet);
2672 delete pRet;
2673 pRet = pNewRet;
2676 // #i73441# preserve LayerID
2677 if(pRet && pRet->GetLayer() != GetLayer())
2679 pRet->SetLayer(GetLayer());
2682 return pRet;
2687 SdrObject* SdrObject::DoConvertToPolyObj(bool /*bBezier*/, bool /*bAddText*/) const
2689 return NULL;
2694 void SdrObject::SetInserted(bool bIns)
2696 if (bIns!=IsInserted()) {
2697 bInserted=bIns;
2698 Rectangle aBoundRect0(GetLastBoundRect());
2699 if (bIns) SendUserCall(SDRUSERCALL_INSERTED,aBoundRect0);
2700 else SendUserCall(SDRUSERCALL_REMOVED,aBoundRect0);
2702 if (pPlusData!=NULL && pPlusData->pBroadcast!=NULL) {
2703 SdrHint aHint(*this);
2704 aHint.SetKind(bIns?HINT_OBJINSERTED:HINT_OBJREMOVED);
2705 pPlusData->pBroadcast->Broadcast(aHint);
2710 void SdrObject::SetMoveProtect(bool bProt)
2712 if(IsMoveProtect() != bProt)
2714 // #i77187# secured and simplified
2715 bMovProt = bProt;
2716 SetChanged();
2717 BroadcastObjectChange();
2721 void SdrObject::SetResizeProtect(bool bProt)
2723 if(IsResizeProtect() != bProt)
2725 // #i77187# secured and simplified
2726 bSizProt = bProt;
2727 SetChanged();
2728 BroadcastObjectChange();
2732 void SdrObject::SetPrintable(bool bPrn)
2734 if( bPrn == bNoPrint )
2736 bNoPrint=!bPrn;
2737 SetChanged();
2738 if (IsInserted() && pModel!=NULL)
2740 SdrHint aHint(*this);
2741 pModel->Broadcast(aHint);
2746 void SdrObject::SetVisible(bool bVisible)
2748 if( bVisible != mbVisible )
2750 mbVisible = bVisible;
2751 SetChanged();
2752 if (IsInserted() && pModel!=NULL)
2754 SdrHint aHint(*this);
2755 pModel->Broadcast(aHint);
2762 sal_uInt16 SdrObject::GetUserDataCount() const
2764 if (pPlusData==NULL || pPlusData->pUserDataList==NULL) return 0;
2765 return pPlusData->pUserDataList->GetUserDataCount();
2768 SdrObjUserData* SdrObject::GetUserData(sal_uInt16 nNum) const
2770 if (pPlusData==NULL || pPlusData->pUserDataList==NULL) return NULL;
2771 return pPlusData->pUserDataList->GetUserData(nNum);
2774 void SdrObject::AppendUserData(SdrObjUserData* pData)
2776 if (!pData)
2778 OSL_FAIL("SdrObject::AppendUserData(): pData is NULL pointer.");
2779 return;
2782 ImpForcePlusData();
2783 if (!pPlusData->pUserDataList)
2784 pPlusData->pUserDataList = new SdrObjUserDataList;
2786 pPlusData->pUserDataList->AppendUserData(pData);
2789 void SdrObject::DeleteUserData(sal_uInt16 nNum)
2791 sal_uInt16 nCount=GetUserDataCount();
2792 if (nNum<nCount) {
2793 pPlusData->pUserDataList->DeleteUserData(nNum);
2794 if (nCount==1) {
2795 delete pPlusData->pUserDataList;
2796 pPlusData->pUserDataList=NULL;
2798 } else {
2799 OSL_FAIL("SdrObject::DeleteUserData(): Invalid Index.");
2803 void SdrObject::SetUserCall(SdrObjUserCall* pUser)
2805 pUserCall = pUser;
2809 void SdrObject::SendUserCall(SdrUserCallType eUserCall, const Rectangle& rBoundRect) const
2811 SdrObject* pGroup = NULL;
2813 if( pObjList && pObjList->GetListKind() == SDROBJLIST_GROUPOBJ )
2814 pGroup = pObjList->GetOwnerObj();
2816 if ( pUserCall )
2818 pUserCall->Changed( *this, eUserCall, rBoundRect );
2821 while( pGroup )
2823 // broadcast to group
2824 if( pGroup->GetUserCall() )
2826 SdrUserCallType eChildUserType = SDRUSERCALL_CHILD_CHGATTR;
2828 switch( eUserCall )
2830 case SDRUSERCALL_MOVEONLY:
2831 eChildUserType = SDRUSERCALL_CHILD_MOVEONLY;
2832 break;
2834 case SDRUSERCALL_RESIZE:
2835 eChildUserType = SDRUSERCALL_CHILD_RESIZE;
2836 break;
2838 case SDRUSERCALL_CHGATTR:
2839 eChildUserType = SDRUSERCALL_CHILD_CHGATTR;
2840 break;
2842 case SDRUSERCALL_DELETE:
2843 eChildUserType = SDRUSERCALL_CHILD_DELETE;
2844 break;
2846 case SDRUSERCALL_COPY:
2847 eChildUserType = SDRUSERCALL_CHILD_COPY;
2848 break;
2850 case SDRUSERCALL_INSERTED:
2851 eChildUserType = SDRUSERCALL_CHILD_INSERTED;
2852 break;
2854 case SDRUSERCALL_REMOVED:
2855 eChildUserType = SDRUSERCALL_CHILD_REMOVED;
2856 break;
2858 default: break;
2861 pGroup->GetUserCall()->Changed( *this, eChildUserType, rBoundRect );
2864 if( pGroup->GetObjList() &&
2865 pGroup->GetObjList()->GetListKind() == SDROBJLIST_GROUPOBJ &&
2866 pGroup != pObjList->GetOwnerObj() )
2867 pGroup = pObjList->GetOwnerObj();
2868 else
2869 pGroup = NULL;
2872 // notify our UNO shape listeners
2873 switch ( eUserCall )
2875 case SDRUSERCALL_RESIZE:
2876 notifyShapePropertyChange( svx::eShapeSize );
2877 // fall through - RESIZE might also imply a change of the position
2878 case SDRUSERCALL_MOVEONLY:
2879 notifyShapePropertyChange( svx::eShapePosition );
2880 break;
2881 default:
2882 // not interested in
2883 break;
2887 // change ItemPool for this object
2888 void SdrObject::MigrateItemPool(SfxItemPool* pSrcPool, SfxItemPool* pDestPool, SdrModel* pNewModel)
2890 if(pSrcPool && pDestPool && (pSrcPool != pDestPool))
2892 GetProperties().MoveToItemPool(pSrcPool, pDestPool, pNewModel);
2896 void SdrObject::impl_setUnoShape( const uno::Reference< uno::XInterface >& _rxUnoShape )
2898 const uno::Reference< uno::XInterface>& xOldUnoShape( maWeakUnoShape );
2899 // the UNO shape would be gutted by the following code; return early
2900 if ( _rxUnoShape == xOldUnoShape )
2902 if ( !xOldUnoShape.is() )
2904 // make sure there is no stale impl. pointer if the UNO
2905 // shape was destroyed meanwhile (remember we only hold weak
2906 // reference to it!)
2907 mpSvxShape = 0;
2909 return;
2912 bool bTransferOwnership( false );
2913 if ( xOldUnoShape.is() )
2915 bTransferOwnership = mpSvxShape->HasSdrObjectOwnership();
2916 // Remove yourself from the current UNO shape. Its destructor
2917 // will reset our UNO shape otherwise.
2918 mpSvxShape->InvalidateSdrObject();
2921 maWeakUnoShape = _rxUnoShape;
2922 mpSvxShape = SvxShape::getImplementation( _rxUnoShape );
2924 // I think this may never happen... But I am not sure enough .-)
2925 if ( bTransferOwnership )
2927 if (mpSvxShape)
2928 mpSvxShape->TakeSdrObjectOwnership();
2929 SAL_WARN( "svx.uno", "a UNO shape took over an SdrObject previously owned by another UNO shape!");
2933 /** only for internal use! */
2934 SvxShape* SdrObject::getSvxShape()
2936 DBG_TESTSOLARMUTEX();
2937 // retrieving the impl pointer and subsequently using it is not thread-safe, of course, so it needs to be
2938 // guarded by the SolarMutex
2940 uno::Reference< uno::XInterface > xShape( maWeakUnoShape );
2941 #if OSL_DEBUG_LEVEL > 0
2942 OSL_ENSURE( !( !xShape.is() && mpSvxShape ),
2943 "SdrObject::getSvxShape: still having IMPL-Pointer to dead object!" );
2944 #endif
2945 //#113608#, make sure mpSvxShape is always synchronized with maWeakUnoShape
2946 if ( mpSvxShape && !xShape.is() )
2947 mpSvxShape = NULL;
2949 return mpSvxShape;
2952 ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SdrObject::getUnoShape()
2954 // try weak reference first
2955 uno::Reference< uno::XInterface > xShape( getWeakUnoShape() );
2956 if( !xShape.is() )
2958 OSL_ENSURE( mpSvxShape == NULL, "SdrObject::getUnoShape: XShape already dead, but still an IMPL pointer!" );
2959 if ( pPage )
2961 uno::Reference< uno::XInterface > xPage( pPage->getUnoPage() );
2962 if( xPage.is() )
2964 SvxDrawPage* pDrawPage = SvxDrawPage::getImplementation(xPage);
2965 if( pDrawPage )
2967 // create one
2968 xShape = pDrawPage->_CreateShape( this );
2969 impl_setUnoShape( xShape );
2973 else
2975 mpSvxShape = SvxDrawPage::CreateShapeByTypeAndInventor( GetObjIdentifier(), GetObjInventor(), this, NULL );
2976 maWeakUnoShape = xShape = static_cast< ::cppu::OWeakObject* >( mpSvxShape );
2980 return xShape;
2983 void SdrObject::setUnoShape(const uno::Reference<uno::XInterface >& _rxUnoShape)
2985 impl_setUnoShape( _rxUnoShape );
2988 svx::PropertyChangeNotifier& SdrObject::getShapePropertyChangeNotifier()
2990 DBG_TESTSOLARMUTEX();
2992 SvxShape* pSvxShape = getSvxShape();
2993 ENSURE_OR_THROW( pSvxShape, "no SvxShape, yet!" );
2994 return pSvxShape->getShapePropertyChangeNotifier();
2997 void SdrObject::notifyShapePropertyChange( const svx::ShapeProperty _eProperty ) const
2999 DBG_TESTSOLARMUTEX();
3001 SvxShape* pSvxShape = const_cast< SdrObject* >( this )->getSvxShape();
3002 if ( pSvxShape )
3003 return pSvxShape->getShapePropertyChangeNotifier().notifyPropertyChange( _eProperty );
3008 // transformation interface for StarOfficeAPI. This implements support for
3009 // homogeneous 3x3 matrices containing the transformation of the SdrObject. At the
3010 // moment it contains a shearX, rotation and translation, but for setting all linear
3011 // transforms like Scale, ShearX, ShearY, Rotate and Translate are supported.
3014 // gets base transformation and rectangle of object. If it's an SdrPathObj it fills the PolyPolygon
3015 // with the base geometry and returns TRUE. Otherwise it returns FALSE.
3016 bool SdrObject::TRGetBaseGeometry(basegfx::B2DHomMatrix& rMatrix, basegfx::B2DPolyPolygon& /*rPolyPolygon*/) const
3018 // any kind of SdrObject, just use SnapRect
3019 Rectangle aRectangle(GetSnapRect());
3021 // convert to transformation values
3022 basegfx::B2DTuple aScale(aRectangle.GetWidth(), aRectangle.GetHeight());
3023 basegfx::B2DTuple aTranslate(aRectangle.Left(), aRectangle.Top());
3025 // position maybe relative to anchorpos, convert
3026 if( pModel && pModel->IsWriter() )
3028 if(GetAnchorPos().X() || GetAnchorPos().Y())
3030 aTranslate -= basegfx::B2DTuple(GetAnchorPos().X(), GetAnchorPos().Y());
3034 // force MapUnit to 100th mm
3035 const SfxMapUnit eMapUnit(GetObjectMapUnit());
3036 if(eMapUnit != SFX_MAPUNIT_100TH_MM)
3038 switch(eMapUnit)
3040 case SFX_MAPUNIT_TWIP :
3042 // position
3043 aTranslate.setX(ImplTwipsToMM(aTranslate.getX()));
3044 aTranslate.setY(ImplTwipsToMM(aTranslate.getY()));
3046 // size
3047 aScale.setX(ImplTwipsToMM(aScale.getX()));
3048 aScale.setY(ImplTwipsToMM(aScale.getY()));
3050 break;
3052 default:
3054 OSL_FAIL("TRGetBaseGeometry: Missing unit translation to 100th mm!");
3059 // build matrix
3060 rMatrix = basegfx::tools::createScaleTranslateB2DHomMatrix(aScale, aTranslate);
3062 return false;
3065 // sets the base geometry of the object using infos contained in the homogeneous 3x3 matrix.
3066 // If it's an SdrPathObj it will use the provided geometry information. The Polygon has
3067 // to use (0,0) as upper left and will be scaled to the given size in the matrix.
3068 void SdrObject::TRSetBaseGeometry(const basegfx::B2DHomMatrix& rMatrix, const basegfx::B2DPolyPolygon& /*rPolyPolygon*/)
3070 // break up matrix
3071 basegfx::B2DTuple aScale;
3072 basegfx::B2DTuple aTranslate;
3073 double fRotate, fShearX;
3074 rMatrix.decompose(aScale, aTranslate, fRotate, fShearX);
3076 // #i75086# Old DrawingLayer (GeoStat and geometry) does not support holding negative scalings
3077 // in X and Y which equal a 180 degree rotation. Recognize it and react accordingly
3078 if(basegfx::fTools::less(aScale.getX(), 0.0) && basegfx::fTools::less(aScale.getY(), 0.0))
3080 aScale.setX(fabs(aScale.getX()));
3081 aScale.setY(fabs(aScale.getY()));
3084 // force metric to pool metric
3085 const SfxMapUnit eMapUnit(GetObjectMapUnit());
3086 if(eMapUnit != SFX_MAPUNIT_100TH_MM)
3088 switch(eMapUnit)
3090 case SFX_MAPUNIT_TWIP :
3092 // position
3093 aTranslate.setX(ImplMMToTwips(aTranslate.getX()));
3094 aTranslate.setY(ImplMMToTwips(aTranslate.getY()));
3096 // size
3097 aScale.setX(ImplMMToTwips(aScale.getX()));
3098 aScale.setY(ImplMMToTwips(aScale.getY()));
3100 break;
3102 default:
3104 OSL_FAIL("TRSetBaseGeometry: Missing unit translation to PoolMetric!");
3109 // if anchor is used, make position relative to it
3110 if( pModel && pModel->IsWriter() )
3112 if(GetAnchorPos().X() || GetAnchorPos().Y())
3114 aTranslate += basegfx::B2DTuple(GetAnchorPos().X(), GetAnchorPos().Y());
3118 // build BaseRect
3119 Point aPoint(FRound(aTranslate.getX()), FRound(aTranslate.getY()));
3120 Rectangle aBaseRect(aPoint, Size(FRound(aScale.getX()), FRound(aScale.getY())));
3122 // set BaseRect
3123 SetSnapRect(aBaseRect);
3126 // Give info if object is in destruction
3127 bool SdrObject::IsInDestruction() const
3129 if(pModel)
3130 return pModel->IsInDestruction();
3131 return false;
3134 // return if fill is != drawing::FillStyle_NONE
3135 bool SdrObject::HasFillStyle() const
3137 return static_cast<const XFillStyleItem&>(GetObjectItem(XATTR_FILLSTYLE)).GetValue() != drawing::FillStyle_NONE;
3140 bool SdrObject::HasLineStyle() const
3142 return static_cast<const XLineStyleItem&>(GetObjectItem(XATTR_LINESTYLE)).GetValue() != drawing::LineStyle_NONE;
3146 // #i52224#
3147 // on import of OLE object from MS documents the BLIP size might be retrieved,
3148 // the following four methods are used to control it;
3149 // usually this data makes no sense after the import is finished, since the object
3150 // might be resized
3153 void SdrObject::SetBLIPSizeRectangle( const Rectangle& aRect )
3155 maBLIPSizeRectangle = aRect;
3158 void SdrObject::SetContextWritingMode( const sal_Int16 /*_nContextWritingMode*/ )
3160 // this base class does not support different writing modes, so ignore the call
3163 void SdrObject::SetDoNotInsertIntoPageAutomatically(const bool bSet)
3165 mbDoNotInsertIntoPageAutomatically = bSet;
3169 // #i121917#
3170 bool SdrObject::HasText() const
3172 return false;
3175 SdrObjFactory::SdrObjFactory(sal_uInt32 nInvent, sal_uInt16 nIdent, SdrPage* pNewPage, SdrModel* pNewModel)
3177 nInventor=nInvent;
3178 nIdentifier=nIdent;
3179 pNewObj=NULL;
3180 pPage=pNewPage;
3181 pModel=pNewModel;
3182 pObj=NULL;
3183 pNewData=NULL;
3186 SdrObject* SdrObjFactory::CreateObjectFromFactory( sal_uInt32 nInventor, sal_uInt16 nIdentifier, SdrPage* pPage, SdrModel* pModel )
3188 boost::scoped_ptr<SdrObjFactory> pFact(new SdrObjFactory(nInventor, nIdentifier, pPage, pModel));
3190 SdrLinkList& rLL = ImpGetUserMakeObjHdl();
3191 unsigned n = rLL.GetLinkCount();
3192 unsigned i = 0;
3193 SdrObject* pObj = NULL;
3194 while (i < n && !pObj)
3196 rLL.GetLink(i).Call((void*)pFact.get());
3197 pObj = pFact->pNewObj;
3198 i++;
3201 return pObj;
3204 SdrObject* SdrObjFactory::MakeNewObject(sal_uInt32 nInvent, sal_uInt16 nIdent, SdrPage* pPage, SdrModel* pModel)
3206 if (!pModel && pPage)
3207 pModel = pPage->GetModel();
3209 SdrObject* pObj = NULL;
3211 if (nInvent == SdrInventor)
3213 switch (nIdent)
3215 case sal_uInt16(OBJ_NONE ): pObj=new SdrObject; break;
3216 case sal_uInt16(OBJ_GRUP ): pObj=new SdrObjGroup; break;
3217 case sal_uInt16(OBJ_LINE ): pObj=new SdrPathObj(OBJ_LINE ); break;
3218 case sal_uInt16(OBJ_POLY ): pObj=new SdrPathObj(OBJ_POLY ); break;
3219 case sal_uInt16(OBJ_PLIN ): pObj=new SdrPathObj(OBJ_PLIN ); break;
3220 case sal_uInt16(OBJ_PATHLINE ): pObj=new SdrPathObj(OBJ_PATHLINE ); break;
3221 case sal_uInt16(OBJ_PATHFILL ): pObj=new SdrPathObj(OBJ_PATHFILL ); break;
3222 case sal_uInt16(OBJ_FREELINE ): pObj=new SdrPathObj(OBJ_FREELINE ); break;
3223 case sal_uInt16(OBJ_FREEFILL ): pObj=new SdrPathObj(OBJ_FREEFILL ); break;
3224 case sal_uInt16(OBJ_PATHPOLY ): pObj=new SdrPathObj(OBJ_POLY ); break;
3225 case sal_uInt16(OBJ_PATHPLIN ): pObj=new SdrPathObj(OBJ_PLIN ); break;
3226 case sal_uInt16(OBJ_EDGE ): pObj=new SdrEdgeObj; break;
3227 case sal_uInt16(OBJ_RECT ): pObj=new SdrRectObj; break;
3228 case sal_uInt16(OBJ_CIRC ): pObj=new SdrCircObj(OBJ_CIRC ); break;
3229 case sal_uInt16(OBJ_SECT ): pObj=new SdrCircObj(OBJ_SECT ); break;
3230 case sal_uInt16(OBJ_CARC ): pObj=new SdrCircObj(OBJ_CARC ); break;
3231 case sal_uInt16(OBJ_CCUT ): pObj=new SdrCircObj(OBJ_CCUT ); break;
3232 case sal_uInt16(OBJ_TEXT ): pObj=new SdrRectObj(OBJ_TEXT ); break;
3233 case sal_uInt16(OBJ_TEXTEXT ): pObj=new SdrRectObj(OBJ_TEXTEXT ); break;
3234 case sal_uInt16(OBJ_TITLETEXT ): pObj=new SdrRectObj(OBJ_TITLETEXT ); break;
3235 case sal_uInt16(OBJ_OUTLINETEXT): pObj=new SdrRectObj(OBJ_OUTLINETEXT); break;
3236 case sal_uInt16(OBJ_MEASURE ): pObj=new SdrMeasureObj; break;
3237 case sal_uInt16(OBJ_GRAF ): pObj=new SdrGrafObj; break;
3238 case sal_uInt16(OBJ_OLE2 ): pObj=new SdrOle2Obj; break;
3239 case sal_uInt16(OBJ_FRAME ): pObj=new SdrOle2Obj(true); break;
3240 case sal_uInt16(OBJ_CAPTION ): pObj=new SdrCaptionObj; break;
3241 case sal_uInt16(OBJ_PAGE ): pObj=new SdrPageObj; break;
3242 case sal_uInt16(OBJ_UNO ): pObj=new SdrUnoObj(OUString()); break;
3243 case sal_uInt16(OBJ_CUSTOMSHAPE ): pObj=new SdrObjCustomShape(); break;
3244 #if HAVE_FEATURE_AVMEDIA
3245 case sal_uInt16(OBJ_MEDIA ): pObj=new SdrMediaObj(); break;
3246 #endif
3247 case sal_uInt16(OBJ_TABLE ): pObj=new sdr::table::SdrTableObj(pModel); break;
3248 case sal_uInt16(OBJ_OPENGL ): pObj=new SdrOpenGLObj; break;
3252 if (!pObj)
3253 pObj = CreateObjectFromFactory(nInvent, nIdent, pPage, pModel);
3255 if (!pObj)
3257 // Well, if no one wants it...
3258 return NULL;
3261 if (pPage)
3262 pObj->SetPage(pPage);
3263 else if (pModel)
3264 pObj->SetModel(pModel);
3266 return pObj;
3269 SdrObject* SdrObjFactory::MakeNewObject(
3270 sal_uInt32 nInventor, sal_uInt16 nIdentifier, const Rectangle& rSnapRect, SdrPage* pPage )
3272 SdrModel* pModel = pPage ? pPage->GetModel() : NULL;
3274 SdrObject* pObj = NULL;
3276 bool bSetSnapRect = true;
3278 if (nInventor == SdrInventor)
3280 switch (nIdentifier)
3282 case OBJ_MEASURE:
3284 pObj = new SdrMeasureObj(rSnapRect.TopLeft(), rSnapRect.BottomRight());
3286 break;
3287 case OBJ_LINE:
3289 basegfx::B2DPolygon aPoly;
3290 aPoly.append(basegfx::B2DPoint(rSnapRect.Left(), rSnapRect.Top()));
3291 aPoly.append(basegfx::B2DPoint(rSnapRect.Right(), rSnapRect.Bottom()));
3292 pObj = new SdrPathObj(OBJ_LINE, basegfx::B2DPolyPolygon(aPoly));
3294 break;
3295 case OBJ_TEXT:
3296 case OBJ_TEXTEXT:
3297 case OBJ_TITLETEXT:
3298 case OBJ_OUTLINETEXT:
3300 pObj = new SdrRectObj(static_cast<SdrObjKind>(nIdentifier), rSnapRect);
3301 bSetSnapRect = false;
3303 break;
3304 case OBJ_CIRC:
3305 case OBJ_SECT:
3306 case OBJ_CARC:
3307 case OBJ_CCUT:
3309 pObj = new SdrCircObj(static_cast<SdrObjKind>(nIdentifier), rSnapRect);
3310 bSetSnapRect = false;
3312 break;
3313 case sal_uInt16(OBJ_NONE ): pObj=new SdrObject; break;
3314 case sal_uInt16(OBJ_GRUP ): pObj=new SdrObjGroup; break;
3315 case sal_uInt16(OBJ_POLY ): pObj=new SdrPathObj(OBJ_POLY ); break;
3316 case sal_uInt16(OBJ_PLIN ): pObj=new SdrPathObj(OBJ_PLIN ); break;
3317 case sal_uInt16(OBJ_PATHLINE ): pObj=new SdrPathObj(OBJ_PATHLINE ); break;
3318 case sal_uInt16(OBJ_PATHFILL ): pObj=new SdrPathObj(OBJ_PATHFILL ); break;
3319 case sal_uInt16(OBJ_FREELINE ): pObj=new SdrPathObj(OBJ_FREELINE ); break;
3320 case sal_uInt16(OBJ_FREEFILL ): pObj=new SdrPathObj(OBJ_FREEFILL ); break;
3321 case sal_uInt16(OBJ_PATHPOLY ): pObj=new SdrPathObj(OBJ_POLY ); break;
3322 case sal_uInt16(OBJ_PATHPLIN ): pObj=new SdrPathObj(OBJ_PLIN ); break;
3323 case sal_uInt16(OBJ_EDGE ): pObj=new SdrEdgeObj; break;
3324 case sal_uInt16(OBJ_RECT ): pObj=new SdrRectObj; break;
3325 case sal_uInt16(OBJ_GRAF ): pObj=new SdrGrafObj; break;
3326 case sal_uInt16(OBJ_OLE2 ): pObj=new SdrOle2Obj; break;
3327 case sal_uInt16(OBJ_FRAME ): pObj=new SdrOle2Obj(true); break;
3328 case sal_uInt16(OBJ_CAPTION ): pObj=new SdrCaptionObj; break;
3329 case sal_uInt16(OBJ_PAGE ): pObj=new SdrPageObj; break;
3330 case sal_uInt16(OBJ_UNO ): pObj=new SdrUnoObj(OUString()); break;
3331 case sal_uInt16(OBJ_CUSTOMSHAPE ): pObj=new SdrObjCustomShape(); break;
3332 #if HAVE_FEATURE_AVMEDIA
3333 case sal_uInt16(OBJ_MEDIA ): pObj=new SdrMediaObj(); break;
3334 #endif
3335 case sal_uInt16(OBJ_TABLE ): pObj=new sdr::table::SdrTableObj(pModel); break;
3336 case sal_uInt16(OBJ_OPENGL ): pObj=new SdrOpenGLObj; break;
3340 if (!pObj)
3341 pObj = CreateObjectFromFactory(nInventor, nIdentifier, pPage, pModel);
3343 if (!pObj)
3345 // Well, if no one wants it...
3346 return NULL;
3349 if (pPage)
3350 pObj->SetPage(pPage);
3352 if (bSetSnapRect)
3353 pObj->SetSnapRect(rSnapRect);
3355 return pObj;
3358 void SdrObjFactory::InsertMakeObjectHdl(const Link<>& rLink)
3360 SdrLinkList& rLL=ImpGetUserMakeObjHdl();
3361 rLL.InsertLink(rLink);
3364 void SdrObjFactory::RemoveMakeObjectHdl(const Link<>& rLink)
3366 SdrLinkList& rLL=ImpGetUserMakeObjHdl();
3367 rLL.RemoveLink(rLink);
3370 void SdrObjFactory::InsertMakeUserDataHdl(const Link<>& rLink)
3372 SdrLinkList& rLL=ImpGetUserMakeObjUserDataHdl();
3373 rLL.InsertLink(rLink);
3376 void SdrObjFactory::RemoveMakeUserDataHdl(const Link<>& rLink)
3378 SdrLinkList& rLL=ImpGetUserMakeObjUserDataHdl();
3379 rLL.RemoveLink(rLink);
3382 namespace svx
3384 ISdrObjectFilter::~ISdrObjectFilter()
3389 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */