Version 4.3.0.0.beta1, tag libreoffice-4.3.0.0.beta1
[LibreOffice.git] / svx / source / svdraw / svdobj.cxx
blobca94637feb5aa157d278dff3be0e35e84b61294e
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 <config_features.h>
22 #include "sal/config.h"
24 #include <com/sun/star/lang/XComponent.hpp>
25 #include <com/sun/star/text/RelOrientation.hpp>
27 #include "svdconv.hxx"
29 #include <basegfx/matrix/b2dhommatrix.hxx>
30 #include <basegfx/matrix/b2dhommatrixtools.hxx>
31 #include <basegfx/polygon/b2dpolygon.hxx>
32 #include <basegfx/polygon/b2dpolygontools.hxx>
33 #include <basegfx/polygon/b2dpolypolygoncutter.hxx>
34 #include <basegfx/polygon/b2dpolypolygontools.hxx>
35 #include <basegfx/range/b2drange.hxx>
36 #include <drawinglayer/processor2d/contourextractor2d.hxx>
37 #include <drawinglayer/processor2d/linegeometryextractor2d.hxx>
38 #include <editeng/editeng.hxx>
39 #include <editeng/eeitem.hxx>
40 #include <math.h>
41 #include <sfx2/objface.hxx>
42 #include <sfx2/objsh.hxx>
43 #include <svl/whiter.hxx>
44 #include <svl/grabbagitem.hxx>
45 #include <svtools/colorcfg.hxx>
46 #include <tools/bigint.hxx>
47 #include <tools/diagnose_ex.h>
48 #include <tools/helpers.hxx>
49 #include <tools/line.hxx>
50 #include <vcl/graphictools.hxx>
51 #include <vcl/metaact.hxx>
52 #include <vcl/virdev.hxx>
53 #include <vector>
55 #include "svx/shapepropertynotifier.hxx"
56 #include "svdglob.hxx"
57 #include "svx/svdotable.hxx"
58 #include "svx/xlinjoit.hxx"
60 #include <svx/fmmodel.hxx>
61 #include <svx/polysc3d.hxx>
62 #include <svx/sdr/contact/displayinfo.hxx>
63 #include <svx/sdr/contact/objectcontactofobjlistpainter.hxx>
64 #include <sdr/contact/viewcontactofgraphic.hxx>
65 #include <svx/sdr/contact/viewcontactofsdrobj.hxx>
66 #include <svx/sdr/properties/emptyproperties.hxx>
67 #include <svx/sdrhittesthelper.hxx>
68 #include <svx/sdrobjectfilter.hxx>
69 #include <svx/svddrag.hxx>
70 #include <svx/svdetc.hxx>
71 #include <svx/svdhdl.hxx>
72 #include <svx/svditer.hxx>
73 #include <svx/svdmodel.hxx>
74 #include <svx/svdoashp.hxx>
75 #include <svx/svdobj.hxx>
76 #include <svx/svdocapt.hxx>
77 #include <svx/svdocirc.hxx>
78 #include <svx/svdoedge.hxx>
79 #include <svx/svdograf.hxx>
80 #include <svx/svdogrp.hxx>
81 #include <svx/svdomeas.hxx>
82 #include <svx/svdomedia.hxx>
83 #include <svx/svdoole2.hxx>
84 #include <svx/svdopage.hxx>
85 #include <svx/svdopath.hxx>
86 #include <svx/svdorect.hxx>
87 #include <svx/svdotext.hxx>
88 #include <svx/svdouno.hxx>
89 #include <svx/svdovirt.hxx>
90 #include <svx/svdpage.hxx>
91 #include <svx/svdpool.hxx>
92 #include <svx/svdstr.hrc>
93 #include <svx/svdtrans.hxx>
94 #include <svx/svdundo.hxx>
95 #include <svx/svdview.hxx>
96 #include <sxlayitm.hxx>
97 #include <sxlogitm.hxx>
98 #include <sxmovitm.hxx>
99 #include <svx/sxmspitm.hxx>
100 #include <sxoneitm.hxx>
101 #include <sxonitm.hxx>
102 #include <sxopitm.hxx>
103 #include <sxraitm.hxx>
104 #include <sxreoitm.hxx>
105 #include <sxrooitm.hxx>
106 #include <sxsaitm.hxx>
107 #include <sxsoitm.hxx>
108 #include <sxtraitm.hxx>
109 #include <svx/unopage.hxx>
110 #include <svx/unoshape.hxx>
111 #include <svx/xbtmpit.hxx>
112 #include <svx/xenum.hxx>
113 #include <svx/xflclit.hxx>
114 #include <svx/xflftrit.hxx>
115 #include <svx/xflhtit.hxx>
116 #include <svx/xfltrit.hxx>
117 #include <svx/xgrad.hxx>
118 #include <svx/xhatch.hxx>
119 #include <svx/xlnclit.hxx>
120 #include <svx/xlndsit.hxx>
121 #include <svx/xlnedcit.hxx>
122 #include <svx/xlnedit.hxx>
123 #include <svx/xlnedwit.hxx>
124 #include <svx/xlnstcit.hxx>
125 #include <svx/xlnstit.hxx>
126 #include <svx/xlnstwit.hxx>
127 #include <svx/xlntrit.hxx>
128 #include <svx/xlnwtit.hxx>
129 #include <svx/xpoly.hxx>
130 #include <rtl/strbuf.hxx>
131 #include <svdoopengl.hxx>
133 using namespace ::com::sun::star;
137 TYPEINIT0(SdrObjUserCall);
139 SdrObjUserCall::~SdrObjUserCall()
143 void SdrObjUserCall::Changed(const SdrObject& /*rObj*/, SdrUserCallType /*eType*/, const Rectangle& /*rOldBoundRect*/)
147 SdrObjMacroHitRec::SdrObjMacroHitRec() :
148 pOut(NULL),
149 pVisiLayer(NULL),
150 pPageView(NULL),
151 nTol(0),
152 bDown(false) {}
156 TYPEINIT0(SdrObjUserData);
158 SdrObjUserData::SdrObjUserData(sal_uInt32 nInv, sal_uInt16 nId, sal_uInt16 nVer) :
159 nInventor(nInv),
160 nIdentifier(nId),
161 nVersion(nVer) {}
163 SdrObjUserData::SdrObjUserData(const SdrObjUserData& rData) :
164 nInventor(rData.nInventor),
165 nIdentifier(rData.nIdentifier),
166 nVersion(rData.nVersion) {}
168 SdrObjUserData::~SdrObjUserData() {}
170 sal_uInt32 SdrObjUserData::GetInventor() const
172 return nInventor;
175 sal_uInt16 SdrObjUserData::GetId() const
177 return nIdentifier;
180 bool SdrObjUserData::HasMacro(const SdrObject* /*pObj*/) const
182 return false;
185 SdrObject* SdrObjUserData::CheckMacroHit(const SdrObjMacroHitRec& rRec, const SdrObject* pObj) const
187 if(pObj)
189 if(rRec.pPageView)
191 return SdrObjectPrimitiveHit(*pObj, rRec.aPos, rRec.nTol, *rRec.pPageView, rRec.pVisiLayer, false);
195 return 0;
198 Pointer SdrObjUserData::GetMacroPointer(const SdrObjMacroHitRec& /*rRec*/, const SdrObject* /*pObj*/) const
200 return Pointer(POINTER_REFHAND);
203 void SdrObjUserData::PaintMacro(OutputDevice& rOut, const Rectangle& /*rDirtyRect*/, const SdrObjMacroHitRec& /*rRec*/, const SdrObject* pObj) const
205 if(!pObj)
206 return;
208 const RasterOp eRop(rOut.GetRasterOp());
209 const basegfx::B2DPolyPolygon aPolyPolygon(pObj->TakeXorPoly());
210 const sal_uInt32 nCount(aPolyPolygon.count());
212 rOut.SetLineColor(COL_BLACK);
213 rOut.SetFillColor();
214 rOut.SetRasterOp(ROP_INVERT);
216 for(sal_uInt32 a(0); a < nCount; a++)
218 rOut.DrawPolyLine(aPolyPolygon.getB2DPolygon(a));
221 rOut.SetRasterOp(eRop);
224 bool SdrObjUserData::DoMacro(const SdrObjMacroHitRec& /*rRec*/, SdrObject* /*pObj*/)
226 return false;
229 OUString SdrObjUserData::GetMacroPopupComment(const SdrObjMacroHitRec& /*rRec*/, const SdrObject* /*pObj*/) const
231 return OUString();
234 SdrObjUserDataList::SdrObjUserDataList() {}
235 SdrObjUserDataList::~SdrObjUserDataList() {}
237 size_t SdrObjUserDataList::GetUserDataCount() const
239 return static_cast<sal_uInt16>(maList.size());
242 const SdrObjUserData* SdrObjUserDataList::GetUserData(size_t nNum) const
244 return &maList.at(nNum);
247 SdrObjUserData* SdrObjUserDataList::GetUserData(size_t nNum)
249 return &maList.at(nNum);
252 void SdrObjUserDataList::AppendUserData(SdrObjUserData* pData)
254 maList.push_back(pData);
257 void SdrObjUserDataList::DeleteUserData(size_t nNum)
259 maList.erase(maList.begin()+nNum);
265 SdrObjGeoData::SdrObjGeoData():
266 pGPL(NULL),
267 bMovProt(false),
268 bSizProt(false),
269 bNoPrint(false),
270 bClosedObj(false),
271 mbVisible(true),
272 mnLayerID(0)
276 SdrObjGeoData::~SdrObjGeoData()
278 delete pGPL;
283 TYPEINIT0(SdrObjPlusData);
285 SdrObjPlusData::SdrObjPlusData():
286 pBroadcast(NULL),
287 pUserDataList(NULL),
288 pGluePoints(NULL)
292 SdrObjPlusData::~SdrObjPlusData()
294 delete pBroadcast;
295 delete pUserDataList;
296 delete pGluePoints;
299 SdrObjPlusData* SdrObjPlusData::Clone(SdrObject* pObj1) const
301 SdrObjPlusData* pNeuPlusData=new SdrObjPlusData;
302 if (pUserDataList!=NULL) {
303 sal_uInt16 nAnz=pUserDataList->GetUserDataCount();
304 if (nAnz!=0) {
305 pNeuPlusData->pUserDataList=new SdrObjUserDataList;
306 for (sal_uInt16 i=0; i<nAnz; i++) {
307 SdrObjUserData* pNeuUserData=pUserDataList->GetUserData(i)->Clone(pObj1);
308 if (pNeuUserData!=NULL) {
309 pNeuPlusData->pUserDataList->AppendUserData(pNeuUserData);
310 } else {
311 OSL_FAIL("SdrObjPlusData::Clone(): UserData.Clone() returns NULL.");
316 if (pGluePoints!=NULL) pNeuPlusData->pGluePoints=new SdrGluePointList(*pGluePoints);
317 // MtfAnimator isn't copied either
319 // #i68101#
320 // copy object name, title and description
321 pNeuPlusData->aObjName = aObjName;
322 pNeuPlusData->aObjTitle = aObjTitle;
323 pNeuPlusData->aObjDescription = aObjDescription;
325 return pNeuPlusData;
328 void SdrObjPlusData::SetGluePoints(const SdrGluePointList& rPts)
330 return *pGluePoints = rPts;
333 SdrObjTransformInfoRec::SdrObjTransformInfoRec() :
334 bSelectAllowed(true),
335 bMoveAllowed(true),
336 bResizeFreeAllowed(true),
337 bResizePropAllowed(true),
338 bRotateFreeAllowed(true),
339 bRotate90Allowed(true),
340 bMirrorFreeAllowed(true),
341 bMirror45Allowed(true),
342 bMirror90Allowed(true),
343 bTransparenceAllowed(true),
344 bGradientAllowed(true),
345 bShearAllowed(true),
346 bEdgeRadiusAllowed(true),
347 bNoOrthoDesired(true),
348 bNoContortion(true),
349 bCanConvToPath(true),
350 bCanConvToPoly(true),
351 bCanConvToContour(false),
352 bCanConvToPathLineToArea(true),
353 bCanConvToPolyLineToArea(true) {}
356 // BaseProperties section
358 sdr::properties::BaseProperties* SdrObject::CreateObjectSpecificProperties()
360 return new sdr::properties::EmptyProperties(*this);
363 sdr::properties::BaseProperties& SdrObject::GetProperties() const
365 if(!mpProperties)
367 const_cast< SdrObject* >(this)->mpProperties =
368 const_cast< SdrObject* >(this)->CreateObjectSpecificProperties();
371 return *mpProperties;
375 // ObjectUser section
377 void SdrObject::AddObjectUser(sdr::ObjectUser& rNewUser)
379 maObjectUsers.push_back(&rNewUser);
382 void SdrObject::RemoveObjectUser(sdr::ObjectUser& rOldUser)
384 const ::sdr::ObjectUserVector::iterator aFindResult = ::std::find(maObjectUsers.begin(), maObjectUsers.end(), &rOldUser);
385 if(aFindResult != maObjectUsers.end())
387 maObjectUsers.erase(aFindResult);
392 // DrawContact section
394 sdr::contact::ViewContact* SdrObject::CreateObjectSpecificViewContact()
396 return new sdr::contact::ViewContactOfSdrObj(*this);
399 sdr::contact::ViewContact& SdrObject::GetViewContact() const
401 if(!mpViewContact)
403 const_cast< SdrObject* >(this)->mpViewContact =
404 const_cast< SdrObject* >(this)->CreateObjectSpecificViewContact();
407 return *mpViewContact;
410 // DrawContact support: Methods for handling Object changes
411 void SdrObject::ActionChanged() const
413 // Do necessary ViewContact actions
414 GetViewContact().ActionChanged();
419 void SdrObject::SetBoundRectDirty()
421 aOutRect = Rectangle();
426 TYPEINIT1(SdrObject,SfxListener);
428 SdrObject::SdrObject()
429 :mpProperties(0L)
430 ,mpViewContact(0L)
431 ,pObjList(NULL)
432 ,pPage(NULL)
433 ,pModel(NULL)
434 ,pUserCall(NULL)
435 ,pPlusData(NULL)
436 ,nOrdNum(0)
437 ,pGrabBagItem(NULL)
438 ,mnNavigationPosition(SAL_MAX_UINT32)
439 ,mnLayerID(0)
440 ,meRelativeWidthRelation(text::RelOrientation::PAGE_FRAME)
441 ,meRelativeHeightRelation(text::RelOrientation::PAGE_FRAME)
442 ,mpSvxShape( NULL )
443 ,maWeakUnoShape()
444 ,mbDoNotInsertIntoPageAutomatically(false)
446 bVirtObj =false;
447 bSnapRectDirty =true;
448 bNetLock =false;
449 bInserted =false;
450 bGrouped =false;
451 bMovProt =false;
452 bSizProt =false;
453 bNoPrint =false;
454 bEmptyPresObj =false;
455 bNotVisibleAsMaster=false;
456 bClosedObj =false;
457 mbVisible = true;
459 // #i25616#
460 mbLineIsOutsideGeometry = false;
462 // #i25616#
463 mbSupportTextIndentingOnLineWidthChange = false;
465 bNotMasterCachable=false;
466 bIsEdge=false;
467 bIs3DObj=false;
468 bMarkProt=false;
469 bIsUnoObj=false;
472 SdrObject::~SdrObject()
474 // tell all the registered ObjectUsers that the page is in destruction
475 ::sdr::ObjectUserVector aListCopy(maObjectUsers.begin(), maObjectUsers.end());
476 for(::sdr::ObjectUserVector::iterator aIterator = aListCopy.begin(); aIterator != aListCopy.end(); ++aIterator)
478 sdr::ObjectUser* pObjectUser = *aIterator;
479 DBG_ASSERT(pObjectUser, "SdrObject::~SdrObject: corrupt ObjectUser list (!)");
480 pObjectUser->ObjectInDestruction(*this);
483 // Clear the vector. This means that user do not need to call RemoveObjectUser()
484 // when they get called from ObjectInDestruction().
485 maObjectUsers.clear();
489 SvxShape* pSvxShape = getSvxShape();
490 if ( pSvxShape )
492 OSL_ENSURE(!pSvxShape->HasSdrObjectOwnership(),"Please check where this call come from and replace it with SdrObject::Free");
493 pSvxShape->InvalidateSdrObject();
494 uno::Reference< lang::XComponent > xShapeComp( getWeakUnoShape(), uno::UNO_QUERY_THROW );
495 xShapeComp->dispose();
498 catch( const uno::Exception& )
500 DBG_UNHANDLED_EXCEPTION();
503 SendUserCall(SDRUSERCALL_DELETE, GetLastBoundRect());
504 delete pPlusData;
506 delete pGrabBagItem;
508 if(mpProperties)
510 delete mpProperties;
511 mpProperties = 0L;
514 if(mpViewContact)
516 delete mpViewContact;
517 mpViewContact = 0L;
521 void SdrObject::Free( SdrObject*& _rpObject )
523 SdrObject* pObject = _rpObject; _rpObject = NULL;
524 if ( pObject == NULL )
525 // nothing to do
526 return;
528 SvxShape* pShape = pObject->getSvxShape();
529 if ( pShape && pShape->HasSdrObjectOwnership() )
530 // only the shape is allowed to delete me, and will reset the ownership before doing so
531 return;
533 delete pObject;
536 SdrObjPlusData* SdrObject::NewPlusData() const
538 return new SdrObjPlusData;
541 void SdrObject::SetRectsDirty(bool bNotMyself)
543 if (!bNotMyself) {
544 SetBoundRectDirty();
545 bSnapRectDirty=true;
547 if (pObjList!=NULL) {
548 pObjList->SetRectsDirty();
552 void SdrObject::SetModel(SdrModel* pNewModel)
554 if(pNewModel && pPage)
556 if(pPage->GetModel() != pNewModel)
558 pPage = NULL;
562 // update listeners at possible API wrapper object
563 if( pModel != pNewModel )
565 SvxShape* pShape = getSvxShape();
566 if( pShape )
567 pShape->ChangeModel( pNewModel );
570 pModel = pNewModel;
573 SdrModel* SdrObject::GetModel() const
575 return pModel;
578 void SdrObject::SetObjList(SdrObjList* pNewObjList)
580 pObjList=pNewObjList;
583 SdrObjList* SdrObject::GetObjList() const
585 return pObjList;
588 void SdrObject::SetPage(SdrPage* pNewPage)
590 SdrModel* pOldModel = pModel;
591 SdrPage* pOldPage = pPage;
593 pPage=pNewPage;
594 if (pPage!=NULL) {
595 SdrModel* pMod=pPage->GetModel();
596 if (pMod!=pModel && pMod!=NULL) {
597 SetModel(pMod);
600 // The creation of the UNO shape in SdrObject::getUnoShape is influenced
601 // by pPage, so when the page changes we need to discard the cached UNO
602 // shape so that a new one will be created.
603 // If the page is changing to another page with the same model, we
604 // assume they create compatible UNO shape objects so we shouldn't have
605 // to invalidate.
606 if (pOldPage != pPage && !(pOldPage && pPage && pOldModel == pModel))
608 SvxShape* const pShape(getSvxShape());
609 if (pShape && !pShape->HasSdrObjectOwnership())
610 setUnoShape(NULL);
614 SdrPage* SdrObject::GetPage() const
616 return pPage;
619 // init global static itempool
620 SdrItemPool* SdrObject::mpGlobalItemPool = NULL;
622 SdrItemPool& SdrObject::GetGlobalDrawObjectItemPool()
624 if(!mpGlobalItemPool)
626 mpGlobalItemPool = new SdrItemPool();
627 SfxItemPool* pGlobalOutlPool = EditEngine::CreatePool();
628 mpGlobalItemPool->SetSecondaryPool(pGlobalOutlPool);
629 mpGlobalItemPool->SetDefaultMetric((SfxMapUnit)SdrEngineDefaults::GetMapUnit());
630 mpGlobalItemPool->FreezeIdRanges();
633 return *mpGlobalItemPool;
636 SdrItemPool* SdrObject::GetObjectItemPool() const
638 if(pModel)
639 return (SdrItemPool*)(&pModel->GetItemPool());
641 // use a static global default pool
642 return &SdrObject::GetGlobalDrawObjectItemPool();
645 sal_uInt32 SdrObject::GetObjInventor() const
647 return SdrInventor;
650 sal_uInt16 SdrObject::GetObjIdentifier() const
652 return sal_uInt16(OBJ_NONE);
655 void SdrObject::TakeObjInfo(SdrObjTransformInfoRec& rInfo) const
657 rInfo.bRotateFreeAllowed=false;
658 rInfo.bMirrorFreeAllowed=false;
659 rInfo.bTransparenceAllowed = false;
660 rInfo.bGradientAllowed = false;
661 rInfo.bShearAllowed =false;
662 rInfo.bEdgeRadiusAllowed=false;
663 rInfo.bCanConvToPath =false;
664 rInfo.bCanConvToPoly =false;
665 rInfo.bCanConvToContour = false;
666 rInfo.bCanConvToPathLineToArea=false;
667 rInfo.bCanConvToPolyLineToArea=false;
670 SdrLayerID SdrObject::GetLayer() const
672 return mnLayerID;
675 void SdrObject::getMergedHierarchyLayerSet(SetOfByte& rSet) const
677 rSet.Set(GetLayer());
678 SdrObjList* pOL=GetSubList();
679 if (pOL!=NULL) {
680 sal_uIntPtr nObjAnz=pOL->GetObjCount();
681 for (sal_uIntPtr nObjNum=0; nObjNum<nObjAnz; nObjNum++) {
682 pOL->GetObj(nObjNum)->getMergedHierarchyLayerSet(rSet);
687 void SdrObject::NbcSetLayer(SdrLayerID nLayer)
689 mnLayerID = nLayer;
692 void SdrObject::SetLayer(SdrLayerID nLayer)
694 NbcSetLayer(nLayer);
695 SetChanged();
696 BroadcastObjectChange();
699 void SdrObject::AddListener(SfxListener& rListener)
701 ImpForcePlusData();
702 if (pPlusData->pBroadcast==NULL) pPlusData->pBroadcast=new SfxBroadcaster;
703 rListener.StartListening(*pPlusData->pBroadcast);
706 void SdrObject::RemoveListener(SfxListener& rListener)
708 if (pPlusData!=NULL && pPlusData->pBroadcast!=NULL) {
709 rListener.EndListening(*pPlusData->pBroadcast);
710 if (!pPlusData->pBroadcast->HasListeners()) {
711 delete pPlusData->pBroadcast;
712 pPlusData->pBroadcast=NULL;
717 const SfxBroadcaster* SdrObject::GetBroadcaster() const
719 return pPlusData!=NULL ? pPlusData->pBroadcast : NULL;
722 void SdrObject::AddReference(SdrVirtObj& rVrtObj)
724 AddListener(rVrtObj);
727 void SdrObject::DelReference(SdrVirtObj& rVrtObj)
729 RemoveListener(rVrtObj);
732 bool SdrObject::HasRefPoint() const
734 return false;
737 Point SdrObject::GetRefPoint() const
739 return GetCurrentBoundRect().Center();
742 void SdrObject::SetRefPoint(const Point& /*rPnt*/)
746 bool SdrObject::IsGroupObject() const
748 return GetSubList()!=NULL;
751 SdrObjList* SdrObject::GetSubList() const
753 return NULL;
756 SdrObject* SdrObject::GetUpGroup() const
758 return pObjList!=NULL ? pObjList->GetOwnerObj() : NULL;
761 void SdrObject::SetName(const OUString& rStr)
763 if (!rStr.isEmpty() && !pPlusData)
765 ImpForcePlusData();
768 if(pPlusData && !pPlusData->aObjName.equals(rStr))
770 // Undo/Redo for setting object's name (#i73249#)
771 bool bUndo( false );
772 if ( GetModel() && GetModel()->IsUndoEnabled() )
774 bUndo = true;
775 SdrUndoAction* pUndoAction =
776 GetModel()->GetSdrUndoFactory().CreateUndoObjectStrAttr(
777 *this,
778 SdrUndoObjStrAttr::OBJ_NAME,
779 GetName(),
780 rStr );
781 GetModel()->BegUndo( pUndoAction->GetComment() );
782 GetModel()->AddUndo( pUndoAction );
784 pPlusData->aObjName = rStr;
785 // Undo/Redo for setting object's name (#i73249#)
786 if ( bUndo )
788 GetModel()->EndUndo();
790 SetChanged();
791 BroadcastObjectChange();
795 OUString SdrObject::GetName() const
797 if(pPlusData)
799 return pPlusData->aObjName;
802 return OUString();
805 void SdrObject::SetTitle(const OUString& rStr)
807 if (!rStr.isEmpty() && !pPlusData)
809 ImpForcePlusData();
812 if(pPlusData && pPlusData->aObjTitle != rStr)
814 // Undo/Redo for setting object's title (#i73249#)
815 bool bUndo( false );
816 if ( GetModel() && GetModel()->IsUndoEnabled() )
818 bUndo = true;
819 SdrUndoAction* pUndoAction =
820 GetModel()->GetSdrUndoFactory().CreateUndoObjectStrAttr(
821 *this,
822 SdrUndoObjStrAttr::OBJ_TITLE,
823 GetTitle(),
824 rStr );
825 GetModel()->BegUndo( pUndoAction->GetComment() );
826 GetModel()->AddUndo( pUndoAction );
828 pPlusData->aObjTitle = rStr;
829 // Undo/Redo for setting object's title (#i73249#)
830 if ( bUndo )
832 GetModel()->EndUndo();
834 SetChanged();
835 BroadcastObjectChange();
839 OUString SdrObject::GetTitle() const
841 if(pPlusData)
843 return pPlusData->aObjTitle;
846 return OUString();
849 void SdrObject::SetDescription(const OUString& rStr)
851 if (!rStr.isEmpty() && !pPlusData)
853 ImpForcePlusData();
856 if(pPlusData && !pPlusData->aObjDescription.equals(rStr))
858 // Undo/Redo for setting object's description (#i73249#)
859 bool bUndo( false );
860 if ( GetModel() && GetModel()->IsUndoEnabled() )
862 bUndo = true;
863 SdrUndoAction* pUndoAction =
864 GetModel()->GetSdrUndoFactory().CreateUndoObjectStrAttr(
865 *this,
866 SdrUndoObjStrAttr::OBJ_DESCRIPTION,
867 GetDescription(),
868 rStr );
869 GetModel()->BegUndo( pUndoAction->GetComment() );
870 GetModel()->AddUndo( pUndoAction );
872 pPlusData->aObjDescription = rStr;
873 // Undo/Redo for setting object's description (#i73249#)
874 if ( bUndo )
876 GetModel()->EndUndo();
878 SetChanged();
879 BroadcastObjectChange();
883 OUString SdrObject::GetDescription() const
885 if(pPlusData)
887 return pPlusData->aObjDescription;
890 return OUString();
893 sal_uInt32 SdrObject::GetOrdNum() const
895 if (pObjList!=NULL) {
896 if (pObjList->IsObjOrdNumsDirty()) {
897 pObjList->RecalcObjOrdNums();
899 } else ((SdrObject*)this)->nOrdNum=0;
900 return nOrdNum;
903 sal_uInt32 SdrObject::GetOrdNumDirect() const
905 return nOrdNum;
908 void SdrObject::SetOrdNum(sal_uInt32 nNum)
910 nOrdNum = nNum;
913 void SdrObject::GetGrabBagItem(com::sun::star::uno::Any& rVal) const
915 if (pGrabBagItem != NULL)
916 pGrabBagItem->QueryValue(rVal);
917 else {
918 uno::Sequence<beans::PropertyValue> aValue(0);
919 rVal = uno::makeAny(aValue);
923 void SdrObject::SetGrabBagItem(const com::sun::star::uno::Any& rVal)
925 if (pGrabBagItem == NULL)
926 pGrabBagItem = new SfxGrabBagItem;
928 pGrabBagItem->PutValue(rVal);
930 SetChanged();
931 BroadcastObjectChange();
934 sal_uInt32 SdrObject::GetNavigationPosition (void)
936 if (pObjList!=NULL && pObjList->RecalcNavigationPositions())
938 return mnNavigationPosition;
940 else
941 return GetOrdNum();
947 void SdrObject::SetNavigationPosition (const sal_uInt32 nNewPosition)
949 mnNavigationPosition = nNewPosition;
955 // To make clearer that this method may trigger RecalcBoundRect and thus may be
956 // expensive and sometimes problematic (inside a bigger object change you will get
957 // non-useful BoundRects sometimes) I rename that method from GetBoundRect() to
958 // GetCurrentBoundRect().
959 const Rectangle& SdrObject::GetCurrentBoundRect() const
961 if(aOutRect.IsEmpty())
963 const_cast< SdrObject* >(this)->RecalcBoundRect();
966 return aOutRect;
969 // To have a possibility to get the last calculated BoundRect e.g for producing
970 // the first rectangle for repaints (old and new need to be used) without forcing
971 // a RecalcBoundRect (which may be problematical and expensive sometimes) I add here
972 // a new method for accessing the last BoundRect.
973 const Rectangle& SdrObject::GetLastBoundRect() const
975 return aOutRect;
978 void SdrObject::RecalcBoundRect()
980 // #i101680# suppress BoundRect calculations on import(s)
981 if(pModel && pModel->isLocked())
982 return;
984 // central new method which will calculate the BoundRect using primitive geometry
985 if(aOutRect.IsEmpty())
987 const drawinglayer::primitive2d::Primitive2DSequence xPrimitives(GetViewContact().getViewIndependentPrimitive2DSequence());
989 if(xPrimitives.hasElements())
991 // use neutral ViewInformation and get the range of the primitives
992 const drawinglayer::geometry::ViewInformation2D aViewInformation2D;
993 const basegfx::B2DRange aRange(drawinglayer::primitive2d::getB2DRangeFromPrimitive2DSequence(xPrimitives, aViewInformation2D));
995 if(!aRange.isEmpty())
997 aOutRect = Rectangle(
998 (sal_Int32)floor(aRange.getMinX()), (sal_Int32)floor(aRange.getMinY()),
999 (sal_Int32)ceil(aRange.getMaxX()), (sal_Int32)ceil(aRange.getMaxY()));
1000 aOutRect -= GetGridOffset(); // don't include grid offset
1001 return;
1007 void SdrObject::BroadcastObjectChange() const
1009 if( pModel && pModel->isLocked() )
1010 return;
1012 bool bPlusDataBroadcast(pPlusData && pPlusData->pBroadcast);
1013 bool bObjectChange(IsInserted() && pModel);
1015 if(bPlusDataBroadcast || bObjectChange)
1017 SdrHint aHint(*this);
1019 if(bPlusDataBroadcast)
1021 pPlusData->pBroadcast->Broadcast(aHint);
1024 if(bObjectChange)
1026 pModel->Broadcast(aHint);
1031 void SdrObject::SetChanged()
1033 // For testing purposes, use the new ViewContact for change
1034 // notification now.
1035 ActionChanged();
1037 if(IsInserted() && pModel)
1039 pModel->SetChanged();
1043 // tooling for painting a single object to an OutputDevice.
1044 bool SdrObject::SingleObjectPainter(OutputDevice& rOut) const
1046 sdr::contact::SdrObjectVector aObjectVector;
1047 aObjectVector.push_back(const_cast< SdrObject* >(this));
1049 sdr::contact::ObjectContactOfObjListPainter aPainter(rOut, aObjectVector, GetPage());
1050 sdr::contact::DisplayInfo aDisplayInfo;
1052 aPainter.ProcessDisplay(aDisplayInfo);
1054 return true;
1057 bool SdrObject::LineGeometryUsageIsNecessary() const
1059 XLineStyle eXLS = (XLineStyle)((const XLineStyleItem&)GetMergedItem(XATTR_LINESTYLE)).GetValue();
1060 return (eXLS != XLINE_NONE);
1063 SdrObject* SdrObject::Clone() const
1065 return CloneHelper< SdrObject >();
1068 SdrObject& SdrObject::operator=(const SdrObject& rObj)
1070 if( this == &rObj )
1071 return *this;
1073 if(mpProperties)
1075 delete mpProperties;
1076 mpProperties = 0L;
1079 if(mpViewContact)
1081 delete mpViewContact;
1082 mpViewContact = 0L;
1085 // The Clone() method uses the local copy constructor from the individual
1086 // sdr::properties::BaseProperties class. Since the target class maybe for another
1087 // draw object, an SdrObject needs to be provided, as in the normal constructor.
1088 mpProperties = &rObj.GetProperties().Clone(*this);
1090 pModel =rObj.pModel;
1091 pPage = rObj.pPage;
1092 aOutRect=rObj.aOutRect;
1093 mnLayerID = rObj.mnLayerID;
1094 aAnchor =rObj.aAnchor;
1095 bVirtObj=rObj.bVirtObj;
1096 bSizProt=rObj.bSizProt;
1097 bMovProt=rObj.bMovProt;
1098 bNoPrint=rObj.bNoPrint;
1099 mbVisible=rObj.mbVisible;
1100 bMarkProt=rObj.bMarkProt;
1101 bEmptyPresObj =rObj.bEmptyPresObj;
1102 bNotVisibleAsMaster=rObj.bNotVisibleAsMaster;
1103 bSnapRectDirty=true;
1104 bNotMasterCachable=rObj.bNotMasterCachable;
1105 delete pPlusData;
1106 pPlusData=NULL;
1107 if (rObj.pPlusData!=NULL) {
1108 pPlusData=rObj.pPlusData->Clone(this);
1110 if (pPlusData!=NULL && pPlusData->pBroadcast!=NULL) {
1111 delete pPlusData->pBroadcast; // broadcaster isn't copied
1112 pPlusData->pBroadcast=NULL;
1115 delete pGrabBagItem;
1116 pGrabBagItem=NULL;
1117 if (rObj.pGrabBagItem!=NULL)
1118 pGrabBagItem=static_cast< SfxGrabBagItem* >( rObj.pGrabBagItem->Clone() );
1120 aGridOffset = rObj.aGridOffset;
1121 return *this;
1124 OUString SdrObject::TakeObjNameSingul() const
1126 OUStringBuffer sName(ImpGetResStr(STR_ObjNameSingulNONE));
1128 OUString aName(GetName());
1129 if (!aName.isEmpty())
1131 sName.append(' ');
1132 sName.append('\'');
1133 sName.append(aName);
1134 sName.append('\'');
1136 return sName.makeStringAndClear();
1139 OUString SdrObject::TakeObjNamePlural() const
1141 return ImpGetResStr(STR_ObjNamePluralNONE);
1144 void SdrObject::ImpTakeDescriptionStr(sal_uInt16 nStrCacheID, OUString& rStr, sal_uInt16 nVal) const
1146 rStr = ImpGetResStr(nStrCacheID);
1147 sal_Int32 nPos = rStr.indexOf("%1");
1148 if (nPos >= 0)
1150 // Replace '%1' with the object name.
1151 OUString aObjName(TakeObjNameSingul());
1152 rStr = rStr.replaceAt(nPos, 2, aObjName);
1155 nPos = rStr.indexOf("%2");
1156 if (nPos >= 0)
1157 // Replace '%2' with the passed value.
1158 rStr = rStr.replaceAt(
1159 nPos, 2, OUString::number(nVal));
1162 void SdrObject::ImpForcePlusData()
1164 if (!pPlusData)
1165 pPlusData = NewPlusData();
1168 OUString SdrObject::GetWinkStr(long nWink, bool bNoDegChar) const
1170 OUString aStr;
1171 if (pModel!=NULL) {
1172 pModel->TakeWinkStr(nWink,aStr,bNoDegChar);
1174 return aStr;
1177 OUString SdrObject::GetMetrStr(long nVal, MapUnit /*eWantMap*/, bool bNoUnitChars) const
1179 OUString aStr;
1180 if (pModel!=NULL) {
1181 pModel->TakeMetricStr(nVal,aStr,bNoUnitChars);
1183 return aStr;
1186 basegfx::B2DPolyPolygon SdrObject::TakeXorPoly() const
1188 basegfx::B2DPolyPolygon aRetval;
1189 const Rectangle aR(GetCurrentBoundRect());
1190 const basegfx::B2DRange aRange(aR.Left(), aR.Top(), aR.Right(), aR.Bottom());
1191 aRetval.append(basegfx::tools::createPolygonFromRect(aRange));
1193 return aRetval;
1196 basegfx::B2DPolyPolygon SdrObject::TakeContour() const
1198 basegfx::B2DPolyPolygon aRetval;
1200 // create cloned object without text, but with XLINE_SOLID,
1201 // COL_BLACK as line color and XFILL_NONE
1202 SdrObject* pClone = Clone();
1204 if(pClone)
1206 const SdrTextObj* pTextObj = dynamic_cast< const SdrTextObj* >(this);
1208 if(pTextObj)
1210 // no text and no text animation
1211 pClone->SetMergedItem(SdrTextAniKindItem(SDRTEXTANI_NONE));
1212 pClone->SetOutlinerParaObject(0);
1215 const SdrEdgeObj* pEdgeObj = dynamic_cast< const SdrEdgeObj* >(this);
1217 if(pEdgeObj)
1219 // create connections if connector, will be cleaned up when
1220 // deleting the connector again
1221 SdrObject* pLeft = pEdgeObj->GetConnectedNode(true);
1222 SdrObject* pRight = pEdgeObj->GetConnectedNode(false);
1224 if(pLeft)
1226 pClone->ConnectToNode(true, pLeft);
1229 if(pRight)
1231 pClone->ConnectToNode(false, pRight);
1235 SfxItemSet aNewSet(*GetObjectItemPool());
1237 // #i101980# ignore LineWidth; that's what the old implementation
1238 // did. With line width, the result may be huge due to fat/thick
1239 // line decompositions
1240 aNewSet.Put(XLineWidthItem(0));
1242 // solid black lines and no fill
1243 aNewSet.Put(XLineStyleItem(XLINE_SOLID));
1244 aNewSet.Put(XLineColorItem(OUString(), Color(COL_BLACK)));
1245 aNewSet.Put(XFillStyleItem(XFILL_NONE));
1246 pClone->SetMergedItemSet(aNewSet);
1248 // get sequence from clone
1249 const sdr::contact::ViewContact& rVC(pClone->GetViewContact());
1250 const drawinglayer::primitive2d::Primitive2DSequence xSequence(rVC.getViewIndependentPrimitive2DSequence());
1252 if(xSequence.hasElements())
1254 // use neutral ViewInformation
1255 const drawinglayer::geometry::ViewInformation2D aViewInformation2D;
1257 // create extractor, process and get result (with hairlines as opened polygons)
1258 drawinglayer::processor2d::ContourExtractor2D aExtractor(aViewInformation2D, false);
1259 aExtractor.process(xSequence);
1260 const basegfx::B2DPolyPolygonVector& rResult(aExtractor.getExtractedContour());
1261 const sal_uInt32 nSize(rResult.size());
1263 // when count is one, it is implied that the object has only its normal
1264 // contour anyways and TakeCountour() is to return an empty PolyPolygon
1265 // (see old implementation for historical reasons)
1266 if(nSize > 1)
1268 // the topology for contour is correctly a vector of PolyPolygons; for
1269 // historical reasons cut it back to a single PolyPolygon here
1270 for(sal_uInt32 a(0); a < nSize; a++)
1272 aRetval.append(rResult[a]);
1277 delete pClone;
1280 return aRetval;
1283 sal_uInt32 SdrObject::GetHdlCount() const
1285 return 8L;
1288 SdrHdl* SdrObject::GetHdl(sal_uInt32 nHdlNum) const
1290 SdrHdl* pH=NULL;
1291 const Rectangle& rR=GetSnapRect();
1292 switch (nHdlNum) {
1293 case 0: pH=new SdrHdl(rR.TopLeft(), HDL_UPLFT); break;
1294 case 1: pH=new SdrHdl(rR.TopCenter(), HDL_UPPER); break;
1295 case 2: pH=new SdrHdl(rR.TopRight(), HDL_UPRGT); break;
1296 case 3: pH=new SdrHdl(rR.LeftCenter(), HDL_LEFT ); break;
1297 case 4: pH=new SdrHdl(rR.RightCenter(), HDL_RIGHT); break;
1298 case 5: pH=new SdrHdl(rR.BottomLeft(), HDL_LWLFT); break;
1299 case 6: pH=new SdrHdl(rR.BottomCenter(),HDL_LOWER); break;
1300 case 7: pH=new SdrHdl(rR.BottomRight(), HDL_LWRGT); break;
1302 return pH;
1305 sal_uInt32 SdrObject::GetPlusHdlCount(const SdrHdl& /*rHdl*/) const
1307 return 0L;
1310 SdrHdl* SdrObject::GetPlusHdl(const SdrHdl& /*rHdl*/, sal_uInt32 /*nPlNum*/) const
1312 return 0L;
1315 void SdrObject::AddToHdlList(SdrHdlList& rHdlList) const
1317 sal_uInt32 nAnz=GetHdlCount();
1318 for (sal_uInt32 i=0L; i<nAnz; i++) {
1319 SdrHdl* pHdl=GetHdl(i);
1320 if (pHdl!=NULL) {
1321 rHdlList.AddHdl(pHdl);
1326 Rectangle SdrObject::ImpDragCalcRect(const SdrDragStat& rDrag) const
1328 Rectangle aTmpRect(GetSnapRect());
1329 Rectangle aRect(aTmpRect);
1330 const SdrHdl* pHdl=rDrag.GetHdl();
1331 SdrHdlKind eHdl=pHdl==NULL ? HDL_MOVE : pHdl->GetKind();
1332 bool bEcke=(eHdl==HDL_UPLFT || eHdl==HDL_UPRGT || eHdl==HDL_LWLFT || eHdl==HDL_LWRGT);
1333 bool bOrtho=rDrag.GetView()!=NULL && rDrag.GetView()->IsOrtho();
1334 bool bBigOrtho=bEcke && bOrtho && rDrag.GetView()->IsBigOrtho();
1335 Point aPos(rDrag.GetNow());
1336 bool bLft=(eHdl==HDL_UPLFT || eHdl==HDL_LEFT || eHdl==HDL_LWLFT);
1337 bool bRgt=(eHdl==HDL_UPRGT || eHdl==HDL_RIGHT || eHdl==HDL_LWRGT);
1338 bool bTop=(eHdl==HDL_UPRGT || eHdl==HDL_UPPER || eHdl==HDL_UPLFT);
1339 bool bBtm=(eHdl==HDL_LWRGT || eHdl==HDL_LOWER || eHdl==HDL_LWLFT);
1340 if (bLft) aTmpRect.Left() =aPos.X();
1341 if (bRgt) aTmpRect.Right() =aPos.X();
1342 if (bTop) aTmpRect.Top() =aPos.Y();
1343 if (bBtm) aTmpRect.Bottom()=aPos.Y();
1344 if (bOrtho) { // Ortho
1345 long nWdt0=aRect.Right() -aRect.Left();
1346 long nHgt0=aRect.Bottom()-aRect.Top();
1347 long nXMul=aTmpRect.Right() -aTmpRect.Left();
1348 long nYMul=aTmpRect.Bottom()-aTmpRect.Top();
1349 long nXDiv=nWdt0;
1350 long nYDiv=nHgt0;
1351 bool bXNeg=(nXMul<0)!=(nXDiv<0);
1352 bool bYNeg=(nYMul<0)!=(nYDiv<0);
1353 nXMul=std::abs(nXMul);
1354 nYMul=std::abs(nYMul);
1355 nXDiv=std::abs(nXDiv);
1356 nYDiv=std::abs(nYDiv);
1357 Fraction aXFact(nXMul,nXDiv); // fractions for canceling
1358 Fraction aYFact(nYMul,nYDiv); // and for comparing
1359 nXMul=aXFact.GetNumerator();
1360 nYMul=aYFact.GetNumerator();
1361 nXDiv=aXFact.GetDenominator();
1362 nYDiv=aYFact.GetDenominator();
1363 if (bEcke) { // corner point handles
1364 bool bUseX=(aXFact<aYFact) != bBigOrtho;
1365 if (bUseX) {
1366 long nNeed=long(BigInt(nHgt0)*BigInt(nXMul)/BigInt(nXDiv));
1367 if (bYNeg) nNeed=-nNeed;
1368 if (bTop) aTmpRect.Top()=aTmpRect.Bottom()-nNeed;
1369 if (bBtm) aTmpRect.Bottom()=aTmpRect.Top()+nNeed;
1370 } else {
1371 long nNeed=long(BigInt(nWdt0)*BigInt(nYMul)/BigInt(nYDiv));
1372 if (bXNeg) nNeed=-nNeed;
1373 if (bLft) aTmpRect.Left()=aTmpRect.Right()-nNeed;
1374 if (bRgt) aTmpRect.Right()=aTmpRect.Left()+nNeed;
1376 } else { // apex handles
1377 if ((bLft || bRgt) && nXDiv!=0) {
1378 long nHgt0b=aRect.Bottom()-aRect.Top();
1379 long nNeed=long(BigInt(nHgt0b)*BigInt(nXMul)/BigInt(nXDiv));
1380 aTmpRect.Top()-=(nNeed-nHgt0b)/2;
1381 aTmpRect.Bottom()=aTmpRect.Top()+nNeed;
1383 if ((bTop || bBtm) && nYDiv!=0) {
1384 long nWdt0b=aRect.Right()-aRect.Left();
1385 long nNeed=long(BigInt(nWdt0b)*BigInt(nYMul)/BigInt(nYDiv));
1386 aTmpRect.Left()-=(nNeed-nWdt0b)/2;
1387 aTmpRect.Right()=aTmpRect.Left()+nNeed;
1391 aTmpRect.Justify();
1392 return aTmpRect;
1397 bool SdrObject::hasSpecialDrag() const
1399 return false;
1402 bool SdrObject::supportsFullDrag() const
1404 return true;
1407 SdrObject* SdrObject::getFullDragClone() const
1409 // default uses simple clone
1410 return Clone();
1413 bool SdrObject::beginSpecialDrag(SdrDragStat& rDrag) const
1415 const SdrHdl* pHdl = rDrag.GetHdl();
1417 SdrHdlKind eHdl = (pHdl == NULL) ? HDL_MOVE : pHdl->GetKind();
1419 if(eHdl==HDL_UPLFT || eHdl==HDL_UPPER || eHdl==HDL_UPRGT ||
1420 eHdl==HDL_LEFT || eHdl==HDL_RIGHT || eHdl==HDL_LWLFT ||
1421 eHdl==HDL_LOWER || eHdl==HDL_LWRGT)
1423 return true;
1426 return false;
1429 bool SdrObject::applySpecialDrag(SdrDragStat& rDrag)
1431 Rectangle aNewRect(ImpDragCalcRect(rDrag));
1433 if(aNewRect != GetSnapRect())
1435 NbcSetSnapRect(aNewRect);
1438 return true;
1441 OUString SdrObject::getSpecialDragComment(const SdrDragStat& /*rDrag*/) const
1443 return OUString();
1446 basegfx::B2DPolyPolygon SdrObject::getSpecialDragPoly(const SdrDragStat& /*rDrag*/) const
1448 // default has nothing to add
1449 return basegfx::B2DPolyPolygon();
1453 // Create
1454 bool SdrObject::BegCreate(SdrDragStat& rStat)
1456 rStat.SetOrtho4Possible();
1457 Rectangle aRect1(rStat.GetStart(), rStat.GetNow());
1458 aRect1.Justify();
1459 rStat.SetActionRect(aRect1);
1460 aOutRect = aRect1;
1461 return true;
1464 bool SdrObject::MovCreate(SdrDragStat& rStat)
1466 rStat.TakeCreateRect(aOutRect);
1467 rStat.SetActionRect(aOutRect);
1468 aOutRect.Justify();
1470 return true;
1473 bool SdrObject::EndCreate(SdrDragStat& rStat, SdrCreateCmd eCmd)
1475 rStat.TakeCreateRect(aOutRect);
1476 aOutRect.Justify();
1478 return (eCmd==SDRCREATE_FORCEEND || rStat.GetPointAnz()>=2);
1481 void SdrObject::BrkCreate(SdrDragStat& /*rStat*/)
1485 bool SdrObject::BckCreate(SdrDragStat& /*rStat*/)
1487 return false;
1490 basegfx::B2DPolyPolygon SdrObject::TakeCreatePoly(const SdrDragStat& rDrag) const
1492 Rectangle aRect1;
1493 rDrag.TakeCreateRect(aRect1);
1494 aRect1.Justify();
1496 basegfx::B2DPolyPolygon aRetval;
1497 const basegfx::B2DRange aRange(aRect1.Left(), aRect1.Top(), aRect1.Right(), aRect1.Bottom());
1498 aRetval.append(basegfx::tools::createPolygonFromRect(aRange));
1499 return aRetval;
1502 Pointer SdrObject::GetCreatePointer() const
1504 return Pointer(POINTER_CROSS);
1507 // transformations
1508 void SdrObject::NbcMove(const Size& rSiz)
1510 MoveRect(aOutRect,rSiz);
1511 SetRectsDirty();
1514 void SdrObject::NbcResize(const Point& rRef, const Fraction& xFact, const Fraction& yFact)
1516 bool bXMirr=(xFact.GetNumerator()<0) != (xFact.GetDenominator()<0);
1517 bool bYMirr=(yFact.GetNumerator()<0) != (yFact.GetDenominator()<0);
1518 if (bXMirr || bYMirr) {
1519 Point aRef1(GetSnapRect().Center());
1520 if (bXMirr) {
1521 Point aRef2(aRef1);
1522 aRef2.Y()++;
1523 NbcMirrorGluePoints(aRef1,aRef2);
1525 if (bYMirr) {
1526 Point aRef2(aRef1);
1527 aRef2.X()++;
1528 NbcMirrorGluePoints(aRef1,aRef2);
1531 ResizeRect(aOutRect,rRef,xFact,yFact);
1532 SetRectsDirty();
1535 void SdrObject::NbcRotate(const Point& rRef, long nWink, double sn, double cs)
1537 SetGlueReallyAbsolute(true);
1538 aOutRect.Move(-rRef.X(),-rRef.Y());
1539 Rectangle R(aOutRect);
1540 if (sn==1.0 && cs==0.0) { // 90deg
1541 aOutRect.Left() =-R.Bottom();
1542 aOutRect.Right() =-R.Top();
1543 aOutRect.Top() =R.Left();
1544 aOutRect.Bottom()=R.Right();
1545 } else if (sn==0.0 && cs==-1.0) { // 180deg
1546 aOutRect.Left() =-R.Right();
1547 aOutRect.Right() =-R.Left();
1548 aOutRect.Top() =-R.Bottom();
1549 aOutRect.Bottom()=-R.Top();
1550 } else if (sn==-1.0 && cs==0.0) { // 270deg
1551 aOutRect.Left() =R.Top();
1552 aOutRect.Right() =R.Bottom();
1553 aOutRect.Top() =-R.Right();
1554 aOutRect.Bottom()=-R.Left();
1556 aOutRect.Move(rRef.X(),rRef.Y());
1557 aOutRect.Justify(); // just in case
1558 SetRectsDirty();
1559 NbcRotateGluePoints(rRef,nWink,sn,cs);
1560 SetGlueReallyAbsolute(false);
1563 void SdrObject::NbcMirror(const Point& rRef1, const Point& rRef2)
1565 SetGlueReallyAbsolute(true);
1566 aOutRect.Move(-rRef1.X(),-rRef1.Y());
1567 Rectangle R(aOutRect);
1568 long dx=rRef2.X()-rRef1.X();
1569 long dy=rRef2.Y()-rRef1.Y();
1570 if (dx==0) { // vertical axis
1571 aOutRect.Left() =-R.Right();
1572 aOutRect.Right()=-R.Left();
1573 } else if (dy==0) { // horizontal axis
1574 aOutRect.Top() =-R.Bottom();
1575 aOutRect.Bottom()=-R.Top();
1576 } else if (dx==dy) { // 45deg axis
1577 aOutRect.Left() =R.Top();
1578 aOutRect.Right() =R.Bottom();
1579 aOutRect.Top() =R.Left();
1580 aOutRect.Bottom()=R.Right();
1581 } else if (dx==-dy) { // 45deg axis
1582 aOutRect.Left() =-R.Bottom();
1583 aOutRect.Right() =-R.Top();
1584 aOutRect.Top() =-R.Right();
1585 aOutRect.Bottom()=-R.Left();
1587 aOutRect.Move(rRef1.X(),rRef1.Y());
1588 aOutRect.Justify(); // just in case
1589 SetRectsDirty();
1590 NbcMirrorGluePoints(rRef1,rRef2);
1591 SetGlueReallyAbsolute(false);
1594 void SdrObject::NbcShear(const Point& rRef, long nWink, double tn, bool bVShear)
1596 SetGlueReallyAbsolute(true);
1597 NbcShearGluePoints(rRef,nWink,tn,bVShear);
1598 SetGlueReallyAbsolute(false);
1601 void SdrObject::Move(const Size& rSiz)
1603 if (rSiz.Width()!=0 || rSiz.Height()!=0) {
1604 Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect();
1605 NbcMove(rSiz);
1606 SetChanged();
1607 BroadcastObjectChange();
1608 SendUserCall(SDRUSERCALL_MOVEONLY,aBoundRect0);
1612 void SdrObject::Resize(const Point& rRef, const Fraction& xFact, const Fraction& yFact, bool bUnsetRelative)
1614 if (xFact.GetNumerator()!=xFact.GetDenominator() || yFact.GetNumerator()!=yFact.GetDenominator()) {
1615 if (bUnsetRelative)
1617 mnRelativeWidth.reset( );
1618 meRelativeWidthRelation = text::RelOrientation::PAGE_FRAME;
1619 meRelativeHeightRelation = text::RelOrientation::PAGE_FRAME;
1620 mnRelativeHeight.reset( );
1622 Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect();
1623 NbcResize(rRef,xFact,yFact);
1624 SetChanged();
1625 BroadcastObjectChange();
1626 SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
1630 void SdrObject::Rotate(const Point& rRef, long nWink, double sn, double cs)
1632 if (nWink!=0) {
1633 Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect();
1634 NbcRotate(rRef,nWink,sn,cs);
1635 SetChanged();
1636 BroadcastObjectChange();
1637 SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
1641 void SdrObject::Mirror(const Point& rRef1, const Point& rRef2)
1643 Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect();
1644 NbcMirror(rRef1,rRef2);
1645 SetChanged();
1646 BroadcastObjectChange();
1647 SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
1650 void SdrObject::Shear(const Point& rRef, long nWink, double tn, bool bVShear)
1652 if (nWink!=0) {
1653 Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect();
1654 NbcShear(rRef,nWink,tn,bVShear);
1655 SetChanged();
1656 BroadcastObjectChange();
1657 SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
1661 void SdrObject::NbcSetRelativePos(const Point& rPnt)
1663 Point aRelPos0(GetSnapRect().TopLeft()-aAnchor);
1664 Size aSiz(rPnt.X()-aRelPos0.X(),rPnt.Y()-aRelPos0.Y());
1665 NbcMove(aSiz); // This also calls SetRectsDirty()
1668 void SdrObject::SetRelativePos(const Point& rPnt)
1670 if (rPnt!=GetRelativePos()) {
1671 Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect();
1672 NbcSetRelativePos(rPnt);
1673 SetChanged();
1674 BroadcastObjectChange();
1675 SendUserCall(SDRUSERCALL_MOVEONLY,aBoundRect0);
1679 Point SdrObject::GetRelativePos() const
1681 return GetSnapRect().TopLeft()-aAnchor;
1684 void SdrObject::ImpSetAnchorPos(const Point& rPnt)
1686 aAnchor = rPnt;
1689 void SdrObject::NbcSetAnchorPos(const Point& rPnt)
1691 Size aSiz(rPnt.X()-aAnchor.X(),rPnt.Y()-aAnchor.Y());
1692 aAnchor=rPnt;
1693 NbcMove(aSiz); // This also calls SetRectsDirty()
1696 void SdrObject::SetAnchorPos(const Point& rPnt)
1698 if (rPnt!=aAnchor) {
1699 Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect();
1700 NbcSetAnchorPos(rPnt);
1701 SetChanged();
1702 BroadcastObjectChange();
1703 SendUserCall(SDRUSERCALL_MOVEONLY,aBoundRect0);
1707 const Point& SdrObject::GetAnchorPos() const
1709 return aAnchor;
1712 void SdrObject::RecalcSnapRect()
1716 const Rectangle& SdrObject::GetSnapRect() const
1718 return aOutRect;
1721 void SdrObject::NbcSetSnapRect(const Rectangle& rRect)
1723 aOutRect=rRect;
1726 const Rectangle& SdrObject::GetLogicRect() const
1728 return GetSnapRect();
1731 void SdrObject::NbcSetLogicRect(const Rectangle& rRect)
1733 NbcSetSnapRect(rRect);
1736 void SdrObject::AdjustToMaxRect( const Rectangle& rMaxRect, bool /* bShrinkOnly = false */ )
1738 SetLogicRect( rMaxRect );
1741 void SdrObject::SetSnapRect(const Rectangle& rRect)
1743 Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect();
1744 NbcSetSnapRect(rRect);
1745 SetChanged();
1746 BroadcastObjectChange();
1747 SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
1750 void SdrObject::SetLogicRect(const Rectangle& rRect)
1752 Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect();
1753 NbcSetLogicRect(rRect);
1754 SetChanged();
1755 BroadcastObjectChange();
1756 SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
1759 long SdrObject::GetRotateAngle() const
1761 return 0;
1764 long SdrObject::GetShearAngle(bool /*bVertical*/) const
1766 return 0;
1769 sal_uInt32 SdrObject::GetSnapPointCount() const
1771 return GetPointCount();
1774 Point SdrObject::GetSnapPoint(sal_uInt32 i) const
1776 return GetPoint(i);
1779 bool SdrObject::IsPolyObj() const
1781 return false;
1784 sal_uInt32 SdrObject::GetPointCount() const
1786 return 0L;
1789 Point SdrObject::GetPoint(sal_uInt32 /*i*/) const
1791 return Point();
1794 void SdrObject::SetPoint(const Point& rPnt, sal_uInt32 i)
1796 Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect();
1797 NbcSetPoint(rPnt, i);
1798 SetChanged();
1799 BroadcastObjectChange();
1800 SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
1803 void SdrObject::NbcSetPoint(const Point& /*rPnt*/, sal_uInt32 /*i*/)
1807 bool SdrObject::HasTextEdit() const
1809 return false;
1812 OString SdrObject::stringify() const
1814 OStringBuffer aString(100);
1815 aString.append(aAnchor.X()).
1816 append(aAnchor.Y()).
1817 append(aGridOffset.X()).
1818 append(aGridOffset.Y()).
1819 append((sal_Int32)nOrdNum).
1820 append((sal_Int32)mnNavigationPosition).
1821 append(mbSupportTextIndentingOnLineWidthChange).
1822 append(mbLineIsOutsideGeometry).
1823 append(bMarkProt).
1824 append(bIs3DObj).
1825 append(bIsEdge).
1826 append(bClosedObj).
1827 append(bNotVisibleAsMaster).
1828 append(bEmptyPresObj).
1829 append(mbVisible).
1830 append(bNoPrint).
1831 append(bSizProt).
1832 append(bMovProt).
1833 append(bGrouped).
1834 append(bInserted).
1835 append(bNetLock).
1836 append(bVirtObj).
1837 //append(maBLIPSizeRectangle).
1838 append(mnLayerID);
1840 SvMemoryStream aStream;
1841 SfxItemSet aSet(GetMergedItemSet());
1842 aSet.InvalidateDefaultItems();
1843 aSet.Store(aStream, true);
1844 aString.append((const char *)aStream.GetBuffer(), aStream.GetEndOfData());
1846 return aString.makeStringAndClear();
1849 bool SdrObject::BegTextEdit(SdrOutliner& /*rOutl*/)
1851 return false;
1854 void SdrObject::EndTextEdit(SdrOutliner& /*rOutl*/)
1858 void SdrObject::SetOutlinerParaObject(OutlinerParaObject* pTextObject)
1860 Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect();
1861 NbcSetOutlinerParaObject(pTextObject);
1862 SetChanged();
1863 BroadcastObjectChange();
1864 if (GetCurrentBoundRect()!=aBoundRect0) {
1865 SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
1869 void SdrObject::NbcSetOutlinerParaObject(OutlinerParaObject* /*pTextObject*/)
1873 OutlinerParaObject* SdrObject::GetOutlinerParaObject() const
1875 return NULL;
1878 void SdrObject::NbcReformatText()
1882 void SdrObject::ReformatText()
1884 Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect();
1885 NbcReformatText();
1886 SetChanged();
1887 BroadcastObjectChange();
1888 if (GetCurrentBoundRect()!=aBoundRect0) {
1889 SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
1893 void SdrObject::BurnInStyleSheetAttributes()
1895 GetProperties().ForceStyleToHardAttributes();
1898 SdrObjUserData* SdrObject::ImpGetMacroUserData() const
1900 SdrObjUserData* pData=NULL;
1901 sal_uInt16 nAnz=GetUserDataCount();
1902 for (sal_uInt16 nNum=nAnz; nNum>0 && pData==NULL;) {
1903 nNum--;
1904 pData=GetUserData(nNum);
1905 if (!pData->HasMacro(this)) pData=NULL;
1907 return pData;
1910 bool SdrObject::HasMacro() const
1912 SdrObjUserData* pData=ImpGetMacroUserData();
1913 return pData && pData->HasMacro(this);
1916 SdrObject* SdrObject::CheckMacroHit(const SdrObjMacroHitRec& rRec) const
1918 SdrObjUserData* pData = ImpGetMacroUserData();
1920 if(pData)
1922 return pData->CheckMacroHit(rRec, this);
1925 if(rRec.pPageView)
1927 return SdrObjectPrimitiveHit(*this, rRec.aPos, rRec.nTol, *rRec.pPageView, rRec.pVisiLayer, false);
1930 return 0;
1933 Pointer SdrObject::GetMacroPointer(const SdrObjMacroHitRec& rRec) const
1935 SdrObjUserData* pData=ImpGetMacroUserData();
1936 if (pData!=NULL) {
1937 return pData->GetMacroPointer(rRec,this);
1939 return Pointer(POINTER_REFHAND);
1942 void SdrObject::PaintMacro(OutputDevice& rOut, const Rectangle& rDirtyRect, const SdrObjMacroHitRec& rRec) const
1944 SdrObjUserData* pData=ImpGetMacroUserData();
1946 if(pData)
1948 pData->PaintMacro(rOut,rDirtyRect,rRec,this);
1950 else
1952 const RasterOp eRop(rOut.GetRasterOp());
1953 const basegfx::B2DPolyPolygon aPolyPolygon(TakeXorPoly());
1954 const sal_uInt32 nCount(aPolyPolygon.count());
1956 rOut.SetLineColor(COL_BLACK);
1957 rOut.SetFillColor();
1958 rOut.SetRasterOp(ROP_INVERT);
1960 for(sal_uInt32 a(0); a < nCount; a++)
1962 rOut.DrawPolyLine(aPolyPolygon.getB2DPolygon(a));
1965 rOut.SetRasterOp(eRop);
1969 bool SdrObject::DoMacro(const SdrObjMacroHitRec& rRec)
1971 SdrObjUserData* pData=ImpGetMacroUserData();
1972 if (pData!=NULL) {
1973 return pData->DoMacro(rRec,this);
1975 return false;
1978 OUString SdrObject::GetMacroPopupComment(const SdrObjMacroHitRec& rRec) const
1980 SdrObjUserData* pData=ImpGetMacroUserData();
1981 if (pData!=NULL) {
1982 return pData->GetMacroPopupComment(rRec,this);
1984 return OUString();
1987 bool SdrObject::IsMacroHit(const SdrObjMacroHitRec& rRec) const
1989 return CheckMacroHit(rRec) != NULL;
1994 SdrObjGeoData* SdrObject::NewGeoData() const
1996 return new SdrObjGeoData;
1999 void SdrObject::SaveGeoData(SdrObjGeoData& rGeo) const
2001 rGeo.aBoundRect =GetCurrentBoundRect();
2002 rGeo.aAnchor =aAnchor ;
2003 rGeo.bMovProt =bMovProt ;
2004 rGeo.bSizProt =bSizProt ;
2005 rGeo.bNoPrint =bNoPrint ;
2006 rGeo.mbVisible =mbVisible ;
2007 rGeo.bClosedObj =bClosedObj ;
2008 rGeo.mnLayerID = mnLayerID;
2010 // user-defined glue points
2011 if (pPlusData!=NULL && pPlusData->pGluePoints!=NULL) {
2012 if (rGeo.pGPL!=NULL) {
2013 *rGeo.pGPL=*pPlusData->pGluePoints;
2014 } else {
2015 rGeo.pGPL=new SdrGluePointList(*pPlusData->pGluePoints);
2017 } else {
2018 if (rGeo.pGPL!=NULL) {
2019 delete rGeo.pGPL;
2020 rGeo.pGPL=NULL;
2025 void SdrObject::RestGeoData(const SdrObjGeoData& rGeo)
2027 SetRectsDirty();
2028 aOutRect =rGeo.aBoundRect ;
2029 aAnchor =rGeo.aAnchor ;
2030 bMovProt =rGeo.bMovProt ;
2031 bSizProt =rGeo.bSizProt ;
2032 bNoPrint =rGeo.bNoPrint ;
2033 mbVisible =rGeo.mbVisible ;
2034 bClosedObj =rGeo.bClosedObj ;
2035 mnLayerID = rGeo.mnLayerID;
2037 // user-defined glue points
2038 if (rGeo.pGPL!=NULL) {
2039 ImpForcePlusData();
2040 if (pPlusData->pGluePoints!=NULL) {
2041 *pPlusData->pGluePoints=*rGeo.pGPL;
2042 } else {
2043 pPlusData->pGluePoints=new SdrGluePointList(*rGeo.pGPL);
2045 } else {
2046 if (pPlusData!=NULL && pPlusData->pGluePoints!=NULL) {
2047 delete pPlusData->pGluePoints;
2048 pPlusData->pGluePoints=NULL;
2053 SdrObjGeoData* SdrObject::GetGeoData() const
2055 SdrObjGeoData* pGeo=NewGeoData();
2056 SaveGeoData(*pGeo);
2057 return pGeo;
2060 void SdrObject::SetGeoData(const SdrObjGeoData& rGeo)
2062 Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect();
2063 RestGeoData(rGeo);
2064 SetChanged();
2065 BroadcastObjectChange();
2066 SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
2070 // ItemSet access
2072 const SfxItemSet& SdrObject::GetObjectItemSet() const
2074 return GetProperties().GetObjectItemSet();
2077 const SfxItemSet& SdrObject::GetMergedItemSet() const
2079 return GetProperties().GetMergedItemSet();
2082 void SdrObject::SetObjectItem(const SfxPoolItem& rItem)
2084 GetProperties().SetObjectItem(rItem);
2087 void SdrObject::SetMergedItem(const SfxPoolItem& rItem)
2089 GetProperties().SetMergedItem(rItem);
2092 void SdrObject::ClearMergedItem(const sal_uInt16 nWhich)
2094 GetProperties().ClearMergedItem(nWhich);
2097 void SdrObject::SetObjectItemSet(const SfxItemSet& rSet)
2099 GetProperties().SetObjectItemSet(rSet);
2102 void SdrObject::SetMergedItemSet(const SfxItemSet& rSet, bool bClearAllItems)
2104 GetProperties().SetMergedItemSet(rSet, bClearAllItems);
2107 const SfxPoolItem& SdrObject::GetObjectItem(const sal_uInt16 nWhich) const
2109 return GetObjectItemSet().Get(nWhich);
2112 SfxMapUnit SdrObject::GetObjectMapUnit() const
2114 SfxMapUnit aRetval(SFX_MAPUNIT_100TH_MM);
2115 SdrItemPool* pPool = GetObjectItemPool();
2117 if(pPool)
2119 aRetval = pPool->GetMetric(0);
2121 else
2123 OSL_ENSURE(pPool, "SdrObjects always need a pool (!)");
2126 return aRetval;
2129 const SfxPoolItem& SdrObject::GetMergedItem(const sal_uInt16 nWhich) const
2131 return GetMergedItemSet().Get(nWhich);
2134 void SdrObject::SetMergedItemSetAndBroadcast(const SfxItemSet& rSet, bool bClearAllItems)
2136 GetProperties().SetMergedItemSetAndBroadcast(rSet, bClearAllItems);
2139 void SdrObject::ApplyNotPersistAttr(const SfxItemSet& rAttr)
2141 Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect();
2142 NbcApplyNotPersistAttr(rAttr);
2143 SetChanged();
2144 BroadcastObjectChange();
2145 SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
2148 void SdrObject::NbcApplyNotPersistAttr(const SfxItemSet& rAttr)
2150 const Rectangle& rSnap=GetSnapRect();
2151 const Rectangle& rLogic=GetLogicRect();
2152 Point aRef1(rSnap.Center());
2153 Point aRef2(aRef1); aRef2.Y()++;
2154 const SfxPoolItem *pPoolItem=NULL;
2155 if (rAttr.GetItemState(SDRATTR_TRANSFORMREF1X,true,&pPoolItem)==SFX_ITEM_SET) {
2156 aRef1.X()=((const SdrTransformRef1XItem*)pPoolItem)->GetValue();
2158 if (rAttr.GetItemState(SDRATTR_TRANSFORMREF1Y,true,&pPoolItem)==SFX_ITEM_SET) {
2159 aRef1.Y()=((const SdrTransformRef1YItem*)pPoolItem)->GetValue();
2161 if (rAttr.GetItemState(SDRATTR_TRANSFORMREF2X,true,&pPoolItem)==SFX_ITEM_SET) {
2162 aRef2.X()=((const SdrTransformRef2XItem*)pPoolItem)->GetValue();
2164 if (rAttr.GetItemState(SDRATTR_TRANSFORMREF2Y,true,&pPoolItem)==SFX_ITEM_SET) {
2165 aRef2.Y()=((const SdrTransformRef2YItem*)pPoolItem)->GetValue();
2168 Rectangle aNewSnap(rSnap);
2169 if (rAttr.GetItemState(SDRATTR_MOVEX,true,&pPoolItem)==SFX_ITEM_SET) {
2170 long n=((const SdrMoveXItem*)pPoolItem)->GetValue();
2171 aNewSnap.Move(n,0);
2173 if (rAttr.GetItemState(SDRATTR_MOVEY,true,&pPoolItem)==SFX_ITEM_SET) {
2174 long n=((const SdrMoveYItem*)pPoolItem)->GetValue();
2175 aNewSnap.Move(0,n);
2177 if (rAttr.GetItemState(SDRATTR_ONEPOSITIONX,true,&pPoolItem)==SFX_ITEM_SET) {
2178 long n=((const SdrOnePositionXItem*)pPoolItem)->GetValue();
2179 aNewSnap.Move(n-aNewSnap.Left(),0);
2181 if (rAttr.GetItemState(SDRATTR_ONEPOSITIONY,true,&pPoolItem)==SFX_ITEM_SET) {
2182 long n=((const SdrOnePositionYItem*)pPoolItem)->GetValue();
2183 aNewSnap.Move(0,n-aNewSnap.Top());
2185 if (rAttr.GetItemState(SDRATTR_ONESIZEWIDTH,true,&pPoolItem)==SFX_ITEM_SET) {
2186 long n=((const SdrOneSizeWidthItem*)pPoolItem)->GetValue();
2187 aNewSnap.Right()=aNewSnap.Left()+n;
2189 if (rAttr.GetItemState(SDRATTR_ONESIZEHEIGHT,true,&pPoolItem)==SFX_ITEM_SET) {
2190 long n=((const SdrOneSizeHeightItem*)pPoolItem)->GetValue();
2191 aNewSnap.Bottom()=aNewSnap.Top()+n;
2193 if (aNewSnap!=rSnap) {
2194 if (aNewSnap.GetSize()==rSnap.GetSize()) {
2195 NbcMove(Size(aNewSnap.Left()-rSnap.Left(),aNewSnap.Top()-rSnap.Top()));
2196 } else {
2197 NbcSetSnapRect(aNewSnap);
2201 if (rAttr.GetItemState(SDRATTR_SHEARANGLE,true,&pPoolItem)==SFX_ITEM_SET) {
2202 long n=((const SdrShearAngleItem*)pPoolItem)->GetValue();
2203 n-=GetShearAngle();
2204 if (n!=0) {
2205 double nTan=tan(n*nPi180);
2206 NbcShear(aRef1,n,nTan,false);
2209 if (rAttr.GetItemState(SDRATTR_ROTATEANGLE,true,&pPoolItem)==SFX_ITEM_SET) {
2210 long n=((const SdrRotateAngleItem*)pPoolItem)->GetValue();
2211 n-=GetRotateAngle();
2212 if (n!=0) {
2213 double nSin=sin(n*nPi180);
2214 double nCos=cos(n*nPi180);
2215 NbcRotate(aRef1,n,nSin,nCos);
2218 if (rAttr.GetItemState(SDRATTR_ROTATEONE,true,&pPoolItem)==SFX_ITEM_SET) {
2219 long n=((const SdrRotateOneItem*)pPoolItem)->GetValue();
2220 double nSin=sin(n*nPi180);
2221 double nCos=cos(n*nPi180);
2222 NbcRotate(aRef1,n,nSin,nCos);
2224 if (rAttr.GetItemState(SDRATTR_HORZSHEARONE,true,&pPoolItem)==SFX_ITEM_SET) {
2225 long n=((const SdrHorzShearOneItem*)pPoolItem)->GetValue();
2226 double nTan=tan(n*nPi180);
2227 NbcShear(aRef1,n,nTan,false);
2229 if (rAttr.GetItemState(SDRATTR_VERTSHEARONE,true,&pPoolItem)==SFX_ITEM_SET) {
2230 long n=((const SdrVertShearOneItem*)pPoolItem)->GetValue();
2231 double nTan=tan(n*nPi180);
2232 NbcShear(aRef1,n,nTan,true);
2235 if (rAttr.GetItemState(SDRATTR_OBJMOVEPROTECT,true,&pPoolItem)==SFX_ITEM_SET) {
2236 bool b=((const SdrObjMoveProtectItem*)pPoolItem)->GetValue();
2237 SetMoveProtect(b);
2239 if (rAttr.GetItemState(SDRATTR_OBJSIZEPROTECT,true,&pPoolItem)==SFX_ITEM_SET) {
2240 bool b=((const SdrObjSizeProtectItem*)pPoolItem)->GetValue();
2241 SetResizeProtect(b);
2244 /* move protect always sets size protect */
2245 if( IsMoveProtect() )
2246 SetResizeProtect( true );
2248 if (rAttr.GetItemState(SDRATTR_OBJPRINTABLE,true,&pPoolItem)==SFX_ITEM_SET) {
2249 bool b=((const SdrObjPrintableItem*)pPoolItem)->GetValue();
2250 SetPrintable(b);
2253 if (rAttr.GetItemState(SDRATTR_OBJVISIBLE,true,&pPoolItem)==SFX_ITEM_SET) {
2254 bool b=((const SdrObjVisibleItem*)pPoolItem)->GetValue();
2255 SetVisible(b);
2258 SdrLayerID nLayer=SDRLAYER_NOTFOUND;
2259 if (rAttr.GetItemState(SDRATTR_LAYERID,true,&pPoolItem)==SFX_ITEM_SET) {
2260 nLayer=((const SdrLayerIdItem*)pPoolItem)->GetValue();
2262 if (rAttr.GetItemState(SDRATTR_LAYERNAME,true,&pPoolItem)==SFX_ITEM_SET && pModel!=NULL) {
2263 OUString aLayerName=((const SdrLayerNameItem*)pPoolItem)->GetValue();
2264 const SdrLayerAdmin* pLayAd=pPage!=NULL ? &pPage->GetLayerAdmin() : pModel!=NULL ? &pModel->GetLayerAdmin() : NULL;
2265 if (pLayAd!=NULL) {
2266 const SdrLayer* pLayer=pLayAd->GetLayer(aLayerName, true);
2267 if (pLayer!=NULL) {
2268 nLayer=pLayer->GetID();
2273 if (nLayer!=SDRLAYER_NOTFOUND) {
2274 NbcSetLayer(nLayer);
2277 if (rAttr.GetItemState(SDRATTR_OBJECTNAME,true,&pPoolItem)==SFX_ITEM_SET) {
2278 OUString aName=((const SdrObjectNameItem*)pPoolItem)->GetValue();
2279 SetName(aName);
2281 Rectangle aNewLogic(rLogic);
2282 if (rAttr.GetItemState(SDRATTR_LOGICSIZEWIDTH,true,&pPoolItem)==SFX_ITEM_SET) {
2283 long n=((const SdrLogicSizeWidthItem*)pPoolItem)->GetValue();
2284 aNewLogic.Right()=aNewLogic.Left()+n;
2286 if (rAttr.GetItemState(SDRATTR_LOGICSIZEHEIGHT,true,&pPoolItem)==SFX_ITEM_SET) {
2287 long n=((const SdrLogicSizeHeightItem*)pPoolItem)->GetValue();
2288 aNewLogic.Bottom()=aNewLogic.Top()+n;
2290 if (aNewLogic!=rLogic) {
2291 NbcSetLogicRect(aNewLogic);
2293 Fraction aResizeX(1,1);
2294 Fraction aResizeY(1,1);
2295 if (rAttr.GetItemState(SDRATTR_RESIZEXONE,true,&pPoolItem)==SFX_ITEM_SET) {
2296 aResizeX*=((const SdrResizeXOneItem*)pPoolItem)->GetValue();
2298 if (rAttr.GetItemState(SDRATTR_RESIZEYONE,true,&pPoolItem)==SFX_ITEM_SET) {
2299 aResizeY*=((const SdrResizeYOneItem*)pPoolItem)->GetValue();
2301 if (aResizeX!=Fraction(1,1) || aResizeY!=Fraction(1,1)) {
2302 NbcResize(aRef1,aResizeX,aResizeY);
2306 static void lcl_SetItem(SfxItemSet& rAttr, bool bMerge, const SfxPoolItem& rItem)
2308 if (bMerge) rAttr.MergeValue(rItem,true);
2309 else rAttr.Put(rItem);
2312 void SdrObject::TakeNotPersistAttr(SfxItemSet& rAttr, bool bMerge) const
2314 const Rectangle& rSnap=GetSnapRect();
2315 const Rectangle& rLogic=GetLogicRect();
2316 lcl_SetItem(rAttr,bMerge,SdrObjMoveProtectItem(IsMoveProtect()));
2317 lcl_SetItem(rAttr,bMerge,SdrObjSizeProtectItem(IsResizeProtect()));
2318 lcl_SetItem(rAttr,bMerge,SdrObjPrintableItem(IsPrintable()));
2319 lcl_SetItem(rAttr,bMerge,SdrObjVisibleItem(IsVisible()));
2320 lcl_SetItem(rAttr,bMerge,SdrRotateAngleItem(GetRotateAngle()));
2321 lcl_SetItem(rAttr,bMerge,SdrShearAngleItem(GetShearAngle()));
2322 lcl_SetItem(rAttr,bMerge,SdrOneSizeWidthItem(rSnap.GetWidth()-1));
2323 lcl_SetItem(rAttr,bMerge,SdrOneSizeHeightItem(rSnap.GetHeight()-1));
2324 lcl_SetItem(rAttr,bMerge,SdrOnePositionXItem(rSnap.Left()));
2325 lcl_SetItem(rAttr,bMerge,SdrOnePositionYItem(rSnap.Top()));
2326 if (rLogic.GetWidth()!=rSnap.GetWidth()) {
2327 lcl_SetItem(rAttr,bMerge,SdrLogicSizeWidthItem(rLogic.GetWidth()-1));
2329 if (rLogic.GetHeight()!=rSnap.GetHeight()) {
2330 lcl_SetItem(rAttr,bMerge,SdrLogicSizeHeightItem(rLogic.GetHeight()-1));
2332 OUString aName(GetName());
2334 if (!aName.isEmpty())
2336 lcl_SetItem(rAttr, bMerge, SdrObjectNameItem(aName));
2339 lcl_SetItem(rAttr,bMerge,SdrLayerIdItem(GetLayer()));
2340 const SdrLayerAdmin* pLayAd=pPage!=NULL ? &pPage->GetLayerAdmin() : pModel!=NULL ? &pModel->GetLayerAdmin() : NULL;
2341 if (pLayAd!=NULL) {
2342 const SdrLayer* pLayer=pLayAd->GetLayerPerID(GetLayer());
2343 if (pLayer!=NULL) {
2344 lcl_SetItem(rAttr,bMerge,SdrLayerNameItem(pLayer->GetName()));
2347 Point aRef1(rSnap.Center());
2348 Point aRef2(aRef1); aRef2.Y()++;
2349 lcl_SetItem(rAttr,bMerge,SdrTransformRef1XItem(aRef1.X()));
2350 lcl_SetItem(rAttr,bMerge,SdrTransformRef1YItem(aRef1.Y()));
2351 lcl_SetItem(rAttr,bMerge,SdrTransformRef2XItem(aRef2.X()));
2352 lcl_SetItem(rAttr,bMerge,SdrTransformRef2YItem(aRef2.Y()));
2355 SfxStyleSheet* SdrObject::GetStyleSheet() const
2357 return GetProperties().GetStyleSheet();
2360 void SdrObject::SetStyleSheet(SfxStyleSheet* pNewStyleSheet, bool bDontRemoveHardAttr)
2362 Rectangle aBoundRect0;
2364 if(pUserCall)
2365 aBoundRect0 = GetLastBoundRect();
2367 NbcSetStyleSheet(pNewStyleSheet, bDontRemoveHardAttr);
2368 SetChanged();
2369 BroadcastObjectChange();
2370 SendUserCall(SDRUSERCALL_CHGATTR, aBoundRect0);
2373 void SdrObject::NbcSetStyleSheet(SfxStyleSheet* pNewStyleSheet, bool bDontRemoveHardAttr)
2375 // only allow graphic and presentation styles for shapes
2376 if( pNewStyleSheet && (pNewStyleSheet->GetFamily() == SFX_STYLE_FAMILY_PARA) && (pNewStyleSheet->GetFamily() == SFX_STYLE_FAMILY_PAGE) )
2377 return;
2379 GetProperties().SetStyleSheet(pNewStyleSheet, bDontRemoveHardAttr);
2382 // Broadcasting while setting attributes is managed by the AttrObj.
2385 bool SdrObject::IsNode() const
2387 return true;
2390 SdrGluePoint SdrObject::GetVertexGluePoint(sal_uInt16 nPosNum) const
2392 // #i41936# Use SnapRect for default GluePoints
2393 const Rectangle aR(GetSnapRect());
2394 Point aPt;
2396 switch(nPosNum)
2398 case 0 : aPt = aR.TopCenter(); break;
2399 case 1 : aPt = aR.RightCenter(); break;
2400 case 2 : aPt = aR.BottomCenter(); break;
2401 case 3 : aPt = aR.LeftCenter(); break;
2404 aPt -= aR.Center();
2405 SdrGluePoint aGP(aPt);
2406 aGP.SetPercent(false);
2408 return aGP;
2411 SdrGluePoint SdrObject::GetCornerGluePoint(sal_uInt16 nPosNum) const
2413 Rectangle aR(GetCurrentBoundRect());
2414 Point aPt;
2415 switch (nPosNum) {
2416 case 0 : aPt=aR.TopLeft(); break;
2417 case 1 : aPt=aR.TopRight(); break;
2418 case 2 : aPt=aR.BottomRight(); break;
2419 case 3 : aPt=aR.BottomLeft(); break;
2421 aPt-=GetSnapRect().Center();
2422 SdrGluePoint aGP(aPt);
2423 aGP.SetPercent(false);
2424 return aGP;
2427 const SdrGluePointList* SdrObject::GetGluePointList() const
2429 if (pPlusData!=NULL) return pPlusData->pGluePoints;
2430 return NULL;
2434 SdrGluePointList* SdrObject::ForceGluePointList()
2436 ImpForcePlusData();
2437 if (pPlusData->pGluePoints==NULL) {
2438 pPlusData->pGluePoints=new SdrGluePointList;
2440 return pPlusData->pGluePoints;
2443 void SdrObject::SetGlueReallyAbsolute(bool bOn)
2445 // First a const call to see whether there are any glue points.
2446 // Force const call!
2447 if (GetGluePointList()!=NULL) {
2448 SdrGluePointList* pGPL=ForceGluePointList();
2449 pGPL->SetReallyAbsolute(bOn,*this);
2453 void SdrObject::NbcRotateGluePoints(const Point& rRef, long nWink, double sn, double cs)
2455 // First a const call to see whether there are any glue points.
2456 // Force const call!
2457 if (GetGluePointList()!=NULL) {
2458 SdrGluePointList* pGPL=ForceGluePointList();
2459 pGPL->Rotate(rRef,nWink,sn,cs,this);
2463 void SdrObject::NbcMirrorGluePoints(const Point& rRef1, const Point& rRef2)
2465 // First a const call to see whether there are any glue points.
2466 // Force const call!
2467 if (GetGluePointList()!=NULL) {
2468 SdrGluePointList* pGPL=ForceGluePointList();
2469 pGPL->Mirror(rRef1,rRef2,this);
2473 void SdrObject::NbcShearGluePoints(const Point& rRef, long nWink, double tn, bool bVShear)
2475 // First a const call to see whether there are any glue points.
2476 // Force const call!
2477 if (GetGluePointList()!=NULL) {
2478 SdrGluePointList* pGPL=ForceGluePointList();
2479 pGPL->Shear(rRef,nWink,tn,bVShear,this);
2483 bool SdrObject::IsEdge() const
2485 return false;
2488 void SdrObject::ConnectToNode(bool /*bTail1*/, SdrObject* /*pObj*/)
2492 void SdrObject::DisconnectFromNode(bool /*bTail1*/)
2496 SdrObject* SdrObject::GetConnectedNode(bool /*bTail1*/) const
2498 return NULL;
2503 void extractLineContourFromPrimitive2DSequence(
2504 const drawinglayer::primitive2d::Primitive2DSequence& rxSequence,
2505 basegfx::B2DPolygonVector& rExtractedHairlines,
2506 basegfx::B2DPolyPolygonVector& rExtractedLineFills)
2508 rExtractedHairlines.clear();
2509 rExtractedLineFills.clear();
2511 if(rxSequence.hasElements())
2513 // use neutral ViewInformation
2514 const drawinglayer::geometry::ViewInformation2D aViewInformation2D;
2516 // create extractor, process and get result
2517 drawinglayer::processor2d::LineGeometryExtractor2D aExtractor(aViewInformation2D);
2518 aExtractor.process(rxSequence);
2520 // copy line results
2521 rExtractedHairlines = aExtractor.getExtractedHairlines();
2523 // copy fill rsults
2524 rExtractedLineFills = aExtractor.getExtractedLineFills();
2530 SdrObject* SdrObject::ImpConvertToContourObj(SdrObject* pRet, bool bForceLineDash) const
2532 bool bNoChange(true);
2534 if(pRet->LineGeometryUsageIsNecessary())
2536 basegfx::B2DPolyPolygon aMergedLineFillPolyPolygon;
2537 basegfx::B2DPolyPolygon aMergedHairlinePolyPolygon;
2538 const drawinglayer::primitive2d::Primitive2DSequence xSequence(pRet->GetViewContact().getViewIndependentPrimitive2DSequence());
2540 if(xSequence.hasElements())
2542 basegfx::B2DPolygonVector aExtractedHairlines;
2543 basegfx::B2DPolyPolygonVector aExtractedLineFills;
2545 extractLineContourFromPrimitive2DSequence(xSequence, aExtractedHairlines, aExtractedLineFills);
2547 if(!aExtractedHairlines.empty())
2549 // for SdrObject creation, just copy all to a single Hairline-PolyPolygon
2550 for(sal_uInt32 a(0); a < aExtractedHairlines.size(); a++)
2552 aMergedHairlinePolyPolygon.append(aExtractedHairlines[a]);
2556 // check for fill rsults
2557 if(!aExtractedLineFills.empty())
2559 // merge to a single PolyPolygon (OR)
2560 aMergedLineFillPolyPolygon = basegfx::tools::mergeToSinglePolyPolygon(aExtractedLineFills);
2564 if(aMergedLineFillPolyPolygon.count() || (bForceLineDash && aMergedHairlinePolyPolygon.count()))
2566 SfxItemSet aSet(pRet->GetMergedItemSet());
2567 XFillStyle eOldFillStyle = ((const XFillStyleItem&)(aSet.Get(XATTR_FILLSTYLE))).GetValue();
2568 SdrPathObj* aLinePolygonPart = NULL;
2569 SdrPathObj* aLineHairlinePart = NULL;
2570 bool bBuildGroup(false);
2572 if(aMergedLineFillPolyPolygon.count())
2574 // create SdrObject for filled line geometry
2575 aLinePolygonPart = new SdrPathObj(OBJ_PATHFILL, aMergedLineFillPolyPolygon);
2576 aLinePolygonPart->SetModel(pRet->GetModel());
2578 // correct item properties
2579 aSet.Put(XLineWidthItem(0L));
2580 aSet.Put(XLineStyleItem(XLINE_NONE));
2581 Color aColorLine = ((const XLineColorItem&)(aSet.Get(XATTR_LINECOLOR))).GetColorValue();
2582 sal_uInt16 nTransLine = ((const XLineTransparenceItem&)(aSet.Get(XATTR_LINETRANSPARENCE))).GetValue();
2583 aSet.Put(XFillColorItem(OUString(), aColorLine));
2584 aSet.Put(XFillStyleItem(XFILL_SOLID));
2585 aSet.Put(XFillTransparenceItem(nTransLine));
2587 aLinePolygonPart->SetMergedItemSet(aSet);
2590 if(aMergedHairlinePolyPolygon.count())
2592 // create SdrObject for hairline geometry
2593 // OBJ_PATHLINE is necessary here, not OBJ_PATHFILL. This is intended
2594 // to get a non-filled object. If the poly is closed, the PathObj takes care for
2595 // the correct closed state.
2596 aLineHairlinePart = new SdrPathObj(OBJ_PATHLINE, aMergedHairlinePolyPolygon);
2597 aLineHairlinePart->SetModel(pRet->GetModel());
2599 aSet.Put(XLineWidthItem(0L));
2600 aSet.Put(XFillStyleItem(XFILL_NONE));
2601 aSet.Put(XLineStyleItem(XLINE_SOLID));
2603 // it is also necessary to switch off line start and ends here
2604 aSet.Put(XLineStartWidthItem(0));
2605 aSet.Put(XLineEndWidthItem(0));
2607 aLineHairlinePart->SetMergedItemSet(aSet);
2609 if(aLinePolygonPart)
2611 bBuildGroup = true;
2615 // check if original geometry should be added (e.g. filled and closed)
2616 bool bAddOriginalGeometry(false);
2617 SdrPathObj* pPath = PTR_CAST(SdrPathObj, pRet);
2619 if(pPath && pPath->IsClosed())
2621 if(eOldFillStyle != XFILL_NONE)
2623 bAddOriginalGeometry = true;
2627 // do we need a group?
2628 if(bBuildGroup || bAddOriginalGeometry)
2630 SdrObject* pGroup = new SdrObjGroup;
2631 pGroup->SetModel(pRet->GetModel());
2633 if(bAddOriginalGeometry)
2635 // Add a clone of the original geometry.
2636 aSet.ClearItem();
2637 aSet.Put(pRet->GetMergedItemSet());
2638 aSet.Put(XLineStyleItem(XLINE_NONE));
2639 aSet.Put(XLineWidthItem(0L));
2641 SdrObject* pClone = pRet->Clone();
2643 pClone->SetModel(pRet->GetModel());
2644 pClone->SetMergedItemSet(aSet);
2646 pGroup->GetSubList()->NbcInsertObject(pClone);
2649 if(aLinePolygonPart)
2651 pGroup->GetSubList()->NbcInsertObject(aLinePolygonPart);
2654 if(aLineHairlinePart)
2656 pGroup->GetSubList()->NbcInsertObject(aLineHairlinePart);
2659 pRet = pGroup;
2661 // be more careful with the state describing bool
2662 bNoChange = false;
2664 else
2666 if(aLinePolygonPart)
2668 pRet = aLinePolygonPart;
2669 // be more careful with the state describing bool
2670 bNoChange = false;
2672 else if(aLineHairlinePart)
2674 pRet = aLineHairlinePart;
2675 // be more careful with the state describing bool
2676 bNoChange = false;
2682 if(bNoChange)
2684 // due to current method usage, create and return a clone when nothing has changed
2685 SdrObject* pClone = pRet->Clone();
2686 pClone->SetModel(pRet->GetModel());
2687 pRet = pClone;
2690 return pRet;
2693 bool SdrObject::IsVirtualObj() const
2695 return bVirtObj;
2698 bool SdrObject::IsClosedObj() const
2700 return bClosedObj;
2703 bool SdrObject::IsEdgeObj() const
2705 return bIsEdge;
2708 bool SdrObject::Is3DObj() const
2710 return bIs3DObj;
2713 bool SdrObject::IsUnoObj() const
2715 return bIsUnoObj;
2718 void SdrObject::SetMarkProtect(bool bProt)
2720 bMarkProt = bProt;
2723 bool SdrObject::IsMarkProtect() const
2725 return bMarkProt;
2728 bool SdrObject::IsInserted() const
2730 return bInserted;
2733 bool SdrObject::IsMoveProtect() const
2735 return bMovProt;
2738 bool SdrObject::IsResizeProtect() const
2740 return bSizProt;
2743 bool SdrObject::IsPrintable() const
2745 return !bNoPrint;
2748 bool SdrObject::IsVisible() const
2750 return mbVisible;
2753 void SdrObject::SetEmptyPresObj(bool bEpt)
2755 bEmptyPresObj = bEpt;
2758 bool SdrObject::IsEmptyPresObj() const
2760 return bEmptyPresObj;
2763 void SdrObject::SetNotVisibleAsMaster(bool bFlg)
2765 bNotVisibleAsMaster=bFlg;
2768 bool SdrObject::IsNotVisibleAsMaster() const
2770 return bNotVisibleAsMaster;
2773 bool SdrObject::LineIsOutsideGeometry() const
2775 return mbLineIsOutsideGeometry;
2778 bool SdrObject::DoesSupportTextIndentingOnLineWidthChange() const
2780 return mbSupportTextIndentingOnLineWidthChange;
2783 // convert this path object to contour object, even when it is a group
2784 SdrObject* SdrObject::ConvertToContourObj(SdrObject* pRet, bool bForceLineDash) const
2786 if(pRet->ISA(SdrObjGroup))
2788 SdrObjList* pObjList2 = pRet->GetSubList();
2789 SdrObject* pGroup = new SdrObjGroup;
2790 pGroup->SetModel(pRet->GetModel());
2792 for(sal_uInt32 a=0;a<pObjList2->GetObjCount();a++)
2794 SdrObject* pIterObj = pObjList2->GetObj(a);
2795 pGroup->GetSubList()->NbcInsertObject(ConvertToContourObj(pIterObj, bForceLineDash));
2798 pRet = pGroup;
2800 else
2802 if(pRet && pRet->ISA(SdrPathObj))
2804 SdrPathObj* pPathObj = (SdrPathObj*)pRet;
2806 // bezier geometry got created, even for straight edges since the given
2807 // object is a result of DoConvertToPolyObj. For conversion to contour
2808 // this is not really needed and can be reduced again AFAP
2809 pPathObj->SetPathPoly(basegfx::tools::simplifyCurveSegments(pPathObj->GetPathPoly()));
2812 pRet = ImpConvertToContourObj(pRet, bForceLineDash);
2815 // #i73441# preserve LayerID
2816 if(pRet && pRet->GetLayer() != GetLayer())
2818 pRet->SetLayer(GetLayer());
2821 return pRet;
2826 SdrObject* SdrObject::ConvertToPolyObj(bool bBezier, bool bLineToArea) const
2828 SdrObject* pRet = DoConvertToPolyObj(bBezier, true);
2830 if(pRet && bLineToArea)
2832 SdrObject* pNewRet = ConvertToContourObj(pRet);
2833 delete pRet;
2834 pRet = pNewRet;
2837 // #i73441# preserve LayerID
2838 if(pRet && pRet->GetLayer() != GetLayer())
2840 pRet->SetLayer(GetLayer());
2843 return pRet;
2848 SdrObject* SdrObject::DoConvertToPolyObj(bool /*bBezier*/, bool /*bAddText*/) const
2850 return NULL;
2855 void SdrObject::SetInserted(bool bIns)
2857 if (bIns!=IsInserted()) {
2858 bInserted=bIns;
2859 Rectangle aBoundRect0(GetLastBoundRect());
2860 if (bIns) SendUserCall(SDRUSERCALL_INSERTED,aBoundRect0);
2861 else SendUserCall(SDRUSERCALL_REMOVED,aBoundRect0);
2863 if (pPlusData!=NULL && pPlusData->pBroadcast!=NULL) {
2864 SdrHint aHint(*this);
2865 aHint.SetKind(bIns?HINT_OBJINSERTED:HINT_OBJREMOVED);
2866 pPlusData->pBroadcast->Broadcast(aHint);
2871 void SdrObject::SetMoveProtect(bool bProt)
2873 if(IsMoveProtect() != bProt)
2875 // #i77187# secured and simplified
2876 bMovProt = bProt;
2877 SetChanged();
2878 BroadcastObjectChange();
2882 void SdrObject::SetResizeProtect(bool bProt)
2884 if(IsResizeProtect() != bProt)
2886 // #i77187# secured and simplified
2887 bSizProt = bProt;
2888 SetChanged();
2889 BroadcastObjectChange();
2893 void SdrObject::SetPrintable(bool bPrn)
2895 if( bPrn == bNoPrint )
2897 bNoPrint=!bPrn;
2898 SetChanged();
2899 if (IsInserted() && pModel!=NULL)
2901 SdrHint aHint(*this);
2902 pModel->Broadcast(aHint);
2907 void SdrObject::SetVisible(bool bVisible)
2909 if( bVisible != mbVisible )
2911 mbVisible = bVisible;
2912 SetChanged();
2913 if (IsInserted() && pModel!=NULL)
2915 SdrHint aHint(*this);
2916 pModel->Broadcast(aHint);
2923 sal_uInt16 SdrObject::GetUserDataCount() const
2925 if (pPlusData==NULL || pPlusData->pUserDataList==NULL) return 0;
2926 return pPlusData->pUserDataList->GetUserDataCount();
2929 SdrObjUserData* SdrObject::GetUserData(sal_uInt16 nNum) const
2931 if (pPlusData==NULL || pPlusData->pUserDataList==NULL) return NULL;
2932 return pPlusData->pUserDataList->GetUserData(nNum);
2935 void SdrObject::AppendUserData(SdrObjUserData* pData)
2937 if (!pData)
2939 OSL_FAIL("SdrObject::AppendUserData(): pData is NULL pointer.");
2940 return;
2943 ImpForcePlusData();
2944 if (!pPlusData->pUserDataList)
2945 pPlusData->pUserDataList = new SdrObjUserDataList;
2947 pPlusData->pUserDataList->AppendUserData(pData);
2950 void SdrObject::DeleteUserData(sal_uInt16 nNum)
2952 sal_uInt16 nAnz=GetUserDataCount();
2953 if (nNum<nAnz) {
2954 pPlusData->pUserDataList->DeleteUserData(nNum);
2955 if (nAnz==1) {
2956 delete pPlusData->pUserDataList;
2957 pPlusData->pUserDataList=NULL;
2959 } else {
2960 OSL_FAIL("SdrObject::DeleteUserData(): Invalid Index.");
2964 void SdrObject::SetUserCall(SdrObjUserCall* pUser)
2966 pUserCall = pUser;
2969 SdrObjUserCall* SdrObject::GetUserCall() const
2971 return pUserCall;
2974 void SdrObject::SendUserCall(SdrUserCallType eUserCall, const Rectangle& rBoundRect) const
2976 SdrObjGroup* pGroup = NULL;
2978 if( pObjList && pObjList->GetListKind() == SDROBJLIST_GROUPOBJ )
2979 pGroup = (SdrObjGroup*) pObjList->GetOwnerObj();
2981 if ( pUserCall )
2983 pUserCall->Changed( *this, eUserCall, rBoundRect );
2986 while( pGroup )
2988 // broadcast to group
2989 if( pGroup->GetUserCall() )
2991 SdrUserCallType eChildUserType = SDRUSERCALL_CHILD_CHGATTR;
2993 switch( eUserCall )
2995 case SDRUSERCALL_MOVEONLY:
2996 eChildUserType = SDRUSERCALL_CHILD_MOVEONLY;
2997 break;
2999 case SDRUSERCALL_RESIZE:
3000 eChildUserType = SDRUSERCALL_CHILD_RESIZE;
3001 break;
3003 case SDRUSERCALL_CHGATTR:
3004 eChildUserType = SDRUSERCALL_CHILD_CHGATTR;
3005 break;
3007 case SDRUSERCALL_DELETE:
3008 eChildUserType = SDRUSERCALL_CHILD_DELETE;
3009 break;
3011 case SDRUSERCALL_COPY:
3012 eChildUserType = SDRUSERCALL_CHILD_COPY;
3013 break;
3015 case SDRUSERCALL_INSERTED:
3016 eChildUserType = SDRUSERCALL_CHILD_INSERTED;
3017 break;
3019 case SDRUSERCALL_REMOVED:
3020 eChildUserType = SDRUSERCALL_CHILD_REMOVED;
3021 break;
3023 default: break;
3026 pGroup->GetUserCall()->Changed( *this, eChildUserType, rBoundRect );
3029 if( pGroup->GetObjList() &&
3030 pGroup->GetObjList()->GetListKind() == SDROBJLIST_GROUPOBJ &&
3031 pGroup != (SdrObjGroup*) pObjList->GetOwnerObj() )
3032 pGroup = (SdrObjGroup*) pObjList->GetOwnerObj();
3033 else
3034 pGroup = NULL;
3037 // notify our UNO shape listeners
3038 switch ( eUserCall )
3040 case SDRUSERCALL_RESIZE:
3041 notifyShapePropertyChange( ::svx::eShapeSize );
3042 // fall through - RESIZE might also imply a change of the position
3043 case SDRUSERCALL_MOVEONLY:
3044 notifyShapePropertyChange( ::svx::eShapePosition );
3045 break;
3046 default:
3047 // not interested in
3048 break;
3052 // change ItemPool for this object
3053 void SdrObject::MigrateItemPool(SfxItemPool* pSrcPool, SfxItemPool* pDestPool, SdrModel* pNewModel)
3055 if(pSrcPool && pDestPool && (pSrcPool != pDestPool))
3057 GetProperties().MoveToItemPool(pSrcPool, pDestPool, pNewModel);
3061 void SdrObject::impl_setUnoShape( const uno::Reference< uno::XInterface >& _rxUnoShape )
3063 const uno::Reference< uno::XInterface>& xOldUnoShape( maWeakUnoShape );
3064 // the UNO shape would be gutted by the following code; return early
3065 if ( _rxUnoShape == xOldUnoShape )
3067 if ( !xOldUnoShape.is() )
3069 // make sure there is no stale impl. pointer if the UNO
3070 // shape was destroyed meanwhile (remember we only hold weak
3071 // reference to it!)
3072 mpSvxShape = 0;
3074 return;
3077 bool bTransferOwnership( false );
3078 if ( xOldUnoShape.is() )
3080 bTransferOwnership = mpSvxShape->HasSdrObjectOwnership();
3081 // Remove yourself from the current UNO shape. Its destructor
3082 // will reset our UNO shape otherwise.
3083 mpSvxShape->InvalidateSdrObject();
3086 maWeakUnoShape = _rxUnoShape;
3087 mpSvxShape = SvxShape::getImplementation( _rxUnoShape );
3089 // I think this may never happen... But I am not sure enough .-)
3090 if ( bTransferOwnership )
3092 if ( _rxUnoShape.is() )
3093 mpSvxShape->TakeSdrObjectOwnership();
3094 SAL_WARN( "svx.uno", "a UNO shape took over an SdrObject previously owned by another UNO shape!");
3098 /** only for internal use! */
3099 SvxShape* SdrObject::getSvxShape()
3101 DBG_TESTSOLARMUTEX();
3102 // retrieving the impl pointer and subsequently using it is not thread-safe, of course, so it needs to be
3103 // guarded by the SolarMutex
3105 uno::Reference< uno::XInterface > xShape( maWeakUnoShape );
3106 #if OSL_DEBUG_LEVEL > 0
3107 OSL_ENSURE( !( !xShape.is() && mpSvxShape ),
3108 "SdrObject::getSvxShape: still having IMPL-Pointer to dead object!" );
3109 #endif
3110 //#113608#, make sure mpSvxShape is always synchronized with maWeakUnoShape
3111 if ( mpSvxShape && !xShape.is() )
3112 mpSvxShape = NULL;
3114 return mpSvxShape;
3117 ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SdrObject::getUnoShape()
3119 // try weak reference first
3120 uno::Reference< uno::XInterface > xShape( getWeakUnoShape() );
3121 if( !xShape.is() )
3123 OSL_ENSURE( mpSvxShape == NULL, "SdrObject::getUnoShape: XShape already dead, but still an IMPL pointer!" );
3124 if ( pPage )
3126 uno::Reference< uno::XInterface > xPage( pPage->getUnoPage() );
3127 if( xPage.is() )
3129 SvxDrawPage* pDrawPage = SvxDrawPage::getImplementation(xPage);
3130 if( pDrawPage )
3132 // create one
3133 xShape = pDrawPage->_CreateShape( this );
3134 impl_setUnoShape( xShape );
3138 else
3140 mpSvxShape = SvxDrawPage::CreateShapeByTypeAndInventor( GetObjIdentifier(), GetObjInventor(), this, NULL );
3141 maWeakUnoShape = xShape = static_cast< ::cppu::OWeakObject* >( mpSvxShape );
3145 return xShape;
3148 void SdrObject::setUnoShape(const uno::Reference<uno::XInterface >& _rxUnoShape)
3150 impl_setUnoShape( _rxUnoShape );
3153 ::svx::PropertyChangeNotifier& SdrObject::getShapePropertyChangeNotifier()
3155 DBG_TESTSOLARMUTEX();
3157 SvxShape* pSvxShape = getSvxShape();
3158 ENSURE_OR_THROW( pSvxShape, "no SvxShape, yet!" );
3159 return pSvxShape->getShapePropertyChangeNotifier();
3162 void SdrObject::notifyShapePropertyChange( const ::svx::ShapeProperty _eProperty ) const
3164 DBG_TESTSOLARMUTEX();
3166 SvxShape* pSvxShape = const_cast< SdrObject* >( this )->getSvxShape();
3167 if ( pSvxShape )
3168 return pSvxShape->getShapePropertyChangeNotifier().notifyPropertyChange( _eProperty );
3173 // transformation interface for StarOfficeAPI. This implements support for
3174 // homogeneous 3x3 matrices containing the transformation of the SdrObject. At the
3175 // moment it contains a shearX, rotation and translation, but for setting all linear
3176 // transforms like Scale, ShearX, ShearY, Rotate and Translate are supported.
3179 // gets base transformation and rectangle of object. If it's an SdrPathObj it fills the PolyPolygon
3180 // with the base geometry and returns TRUE. Otherwise it returns FALSE.
3181 bool SdrObject::TRGetBaseGeometry(basegfx::B2DHomMatrix& rMatrix, basegfx::B2DPolyPolygon& /*rPolyPolygon*/) const
3183 // any kind of SdrObject, just use SnapRect
3184 Rectangle aRectangle(GetSnapRect());
3186 // convert to transformation values
3187 basegfx::B2DTuple aScale(aRectangle.GetWidth(), aRectangle.GetHeight());
3188 basegfx::B2DTuple aTranslate(aRectangle.Left(), aRectangle.Top());
3190 // position maybe relative to anchorpos, convert
3191 if( pModel && pModel->IsWriter() )
3193 if(GetAnchorPos().X() || GetAnchorPos().Y())
3195 aTranslate -= basegfx::B2DTuple(GetAnchorPos().X(), GetAnchorPos().Y());
3199 // force MapUnit to 100th mm
3200 const SfxMapUnit eMapUnit(GetObjectMapUnit());
3201 if(eMapUnit != SFX_MAPUNIT_100TH_MM)
3203 switch(eMapUnit)
3205 case SFX_MAPUNIT_TWIP :
3207 // position
3208 aTranslate.setX(ImplTwipsToMM(aTranslate.getX()));
3209 aTranslate.setY(ImplTwipsToMM(aTranslate.getY()));
3211 // size
3212 aScale.setX(ImplTwipsToMM(aScale.getX()));
3213 aScale.setY(ImplTwipsToMM(aScale.getY()));
3215 break;
3217 default:
3219 OSL_FAIL("TRGetBaseGeometry: Missing unit translation to 100th mm!");
3224 // build matrix
3225 rMatrix = basegfx::tools::createScaleTranslateB2DHomMatrix(aScale, aTranslate);
3227 return false;
3230 // sets the base geometry of the object using infos contained in the homogeneous 3x3 matrix.
3231 // If it's an SdrPathObj it will use the provided geometry information. The Polygon has
3232 // to use (0,0) as upper left and will be scaled to the given size in the matrix.
3233 void SdrObject::TRSetBaseGeometry(const basegfx::B2DHomMatrix& rMatrix, const basegfx::B2DPolyPolygon& /*rPolyPolygon*/)
3235 // break up matrix
3236 basegfx::B2DTuple aScale;
3237 basegfx::B2DTuple aTranslate;
3238 double fRotate, fShearX;
3239 rMatrix.decompose(aScale, aTranslate, fRotate, fShearX);
3241 // #i75086# Old DrawingLayer (GeoStat and geometry) does not support holding negative scalings
3242 // in X and Y which equal a 180 degree rotation. Recognize it and react accordingly
3243 if(basegfx::fTools::less(aScale.getX(), 0.0) && basegfx::fTools::less(aScale.getY(), 0.0))
3245 aScale.setX(fabs(aScale.getX()));
3246 aScale.setY(fabs(aScale.getY()));
3247 fRotate = fmod(fRotate + F_PI, F_2PI);
3250 // force metric to pool metric
3251 const SfxMapUnit eMapUnit(GetObjectMapUnit());
3252 if(eMapUnit != SFX_MAPUNIT_100TH_MM)
3254 switch(eMapUnit)
3256 case SFX_MAPUNIT_TWIP :
3258 // position
3259 aTranslate.setX(ImplMMToTwips(aTranslate.getX()));
3260 aTranslate.setY(ImplMMToTwips(aTranslate.getY()));
3262 // size
3263 aScale.setX(ImplMMToTwips(aScale.getX()));
3264 aScale.setY(ImplMMToTwips(aScale.getY()));
3266 break;
3268 default:
3270 OSL_FAIL("TRSetBaseGeometry: Missing unit translation to PoolMetric!");
3275 // if anchor is used, make position relative to it
3276 if( pModel && pModel->IsWriter() )
3278 if(GetAnchorPos().X() || GetAnchorPos().Y())
3280 aTranslate += basegfx::B2DTuple(GetAnchorPos().X(), GetAnchorPos().Y());
3284 // build BaseRect
3285 Point aPoint(FRound(aTranslate.getX()), FRound(aTranslate.getY()));
3286 Rectangle aBaseRect(aPoint, Size(FRound(aScale.getX()), FRound(aScale.getY())));
3288 // set BaseRect
3289 SetSnapRect(aBaseRect);
3292 // Give info if object is in destruction
3293 bool SdrObject::IsInDestruction() const
3295 if(pModel)
3296 return pModel->IsInDestruction();
3297 return false;
3300 // return if fill is != XFILL_NONE
3301 bool SdrObject::HasFillStyle() const
3303 return (((const XFillStyleItem&)GetObjectItem(XATTR_FILLSTYLE)).GetValue() != XFILL_NONE);
3306 bool SdrObject::HasLineStyle() const
3308 return (((const XLineStyleItem&)GetObjectItem(XATTR_LINESTYLE)).GetValue() != XLINE_NONE);
3312 // #i52224#
3313 // on import of OLE object from MS documents the BLIP size might be retrieved,
3314 // the following four methods are used to control it;
3315 // usually this data makes no sence after the import is finished, since the object
3316 // might be resized
3318 Rectangle SdrObject::GetBLIPSizeRectangle() const
3320 return maBLIPSizeRectangle;
3323 void SdrObject::SetBLIPSizeRectangle( const Rectangle& aRect )
3325 maBLIPSizeRectangle = aRect;
3328 void SdrObject::SetContextWritingMode( const sal_Int16 /*_nContextWritingMode*/ )
3330 // this base class does not support different writing modes, so ignore the call
3333 void SdrObject::SetDoNotInsertIntoPageAutomatically(const bool bSet)
3335 mbDoNotInsertIntoPageAutomatically = bSet;
3338 bool SdrObject::IsDoNotInsertIntoPageAutomatically() const
3340 return mbDoNotInsertIntoPageAutomatically;
3343 // #i121917#
3344 bool SdrObject::HasText() const
3346 return false;
3349 SdrObjFactory::SdrObjFactory(sal_uInt32 nInvent, sal_uInt16 nIdent, SdrPage* pNewPage, SdrModel* pNewModel)
3351 nInventor=nInvent;
3352 nIdentifier=nIdent;
3353 pNewObj=NULL;
3354 pPage=pNewPage;
3355 pModel=pNewModel;
3356 pObj=NULL;
3357 pNewData=NULL;
3360 SdrObject* SdrObjFactory::MakeNewObject(sal_uInt32 nInvent, sal_uInt16 nIdent, SdrPage* pPage, SdrModel* pModel)
3362 if(pModel == NULL && pPage != NULL)
3363 pModel = pPage->GetModel();
3364 SdrObject* pObj = NULL;
3366 if(nInvent == SdrInventor)
3368 switch (nIdent)
3370 case sal_uInt16(OBJ_NONE ): pObj=new SdrObject; break;
3371 case sal_uInt16(OBJ_GRUP ): pObj=new SdrObjGroup; break;
3372 case sal_uInt16(OBJ_LINE ): pObj=new SdrPathObj(OBJ_LINE ); break;
3373 case sal_uInt16(OBJ_POLY ): pObj=new SdrPathObj(OBJ_POLY ); break;
3374 case sal_uInt16(OBJ_PLIN ): pObj=new SdrPathObj(OBJ_PLIN ); break;
3375 case sal_uInt16(OBJ_PATHLINE ): pObj=new SdrPathObj(OBJ_PATHLINE ); break;
3376 case sal_uInt16(OBJ_PATHFILL ): pObj=new SdrPathObj(OBJ_PATHFILL ); break;
3377 case sal_uInt16(OBJ_FREELINE ): pObj=new SdrPathObj(OBJ_FREELINE ); break;
3378 case sal_uInt16(OBJ_FREEFILL ): pObj=new SdrPathObj(OBJ_FREEFILL ); break;
3379 case sal_uInt16(OBJ_PATHPOLY ): pObj=new SdrPathObj(OBJ_POLY ); break;
3380 case sal_uInt16(OBJ_PATHPLIN ): pObj=new SdrPathObj(OBJ_PLIN ); break;
3381 case sal_uInt16(OBJ_EDGE ): pObj=new SdrEdgeObj; break;
3382 case sal_uInt16(OBJ_RECT ): pObj=new SdrRectObj; break;
3383 case sal_uInt16(OBJ_CIRC ): pObj=new SdrCircObj(OBJ_CIRC ); break;
3384 case sal_uInt16(OBJ_SECT ): pObj=new SdrCircObj(OBJ_SECT ); break;
3385 case sal_uInt16(OBJ_CARC ): pObj=new SdrCircObj(OBJ_CARC ); break;
3386 case sal_uInt16(OBJ_CCUT ): pObj=new SdrCircObj(OBJ_CCUT ); break;
3387 case sal_uInt16(OBJ_TEXT ): pObj=new SdrRectObj(OBJ_TEXT ); break;
3388 case sal_uInt16(OBJ_TEXTEXT ): pObj=new SdrRectObj(OBJ_TEXTEXT ); break;
3389 case sal_uInt16(OBJ_TITLETEXT ): pObj=new SdrRectObj(OBJ_TITLETEXT ); break;
3390 case sal_uInt16(OBJ_OUTLINETEXT): pObj=new SdrRectObj(OBJ_OUTLINETEXT); break;
3391 case sal_uInt16(OBJ_MEASURE ): pObj=new SdrMeasureObj; break;
3392 case sal_uInt16(OBJ_GRAF ): pObj=new SdrGrafObj; break;
3393 case sal_uInt16(OBJ_OLE2 ): pObj=new SdrOle2Obj; break;
3394 case sal_uInt16(OBJ_FRAME ): pObj=new SdrOle2Obj(true); break;
3395 case sal_uInt16(OBJ_CAPTION ): pObj=new SdrCaptionObj; break;
3396 case sal_uInt16(OBJ_PAGE ): pObj=new SdrPageObj; break;
3397 case sal_uInt16(OBJ_UNO ): pObj=new SdrUnoObj(OUString()); break;
3398 case sal_uInt16(OBJ_CUSTOMSHAPE ): pObj=new SdrObjCustomShape(); break;
3399 #if HAVE_FEATURE_AVMEDIA
3400 case sal_uInt16(OBJ_MEDIA ): pObj=new SdrMediaObj(); break;
3401 #endif
3402 case sal_uInt16(OBJ_TABLE ): pObj=new ::sdr::table::SdrTableObj(pModel); break;
3403 case sal_uInt16(OBJ_OPENGL ): pObj=new SdrOpenGLObj; break;
3407 if(pObj == NULL)
3409 SdrObjFactory* pFact=new SdrObjFactory(nInvent,nIdent,pPage,pModel);
3410 SdrLinkList& rLL=ImpGetUserMakeObjHdl();
3411 unsigned nAnz=rLL.GetLinkCount();
3412 unsigned i=0;
3413 while (i<nAnz && pObj==NULL) {
3414 rLL.GetLink(i).Call((void*)pFact);
3415 pObj=pFact->pNewObj;
3416 i++;
3418 delete pFact;
3421 if(pObj == NULL)
3423 // Well, if no one wants it...
3426 if(pObj != NULL)
3428 if(pPage != NULL)
3429 pObj->SetPage(pPage);
3430 else if(pModel != NULL)
3431 pObj->SetModel(pModel);
3434 return pObj;
3437 void SdrObjFactory::InsertMakeObjectHdl(const Link& rLink)
3439 SdrLinkList& rLL=ImpGetUserMakeObjHdl();
3440 rLL.InsertLink(rLink);
3443 void SdrObjFactory::RemoveMakeObjectHdl(const Link& rLink)
3445 SdrLinkList& rLL=ImpGetUserMakeObjHdl();
3446 rLL.RemoveLink(rLink);
3449 void SdrObjFactory::InsertMakeUserDataHdl(const Link& rLink)
3451 SdrLinkList& rLL=ImpGetUserMakeObjUserDataHdl();
3452 rLL.InsertLink(rLink);
3455 void SdrObjFactory::RemoveMakeUserDataHdl(const Link& rLink)
3457 SdrLinkList& rLL=ImpGetUserMakeObjUserDataHdl();
3458 rLL.RemoveLink(rLink);
3461 namespace svx
3463 ISdrObjectFilter::~ISdrObjectFilter()
3468 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */