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