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