xref: /aoo41x/main/svx/source/svdraw/svdobj.cxx (revision a5258243)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_svx.hxx"
30 #include <com/sun/star/lang/XComponent.hpp>
31 
32 #define _USE_MATH_DEFINES
33 #include <math.h>
34 #include <vcl/metaact.hxx>   // fuer TakeContour
35 #include <vcl/cvtsvm.hxx>
36 #include <tools/line.hxx>
37 #include <tools/bigint.hxx>
38 #include <tools/diagnose_ex.h>
39 #include <vector>
40 #include <svx/svdobj.hxx>
41 #include <svx/xpoly.hxx>
42 #include <svx/svdetc.hxx>
43 #include <svx/svdtrans.hxx>
44 #include <svx/svdhdl.hxx>
45 #include <svx/svddrag.hxx>
46 #include <svx/svdmodel.hxx>
47 #include <svx/svdpage.hxx>
48 #include <svx/svdovirt.hxx>  // Fuer Add/Del Ref
49 #include <svx/svdview.hxx>   // fuer Dragging (Ortho abfragen)
50 #include "svx/svdglob.hxx"   // StringCache
51 #include <svx/svdstr.hrc>    // Objektname
52 #include <svx/svdogrp.hxx>   // Factory
53 #include <svx/svdopath.hxx>  // Factory
54 #include <svx/svdoedge.hxx>  // Factory
55 #include <svx/svdorect.hxx>  // Factory
56 #include <svx/svdocirc.hxx>  // Factory
57 #include <svx/svdotext.hxx>  // Factory
58 #include <svx/svdomeas.hxx>  // Factory
59 #include <svx/svdograf.hxx>  // Factory
60 #include <svx/svdoole2.hxx>  // Factory
61 #include <svx/svdocapt.hxx>  // Factory
62 #include <svx/svdopage.hxx>  // Factory
63 #include <svx/svdouno.hxx>   // Factory
64 #include <svx/svdattrx.hxx> // NotPersistItems
65 #include <svx/svdoashp.hxx>
66 #include <svx/svdomedia.hxx>
67 #include <svx/xlnwtit.hxx>
68 #include <svx/xlnstwit.hxx>
69 #include <svx/xlnedwit.hxx>
70 #include <svx/xlnstit.hxx>
71 #include <svx/xlnedit.hxx>
72 #include <svx/xlnstcit.hxx>
73 #include <svx/xlnedcit.hxx>
74 #include <svx/xlndsit.hxx>
75 #include <svx/xlnclit.hxx>
76 #include <svx/xflclit.hxx>
77 #include <svx/svditer.hxx>
78 #include <svx/xlntrit.hxx>
79 #include <svx/xfltrit.hxx>
80 #include <svx/xfltrit.hxx>
81 #include <svx/xflftrit.hxx>
82 #include "svx/xlinjoit.hxx"
83 #include <svx/unopage.hxx>
84 #include <editeng/eeitem.hxx>
85 #include <svx/xenum.hxx>
86 #include <svx/xgrad.hxx>
87 #include <svx/xhatch.hxx>
88 #include <svx/xflhtit.hxx>
89 #include <svx/xbtmpit.hxx>
90 #include <svx/svdpool.hxx>
91 #include <editeng/editeng.hxx>
92 #include <vcl/salbtype.hxx>		// FRound
93 #include <svl/whiter.hxx>
94 
95 // #97849#
96 #include <svx/fmmodel.hxx>
97 #include <sfx2/objsh.hxx>
98 #include <sfx2/objface.hxx>
99 #include "svdoimp.hxx"
100 #include <vcl/graphictools.hxx>
101 #include <svtools/colorcfg.hxx>
102 #include <svx/sdr/properties/emptyproperties.hxx>
103 #include <svx/sdr/contact/viewcontactofsdrobj.hxx>
104 #include <svx/sdr/contact/viewcontactofgraphic.hxx>
105 #include <svx/sdr/contact/objectcontactofobjlistpainter.hxx>
106 #include <svx/sdr/contact/displayinfo.hxx>
107 #include <basegfx/polygon/b2dpolygon.hxx>
108 #include <basegfx/polygon/b2dpolygontools.hxx>
109 #include <basegfx/matrix/b2dhommatrix.hxx>
110 #include <basegfx/polygon/b2dpolypolygontools.hxx>
111 #include <basegfx/range/b2drange.hxx>
112 #include <svx/unoshape.hxx>
113 #include <vcl/virdev.hxx>
114 #include <basegfx/polygon/b2dpolypolygoncutter.hxx>
115 #include <drawinglayer/processor2d/contourextractor2d.hxx>
116 #include <drawinglayer/processor2d/linegeometryextractor2d.hxx>
117 #include <svx/polysc3d.hxx>
118 #include "svx/svdotable.hxx"
119 #include "svx/shapepropertynotifier.hxx"
120 #include <svx/sdrhittesthelper.hxx>
121 #include <svx/svdundo.hxx>
122 #include <basegfx/matrix/b2dhommatrixtools.hxx>
123 #include <svx/sdrobjectfilter.hxx>
124 
125 using namespace ::com::sun::star;
126 
127 // #104018# replace macros above with type-detecting methods
128 inline double ImplTwipsToMM(double fVal) { return (fVal * (127.0 / 72.0)); }
129 inline double ImplMMToTwips(double fVal) { return (fVal * (72.0 / 127.0)); }
130 
131 ////////////////////////////////////////////////////////////////////////////////////////////////////
132 
133 TYPEINIT0(SdrObjUserCall);
134 
135 SdrObjUserCall::~SdrObjUserCall()
136 {
137 }
138 
139 void SdrObjUserCall::Changed(const SdrObject& /*rObj*/, SdrUserCallType /*eType*/, const Rectangle& /*rOldBoundRect*/)
140 {
141 }
142 
143 ////////////////////////////////////////////////////////////////////////////////////////////////////
144 
145 TYPEINIT0(SdrObjUserData);
146 
147 void SdrObjUserData::operator=(const SdrObjUserData& /*rData*/)    // nicht implementiert
148 {
149 }
150 
151 sal_Bool SdrObjUserData::operator==(const SdrObjUserData& /*rData*/) const // nicht implementiert
152 {
153 	return sal_False;
154 }
155 
156 sal_Bool SdrObjUserData::operator!=(const SdrObjUserData& /*rData*/) const // nicht implementiert
157 {
158 	return sal_False;
159 }
160 
161 SdrObjUserData::~SdrObjUserData()
162 {
163 }
164 
165 FASTBOOL SdrObjUserData::HasMacro(const SdrObject* /*pObj*/) const
166 {
167 	return sal_False;
168 }
169 
170 SdrObject* SdrObjUserData::CheckMacroHit(const SdrObjMacroHitRec& rRec, const SdrObject* pObj) const
171 {
172 	if(pObj)
173     {
174         if(rRec.pPageView)
175         {
176     	    return SdrObjectPrimitiveHit(*pObj, rRec.aPos, rRec.nTol, *rRec.pPageView, rRec.pVisiLayer, false);
177         }
178     }
179 
180 	return 0;
181 }
182 
183 Pointer SdrObjUserData::GetMacroPointer(const SdrObjMacroHitRec& /*rRec*/, const SdrObject* /*pObj*/) const
184 {
185 	return Pointer(POINTER_REFHAND);
186 }
187 
188 void SdrObjUserData::PaintMacro(OutputDevice& rOut, const Rectangle& /*rDirtyRect*/, const SdrObjMacroHitRec& /*rRec*/, const SdrObject* pObj) const
189 {
190 	if(!pObj)
191         return;
192 
193 	const RasterOp eRop(rOut.GetRasterOp());
194 	const basegfx::B2DPolyPolygon aPolyPolygon(pObj->TakeXorPoly());
195 	const sal_uInt32 nCount(aPolyPolygon.count());
196 
197     rOut.SetLineColor(COL_BLACK);
198     rOut.SetFillColor();
199 	rOut.SetRasterOp(ROP_INVERT);
200 
201 	for(sal_uInt32 a(0); a < nCount; a++)
202 	{
203 		rOut.DrawPolyLine(aPolyPolygon.getB2DPolygon(a));
204 	}
205 
206     rOut.SetRasterOp(eRop);
207 }
208 
209 FASTBOOL SdrObjUserData::DoMacro(const SdrObjMacroHitRec& /*rRec*/, SdrObject* /*pObj*/)
210 {
211 	return sal_False;
212 }
213 
214 XubString SdrObjUserData::GetMacroPopupComment(const SdrObjMacroHitRec& /*rRec*/, const SdrObject* /*pObj*/) const
215 {
216 	return String();
217 }
218 
219 void SdrObjUserDataList::Clear()
220 {
221 	sal_uInt16 nAnz=GetUserDataCount();
222 	for (sal_uInt16 i=0; i<nAnz; i++) {
223 		delete GetUserData(i);
224 	}
225 	aList.Clear();
226 }
227 
228 ////////////////////////////////////////////////////////////////////////////////////////////////////
229 
230 DBG_NAME(SdrObjGeoData);
231 
232 SdrObjGeoData::SdrObjGeoData():
233 	pGPL(NULL),
234 	bMovProt(sal_False),
235 	bSizProt(sal_False),
236 	bNoPrint(sal_False),
237 	bClosedObj(sal_False),
238 	mbVisible(true),
239 	mnLayerID(0)
240 {
241 	DBG_CTOR(SdrObjGeoData,NULL);
242 }
243 
244 SdrObjGeoData::~SdrObjGeoData()
245 {
246 	DBG_DTOR(SdrObjGeoData,NULL);
247 	delete pGPL;
248 }
249 
250 ////////////////////////////////////////////////////////////////////////////////////////////////////
251 
252 TYPEINIT0(SdrObjPlusData);
253 
254 SdrObjPlusData::SdrObjPlusData():
255 	pBroadcast(NULL),
256 	pUserDataList(NULL),
257 	pGluePoints(NULL),
258 	pAutoTimer(NULL)
259 {
260 }
261 
262 SdrObjPlusData::~SdrObjPlusData()
263 {
264 	if (pBroadcast   !=NULL) delete pBroadcast;
265 	if (pUserDataList!=NULL) delete pUserDataList;
266 	if (pGluePoints  !=NULL) delete pGluePoints;
267 	if (pAutoTimer   !=NULL) delete pAutoTimer;
268 }
269 
270 SdrObjPlusData* SdrObjPlusData::Clone(SdrObject* pObj1) const
271 {
272 	SdrObjPlusData* pNeuPlusData=new SdrObjPlusData;
273 	if (pUserDataList!=NULL) {
274 		sal_uInt16 nAnz=pUserDataList->GetUserDataCount();
275 		if (nAnz!=0) {
276 			pNeuPlusData->pUserDataList=new SdrObjUserDataList;
277 			for (sal_uInt16 i=0; i<nAnz; i++) {
278 				SdrObjUserData* pNeuUserData=pUserDataList->GetUserData(i)->Clone(pObj1);
279 				if (pNeuUserData!=NULL) {
280 					pNeuPlusData->pUserDataList->InsertUserData(pNeuUserData);
281 				} else {
282 					DBG_ERROR("SdrObjPlusData::Clone(): UserData.Clone() liefert NULL");
283 				}
284 			}
285 		}
286 	}
287 	if (pGluePoints!=NULL) pNeuPlusData->pGluePoints=new SdrGluePointList(*pGluePoints);
288 	// MtfAnimator wird auch nicht mitkopiert
289 
290 	// #i68101#
291 	// copy object name, title and description
292 	pNeuPlusData->aObjName = aObjName;
293 	pNeuPlusData->aObjTitle = aObjTitle;
294 	pNeuPlusData->aObjDescription = aObjDescription;
295 
296 	if (pAutoTimer!=NULL) {
297 		pNeuPlusData->pAutoTimer=new AutoTimer;
298 		// Handler, etc. nicht mitkopieren!
299 	}
300 
301 	// For HTMLName: Do not clone, leave uninitialized (empty string)
302 
303 	return pNeuPlusData;
304 }
305 
306 ////////////////////////////////////////////////////////////////////////////////////////////////////
307 //
308 //   @@@@  @@@@@  @@@@@@ @@@@@  @@@@  @@@@@@
309 //  @@  @@ @@  @@     @@ @@    @@  @@   @@
310 //  @@  @@ @@  @@     @@ @@    @@       @@
311 //  @@  @@ @@@@@      @@ @@@@  @@       @@
312 //  @@  @@ @@  @@     @@ @@    @@       @@
313 //  @@  @@ @@  @@ @@  @@ @@    @@  @@   @@
314 //   @@@@  @@@@@   @@@@  @@@@@  @@@@    @@
315 //
316 ////////////////////////////////////////////////////////////////////////////////////////////////////
317 
318 //////////////////////////////////////////////////////////////////////////////
319 // BaseProperties section
320 
321 sdr::properties::BaseProperties* SdrObject::CreateObjectSpecificProperties()
322 {
323 	return new sdr::properties::EmptyProperties(*this);
324 }
325 
326 sdr::properties::BaseProperties& SdrObject::GetProperties() const
327 {
328 	if(!mpProperties)
329 	{
330 		const_cast< SdrObject* >(this)->mpProperties =
331             const_cast< SdrObject* >(this)->CreateObjectSpecificProperties();
332 	}
333 
334 	return *mpProperties;
335 }
336 
337 //////////////////////////////////////////////////////////////////////////////
338 // ObjectUser section
339 
340 void SdrObject::AddObjectUser(sdr::ObjectUser& rNewUser)
341 {
342 	maObjectUsers.push_back(&rNewUser);
343 }
344 
345 void SdrObject::RemoveObjectUser(sdr::ObjectUser& rOldUser)
346 {
347 	const ::sdr::ObjectUserVector::iterator aFindResult = ::std::find(maObjectUsers.begin(), maObjectUsers.end(), &rOldUser);
348 	if(aFindResult != maObjectUsers.end())
349 	{
350 		maObjectUsers.erase(aFindResult);
351 	}
352 }
353 
354 //////////////////////////////////////////////////////////////////////////////
355 // #110094# DrawContact section
356 
357 sdr::contact::ViewContact* SdrObject::CreateObjectSpecificViewContact()
358 {
359 	return new sdr::contact::ViewContactOfSdrObj(*this);
360 }
361 
362 sdr::contact::ViewContact& SdrObject::GetViewContact() const
363 {
364 	if(!mpViewContact)
365 	{
366 		const_cast< SdrObject* >(this)->mpViewContact =
367             const_cast< SdrObject* >(this)->CreateObjectSpecificViewContact();
368 	}
369 
370 	return *mpViewContact;
371 }
372 
373 // DrawContact support: Methods for handling Object changes
374 void SdrObject::ActionChanged() const
375 {
376     // Do necessary ViewContact actions
377 	GetViewContact().ActionChanged();
378 }
379 
380 //////////////////////////////////////////////////////////////////////////////
381 
382 void SdrObject::SetBoundRectDirty()
383 {
384 	aOutRect = Rectangle();
385 }
386 
387 //////////////////////////////////////////////////////////////////////////////
388 
389 DBG_NAME(SdrObject);
390 TYPEINIT1(SdrObject,SfxListener);
391 
392 SdrObject::SdrObject()
393     :mpProperties(0L)
394     ,mpViewContact(0L)
395     ,pObjList(NULL)
396     ,pPage(NULL)
397     ,pModel(NULL)
398     ,pUserCall(NULL)
399     ,pPlusData(NULL)
400     ,nOrdNum(0)
401     ,mnNavigationPosition(SAL_MAX_UINT32)
402     ,mnLayerID(0)
403     ,mpSvxShape( NULL )
404     ,maWeakUnoShape()
405 {
406 	DBG_CTOR(SdrObject,NULL);
407 	bVirtObj         =sal_False;
408 	bSnapRectDirty   =sal_True;
409 	bNetLock         =sal_False;
410 	bInserted        =sal_False;
411 	bGrouped         =sal_False;
412 	bMovProt         =sal_False;
413 	bSizProt         =sal_False;
414 	bNoPrint         =sal_False;
415 	bEmptyPresObj    =sal_False;
416 	bNotVisibleAsMaster=sal_False;
417 	bClosedObj       =sal_False;
418 	mbVisible		 = true;
419 
420 	// #i25616#
421 	mbLineIsOutsideGeometry = sal_False;
422 
423 	// #i25616#
424 	mbSupportTextIndentingOnLineWidthChange = sal_False;
425 
426 	//#110094#-1
427 	//bWriterFlyFrame  =sal_False;
428 
429 	bNotMasterCachable=sal_False;
430 	bIsEdge=sal_False;
431 	bIs3DObj=sal_False;
432 	bMarkProt=sal_False;
433 	bIsUnoObj=sal_False;
434 }
435 
436 SdrObject::~SdrObject()
437 {
438 	// tell all the registered ObjectUsers that the page is in destruction
439 	::sdr::ObjectUserVector aListCopy(maObjectUsers.begin(), maObjectUsers.end());
440 	for(::sdr::ObjectUserVector::iterator aIterator = aListCopy.begin(); aIterator != aListCopy.end(); aIterator++)
441 	{
442 		sdr::ObjectUser* pObjectUser = *aIterator;
443 		DBG_ASSERT(pObjectUser, "SdrObject::~SdrObject: corrupt ObjectUser list (!)");
444 		pObjectUser->ObjectInDestruction(*this);
445 	}
446 
447 	// Clear the vector. This means that user do not need to call RemoveObjectUser()
448 	// when they get called from ObjectInDestruction().
449 	maObjectUsers.clear();
450 
451     try
452     {
453         SvxShape* pSvxShape = getSvxShape();
454         if ( pSvxShape )
455         {
456             OSL_ENSURE(!pSvxShape->HasSdrObjectOwnership(),"Please check where this call come from and replace it with SdrObject::Free");
457             pSvxShape->InvalidateSdrObject();
458 	        uno::Reference< lang::XComponent > xShapeComp( getWeakUnoShape(), uno::UNO_QUERY_THROW );
459 		    xShapeComp->dispose();
460         }
461     }
462     catch( const uno::Exception& )
463     {
464     	DBG_UNHANDLED_EXCEPTION();
465     }
466 
467 	DBG_DTOR(SdrObject,NULL);
468 	SendUserCall(SDRUSERCALL_DELETE, GetLastBoundRect());
469 	if (pPlusData!=NULL) delete pPlusData;
470 
471 	if(mpProperties)
472 	{
473 		delete mpProperties;
474 		mpProperties = 0L;
475 	}
476 
477 	// #110094#
478 	if(mpViewContact)
479 	{
480 		delete mpViewContact;
481 		mpViewContact = 0L;
482 	}
483 }
484 
485 void SdrObject::Free( SdrObject*& _rpObject )
486 {
487     SdrObject* pObject = _rpObject; _rpObject = NULL;
488     if ( pObject == NULL )
489         // nothing to do
490         return;
491 
492 	SvxShape* pShape = pObject->getSvxShape();
493     if ( pShape && pShape->HasSdrObjectOwnership() )
494         // only the shape is allowed to delete me, and will reset the ownership before doing so
495         return;
496 
497     delete pObject;
498 }
499 
500 SdrObjPlusData* SdrObject::NewPlusData() const
501 {
502 	return new SdrObjPlusData;
503 }
504 
505 void SdrObject::SetRectsDirty(sal_Bool bNotMyself)
506 {
507 	if (!bNotMyself) {
508 		SetBoundRectDirty();
509 		bSnapRectDirty=sal_True;
510 	}
511 	if (pObjList!=NULL) {
512 		pObjList->SetRectsDirty();
513 	}
514 }
515 
516 void SdrObject::SetModel(SdrModel* pNewModel)
517 {
518 	if(pNewModel && pPage)
519 	{
520 		if(pPage->GetModel() != pNewModel)
521 		{
522 			pPage = NULL;
523 		}
524 	}
525 
526 	// update listeners at possible api wrapper object
527 	if( pModel != pNewModel )
528 	{
529 		SvxShape* pShape = getSvxShape();
530 		if( pShape )
531 			pShape->ChangeModel( pNewModel );
532 	}
533 
534 	pModel = pNewModel;
535 }
536 
537 void SdrObject::SetObjList(SdrObjList* pNewObjList)
538 {
539 	pObjList=pNewObjList;
540 }
541 
542 void SdrObject::SetPage(SdrPage* pNewPage)
543 {
544 	pPage=pNewPage;
545 	if (pPage!=NULL) {
546 		SdrModel* pMod=pPage->GetModel();
547 		if (pMod!=pModel && pMod!=NULL) {
548 			SetModel(pMod);
549 		}}
550 }
551 
552 // init global static itempool
553 SdrItemPool* SdrObject::mpGlobalItemPool = NULL;
554 
555 SdrItemPool& SdrObject::GetGlobalDrawObjectItemPool()
556 {
557 	if(!mpGlobalItemPool)
558 	{
559 		mpGlobalItemPool = new SdrItemPool();
560 		SfxItemPool* pGlobalOutlPool = EditEngine::CreatePool();
561 		mpGlobalItemPool->SetSecondaryPool(pGlobalOutlPool);
562 		mpGlobalItemPool->SetDefaultMetric((SfxMapUnit)SdrEngineDefaults::GetMapUnit());
563 		mpGlobalItemPool->FreezeIdRanges();
564 	}
565 
566 	return *mpGlobalItemPool;
567 }
568 
569 void SdrObject::FreeGlobalDrawObjectItemPool()
570 {
571 	// code for deletion of GlobalItemPool
572 	if(mpGlobalItemPool)
573 	{
574 		SfxItemPool* pGlobalOutlPool = mpGlobalItemPool->GetSecondaryPool();
575         SfxItemPool::Free(mpGlobalItemPool);
576         SfxItemPool::Free(pGlobalOutlPool);
577 	}
578 }
579 
580 SdrItemPool* SdrObject::GetObjectItemPool() const
581 {
582 	if(pModel)
583 		return (SdrItemPool*)(&pModel->GetItemPool());
584 
585 	// use a static global default pool
586 	return &SdrObject::GetGlobalDrawObjectItemPool();
587 }
588 
589 sal_uInt32 SdrObject::GetObjInventor()   const
590 {
591 	return SdrInventor;
592 }
593 
594 sal_uInt16 SdrObject::GetObjIdentifier() const
595 {
596 	return sal_uInt16(OBJ_NONE);
597 }
598 
599 void SdrObject::TakeObjInfo(SdrObjTransformInfoRec& rInfo) const
600 {
601 	rInfo.bRotateFreeAllowed=sal_False;
602 	rInfo.bMirrorFreeAllowed=sal_False;
603 	rInfo.bTransparenceAllowed = sal_False;
604 	rInfo.bGradientAllowed = sal_False;
605 	rInfo.bShearAllowed     =sal_False;
606 	rInfo.bEdgeRadiusAllowed=sal_False;
607 	rInfo.bCanConvToPath    =sal_False;
608 	rInfo.bCanConvToPoly    =sal_False;
609 	rInfo.bCanConvToContour = sal_False;
610 	rInfo.bCanConvToPathLineToArea=sal_False;
611 	rInfo.bCanConvToPolyLineToArea=sal_False;
612 }
613 
614 SdrLayerID SdrObject::GetLayer() const
615 {
616 	return mnLayerID;
617 }
618 
619 void SdrObject::getMergedHierarchyLayerSet(SetOfByte& rSet) const
620 {
621 	rSet.Set(GetLayer());
622 	SdrObjList* pOL=GetSubList();
623 	if (pOL!=NULL) {
624 		sal_uIntPtr nObjAnz=pOL->GetObjCount();
625 		for (sal_uIntPtr nObjNum=0; nObjNum<nObjAnz; nObjNum++) {
626 			pOL->GetObj(nObjNum)->getMergedHierarchyLayerSet(rSet);
627 		}
628 	}
629 }
630 
631 void SdrObject::NbcSetLayer(SdrLayerID nLayer)
632 {
633 	if(GetLayer() != nLayer)
634 	{
635 		mnLayerID = nLayer;
636 	}
637 }
638 
639 void SdrObject::SetLayer(SdrLayerID nLayer)
640 {
641 	NbcSetLayer(nLayer);
642 	SetChanged();
643 	BroadcastObjectChange();
644 }
645 
646 void SdrObject::AddListener(SfxListener& rListener)
647 {
648 	ImpForcePlusData();
649 	if (pPlusData->pBroadcast==NULL) pPlusData->pBroadcast=new SfxBroadcaster;
650 	rListener.StartListening(*pPlusData->pBroadcast);
651 }
652 
653 void SdrObject::RemoveListener(SfxListener& rListener)
654 {
655 	if (pPlusData!=NULL && pPlusData->pBroadcast!=NULL) {
656 		rListener.EndListening(*pPlusData->pBroadcast);
657 		if (!pPlusData->pBroadcast->HasListeners()) {
658 			delete pPlusData->pBroadcast;
659 			pPlusData->pBroadcast=NULL;
660 		}
661 	}
662 }
663 
664 void SdrObject::AddReference(SdrVirtObj& rVrtObj)
665 {
666 	AddListener(rVrtObj);
667 }
668 
669 void SdrObject::DelReference(SdrVirtObj& rVrtObj)
670 {
671 	RemoveListener(rVrtObj);
672 }
673 
674 AutoTimer* SdrObject::ForceAutoTimer()
675 {
676 	ImpForcePlusData();
677 	if (pPlusData->pAutoTimer==NULL) pPlusData->pAutoTimer=new AutoTimer;
678 	return pPlusData->pAutoTimer;
679 }
680 
681 FASTBOOL SdrObject::HasRefPoint() const
682 {
683 	return sal_False;
684 }
685 
686 Point SdrObject::GetRefPoint() const
687 {
688 	return GetCurrentBoundRect().Center();
689 }
690 
691 void SdrObject::SetRefPoint(const Point& /*rPnt*/)
692 {
693 }
694 
695 SdrObjList* SdrObject::GetSubList() const
696 {
697 	return NULL;
698 }
699 
700 SdrObject* SdrObject::GetUpGroup() const
701 {
702 	return pObjList!=NULL ? pObjList->GetOwnerObj() : NULL;
703 }
704 
705 void SdrObject::SetName(const String& rStr)
706 {
707 	if(rStr.Len() && !pPlusData)
708 	{
709 		ImpForcePlusData();
710 	}
711 
712 	if(pPlusData && pPlusData->aObjName != rStr)
713 	{
714         // --> OD 2009-07-09 #i73249#
715         // Undo/Redo for setting object's name
716         bool bUndo( false );
717         if ( GetModel() && GetModel()->IsUndoEnabled() )
718         {
719             bUndo = true;
720             SdrUndoAction* pUndoAction =
721                     GetModel()->GetSdrUndoFactory().CreateUndoObjectStrAttr(
722                                                     *this,
723                                                     SdrUndoObjStrAttr::OBJ_NAME,
724                                                     GetName(),
725                                                     rStr );
726             GetModel()->BegUndo( pUndoAction->GetComment() );
727             GetModel()->AddUndo( pUndoAction );
728         }
729         // <--
730         pPlusData->aObjName = rStr;
731         // --> OD 2009-07-09 #i73249#
732         if ( bUndo )
733         {
734             GetModel()->EndUndo();
735         }
736         // <--
737 		SetChanged();
738         BroadcastObjectChange();
739 	}
740 }
741 
742 String SdrObject::GetName() const
743 {
744 	if(pPlusData)
745 	{
746 		return pPlusData->aObjName;
747 	}
748 
749 	return String();
750 }
751 
752 void SdrObject::SetTitle(const String& rStr)
753 {
754 	if(rStr.Len() && !pPlusData)
755 	{
756 		ImpForcePlusData();
757 	}
758 
759 	if(pPlusData && pPlusData->aObjTitle != rStr)
760 	{
761         // --> OD 2009-07-13 #i73249#
762         // Undo/Redo for setting object's title
763         bool bUndo( false );
764         if ( GetModel() && GetModel()->IsUndoEnabled() )
765         {
766             bUndo = true;
767             SdrUndoAction* pUndoAction =
768                     GetModel()->GetSdrUndoFactory().CreateUndoObjectStrAttr(
769                                                     *this,
770                                                     SdrUndoObjStrAttr::OBJ_TITLE,
771                                                     GetTitle(),
772                                                     rStr );
773             GetModel()->BegUndo( pUndoAction->GetComment() );
774             GetModel()->AddUndo( pUndoAction );
775         }
776         // <--
777 		pPlusData->aObjTitle = rStr;
778         // --> OD 2009-07-13 #i73249#
779         if ( bUndo )
780         {
781             GetModel()->EndUndo();
782         }
783         // <--
784 		SetChanged();
785         BroadcastObjectChange();
786 	}
787 }
788 
789 String SdrObject::GetTitle() const
790 {
791 	if(pPlusData)
792 	{
793 		return pPlusData->aObjTitle;
794 	}
795 
796 	return String();
797 }
798 
799 void SdrObject::SetDescription(const String& rStr)
800 {
801 	if(rStr.Len() && !pPlusData)
802 	{
803 		ImpForcePlusData();
804 	}
805 
806 	if(pPlusData && pPlusData->aObjDescription != rStr)
807 	{
808         // --> OD 2009-07-13 #i73249#
809         // Undo/Redo for setting object's description
810         bool bUndo( false );
811         if ( GetModel() && GetModel()->IsUndoEnabled() )
812         {
813             bUndo = true;
814             SdrUndoAction* pUndoAction =
815                     GetModel()->GetSdrUndoFactory().CreateUndoObjectStrAttr(
816                                                     *this,
817                                                     SdrUndoObjStrAttr::OBJ_DESCRIPTION,
818                                                     GetDescription(),
819                                                     rStr );
820             GetModel()->BegUndo( pUndoAction->GetComment() );
821             GetModel()->AddUndo( pUndoAction );
822         }
823         // <--
824 		pPlusData->aObjDescription = rStr;
825         // --> OD 2009-07-13 #i73249#
826         if ( bUndo )
827         {
828             GetModel()->EndUndo();
829         }
830         // <--
831 		SetChanged();
832         BroadcastObjectChange();
833 	}
834 }
835 
836 String SdrObject::GetDescription() const
837 {
838 	if(pPlusData)
839 	{
840 		return pPlusData->aObjDescription;
841 	}
842 
843 	return String();
844 }
845 
846 void SdrObject::SetHTMLName(const String& rStr)
847 {
848 	if(rStr.Len() && !pPlusData)
849 	{
850 		ImpForcePlusData();
851 	}
852 
853 	if(pPlusData && pPlusData->aObjName != rStr)
854 	{
855 		pPlusData->aHTMLName = rStr;
856 		SetChanged();
857 	}
858 }
859 
860 String SdrObject::GetHTMLName() const
861 {
862 	if(pPlusData)
863 	{
864 		return pPlusData->aHTMLName;
865 	}
866 
867 	return String();
868 }
869 
870 sal_uInt32 SdrObject::GetOrdNum() const
871 {
872 	if (pObjList!=NULL) {
873 		if (pObjList->IsObjOrdNumsDirty()) {
874 			pObjList->RecalcObjOrdNums();
875 		}
876 	} else ((SdrObject*)this)->nOrdNum=0;
877 	return nOrdNum;
878 }
879 
880 
881 
882 
883 sal_uInt32 SdrObject::GetNavigationPosition (void)
884 {
885     if (pObjList!=NULL && pObjList->RecalcNavigationPositions())
886     {
887         return mnNavigationPosition;
888     }
889     else
890         return GetOrdNum();
891 }
892 
893 
894 
895 
896 void SdrObject::SetNavigationPosition (const sal_uInt32 nNewPosition)
897 {
898     mnNavigationPosition = nNewPosition;
899 }
900 
901 
902 
903 
904 // #111111#
905 // To make clearer that this method may trigger RecalcBoundRect and thus may be
906 // expensive and somtimes problematic (inside a bigger object change You will get
907 // non-useful BoundRects sometimes) i rename that method from GetBoundRect() to
908 // GetCurrentBoundRect().
909 const Rectangle& SdrObject::GetCurrentBoundRect() const
910 {
911 	if(aOutRect.IsEmpty())
912 	{
913 		const_cast< SdrObject* >(this)->RecalcBoundRect();
914 	}
915 
916 	return aOutRect;
917 }
918 
919 // #111111#
920 // To have a possibility to get the last calculated BoundRect e.g for producing
921 // the first rectangle for repaints (old and new need to be used) without forcing
922 // a RecalcBoundRect (which may be problematical and expensive sometimes) i add here
923 // a new method for accessing the last BoundRect.
924 const Rectangle& SdrObject::GetLastBoundRect() const
925 {
926 	return aOutRect;
927 }
928 
929 void SdrObject::RecalcBoundRect()
930 {
931 	// #i101680# suppress BoundRect calculations on import(s)
932 	if(pModel && pModel->isLocked())
933 		return;
934 
935 	// central new method which will calculate the BoundRect using primitive geometry
936 	if(aOutRect.IsEmpty())
937 	{
938     	const drawinglayer::primitive2d::Primitive2DSequence xPrimitives(GetViewContact().getViewIndependentPrimitive2DSequence());
939 
940 	    if(xPrimitives.hasElements())
941 	    {
942 		    // use neutral ViewInformation and get the range of the primitives
943 		    const drawinglayer::geometry::ViewInformation2D aViewInformation2D;
944     		const basegfx::B2DRange aRange(drawinglayer::primitive2d::getB2DRangeFromPrimitive2DSequence(xPrimitives, aViewInformation2D));
945 
946 		    if(!aRange.isEmpty())
947 		    {
948 			    aOutRect = Rectangle(
949 					    (sal_Int32)floor(aRange.getMinX()), (sal_Int32)floor(aRange.getMinY()),
950 					    (sal_Int32)ceil(aRange.getMaxX()), (sal_Int32)ceil(aRange.getMaxY()));
951                 return;
952 		    }
953         }
954 	}
955 }
956 
957 void SdrObject::BroadcastObjectChange() const
958 {
959 	if( pModel && pModel->isLocked() )
960 		return;
961 
962 	sal_Bool bPlusDataBroadcast(pPlusData && pPlusData->pBroadcast);
963 	sal_Bool bObjectChange(IsInserted() && pModel);
964 
965 	if(bPlusDataBroadcast || bObjectChange)
966 	{
967 		SdrHint aHint(*this);
968 
969 		if(bPlusDataBroadcast)
970 		{
971 			pPlusData->pBroadcast->Broadcast(aHint);
972 		}
973 
974 		if(bObjectChange)
975 		{
976 			pModel->Broadcast(aHint);
977 		}
978 	}
979 }
980 
981 void SdrObject::SetChanged()
982 {
983 	// #110094#-11
984 	// For test purposes, use the new ViewContact for change
985 	// notification now.
986 	ActionChanged();
987 
988 	if(IsInserted() && pModel)
989 	{
990 		pModel->SetChanged();
991 	}
992 }
993 
994 // Tooling for painting a single object to a OutputDevice.
995 sal_Bool SdrObject::SingleObjectPainter(OutputDevice& rOut) const
996 {
997 	sdr::contact::SdrObjectVector aObjectVector;
998 	aObjectVector.push_back(const_cast< SdrObject* >(this));
999 
1000 	sdr::contact::ObjectContactOfObjListPainter aPainter(rOut, aObjectVector, GetPage());
1001 	sdr::contact::DisplayInfo aDisplayInfo;
1002 
1003 	// do processing
1004 	aPainter.ProcessDisplay(aDisplayInfo);
1005 
1006 	return sal_True;
1007 }
1008 
1009 sal_Bool SdrObject::LineGeometryUsageIsNecessary() const
1010 {
1011 	XLineStyle eXLS = (XLineStyle)((const XLineStyleItem&)GetMergedItem(XATTR_LINESTYLE)).GetValue();
1012 	return (eXLS != XLINE_NONE);
1013 }
1014 
1015 SdrObject* SdrObject::Clone() const
1016 {
1017 	SdrObject* pObj=SdrObjFactory::MakeNewObject(GetObjInventor(),GetObjIdentifier(),NULL);
1018 	if (pObj!=NULL) {
1019 		pObj->pModel=pModel;
1020 		pObj->pPage=pPage;
1021 		*pObj=*this;
1022 	}
1023 	return pObj;
1024 }
1025 
1026 void SdrObject::operator=(const SdrObject& rObj)
1027 {
1028 	if(mpProperties)
1029 	{
1030 		delete mpProperties;
1031 		mpProperties = 0L;
1032 	}
1033 
1034 	// #110094#
1035 	if(mpViewContact)
1036 	{
1037 		delete mpViewContact;
1038 		mpViewContact = 0L;
1039 	}
1040 
1041 	// The Clone() method uses the local copy constructor from the individual
1042 	// sdr::properties::BaseProperties class. Since the target class maybe for another
1043 	// draw object a SdrObject needs to be provided, as in the nromal constructor.
1044 	mpProperties = &rObj.GetProperties().Clone(*this);
1045 
1046 	pModel  =rObj.pModel;
1047 	aOutRect=rObj.aOutRect;
1048 	mnLayerID = rObj.mnLayerID;
1049 	aAnchor =rObj.aAnchor;
1050 	bVirtObj=rObj.bVirtObj;
1051 	bSizProt=rObj.bSizProt;
1052 	bMovProt=rObj.bMovProt;
1053 	bNoPrint=rObj.bNoPrint;
1054 	mbVisible=rObj.mbVisible;
1055 	bMarkProt=rObj.bMarkProt;
1056 	//EmptyPresObj wird nicht kopiert: nun doch! (25-07-1995, Joe)
1057 	bEmptyPresObj =rObj.bEmptyPresObj;
1058 	//NotVisibleAsMaster wird nicht kopiert: nun doch! (25-07-1995, Joe)
1059 	bNotVisibleAsMaster=rObj.bNotVisibleAsMaster;
1060 	bSnapRectDirty=sal_True; //rObj.bSnapRectDirty;
1061 	bNotMasterCachable=rObj.bNotMasterCachable;
1062 	if (pPlusData!=NULL) { delete pPlusData; pPlusData=NULL; }
1063 	if (rObj.pPlusData!=NULL) {
1064 		pPlusData=rObj.pPlusData->Clone(this);
1065 	}
1066 	if (pPlusData!=NULL && pPlusData->pBroadcast!=NULL) {
1067 		delete pPlusData->pBroadcast; // der Broadcaster wird nicht mitkopiert
1068 		pPlusData->pBroadcast=NULL;
1069 	}
1070 }
1071 
1072 void SdrObject::TakeObjNameSingul(XubString& rName) const
1073 {
1074 	rName=ImpGetResStr(STR_ObjNameSingulNONE);
1075 
1076 	String aName( GetName() );
1077 	if(aName.Len())
1078 	{
1079 		rName += sal_Unicode(' ');
1080 		rName += sal_Unicode('\'');
1081 		rName += aName;
1082 		rName += sal_Unicode('\'');
1083 	}
1084 }
1085 
1086 void SdrObject::TakeObjNamePlural(XubString& rName) const
1087 {
1088 	rName=ImpGetResStr(STR_ObjNamePluralNONE);
1089 }
1090 
1091 void SdrObject::ImpTakeDescriptionStr(sal_uInt16 nStrCacheID, XubString& rStr, sal_uInt16 nVal) const
1092 {
1093 	rStr = ImpGetResStr(nStrCacheID);
1094 
1095 	sal_Char aSearchText1[] = "%1";
1096 	sal_Char aSearchText2[] = "%2";
1097 	xub_StrLen nPos = rStr.SearchAscii(aSearchText1);
1098 
1099 	if(nPos != STRING_NOTFOUND)
1100 	{
1101 		rStr.Erase(nPos, 2);
1102 
1103 		XubString aObjName;
1104 
1105 		TakeObjNameSingul(aObjName);
1106 		rStr.Insert(aObjName, nPos);
1107 	}
1108 
1109 	nPos = rStr.SearchAscii(aSearchText2);
1110 
1111 	if(nPos != STRING_NOTFOUND)
1112 	{
1113 		rStr.Erase(nPos, 2);
1114 		rStr.Insert(UniString::CreateFromInt32(nVal), nPos);
1115 	}
1116 }
1117 
1118 XubString SdrObject::GetWinkStr(long nWink, FASTBOOL bNoDegChar) const
1119 {
1120 	XubString aStr;
1121 	if (pModel!=NULL) {
1122 		pModel->TakeWinkStr(nWink,aStr,bNoDegChar);
1123 	}
1124 	return aStr;
1125 }
1126 
1127 XubString SdrObject::GetMetrStr(long nVal, MapUnit /*eWantMap*/, FASTBOOL bNoUnitChars) const
1128 {
1129 	XubString aStr;
1130 	if (pModel!=NULL) {
1131 		pModel->TakeMetricStr(nVal,aStr,bNoUnitChars);
1132 	}
1133 	return aStr;
1134 }
1135 
1136 basegfx::B2DPolyPolygon SdrObject::TakeXorPoly() const
1137 {
1138 	basegfx::B2DPolyPolygon aRetval;
1139 	const Rectangle aR(GetCurrentBoundRect());
1140 	const basegfx::B2DRange aRange(aR.Left(), aR.Top(), aR.Right(), aR.Bottom());
1141 	aRetval.append(basegfx::tools::createPolygonFromRect(aRange));
1142 
1143 	return aRetval;
1144 }
1145 
1146 basegfx::B2DPolyPolygon SdrObject::TakeContour() const
1147 {
1148 	basegfx::B2DPolyPolygon aRetval;
1149 
1150     // create cloned object without text, but with XLINE_SOLID,
1151     // COL_BLACK as line color and XFILL_NONE
1152 	SdrObject* pClone = Clone();
1153 
1154     if(pClone)
1155     {
1156         const SdrTextObj* pTextObj = dynamic_cast< const SdrTextObj* >(this);
1157 
1158         if(pTextObj)
1159 	    {
1160             // no text and no text animation
1161 		    pClone->SetMergedItem(SdrTextAniKindItem(SDRTEXTANI_NONE));
1162             pClone->SetOutlinerParaObject(0);
1163 	    }
1164 
1165         const SdrEdgeObj* pEdgeObj = dynamic_cast< const SdrEdgeObj* >(this);
1166 
1167         if(pEdgeObj)
1168 	    {
1169             // create connections if connector, will be cleaned up when
1170             // deleting the connector again
1171 		    SdrObject* pLeft = pEdgeObj->GetConnectedNode(sal_True);
1172 		    SdrObject* pRight = pEdgeObj->GetConnectedNode(sal_False);
1173 
1174 		    if(pLeft)
1175 		    {
1176 			    pClone->ConnectToNode(sal_True, pLeft);
1177 		    }
1178 
1179 		    if(pRight)
1180 		    {
1181 			    pClone->ConnectToNode(sal_False, pRight);
1182 		    }
1183 	    }
1184 
1185 	    SfxItemSet aNewSet(*GetObjectItemPool());
1186 
1187         // #i101980# ignore LineWidth; that's what the old implementation
1188         // did. With linewidth, the result may be huge due to fat/thick
1189         // line decompositions
1190     	aNewSet.Put(XLineWidthItem(0));
1191 
1192         // solid black lines and no fill
1193         aNewSet.Put(XLineStyleItem(XLINE_SOLID));
1194 	    aNewSet.Put(XLineColorItem(String(), Color(COL_BLACK)));
1195 	    aNewSet.Put(XFillStyleItem(XFILL_NONE));
1196 	    pClone->SetMergedItemSet(aNewSet);
1197 
1198         // get sequence from clone
1199 	    const sdr::contact::ViewContact& rVC(pClone->GetViewContact());
1200 	    const drawinglayer::primitive2d::Primitive2DSequence xSequence(rVC.getViewIndependentPrimitive2DSequence());
1201 
1202 	    if(xSequence.hasElements())
1203 	    {
1204 		    // use neutral ViewInformation
1205 		    const drawinglayer::geometry::ViewInformation2D aViewInformation2D;
1206 
1207 		    // create extractor, process and get result
1208 		    drawinglayer::processor2d::ContourExtractor2D aExtractor(aViewInformation2D);
1209 		    aExtractor.process(xSequence);
1210             const std::vector< basegfx::B2DPolyPolygon >& rResult(aExtractor.getExtractedContour());
1211             const sal_uInt32 nSize(rResult.size());
1212 
1213             // when count is one, it is implied that the object has only it's normal
1214             // contour anyways and TakeCountour() is to return an empty PolyPolygon
1215             // (see old implementation for historical reasons)
1216             if(nSize > 1)
1217             {
1218                 // the topology for contour is correctly a vector of PolyPolygons; for
1219                 // historical reasons cut it back to a single PolyPolygon here
1220                 for(sal_uInt32 a(0); a < nSize; a++)
1221                 {
1222                     aRetval.append(rResult[a]);
1223                 }
1224             }
1225         }
1226 
1227     	delete pClone;
1228     }
1229 
1230 	return aRetval;
1231 }
1232 
1233 sal_uInt32 SdrObject::GetHdlCount() const
1234 {
1235 	return 8L;
1236 }
1237 
1238 SdrHdl* SdrObject::GetHdl(sal_uInt32 nHdlNum) const
1239 {
1240 	SdrHdl* pH=NULL;
1241 	const Rectangle& rR=GetSnapRect();
1242 	switch (nHdlNum) {
1243 		case 0: pH=new SdrHdl(rR.TopLeft(),     HDL_UPLFT); break; // Oben links
1244 		case 1: pH=new SdrHdl(rR.TopCenter(),   HDL_UPPER); break; // Oben
1245 		case 2: pH=new SdrHdl(rR.TopRight(),    HDL_UPRGT); break; // Oben rechts
1246 		case 3: pH=new SdrHdl(rR.LeftCenter(),  HDL_LEFT ); break; // Links
1247 		case 4: pH=new SdrHdl(rR.RightCenter(), HDL_RIGHT); break; // Rechts
1248 		case 5: pH=new SdrHdl(rR.BottomLeft(),  HDL_LWLFT); break; // Unten links
1249 		case 6: pH=new SdrHdl(rR.BottomCenter(),HDL_LOWER); break; // Unten
1250 		case 7: pH=new SdrHdl(rR.BottomRight(), HDL_LWRGT); break; // Unten rechts
1251 	}
1252 	return pH;
1253 }
1254 
1255 sal_uInt32 SdrObject::GetPlusHdlCount(const SdrHdl& /*rHdl*/) const
1256 {
1257 	return 0L;
1258 }
1259 
1260 SdrHdl* SdrObject::GetPlusHdl(const SdrHdl& /*rHdl*/, sal_uInt32 /*nPlNum*/) const
1261 {
1262 	return 0L;
1263 }
1264 
1265 void SdrObject::AddToHdlList(SdrHdlList& rHdlList) const
1266 {
1267 	sal_uInt32 nAnz=GetHdlCount();
1268 	for (sal_uInt32 i=0L; i<nAnz; i++) {
1269 		SdrHdl* pHdl=GetHdl(i);
1270 		if (pHdl!=NULL) {
1271 			rHdlList.AddHdl(pHdl);
1272 		}
1273 	}
1274 }
1275 
1276 Rectangle SdrObject::ImpDragCalcRect(const SdrDragStat& rDrag) const
1277 {
1278 	Rectangle aTmpRect(GetSnapRect());
1279 	Rectangle aRect(aTmpRect);
1280 	const SdrHdl* pHdl=rDrag.GetHdl();
1281 	SdrHdlKind eHdl=pHdl==NULL ? HDL_MOVE : pHdl->GetKind();
1282 	FASTBOOL bEcke=(eHdl==HDL_UPLFT || eHdl==HDL_UPRGT || eHdl==HDL_LWLFT || eHdl==HDL_LWRGT);
1283 	FASTBOOL bOrtho=rDrag.GetView()!=NULL && rDrag.GetView()->IsOrtho();
1284 	FASTBOOL bBigOrtho=bEcke && bOrtho && rDrag.GetView()->IsBigOrtho();
1285 	Point aPos(rDrag.GetNow());
1286 	FASTBOOL bLft=(eHdl==HDL_UPLFT || eHdl==HDL_LEFT  || eHdl==HDL_LWLFT);
1287 	FASTBOOL bRgt=(eHdl==HDL_UPRGT || eHdl==HDL_RIGHT || eHdl==HDL_LWRGT);
1288 	FASTBOOL bTop=(eHdl==HDL_UPRGT || eHdl==HDL_UPPER || eHdl==HDL_UPLFT);
1289 	FASTBOOL bBtm=(eHdl==HDL_LWRGT || eHdl==HDL_LOWER || eHdl==HDL_LWLFT);
1290 	if (bLft) aTmpRect.Left()  =aPos.X();
1291 	if (bRgt) aTmpRect.Right() =aPos.X();
1292 	if (bTop) aTmpRect.Top()   =aPos.Y();
1293 	if (bBtm) aTmpRect.Bottom()=aPos.Y();
1294 	if (bOrtho) { // Ortho
1295 		long nWdt0=aRect.Right() -aRect.Left();
1296 		long nHgt0=aRect.Bottom()-aRect.Top();
1297 		long nXMul=aTmpRect.Right() -aTmpRect.Left();
1298 		long nYMul=aTmpRect.Bottom()-aTmpRect.Top();
1299 		long nXDiv=nWdt0;
1300 		long nYDiv=nHgt0;
1301 		FASTBOOL bXNeg=(nXMul<0)!=(nXDiv<0);
1302 		FASTBOOL bYNeg=(nYMul<0)!=(nYDiv<0);
1303 		nXMul=Abs(nXMul);
1304 		nYMul=Abs(nYMul);
1305 		nXDiv=Abs(nXDiv);
1306 		nYDiv=Abs(nYDiv);
1307 		Fraction aXFact(nXMul,nXDiv); // Fractions zum kuerzen
1308 		Fraction aYFact(nYMul,nYDiv); // und zum vergleichen
1309 		nXMul=aXFact.GetNumerator();
1310 		nYMul=aYFact.GetNumerator();
1311 		nXDiv=aXFact.GetDenominator();
1312 		nYDiv=aYFact.GetDenominator();
1313 		if (bEcke) { // Eckpunkthandles
1314 			FASTBOOL bUseX=(aXFact<aYFact) != bBigOrtho;
1315 			if (bUseX) {
1316 				long nNeed=long(BigInt(nHgt0)*BigInt(nXMul)/BigInt(nXDiv));
1317 				if (bYNeg) nNeed=-nNeed;
1318 				if (bTop) aTmpRect.Top()=aTmpRect.Bottom()-nNeed;
1319 				if (bBtm) aTmpRect.Bottom()=aTmpRect.Top()+nNeed;
1320 			} else {
1321 				long nNeed=long(BigInt(nWdt0)*BigInt(nYMul)/BigInt(nYDiv));
1322 				if (bXNeg) nNeed=-nNeed;
1323 				if (bLft) aTmpRect.Left()=aTmpRect.Right()-nNeed;
1324 				if (bRgt) aTmpRect.Right()=aTmpRect.Left()+nNeed;
1325 			}
1326 		} else { // Scheitelpunkthandles
1327 			if ((bLft || bRgt) && nXDiv!=0) {
1328 				long nHgt0b=aRect.Bottom()-aRect.Top();
1329 				long nNeed=long(BigInt(nHgt0b)*BigInt(nXMul)/BigInt(nXDiv));
1330 				aTmpRect.Top()-=(nNeed-nHgt0b)/2;
1331 				aTmpRect.Bottom()=aTmpRect.Top()+nNeed;
1332 			}
1333 			if ((bTop || bBtm) && nYDiv!=0) {
1334 				long nWdt0b=aRect.Right()-aRect.Left();
1335 				long nNeed=long(BigInt(nWdt0b)*BigInt(nYMul)/BigInt(nYDiv));
1336 				aTmpRect.Left()-=(nNeed-nWdt0b)/2;
1337 				aTmpRect.Right()=aTmpRect.Left()+nNeed;
1338 			}
1339 		}
1340 	}
1341 	aTmpRect.Justify();
1342 	return aTmpRect;
1343 }
1344 
1345 ////////////////////////////////////////////////////////////////////////////////////////////////////
1346 
1347 bool SdrObject::hasSpecialDrag() const
1348 {
1349 	return false;
1350 }
1351 
1352 bool SdrObject::supportsFullDrag() const
1353 {
1354     return true;
1355 }
1356 
1357 SdrObject* SdrObject::getFullDragClone() const
1358 {
1359 	// default uses simple clone
1360 	return Clone();
1361 }
1362 
1363 bool SdrObject::beginSpecialDrag(SdrDragStat& rDrag) const
1364 {
1365     const SdrHdl* pHdl = rDrag.GetHdl();
1366 
1367     SdrHdlKind eHdl = (pHdl == NULL) ? HDL_MOVE : pHdl->GetKind();
1368 
1369     if(eHdl==HDL_UPLFT || eHdl==HDL_UPPER || eHdl==HDL_UPRGT ||
1370 	    eHdl==HDL_LEFT || eHdl==HDL_RIGHT || eHdl==HDL_LWLFT ||
1371         eHdl==HDL_LOWER || eHdl==HDL_LWRGT)
1372     {
1373         return true;
1374     }
1375 
1376     return false;
1377 }
1378 
1379 bool SdrObject::applySpecialDrag(SdrDragStat& rDrag)
1380 {
1381 	Rectangle aNewRect(ImpDragCalcRect(rDrag));
1382 
1383     if(aNewRect != GetSnapRect())
1384     {
1385    		NbcSetSnapRect(aNewRect);
1386 	}
1387 
1388     return true;
1389 }
1390 
1391 String SdrObject::getSpecialDragComment(const SdrDragStat& /*rDrag*/) const
1392 {
1393 	return String();
1394 }
1395 
1396 basegfx::B2DPolyPolygon SdrObject::getSpecialDragPoly(const SdrDragStat& /*rDrag*/) const
1397 {
1398     // default has nothing to add
1399     return basegfx::B2DPolyPolygon();
1400 }
1401 
1402 ////////////////////////////////////////////////////////////////////////////////////////////////////
1403 // Create
1404 FASTBOOL SdrObject::BegCreate(SdrDragStat& rStat)
1405 {
1406 	rStat.SetOrtho4Possible();
1407 	Rectangle aRect1(rStat.GetStart(), rStat.GetNow());
1408 	aRect1.Justify();
1409 	rStat.SetActionRect(aRect1);
1410 	aOutRect = aRect1;
1411 	return sal_True;
1412 }
1413 
1414 FASTBOOL SdrObject::MovCreate(SdrDragStat& rStat)
1415 {
1416 	rStat.TakeCreateRect(aOutRect);
1417 	rStat.SetActionRect(aOutRect);
1418 	aOutRect.Justify();
1419 
1420 	// #i101648# for naked (non-derived) SdrObjects, do not invalidate aOutRect
1421 	// by calling SetBoundRectDirty(); aOutRect IS the geometry for such objects.
1422 	// No derivation implementation calls the parent implementation, so this will
1423 	// cause no further prolems
1424 	//
1425 	// SetBoundRectDirty();
1426 	// bSnapRectDirty=sal_True;
1427 
1428 	return sal_True;
1429 }
1430 
1431 FASTBOOL SdrObject::EndCreate(SdrDragStat& rStat, SdrCreateCmd eCmd)
1432 {
1433 	rStat.TakeCreateRect(aOutRect);
1434 	aOutRect.Justify();
1435 
1436 	// #i101648# see description at MovCreate
1437 	//
1438 	// SetRectsDirty();
1439 
1440 	return (eCmd==SDRCREATE_FORCEEND || rStat.GetPointAnz()>=2);
1441 }
1442 
1443 void SdrObject::BrkCreate(SdrDragStat& /*rStat*/)
1444 {
1445 }
1446 
1447 FASTBOOL SdrObject::BckCreate(SdrDragStat& /*rStat*/)
1448 {
1449 	return sal_False;
1450 }
1451 
1452 basegfx::B2DPolyPolygon SdrObject::TakeCreatePoly(const SdrDragStat& rDrag) const
1453 {
1454 	Rectangle aRect1;
1455 	rDrag.TakeCreateRect(aRect1);
1456 	aRect1.Justify();
1457 
1458 	basegfx::B2DPolyPolygon aRetval;
1459 	const basegfx::B2DRange aRange(aRect1.Left(), aRect1.Top(), aRect1.Right(), aRect1.Bottom());
1460 	aRetval.append(basegfx::tools::createPolygonFromRect(aRange));
1461 	return aRetval;
1462 }
1463 
1464 Pointer SdrObject::GetCreatePointer() const
1465 {
1466 	return Pointer(POINTER_CROSS);
1467 }
1468 
1469 // Transformationen
1470 void SdrObject::NbcMove(const Size& rSiz)
1471 {
1472 	MoveRect(aOutRect,rSiz);
1473 	SetRectsDirty();
1474 }
1475 
1476 void SdrObject::NbcResize(const Point& rRef, const Fraction& xFact, const Fraction& yFact)
1477 {
1478 	FASTBOOL bXMirr=(xFact.GetNumerator()<0) != (xFact.GetDenominator()<0);
1479 	FASTBOOL bYMirr=(yFact.GetNumerator()<0) != (yFact.GetDenominator()<0);
1480 	if (bXMirr || bYMirr) {
1481 		Point aRef1(GetSnapRect().Center());
1482 		if (bXMirr) {
1483 			Point aRef2(aRef1);
1484 			aRef2.Y()++;
1485 			NbcMirrorGluePoints(aRef1,aRef2);
1486 		}
1487 		if (bYMirr) {
1488 			Point aRef2(aRef1);
1489 			aRef2.X()++;
1490 			NbcMirrorGluePoints(aRef1,aRef2);
1491 		}
1492 	}
1493 	ResizeRect(aOutRect,rRef,xFact,yFact);
1494 	SetRectsDirty();
1495 }
1496 
1497 void SdrObject::NbcRotate(const Point& rRef, long nWink, double sn, double cs)
1498 {
1499 	SetGlueReallyAbsolute(sal_True);
1500 	aOutRect.Move(-rRef.X(),-rRef.Y());
1501 	Rectangle R(aOutRect);
1502     if (sn==1.0 && cs==0.0) { // 90deg
1503 		aOutRect.Left()  =-R.Bottom();
1504 		aOutRect.Right() =-R.Top();
1505 		aOutRect.Top()   =R.Left();
1506 		aOutRect.Bottom()=R.Right();
1507     } else if (sn==0.0 && cs==-1.0) { // 180deg
1508 		aOutRect.Left()  =-R.Right();
1509 		aOutRect.Right() =-R.Left();
1510 		aOutRect.Top()   =-R.Bottom();
1511 		aOutRect.Bottom()=-R.Top();
1512     } else if (sn==-1.0 && cs==0.0) { // 270deg
1513 		aOutRect.Left()  =R.Top();
1514 		aOutRect.Right() =R.Bottom();
1515 		aOutRect.Top()   =-R.Right();
1516 		aOutRect.Bottom()=-R.Left();
1517 	}
1518 	aOutRect.Move(rRef.X(),rRef.Y());
1519 	aOutRect.Justify(); // Sicherheitshalber
1520 	SetRectsDirty();
1521 	NbcRotateGluePoints(rRef,nWink,sn,cs);
1522 	SetGlueReallyAbsolute(sal_False);
1523 }
1524 
1525 void SdrObject::NbcMirror(const Point& rRef1, const Point& rRef2)
1526 {
1527 	SetGlueReallyAbsolute(sal_True);
1528 	aOutRect.Move(-rRef1.X(),-rRef1.Y());
1529 	Rectangle R(aOutRect);
1530 	long dx=rRef2.X()-rRef1.X();
1531 	long dy=rRef2.Y()-rRef1.Y();
1532 	if (dx==0) {          // Vertikale Achse
1533 		aOutRect.Left() =-R.Right();
1534 		aOutRect.Right()=-R.Left();
1535 	} else if (dy==0) {   // Horizontale Achse
1536 		aOutRect.Top()   =-R.Bottom();
1537 		aOutRect.Bottom()=-R.Top();
1538 	} else if (dx==dy) {  /* 45 Grad Achse \ */
1539 		aOutRect.Left()  =R.Top();
1540 		aOutRect.Right() =R.Bottom();
1541 		aOutRect.Top()   =R.Left();
1542 		aOutRect.Bottom()=R.Right();
1543 	} else if (dx==-dy) { // 45 Grad Achse /
1544 		aOutRect.Left()  =-R.Bottom();
1545 		aOutRect.Right() =-R.Top();
1546 		aOutRect.Top()   =-R.Right();
1547 		aOutRect.Bottom()=-R.Left();
1548 	}
1549 	aOutRect.Move(rRef1.X(),rRef1.Y());
1550 	aOutRect.Justify(); // Sicherheitshalber
1551 	SetRectsDirty();
1552 	NbcMirrorGluePoints(rRef1,rRef2);
1553 	SetGlueReallyAbsolute(sal_False);
1554 }
1555 
1556 void SdrObject::NbcShear(const Point& rRef, long nWink, double tn, FASTBOOL bVShear)
1557 {
1558 	SetGlueReallyAbsolute(sal_True);
1559 	NbcShearGluePoints(rRef,nWink,tn,bVShear);
1560 	SetGlueReallyAbsolute(sal_False);
1561 }
1562 
1563 void SdrObject::Move(const Size& rSiz)
1564 {
1565 	if (rSiz.Width()!=0 || rSiz.Height()!=0) {
1566 		Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect();
1567 		// #110094#-14 SendRepaintBroadcast();
1568 		NbcMove(rSiz);
1569 		SetChanged();
1570 		BroadcastObjectChange();
1571 		SendUserCall(SDRUSERCALL_MOVEONLY,aBoundRect0);
1572 	}
1573 }
1574 
1575 void SdrObject::Resize(const Point& rRef, const Fraction& xFact, const Fraction& yFact)
1576 {
1577 	if (xFact.GetNumerator()!=xFact.GetDenominator() || yFact.GetNumerator()!=yFact.GetDenominator()) {
1578 		Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect();
1579 		// #110094#-14 SendRepaintBroadcast();
1580 		NbcResize(rRef,xFact,yFact);
1581 		SetChanged();
1582 		BroadcastObjectChange();
1583 		SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
1584 	}
1585 }
1586 
1587 void SdrObject::Rotate(const Point& rRef, long nWink, double sn, double cs)
1588 {
1589 	if (nWink!=0) {
1590 		Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect();
1591 		// #110094#-14 SendRepaintBroadcast();
1592 		NbcRotate(rRef,nWink,sn,cs);
1593 		SetChanged();
1594 		BroadcastObjectChange();
1595 		SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
1596 	}
1597 }
1598 
1599 void SdrObject::Mirror(const Point& rRef1, const Point& rRef2)
1600 {
1601 	Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect();
1602 	// #110094#-14 SendRepaintBroadcast();
1603 	NbcMirror(rRef1,rRef2);
1604 	SetChanged();
1605 	BroadcastObjectChange();
1606 	SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
1607 }
1608 
1609 void SdrObject::Shear(const Point& rRef, long nWink, double tn, FASTBOOL bVShear)
1610 {
1611 	if (nWink!=0) {
1612 		Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect();
1613 		// #110094#-14 SendRepaintBroadcast();
1614 		NbcShear(rRef,nWink,tn,bVShear);
1615 		SetChanged();
1616 		BroadcastObjectChange();
1617 		SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
1618 	}
1619 }
1620 
1621 void SdrObject::NbcSetRelativePos(const Point& rPnt)
1622 {
1623 	Point aRelPos0(GetSnapRect().TopLeft()-aAnchor);
1624 	Size aSiz(rPnt.X()-aRelPos0.X(),rPnt.Y()-aRelPos0.Y());
1625 	NbcMove(aSiz); // Der ruft auch das SetRectsDirty()
1626 }
1627 
1628 void SdrObject::SetRelativePos(const Point& rPnt)
1629 {
1630 	if (rPnt!=GetRelativePos()) {
1631 		Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect();
1632 		// #110094#-14 SendRepaintBroadcast();
1633 		NbcSetRelativePos(rPnt);
1634 		SetChanged();
1635 		BroadcastObjectChange();
1636 		SendUserCall(SDRUSERCALL_MOVEONLY,aBoundRect0);
1637 	}
1638 }
1639 
1640 Point SdrObject::GetRelativePos() const
1641 {
1642 	return GetSnapRect().TopLeft()-aAnchor;
1643 }
1644 
1645 void SdrObject::NbcSetAnchorPos(const Point& rPnt)
1646 {
1647 	Size aSiz(rPnt.X()-aAnchor.X(),rPnt.Y()-aAnchor.Y());
1648 	aAnchor=rPnt;
1649 	NbcMove(aSiz); // Der ruft auch das SetRectsDirty()
1650 }
1651 
1652 void SdrObject::SetAnchorPos(const Point& rPnt)
1653 {
1654 	if (rPnt!=aAnchor) {
1655 		Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect();
1656 		// #110094#-14 SendRepaintBroadcast();
1657 		NbcSetAnchorPos(rPnt);
1658 		SetChanged();
1659 		BroadcastObjectChange();
1660 		SendUserCall(SDRUSERCALL_MOVEONLY,aBoundRect0);
1661 	}
1662 }
1663 
1664 const Point& SdrObject::GetAnchorPos() const
1665 {
1666 	return aAnchor;
1667 }
1668 
1669 void SdrObject::RecalcSnapRect()
1670 {
1671 }
1672 
1673 const Rectangle& SdrObject::GetSnapRect() const
1674 {
1675 	return aOutRect;
1676 }
1677 
1678 void SdrObject::NbcSetSnapRect(const Rectangle& rRect)
1679 {
1680 	aOutRect=rRect;
1681 }
1682 
1683 const Rectangle& SdrObject::GetLogicRect() const
1684 {
1685 	return GetSnapRect();
1686 }
1687 
1688 void SdrObject::NbcSetLogicRect(const Rectangle& rRect)
1689 {
1690 	NbcSetSnapRect(rRect);
1691 }
1692 
1693 void SdrObject::AdjustToMaxRect( const Rectangle& rMaxRect, bool /* bShrinkOnly = false */ )
1694 {
1695 	SetLogicRect( rMaxRect );
1696 }
1697 
1698 void SdrObject::SetSnapRect(const Rectangle& rRect)
1699 {
1700 	Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect();
1701 	// #110094#-14 SendRepaintBroadcast();
1702 	NbcSetSnapRect(rRect);
1703 	SetChanged();
1704 	BroadcastObjectChange();
1705 	SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
1706 }
1707 
1708 void SdrObject::SetLogicRect(const Rectangle& rRect)
1709 {
1710 	Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect();
1711 	// #110094#-14 SendRepaintBroadcast();
1712 	NbcSetLogicRect(rRect);
1713 	SetChanged();
1714 	BroadcastObjectChange();
1715 	SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
1716 }
1717 
1718 long SdrObject::GetRotateAngle() const
1719 {
1720 	return 0;
1721 }
1722 
1723 long SdrObject::GetShearAngle(FASTBOOL /*bVertical*/) const
1724 {
1725 	return 0;
1726 }
1727 
1728 sal_uInt32 SdrObject::GetSnapPointCount() const
1729 {
1730 	return GetPointCount();
1731 }
1732 
1733 Point SdrObject::GetSnapPoint(sal_uInt32 i) const
1734 {
1735 	return GetPoint(i);
1736 }
1737 
1738 sal_Bool SdrObject::IsPolyObj() const
1739 {
1740 	return sal_False;
1741 }
1742 
1743 sal_uInt32 SdrObject::GetPointCount() const
1744 {
1745 	return 0L;
1746 }
1747 
1748 Point SdrObject::GetPoint(sal_uInt32 /*i*/) const
1749 {
1750 	return Point();
1751 }
1752 
1753 void SdrObject::SetPoint(const Point& rPnt, sal_uInt32 i)
1754 {
1755 	Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect();
1756 	// #110094#-14 SendRepaintBroadcast();
1757 	NbcSetPoint(rPnt, i);
1758 	SetChanged();
1759 	BroadcastObjectChange();
1760 	SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
1761 }
1762 
1763 void SdrObject::NbcSetPoint(const Point& /*rPnt*/, sal_uInt32 /*i*/)
1764 {
1765 }
1766 
1767 FASTBOOL SdrObject::HasTextEdit() const
1768 {
1769 	return sal_False;
1770 }
1771 
1772 sal_Bool SdrObject::BegTextEdit(SdrOutliner& /*rOutl*/)
1773 {
1774 	return sal_False;
1775 }
1776 
1777 void SdrObject::EndTextEdit(SdrOutliner& /*rOutl*/)
1778 {
1779 }
1780 
1781 void SdrObject::SetOutlinerParaObject(OutlinerParaObject* pTextObject)
1782 {
1783 	Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect();
1784 	// #110094#-14 SendRepaintBroadcast();
1785 	NbcSetOutlinerParaObject(pTextObject);
1786 	SetChanged();
1787 	BroadcastObjectChange();
1788 	if (GetCurrentBoundRect()!=aBoundRect0) {
1789 		SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
1790 	}
1791 }
1792 
1793 void SdrObject::NbcSetOutlinerParaObject(OutlinerParaObject* /*pTextObject*/)
1794 {
1795 }
1796 
1797 OutlinerParaObject* SdrObject::GetOutlinerParaObject() const
1798 {
1799 	return NULL;
1800 }
1801 
1802 void SdrObject::NbcReformatText()
1803 {
1804 }
1805 
1806 void SdrObject::ReformatText()
1807 {
1808 	Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect();
1809 	NbcReformatText();
1810 	SetChanged();
1811 	BroadcastObjectChange();
1812 	if (GetCurrentBoundRect()!=aBoundRect0) {
1813 		SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
1814 	}
1815 }
1816 
1817 void SdrObject::BurnInStyleSheetAttributes()
1818 {
1819 	GetProperties().ForceStyleToHardAttributes();
1820 }
1821 
1822 #define Imp2ndKennung (0x434F4D43)
1823 SdrObjUserData* SdrObject::ImpGetMacroUserData() const
1824 {
1825 	SdrObjUserData* pData=NULL;
1826 	sal_uInt16 nAnz=GetUserDataCount();
1827 	for (sal_uInt16 nNum=nAnz; nNum>0 && pData==NULL;) {
1828 		nNum--;
1829 		pData=GetUserData(nNum);
1830 		if (!pData->HasMacro(this)) pData=NULL;
1831 	}
1832 	return pData;
1833 }
1834 
1835 FASTBOOL SdrObject::HasMacro() const
1836 {
1837 	SdrObjUserData* pData=ImpGetMacroUserData();
1838 	return pData!=NULL ? pData->HasMacro(this) : sal_False;
1839 }
1840 
1841 SdrObject* SdrObject::CheckMacroHit(const SdrObjMacroHitRec& rRec) const
1842 {
1843 	SdrObjUserData* pData = ImpGetMacroUserData();
1844 
1845     if(pData)
1846     {
1847 		return pData->CheckMacroHit(rRec, this);
1848 	}
1849 
1850     if(rRec.pPageView)
1851     {
1852 	    return SdrObjectPrimitiveHit(*this, rRec.aPos, rRec.nTol, *rRec.pPageView, rRec.pVisiLayer, false);
1853     }
1854 
1855 	return 0;
1856 }
1857 
1858 Pointer SdrObject::GetMacroPointer(const SdrObjMacroHitRec& rRec) const
1859 {
1860 	SdrObjUserData* pData=ImpGetMacroUserData();
1861 	if (pData!=NULL) {
1862 		return pData->GetMacroPointer(rRec,this);
1863 	}
1864 	return Pointer(POINTER_REFHAND);
1865 }
1866 
1867 void SdrObject::PaintMacro(OutputDevice& rOut, const Rectangle& rDirtyRect, const SdrObjMacroHitRec& rRec) const
1868 {
1869 	SdrObjUserData* pData=ImpGetMacroUserData();
1870 
1871     if(pData)
1872     {
1873 		pData->PaintMacro(rOut,rDirtyRect,rRec,this);
1874 	}
1875     else
1876     {
1877 	    const RasterOp eRop(rOut.GetRasterOp());
1878 	    const basegfx::B2DPolyPolygon aPolyPolygon(TakeXorPoly());
1879 	    const sal_uInt32 nCount(aPolyPolygon.count());
1880 
1881         rOut.SetLineColor(COL_BLACK);
1882         rOut.SetFillColor();
1883 	    rOut.SetRasterOp(ROP_INVERT);
1884 
1885 	    for(sal_uInt32 a(0); a < nCount; a++)
1886 	    {
1887 		    rOut.DrawPolyLine(aPolyPolygon.getB2DPolygon(a));
1888 	    }
1889 
1890         rOut.SetRasterOp(eRop);
1891 	}
1892 }
1893 
1894 FASTBOOL SdrObject::DoMacro(const SdrObjMacroHitRec& rRec)
1895 {
1896 	SdrObjUserData* pData=ImpGetMacroUserData();
1897 	if (pData!=NULL) {
1898 		return pData->DoMacro(rRec,this);
1899 	}
1900 	return sal_False;
1901 }
1902 
1903 XubString SdrObject::GetMacroPopupComment(const SdrObjMacroHitRec& rRec) const
1904 {
1905 	SdrObjUserData* pData=ImpGetMacroUserData();
1906 	if (pData!=NULL) {
1907 		return pData->GetMacroPopupComment(rRec,this);
1908 	}
1909 	return String();
1910 }
1911 
1912 ////////////////////////////////////////////////////////////////////////////////////////////////////
1913 
1914 SdrObjGeoData* SdrObject::NewGeoData() const
1915 {
1916 	return new SdrObjGeoData;
1917 }
1918 
1919 void SdrObject::SaveGeoData(SdrObjGeoData& rGeo) const
1920 {
1921 	rGeo.aBoundRect    =GetCurrentBoundRect();
1922 	rGeo.aAnchor       =aAnchor       ;
1923 	rGeo.bMovProt      =bMovProt      ;
1924 	rGeo.bSizProt      =bSizProt      ;
1925 	rGeo.bNoPrint      =bNoPrint      ;
1926 	rGeo.mbVisible	   =mbVisible     ;
1927 	rGeo.bClosedObj    =bClosedObj    ;
1928 	rGeo.mnLayerID = mnLayerID;
1929 
1930 	// Benutzerdefinierte Klebepunkte
1931 	if (pPlusData!=NULL && pPlusData->pGluePoints!=NULL) {
1932 		if (rGeo.pGPL!=NULL) {
1933 			*rGeo.pGPL=*pPlusData->pGluePoints;
1934 		} else {
1935 			rGeo.pGPL=new SdrGluePointList(*pPlusData->pGluePoints);
1936 		}
1937 	} else {
1938 		if (rGeo.pGPL!=NULL) {
1939 			delete rGeo.pGPL;
1940 			rGeo.pGPL=NULL;
1941 		}
1942 	}
1943 }
1944 
1945 void SdrObject::RestGeoData(const SdrObjGeoData& rGeo)
1946 {
1947 	SetRectsDirty();
1948 	aOutRect      =rGeo.aBoundRect    ;
1949 	aAnchor       =rGeo.aAnchor       ;
1950 	bMovProt      =rGeo.bMovProt      ;
1951 	bSizProt      =rGeo.bSizProt      ;
1952 	bNoPrint      =rGeo.bNoPrint      ;
1953 	mbVisible     =rGeo.mbVisible     ;
1954 	bClosedObj    =rGeo.bClosedObj    ;
1955 	mnLayerID = rGeo.mnLayerID;
1956 
1957 	// Benutzerdefinierte Klebepunkte
1958 	if (rGeo.pGPL!=NULL) {
1959 		ImpForcePlusData();
1960 		if (pPlusData->pGluePoints!=NULL) {
1961 			*pPlusData->pGluePoints=*rGeo.pGPL;
1962 		} else {
1963 			pPlusData->pGluePoints=new SdrGluePointList(*rGeo.pGPL);
1964 		}
1965 	} else {
1966 		if (pPlusData!=NULL && pPlusData->pGluePoints!=NULL) {
1967 			delete pPlusData->pGluePoints;
1968 			pPlusData->pGluePoints=NULL;
1969 		}
1970 	}
1971 }
1972 
1973 SdrObjGeoData* SdrObject::GetGeoData() const
1974 {
1975 	SdrObjGeoData* pGeo=NewGeoData();
1976 	SaveGeoData(*pGeo);
1977 	return pGeo;
1978 }
1979 
1980 void SdrObject::SetGeoData(const SdrObjGeoData& rGeo)
1981 {
1982 	Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect();
1983 	RestGeoData(rGeo);
1984 	SetChanged();
1985 	BroadcastObjectChange();
1986 	SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
1987 }
1988 
1989 ////////////////////////////////////////////////////////////////////////////////////////////////////
1990 // ItemSet access
1991 
1992 const SfxItemSet& SdrObject::GetObjectItemSet() const
1993 {
1994 	return GetProperties().GetObjectItemSet();
1995 }
1996 
1997 const SfxItemSet& SdrObject::GetMergedItemSet() const
1998 {
1999 	return GetProperties().GetMergedItemSet();
2000 }
2001 
2002 void SdrObject::SetObjectItem(const SfxPoolItem& rItem)
2003 {
2004 	GetProperties().SetObjectItem(rItem);
2005 }
2006 
2007 void SdrObject::SetMergedItem(const SfxPoolItem& rItem)
2008 {
2009 	GetProperties().SetMergedItem(rItem);
2010 }
2011 
2012 void SdrObject::ClearObjectItem(const sal_uInt16 nWhich)
2013 {
2014 	GetProperties().ClearObjectItem(nWhich);
2015 }
2016 
2017 void SdrObject::ClearMergedItem(const sal_uInt16 nWhich)
2018 {
2019 	GetProperties().ClearMergedItem(nWhich);
2020 }
2021 
2022 void SdrObject::SetObjectItemSet(const SfxItemSet& rSet)
2023 {
2024 	GetProperties().SetObjectItemSet(rSet);
2025 }
2026 
2027 void SdrObject::SetMergedItemSet(const SfxItemSet& rSet, sal_Bool bClearAllItems)
2028 {
2029 	GetProperties().SetMergedItemSet(rSet, bClearAllItems);
2030 }
2031 
2032 const SfxPoolItem& SdrObject::GetObjectItem(const sal_uInt16 nWhich) const
2033 {
2034 	return GetObjectItemSet().Get(nWhich);
2035 }
2036 
2037 const SfxPoolItem& SdrObject::GetMergedItem(const sal_uInt16 nWhich) const
2038 {
2039 	return GetMergedItemSet().Get(nWhich);
2040 }
2041 
2042 void SdrObject::SetMergedItemSetAndBroadcast(const SfxItemSet& rSet, sal_Bool bClearAllItems)
2043 {
2044 	GetProperties().SetMergedItemSetAndBroadcast(rSet, bClearAllItems);
2045 }
2046 
2047 void SdrObject::ApplyNotPersistAttr(const SfxItemSet& rAttr)
2048 {
2049 	Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect();
2050 	NbcApplyNotPersistAttr(rAttr);
2051 	SetChanged();
2052 	BroadcastObjectChange();
2053 	SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
2054 }
2055 
2056 void SdrObject::NbcApplyNotPersistAttr(const SfxItemSet& rAttr)
2057 {
2058 	const Rectangle& rSnap=GetSnapRect();
2059 	const Rectangle& rLogic=GetLogicRect();
2060 	Point aRef1(rSnap.Center());
2061 	Point aRef2(aRef1); aRef2.Y()++;
2062 	const SfxPoolItem *pPoolItem=NULL;
2063 	if (rAttr.GetItemState(SDRATTR_TRANSFORMREF1X,sal_True,&pPoolItem)==SFX_ITEM_SET) {
2064 		aRef1.X()=((const SdrTransformRef1XItem*)pPoolItem)->GetValue();
2065 	}
2066 	if (rAttr.GetItemState(SDRATTR_TRANSFORMREF1Y,sal_True,&pPoolItem)==SFX_ITEM_SET) {
2067 		aRef1.Y()=((const SdrTransformRef1YItem*)pPoolItem)->GetValue();
2068 	}
2069 	if (rAttr.GetItemState(SDRATTR_TRANSFORMREF2X,sal_True,&pPoolItem)==SFX_ITEM_SET) {
2070 		aRef2.X()=((const SdrTransformRef2XItem*)pPoolItem)->GetValue();
2071 	}
2072 	if (rAttr.GetItemState(SDRATTR_TRANSFORMREF2Y,sal_True,&pPoolItem)==SFX_ITEM_SET) {
2073 		aRef2.Y()=((const SdrTransformRef2YItem*)pPoolItem)->GetValue();
2074 	}
2075 
2076 	Rectangle aNewSnap(rSnap);
2077 	if (rAttr.GetItemState(SDRATTR_MOVEX,sal_True,&pPoolItem)==SFX_ITEM_SET) {
2078 		long n=((const SdrMoveXItem*)pPoolItem)->GetValue();
2079 		aNewSnap.Move(n,0);
2080 	}
2081 	if (rAttr.GetItemState(SDRATTR_MOVEY,sal_True,&pPoolItem)==SFX_ITEM_SET) {
2082 		long n=((const SdrMoveYItem*)pPoolItem)->GetValue();
2083 		aNewSnap.Move(0,n);
2084 	}
2085 	if (rAttr.GetItemState(SDRATTR_ONEPOSITIONX,sal_True,&pPoolItem)==SFX_ITEM_SET) {
2086 		long n=((const SdrOnePositionXItem*)pPoolItem)->GetValue();
2087 		aNewSnap.Move(n-aNewSnap.Left(),0);
2088 	}
2089 	if (rAttr.GetItemState(SDRATTR_ONEPOSITIONY,sal_True,&pPoolItem)==SFX_ITEM_SET) {
2090 		long n=((const SdrOnePositionYItem*)pPoolItem)->GetValue();
2091 		aNewSnap.Move(0,n-aNewSnap.Top());
2092 	}
2093 	if (rAttr.GetItemState(SDRATTR_ONESIZEWIDTH,sal_True,&pPoolItem)==SFX_ITEM_SET) {
2094 		long n=((const SdrOneSizeWidthItem*)pPoolItem)->GetValue();
2095 		aNewSnap.Right()=aNewSnap.Left()+n;
2096 	}
2097 	if (rAttr.GetItemState(SDRATTR_ONESIZEHEIGHT,sal_True,&pPoolItem)==SFX_ITEM_SET) {
2098 		long n=((const SdrOneSizeHeightItem*)pPoolItem)->GetValue();
2099 		aNewSnap.Bottom()=aNewSnap.Top()+n;
2100 	}
2101 	if (aNewSnap!=rSnap) {
2102 		if (aNewSnap.GetSize()==rSnap.GetSize()) {
2103 			NbcMove(Size(aNewSnap.Left()-rSnap.Left(),aNewSnap.Top()-rSnap.Top()));
2104 		} else {
2105 			NbcSetSnapRect(aNewSnap);
2106 		}
2107 	}
2108 
2109 	if (rAttr.GetItemState(SDRATTR_SHEARANGLE,sal_True,&pPoolItem)==SFX_ITEM_SET) {
2110 		long n=((const SdrShearAngleItem*)pPoolItem)->GetValue();
2111 		n-=GetShearAngle();
2112 		if (n!=0) {
2113 			double nTan=tan(n*nPi180);
2114 			NbcShear(aRef1,n,nTan,sal_False);
2115 		}
2116 	}
2117 	if (rAttr.GetItemState(SDRATTR_ROTATEANGLE,sal_True,&pPoolItem)==SFX_ITEM_SET) {
2118 		long n=((const SdrRotateAngleItem*)pPoolItem)->GetValue();
2119 		n-=GetRotateAngle();
2120 		if (n!=0) {
2121 			double nSin=sin(n*nPi180);
2122 			double nCos=cos(n*nPi180);
2123 			NbcRotate(aRef1,n,nSin,nCos);
2124 		}
2125 	}
2126 	if (rAttr.GetItemState(SDRATTR_ROTATEONE,sal_True,&pPoolItem)==SFX_ITEM_SET) {
2127 		long n=((const SdrRotateOneItem*)pPoolItem)->GetValue();
2128 		double nSin=sin(n*nPi180);
2129 		double nCos=cos(n*nPi180);
2130 		NbcRotate(aRef1,n,nSin,nCos);
2131 	}
2132 	if (rAttr.GetItemState(SDRATTR_HORZSHEARONE,sal_True,&pPoolItem)==SFX_ITEM_SET) {
2133 		long n=((const SdrHorzShearOneItem*)pPoolItem)->GetValue();
2134 		double nTan=tan(n*nPi180);
2135 		NbcShear(aRef1,n,nTan,sal_False);
2136 	}
2137 	if (rAttr.GetItemState(SDRATTR_VERTSHEARONE,sal_True,&pPoolItem)==SFX_ITEM_SET) {
2138 		long n=((const SdrVertShearOneItem*)pPoolItem)->GetValue();
2139 		double nTan=tan(n*nPi180);
2140 		NbcShear(aRef1,n,nTan,sal_True);
2141 	}
2142 
2143 	if (rAttr.GetItemState(SDRATTR_OBJMOVEPROTECT,sal_True,&pPoolItem)==SFX_ITEM_SET) {
2144 		bool b=((const SdrObjMoveProtectItem*)pPoolItem)->GetValue();
2145 		SetMoveProtect(b);
2146 	}
2147 	if (rAttr.GetItemState(SDRATTR_OBJSIZEPROTECT,sal_True,&pPoolItem)==SFX_ITEM_SET) {
2148 		bool b=((const SdrObjSizeProtectItem*)pPoolItem)->GetValue();
2149 		SetResizeProtect(b);
2150 	}
2151 
2152 	/* #67368# move protect always sets size protect */
2153 	if( IsMoveProtect() )
2154 		SetResizeProtect( true );
2155 
2156 	if (rAttr.GetItemState(SDRATTR_OBJPRINTABLE,sal_True,&pPoolItem)==SFX_ITEM_SET) {
2157 		bool b=((const SdrObjPrintableItem*)pPoolItem)->GetValue();
2158 		SetPrintable(b);
2159 	}
2160 
2161 	if (rAttr.GetItemState(SDRATTR_OBJVISIBLE,sal_True,&pPoolItem)==SFX_ITEM_SET) {
2162 		bool b=((const SdrObjVisibleItem*)pPoolItem)->GetValue();
2163 		SetVisible(b);
2164 	}
2165 
2166 	SdrLayerID nLayer=SDRLAYER_NOTFOUND;
2167 	if (rAttr.GetItemState(SDRATTR_LAYERID,sal_True,&pPoolItem)==SFX_ITEM_SET) {
2168 		nLayer=((const SdrLayerIdItem*)pPoolItem)->GetValue();
2169 	}
2170 	if (rAttr.GetItemState(SDRATTR_LAYERNAME,sal_True,&pPoolItem)==SFX_ITEM_SET && pModel!=NULL) {
2171 		XubString aLayerName=((const SdrLayerNameItem*)pPoolItem)->GetValue();
2172 		const SdrLayerAdmin* pLayAd=pPage!=NULL ? &pPage->GetLayerAdmin() : pModel!=NULL ? &pModel->GetLayerAdmin() : NULL;
2173 		if (pLayAd!=NULL) {
2174 			const SdrLayer* pLayer=pLayAd->GetLayer(aLayerName, sal_True);
2175 			if (pLayer!=NULL) {
2176 				nLayer=pLayer->GetID();
2177 			}
2178 		}
2179 
2180 	}
2181 	if (nLayer!=SDRLAYER_NOTFOUND) {
2182 		NbcSetLayer(nLayer);
2183 	}
2184 
2185 	if (rAttr.GetItemState(SDRATTR_OBJECTNAME,sal_True,&pPoolItem)==SFX_ITEM_SET) {
2186 		XubString aName=((const SdrObjectNameItem*)pPoolItem)->GetValue();
2187 		SetName(aName);
2188 	}
2189 	Rectangle aNewLogic(rLogic);
2190 	if (rAttr.GetItemState(SDRATTR_LOGICSIZEWIDTH,sal_True,&pPoolItem)==SFX_ITEM_SET) {
2191 		long n=((const SdrLogicSizeWidthItem*)pPoolItem)->GetValue();
2192 		aNewLogic.Right()=aNewLogic.Left()+n;
2193 	}
2194 	if (rAttr.GetItemState(SDRATTR_LOGICSIZEHEIGHT,sal_True,&pPoolItem)==SFX_ITEM_SET) {
2195 		long n=((const SdrLogicSizeHeightItem*)pPoolItem)->GetValue();
2196 		aNewLogic.Bottom()=aNewLogic.Top()+n;
2197 	}
2198 	if (aNewLogic!=rLogic) {
2199 		NbcSetLogicRect(aNewLogic);
2200 	}
2201 	Fraction aResizeX(1,1);
2202 	Fraction aResizeY(1,1);
2203 	if (rAttr.GetItemState(SDRATTR_RESIZEXONE,sal_True,&pPoolItem)==SFX_ITEM_SET) {
2204 		aResizeX*=((const SdrResizeXOneItem*)pPoolItem)->GetValue();
2205 	}
2206 	if (rAttr.GetItemState(SDRATTR_RESIZEYONE,sal_True,&pPoolItem)==SFX_ITEM_SET) {
2207 		aResizeY*=((const SdrResizeYOneItem*)pPoolItem)->GetValue();
2208 	}
2209 	if (aResizeX!=Fraction(1,1) || aResizeY!=Fraction(1,1)) {
2210 		NbcResize(aRef1,aResizeX,aResizeY);
2211 	}
2212 }
2213 
2214 void lcl_SetItem(SfxItemSet& rAttr, FASTBOOL bMerge, const SfxPoolItem& rItem)
2215 {
2216 	if (bMerge) rAttr.MergeValue(rItem,sal_True);
2217 	else rAttr.Put(rItem);
2218 }
2219 
2220 void SdrObject::TakeNotPersistAttr(SfxItemSet& rAttr, FASTBOOL bMerge) const
2221 {
2222 	const Rectangle& rSnap=GetSnapRect();
2223 	const Rectangle& rLogic=GetLogicRect();
2224 	lcl_SetItem(rAttr,bMerge,SdrObjMoveProtectItem(IsMoveProtect()));
2225 	lcl_SetItem(rAttr,bMerge,SdrObjSizeProtectItem(IsResizeProtect()));
2226 	lcl_SetItem(rAttr,bMerge,SdrObjPrintableItem(IsPrintable()));
2227 	lcl_SetItem(rAttr,bMerge,SdrObjVisibleItem(IsVisible()));
2228 	lcl_SetItem(rAttr,bMerge,SdrRotateAngleItem(GetRotateAngle()));
2229 	lcl_SetItem(rAttr,bMerge,SdrShearAngleItem(GetShearAngle()));
2230 	lcl_SetItem(rAttr,bMerge,SdrOneSizeWidthItem(rSnap.GetWidth()-1));
2231 	lcl_SetItem(rAttr,bMerge,SdrOneSizeHeightItem(rSnap.GetHeight()-1));
2232 	lcl_SetItem(rAttr,bMerge,SdrOnePositionXItem(rSnap.Left()));
2233 	lcl_SetItem(rAttr,bMerge,SdrOnePositionYItem(rSnap.Top()));
2234 	if (rLogic.GetWidth()!=rSnap.GetWidth()) {
2235 		lcl_SetItem(rAttr,bMerge,SdrLogicSizeWidthItem(rLogic.GetWidth()-1));
2236 	}
2237 	if (rLogic.GetHeight()!=rSnap.GetHeight()) {
2238 		lcl_SetItem(rAttr,bMerge,SdrLogicSizeHeightItem(rLogic.GetHeight()-1));
2239 	}
2240 	XubString aName(GetName());
2241 
2242 	if(aName.Len())
2243 	{
2244 		lcl_SetItem(rAttr, bMerge, SdrObjectNameItem(aName));
2245 	}
2246 
2247 	lcl_SetItem(rAttr,bMerge,SdrLayerIdItem(GetLayer()));
2248 	const SdrLayerAdmin* pLayAd=pPage!=NULL ? &pPage->GetLayerAdmin() : pModel!=NULL ? &pModel->GetLayerAdmin() : NULL;
2249 	if (pLayAd!=NULL) {
2250 		const SdrLayer* pLayer=pLayAd->GetLayerPerID(GetLayer());
2251 		if (pLayer!=NULL) {
2252 			lcl_SetItem(rAttr,bMerge,SdrLayerNameItem(pLayer->GetName()));
2253 		}
2254 	}
2255 	Point aRef1(rSnap.Center());
2256 	Point aRef2(aRef1); aRef2.Y()++;
2257 	lcl_SetItem(rAttr,bMerge,SdrTransformRef1XItem(aRef1.X()));
2258 	lcl_SetItem(rAttr,bMerge,SdrTransformRef1YItem(aRef1.Y()));
2259 	lcl_SetItem(rAttr,bMerge,SdrTransformRef2XItem(aRef2.X()));
2260 	lcl_SetItem(rAttr,bMerge,SdrTransformRef2YItem(aRef2.Y()));
2261 }
2262 
2263 SfxStyleSheet* SdrObject::GetStyleSheet() const
2264 {
2265 	return GetProperties().GetStyleSheet();
2266 }
2267 
2268 void SdrObject::SetStyleSheet(SfxStyleSheet* pNewStyleSheet, sal_Bool bDontRemoveHardAttr)
2269 {
2270 	Rectangle aBoundRect0;
2271 
2272 	if(pUserCall)
2273 		aBoundRect0 = GetLastBoundRect();
2274 
2275 	// #110094#-14 SendRepaintBroadcast();
2276 	NbcSetStyleSheet(pNewStyleSheet, bDontRemoveHardAttr);
2277 	SetChanged();
2278 	BroadcastObjectChange();
2279 	SendUserCall(SDRUSERCALL_CHGATTR, aBoundRect0);
2280 }
2281 
2282 void SdrObject::NbcSetStyleSheet(SfxStyleSheet* pNewStyleSheet, sal_Bool bDontRemoveHardAttr)
2283 {
2284 	// only allow graphic and presentation styles for shapes
2285 	if( pNewStyleSheet && (pNewStyleSheet->GetFamily() == SFX_STYLE_FAMILY_PARA) && (pNewStyleSheet->GetFamily() == SFX_STYLE_FAMILY_PAGE) )
2286 		return;
2287 
2288 	GetProperties().SetStyleSheet(pNewStyleSheet, bDontRemoveHardAttr);
2289 }
2290 
2291 // Das Broadcasting beim Setzen der Attribute wird vom AttrObj gemanagt
2292 ////////////////////////////////////////////////////////////////////////////////////////////////////
2293 
2294 FASTBOOL SdrObject::IsNode() const
2295 {
2296 	return sal_True;
2297 }
2298 
2299 SdrGluePoint SdrObject::GetVertexGluePoint(sal_uInt16 nPosNum) const
2300 {
2301 	// #i41936# Use SnapRect for default GluePoints
2302 	const Rectangle aR(GetSnapRect());
2303 	Point aPt;
2304 
2305 	switch(nPosNum)
2306 	{
2307 		case 0 : aPt = aR.TopCenter();    break;
2308 		case 1 : aPt = aR.RightCenter();  break;
2309 		case 2 : aPt = aR.BottomCenter(); break;
2310 		case 3 : aPt = aR.LeftCenter();   break;
2311 	}
2312 
2313 	aPt -= aR.Center();
2314 	SdrGluePoint aGP(aPt);
2315 	aGP.SetPercent(sal_False);
2316 
2317 	return aGP;
2318 }
2319 
2320 SdrGluePoint SdrObject::GetCornerGluePoint(sal_uInt16 nPosNum) const
2321 {
2322 	Rectangle aR(GetCurrentBoundRect());
2323 	Point aPt;
2324 	switch (nPosNum) {
2325 		case 0 : aPt=aR.TopLeft();     break;
2326 		case 1 : aPt=aR.TopRight();    break;
2327 		case 2 : aPt=aR.BottomRight(); break;
2328 		case 3 : aPt=aR.BottomLeft();  break;
2329 	}
2330 	aPt-=GetSnapRect().Center();
2331 	SdrGluePoint aGP(aPt);
2332 	aGP.SetPercent(sal_False);
2333 	return aGP;
2334 }
2335 
2336 const SdrGluePointList* SdrObject::GetGluePointList() const
2337 {
2338 	if (pPlusData!=NULL) return pPlusData->pGluePoints;
2339 	return NULL;
2340 }
2341 
2342 //SdrGluePointList* SdrObject::GetGluePointList()
2343 //{
2344 //	if (pPlusData!=NULL) return pPlusData->pGluePoints;
2345 //	return NULL;
2346 //}
2347 
2348 SdrGluePointList* SdrObject::ForceGluePointList()
2349 {
2350 	ImpForcePlusData();
2351 	if (pPlusData->pGluePoints==NULL) {
2352 		pPlusData->pGluePoints=new SdrGluePointList;
2353 	}
2354 	return pPlusData->pGluePoints;
2355 }
2356 
2357 void SdrObject::SetGlueReallyAbsolute(FASTBOOL bOn)
2358 {
2359 	// erst Const-Aufruf um zu sehen, ob
2360 	// ueberhaupt Klebepunkte da sind
2361 	// const-Aufruf erzwingen!
2362 	if (GetGluePointList()!=NULL) {
2363 		SdrGluePointList* pGPL=ForceGluePointList();
2364 		pGPL->SetReallyAbsolute(bOn,*this);
2365 	}
2366 }
2367 
2368 void SdrObject::NbcRotateGluePoints(const Point& rRef, long nWink, double sn, double cs)
2369 {
2370 	// erst Const-Aufruf um zu sehen, ob
2371 	// ueberhaupt Klebepunkte da sind
2372 	// const-Aufruf erzwingen!
2373 	if (GetGluePointList()!=NULL) {
2374 		SdrGluePointList* pGPL=ForceGluePointList();
2375 		pGPL->Rotate(rRef,nWink,sn,cs,this);
2376 	}
2377 }
2378 
2379 void SdrObject::NbcMirrorGluePoints(const Point& rRef1, const Point& rRef2)
2380 {
2381 	// erst Const-Aufruf um zu sehen, ob
2382 	// ueberhaupt Klebepunkte da sind
2383 	// const-Aufruf erzwingen!
2384 	if (GetGluePointList()!=NULL) {
2385 		SdrGluePointList* pGPL=ForceGluePointList();
2386 		pGPL->Mirror(rRef1,rRef2,this);
2387 	}
2388 }
2389 
2390 void SdrObject::NbcShearGluePoints(const Point& rRef, long nWink, double tn, FASTBOOL bVShear)
2391 {
2392 	// erst Const-Aufruf um zu sehen, ob
2393 	// ueberhaupt Klebepunkte da sind
2394 	// const-Aufruf erzwingen!
2395 	if (GetGluePointList()!=NULL) {
2396 		SdrGluePointList* pGPL=ForceGluePointList();
2397 		pGPL->Shear(rRef,nWink,tn,bVShear,this);
2398 	}
2399 }
2400 
2401 FASTBOOL SdrObject::IsEdge() const
2402 {
2403 	return sal_False;
2404 }
2405 
2406 void SdrObject::ConnectToNode(FASTBOOL /*bTail1*/, SdrObject* /*pObj*/)
2407 {
2408 }
2409 
2410 void SdrObject::DisconnectFromNode(FASTBOOL /*bTail1*/)
2411 {
2412 }
2413 
2414 SdrObject* SdrObject::GetConnectedNode(FASTBOOL /*bTail1*/) const
2415 {
2416 	return NULL;
2417 }
2418 
2419 ////////////////////////////////////////////////////////////////////////////////////////////////////
2420 
2421 SdrObject* SdrObject::ImpConvertToContourObj(SdrObject* pRet, sal_Bool bForceLineDash) const
2422 {
2423 	bool bNoChange(true);
2424 
2425 	if(pRet->LineGeometryUsageIsNecessary())
2426 	{
2427 		basegfx::B2DPolyPolygon aMergedLineFillPolyPolygon;
2428 		basegfx::B2DPolyPolygon aMergedHairlinePolyPolygon;
2429 		const drawinglayer::primitive2d::Primitive2DSequence xSequence(pRet->GetViewContact().getViewIndependentPrimitive2DSequence());
2430 
2431 		if(xSequence.hasElements())
2432 		{
2433 			// use neutral ViewInformation
2434 			const drawinglayer::geometry::ViewInformation2D aViewInformation2D;
2435 
2436 			// create extractor, process and get result
2437 			drawinglayer::processor2d::LineGeometryExtractor2D aExtractor(aViewInformation2D);
2438 			aExtractor.process(xSequence);
2439 
2440 			// #i102241# check for line results
2441 			const std::vector< basegfx::B2DPolygon >& rHairlineVector = aExtractor.getExtractedHairlines();
2442 
2443 			if(!rHairlineVector.empty())
2444 			{
2445 				// for SdrObject creation, just copy all to a single Hairline-PolyPolygon
2446 				for(sal_uInt32 a(0); a < rHairlineVector.size(); a++)
2447 				{
2448 					aMergedHairlinePolyPolygon.append(rHairlineVector[a]);
2449 				}
2450 			}
2451 
2452 			// #i102241# check for fill rsults
2453 			const std::vector< basegfx::B2DPolyPolygon >& rLineFillVector(aExtractor.getExtractedLineFills());
2454 
2455 			if(!rLineFillVector.empty())
2456 			{
2457 				// merge to a single PolyPolygon (OR)
2458 				aMergedLineFillPolyPolygon = basegfx::tools::mergeToSinglePolyPolygon(rLineFillVector);
2459 			}
2460 		}
2461 
2462 		//  || aMergedHairlinePolyPolygon.Count() removed; the conversion is ONLY
2463 		// useful when new closed filled polygons are created
2464 		if(aMergedLineFillPolyPolygon.count() || (bForceLineDash && aMergedHairlinePolyPolygon.count()))
2465 		{
2466 			SfxItemSet aSet(pRet->GetMergedItemSet());
2467 			XFillStyle eOldFillStyle = ((const XFillStyleItem&)(aSet.Get(XATTR_FILLSTYLE))).GetValue();
2468 			SdrPathObj* aLinePolygonPart = NULL;
2469 			SdrPathObj* aLineHairlinePart = NULL;
2470 			bool bBuildGroup(false);
2471 
2472 			if(aMergedLineFillPolyPolygon.count())
2473 			{
2474                 // create SdrObject for filled line geometry
2475 				aLinePolygonPart = new SdrPathObj(OBJ_PATHFILL, aMergedLineFillPolyPolygon);
2476 				aLinePolygonPart->SetModel(pRet->GetModel());
2477 
2478                 // correct item properties
2479 				aSet.Put(XLineWidthItem(0L));
2480 				aSet.Put(XLineStyleItem(XLINE_NONE));
2481 				Color aColorLine = ((const XLineColorItem&)(aSet.Get(XATTR_LINECOLOR))).GetColorValue();
2482 				sal_uInt16 nTransLine = ((const XLineTransparenceItem&)(aSet.Get(XATTR_LINETRANSPARENCE))).GetValue();
2483 				aSet.Put(XFillColorItem(XubString(), aColorLine));
2484 				aSet.Put(XFillStyleItem(XFILL_SOLID));
2485 				aSet.Put(XFillTransparenceItem(nTransLine));
2486 
2487 				aLinePolygonPart->SetMergedItemSet(aSet);
2488 			}
2489 
2490 			if(aMergedHairlinePolyPolygon.count())
2491 			{
2492                 // create SdrObject for hairline geometry
2493 				// OBJ_PATHLINE is necessary here, not OBJ_PATHFILL. This is intended
2494 				// to get a non-filled object. If the poly is closed, the PathObj takes care for
2495 				// the correct closed state.
2496 				aLineHairlinePart = new SdrPathObj(OBJ_PATHLINE, aMergedHairlinePolyPolygon);
2497 				aLineHairlinePart->SetModel(pRet->GetModel());
2498 
2499 				aSet.Put(XLineWidthItem(0L));
2500 				aSet.Put(XFillStyleItem(XFILL_NONE));
2501 				aSet.Put(XLineStyleItem(XLINE_SOLID));
2502 
2503 				// it is also necessary to switch off line start and ends here
2504 				aSet.Put(XLineStartWidthItem(0));
2505 				aSet.Put(XLineEndWidthItem(0));
2506 
2507 				aLineHairlinePart->SetMergedItemSet(aSet);
2508 
2509 				if(aLinePolygonPart)
2510                 {
2511 					bBuildGroup = true;
2512                 }
2513 			}
2514 
2515 			// check if original geometry should be added (e.g. filled and closed)
2516 			bool bAddOriginalGeometry(false);
2517 			SdrPathObj* pPath = PTR_CAST(SdrPathObj, pRet);
2518 
2519             if(pPath && pPath->IsClosed())
2520 			{
2521 				if(eOldFillStyle != XFILL_NONE)
2522 				{
2523 					// #107600# use new boolean here
2524 					bAddOriginalGeometry = true;
2525 				}
2526 			}
2527 
2528 			// do we need a group?
2529 			if(bBuildGroup || bAddOriginalGeometry)
2530 			{
2531 				SdrObject* pGroup = new SdrObjGroup;
2532 				pGroup->SetModel(pRet->GetModel());
2533 
2534 				if(bAddOriginalGeometry)
2535 				{
2536 					// Add a clone of the original geometry.
2537 					aSet.ClearItem();
2538 					aSet.Put(pRet->GetMergedItemSet());
2539 					aSet.Put(XLineStyleItem(XLINE_NONE));
2540 					aSet.Put(XLineWidthItem(0L));
2541 
2542 					SdrObject* pClone = pRet->Clone();
2543 
2544 					pClone->SetModel(pRet->GetModel());
2545 					pClone->SetMergedItemSet(aSet);
2546 
2547 					pGroup->GetSubList()->NbcInsertObject(pClone);
2548 				}
2549 
2550 				if(aLinePolygonPart)
2551 				{
2552 					pGroup->GetSubList()->NbcInsertObject(aLinePolygonPart);
2553 				}
2554 
2555 				if(aLineHairlinePart)
2556 				{
2557 					pGroup->GetSubList()->NbcInsertObject(aLineHairlinePart);
2558 				}
2559 
2560 				pRet = pGroup;
2561 
2562 				// be more careful with the state describing bool
2563 				bNoChange = false;
2564 			}
2565 			else
2566 			{
2567 				if(aLinePolygonPart)
2568 				{
2569 					pRet = aLinePolygonPart;
2570 					// be more careful with the state describing bool
2571 					bNoChange = false;
2572 				}
2573 				else if(aLineHairlinePart)
2574 				{
2575 					pRet = aLineHairlinePart;
2576 					// be more careful with the state describing bool
2577 					bNoChange = false;
2578 				}
2579 			}
2580 		}
2581 	}
2582 
2583 	if(bNoChange)
2584 	{
2585         // due to current method usage, create and return a clone when nothing has changed
2586 		SdrObject* pClone = pRet->Clone();
2587 		pClone->SetModel(pRet->GetModel());
2588 		pRet = pClone;
2589 	}
2590 
2591 	return pRet;
2592 }
2593 
2594 // convert this path object to contour object, even when it is a group
2595 SdrObject* SdrObject::ConvertToContourObj(SdrObject* pRet, sal_Bool bForceLineDash) const
2596 {
2597 	if(pRet->ISA(SdrObjGroup))
2598 	{
2599 		SdrObjList* pObjList2 = pRet->GetSubList();
2600 		SdrObject* pGroup = new SdrObjGroup;
2601 		pGroup->SetModel(pRet->GetModel());
2602 
2603 		for(sal_uInt32 a=0;a<pObjList2->GetObjCount();a++)
2604 		{
2605 			SdrObject* pIterObj = pObjList2->GetObj(a);
2606 			pGroup->GetSubList()->NbcInsertObject(ConvertToContourObj(pIterObj, bForceLineDash));
2607 		}
2608 
2609 		pRet = pGroup;
2610 	}
2611 	else
2612 	{
2613         if(pRet && pRet->ISA(SdrPathObj))
2614         {
2615             SdrPathObj* pPathObj = (SdrPathObj*)pRet;
2616 
2617             // bezier geometry got created, even for straight edges since the given
2618             // object is a result of DoConvertToPolyObj. For conversion to contour
2619             // this is not really needed and can be reduced again AFAP
2620             pPathObj->SetPathPoly(basegfx::tools::simplifyCurveSegments(pPathObj->GetPathPoly()));
2621         }
2622 
2623 		pRet = ImpConvertToContourObj(pRet, bForceLineDash);
2624 	}
2625 
2626 	// #i73441# preserve LayerID
2627 	if(pRet && pRet->GetLayer() != GetLayer())
2628 	{
2629 		pRet->SetLayer(GetLayer());
2630 	}
2631 
2632 	return pRet;
2633 }
2634 
2635 ////////////////////////////////////////////////////////////////////////////////////////////////////
2636 
2637 SdrObject* SdrObject::ConvertToPolyObj(sal_Bool bBezier, sal_Bool bLineToArea) const
2638 {
2639 	SdrObject* pRet = DoConvertToPolyObj(bBezier, true);
2640 
2641 	if(pRet && bLineToArea)
2642 	{
2643 		SdrObject* pNewRet = ConvertToContourObj(pRet);
2644 		delete pRet;
2645 		pRet = pNewRet;
2646 	}
2647 
2648 	// #i73441# preserve LayerID
2649 	if(pRet && pRet->GetLayer() != GetLayer())
2650 	{
2651 		pRet->SetLayer(GetLayer());
2652 	}
2653 
2654 	return pRet;
2655 }
2656 
2657 ////////////////////////////////////////////////////////////////////////////////////////////////////
2658 
2659 SdrObject* SdrObject::DoConvertToPolyObj(sal_Bool /*bBezier*/, bool /*bAddText*/) const
2660 {
2661 	return NULL;
2662 }
2663 
2664 ////////////////////////////////////////////////////////////////////////////////////////////////////
2665 
2666 void SdrObject::SetInserted(sal_Bool bIns)
2667 {
2668 	if (bIns!=IsInserted()) {
2669 		bInserted=bIns;
2670 		Rectangle aBoundRect0(GetLastBoundRect());
2671 		if (bIns) SendUserCall(SDRUSERCALL_INSERTED,aBoundRect0);
2672 		else SendUserCall(SDRUSERCALL_REMOVED,aBoundRect0);
2673 
2674 		if (pPlusData!=NULL && pPlusData->pBroadcast!=NULL) { // #42522#
2675 			SdrHint aHint(*this);
2676 			aHint.SetKind(bIns?HINT_OBJINSERTED:HINT_OBJREMOVED);
2677 			pPlusData->pBroadcast->Broadcast(aHint);
2678 		}
2679 	}
2680 }
2681 
2682 void SdrObject::SetMoveProtect(sal_Bool bProt)
2683 {
2684 	if(IsMoveProtect() != bProt)
2685 	{
2686 		// #i77187# secured and simplified
2687 		bMovProt = bProt;
2688 		SetChanged();
2689 		BroadcastObjectChange();
2690 	}
2691 }
2692 
2693 void SdrObject::SetResizeProtect(sal_Bool bProt)
2694 {
2695 	if(IsResizeProtect() != bProt)
2696 	{
2697 		// #i77187# secured and simplified
2698 		bSizProt = bProt;
2699 		SetChanged();
2700 		BroadcastObjectChange();
2701 	}
2702 }
2703 
2704 void SdrObject::SetPrintable(sal_Bool bPrn)
2705 {
2706 	if( bPrn == bNoPrint )
2707 	{
2708 		bNoPrint=!bPrn;
2709 		SetChanged();
2710 		if (IsInserted() && pModel!=NULL)
2711 		{
2712 			SdrHint aHint(*this);
2713 			pModel->Broadcast(aHint);
2714 		}
2715 	}
2716 }
2717 
2718 void SdrObject::SetVisible(sal_Bool bVisible)
2719 {
2720 	if( bVisible != mbVisible )
2721 	{
2722 		mbVisible = bVisible;
2723 		SetChanged();
2724 		if (IsInserted() && pModel!=NULL)
2725 		{
2726 			SdrHint aHint(*this);
2727 			pModel->Broadcast(aHint);
2728 		}
2729 	}
2730 }
2731 
2732 ////////////////////////////////////////////////////////////////////////////////////////////////////
2733 
2734 sal_uInt16 SdrObject::GetUserDataCount() const
2735 {
2736 	if (pPlusData==NULL || pPlusData->pUserDataList==NULL) return 0;
2737 	return pPlusData->pUserDataList->GetUserDataCount();
2738 }
2739 
2740 SdrObjUserData* SdrObject::GetUserData(sal_uInt16 nNum) const
2741 {
2742 	if (pPlusData==NULL || pPlusData->pUserDataList==NULL) return NULL;
2743 	return pPlusData->pUserDataList->GetUserData(nNum);
2744 }
2745 
2746 void SdrObject::InsertUserData(SdrObjUserData* pData, sal_uInt16 nPos)
2747 {
2748 	if (pData!=NULL) {
2749 		ImpForcePlusData();
2750 		if (pPlusData->pUserDataList==NULL) pPlusData->pUserDataList=new SdrObjUserDataList;
2751 		pPlusData->pUserDataList->InsertUserData(pData,nPos);
2752 	} else {
2753 		DBG_ERROR("SdrObject::InsertUserData(): pData ist NULL-Pointer");
2754 	}
2755 }
2756 
2757 void SdrObject::DeleteUserData(sal_uInt16 nNum)
2758 {
2759 	sal_uInt16 nAnz=GetUserDataCount();
2760 	if (nNum<nAnz) {
2761 		pPlusData->pUserDataList->DeleteUserData(nNum);
2762 		if (nAnz==1)  {
2763 			delete pPlusData->pUserDataList;
2764 			pPlusData->pUserDataList=NULL;
2765 		}
2766 	} else {
2767 		DBG_ERROR("SdrObject::DeleteUserData(): ungueltiger Index");
2768 	}
2769 }
2770 
2771 void SdrObject::SendUserCall(SdrUserCallType eUserCall, const Rectangle& rBoundRect) const
2772 {
2773 	SdrObjGroup* pGroup = NULL;
2774 
2775 	if( pObjList && pObjList->GetListKind() == SDROBJLIST_GROUPOBJ )
2776 		pGroup = (SdrObjGroup*) pObjList->GetOwnerObj();
2777 
2778 	if ( pUserCall )
2779 	{
2780 		// UserCall ausfuehren
2781 		pUserCall->Changed( *this, eUserCall, rBoundRect );
2782 	}
2783 
2784 	while( pGroup )
2785 	{
2786 		// Gruppe benachrichtigen
2787 		if( pGroup->GetUserCall() )
2788 		{
2789 			SdrUserCallType eChildUserType = SDRUSERCALL_CHILD_CHGATTR;
2790 
2791 			switch( eUserCall )
2792 			{
2793 				case SDRUSERCALL_MOVEONLY:
2794 					eChildUserType = SDRUSERCALL_CHILD_MOVEONLY;
2795 				break;
2796 
2797 				case SDRUSERCALL_RESIZE:
2798 					eChildUserType = SDRUSERCALL_CHILD_RESIZE;
2799 				break;
2800 
2801 				case SDRUSERCALL_CHGATTR:
2802 					eChildUserType = SDRUSERCALL_CHILD_CHGATTR;
2803 				break;
2804 
2805 				case SDRUSERCALL_DELETE:
2806 					eChildUserType = SDRUSERCALL_CHILD_DELETE;
2807 				break;
2808 
2809 				case SDRUSERCALL_COPY:
2810 					eChildUserType = SDRUSERCALL_CHILD_COPY;
2811 				break;
2812 
2813 				case SDRUSERCALL_INSERTED:
2814 					eChildUserType = SDRUSERCALL_CHILD_INSERTED;
2815 				break;
2816 
2817 				case SDRUSERCALL_REMOVED:
2818 					eChildUserType = SDRUSERCALL_CHILD_REMOVED;
2819 				break;
2820 
2821 				default: break;
2822 			}
2823 
2824 			pGroup->GetUserCall()->Changed( *this, eChildUserType, rBoundRect );
2825 		}
2826 
2827 		if( pGroup->GetObjList()                                       &&
2828 			pGroup->GetObjList()->GetListKind() == SDROBJLIST_GROUPOBJ &&
2829 			pGroup != (SdrObjGroup*) pObjList->GetOwnerObj() )
2830 			pGroup = (SdrObjGroup*) pObjList->GetOwnerObj();
2831 		else
2832 			pGroup = NULL;
2833 	}
2834 
2835     // notify our UNO shape listeners
2836     switch ( eUserCall )
2837     {
2838     case SDRUSERCALL_RESIZE:
2839         notifyShapePropertyChange( ::svx::eShapeSize );
2840         // fall through - RESIZE might also imply a change of the position
2841     case SDRUSERCALL_MOVEONLY:
2842         notifyShapePropertyChange( ::svx::eShapePosition );
2843         break;
2844     default:
2845         // not interested in
2846         break;
2847     }
2848 }
2849 
2850 // ItemPool fuer dieses Objekt wechseln
2851 void SdrObject::MigrateItemPool(SfxItemPool* pSrcPool, SfxItemPool* pDestPool, SdrModel* pNewModel)
2852 {
2853 	if(pSrcPool && pDestPool && (pSrcPool != pDestPool))
2854 	{
2855 		GetProperties().MoveToItemPool(pSrcPool, pDestPool, pNewModel);
2856 	}
2857 }
2858 
2859 sal_Bool SdrObject::IsTransparent( sal_Bool /*bCheckForAlphaChannel*/) const
2860 {
2861 	bool bRet = false;
2862 
2863 	if( IsGroupObject() )
2864 	{
2865 		SdrObjListIter aIter( *GetSubList(), IM_DEEPNOGROUPS );
2866 
2867 		for( SdrObject*	pO = aIter.Next(); pO && !bRet; pO = aIter.Next() )
2868 		{
2869 			const SfxItemSet& rAttr = pO->GetMergedItemSet();
2870 
2871 			if( ( ( (const XFillTransparenceItem&) rAttr.Get( XATTR_FILLTRANSPARENCE ) ).GetValue() ||
2872 				  ( (const XLineTransparenceItem&) rAttr.Get( XATTR_LINETRANSPARENCE ) ).GetValue()	) ||
2873 				( ( rAttr.GetItemState( XATTR_FILLFLOATTRANSPARENCE ) == SFX_ITEM_SET ) &&
2874 				  ( (const XFillFloatTransparenceItem&) rAttr.Get( XATTR_FILLFLOATTRANSPARENCE ) ).IsEnabled() ) )
2875 			{
2876 				bRet = sal_True;
2877 			}
2878 			else if( pO->ISA( SdrGrafObj ) )
2879 			{
2880 				SdrGrafObj* pGrafObj = (SdrGrafObj*) pO;
2881 				if( ( (const SdrGrafTransparenceItem&) rAttr.Get( SDRATTR_GRAFTRANSPARENCE ) ).GetValue() ||
2882                     ( pGrafObj->GetGraphicType() == GRAPHIC_BITMAP && pGrafObj->GetGraphic().GetBitmapEx().IsAlpha() ) )
2883 				{
2884 					bRet = sal_True;
2885 				}
2886 			}
2887 		}
2888 	}
2889 	else
2890 	{
2891 		const SfxItemSet& rAttr = GetMergedItemSet();
2892 
2893 		if( ( ( (const XFillTransparenceItem&) rAttr.Get( XATTR_FILLTRANSPARENCE ) ).GetValue() ||
2894 			  ( (const XLineTransparenceItem&) rAttr.Get( XATTR_LINETRANSPARENCE ) ).GetValue()	) ||
2895 			( ( rAttr.GetItemState( XATTR_FILLFLOATTRANSPARENCE ) == SFX_ITEM_SET ) &&
2896 			  ( (const XFillFloatTransparenceItem&) rAttr.Get( XATTR_FILLFLOATTRANSPARENCE ) ).IsEnabled() ) )
2897 		{
2898 			bRet = sal_True;
2899 		}
2900 		else if( ISA( SdrGrafObj ) )
2901 		{
2902 			SdrGrafObj* pGrafObj = (SdrGrafObj*) this;
2903 
2904 			// #i25616#
2905 			bRet = pGrafObj->IsObjectTransparent();
2906 		}
2907 	}
2908 
2909 	return bRet;
2910 }
2911 
2912 void SdrObject::impl_setUnoShape( const uno::Reference< uno::XInterface >& _rxUnoShape )
2913 {
2914 	maWeakUnoShape = _rxUnoShape;
2915 	mpSvxShape = SvxShape::getImplementation( _rxUnoShape );
2916 //    OSL_ENSURE( mpSvxShape || !_rxUnoShape.is(),
2917 //        "SdrObject::setUnoShape: not sure it's a good idea to have an XShape which is not implemented by SvxShape ..." );
2918 }
2919 
2920 /** only for internal use! */
2921 SvxShape* SdrObject::getSvxShape() const
2922 {
2923     DBG_TESTSOLARMUTEX();
2924         // retrieving the impl pointer and subsequently using it is not thread-safe, of course, so it needs to be
2925         // guarded by the SolarMutex
2926 
2927 #if OSL_DEBUG_LEVE > 0
2928     uno::Reference< uno::XInterface > xShape( maWeakUnoShape );
2929     OSL_ENSURE( !( !xShapeGuard.is() && mpSvxShape ),
2930         "SdrObject::getSvxShape: still having IMPL-Pointer to dead object!" );
2931 #endif
2932 
2933 	return mpSvxShape;
2934 }
2935 
2936 ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SdrObject::getUnoShape()
2937 {
2938 	// try weak reference first
2939 	uno::Reference< uno::XInterface > xShape( getWeakUnoShape() );
2940 	if( !xShape.is() )
2941 	{
2942         OSL_ENSURE( mpSvxShape == NULL, "SdrObject::getUnoShape: XShape already dead, but still an IMPL pointer!" );
2943 		if ( pPage )
2944 		{
2945 			uno::Reference< uno::XInterface > xPage( pPage->getUnoPage() );
2946 			if( xPage.is() )
2947 			{
2948 				SvxDrawPage* pDrawPage = SvxDrawPage::getImplementation(xPage);
2949 				if( pDrawPage )
2950 				{
2951 					// create one
2952                     xShape = pDrawPage->_CreateShape( this );
2953                     impl_setUnoShape( xShape );
2954 				}
2955 			}
2956 		}
2957 		else
2958 		{
2959 			mpSvxShape = SvxDrawPage::CreateShapeByTypeAndInventor( GetObjIdentifier(), GetObjInventor(), this, NULL );
2960 			maWeakUnoShape = xShape = static_cast< ::cppu::OWeakObject* >( mpSvxShape );
2961 		}
2962 	}
2963 
2964 	return xShape;
2965 }
2966 
2967 ::svx::PropertyChangeNotifier& SdrObject::getShapePropertyChangeNotifier()
2968 {
2969     DBG_TESTSOLARMUTEX();
2970 
2971     SvxShape* pSvxShape = getSvxShape();
2972     ENSURE_OR_THROW( pSvxShape, "no SvxShape, yet!" );
2973     return pSvxShape->getShapePropertyChangeNotifier();
2974 }
2975 
2976 void SdrObject::notifyShapePropertyChange( const ::svx::ShapeProperty _eProperty ) const
2977 {
2978     DBG_TESTSOLARMUTEX();
2979 
2980     SvxShape* pSvxShape = const_cast< SdrObject* >( this )->getSvxShape();
2981     if ( pSvxShape )
2982         return pSvxShape->getShapePropertyChangeNotifier().notifyPropertyChange( _eProperty );
2983 }
2984 
2985 ////////////////////////////////////////////////////////////////////////////////////////////////////
2986 //
2987 // transformation interface for StarOfficeAPI. This implements support for
2988 // homogen 3x3 matrices containing the transformation of the SdrObject. At the
2989 // moment it contains a shearX, rotation and translation, but for setting all linear
2990 // transforms like Scale, ShearX, ShearY, Rotate and Translate are supported.
2991 //
2992 ////////////////////////////////////////////////////////////////////////////////////////////////////
2993 // gets base transformation and rectangle of object. If it's an SdrPathObj it fills the PolyPolygon
2994 // with the base geometry and returns TRUE. Otherwise it returns FALSE.
2995 sal_Bool SdrObject::TRGetBaseGeometry(basegfx::B2DHomMatrix& rMatrix, basegfx::B2DPolyPolygon& /*rPolyPolygon*/) const
2996 {
2997 	// any kind of SdrObject, just use SnapRect
2998 	Rectangle aRectangle(GetSnapRect());
2999 
3000 	// convert to transformation values
3001 	basegfx::B2DTuple aScale(aRectangle.GetWidth(), aRectangle.GetHeight());
3002 	basegfx::B2DTuple aTranslate(aRectangle.Left(), aRectangle.Top());
3003 
3004 	// position maybe relative to anchorpos, convert
3005 	if( pModel && pModel->IsWriter() )
3006 	{
3007 		if(GetAnchorPos().X() || GetAnchorPos().Y())
3008 		{
3009 			aTranslate -= basegfx::B2DTuple(GetAnchorPos().X(), GetAnchorPos().Y());
3010 		}
3011 	}
3012 
3013 	// force MapUnit to 100th mm
3014 	SfxMapUnit eMapUnit = GetObjectItemSet().GetPool()->GetMetric(0);
3015 	if(eMapUnit != SFX_MAPUNIT_100TH_MM)
3016 	{
3017 		switch(eMapUnit)
3018 		{
3019 			case SFX_MAPUNIT_TWIP :
3020 			{
3021 				// postion
3022 				aTranslate.setX(ImplTwipsToMM(aTranslate.getX()));
3023 				aTranslate.setY(ImplTwipsToMM(aTranslate.getY()));
3024 
3025 				// size
3026 				aScale.setX(ImplTwipsToMM(aScale.getX()));
3027 				aScale.setY(ImplTwipsToMM(aScale.getY()));
3028 
3029 				break;
3030 			}
3031 			default:
3032 			{
3033 				DBG_ERROR("TRGetBaseGeometry: Missing unit translation to 100th mm!");
3034 			}
3035 		}
3036 	}
3037 
3038 	// build matrix
3039 	rMatrix = basegfx::tools::createScaleTranslateB2DHomMatrix(aScale, aTranslate);
3040 
3041 	return sal_False;
3042 }
3043 
3044 // sets the base geometry of the object using infos contained in the homogen 3x3 matrix.
3045 // If it's an SdrPathObj it will use the provided geometry information. The Polygon has
3046 // to use (0,0) as upper left and will be scaled to the given size in the matrix.
3047 void SdrObject::TRSetBaseGeometry(const basegfx::B2DHomMatrix& rMatrix, const basegfx::B2DPolyPolygon& /*rPolyPolygon*/)
3048 {
3049 	// break up matrix
3050 	basegfx::B2DTuple aScale;
3051 	basegfx::B2DTuple aTranslate;
3052 	double fRotate, fShearX;
3053 	rMatrix.decompose(aScale, aTranslate, fRotate, fShearX);
3054 
3055 	// #i75086# Old DrawingLayer (GeoStat and geometry) does not support holding negative scalings
3056 	// in X and Y which equal a 180 degree rotation. Recognize it and react accordingly
3057 	if(basegfx::fTools::less(aScale.getX(), 0.0) && basegfx::fTools::less(aScale.getY(), 0.0))
3058 	{
3059 		aScale.setX(fabs(aScale.getX()));
3060 		aScale.setY(fabs(aScale.getY()));
3061 		fRotate = fmod(fRotate + F_PI, F_2PI);
3062 	}
3063 
3064 	// force metric to pool metric
3065 	SfxMapUnit eMapUnit = GetObjectItemSet().GetPool()->GetMetric(0);
3066 	if(eMapUnit != SFX_MAPUNIT_100TH_MM)
3067 	{
3068 		switch(eMapUnit)
3069 		{
3070 			case SFX_MAPUNIT_TWIP :
3071 			{
3072 				// position
3073 				aTranslate.setX(ImplMMToTwips(aTranslate.getX()));
3074 				aTranslate.setY(ImplMMToTwips(aTranslate.getY()));
3075 
3076 				// size
3077 				aScale.setX(ImplMMToTwips(aScale.getX()));
3078 				aScale.setY(ImplMMToTwips(aScale.getY()));
3079 
3080 				break;
3081 			}
3082 			default:
3083 			{
3084 				DBG_ERROR("TRSetBaseGeometry: Missing unit translation to PoolMetric!");
3085 			}
3086 		}
3087 	}
3088 
3089 	// if anchor is used, make position relative to it
3090 	if( pModel && pModel->IsWriter() )
3091 	{
3092 		if(GetAnchorPos().X() || GetAnchorPos().Y())
3093 		{
3094 			aTranslate += basegfx::B2DTuple(GetAnchorPos().X(), GetAnchorPos().Y());
3095 		}
3096 	}
3097 
3098 	// build BaseRect
3099 	Point aPoint(FRound(aTranslate.getX()), FRound(aTranslate.getY()));
3100 	Rectangle aBaseRect(aPoint, Size(FRound(aScale.getX()), FRound(aScale.getY())));
3101 
3102 	// set BaseRect
3103 	SetSnapRect(aBaseRect);
3104 }
3105 
3106 // #116168#
3107 // Give info if object is in destruction
3108 sal_Bool SdrObject::IsInDestruction() const
3109 {
3110 	if(pModel)
3111 		return pModel->IsInDestruction();
3112 	return sal_False;
3113 }
3114 
3115 // return if fill is != XFILL_NONE
3116 bool SdrObject::HasFillStyle() const
3117 {
3118 	return (((const XFillStyleItem&)GetObjectItem(XATTR_FILLSTYLE)).GetValue() != XFILL_NONE);
3119 }
3120 
3121 bool SdrObject::HasLineStyle() const
3122 {
3123 	return (((const XLineStyleItem&)GetObjectItem(XATTR_LINESTYLE)).GetValue() != XLINE_NONE);
3124 }
3125 
3126 
3127 // #i52224#
3128 // on import of OLE object from MS documents the BLIP size might be retrieved,
3129 // the following four methods are used to control it;
3130 // usually this data makes no sence after the import is finished, since the object
3131 // might be resized
3132 
3133 Rectangle SdrObject::GetBLIPSizeRectangle() const
3134 {
3135 	return maBLIPSizeRectangle;
3136 }
3137 
3138 void SdrObject::SetBLIPSizeRectangle( const Rectangle& aRect )
3139 {
3140 	maBLIPSizeRectangle = aRect;
3141 }
3142 
3143 void SdrObject::SetContextWritingMode( const sal_Int16 /*_nContextWritingMode*/ )
3144 {
3145     // this base class does not support different writing modes, so ignore the call
3146 }
3147 
3148 ////////////////////////////////////////////////////////////////////////////////////////////////////
3149 //
3150 //   @@@@  @@@@@  @@@@@@  @@@@@  @@@@   @@@@  @@@@@@  @@@@  @@@@@  @@  @@
3151 //  @@  @@ @@  @@     @@  @@    @@  @@ @@  @@   @@   @@  @@ @@  @@ @@  @@
3152 //  @@  @@ @@  @@     @@  @@    @@  @@ @@       @@   @@  @@ @@  @@ @@  @@
3153 //  @@  @@ @@@@@      @@  @@@@  @@@@@@ @@       @@   @@  @@ @@@@@   @@@@
3154 //  @@  @@ @@  @@     @@  @@    @@  @@ @@       @@   @@  @@ @@  @@   @@
3155 //  @@  @@ @@  @@ @@  @@  @@    @@  @@ @@  @@   @@   @@  @@ @@  @@   @@
3156 //   @@@@  @@@@@   @@@@   @@    @@  @@  @@@@    @@    @@@@  @@  @@   @@
3157 //
3158 ////////////////////////////////////////////////////////////////////////////////////////////////////
3159 
3160 SdrObjFactory::SdrObjFactory(sal_uInt32 nInvent, sal_uInt16 nIdent, SdrPage* pNewPage, SdrModel* pNewModel)
3161 {
3162 	nInventor=nInvent;
3163 	nIdentifier=nIdent;
3164 	pNewObj=NULL;
3165 	pPage=pNewPage;
3166 	pModel=pNewModel;
3167 	pObj=NULL;
3168 	pNewData=NULL;
3169 }
3170 
3171 SdrObjFactory::SdrObjFactory(sal_uInt32 nInvent, sal_uInt16 nIdent, SdrObject* pObj1)
3172 {
3173 	nInventor=nInvent;
3174 	nIdentifier=nIdent;
3175 	pNewObj=NULL;
3176 	pPage=NULL;
3177 	pModel=NULL;
3178 	pObj=pObj1;
3179 	pNewData=NULL;
3180 }
3181 
3182 SdrObject* SdrObjFactory::MakeNewObject(sal_uInt32 nInvent, sal_uInt16 nIdent, SdrPage* pPage, SdrModel* pModel)
3183 {
3184 	if(pModel == NULL && pPage != NULL)
3185 		pModel = pPage->GetModel();
3186 	SdrObject* pObj = NULL;
3187 
3188 	if(nInvent == SdrInventor)
3189 	{
3190 		switch (nIdent)
3191 		{
3192 			case sal_uInt16(OBJ_NONE       ): pObj=new SdrObject;                   break;
3193 			case sal_uInt16(OBJ_GRUP       ): pObj=new SdrObjGroup;                 break;
3194 			case sal_uInt16(OBJ_LINE       ): pObj=new SdrPathObj(OBJ_LINE       ); break;
3195 			case sal_uInt16(OBJ_POLY       ): pObj=new SdrPathObj(OBJ_POLY       ); break;
3196 			case sal_uInt16(OBJ_PLIN       ): pObj=new SdrPathObj(OBJ_PLIN       ); break;
3197 			case sal_uInt16(OBJ_PATHLINE   ): pObj=new SdrPathObj(OBJ_PATHLINE   ); break;
3198 			case sal_uInt16(OBJ_PATHFILL   ): pObj=new SdrPathObj(OBJ_PATHFILL   ); break;
3199 			case sal_uInt16(OBJ_FREELINE   ): pObj=new SdrPathObj(OBJ_FREELINE   ); break;
3200 			case sal_uInt16(OBJ_FREEFILL   ): pObj=new SdrPathObj(OBJ_FREEFILL   ); break;
3201 			case sal_uInt16(OBJ_PATHPOLY   ): pObj=new SdrPathObj(OBJ_POLY       ); break;
3202 			case sal_uInt16(OBJ_PATHPLIN   ): pObj=new SdrPathObj(OBJ_PLIN       ); break;
3203 			case sal_uInt16(OBJ_EDGE       ): pObj=new SdrEdgeObj;                  break;
3204 			case sal_uInt16(OBJ_RECT       ): pObj=new SdrRectObj;                  break;
3205 			case sal_uInt16(OBJ_CIRC       ): pObj=new SdrCircObj(OBJ_CIRC       ); break;
3206 			case sal_uInt16(OBJ_SECT       ): pObj=new SdrCircObj(OBJ_SECT       ); break;
3207 			case sal_uInt16(OBJ_CARC       ): pObj=new SdrCircObj(OBJ_CARC       ); break;
3208 			case sal_uInt16(OBJ_CCUT       ): pObj=new SdrCircObj(OBJ_CCUT       ); break;
3209 			case sal_uInt16(OBJ_TEXT       ): pObj=new SdrRectObj(OBJ_TEXT       ); break;
3210 			case sal_uInt16(OBJ_TEXTEXT    ): pObj=new SdrRectObj(OBJ_TEXTEXT    ); break;
3211 			case sal_uInt16(OBJ_TITLETEXT  ): pObj=new SdrRectObj(OBJ_TITLETEXT  ); break;
3212 			case sal_uInt16(OBJ_OUTLINETEXT): pObj=new SdrRectObj(OBJ_OUTLINETEXT); break;
3213 			case sal_uInt16(OBJ_MEASURE    ): pObj=new SdrMeasureObj;               break;
3214 			case sal_uInt16(OBJ_GRAF       ): pObj=new SdrGrafObj;                  break;
3215 			case sal_uInt16(OBJ_OLE2       ): pObj=new SdrOle2Obj;                  break;
3216 			case sal_uInt16(OBJ_FRAME      ): pObj=new SdrOle2Obj(sal_True);            break;
3217 			case sal_uInt16(OBJ_CAPTION    ): pObj=new SdrCaptionObj;               break;
3218 			case sal_uInt16(OBJ_PAGE       ): pObj=new SdrPageObj;                  break;
3219 			case sal_uInt16(OBJ_UNO        ): pObj=new SdrUnoObj(String());			break;
3220 			case sal_uInt16(OBJ_CUSTOMSHAPE  ): pObj=new SdrObjCustomShape();       break;
3221 			case sal_uInt16(OBJ_MEDIA 	   ): pObj=new SdrMediaObj();           	break;
3222 			case sal_uInt16(OBJ_TABLE	   ): pObj=new ::sdr::table::SdrTableObj(pModel);	break;
3223 		}
3224 	}
3225 
3226 	if(pObj == NULL)
3227 	{
3228 		SdrObjFactory* pFact=new SdrObjFactory(nInvent,nIdent,pPage,pModel);
3229 		SdrLinkList& rLL=ImpGetUserMakeObjHdl();
3230 		unsigned nAnz=rLL.GetLinkCount();
3231 		unsigned i=0;
3232 		while (i<nAnz && pObj==NULL) {
3233 			rLL.GetLink(i).Call((void*)pFact);
3234 			pObj=pFact->pNewObj;
3235 			i++;
3236 		}
3237 		delete pFact;
3238 	}
3239 
3240 	if(pObj == NULL)
3241 	{
3242 		// Na wenn's denn keiner will ...
3243 	}
3244 
3245 	if(pObj != NULL)
3246 	{
3247 		if(pPage != NULL)
3248 			pObj->SetPage(pPage);
3249 		else if(pModel != NULL)
3250 			pObj->SetModel(pModel);
3251 	}
3252 
3253 	return pObj;
3254 }
3255 
3256 SdrObjUserData* SdrObjFactory::MakeNewObjUserData(sal_uInt32 nInvent, sal_uInt16 nIdent, SdrObject* pObj1)
3257 {
3258 	SdrObjUserData* pData=NULL;
3259 	if (nInvent==SdrInventor) {
3260 		switch (nIdent)
3261 		{
3262 			case sal_uInt16(SDRUSERDATA_OBJTEXTLINK) : pData=new ImpSdrObjTextLinkUserData((SdrTextObj*)pObj1); break;
3263 		}
3264 	}
3265 	if (pData==NULL) {
3266 		SdrObjFactory aFact(nInvent,nIdent,pObj1);
3267 		SdrLinkList& rLL=ImpGetUserMakeObjUserDataHdl();
3268 		unsigned nAnz=rLL.GetLinkCount();
3269 		unsigned i=0;
3270 		while (i<nAnz && pData==NULL) {
3271 			rLL.GetLink(i).Call((void*)&aFact);
3272 			pData=aFact.pNewData;
3273 			i++;
3274 		}
3275 	}
3276 	return pData;
3277 }
3278 
3279 void SdrObjFactory::InsertMakeObjectHdl(const Link& rLink)
3280 {
3281 	SdrLinkList& rLL=ImpGetUserMakeObjHdl();
3282 	rLL.InsertLink(rLink);
3283 }
3284 
3285 void SdrObjFactory::RemoveMakeObjectHdl(const Link& rLink)
3286 {
3287 	SdrLinkList& rLL=ImpGetUserMakeObjHdl();
3288 	rLL.RemoveLink(rLink);
3289 }
3290 
3291 void SdrObjFactory::InsertMakeUserDataHdl(const Link& rLink)
3292 {
3293 	SdrLinkList& rLL=ImpGetUserMakeObjUserDataHdl();
3294 	rLL.InsertLink(rLink);
3295 }
3296 
3297 void SdrObjFactory::RemoveMakeUserDataHdl(const Link& rLink)
3298 {
3299 	SdrLinkList& rLL=ImpGetUserMakeObjUserDataHdl();
3300 	rLL.RemoveLink(rLink);
3301 }
3302 
3303 namespace svx
3304 {
3305     ISdrObjectFilter::~ISdrObjectFilter()
3306     {
3307     }
3308 }
3309 
3310 // eof
3311