xref: /trunk/main/sw/source/core/draw/dcontact.cxx (revision 26ea3662)
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 // MARKER(update_precomp.py): autogen include statement, do not remove
23 #include "precompiled_sw.hxx"
24 #include "hintids.hxx"
25 #include <editeng/protitem.hxx>
26 #include <editeng/opaqitem.hxx>
27 #include <editeng/ulspitem.hxx>
28 #include <editeng/lrspitem.hxx>
29 #include <svx/svdpage.hxx>
30 #include <svx/svditer.hxx>
31 #include <svx/fmglob.hxx>
32 #include <svx/svdogrp.hxx>
33 #include <svx/svdotext.hxx>
34 #include <svx/svdmodel.hxx>
35 #include <svx/svdpagv.hxx>
36 #include <svx/svdviter.hxx>
37 #include <svx/svdview.hxx>
38 #include <svx/shapepropertynotifier.hxx>
39 #include <svx/sdr/contact/objectcontactofobjlistpainter.hxx>
40 #include <svx/sdr/contact/displayinfo.hxx>
41 #include <fmtornt.hxx>
42 #include <viewimp.hxx>
43 #include <fmtsrnd.hxx>
44 #include <fmtanchr.hxx>
45 #include <node.hxx>
46 #include <fmtcntnt.hxx>
47 #include <pagefrm.hxx>
48 #include <rootfrm.hxx>
49 #include <frmtool.hxx>	// Notify_Background
50 #include <flyfrm.hxx>
51 #include <frmfmt.hxx>
52 #include <dflyobj.hxx>
53 #include <dcontact.hxx>
54 #include <unodraw.hxx>
55 #include <IDocumentDrawModelAccess.hxx>
56 #include <doc.hxx>
57 #include <hints.hxx>
58 #include <txtfrm.hxx>
59 #include <editsh.hxx>
60 #include <docary.hxx>
61 #include <flyfrms.hxx>
62 #include <sortedobjs.hxx>
63 #include <basegfx/matrix/b2dhommatrix.hxx>
64 #include <basegfx/matrix/b2dhommatrixtools.hxx>
65 #include <svx/sdr/contact/viewcontactofvirtobj.hxx>
66 #include <drawinglayer/primitive2d/transformprimitive2d.hxx>
67 #include <svx/sdr/contact/viewobjectcontactofsdrobj.hxx>
68 #include <com/sun/star/text/WritingMode2.hpp>
69 #include <switerator.hxx>
70 #include <algorithm>
71 #include <drawdoc.hxx>
72 
73 using namespace ::com::sun::star;
74 
TYPEINIT1(SwContact,SwClient)75 TYPEINIT1( SwContact, SwClient )
76 TYPEINIT1( SwFlyDrawContact, SwContact )
77 TYPEINIT1( SwDrawContact, SwContact )
78 
79 void setContextWritingMode( SdrObject* pObj, SwFrm* pAnchor )
80 {
81     if( pObj && pAnchor )
82     {
83         short nWritingDirection = text::WritingMode2::LR_TB;
84         if( pAnchor->IsVertical() )
85         {
86             nWritingDirection = text::WritingMode2::TB_RL;
87         } else if( pAnchor->IsRightToLeft() )
88         {
89             nWritingDirection = text::WritingMode2::RL_TB;
90         }
91         pObj->SetContextWritingMode( nWritingDirection );
92     }
93 }
94 
95 
96 //Der Umgekehrte Weg: Sucht das Format zum angegebenen Objekt.
97 //Wenn das Object ein SwVirtFlyDrawObj ist so wird das Format von
98 //selbigem besorgt.
99 //Anderfalls ist es eben ein einfaches Zeichenobjekt. Diese hat einen
100 //UserCall und der ist Client vom gesuchten Format.
101 
FindFrmFmt(SdrObject * pObj)102 SwFrmFmt *FindFrmFmt( SdrObject *pObj )
103 {
104     SwFrmFmt* pRetval = 0L;
105 
106 	if ( pObj->ISA(SwVirtFlyDrawObj) )
107 	{
108        pRetval = ((SwVirtFlyDrawObj*)pObj)->GetFmt();
109 	}
110 	else
111 	{
112         SwDrawContact* pContact = static_cast<SwDrawContact*>(GetUserCall( pObj ));
113         if ( pContact )
114 		{
115 			pRetval = pContact->GetFmt();
116 		}
117 	}
118 /* SJ: after prior consultation with OD we decided to remove this Assertion
119 #if OSL_DEBUG_LEVEL > 1
120     ASSERT( pRetval,
121             "<::FindFrmFmt(..)> - no frame format found for given object. Please inform OD." );
122 #endif
123 */
124     return pRetval;
125 }
126 
HasWrap(const SdrObject * pObj)127 sal_Bool HasWrap( const SdrObject* pObj )
128 {
129     if ( pObj )
130     {
131         const SwFrmFmt* pFmt = ::FindFrmFmt( pObj );
132         if ( pFmt )
133         {
134             return SURROUND_THROUGHT != pFmt->GetSurround().GetSurround();
135         }
136     }
137 
138     return sal_False;
139 }
140 
141 /*****************************************************************************
142  *
143  * GetBoundRect liefert das BoundRect _inklusive_ Abstand des Objekts.
144  *
145  *****************************************************************************/
146 
147 // --> OD 2006-08-15 #i68520# - change naming
GetBoundRectOfAnchoredObj(const SdrObject * pObj)148 SwRect GetBoundRectOfAnchoredObj( const SdrObject* pObj )
149 // <--
150 {
151 	SwRect aRet( pObj->GetCurrentBoundRect() );
152     // --> OD 2006-08-10 #i68520# - call cache of <SwAnchoredObject>
153     SwContact* pContact( GetUserCall( pObj ) );
154     if ( pContact )
155     {
156         const SwAnchoredObject* pAnchoredObj( pContact->GetAnchoredObj( pObj ) );
157         if ( pAnchoredObj )
158         {
159             aRet = pAnchoredObj->GetObjRectWithSpaces();
160         }
161     }
162     // <--
163 	return aRet;
164 }
165 
166 //Liefert den UserCall ggf. vom Gruppenobjekt
167 // OD 2004-03-31 #i26791# - change return type
GetUserCall(const SdrObject * pObj)168 SwContact* GetUserCall( const SdrObject* pObj )
169 {
170     SdrObject *pTmp;
171 	while ( !pObj->GetUserCall() && 0 != (pTmp = pObj->GetUpGroup()) )
172 		pObj = pTmp;
173     ASSERT( !pObj->GetUserCall() || pObj->GetUserCall()->ISA(SwContact),
174             "<::GetUserCall(..)> - wrong type of found object user call." );
175     return static_cast<SwContact*>(pObj->GetUserCall());
176 }
177 
178 // liefert sal_True falls das SrdObject ein Marquee-Object (Lauftext) ist
IsMarqueeTextObj(const SdrObject & rObj)179 sal_Bool IsMarqueeTextObj( const SdrObject& rObj )
180 {
181 	SdrTextAniKind eTKind;
182 	return SdrInventor == rObj.GetObjInventor() &&
183 		OBJ_TEXT == rObj.GetObjIdentifier() &&
184 		( SDRTEXTANI_SCROLL == ( eTKind = ((SdrTextObj&)rObj).GetTextAniKind())
185 		 || SDRTEXTANI_ALTERNATE == eTKind || SDRTEXTANI_SLIDE == eTKind );
186 }
187 
188 /*************************************************************************
189 |*
190 |*	SwContact, Ctor und Dtor
191 |*
192 |*	Ersterstellung		AMA 27.Sep.96 18:13
193 |*	Letzte Aenderung	AMA 27.Sep.96
194 |*
195 |*************************************************************************/
196 
SwContact(SwFrmFmt * pToRegisterIn)197 SwContact::SwContact( SwFrmFmt *pToRegisterIn ) :
198 	SwClient( pToRegisterIn ),
199     // OD 05.09.2003 #112039# - init member <mbInDTOR>
200     mbInDTOR( false )
201 {}
202 
~SwContact()203 SwContact::~SwContact()
204 {
205     // OD 05.09.2003 #112039# - set <mbInDTOR>
206     SetInDTOR();
207 }
208 
209 // OD 05.09.2003 #112039# - accessor for member <mbInDTOR>
IsInDTOR() const210 bool SwContact::IsInDTOR() const
211 {
212     return mbInDTOR;
213 }
214 
215 // OD 05.09.2003 #112039# - accessor to set member <mbInDTOR>
SetInDTOR()216 void SwContact::SetInDTOR()
217 {
218     mbInDTOR = true;
219 }
220 
221 /** method to move drawing object to corresponding visible layer
222 
223     OD 21.08.2003 #i18447#
224 
225     @author OD
226 */
MoveObjToVisibleLayer(SdrObject * _pDrawObj)227 void SwContact::MoveObjToVisibleLayer( SdrObject* _pDrawObj )
228 {
229     // --> OD 2005-06-08 #i46297# - notify background about the arriving of
230     // the object and invalidate its position.
231     const bool bNotify( !GetFmt()->getIDocumentDrawModelAccess()->IsVisibleLayerId( _pDrawObj->GetLayer() ) );
232     // <--
233 
234     _MoveObjToLayer( true, _pDrawObj );
235 
236     // --> OD 2005-05-23 #i46297#
237     if ( bNotify )
238     {
239         SwAnchoredObject* pAnchoredObj = GetAnchoredObj( _pDrawObj );
240         ASSERT( pAnchoredObj,
241                 "<SwContact::MoveObjToInvisibleLayer(..)> - missing anchored object" );
242         if ( pAnchoredObj )
243         {
244             ::setContextWritingMode( _pDrawObj, pAnchoredObj->GetAnchorFrmContainingAnchPos() );
245             // Note: as-character anchored objects aren't registered at a page frame and
246             //       a notification of its background isn't needed.
247             if ( pAnchoredObj->GetPageFrm() )
248             {
249                 ::Notify_Background( _pDrawObj, pAnchoredObj->GetPageFrm(),
250                                      pAnchoredObj->GetObjRect(), PREP_FLY_ARRIVE, sal_True );
251             }
252 
253             pAnchoredObj->InvalidateObjPos();
254         }
255     }
256     // <--
257 }
258 
259 /** method to move drawing object to corresponding invisible layer
260 
261     OD 21.08.2003 #i18447#
262 
263     @author OD
264 */
MoveObjToInvisibleLayer(SdrObject * _pDrawObj)265 void SwContact::MoveObjToInvisibleLayer( SdrObject* _pDrawObj )
266 {
267     // --> OD 2005-06-08 #i46297# - notify background about the leaving of the object.
268     const bool bNotify( GetFmt()->getIDocumentDrawModelAccess()->IsVisibleLayerId( _pDrawObj->GetLayer() ) );
269     // <--
270 
271     _MoveObjToLayer( false, _pDrawObj );
272 
273     // --> OD 2005-05-19 #i46297#
274     if ( bNotify )
275     {
276         SwAnchoredObject* pAnchoredObj = GetAnchoredObj( _pDrawObj );
277         ASSERT( pAnchoredObj,
278                 "<SwContact::MoveObjToInvisibleLayer(..)> - missing anchored object" );
279         // Note: as-character anchored objects aren't registered at a page frame and
280         //       a notification of its background isn't needed.
281         if ( pAnchoredObj && pAnchoredObj->GetPageFrm() )
282         {
283             ::Notify_Background( _pDrawObj, pAnchoredObj->GetPageFrm(),
284                                  pAnchoredObj->GetObjRect(), PREP_FLY_LEAVE, sal_True );
285         }
286     }
287     // <--
288 }
289 
290 /** method to move object to visible/invisible layer
291 
292     OD 21.08.2003 #i18447#
293     implementation for the public method <MoveObjToVisibleLayer(..)>
294     and <MoveObjToInvisibleLayer(..)>
295 
296     @author OD
297 */
_MoveObjToLayer(const bool _bToVisible,SdrObject * _pDrawObj)298 void SwContact::_MoveObjToLayer( const bool _bToVisible,
299                                  SdrObject* _pDrawObj )
300 {
301     if ( !_pDrawObj )
302     {
303         ASSERT( false, "SwDrawContact::_MoveObjToLayer(..) - no drawing object!" );
304         return;
305     }
306 
307     if ( !GetRegisteredIn() )
308     {
309         ASSERT( false, "SwDrawContact::_MoveObjToLayer(..) - no drawing frame format!" );
310         return;
311     }
312 
313     const IDocumentDrawModelAccess* pIDDMA = static_cast<SwFrmFmt*>(GetRegisteredInNonConst())->getIDocumentDrawModelAccess();
314     if ( !pIDDMA )
315     {
316         ASSERT( false, "SwDrawContact::_MoveObjToLayer(..) - no writer document!" );
317         return;
318     }
319 
320     SdrLayerID nToHellLayerId =
321         _bToVisible ? pIDDMA->GetHellId() : pIDDMA->GetInvisibleHellId();
322     SdrLayerID nToHeavenLayerId =
323         _bToVisible ? pIDDMA->GetHeavenId() : pIDDMA->GetInvisibleHeavenId();
324     SdrLayerID nToControlLayerId =
325         _bToVisible ? pIDDMA->GetControlsId() : pIDDMA->GetInvisibleControlsId();
326     SdrLayerID nFromHellLayerId =
327         _bToVisible ? pIDDMA->GetInvisibleHellId() : pIDDMA->GetHellId();
328     SdrLayerID nFromHeavenLayerId =
329         _bToVisible ? pIDDMA->GetInvisibleHeavenId() : pIDDMA->GetHeavenId();
330     SdrLayerID nFromControlLayerId =
331         _bToVisible ? pIDDMA->GetInvisibleControlsId() : pIDDMA->GetControlsId();
332 
333     if ( _pDrawObj->ISA( SdrObjGroup ) )
334     {
335         // determine layer for group object
336         {
337             // proposed layer of a group object is the hell layer
338             SdrLayerID nNewLayerId = nToHellLayerId;
339             if ( ::CheckControlLayer( _pDrawObj ) )
340             {
341                 // it has to be the control layer, if one of the member
342                 // is a control
343                 nNewLayerId = nToControlLayerId;
344             }
345             else if ( _pDrawObj->GetLayer() == pIDDMA->GetHeavenId() ||
346                       _pDrawObj->GetLayer() == pIDDMA->GetInvisibleHeavenId() )
347             {
348                 // it has to be the heaven layer, if method <GetLayer()> reveals
349                 // a heaven layer
350                 nNewLayerId = nToHeavenLayerId;
351             }
352             // set layer at group object, but do *not* broadcast and
353             // no propagation to the members.
354             // Thus, call <NbcSetLayer(..)> at super class
355             _pDrawObj->SdrObject::NbcSetLayer( nNewLayerId );
356         }
357 
358         // call method recursively for group object members
359         const SdrObjList* pLst =
360                 static_cast<SdrObjGroup*>(_pDrawObj)->GetSubList();
361         if ( pLst )
362         {
363             for ( sal_uInt16 i = 0; i < pLst->GetObjCount(); ++i )
364             {
365                 _MoveObjToLayer( _bToVisible, pLst->GetObj( i ) );
366             }
367         }
368     }
369     else
370     {
371         const SdrLayerID nLayerIdOfObj = _pDrawObj->GetLayer();
372         if ( nLayerIdOfObj == nFromHellLayerId )
373         {
374             _pDrawObj->SetLayer( nToHellLayerId );
375         }
376         else if ( nLayerIdOfObj == nFromHeavenLayerId )
377         {
378             _pDrawObj->SetLayer( nToHeavenLayerId );
379         }
380         else if ( nLayerIdOfObj == nFromControlLayerId )
381         {
382             _pDrawObj->SetLayer( nToControlLayerId );
383         }
384     }
385 }
386 
387 // -------------------------------------------------------------------------
388 // OD 2004-01-16 #110582# - some virtual helper methods for information
389 // about the object (Writer fly frame resp. drawing object)
390 
GetCntntAnchorIndex() const391 const SwIndex& SwContact::GetCntntAnchorIndex() const
392 {
393     return GetCntntAnchor().nContent;
394 }
395 
396 /** get minimum order number of anchored objects handled by with contact
397 
398     OD 2004-08-24 #110810#
399 
400     @author
401 */
GetMinOrdNum() const402 sal_uInt32 SwContact::GetMinOrdNum() const
403 {
404     sal_uInt32 nMinOrdNum( SAL_MAX_UINT32 );
405 
406     std::list< SwAnchoredObject* > aObjs;
407     GetAnchoredObjs( aObjs );
408 
409     while ( !aObjs.empty() )
410     {
411         sal_uInt32 nTmpOrdNum = aObjs.back()->GetDrawObj()->GetOrdNum();
412 
413         if ( nTmpOrdNum < nMinOrdNum )
414         {
415             nMinOrdNum = nTmpOrdNum;
416         }
417 
418         aObjs.pop_back();
419     }
420 
421     ASSERT( nMinOrdNum != SAL_MAX_UINT32,
422             "<SwContact::GetMinOrdNum()> - no order number found." );
423     return nMinOrdNum;
424 }
425 
426 /** get maximum order number of anchored objects handled by with contact
427 
428     OD 2004-08-24 #110810#
429 
430     @author
431 */
GetMaxOrdNum() const432 sal_uInt32 SwContact::GetMaxOrdNum() const
433 {
434     sal_uInt32 nMaxOrdNum( 0L );
435 
436     std::list< SwAnchoredObject* > aObjs;
437     GetAnchoredObjs( aObjs );
438 
439     while ( !aObjs.empty() )
440     {
441         sal_uInt32 nTmpOrdNum = aObjs.back()->GetDrawObj()->GetOrdNum();
442 
443         if ( nTmpOrdNum > nMaxOrdNum )
444         {
445             nMaxOrdNum = nTmpOrdNum;
446         }
447 
448         aObjs.pop_back();
449     }
450 
451     return nMaxOrdNum;
452 }
453 // -------------------------------------------------------------------------
454 
455 /*************************************************************************
456 |*
457 |*	SwFlyDrawContact, Ctor und Dtor
458 |*
459 |*	Ersterstellung		OK 23.11.94 18:13
460 |*	Letzte Aenderung	MA 06. Apr. 95
461 |*
462 |*************************************************************************/
463 
SwFlyDrawContact(SwFlyFrmFmt * pToRegisterIn,SdrModel *)464 SwFlyDrawContact::SwFlyDrawContact( SwFlyFrmFmt *pToRegisterIn, SdrModel * ) :
465 	SwContact( pToRegisterIn )
466 {
467     // OD 2004-04-01 #i26791# - class <SwFlyDrawContact> contains the 'master'
468     // drawing object of type <SwFlyDrawObj> on its own.
469     mpMasterObj = new SwFlyDrawObj;
470     mpMasterObj->SetOrdNum( 0xFFFFFFFE );
471     mpMasterObj->SetUserCall( this );
472 }
473 
~SwFlyDrawContact()474 SwFlyDrawContact::~SwFlyDrawContact()
475 {
476     if ( mpMasterObj )
477     {
478         mpMasterObj->SetUserCall( 0 );
479         if ( mpMasterObj->GetPage() )
480             mpMasterObj->GetPage()->RemoveObject( mpMasterObj->GetOrdNum() );
481         delete mpMasterObj;
482     }
483 }
484 
485 // OD 2004-03-29 #i26791#
GetAnchoredObj(const SdrObject * _pSdrObj) const486 const SwAnchoredObject* SwFlyDrawContact::GetAnchoredObj( const SdrObject* _pSdrObj ) const
487 {
488     ASSERT( _pSdrObj,
489             "<SwFlyDrawContact::GetAnchoredObj(..)> - no object provided" );
490     ASSERT( _pSdrObj->ISA(SwVirtFlyDrawObj),
491             "<SwFlyDrawContact::GetAnchoredObj(..)> - wrong object type object provided" );
492     ASSERT( GetUserCall( _pSdrObj ) == const_cast<SwFlyDrawContact*>(this),
493             "<SwFlyDrawContact::GetAnchoredObj(..)> - provided object doesn't belongs to this contact" );
494 
495     const SwAnchoredObject* pRetAnchoredObj = 0L;
496 
497     if ( _pSdrObj && _pSdrObj->ISA(SwVirtFlyDrawObj) )
498     {
499         pRetAnchoredObj = static_cast<const SwVirtFlyDrawObj*>(_pSdrObj)->GetFlyFrm();
500     }
501 
502     return pRetAnchoredObj;
503 }
504 
GetAnchoredObj(SdrObject * _pSdrObj)505 SwAnchoredObject* SwFlyDrawContact::GetAnchoredObj( SdrObject* _pSdrObj )
506 {
507     ASSERT( _pSdrObj,
508             "<SwFlyDrawContact::GetAnchoredObj(..)> - no object provided" );
509     ASSERT( _pSdrObj->ISA(SwVirtFlyDrawObj),
510             "<SwFlyDrawContact::GetAnchoredObj(..)> - wrong object type provided" );
511     ASSERT( GetUserCall( _pSdrObj ) == this,
512             "<SwFlyDrawContact::GetAnchoredObj(..)> - provided object doesn't belongs to this contact" );
513 
514     SwAnchoredObject* pRetAnchoredObj = 0L;
515 
516     if ( _pSdrObj && _pSdrObj->ISA(SwVirtFlyDrawObj) )
517     {
518         pRetAnchoredObj = static_cast<SwVirtFlyDrawObj*>(_pSdrObj)->GetFlyFrm();
519     }
520 
521     return pRetAnchoredObj;
522 }
523 
GetMaster() const524 const SdrObject* SwFlyDrawContact::GetMaster() const
525 {
526     return mpMasterObj;
527 }
528 
GetMaster()529 SdrObject* SwFlyDrawContact::GetMaster()
530 {
531     return mpMasterObj;
532 }
533 
SetMaster(SdrObject * _pNewMaster)534 void SwFlyDrawContact::SetMaster( SdrObject* _pNewMaster )
535 {
536     ASSERT( _pNewMaster->ISA(SwFlyDrawObj),
537             "<SwFlyDrawContact::SetMaster(..)> - wrong type of new master object" );
538     mpMasterObj = static_cast<SwFlyDrawObj *>(_pNewMaster);
539 }
540 
541 /*************************************************************************
542 |*
543 |*	SwFlyDrawContact::Modify()
544 |*
545 |*	Ersterstellung		OK 08.11.94 10:21
546 |*	Letzte Aenderung	MA 06. Dec. 94
547 |*
548 |*************************************************************************/
549 
Modify(const SfxPoolItem *,const SfxPoolItem *)550 void SwFlyDrawContact::Modify( const SfxPoolItem*, const SfxPoolItem * )
551 {
552 }
553 
554 // OD 2004-01-16 #110582# - override method to control Writer fly frames,
555 // which are linked, and to assure that all objects anchored at/inside the
556 // Writer fly frame are also made visible.
MoveObjToVisibleLayer(SdrObject * _pDrawObj)557 void SwFlyDrawContact::MoveObjToVisibleLayer( SdrObject* _pDrawObj )
558 {
559     ASSERT( _pDrawObj->ISA(SwVirtFlyDrawObj),
560             "<SwFlyDrawContact::MoveObjToVisibleLayer(..)> - wrong SdrObject type -> crash" );
561 
562     if ( GetFmt()->getIDocumentDrawModelAccess()->IsVisibleLayerId( _pDrawObj->GetLayer() ) )
563     {
564         // nothing to do
565         return;
566     }
567 
568     SwFlyFrm* pFlyFrm = static_cast<SwVirtFlyDrawObj*>(_pDrawObj)->GetFlyFrm();
569 
570     // --> OD 2005-03-09 #i44464# - consider, that Writer fly frame content
571     // already exists - (e.g. WW8 document is inserted into a existing document).
572     if ( !pFlyFrm->Lower() )
573     {
574         pFlyFrm->InsertColumns();
575         pFlyFrm->Chain( pFlyFrm->AnchorFrm() );
576         pFlyFrm->InsertCnt();
577     }
578     if ( pFlyFrm->GetDrawObjs() )
579     {
580         for ( sal_uInt8 i = 0; i < pFlyFrm->GetDrawObjs()->Count(); ++i)
581         {
582             // --> OD 2004-07-01 #i28701# - consider type of objects in sorted object list.
583             SdrObject* pObj = (*pFlyFrm->GetDrawObjs())[i]->DrawObj();
584             SwContact* pContact = static_cast<SwContact*>(pObj->GetUserCall());
585             pContact->MoveObjToVisibleLayer( pObj );
586         }
587     }
588 
589     // make fly frame visible
590     SwContact::MoveObjToVisibleLayer( _pDrawObj );
591 }
592 
593 // OD 2004-01-16 #110582# - override method to control Writer fly frames,
594 // which are linked, and to assure that all objects anchored at/inside the
595 // Writer fly frame are also made invisible.
MoveObjToInvisibleLayer(SdrObject * _pDrawObj)596 void SwFlyDrawContact::MoveObjToInvisibleLayer( SdrObject* _pDrawObj )
597 {
598     ASSERT( _pDrawObj->ISA(SwVirtFlyDrawObj),
599             "<SwFlyDrawContact::MoveObjToInvisibleLayer(..)> - wrong SdrObject type -> crash" );
600 
601     if ( !GetFmt()->getIDocumentDrawModelAccess()->IsVisibleLayerId( _pDrawObj->GetLayer() ) )
602     {
603         // nothing to do
604         return;
605     }
606 
607     SwFlyFrm* pFlyFrm = static_cast<SwVirtFlyDrawObj*>(_pDrawObj)->GetFlyFrm();
608 
609     pFlyFrm->Unchain();
610     pFlyFrm->DeleteCnt();
611     if ( pFlyFrm->GetDrawObjs() )
612     {
613         for ( sal_uInt8 i = 0; i < pFlyFrm->GetDrawObjs()->Count(); ++i)
614         {
615             // --> OD 2004-07-01 #i28701# - consider type of objects in sorted object list.
616             SdrObject* pObj = (*pFlyFrm->GetDrawObjs())[i]->DrawObj();
617             SwContact* pContact = static_cast<SwContact*>(pObj->GetUserCall());
618             pContact->MoveObjToInvisibleLayer( pObj );
619         }
620     }
621 
622     // make fly frame invisible
623     SwContact::MoveObjToInvisibleLayer( _pDrawObj );
624 }
625 
626 /** get data collection of anchored objects, handled by with contact
627 
628     OD 2004-08-23 #110810#
629 
630     @author
631 */
GetAnchoredObjs(std::list<SwAnchoredObject * > & _roAnchoredObjs) const632 void SwFlyDrawContact::GetAnchoredObjs( std::list<SwAnchoredObject*>& _roAnchoredObjs ) const
633 {
634     const SwFrmFmt* pFmt = GetFmt();
635     SwFlyFrm::GetAnchoredObjects( _roAnchoredObjs, *pFmt );
636 }
637 
638 /*************************************************************************
639 |*
640 |*	SwDrawContact, Ctor+Dtor
641 |*
642 |*	Ersterstellung		MA 09. Jan. 95
643 |*	Letzte Aenderung	MA 22. Jul. 98
644 |*
645 |*************************************************************************/
CheckControlLayer(const SdrObject * pObj)646 bool CheckControlLayer( const SdrObject *pObj )
647 {
648 	if ( FmFormInventor == pObj->GetObjInventor() )
649         return true;
650 	if ( pObj->ISA( SdrObjGroup ) )
651 	{
652 		const SdrObjList *pLst = ((SdrObjGroup*)pObj)->GetSubList();
653 		for ( sal_uInt16 i = 0; i < pLst->GetObjCount(); ++i )
654         {
655             if ( ::CheckControlLayer( pLst->GetObj( i ) ) )
656             {
657                 // OD 21.08.2003 #i18447# - return correct value ;-)
658                 return true;
659             }
660         }
661 	}
662     return false;
663 }
664 
SwDrawContact(SwFrmFmt * pToRegisterIn,SdrObject * pObj)665 SwDrawContact::SwDrawContact( SwFrmFmt* pToRegisterIn, SdrObject* pObj ) :
666     SwContact( pToRegisterIn ),
667     maAnchoredDrawObj(),
668     mbMasterObjCleared( false ),
669     // OD 10.10.2003 #112299#
670     mbDisconnectInProgress( false ),
671     // --> OD 2006-01-18 #129959#
672     mbUserCallActive( false ),
673     // Note: value of <meEventTypeOfCurrentUserCall> isn't of relevance, because
674     //       <mbUserCallActive> is sal_False.
675     meEventTypeOfCurrentUserCall( SDRUSERCALL_MOVEONLY )
676     // <--
677 {
678     // clear list containing 'virtual' drawing objects.
679     maDrawVirtObjs.clear();
680 
681     // --> OD 2004-09-22 #i33909# - assure, that drawing object is inserted
682     // in the drawing page.
683     if ( !pObj->IsInserted() )
684     {
685         pToRegisterIn->getIDocumentDrawModelAccess()->GetDrawModel()->GetPage(0)->
686                                 InsertObject( pObj, pObj->GetOrdNumDirect() );
687     }
688     // <--
689 
690     //Controls muessen immer im Control-Layer liegen. Das gilt auch fuer
691 	//Gruppenobjekte, wenn diese Controls enthalten.
692     if ( ::CheckControlLayer( pObj ) )
693     {
694         // OD 25.06.2003 #108784# - set layer of object to corresponding invisible layer.
695         pObj->SetLayer( pToRegisterIn->getIDocumentDrawModelAccess()->GetInvisibleControlsId() );
696     }
697 
698     // OD 2004-03-29 #i26791#
699     pObj->SetUserCall( this );
700     maAnchoredDrawObj.SetDrawObj( *pObj );
701 
702     // if there already exists an SwXShape for the object, ensure it knows about us, and the SdrObject
703     // FS 2009-04-07 #i99056#
704     SwXShape::AddExistingShapeToFmt( *pObj );
705 }
706 
~SwDrawContact()707 SwDrawContact::~SwDrawContact()
708 {
709     // OD 05.09.2003 #112039# - set <mbInDTOR>
710     SetInDTOR();
711 
712     DisconnectFromLayout();
713 
714     // OD 25.06.2003 #108784# - remove 'master' from drawing page
715     RemoveMasterFromDrawPage();
716 
717     // remove and destroy 'virtual' drawing objects.
718     RemoveAllVirtObjs();
719 
720     if ( !mbMasterObjCleared )
721     {
722         SdrObject* pObject = const_cast< SdrObject* >( maAnchoredDrawObj.GetDrawObj() );
723         SdrObject::Free( pObject );
724     }
725 }
726 
GetTextObjectsFromFmt(std::list<SdrTextObj * > & rTextObjects,SwDoc * pDoc)727 void SwDrawContact::GetTextObjectsFromFmt( std::list<SdrTextObj*>& rTextObjects, SwDoc* pDoc )
728 {
729     for( sal_Int32 n=0; n<pDoc->GetSpzFrmFmts()->Count(); n++ )
730     {
731         SwFrmFmt* pFly = (*pDoc->GetSpzFrmFmts())[n];
732         if( pFly->IsA( TYPE(SwDrawFrmFmt) ) )
733         {
734             std::list<SdrTextObj*> aTextObjs;
735             SwDrawContact* pContact = SwIterator<SwDrawContact,SwFrmFmt>::FirstElement(*pFly);
736             if( pContact )
737             {
738                 SdrObject* pSdrO = pContact->GetMaster();
739                 if ( pSdrO )
740                 {
741                     if ( pSdrO->IsA( TYPE(SdrObjGroup) ) )
742                     {
743                         SdrObjListIter aListIter( *pSdrO, IM_DEEPNOGROUPS );
744                         //iterate inside of a grouped object
745                         while( aListIter.IsMore() )
746                         {
747                             SdrObject* pSdrOElement = aListIter.Next();
748                             if( pSdrOElement && pSdrOElement->IsA( TYPE(SdrTextObj) ) &&
749                                 static_cast<SdrTextObj*>( pSdrOElement)->HasText() )
750                             {
751                                 rTextObjects.push_back((SdrTextObj*) pSdrOElement);
752                             }
753                         }
754                     }
755                     else if( pSdrO->IsA( TYPE(SdrTextObj) ) &&
756                             static_cast<SdrTextObj*>( pSdrO )->HasText() )
757                     {
758                         rTextObjects.push_back((SdrTextObj*) pSdrO);
759                     }
760                 }
761             }
762         }
763     }
764 }
765 
766 // OD 2004-03-29 #i26791#
GetAnchoredObj(const SdrObject * _pSdrObj) const767 const SwAnchoredObject* SwDrawContact::GetAnchoredObj( const SdrObject* _pSdrObj ) const
768 {
769     // handle default parameter value
770     if ( !_pSdrObj )
771     {
772         _pSdrObj = GetMaster();
773     }
774 
775     ASSERT( _pSdrObj,
776             "<SwDrawContact::GetAnchoredObj(..)> - no object provided" );
777     ASSERT( _pSdrObj->ISA(SwDrawVirtObj) ||
778             ( !_pSdrObj->ISA(SdrVirtObj) && !_pSdrObj->ISA(SwDrawVirtObj) ),
779             "<SwDrawContact::GetAnchoredObj(..)> - wrong object type object provided" );
780     ASSERT( GetUserCall( _pSdrObj ) == const_cast<SwDrawContact*>(this) ||
781             _pSdrObj == GetMaster(),
782             "<SwDrawContact::GetAnchoredObj(..)> - provided object doesn't belongs to this contact" );
783 
784     const SwAnchoredObject* pRetAnchoredObj = 0L;
785 
786     if ( _pSdrObj )
787     {
788         if ( _pSdrObj->ISA(SwDrawVirtObj) )
789         {
790             pRetAnchoredObj = static_cast<const SwDrawVirtObj*>(_pSdrObj)->GetAnchoredObj();
791         }
792         else if ( !_pSdrObj->ISA(SdrVirtObj) && !_pSdrObj->ISA(SwDrawVirtObj) )
793         {
794             pRetAnchoredObj = &maAnchoredDrawObj;
795         }
796     }
797 
798     return pRetAnchoredObj;
799 }
800 
GetAnchoredObj(SdrObject * _pSdrObj)801 SwAnchoredObject* SwDrawContact::GetAnchoredObj( SdrObject* _pSdrObj )
802 {
803     // handle default parameter value
804     if ( !_pSdrObj )
805     {
806         _pSdrObj = GetMaster();
807     }
808 
809     ASSERT( _pSdrObj,
810             "<SwDrawContact::GetAnchoredObj(..)> - no object provided" );
811     ASSERT( _pSdrObj->ISA(SwDrawVirtObj) ||
812             ( !_pSdrObj->ISA(SdrVirtObj) && !_pSdrObj->ISA(SwDrawVirtObj) ),
813             "<SwDrawContact::GetAnchoredObj(..)> - wrong object type object provided" );
814     ASSERT( GetUserCall( _pSdrObj ) == this || _pSdrObj == GetMaster(),
815             "<SwDrawContact::GetAnchoredObj(..)> - provided object doesn't belongs to this contact" );
816 
817     SwAnchoredObject* pRetAnchoredObj = 0L;
818 
819     if ( _pSdrObj )
820     {
821         if ( _pSdrObj->ISA(SwDrawVirtObj) )
822         {
823             pRetAnchoredObj = static_cast<SwDrawVirtObj*>(_pSdrObj)->AnchoredObj();
824         }
825         else if ( !_pSdrObj->ISA(SdrVirtObj) && !_pSdrObj->ISA(SwDrawVirtObj) )
826         {
827             pRetAnchoredObj = &maAnchoredDrawObj;
828         }
829     }
830 
831     return pRetAnchoredObj;
832 }
833 
GetMaster() const834 const SdrObject* SwDrawContact::GetMaster() const
835 {
836     return !mbMasterObjCleared
837            ? maAnchoredDrawObj.GetDrawObj()
838            : 0L;
839 }
840 
GetMaster()841 SdrObject* SwDrawContact::GetMaster()
842 {
843     return !mbMasterObjCleared
844            ? maAnchoredDrawObj.DrawObj()
845            : 0L;
846 }
847 
848 // OD 16.05.2003 #108784# - overload <SwContact::SetMaster(..)> in order to
849 // assert, if the 'master' drawing object is replaced.
850 // OD 10.07.2003 #110742# - replace of master object correctly handled, if
851 // handled by method <SwDrawContact::ChangeMasterObject(..)>. Thus, assert
852 // only, if a debug level is given.
SetMaster(SdrObject * _pNewMaster)853 void SwDrawContact::SetMaster( SdrObject* _pNewMaster )
854 {
855     if ( _pNewMaster )
856     {
857 #if OSL_DEBUG_LEVEL > 1
858         ASSERT( false, "debug notification - master replaced!" );
859 #endif
860         maAnchoredDrawObj.SetDrawObj( *_pNewMaster );
861     }
862     else
863     {
864         mbMasterObjCleared = true;
865     }
866 }
867 
GetAnchorFrm(const SdrObject * _pDrawObj) const868 const SwFrm* SwDrawContact::GetAnchorFrm( const SdrObject* _pDrawObj ) const
869 {
870     const SwFrm* pAnchorFrm = 0L;
871     if ( !_pDrawObj ||
872          _pDrawObj == GetMaster() ||
873          ( !_pDrawObj->GetUserCall() &&
874            GetUserCall( _pDrawObj ) == static_cast<const SwContact* const>(this) ) )
875     {
876         pAnchorFrm = maAnchoredDrawObj.GetAnchorFrm();
877     }
878     else if ( _pDrawObj->ISA(SwDrawVirtObj) )
879     {
880         pAnchorFrm = static_cast<const SwDrawVirtObj*>(_pDrawObj)->GetAnchorFrm();
881     }
882     else
883     {
884         ASSERT( false,
885                 "<SwDrawContact::GetAnchorFrm(..)> - unknown drawing object." )
886     }
887 
888     return pAnchorFrm;
889 }
GetAnchorFrm(SdrObject * _pDrawObj)890 SwFrm* SwDrawContact::GetAnchorFrm( SdrObject* _pDrawObj )
891 {
892     SwFrm* pAnchorFrm = 0L;
893     if ( !_pDrawObj ||
894          _pDrawObj == GetMaster() ||
895          ( !_pDrawObj->GetUserCall() &&
896            GetUserCall( _pDrawObj ) == this ) )
897     {
898         pAnchorFrm = maAnchoredDrawObj.AnchorFrm();
899     }
900     else
901     {
902         ASSERT( _pDrawObj->ISA(SwDrawVirtObj),
903                 "<SwDrawContact::GetAnchorFrm(..)> - unknown drawing object." )
904         pAnchorFrm = static_cast<SwDrawVirtObj*>(_pDrawObj)->AnchorFrm();
905     }
906 
907     return pAnchorFrm;
908 }
909 
910 // OD 23.06.2003 #108784# - method to create a new 'virtual' drawing object.
CreateVirtObj()911 SwDrawVirtObj* SwDrawContact::CreateVirtObj()
912 {
913     // determine 'master'
914     SdrObject* pOrgMasterSdrObj = GetMaster();
915 
916     // create 'virtual' drawing object
917     SwDrawVirtObj* pNewDrawVirtObj = new SwDrawVirtObj ( *(pOrgMasterSdrObj), *(this) );
918 
919     // add new 'virtual' drawing object managing data structure
920     maDrawVirtObjs.push_back( pNewDrawVirtObj );
921 
922     return pNewDrawVirtObj;
923 }
924 
925 // OD 23.06.2003 #108784# - destroys a given 'virtual' drawing object.
926 // side effect: 'virtual' drawing object is removed from data structure
927 //              <maDrawVirtObjs>.
DestroyVirtObj(SwDrawVirtObj * _pVirtObj)928 void SwDrawContact::DestroyVirtObj( SwDrawVirtObj* _pVirtObj )
929 {
930     if ( _pVirtObj )
931     {
932         delete _pVirtObj;
933         _pVirtObj = 0;
934     }
935 }
936 
937 // OD 16.05.2003 #108784# - add a 'virtual' drawing object to drawing page.
938 // Use an already created one, which isn't used, or create a new one.
AddVirtObj()939 SwDrawVirtObj* SwDrawContact::AddVirtObj()
940 {
941     SwDrawVirtObj* pAddedDrawVirtObj = 0L;
942 
943     // check, if a disconnected 'virtual' drawing object exist and use it
944     std::list<SwDrawVirtObj*>::const_iterator aFoundVirtObjIter =
945             std::find_if( maDrawVirtObjs.begin(), maDrawVirtObjs.end(),
946                           UsedOrUnusedVirtObjPred( false ) );
947 
948     if ( aFoundVirtObjIter != maDrawVirtObjs.end() )
949     {
950         // use already created, disconnected 'virtual' drawing object
951         pAddedDrawVirtObj = (*aFoundVirtObjIter);
952     }
953     else
954     {
955         // create new 'virtual' drawing object.
956         pAddedDrawVirtObj = CreateVirtObj();
957     }
958     pAddedDrawVirtObj->AddToDrawingPage();
959 
960     return pAddedDrawVirtObj;
961 }
962 
963 // OD 16.05.2003 #108784# - remove 'virtual' drawing objects and destroy them.
RemoveAllVirtObjs()964 void SwDrawContact::RemoveAllVirtObjs()
965 {
966     for ( std::list<SwDrawVirtObj*>::iterator aDrawVirtObjsIter = maDrawVirtObjs.begin();
967           aDrawVirtObjsIter != maDrawVirtObjs.end();
968           ++aDrawVirtObjsIter )
969     {
970         // remove and destroy 'virtual object'
971         SwDrawVirtObj* pDrawVirtObj = (*aDrawVirtObjsIter);
972         pDrawVirtObj->RemoveFromWriterLayout();
973         pDrawVirtObj->RemoveFromDrawingPage();
974         DestroyVirtObj( pDrawVirtObj );
975     }
976     maDrawVirtObjs.clear();
977 }
978 
VirtObjAnchoredAtFrmPred(const SwFrm & _rAnchorFrm)979 SwDrawContact::VirtObjAnchoredAtFrmPred::VirtObjAnchoredAtFrmPred(
980                                                 const SwFrm& _rAnchorFrm )
981     : mpAnchorFrm( &_rAnchorFrm )
982 {
983     if ( mpAnchorFrm->IsCntntFrm() )
984     {
985         const SwCntntFrm* pTmpFrm =
986                             static_cast<const SwCntntFrm*>( mpAnchorFrm );
987         while ( pTmpFrm->IsFollow() )
988         {
989             pTmpFrm = pTmpFrm->FindMaster();
990         }
991         mpAnchorFrm = pTmpFrm;
992     }
993 }
994 
995 // OD 2004-04-14 #i26791# - compare with master frame
operator ()(const SwDrawVirtObj * _pDrawVirtObj)996 bool SwDrawContact::VirtObjAnchoredAtFrmPred::operator() ( const SwDrawVirtObj* _pDrawVirtObj )
997 {
998     const SwFrm* pObjAnchorFrm = _pDrawVirtObj->GetAnchorFrm();
999     if ( pObjAnchorFrm && pObjAnchorFrm->IsCntntFrm() )
1000     {
1001         const SwCntntFrm* pTmpFrm =
1002                             static_cast<const SwCntntFrm*>( pObjAnchorFrm );
1003         while ( pTmpFrm->IsFollow() )
1004         {
1005             pTmpFrm = pTmpFrm->FindMaster();
1006         }
1007         pObjAnchorFrm = pTmpFrm;
1008     }
1009 
1010     return ( pObjAnchorFrm == mpAnchorFrm );
1011 }
1012 
1013 // OD 19.06.2003 #108784# - get drawing object ('master' or 'virtual') by frame.
GetDrawObjectByAnchorFrm(const SwFrm & _rAnchorFrm)1014 SdrObject* SwDrawContact::GetDrawObjectByAnchorFrm( const SwFrm& _rAnchorFrm )
1015 {
1016     SdrObject* pRetDrawObj = 0L;
1017 
1018     // OD 2004-04-14 #i26791# - compare master frames instead of direct frames
1019     const SwFrm* pProposedAnchorFrm = &_rAnchorFrm;
1020     if ( pProposedAnchorFrm->IsCntntFrm() )
1021     {
1022         const SwCntntFrm* pTmpFrm =
1023                             static_cast<const SwCntntFrm*>( pProposedAnchorFrm );
1024         while ( pTmpFrm->IsFollow() )
1025         {
1026             pTmpFrm = pTmpFrm->FindMaster();
1027         }
1028         pProposedAnchorFrm = pTmpFrm;
1029     }
1030 
1031     const SwFrm* pMasterObjAnchorFrm = GetAnchorFrm();
1032     if ( pMasterObjAnchorFrm && pMasterObjAnchorFrm->IsCntntFrm() )
1033     {
1034         const SwCntntFrm* pTmpFrm =
1035                             static_cast<const SwCntntFrm*>( pMasterObjAnchorFrm );
1036         while ( pTmpFrm->IsFollow() )
1037         {
1038             pTmpFrm = pTmpFrm->FindMaster();
1039         }
1040         pMasterObjAnchorFrm = pTmpFrm;
1041     }
1042 
1043     if ( pMasterObjAnchorFrm && pMasterObjAnchorFrm == pProposedAnchorFrm )
1044     {
1045         pRetDrawObj = GetMaster();
1046     }
1047     else
1048     {
1049         std::list<SwDrawVirtObj*>::const_iterator aFoundVirtObjIter =
1050                 std::find_if( maDrawVirtObjs.begin(), maDrawVirtObjs.end(),
1051                               VirtObjAnchoredAtFrmPred( *pProposedAnchorFrm ) );
1052 
1053         if ( aFoundVirtObjIter != maDrawVirtObjs.end() )
1054         {
1055             pRetDrawObj = (*aFoundVirtObjIter);
1056         }
1057     }
1058 
1059     return pRetDrawObj;
1060 }
1061 
1062 /*************************************************************************
1063 |*
1064 |*	SwDrawContact::Changed
1065 |*
1066 |*	Ersterstellung		MA 09. Jan. 95
1067 |*	Letzte Aenderung	MA 29. May. 96
1068 |*
1069 |*************************************************************************/
1070 
1071 // OD 03.07.2003 #108784#
NotifyBackgrdOfAllVirtObjs(const Rectangle * pOldBoundRect)1072 void SwDrawContact::NotifyBackgrdOfAllVirtObjs( const Rectangle* pOldBoundRect )
1073 {
1074     for ( std::list<SwDrawVirtObj*>::iterator aDrawVirtObjIter = maDrawVirtObjs.begin();
1075           aDrawVirtObjIter != maDrawVirtObjs.end();
1076           ++aDrawVirtObjIter )
1077     {
1078         SwDrawVirtObj* pDrawVirtObj = (*aDrawVirtObjIter);
1079         if ( pDrawVirtObj->GetAnchorFrm() )
1080         {
1081             // --> OD 2004-10-21 #i34640# - determine correct page frame
1082             SwPageFrm* pPage = pDrawVirtObj->AnchoredObj()->FindPageFrmOfAnchor();
1083             // <--
1084             if( pOldBoundRect && pPage )
1085             {
1086                 SwRect aOldRect( *pOldBoundRect );
1087                 aOldRect.Pos() += pDrawVirtObj->GetOffset();
1088                 if( aOldRect.HasArea() )
1089                     ::Notify_Background( pDrawVirtObj, pPage,
1090                                          aOldRect, PREP_FLY_LEAVE,sal_True);
1091             }
1092             // --> OD 2004-10-21 #i34640# - include spacing for wrapping
1093             SwRect aRect( pDrawVirtObj->GetAnchoredObj()->GetObjRectWithSpaces() );
1094             // <--
1095             if( aRect.HasArea() )
1096             {
1097                 // --> OD 2004-10-21 #i34640# - simplify
1098                 SwPageFrm* pPg = (SwPageFrm*)::FindPage( aRect, pPage );
1099                 // <--
1100                 if ( pPg )
1101                     ::Notify_Background( pDrawVirtObj, pPg, aRect,
1102                                          PREP_FLY_ARRIVE, sal_True );
1103             }
1104             ::ClrContourCache( pDrawVirtObj );
1105         }
1106     }
1107 }
1108 
1109 // OD 2004-04-08 #i26791# - local method to notify the background for a drawing object
lcl_NotifyBackgroundOfObj(SwDrawContact & _rDrawContact,const SdrObject & _rObj,const Rectangle * _pOldObjRect)1110 void lcl_NotifyBackgroundOfObj( SwDrawContact& _rDrawContact,
1111                                 const SdrObject& _rObj,
1112                                 const Rectangle* _pOldObjRect )
1113 {
1114     // --> OD 2004-10-21 #i34640#
1115     SwAnchoredObject* pAnchoredObj =
1116         const_cast<SwAnchoredObject*>(_rDrawContact.GetAnchoredObj( &_rObj ));
1117     if ( pAnchoredObj && pAnchoredObj->GetAnchorFrm() )
1118     // <--
1119     {
1120         // --> OD 2004-10-21 #i34640# - determine correct page frame
1121         SwPageFrm* pPageFrm = pAnchoredObj->FindPageFrmOfAnchor();
1122         // <--
1123         if( _pOldObjRect && pPageFrm )
1124         {
1125             SwRect aOldRect( *_pOldObjRect );
1126             if( aOldRect.HasArea() )
1127             {
1128                 // --> OD 2004-10-21 #i34640# - determine correct page frame
1129                 SwPageFrm* pOldPageFrm = (SwPageFrm*)::FindPage( aOldRect, pPageFrm );
1130                 // <--
1131                 ::Notify_Background( &_rObj, pOldPageFrm, aOldRect,
1132                                      PREP_FLY_LEAVE, sal_True);
1133             }
1134         }
1135         // --> OD 2004-10-21 #i34640# - include spacing for wrapping
1136         SwRect aNewRect( pAnchoredObj->GetObjRectWithSpaces() );
1137         // <--
1138         if( aNewRect.HasArea() && pPageFrm )
1139         {
1140             pPageFrm = (SwPageFrm*)::FindPage( aNewRect, pPageFrm );
1141             ::Notify_Background( &_rObj, pPageFrm, aNewRect,
1142                                  PREP_FLY_ARRIVE, sal_True );
1143         }
1144         ClrContourCache( &_rObj );
1145     }
1146 }
1147 
Changed(const SdrObject & rObj,SdrUserCallType eType,const Rectangle & rOldBoundRect)1148 void SwDrawContact::Changed( const SdrObject& rObj,
1149                              SdrUserCallType eType,
1150                              const Rectangle& rOldBoundRect )
1151 {
1152     // OD 2004-06-01 #i26791# - no event handling, if existing <ViewShell>
1153     // is in construction
1154     SwDoc* pDoc = GetFmt()->GetDoc();
1155     if ( pDoc->GetCurrentViewShell() &&
1156          pDoc->GetCurrentViewShell()->IsInConstructor() )
1157     {
1158         return;
1159     }
1160 
1161     // --> OD 2005-03-08 #i44339#
1162     // no event handling, if document is in destruction.
1163     // Exception: It's the SDRUSERCALL_DELETE event
1164     if ( pDoc->IsInDtor() && eType != SDRUSERCALL_DELETE )
1165     {
1166         return;
1167     }
1168     // <--
1169 
1170     //Action aufsetzen, aber nicht wenn gerade irgendwo eine Action laeuft.
1171 	ViewShell *pSh = 0, *pOrg;
1172 	SwRootFrm *pTmpRoot = pDoc->GetCurrentLayout();//swmod 080317
1173 	if ( pTmpRoot && pTmpRoot->IsCallbackActionEnabled() )
1174 	{
1175 		pDoc->GetEditShell( &pOrg );
1176 		pSh = pOrg;
1177 		if ( pSh )
1178 			do
1179 			{   if ( pSh->Imp()->IsAction() || pSh->Imp()->IsIdleAction() )
1180 					pSh = 0;
1181 				else
1182 					pSh = (ViewShell*)pSh->GetNext();
1183 
1184 			} while ( pSh && pSh != pOrg );
1185 
1186 		if ( pSh )
1187 			pTmpRoot->StartAllAction();
1188 	}
1189 	SdrObjUserCall::Changed( rObj, eType, rOldBoundRect );
1190     _Changed( rObj, eType, &rOldBoundRect );    //Achtung, ggf. Suizid!
1191 
1192 	if ( pSh )
1193 		pTmpRoot->EndAllAction();
1194 }
1195 
1196 // --> OD 2006-01-18 #129959#
1197 // helper class for method <SwDrawContact::_Changed(..)> for handling nested
1198 // <SdrObjUserCall> events
1199 class NestedUserCallHdl
1200 {
1201     private:
1202         SwDrawContact* mpDrawContact;
1203         bool mbParentUserCallActive;
1204         SdrUserCallType meParentUserCallEventType;
1205 
1206     public:
NestedUserCallHdl(SwDrawContact * _pDrawContact,SdrUserCallType _eEventType)1207         NestedUserCallHdl( SwDrawContact* _pDrawContact,
1208                            SdrUserCallType _eEventType )
1209             : mpDrawContact( _pDrawContact ),
1210               mbParentUserCallActive( _pDrawContact->mbUserCallActive ),
1211               meParentUserCallEventType( _pDrawContact->meEventTypeOfCurrentUserCall )
1212         {
1213             mpDrawContact->mbUserCallActive = true;
1214             mpDrawContact->meEventTypeOfCurrentUserCall = _eEventType;
1215         }
1216 
~NestedUserCallHdl()1217         ~NestedUserCallHdl()
1218         {
1219             if ( mpDrawContact )
1220             {
1221                 mpDrawContact->mbUserCallActive = mbParentUserCallActive;
1222                 mpDrawContact->meEventTypeOfCurrentUserCall = meParentUserCallEventType;
1223             }
1224         }
1225 
DrawContactDeleted()1226         void DrawContactDeleted()
1227         {
1228             mpDrawContact = 0;
1229         }
1230 
IsNestedUserCall()1231         bool IsNestedUserCall()
1232         {
1233             return mbParentUserCallActive;
1234         }
1235 
AssertNestedUserCall()1236         void AssertNestedUserCall()
1237         {
1238             if ( IsNestedUserCall() )
1239             {
1240                 bool bTmpAssert( true );
1241                 // Currently its known, that a nested event SDRUSERCALL_RESIZE
1242                 // could occur during parent user call SDRUSERCALL_INSERTED,
1243                 // SDRUSERCALL_DELETE and SDRUSERCALL_RESIZE for edge objects.
1244                 // Also possible are nested SDRUSERCALL_CHILD_RESIZE events for
1245                 // edge objects
1246                 // Thus, assert all other combinations
1247                 if ( ( meParentUserCallEventType == SDRUSERCALL_INSERTED ||
1248                        meParentUserCallEventType == SDRUSERCALL_DELETE ||
1249                        meParentUserCallEventType == SDRUSERCALL_RESIZE ) &&
1250                      mpDrawContact->meEventTypeOfCurrentUserCall == SDRUSERCALL_RESIZE )
1251                 {
1252                     bTmpAssert = false;
1253                 }
1254                 else if ( meParentUserCallEventType == SDRUSERCALL_CHILD_RESIZE &&
1255                           mpDrawContact->meEventTypeOfCurrentUserCall == SDRUSERCALL_CHILD_RESIZE )
1256                 {
1257                     bTmpAssert = false;
1258                 }
1259 
1260                 if ( bTmpAssert )
1261                 {
1262                     ASSERT( false,
1263                             "<SwDrawContact::_Changed(..)> - unknown nested <UserCall> event. This is serious, please inform OD." );
1264                 }
1265             }
1266         }
1267 };
1268 
1269 // <--
1270 //
1271 // !!!ACHTUNG!!! The object may commit suicide!!!
1272 //
_Changed(const SdrObject & rObj,SdrUserCallType eType,const Rectangle * pOldBoundRect)1273 void SwDrawContact::_Changed( const SdrObject& rObj,
1274                               SdrUserCallType eType,
1275                               const Rectangle* pOldBoundRect )
1276 {
1277     // --> OD 2006-01-18 #129959#
1278     // suppress handling of nested <SdrObjUserCall> events
1279     NestedUserCallHdl aNestedUserCallHdl( this, eType );
1280     if ( aNestedUserCallHdl.IsNestedUserCall() )
1281     {
1282         aNestedUserCallHdl.AssertNestedUserCall();
1283         return;
1284     }
1285     // <--
1286     // OD 05.08.2002 #100843# - do *not* notify, if document is destructing
1287     // --> OD 2004-10-21 #i35912# - do *not* notify for as-character anchored
1288     // drawing objects.
1289     // --> OD 2004-11-11 #i35007#
1290     // improvement: determine as-character anchored object flag only once.
1291     const bool bAnchoredAsChar = ObjAnchoredAsChar();
1292     // <--
1293     const bool bNotify = !(GetFmt()->GetDoc()->IsInDtor()) &&
1294                          ( SURROUND_THROUGHT != GetFmt()->GetSurround().GetSurround() ) &&
1295                          !bAnchoredAsChar;
1296     // <--
1297 	switch( eType )
1298 	{
1299 		case SDRUSERCALL_DELETE:
1300 			{
1301                 if ( bNotify )
1302                 {
1303                     lcl_NotifyBackgroundOfObj( *this, rObj, pOldBoundRect );
1304                     // --> OD 2004-10-27 #i36181# - background of 'virtual'
1305                     // drawing objects have also been notified.
1306                     NotifyBackgrdOfAllVirtObjs( pOldBoundRect );
1307                     // <--
1308                 }
1309                 DisconnectFromLayout( false );
1310 				SetMaster( NULL );
1311 				delete this;
1312                 // --> FME 2006-07-12 #i65784# Prevent memory corruption
1313                 aNestedUserCallHdl.DrawContactDeleted();
1314                 // <--
1315 				break;
1316 			}
1317 		case SDRUSERCALL_INSERTED:
1318 			{
1319                 // OD 10.10.2003 #112299#
1320                 if ( mbDisconnectInProgress )
1321                 {
1322                     ASSERT( false,
1323                             "<SwDrawContact::_Changed(..)> - Insert event during disconnection from layout is invalid." );
1324                 }
1325                 else
1326                 {
1327                     ConnectToLayout();
1328                     if ( bNotify )
1329                     {
1330                         lcl_NotifyBackgroundOfObj( *this, rObj, pOldBoundRect );
1331                     }
1332                 }
1333 				break;
1334 			}
1335 		case SDRUSERCALL_REMOVED:
1336 			{
1337                 if ( bNotify )
1338                 {
1339                     lcl_NotifyBackgroundOfObj( *this, rObj, pOldBoundRect );
1340                 }
1341                 DisconnectFromLayout( false );
1342 				break;
1343 			}
1344         case SDRUSERCALL_CHILD_INSERTED :
1345         case SDRUSERCALL_CHILD_REMOVED :
1346         {
1347             // --> AW, OD 2010-09-13 #i113730#
1348             // force layer of controls for group objects containing control objects
1349             if(dynamic_cast< SdrObjGroup* >(maAnchoredDrawObj.DrawObj()))
1350             {
1351                 if(::CheckControlLayer(maAnchoredDrawObj.DrawObj()))
1352                 {
1353                     const IDocumentDrawModelAccess* pIDDMA = static_cast<SwFrmFmt*>(GetRegisteredInNonConst())->getIDocumentDrawModelAccess();
1354                     const SdrLayerID aCurrentLayer(maAnchoredDrawObj.DrawObj()->GetLayer());
1355                     const SdrLayerID aControlLayerID(pIDDMA->GetControlsId());
1356                     const SdrLayerID aInvisibleControlLayerID(pIDDMA->GetInvisibleControlsId());
1357 
1358                     if(aCurrentLayer != aControlLayerID && aCurrentLayer != aInvisibleControlLayerID)
1359                     {
1360                         if ( aCurrentLayer == pIDDMA->GetInvisibleHellId() ||
1361                              aCurrentLayer == pIDDMA->GetInvisibleHeavenId() )
1362                         {
1363                             maAnchoredDrawObj.DrawObj()->SetLayer(aInvisibleControlLayerID);
1364                         }
1365                         else
1366                         {
1367                             maAnchoredDrawObj.DrawObj()->SetLayer(aControlLayerID);
1368                         }
1369                     }
1370                 }
1371             }
1372             // fallthrough intended here
1373             // <--
1374         }
1375         case SDRUSERCALL_MOVEONLY:
1376 		case SDRUSERCALL_RESIZE:
1377 		case SDRUSERCALL_CHILD_MOVEONLY :
1378 		case SDRUSERCALL_CHILD_RESIZE :
1379 		case SDRUSERCALL_CHILD_CHGATTR :
1380 		case SDRUSERCALL_CHILD_DELETE :
1381 		case SDRUSERCALL_CHILD_COPY :
1382         {
1383             // --> OD 2004-08-04 #i31698# - improvement:
1384             // get instance <SwAnchoredDrawObject> only once
1385             const SwAnchoredDrawObject* pAnchoredDrawObj =
1386                 static_cast<const SwAnchoredDrawObject*>( GetAnchoredObj( &rObj ) );
1387             // <--
1388             // OD 2004-04-06 #i26791# - adjust positioning and alignment attributes,
1389             // if positioning of drawing object isn't in progress.
1390             // --> OD 2005-08-15 #i53320# - no adjust of positioning attributes,
1391             // if drawing object isn't positioned.
1392             if ( !pAnchoredDrawObj->IsPositioningInProgress() &&
1393                  !pAnchoredDrawObj->NotYetPositioned() )
1394             // <--
1395             {
1396                 // --> OD 2004-09-29 #i34748# - If no last object rectangle is
1397                 // provided by the anchored object, use parameter <pOldBoundRect>.
1398                 const Rectangle& aOldObjRect = pAnchoredDrawObj->GetLastObjRect()
1399                                                ? *(pAnchoredDrawObj->GetLastObjRect())
1400                                                : *(pOldBoundRect);
1401                 // <--
1402                 // --> OD 2008-02-18 #i79400#
1403                 // always invalidate object rectangle inclusive spaces
1404                 pAnchoredDrawObj->InvalidateObjRectWithSpaces();
1405                 // <--
1406                 // --> OD 2005-01-28 #i41324# - notify background before
1407                 // adjusting position
1408                 if ( bNotify )
1409                 {
1410                     // --> OD 2004-07-20 #i31573# - correction: Only invalidate
1411                     // background of given drawing object.
1412                     lcl_NotifyBackgroundOfObj( *this, rObj, &aOldObjRect );
1413                 }
1414                 // <--
1415                 // --> OD 2004-08-04 #i31698# - determine layout direction
1416                 // via draw frame format.
1417                 SwFrmFmt::tLayoutDir eLayoutDir =
1418                                 pAnchoredDrawObj->GetFrmFmt().GetLayoutDir();
1419                 // <--
1420                 // use geometry of drawing object
1421                 SwRect aObjRect( rObj.GetSnapRect() );
1422                 // If drawing object is a member of a group, the adjustment
1423                 // of the positioning and the alignment attributes has to
1424                 // be done for the top group object.
1425                 if ( rObj.GetUpGroup() )
1426                 {
1427                     const SdrObject* pGroupObj = rObj.GetUpGroup();
1428                     while ( pGroupObj->GetUpGroup() )
1429                     {
1430                         pGroupObj = pGroupObj->GetUpGroup();
1431                     }
1432                     // use geometry of drawing object
1433                     aObjRect = pGroupObj->GetSnapRect();
1434                 }
1435                 SwTwips nXPosDiff(0L);
1436                 SwTwips nYPosDiff(0L);
1437                 switch ( eLayoutDir )
1438                 {
1439                     case SwFrmFmt::HORI_L2R:
1440                     {
1441                         nXPosDiff = aObjRect.Left() - aOldObjRect.Left();
1442                         nYPosDiff = aObjRect.Top() - aOldObjRect.Top();
1443                     }
1444                     break;
1445                     case SwFrmFmt::HORI_R2L:
1446                     {
1447                         nXPosDiff = aOldObjRect.Right() - aObjRect.Right();
1448                         nYPosDiff = aObjRect.Top() - aOldObjRect.Top();
1449                     }
1450                     break;
1451                     case SwFrmFmt::VERT_R2L:
1452                     {
1453                         nXPosDiff = aObjRect.Top() - aOldObjRect.Top();
1454                         nYPosDiff = aOldObjRect.Right() - aObjRect.Right();
1455                     }
1456                     break;
1457                     default:
1458                     {
1459                         ASSERT( false,
1460                                 "<SwDrawContact::_Changed(..)> - unsupported layout direction" );
1461                     }
1462                 }
1463                 SfxItemSet aSet( GetFmt()->GetDoc()->GetAttrPool(),
1464                                  RES_VERT_ORIENT, RES_HORI_ORIENT, 0 );
1465                 const SwFmtVertOrient& rVert = GetFmt()->GetVertOrient();
1466                 if ( nYPosDiff != 0 )
1467                 {
1468 
1469                     if ( rVert.GetRelationOrient() == text::RelOrientation::CHAR ||
1470                          rVert.GetRelationOrient() == text::RelOrientation::TEXT_LINE )
1471                     {
1472                         nYPosDiff = -nYPosDiff;
1473                     }
1474                     aSet.Put( SwFmtVertOrient( rVert.GetPos()+nYPosDiff,
1475                                                text::VertOrientation::NONE,
1476                                                rVert.GetRelationOrient() ) );
1477                 }
1478 
1479                 const SwFmtHoriOrient& rHori = GetFmt()->GetHoriOrient();
1480                 if ( !bAnchoredAsChar && nXPosDiff != 0 )
1481                 {
1482                     aSet.Put( SwFmtHoriOrient( rHori.GetPos()+nXPosDiff,
1483                                                text::HoriOrientation::NONE,
1484                                                rHori.GetRelationOrient() ) );
1485                 }
1486 
1487                 if ( nYPosDiff ||
1488                      ( !bAnchoredAsChar && nXPosDiff != 0 ) )
1489                 {
1490                     GetFmt()->GetDoc()->SetFlyFrmAttr( *(GetFmt()), aSet );
1491                     // keep new object rectangle, to avoid multiple
1492                     // changes of the attributes by multiple event from
1493                     // the drawing layer - e.g. group objects and its members
1494                     // --> OD 2004-09-29 #i34748# - use new method
1495                     // <SwAnchoredDrawObject::SetLastObjRect(..)>.
1496                     const_cast<SwAnchoredDrawObject*>(pAnchoredDrawObj)
1497                                     ->SetLastObjRect( aObjRect.SVRect() );
1498                 }
1499                 else if ( aObjRect.SSize() != aOldObjRect.GetSize() )
1500                 {
1501                     _InvalidateObjs();
1502                     // --> OD 2004-11-11 #i35007# - notify anchor frame
1503                     // of as-character anchored object
1504                     if ( bAnchoredAsChar )
1505                     {
1506                         //-->Modified for i119654,2012.6.8
1507                         SwFrm* pAnchorFrame = pAnchoredDrawObj
1508                                               ? const_cast<SwAnchoredDrawObject*>( pAnchoredDrawObj )->AnchorFrm()
1509                                               : NULL;
1510                         if ( pAnchorFrame )
1511                         {
1512                             pAnchorFrame->Prepare( PREP_FLY_ATTR_CHG, GetFmt() );
1513                         }
1514                         //<--
1515                     }
1516                     // <--
1517                 }
1518             }
1519             // --> OD 2006-01-18 #129959#
1520             // It reveals that the following code causes several defects -
1521             // on copying or on ungrouping a group shape containing edge objects.
1522             // Testing fix for #i53320# also reveal that the following code
1523             // isn't necessary.
1524 //            // --> OD 2005-08-15 #i53320# - reset positioning attributes,
1525 //            // if anchored drawing object isn't yet positioned.
1526 //            else if ( pAnchoredDrawObj->NotYetPositioned() &&
1527 //                      static_cast<const SwDrawFrmFmt&>(pAnchoredDrawObj->GetFrmFmt()).IsPosAttrSet() )
1528 //            {
1529 //                const_cast<SwDrawFrmFmt&>(
1530 //                    static_cast<const SwDrawFrmFmt&>(pAnchoredDrawObj->GetFrmFmt()))
1531 //                        .ResetPosAttr();
1532 //            }
1533 //            // <--
1534             // <--
1535         }
1536         break;
1537 		case SDRUSERCALL_CHGATTR:
1538             if ( bNotify )
1539             {
1540                 lcl_NotifyBackgroundOfObj( *this, rObj, pOldBoundRect );
1541             }
1542 			break;
1543         default:
1544             break;
1545 	}
1546 }
1547 
1548 namespace
1549 {
lcl_getAnchorFmt(const SfxPoolItem & _rItem)1550     static const SwFmtAnchor* lcl_getAnchorFmt( const SfxPoolItem& _rItem )
1551     {
1552 	    sal_uInt16 nWhich = _rItem.Which();
1553         const SwFmtAnchor* pAnchorFmt = NULL;
1554         if ( RES_ATTRSET_CHG == nWhich )
1555 	    {
1556             static_cast<const SwAttrSetChg&>(_rItem).GetChgSet()->
1557                 GetItemState( RES_ANCHOR, sal_False, (const SfxPoolItem**)&pAnchorFmt );
1558 	    }
1559         else if ( RES_ANCHOR == nWhich )
1560         {
1561             pAnchorFmt = &static_cast<const SwFmtAnchor&>(_rItem);
1562         }
1563         return pAnchorFmt;
1564     }
1565 }
1566 
1567 /*************************************************************************
1568 |*
1569 |*	SwDrawContact::Modify()
1570 |*
1571 |*	Ersterstellung		MA 09. Jan. 95
1572 |*	Letzte Aenderung	MA 03. Dec. 95
1573 |*
1574 |*************************************************************************/
1575 
Modify(const SfxPoolItem * pOld,const SfxPoolItem * pNew)1576 void SwDrawContact::Modify( const SfxPoolItem* pOld, const SfxPoolItem *pNew )
1577 {
1578     // OD 10.10.2003 #112299#
1579     ASSERT( !mbDisconnectInProgress,
1580             "<SwDrawContact::Modify(..)> called during disconnection.");
1581 
1582 	sal_uInt16 nWhich = pNew ? pNew->Which() : 0;
1583     const SwFmtAnchor* pNewAnchorFmt = pNew ? lcl_getAnchorFmt( *pNew ) : NULL;
1584 
1585     if ( pNewAnchorFmt )
1586 	{
1587 		// JP 10.04.95: nicht auf ein Reset Anchor reagieren !!!!!
1588         if ( SFX_ITEM_SET ==
1589                 GetFmt()->GetAttrSet().GetItemState( RES_ANCHOR, sal_False ) )
1590 		{
1591             // OD 10.10.2003 #112299# - no connect to layout during disconnection
1592             if ( !mbDisconnectInProgress )
1593             {
1594                 // determine old object retangle of 'master' drawing object
1595                 // for notification
1596                 const Rectangle* pOldRect = 0L;
1597                 Rectangle aOldRect;
1598                 if ( GetAnchorFrm() )
1599                 {
1600                     // --> OD 2004-10-27 #i36181# - include spacing in object
1601                     // rectangle for notification.
1602                     aOldRect = maAnchoredDrawObj.GetObjRectWithSpaces().SVRect();
1603                     pOldRect = &aOldRect;
1604                     // <--
1605                 }
1606                 // re-connect to layout due to anchor format change
1607                 ConnectToLayout( pNewAnchorFmt );
1608                 // notify background of drawing objects
1609                 lcl_NotifyBackgroundOfObj( *this, *GetMaster(), pOldRect );
1610                 NotifyBackgrdOfAllVirtObjs( pOldRect );
1611 
1612                 const SwFmtAnchor* pOldAnchorFmt = pOld ? lcl_getAnchorFmt( *pOld ) : NULL;
1613                 if ( !pOldAnchorFmt || ( pOldAnchorFmt->GetAnchorId() != pNewAnchorFmt->GetAnchorId() ) )
1614                 {
1615                     ASSERT( maAnchoredDrawObj.DrawObj(), "SwDrawContact::Modify: no draw object here?" );
1616                     if ( maAnchoredDrawObj.DrawObj() )
1617                     {
1618                         // --> OD 2009-07-10 #i102752#
1619                         // assure that a ShapePropertyChangeNotifier exists
1620                         maAnchoredDrawObj.DrawObj()->notifyShapePropertyChange( ::svx::eTextShapeAnchorType );
1621                         // <--
1622                     }
1623                 }
1624             }
1625 		}
1626 		else
1627 			DisconnectFromLayout();
1628 	}
1629     // --> OD 2006-03-17 #i62875# - revised fix for issue #124157#
1630     // no further notification, if not connected to Writer layout
1631     else if ( maAnchoredDrawObj.GetAnchorFrm() &&
1632               maAnchoredDrawObj.GetDrawObj()->GetUserCall() )
1633     {
1634         // --> OD 2004-07-01 #i28701# - on change of wrapping style, hell|heaven layer,
1635         // or wrapping style influence an update of the <SwSortedObjs> list,
1636         // the drawing object is registered in, has to be performed. This is triggered
1637         // by the 1st parameter of method call <_InvalidateObjs(..)>.
1638         if ( RES_SURROUND == nWhich ||
1639              RES_OPAQUE == nWhich ||
1640              RES_WRAP_INFLUENCE_ON_OBJPOS == nWhich ||
1641              ( RES_ATTRSET_CHG == nWhich &&
1642                ( SFX_ITEM_SET == ((SwAttrSetChg*)pNew)->GetChgSet()->GetItemState(
1643                            RES_SURROUND, sal_False ) ||
1644                  SFX_ITEM_SET == ((SwAttrSetChg*)pNew)->GetChgSet()->GetItemState(
1645                            RES_OPAQUE, sal_False ) ||
1646                  SFX_ITEM_SET == ((SwAttrSetChg*)pNew)->GetChgSet()->GetItemState(
1647                            RES_WRAP_INFLUENCE_ON_OBJPOS, sal_False ) ) ) )
1648         {
1649             lcl_NotifyBackgroundOfObj( *this, *GetMaster(), 0L );
1650             NotifyBackgrdOfAllVirtObjs( 0L );
1651             _InvalidateObjs( true );
1652         }
1653         else if ( RES_UL_SPACE == nWhich || RES_LR_SPACE == nWhich ||
1654                   RES_HORI_ORIENT == nWhich || RES_VERT_ORIENT == nWhich ||
1655                   // --> OD 2004-07-01 #i28701# - add attribute 'Follow text flow'
1656                   RES_FOLLOW_TEXT_FLOW == nWhich ||
1657                   ( RES_ATTRSET_CHG == nWhich &&
1658                     ( SFX_ITEM_SET == ((SwAttrSetChg*)pNew)->GetChgSet()->GetItemState(
1659                                 RES_LR_SPACE, sal_False ) ||
1660                       SFX_ITEM_SET == ((SwAttrSetChg*)pNew)->GetChgSet()->GetItemState(
1661                                 RES_UL_SPACE, sal_False ) ||
1662                       SFX_ITEM_SET == ((SwAttrSetChg*)pNew)->GetChgSet()->GetItemState(
1663                                 RES_HORI_ORIENT, sal_False ) ||
1664                       SFX_ITEM_SET == ((SwAttrSetChg*)pNew)->GetChgSet()->GetItemState(
1665                                 RES_VERT_ORIENT, sal_False ) ||
1666                       SFX_ITEM_SET == ((SwAttrSetChg*)pNew)->GetChgSet()->GetItemState(
1667                                 RES_FOLLOW_TEXT_FLOW, sal_False ) ) ) )
1668         {
1669             lcl_NotifyBackgroundOfObj( *this, *GetMaster(), 0L );
1670             NotifyBackgrdOfAllVirtObjs( 0L );
1671             _InvalidateObjs();
1672         }
1673         // --> OD 2004-10-26 #i35443#
1674         else if ( RES_ATTRSET_CHG == nWhich )
1675         {
1676             lcl_NotifyBackgroundOfObj( *this, *GetMaster(), 0L );
1677             NotifyBackgrdOfAllVirtObjs( 0L );
1678             _InvalidateObjs();
1679         }
1680         // <--
1681         else if ( RES_REMOVE_UNO_OBJECT == nWhich )
1682         {
1683             // nothing to do
1684         }
1685 #if OSL_DEBUG_LEVEL > 1
1686         else
1687         {
1688             ASSERT( false,
1689                     "<SwDrawContact::Modify(..)> - unhandled attribute? - please inform od@openoffice.org" );
1690         }
1691 #endif
1692     }
1693 
1694     // --> OD 2005-07-18 #i51474#
1695     GetAnchoredObj( 0L )->ResetLayoutProcessBools();
1696     // <--
1697 }
1698 
1699 // OD 2004-03-31 #i26791#
1700 // --> OD 2004-07-01 #i28701# - added parameter <_bUpdateSortedObjsList>
_InvalidateObjs(const bool _bUpdateSortedObjsList)1701 void SwDrawContact::_InvalidateObjs( const bool _bUpdateSortedObjsList )
1702 {
1703     // invalidate position of existing 'virtual' drawing objects
1704     for ( std::list<SwDrawVirtObj*>::iterator aDisconnectIter = maDrawVirtObjs.begin();
1705           aDisconnectIter != maDrawVirtObjs.end();
1706           ++aDisconnectIter )
1707     {
1708         SwDrawVirtObj* pDrawVirtObj = (*aDisconnectIter);
1709         // --> OD 2004-08-23 #i33313# - invalidation only for connected
1710         // 'virtual' drawing objects
1711         if ( pDrawVirtObj->IsConnected() )
1712         {
1713             pDrawVirtObj->AnchoredObj()->InvalidateObjPos();
1714             // --> OD 2004-07-01 #i28701#
1715             if ( _bUpdateSortedObjsList )
1716             {
1717                 pDrawVirtObj->AnchoredObj()->UpdateObjInSortedList();
1718             }
1719             // <--
1720         }
1721         // <--
1722     }
1723 
1724     // invalidate position of 'master' drawing object
1725     SwAnchoredObject* pAnchoredObj = GetAnchoredObj( 0L );
1726     pAnchoredObj->InvalidateObjPos();
1727     // --> OD 2004-07-01 #i28701#
1728     if ( _bUpdateSortedObjsList )
1729     {
1730         pAnchoredObj->UpdateObjInSortedList();
1731     }
1732     // <--
1733 }
1734 
1735 /*************************************************************************
1736 |*
1737 |*	SwDrawContact::DisconnectFromLayout()
1738 |*
1739 |*	Ersterstellung		MA 09. Jan. 95
1740 |*	Letzte Aenderung	MA 25. Mar. 99
1741 |*
1742 |*************************************************************************/
1743 
DisconnectFromLayout(bool _bMoveMasterToInvisibleLayer)1744 void SwDrawContact::DisconnectFromLayout( bool _bMoveMasterToInvisibleLayer )
1745 {
1746     // OD 10.10.2003 #112299#
1747     mbDisconnectInProgress = true;
1748 
1749     // --> OD 2004-10-27 #i36181# - notify background of drawing object
1750     if ( _bMoveMasterToInvisibleLayer &&
1751          !(GetFmt()->GetDoc()->IsInDtor()) &&
1752          GetAnchorFrm() )
1753     {
1754         const Rectangle aOldRect( maAnchoredDrawObj.GetObjRectWithSpaces().SVRect() );
1755         lcl_NotifyBackgroundOfObj( *this, *GetMaster(), &aOldRect );
1756         NotifyBackgrdOfAllVirtObjs( &aOldRect );
1757     }
1758     // <--
1759 
1760     // OD 16.05.2003 #108784# - remove 'virtual' drawing objects from writer
1761     // layout and from drawing page
1762     for ( std::list<SwDrawVirtObj*>::iterator aDisconnectIter = maDrawVirtObjs.begin();
1763           aDisconnectIter != maDrawVirtObjs.end();
1764           ++aDisconnectIter )
1765     {
1766         SwDrawVirtObj* pDrawVirtObj = (*aDisconnectIter);
1767         pDrawVirtObj->RemoveFromWriterLayout();
1768         pDrawVirtObj->RemoveFromDrawingPage();
1769     }
1770 
1771     if ( maAnchoredDrawObj.GetAnchorFrm() )
1772     {
1773         maAnchoredDrawObj.AnchorFrm()->RemoveDrawObj( maAnchoredDrawObj );
1774     }
1775 
1776     if ( _bMoveMasterToInvisibleLayer && GetMaster() && GetMaster()->IsInserted() )
1777 	{
1778 		SdrViewIter aIter( GetMaster() );
1779 		for( SdrView* pView = aIter.FirstView(); pView;
1780 					pView = aIter.NextView() )
1781         {
1782 			pView->MarkObj( GetMaster(), pView->GetSdrPageView(), sal_True );
1783         }
1784 
1785         // OD 25.06.2003 #108784# - Instead of removing 'master' object from
1786         // drawing page, move the 'master' drawing object into the corresponding
1787         // invisible layer.
1788         {
1789             //((SwFrmFmt*)GetRegisteredIn())->getIDocumentDrawModelAccess()->GetDrawModel()->GetPage(0)->
1790             //                            RemoveObject( GetMaster()->GetOrdNum() );
1791             // OD 21.08.2003 #i18447# - in order to consider group object correct
1792             // use new method <SwDrawContact::MoveObjToInvisibleLayer(..)>
1793             MoveObjToInvisibleLayer( GetMaster() );
1794         }
1795 	}
1796 
1797     // OD 10.10.2003 #112299#
1798     mbDisconnectInProgress = false;
1799 }
1800 
1801 // OD 26.06.2003 #108784# - method to remove 'master' drawing object
1802 // from drawing page.
RemoveMasterFromDrawPage()1803 void SwDrawContact::RemoveMasterFromDrawPage()
1804 {
1805     if ( GetMaster() )
1806     {
1807         GetMaster()->SetUserCall( 0 );
1808         if ( GetMaster()->IsInserted() )
1809         {
1810             ((SwFrmFmt*)GetRegisteredIn())->getIDocumentDrawModelAccess()->GetDrawModel()->GetPage(0)->
1811                                         RemoveObject( GetMaster()->GetOrdNum() );
1812         }
1813     }
1814 }
1815 
1816 // OD 19.06.2003 #108784# - disconnect for a dedicated drawing object -
1817 // could be 'master' or 'virtual'.
1818 // a 'master' drawing object will disconnect a 'virtual' drawing object
1819 // in order to take its place.
1820 // OD 13.10.2003 #i19919# - no special case, if drawing object isn't in
1821 // page header/footer, in order to get drawing objects in repeating table headers
1822 // also working.
DisconnectObjFromLayout(SdrObject * _pDrawObj)1823 void SwDrawContact::DisconnectObjFromLayout( SdrObject* _pDrawObj )
1824 {
1825     if ( _pDrawObj->ISA(SwDrawVirtObj) )
1826     {
1827         SwDrawVirtObj* pDrawVirtObj = static_cast<SwDrawVirtObj*>(_pDrawObj);
1828         pDrawVirtObj->RemoveFromWriterLayout();
1829         pDrawVirtObj->RemoveFromDrawingPage();
1830     }
1831     else
1832     {
1833         std::list<SwDrawVirtObj*>::const_iterator aFoundVirtObjIter =
1834                 std::find_if( maDrawVirtObjs.begin(), maDrawVirtObjs.end(),
1835                               UsedOrUnusedVirtObjPred( true ) );
1836         if ( aFoundVirtObjIter != maDrawVirtObjs.end() )
1837         {
1838             // replace found 'virtual' drawing object by 'master' drawing
1839             // object and disconnect the 'virtual' one
1840             SwDrawVirtObj* pDrawVirtObj = (*aFoundVirtObjIter);
1841             SwFrm* pNewAnchorFrmOfMaster = pDrawVirtObj->AnchorFrm();
1842             // disconnect 'virtual' drawing object
1843             pDrawVirtObj->RemoveFromWriterLayout();
1844             pDrawVirtObj->RemoveFromDrawingPage();
1845             // disconnect 'master' drawing object from current frame
1846             GetAnchorFrm()->RemoveDrawObj( maAnchoredDrawObj );
1847             // re-connect 'master' drawing object to frame of found 'virtual'
1848             // drawing object.
1849             pNewAnchorFrmOfMaster->AppendDrawObj( maAnchoredDrawObj );
1850         }
1851         else
1852         {
1853             // no connected 'virtual' drawing object found. Thus, disconnect
1854             // completely from layout.
1855             DisconnectFromLayout();
1856         }
1857     }
1858 }
1859 
1860 /*************************************************************************
1861 |*
1862 |*	SwDrawContact::ConnectToLayout()
1863 |*
1864 |*	Ersterstellung		MA 09. Jan. 95
1865 |*	Letzte Aenderung	MA 25. Mar. 99
1866 |*
1867 |*************************************************************************/
lcl_GetFlyInCntntAnchor(SwTxtFrm * _pProposedAnchorFrm,const xub_StrLen _nTxtOfs)1868 SwTxtFrm* lcl_GetFlyInCntntAnchor( SwTxtFrm* _pProposedAnchorFrm,
1869                                    const xub_StrLen _nTxtOfs )
1870 {
1871     SwTxtFrm* pAct = _pProposedAnchorFrm;
1872     SwTxtFrm* pTmp;
1873     do
1874     {
1875         pTmp = pAct;
1876         pAct = pTmp->GetFollow();
1877     }
1878     while( pAct && _nTxtOfs >= pAct->GetOfst() );
1879     return pTmp;
1880 }
1881 
ConnectToLayout(const SwFmtAnchor * pAnch)1882 void SwDrawContact::ConnectToLayout( const SwFmtAnchor* pAnch )
1883 {
1884     // OD 10.10.2003 #112299# - *no* connect to layout during disconnection from
1885     // layout.
1886     if ( mbDisconnectInProgress )
1887     {
1888         ASSERT( false,
1889                 "<SwDrawContact::ConnectToLayout(..)> called during disconnection.");
1890         return;
1891     }
1892 
1893     // --> OD 2004-09-22 #i33909# - *no* connect to layout, if 'master' drawing
1894     // object isn't inserted in the drawing page
1895     if ( !GetMaster()->IsInserted() )
1896     {
1897         ASSERT( false, "<SwDrawContact::ConnectToLayout(..)> - master drawing object not inserted -> no connect to layout. Please inform od@openoffice.org" );
1898         return;
1899     }
1900     // <--
1901 
1902     SwFrmFmt* pDrawFrmFmt = (SwFrmFmt*)GetRegisteredIn();
1903 
1904     if( !pDrawFrmFmt->getIDocumentLayoutAccess()->GetCurrentViewShell() )
1905 		return;
1906 
1907     // OD 16.05.2003 #108784# - remove 'virtual' drawing objects from writer
1908     // layout and from drawing page, and remove 'master' drawing object from
1909     // writer layout - 'master' object will remain in drawing page.
1910     DisconnectFromLayout( false );
1911 
1912 	if ( !pAnch )
1913     {
1914         pAnch = &(pDrawFrmFmt->GetAnchor());
1915     }
1916 
1917 	switch ( pAnch->GetAnchorId() )
1918 	{
1919         case FLY_AT_PAGE:
1920                 {
1921                 sal_uInt16 nPgNum = pAnch->GetPageNum();
1922                 ViewShell *pShell = pDrawFrmFmt->getIDocumentLayoutAccess()->GetCurrentViewShell();
1923                 if( !pShell )
1924                     break;
1925                 SwRootFrm* pRoot = pShell->GetLayout();
1926                 SwPageFrm *pPage = static_cast<SwPageFrm*>(pRoot->Lower());
1927 
1928                 for ( sal_uInt16 i = 1; i < nPgNum && pPage; ++i )
1929                 {
1930                     pPage = static_cast<SwPageFrm*>(pPage->GetNext());
1931                 }
1932 
1933                 if ( pPage )
1934                 {
1935                     pPage->AppendDrawObj( maAnchoredDrawObj );
1936                 }
1937                 else
1938                     //Sieht doof aus, ist aber erlaubt (vlg. SwFEShell::SetPageObjsNewPage)
1939                     pRoot->SetAssertFlyPages();
1940                 }
1941                 break;
1942 
1943         case FLY_AT_CHAR:
1944         case FLY_AT_PARA:
1945         case FLY_AT_FLY:
1946         case FLY_AS_CHAR:
1947             {
1948                 if ( pAnch->GetAnchorId() == FLY_AS_CHAR )
1949                 {
1950                     ClrContourCache( GetMaster() );
1951                 }
1952                 // OD 16.05.2003 #108784# - support drawing objects in header/footer,
1953                 // but not control objects:
1954                 // anchor at first found frame the 'master' object and
1955                 // at the following frames 'virtual' drawing objects.
1956                 // Note: method is similar to <SwFlyFrmFmt::MakeFrms(..)>
1957                 SwModify *pModify = 0;
1958                 if( pAnch->GetCntntAnchor() )
1959                 {
1960                     if ( pAnch->GetAnchorId() == FLY_AT_FLY )
1961                     {
1962                         SwNodeIndex aIdx( pAnch->GetCntntAnchor()->nNode );
1963                         SwCntntNode* pCNd = pDrawFrmFmt->GetDoc()->GetNodes().GoNext( &aIdx );
1964                         if ( SwIterator<SwFrm,SwCntntNode>::FirstElement( *pCNd ) )
1965                             pModify = pCNd;
1966                         else
1967                         {
1968                             const SwNodeIndex& rIdx = pAnch->GetCntntAnchor()->nNode;
1969                             SwSpzFrmFmts& rFmts = *(pDrawFrmFmt->GetDoc()->GetSpzFrmFmts());
1970                             for( sal_uInt16 i = 0; i < rFmts.Count(); ++i )
1971                             {
1972                                 SwFrmFmt* pFlyFmt = rFmts[i];
1973                                 if( pFlyFmt->GetCntnt().GetCntntIdx() &&
1974                                     rIdx == *(pFlyFmt->GetCntnt().GetCntntIdx()) )
1975                                 {
1976                                     pModify = pFlyFmt;
1977                                     break;
1978                                 }
1979                             }
1980                         }
1981                         // --> OD 2004-06-15 #i29199# - It is possible, that
1982                         // the anchor doesn't exist - E.g., reordering the
1983                         // sub-documents in a master document.
1984                         // Note: The anchor will be inserted later.
1985                         if ( !pModify )
1986                         {
1987                             // break to end of the current switch case.
1988                             break;
1989                         }
1990                     }
1991                     else
1992                     {
1993                         pModify = pAnch->GetCntntAnchor()->nNode.GetNode().GetCntntNode();
1994                     }
1995                 }
1996                 SwIterator<SwFrm,SwModify> aIter( *pModify );
1997                 SwFrm* pAnchorFrmOfMaster = 0;
1998                 for( SwFrm *pFrm = aIter.First(); pFrm; pFrm = aIter.Next() )
1999                 {
2000                     // append drawing object, if
2001                     // (1) proposed anchor frame isn't a follow and
2002                     // (2) drawing object isn't a control object to be anchored
2003                     //     in header/footer.
2004                     const bool bAdd = ( !pFrm->IsCntntFrm() ||
2005                                         !((SwCntntFrm*)pFrm)->IsFollow() ) &&
2006                                       ( !::CheckControlLayer( GetMaster() ) ||
2007                                         !pFrm->FindFooterOrHeader() );
2008 
2009                     if( bAdd )
2010                     {
2011                         if ( FLY_AT_FLY == pAnch->GetAnchorId() && !pFrm->IsFlyFrm() )
2012                         {
2013                             pFrm = pFrm->FindFlyFrm();
2014                             ASSERT( pFrm,
2015                                     "<SwDrawContact::ConnectToLayout(..)> - missing fly frame -> crash." );
2016                         }
2017 
2018                         // OD 2004-01-20 #110582# - find correct follow for
2019                         // as character anchored objects.
2020                         if ((pAnch->GetAnchorId() == FLY_AS_CHAR) &&
2021                              pFrm->IsTxtFrm() )
2022                         {
2023                             pFrm = lcl_GetFlyInCntntAnchor(
2024                                         static_cast<SwTxtFrm*>(pFrm),
2025                                         pAnch->GetCntntAnchor()->nContent.GetIndex() );
2026                         }
2027 
2028                         if ( !pAnchorFrmOfMaster )
2029                         {
2030                             // append 'master' drawing object
2031                             pAnchorFrmOfMaster = pFrm;
2032                             pFrm->AppendDrawObj( maAnchoredDrawObj );
2033                         }
2034                         else
2035                         {
2036                             // append 'virtual' drawing object
2037                             SwDrawVirtObj* pDrawVirtObj = AddVirtObj();
2038                             if ( pAnch->GetAnchorId() == FLY_AS_CHAR )
2039                             {
2040                                 ClrContourCache( pDrawVirtObj );
2041                             }
2042                             pFrm->AppendDrawObj( *(pDrawVirtObj->AnchoredObj()) );
2043 
2044 							// for repaint, use new ActionChanged()
2045                             // pDrawVirtObj->SendRepaintBroadcast();
2046                             pDrawVirtObj->ActionChanged();
2047                         }
2048 
2049                         if ( pAnch->GetAnchorId() == FLY_AS_CHAR )
2050                         {
2051                             pFrm->InvalidatePrt();
2052                         }
2053                     }
2054                 }
2055 			}
2056 			break;
2057         default:
2058             ASSERT( sal_False, "Unknown Anchor." )
2059             break;
2060     }
2061     if ( GetAnchorFrm() )
2062 	{
2063         ::setContextWritingMode( maAnchoredDrawObj.DrawObj(), GetAnchorFrm() );
2064         // OD 2004-04-01 #i26791# - invalidate objects instead of direct positioning
2065         _InvalidateObjs();
2066 	}
2067 }
2068 
2069 // OD 27.06.2003 #108784# - insert 'master' drawing object into drawing page
InsertMasterIntoDrawPage()2070 void SwDrawContact::InsertMasterIntoDrawPage()
2071 {
2072     if ( !GetMaster()->IsInserted() )
2073     {
2074         GetFmt()->getIDocumentDrawModelAccess()->GetDrawModel()->GetPage(0)
2075                 ->InsertObject( GetMaster(), GetMaster()->GetOrdNumDirect() );
2076     }
2077     GetMaster()->SetUserCall( this );
2078 }
2079 
2080 /*************************************************************************
2081 |*
2082 |*	SwDrawContact::FindPage(), ChkPage()
2083 |*
2084 |*	Ersterstellung		MA 21. Mar. 95
2085 |*	Letzte Aenderung	MA 19. Jul. 96
2086 |*
2087 |*************************************************************************/
2088 
FindPage(const SwRect & rRect)2089 SwPageFrm* SwDrawContact::FindPage( const SwRect &rRect )
2090 {
2091     // --> OD 2004-07-01 #i28701# - use method <GetPageFrm()>
2092     SwPageFrm* pPg = GetPageFrm();
2093     if ( !pPg && GetAnchorFrm() )
2094         pPg = GetAnchorFrm()->FindPageFrm();
2095 	if ( pPg )
2096 		pPg = (SwPageFrm*)::FindPage( rRect, pPg );
2097 	return pPg;
2098 }
2099 
ChkPage()2100 void SwDrawContact::ChkPage()
2101 {
2102     // OD 10.10.2003 #112299#
2103     if ( mbDisconnectInProgress )
2104     {
2105         ASSERT( false,
2106                 "<SwDrawContact::ChkPage()> called during disconnection." );
2107         return;
2108     }
2109 
2110     // --> OD 2004-07-01 #i28701#
2111     SwPageFrm* pPg = ( maAnchoredDrawObj.GetAnchorFrm() &&
2112                        maAnchoredDrawObj.GetAnchorFrm()->IsPageFrm() )
2113                      ? GetPageFrm()
2114                      : FindPage( GetMaster()->GetCurrentBoundRect() );
2115     if ( GetPageFrm() != pPg )
2116 	{
2117         // OD 27.06.2003 #108784# - if drawing object is anchor in header/footer
2118         // a change of the page is a dramatic change. Thus, completely re-connect
2119         // to the layout
2120         if ( maAnchoredDrawObj.GetAnchorFrm() &&
2121              maAnchoredDrawObj.GetAnchorFrm()->FindFooterOrHeader() )
2122         {
2123             ConnectToLayout();
2124         }
2125         else
2126         {
2127             // --> OD 2004-07-01 #i28701# - use methods <GetPageFrm()> and <SetPageFrm>
2128             if ( GetPageFrm() )
2129                 GetPageFrm()->RemoveDrawObjFromPage( maAnchoredDrawObj );
2130             pPg->AppendDrawObjToPage( maAnchoredDrawObj );
2131             SetPageFrm( pPg );
2132         }
2133 	}
2134 }
2135 
2136 /*************************************************************************
2137 |*
2138 |*	SwDrawContact::ChangeMasterObject()
2139 |*
2140 |*	Ersterstellung		MA 07. Aug. 95
2141 |*	Letzte Aenderung	MA 20. Apr. 99
2142 |*
2143 |*************************************************************************/
2144 // OD 10.07.2003 #110742# - Important note:
2145 // method is called by method <SwDPage::ReplaceObject(..)>, which called its
2146 // corresponding superclass method <FmFormPage::ReplaceObject(..)>.
2147 // Note: 'master' drawing object *has* to be connected to layout triggered
2148 //       by the caller of this, if method is called.
ChangeMasterObject(SdrObject * pNewMaster)2149 void SwDrawContact::ChangeMasterObject( SdrObject *pNewMaster )
2150 {
2151     DisconnectFromLayout( false );
2152     // OD 10.07.2003 #110742# - consider 'virtual' drawing objects
2153     RemoveAllVirtObjs();
2154 
2155     GetMaster()->SetUserCall( 0 );
2156 	SetMaster( pNewMaster );
2157 	GetMaster()->SetUserCall( this );
2158 
2159     _InvalidateObjs();
2160 }
2161 
2162 /** get data collection of anchored objects, handled by with contact
2163 
2164     OD 2004-08-23 #110810#
2165 
2166     @author
2167 */
GetAnchoredObjs(std::list<SwAnchoredObject * > & _roAnchoredObjs) const2168 void SwDrawContact::GetAnchoredObjs( std::list<SwAnchoredObject*>& _roAnchoredObjs ) const
2169 {
2170     _roAnchoredObjs.push_back( const_cast<SwAnchoredDrawObject*>(&maAnchoredDrawObj) );
2171 
2172     for ( std::list<SwDrawVirtObj*>::const_iterator aDrawVirtObjsIter = maDrawVirtObjs.begin();
2173           aDrawVirtObjsIter != maDrawVirtObjs.end();
2174           ++aDrawVirtObjsIter )
2175     {
2176         _roAnchoredObjs.push_back( (*aDrawVirtObjsIter)->AnchoredObj() );
2177     }
2178 }
2179 
2180 //////////////////////////////////////////////////////////////////////////////////////
2181 // AW: own sdr::contact::ViewContact (VC) sdr::contact::ViewObjectContact (VOC) needed
2182 // since offset is defined different from SdrVirtObj's sdr::contact::ViewContactOfVirtObj.
2183 // For paint, that offset is used by setting at the OutputDevice; for primitives this is
2184 // not possible since we have no OutputDevice, but define the geometry itself.
2185 
2186 namespace sdr
2187 {
2188 	namespace contact
2189 	{
2190         class VOCOfDrawVirtObj : public ViewObjectContactOfSdrObj
2191 		{
2192 		protected:
2193 			// This method is responsible for creating the graphical visualisation data which is
2194 			// stored/cached in the local primitive. Default gets view-independent Primitive
2195 			// from the ViewContact using ViewContact::getViewIndependentPrimitive2DSequence(), takes care of
2196 			// visibility, handles glue and ghosted.
2197 			// This method will not handle included hierarchies and not check geometric visibility.
2198 			virtual drawinglayer::primitive2d::Primitive2DSequence createPrimitive2DSequence(const DisplayInfo& rDisplayInfo) const;
2199 
2200         public:
VOCOfDrawVirtObj(ObjectContact & rObjectContact,ViewContact & rViewContact)2201 			VOCOfDrawVirtObj(ObjectContact& rObjectContact, ViewContact& rViewContact)
2202             :   ViewObjectContactOfSdrObj(rObjectContact, rViewContact)
2203             {
2204             }
2205 
2206 			virtual ~VOCOfDrawVirtObj();
2207 		};
2208 
2209 		class VCOfDrawVirtObj : public ViewContactOfVirtObj
2210 		{
2211         protected:
2212 			// Create a Object-Specific ViewObjectContact, set ViewContact and
2213 			// ObjectContact. Always needs to return something. Default is to create
2214 			// a standard ViewObjectContact containing the given ObjectContact and *this
2215 			virtual ViewObjectContact& CreateObjectSpecificViewObjectContact(ObjectContact& rObjectContact);
2216 
2217         public:
2218 			// basic constructor, used from SdrObject.
VCOfDrawVirtObj(SwDrawVirtObj & rObj)2219             VCOfDrawVirtObj(SwDrawVirtObj& rObj)
2220             :   ViewContactOfVirtObj(rObj)
2221             {
2222             }
2223 			virtual ~VCOfDrawVirtObj();
2224 
2225             // access to SwDrawVirtObj
GetSwDrawVirtObj() const2226             SwDrawVirtObj& GetSwDrawVirtObj() const
2227             {
2228 			    return (SwDrawVirtObj&)mrObject;
2229             }
2230 		};
2231 	} // end of namespace contact
2232 } // end of namespace sdr
2233 
2234 namespace sdr
2235 {
2236 	namespace contact
2237 	{
2238         // recursively collect primitive data from given VOC with given offset
impAddPrimitivesFromGroup(const ViewObjectContact & rVOC,const basegfx::B2DHomMatrix & rOffsetMatrix,const DisplayInfo & rDisplayInfo,drawinglayer::primitive2d::Primitive2DSequence & rxTarget)2239         void impAddPrimitivesFromGroup(const ViewObjectContact& rVOC, const basegfx::B2DHomMatrix& rOffsetMatrix, const DisplayInfo& rDisplayInfo, drawinglayer::primitive2d::Primitive2DSequence& rxTarget)
2240         {
2241 			const sal_uInt32 nSubHierarchyCount(rVOC.GetViewContact().GetObjectCount());
2242 
2243 			for(sal_uInt32 a(0L); a < nSubHierarchyCount; a++)
2244 			{
2245 				const ViewObjectContact& rCandidate(rVOC.GetViewContact().GetViewContact(a).GetViewObjectContact(rVOC.GetObjectContact()));
2246 
2247                 if(rCandidate.GetViewContact().GetObjectCount())
2248                 {
2249                     // is a group object itself, call resursively
2250                     impAddPrimitivesFromGroup(rCandidate, rOffsetMatrix, rDisplayInfo, rxTarget);
2251                 }
2252                 else
2253                 {
2254                     // single object, add primitives; check model-view visibility
2255 			        if(rCandidate.isPrimitiveVisible(rDisplayInfo))
2256 			        {
2257                         drawinglayer::primitive2d::Primitive2DSequence aNewSequence(rCandidate.getPrimitive2DSequence(rDisplayInfo));
2258 
2259 				        if(aNewSequence.hasElements())
2260 				        {
2261 					        // get ranges
2262 					        const drawinglayer::geometry::ViewInformation2D& rViewInformation2D(rCandidate.GetObjectContact().getViewInformation2D());
2263 					        const basegfx::B2DRange aViewRange(rViewInformation2D.getViewport());
2264 					        basegfx::B2DRange aObjectRange(rCandidate.getObjectRange());
2265 
2266                             // correct with virtual object's offset
2267                             aObjectRange.transform(rOffsetMatrix);
2268 
2269 					        // check geometrical visibility (with offset)
2270 					        if(!aViewRange.overlaps(aObjectRange))
2271 					        {
2272 						        // not visible, release
2273 						        aNewSequence.realloc(0);
2274 					        }
2275 				        }
2276 
2277 				        if(aNewSequence.hasElements())
2278 				        {
2279                             drawinglayer::primitive2d::appendPrimitive2DSequenceToPrimitive2DSequence(rxTarget, aNewSequence);
2280                         }
2281                     }
2282                 }
2283 			}
2284         }
2285 
createPrimitive2DSequence(const DisplayInfo & rDisplayInfo) const2286         drawinglayer::primitive2d::Primitive2DSequence VOCOfDrawVirtObj::createPrimitive2DSequence(const DisplayInfo& rDisplayInfo) const
2287         {
2288 #ifdef DBG_UTIL
2289 			// #i101734#
2290 			static bool bCheckOtherThanTranslate(false);
2291 			static double fShearX(0.0);
2292 			static double fRotation(0.0);
2293 			static double fScaleX(0.0);
2294 			static double fScaleY(0.0);
2295 #endif
2296 
2297 			const VCOfDrawVirtObj& rVC = static_cast< const VCOfDrawVirtObj& >(GetViewContact());
2298             const SdrObject& rReferencedObject = rVC.GetSwDrawVirtObj().GetReferencedObj();
2299 			drawinglayer::primitive2d::Primitive2DSequence xRetval;
2300 
2301 		    // create offset transformation
2302 		    basegfx::B2DHomMatrix aOffsetMatrix;
2303             const Point aLocalOffset(rVC.GetSwDrawVirtObj().GetOffset());
2304 
2305 		    if(aLocalOffset.X() || aLocalOffset.Y())
2306 		    {
2307 #ifdef DBG_UTIL
2308 				// #i101734# added debug code to check more complex transformations
2309 				// than just a translation
2310 				if(bCheckOtherThanTranslate)
2311 				{
2312 					aOffsetMatrix.scale(fScaleX, fScaleY);
2313 					aOffsetMatrix.shearX(tan(fShearX * F_PI180));
2314 					aOffsetMatrix.rotate(fRotation * F_PI180);
2315 				}
2316 #endif
2317 
2318 			    aOffsetMatrix.set(0, 2, aLocalOffset.X());
2319 			    aOffsetMatrix.set(1, 2, aLocalOffset.Y());
2320 
2321 		    }
2322 
2323             if(rReferencedObject.ISA(SdrObjGroup))
2324             {
2325                 // group object. Since the VOC/OC/VC hierarchy does not represent the
2326                 // hierarchy virtual objects when they have group objects
2327                 // (ViewContactOfVirtObj::GetObjectCount() returns null for that purpose)
2328                 // to avoid multiple usages of VOCs (which would not work), the primitives
2329                 // for the sub-hierarchy need to be collected here
2330 
2331                 // Get the VOC of the referenced object (the Group) and fetch primitives from it
2332                 const ViewObjectContact& rVOCOfRefObj = rReferencedObject.GetViewContact().GetViewObjectContact(GetObjectContact());
2333                 impAddPrimitivesFromGroup(rVOCOfRefObj, aOffsetMatrix, rDisplayInfo, xRetval);
2334             }
2335             else
2336             {
2337 			    // single object, use method from referenced object to get the Primitive2DSequence
2338 			    xRetval = rReferencedObject.GetViewContact().getViewIndependentPrimitive2DSequence();
2339             }
2340 
2341             if(xRetval.hasElements())
2342 		    {
2343 			    // create transform primitive
2344 			    const drawinglayer::primitive2d::Primitive2DReference xReference(new drawinglayer::primitive2d::TransformPrimitive2D(aOffsetMatrix, xRetval));
2345                 xRetval = drawinglayer::primitive2d::Primitive2DSequence(&xReference, 1);
2346 		    }
2347 
2348             return xRetval;
2349         }
2350 
~VOCOfDrawVirtObj()2351         VOCOfDrawVirtObj::~VOCOfDrawVirtObj()
2352         {
2353         }
2354 
CreateObjectSpecificViewObjectContact(ObjectContact & rObjectContact)2355 		ViewObjectContact& VCOfDrawVirtObj::CreateObjectSpecificViewObjectContact(ObjectContact& rObjectContact)
2356         {
2357 			return *(new VOCOfDrawVirtObj(rObjectContact, *this));
2358         }
2359 
~VCOfDrawVirtObj()2360         VCOfDrawVirtObj::~VCOfDrawVirtObj()
2361         {
2362         }
2363 	} // end of namespace contact
2364 } // end of namespace sdr
2365 
2366 //////////////////////////////////////////////////////////////////////////////////////
2367 
2368 // =============================================================================
2369 /** implementation of class <SwDrawVirtObj>
2370 
2371     OD 14.05.2003 #108784#
2372 
2373     @author OD
2374 */
2375 
2376 TYPEINIT1(SwDrawVirtObj,SdrVirtObj);
2377 
CreateObjectSpecificViewContact()2378 sdr::contact::ViewContact* SwDrawVirtObj::CreateObjectSpecificViewContact()
2379 {
2380 	return new sdr::contact::VCOfDrawVirtObj(*this);
2381 }
2382 
2383 // #108784#
2384 // implemetation of SwDrawVirtObj
SwDrawVirtObj(SdrObject & _rNewObj,SwDrawContact & _rDrawContact)2385 SwDrawVirtObj::SwDrawVirtObj( SdrObject&        _rNewObj,
2386                               SwDrawContact&    _rDrawContact )
2387     : SdrVirtObj( _rNewObj ),
2388       // OD 2004-03-29 #i26791# - init new member <maAnchoredDrawObj>
2389       maAnchoredDrawObj(),
2390       mrDrawContact( _rDrawContact )
2391 {
2392     // OD 2004-03-29 #i26791#
2393     maAnchoredDrawObj.SetDrawObj( *this );
2394     // --> OD 2004-11-17 #i35635# - set initial position out of sight
2395     NbcMove( Size( -RECT_EMPTY, -RECT_EMPTY ) );
2396     // <--
2397 }
2398 
~SwDrawVirtObj()2399 SwDrawVirtObj::~SwDrawVirtObj()
2400 {}
2401 
operator =(const SdrObject & rObj)2402 void SwDrawVirtObj::operator=( const SdrObject& rObj )
2403 {
2404 	SdrVirtObj::operator=(rObj);
2405     // Note: Members <maAnchoredDrawObj> and <mrDrawContact>
2406     //       haven't to be considered.
2407 }
2408 
Clone() const2409 SdrObject* SwDrawVirtObj::Clone() const
2410 {
2411     SwDrawVirtObj* pObj = new SwDrawVirtObj( rRefObj, mrDrawContact );
2412 
2413     if ( pObj )
2414     {
2415         pObj->operator=(static_cast<const SdrObject&>(*this));
2416         // Note: Member <maAnchoredDrawObj> hasn't to be considered.
2417     }
2418 
2419     return pObj;
2420 }
2421 
2422 // --------------------------------------------------------------------
2423 // connection to writer layout: <GetAnchoredObj()>, <SetAnchorFrm(..)>,
2424 // <GetAnchorFrm()>, <SetPageFrm(..)>, <GetPageFrm()> and <RemoveFromWriterLayout()>
2425 // --------------------------------------------------------------------
GetAnchoredObj() const2426 const SwAnchoredObject* SwDrawVirtObj::GetAnchoredObj() const
2427 {
2428     return &maAnchoredDrawObj;
2429 }
2430 
AnchoredObj()2431 SwAnchoredObject* SwDrawVirtObj::AnchoredObj()
2432 {
2433     return &maAnchoredDrawObj;
2434 }
2435 
GetAnchorFrm() const2436 const SwFrm* SwDrawVirtObj::GetAnchorFrm() const
2437 {
2438     // OD 2004-03-29 #i26791# - use new member <maAnchoredDrawObj>
2439     return maAnchoredDrawObj.GetAnchorFrm();
2440 }
2441 
AnchorFrm()2442 SwFrm* SwDrawVirtObj::AnchorFrm()
2443 {
2444     // OD 2004-03-29 #i26791# - use new member <maAnchoredDrawObj>
2445     return maAnchoredDrawObj.AnchorFrm();
2446 }
2447 
RemoveFromWriterLayout()2448 void SwDrawVirtObj::RemoveFromWriterLayout()
2449 {
2450     // remove contact object from frame for 'virtual' drawing object
2451     // OD 2004-03-29 #i26791# - use new member <maAnchoredDrawObj>
2452     if ( maAnchoredDrawObj.GetAnchorFrm() )
2453     {
2454         maAnchoredDrawObj.AnchorFrm()->RemoveDrawObj( maAnchoredDrawObj );
2455     }
2456 }
2457 
2458 // --------------------------------------------------------------------
2459 // connection to writer layout: <AddToDrawingPage()>, <RemoveFromDrawingPage()>
2460 // --------------------------------------------------------------------
AddToDrawingPage()2461 void SwDrawVirtObj::AddToDrawingPage()
2462 {
2463     // determine 'master'
2464     SdrObject* pOrgMasterSdrObj = mrDrawContact.GetMaster();
2465 
2466     // insert 'virtual' drawing object into page, set layer and user call.
2467     SdrPage* pDrawPg;
2468     // --> OD 2004-08-16 #i27030# - apply order number of referenced object
2469     if ( 0 != ( pDrawPg = pOrgMasterSdrObj->GetPage() ) )
2470     {
2471         // --> OD 2004-08-16 #i27030# - apply order number of referenced object
2472         pDrawPg->InsertObject( this, GetReferencedObj().GetOrdNum() );
2473     }
2474     else
2475     {
2476         pDrawPg = GetPage();
2477         if ( pDrawPg )
2478         {
2479             pDrawPg->SetObjectOrdNum( GetOrdNumDirect(),
2480                                       GetReferencedObj().GetOrdNum() );
2481         }
2482         else
2483         {
2484             SetOrdNum( GetReferencedObj().GetOrdNum() );
2485         }
2486     }
2487     // <--
2488     SetUserCall( &mrDrawContact );
2489 }
2490 
RemoveFromDrawingPage()2491 void SwDrawVirtObj::RemoveFromDrawingPage()
2492 {
2493     SetUserCall( 0 );
2494     if ( GetPage() )
2495     {
2496         GetPage()->RemoveObject( GetOrdNum() );
2497     }
2498 }
2499 
2500 // is 'virtual' drawing object connected to writer layout and to drawing layer.
IsConnected() const2501 bool SwDrawVirtObj::IsConnected() const
2502 {
2503     bool bRetVal = GetAnchorFrm() &&
2504                    ( GetPage() && GetUserCall() );
2505 
2506     return bRetVal;
2507 }
2508 
NbcSetAnchorPos(const Point & rPnt)2509 void SwDrawVirtObj::NbcSetAnchorPos(const Point& rPnt)
2510 {
2511     SdrObject::NbcSetAnchorPos( rPnt );
2512 }
2513 
2514 //////////////////////////////////////////////////////////////////////////////
2515 // #i97197#
2516 // the methods relevant for positioning
2517 
GetCurrentBoundRect() const2518 const Rectangle& SwDrawVirtObj::GetCurrentBoundRect() const
2519 {
2520     if(aOutRect.IsEmpty())
2521     {
2522         const_cast<SwDrawVirtObj*>(this)->RecalcBoundRect();
2523     }
2524 
2525     return aOutRect;
2526 }
2527 
GetLastBoundRect() const2528 const Rectangle& SwDrawVirtObj::GetLastBoundRect() const
2529 {
2530 	return aOutRect;
2531 }
2532 
GetOffset() const2533 const Point SwDrawVirtObj::GetOffset() const
2534 {
2535     // do NOT use IsEmpty() here, there is already a useful offset
2536     // in the position
2537     if(aOutRect == Rectangle())
2538     {
2539         return Point();
2540     }
2541     else
2542     {
2543         return aOutRect.TopLeft() - GetReferencedObj().GetCurrentBoundRect().TopLeft();
2544     }
2545 }
2546 
SetBoundRectDirty()2547 void SwDrawVirtObj::SetBoundRectDirty()
2548 {
2549     // do nothing to not lose model information in aOutRect
2550 }
2551 
RecalcBoundRect()2552 void SwDrawVirtObj::RecalcBoundRect()
2553 {
2554     // OD 2004-04-05 #i26791# - switch order of calling <GetOffset()> and
2555     // <ReferencedObj().GetCurrentBoundRect()>, because <GetOffset()> calculates
2556     // its value by the 'BoundRect' of the referenced object.
2557     //aOutRect = rRefObj.GetCurrentBoundRect();
2558     //aOutRect += GetOffset();
2559 
2560     const Point aOffset(GetOffset());
2561     aOutRect = ReferencedObj().GetCurrentBoundRect() + aOffset;
2562 }
2563 
TakeXorPoly() const2564 basegfx::B2DPolyPolygon SwDrawVirtObj::TakeXorPoly() const
2565 {
2566 	basegfx::B2DPolyPolygon aRetval(rRefObj.TakeXorPoly());
2567 	aRetval.transform(basegfx::tools::createTranslateB2DHomMatrix(GetOffset().X(), GetOffset().Y()));
2568 
2569 	return aRetval;
2570 }
2571 
TakeContour() const2572 basegfx::B2DPolyPolygon SwDrawVirtObj::TakeContour() const
2573 {
2574     basegfx::B2DPolyPolygon aRetval(rRefObj.TakeContour());
2575 	aRetval.transform(basegfx::tools::createTranslateB2DHomMatrix(GetOffset().X(), GetOffset().Y()));
2576 
2577 	return aRetval;
2578 }
2579 
GetHdl(sal_uInt32 nHdlNum) const2580 SdrHdl* SwDrawVirtObj::GetHdl(sal_uInt32 nHdlNum) const
2581 {
2582 	SdrHdl* pHdl = rRefObj.GetHdl(nHdlNum);
2583 
2584     if(pHdl)
2585     {
2586         Point aP(pHdl->GetPos() + GetOffset());
2587         pHdl->SetPos(aP);
2588     }
2589     else
2590     {
2591         OSL_ENSURE(false, "Got no SdrHdl(!)");
2592     }
2593 
2594 	return pHdl;
2595 }
2596 
GetPlusHdl(const SdrHdl & rHdl,sal_uInt16 nPlNum) const2597 SdrHdl* SwDrawVirtObj::GetPlusHdl(const SdrHdl& rHdl, sal_uInt16 nPlNum) const
2598 {
2599 	SdrHdl* pHdl = rRefObj.GetPlusHdl(rHdl, nPlNum);
2600 
2601     if(pHdl)
2602     {
2603         pHdl->SetPos(pHdl->GetPos() + GetOffset());
2604     }
2605     else
2606     {
2607         OSL_ENSURE(false, "Got no SdrHdl(!)");
2608     }
2609 
2610 	return pHdl;
2611 }
2612 
NbcMove(const Size & rSiz)2613 void SwDrawVirtObj::NbcMove(const Size& rSiz)
2614 {
2615     SdrObject::NbcMove( rSiz );
2616 }
2617 
NbcResize(const Point & rRef,const Fraction & xFact,const Fraction & yFact)2618 void SwDrawVirtObj::NbcResize(const Point& rRef, const Fraction& xFact, const Fraction& yFact)
2619 {
2620     rRefObj.NbcResize(rRef - GetOffset(), xFact, yFact);
2621 	SetRectsDirty();
2622 }
2623 
NbcRotate(const Point & rRef,long nWink,double sn,double cs)2624 void SwDrawVirtObj::NbcRotate(const Point& rRef, long nWink, double sn, double cs)
2625 {
2626     rRefObj.NbcRotate(rRef - GetOffset(), nWink, sn, cs);
2627 	SetRectsDirty();
2628 }
2629 
NbcMirror(const Point & rRef1,const Point & rRef2)2630 void SwDrawVirtObj::NbcMirror(const Point& rRef1, const Point& rRef2)
2631 {
2632     rRefObj.NbcMirror(rRef1 - GetOffset(), rRef2 - GetOffset());
2633 	SetRectsDirty();
2634 }
2635 
NbcShear(const Point & rRef,long nWink,double tn,FASTBOOL bVShear)2636 void SwDrawVirtObj::NbcShear(const Point& rRef, long nWink, double tn, FASTBOOL bVShear)
2637 {
2638     rRefObj.NbcShear(rRef - GetOffset(), nWink, tn, bVShear);
2639 	SetRectsDirty();
2640 }
2641 
Move(const Size & rSiz)2642 void SwDrawVirtObj::Move(const Size& rSiz)
2643 {
2644     SdrObject::Move( rSiz );
2645 //    Rectangle aBoundRect0; if(pUserCall) aBoundRect0 = GetLastBoundRect();
2646 //    rRefObj.Move( rSiz );
2647 //    SetRectsDirty();
2648 //    SendUserCall(SDRUSERCALL_RESIZE, aBoundRect0);
2649 }
2650 
Resize(const Point & rRef,const Fraction & xFact,const Fraction & yFact)2651 void SwDrawVirtObj::Resize(const Point& rRef, const Fraction& xFact, const Fraction& yFact)
2652 {
2653 	if(xFact.GetNumerator() != xFact.GetDenominator() || yFact.GetNumerator() != yFact.GetDenominator())
2654 	{
2655 		Rectangle aBoundRect0; if(pUserCall) aBoundRect0 = GetLastBoundRect();
2656         rRefObj.Resize(rRef - GetOffset(), xFact, yFact);
2657 		SetRectsDirty();
2658 		SendUserCall(SDRUSERCALL_RESIZE, aBoundRect0);
2659 	}
2660 }
2661 
Rotate(const Point & rRef,long nWink,double sn,double cs)2662 void SwDrawVirtObj::Rotate(const Point& rRef, long nWink, double sn, double cs)
2663 {
2664 	if(nWink)
2665 	{
2666 		Rectangle aBoundRect0; if(pUserCall) aBoundRect0 = GetLastBoundRect();
2667         rRefObj.Rotate(rRef - GetOffset(), nWink, sn, cs);
2668 		SetRectsDirty();
2669 		SendUserCall(SDRUSERCALL_RESIZE, aBoundRect0);
2670 	}
2671 }
2672 
Mirror(const Point & rRef1,const Point & rRef2)2673 void SwDrawVirtObj::Mirror(const Point& rRef1, const Point& rRef2)
2674 {
2675 	Rectangle aBoundRect0; if(pUserCall) aBoundRect0 = GetLastBoundRect();
2676     rRefObj.Mirror(rRef1 - GetOffset(), rRef2 - GetOffset());
2677 	SetRectsDirty();
2678 	SendUserCall(SDRUSERCALL_RESIZE, aBoundRect0);
2679 }
2680 
Shear(const Point & rRef,long nWink,double tn,FASTBOOL bVShear)2681 void SwDrawVirtObj::Shear(const Point& rRef, long nWink, double tn, FASTBOOL bVShear)
2682 {
2683 	if(nWink)
2684 	{
2685 		Rectangle aBoundRect0; if(pUserCall) aBoundRect0 = GetLastBoundRect();
2686         rRefObj.Shear(rRef - GetOffset(), nWink, tn, bVShear);
2687 		SetRectsDirty();
2688 		SendUserCall(SDRUSERCALL_RESIZE, aBoundRect0);
2689 	}
2690 }
2691 
RecalcSnapRect()2692 void SwDrawVirtObj::RecalcSnapRect()
2693 {
2694     aSnapRect = rRefObj.GetSnapRect();
2695     aSnapRect += GetOffset();
2696 }
2697 
GetSnapRect() const2698 const Rectangle& SwDrawVirtObj::GetSnapRect() const
2699 {
2700     ((SwDrawVirtObj*)this)->aSnapRect = rRefObj.GetSnapRect();
2701     ((SwDrawVirtObj*)this)->aSnapRect += GetOffset();
2702 
2703     return aSnapRect;
2704 }
2705 
SetSnapRect(const Rectangle & rRect)2706 void SwDrawVirtObj::SetSnapRect(const Rectangle& rRect)
2707 {
2708 	Rectangle aBoundRect0; if(pUserCall) aBoundRect0 = GetLastBoundRect();
2709 	Rectangle aR(rRect);
2710     aR -= GetOffset();
2711 	rRefObj.SetSnapRect(aR);
2712 	SetRectsDirty();
2713 	SendUserCall(SDRUSERCALL_RESIZE, aBoundRect0);
2714 }
2715 
NbcSetSnapRect(const Rectangle & rRect)2716 void SwDrawVirtObj::NbcSetSnapRect(const Rectangle& rRect)
2717 {
2718 	Rectangle aR(rRect);
2719     aR -= GetOffset();
2720 	SetRectsDirty();
2721 	rRefObj.NbcSetSnapRect(aR);
2722 }
2723 
GetLogicRect() const2724 const Rectangle& SwDrawVirtObj::GetLogicRect() const
2725 {
2726 	((SwDrawVirtObj*)this)->aSnapRect = rRefObj.GetLogicRect();
2727     ((SwDrawVirtObj*)this)->aSnapRect += GetOffset();
2728 
2729 	return aSnapRect;
2730 }
2731 
SetLogicRect(const Rectangle & rRect)2732 void SwDrawVirtObj::SetLogicRect(const Rectangle& rRect)
2733 {
2734 	Rectangle aBoundRect0; if(pUserCall) aBoundRect0 = GetLastBoundRect();
2735 	Rectangle aR(rRect);
2736     aR -= GetOffset();
2737 	rRefObj.SetLogicRect(aR);
2738 	SetRectsDirty();
2739 	SendUserCall(SDRUSERCALL_RESIZE, aBoundRect0);
2740 }
2741 
NbcSetLogicRect(const Rectangle & rRect)2742 void SwDrawVirtObj::NbcSetLogicRect(const Rectangle& rRect)
2743 {
2744 	Rectangle aR(rRect);
2745     aR -= GetOffset();
2746 	rRefObj.NbcSetLogicRect(aR);
2747 	SetRectsDirty();
2748 }
2749 
GetSnapPoint(sal_uInt32 i) const2750 Point SwDrawVirtObj::GetSnapPoint(sal_uInt32 i) const
2751 {
2752 	Point aP(rRefObj.GetSnapPoint(i));
2753     aP += GetOffset();
2754 
2755 	return aP;
2756 }
2757 
GetPoint(sal_uInt32 i) const2758 Point SwDrawVirtObj::GetPoint(sal_uInt32 i) const
2759 {
2760 	return Point(rRefObj.GetPoint(i) + GetOffset());
2761 }
2762 
NbcSetPoint(const Point & rPnt,sal_uInt32 i)2763 void SwDrawVirtObj::NbcSetPoint(const Point& rPnt, sal_uInt32 i)
2764 {
2765 	Point aP(rPnt);
2766     aP -= GetOffset();
2767 	rRefObj.SetPoint(aP, i);
2768 	SetRectsDirty();
2769 }
2770 
2771 // #108784#
HasTextEdit() const2772 FASTBOOL SwDrawVirtObj::HasTextEdit() const
2773 {
2774 	return rRefObj.HasTextEdit();
2775 }
2776 
2777 // OD 18.06.2003 #108784# - overloaded 'layer' methods for 'virtual' drawing
2778 // object to assure, that layer of 'virtual' object is the layer of the referenced
2779 // object.
GetLayer() const2780 SdrLayerID SwDrawVirtObj::GetLayer() const
2781 {
2782     return GetReferencedObj().GetLayer();
2783 }
2784 
NbcSetLayer(SdrLayerID nLayer)2785 void SwDrawVirtObj::NbcSetLayer(SdrLayerID nLayer)
2786 {
2787     ReferencedObj().NbcSetLayer( nLayer );
2788     SdrVirtObj::NbcSetLayer( ReferencedObj().GetLayer() );
2789 }
2790 
SetLayer(SdrLayerID nLayer)2791 void SwDrawVirtObj::SetLayer(SdrLayerID nLayer)
2792 {
2793     ReferencedObj().SetLayer( nLayer );
2794     SdrVirtObj::NbcSetLayer( ReferencedObj().GetLayer() );
2795 }
2796 
supportsFullDrag() const2797 bool SwDrawVirtObj::supportsFullDrag() const
2798 {
2799     // call parent
2800     return SdrVirtObj::supportsFullDrag();
2801 }
2802 
getFullDragClone() const2803 SdrObject* SwDrawVirtObj::getFullDragClone() const
2804 {
2805     // call parent
2806     return SdrVirtObj::getFullDragClone();
2807 }
2808 
2809 // eof
2810 
2811