xref: /aoo42x/main/sw/source/core/draw/dcontact.cxx (revision 371e7ce6)
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 						//-->Modified for i119654,2012.6.8
1509 						SwFrm *pAnchorFrame = NULL;
1510                         if ( pAnchoredDrawObj && ( pAnchorFrame =
1511 								const_cast<SwAnchoredDrawObject*>( pAnchoredDrawObj )->AnchorFrm() ) )
1512 							pAnchorFrame->Prepare( PREP_FLY_ATTR_CHG, GetFmt() );
1513 						//<--
1514                     }
1515                     // <--
1516                 }
1517             }
1518             // --> OD 2006-01-18 #129959#
1519             // It reveals that the following code causes several defects -
1520             // on copying or on ungrouping a group shape containing edge objects.
1521             // Testing fix for #i53320# also reveal that the following code
1522             // isn't necessary.
1523 //            // --> OD 2005-08-15 #i53320# - reset positioning attributes,
1524 //            // if anchored drawing object isn't yet positioned.
1525 //            else if ( pAnchoredDrawObj->NotYetPositioned() &&
1526 //                      static_cast<const SwDrawFrmFmt&>(pAnchoredDrawObj->GetFrmFmt()).IsPosAttrSet() )
1527 //            {
1528 //                const_cast<SwDrawFrmFmt&>(
1529 //                    static_cast<const SwDrawFrmFmt&>(pAnchoredDrawObj->GetFrmFmt()))
1530 //                        .ResetPosAttr();
1531 //            }
1532 //            // <--
1533             // <--
1534         }
1535         break;
1536 		case SDRUSERCALL_CHGATTR:
1537             if ( bNotify )
1538             {
1539                 lcl_NotifyBackgroundOfObj( *this, rObj, pOldBoundRect );
1540             }
1541 			break;
1542         default:
1543             break;
1544 	}
1545 }
1546 
1547 namespace
1548 {
1549     static const SwFmtAnchor* lcl_getAnchorFmt( const SfxPoolItem& _rItem )
1550     {
1551 	    sal_uInt16 nWhich = _rItem.Which();
1552         const SwFmtAnchor* pAnchorFmt = NULL;
1553         if ( RES_ATTRSET_CHG == nWhich )
1554 	    {
1555             static_cast<const SwAttrSetChg&>(_rItem).GetChgSet()->
1556                 GetItemState( RES_ANCHOR, sal_False, (const SfxPoolItem**)&pAnchorFmt );
1557 	    }
1558         else if ( RES_ANCHOR == nWhich )
1559         {
1560             pAnchorFmt = &static_cast<const SwFmtAnchor&>(_rItem);
1561         }
1562         return pAnchorFmt;
1563     }
1564 }
1565 
1566 /*************************************************************************
1567 |*
1568 |*	SwDrawContact::Modify()
1569 |*
1570 |*	Ersterstellung		MA 09. Jan. 95
1571 |*	Letzte Aenderung	MA 03. Dec. 95
1572 |*
1573 |*************************************************************************/
1574 
1575 void SwDrawContact::Modify( const SfxPoolItem* pOld, const SfxPoolItem *pNew )
1576 {
1577     // OD 10.10.2003 #112299#
1578     ASSERT( !mbDisconnectInProgress,
1579             "<SwDrawContact::Modify(..)> called during disconnection.");
1580 
1581 	sal_uInt16 nWhich = pNew ? pNew->Which() : 0;
1582     const SwFmtAnchor* pNewAnchorFmt = pNew ? lcl_getAnchorFmt( *pNew ) : NULL;
1583 
1584     if ( pNewAnchorFmt )
1585 	{
1586 		// JP 10.04.95: nicht auf ein Reset Anchor reagieren !!!!!
1587         if ( SFX_ITEM_SET ==
1588                 GetFmt()->GetAttrSet().GetItemState( RES_ANCHOR, sal_False ) )
1589 		{
1590             // OD 10.10.2003 #112299# - no connect to layout during disconnection
1591             if ( !mbDisconnectInProgress )
1592             {
1593                 // determine old object retangle of 'master' drawing object
1594                 // for notification
1595                 const Rectangle* pOldRect = 0L;
1596                 Rectangle aOldRect;
1597                 if ( GetAnchorFrm() )
1598                 {
1599                     // --> OD 2004-10-27 #i36181# - include spacing in object
1600                     // rectangle for notification.
1601                     aOldRect = maAnchoredDrawObj.GetObjRectWithSpaces().SVRect();
1602                     pOldRect = &aOldRect;
1603                     // <--
1604                 }
1605                 // re-connect to layout due to anchor format change
1606                 ConnectToLayout( pNewAnchorFmt );
1607                 // notify background of drawing objects
1608                 lcl_NotifyBackgroundOfObj( *this, *GetMaster(), pOldRect );
1609                 NotifyBackgrdOfAllVirtObjs( pOldRect );
1610 
1611                 const SwFmtAnchor* pOldAnchorFmt = pOld ? lcl_getAnchorFmt( *pOld ) : NULL;
1612                 if ( !pOldAnchorFmt || ( pOldAnchorFmt->GetAnchorId() != pNewAnchorFmt->GetAnchorId() ) )
1613                 {
1614                     ASSERT( maAnchoredDrawObj.DrawObj(), "SwDrawContact::Modify: no draw object here?" );
1615                     if ( maAnchoredDrawObj.DrawObj() )
1616                     {
1617                         // --> OD 2009-07-10 #i102752#
1618                         // assure that a ShapePropertyChangeNotifier exists
1619                         maAnchoredDrawObj.DrawObj()->notifyShapePropertyChange( ::svx::eTextShapeAnchorType );
1620                         // <--
1621                     }
1622                 }
1623             }
1624 		}
1625 		else
1626 			DisconnectFromLayout();
1627 	}
1628     // --> OD 2006-03-17 #i62875# - revised fix for issue #124157#
1629     // no further notification, if not connected to Writer layout
1630     else if ( maAnchoredDrawObj.GetAnchorFrm() &&
1631               maAnchoredDrawObj.GetDrawObj()->GetUserCall() )
1632     {
1633         // --> OD 2004-07-01 #i28701# - on change of wrapping style, hell|heaven layer,
1634         // or wrapping style influence an update of the <SwSortedObjs> list,
1635         // the drawing object is registered in, has to be performed. This is triggered
1636         // by the 1st parameter of method call <_InvalidateObjs(..)>.
1637         if ( RES_SURROUND == nWhich ||
1638              RES_OPAQUE == nWhich ||
1639              RES_WRAP_INFLUENCE_ON_OBJPOS == nWhich ||
1640              ( RES_ATTRSET_CHG == nWhich &&
1641                ( SFX_ITEM_SET == ((SwAttrSetChg*)pNew)->GetChgSet()->GetItemState(
1642                            RES_SURROUND, sal_False ) ||
1643                  SFX_ITEM_SET == ((SwAttrSetChg*)pNew)->GetChgSet()->GetItemState(
1644                            RES_OPAQUE, sal_False ) ||
1645                  SFX_ITEM_SET == ((SwAttrSetChg*)pNew)->GetChgSet()->GetItemState(
1646                            RES_WRAP_INFLUENCE_ON_OBJPOS, sal_False ) ) ) )
1647         {
1648             lcl_NotifyBackgroundOfObj( *this, *GetMaster(), 0L );
1649             NotifyBackgrdOfAllVirtObjs( 0L );
1650             _InvalidateObjs( true );
1651         }
1652         else if ( RES_UL_SPACE == nWhich || RES_LR_SPACE == nWhich ||
1653                   RES_HORI_ORIENT == nWhich || RES_VERT_ORIENT == nWhich ||
1654                   // --> OD 2004-07-01 #i28701# - add attribute 'Follow text flow'
1655                   RES_FOLLOW_TEXT_FLOW == nWhich ||
1656                   ( RES_ATTRSET_CHG == nWhich &&
1657                     ( SFX_ITEM_SET == ((SwAttrSetChg*)pNew)->GetChgSet()->GetItemState(
1658                                 RES_LR_SPACE, sal_False ) ||
1659                       SFX_ITEM_SET == ((SwAttrSetChg*)pNew)->GetChgSet()->GetItemState(
1660                                 RES_UL_SPACE, sal_False ) ||
1661                       SFX_ITEM_SET == ((SwAttrSetChg*)pNew)->GetChgSet()->GetItemState(
1662                                 RES_HORI_ORIENT, sal_False ) ||
1663                       SFX_ITEM_SET == ((SwAttrSetChg*)pNew)->GetChgSet()->GetItemState(
1664                                 RES_VERT_ORIENT, sal_False ) ||
1665                       SFX_ITEM_SET == ((SwAttrSetChg*)pNew)->GetChgSet()->GetItemState(
1666                                 RES_FOLLOW_TEXT_FLOW, sal_False ) ) ) )
1667         {
1668             lcl_NotifyBackgroundOfObj( *this, *GetMaster(), 0L );
1669             NotifyBackgrdOfAllVirtObjs( 0L );
1670             _InvalidateObjs();
1671         }
1672         // --> OD 2004-10-26 #i35443#
1673         else if ( RES_ATTRSET_CHG == nWhich )
1674         {
1675             lcl_NotifyBackgroundOfObj( *this, *GetMaster(), 0L );
1676             NotifyBackgrdOfAllVirtObjs( 0L );
1677             _InvalidateObjs();
1678         }
1679         // <--
1680         else if ( RES_REMOVE_UNO_OBJECT == nWhich )
1681         {
1682             // nothing to do
1683         }
1684 #if OSL_DEBUG_LEVEL > 1
1685         else
1686         {
1687             ASSERT( false,
1688                     "<SwDrawContact::Modify(..)> - unhandled attribute? - please inform od@openoffice.org" );
1689         }
1690 #endif
1691     }
1692 
1693     // --> OD 2005-07-18 #i51474#
1694     GetAnchoredObj( 0L )->ResetLayoutProcessBools();
1695     // <--
1696 }
1697 
1698 // OD 2004-03-31 #i26791#
1699 // --> OD 2004-07-01 #i28701# - added parameter <_bUpdateSortedObjsList>
1700 void SwDrawContact::_InvalidateObjs( const bool _bUpdateSortedObjsList )
1701 {
1702     // invalidate position of existing 'virtual' drawing objects
1703     for ( std::list<SwDrawVirtObj*>::iterator aDisconnectIter = maDrawVirtObjs.begin();
1704           aDisconnectIter != maDrawVirtObjs.end();
1705           ++aDisconnectIter )
1706     {
1707         SwDrawVirtObj* pDrawVirtObj = (*aDisconnectIter);
1708         // --> OD 2004-08-23 #i33313# - invalidation only for connected
1709         // 'virtual' drawing objects
1710         if ( pDrawVirtObj->IsConnected() )
1711         {
1712             pDrawVirtObj->AnchoredObj()->InvalidateObjPos();
1713             // --> OD 2004-07-01 #i28701#
1714             if ( _bUpdateSortedObjsList )
1715             {
1716                 pDrawVirtObj->AnchoredObj()->UpdateObjInSortedList();
1717             }
1718             // <--
1719         }
1720         // <--
1721     }
1722 
1723     // invalidate position of 'master' drawing object
1724     SwAnchoredObject* pAnchoredObj = GetAnchoredObj( 0L );
1725     pAnchoredObj->InvalidateObjPos();
1726     // --> OD 2004-07-01 #i28701#
1727     if ( _bUpdateSortedObjsList )
1728     {
1729         pAnchoredObj->UpdateObjInSortedList();
1730     }
1731     // <--
1732 }
1733 
1734 /*************************************************************************
1735 |*
1736 |*	SwDrawContact::DisconnectFromLayout()
1737 |*
1738 |*	Ersterstellung		MA 09. Jan. 95
1739 |*	Letzte Aenderung	MA 25. Mar. 99
1740 |*
1741 |*************************************************************************/
1742 
1743 void SwDrawContact::DisconnectFromLayout( bool _bMoveMasterToInvisibleLayer )
1744 {
1745     // OD 10.10.2003 #112299#
1746     mbDisconnectInProgress = true;
1747 
1748     // --> OD 2004-10-27 #i36181# - notify background of drawing object
1749     if ( _bMoveMasterToInvisibleLayer &&
1750          !(GetFmt()->GetDoc()->IsInDtor()) &&
1751          GetAnchorFrm() )
1752     {
1753         const Rectangle aOldRect( maAnchoredDrawObj.GetObjRectWithSpaces().SVRect() );
1754         lcl_NotifyBackgroundOfObj( *this, *GetMaster(), &aOldRect );
1755         NotifyBackgrdOfAllVirtObjs( &aOldRect );
1756     }
1757     // <--
1758 
1759     // OD 16.05.2003 #108784# - remove 'virtual' drawing objects from writer
1760     // layout and from drawing page
1761     for ( std::list<SwDrawVirtObj*>::iterator aDisconnectIter = maDrawVirtObjs.begin();
1762           aDisconnectIter != maDrawVirtObjs.end();
1763           ++aDisconnectIter )
1764     {
1765         SwDrawVirtObj* pDrawVirtObj = (*aDisconnectIter);
1766         pDrawVirtObj->RemoveFromWriterLayout();
1767         pDrawVirtObj->RemoveFromDrawingPage();
1768     }
1769 
1770     if ( maAnchoredDrawObj.GetAnchorFrm() )
1771     {
1772         maAnchoredDrawObj.AnchorFrm()->RemoveDrawObj( maAnchoredDrawObj );
1773     }
1774 
1775     if ( _bMoveMasterToInvisibleLayer && GetMaster() && GetMaster()->IsInserted() )
1776 	{
1777 		SdrViewIter aIter( GetMaster() );
1778 		for( SdrView* pView = aIter.FirstView(); pView;
1779 					pView = aIter.NextView() )
1780         {
1781 			pView->MarkObj( GetMaster(), pView->GetSdrPageView(), sal_True );
1782         }
1783 
1784         // OD 25.06.2003 #108784# - Instead of removing 'master' object from
1785         // drawing page, move the 'master' drawing object into the corresponding
1786         // invisible layer.
1787         {
1788             //((SwFrmFmt*)GetRegisteredIn())->getIDocumentDrawModelAccess()->GetDrawModel()->GetPage(0)->
1789             //                            RemoveObject( GetMaster()->GetOrdNum() );
1790             // OD 21.08.2003 #i18447# - in order to consider group object correct
1791             // use new method <SwDrawContact::MoveObjToInvisibleLayer(..)>
1792             MoveObjToInvisibleLayer( GetMaster() );
1793         }
1794 	}
1795 
1796     // OD 10.10.2003 #112299#
1797     mbDisconnectInProgress = false;
1798 }
1799 
1800 // OD 26.06.2003 #108784# - method to remove 'master' drawing object
1801 // from drawing page.
1802 void SwDrawContact::RemoveMasterFromDrawPage()
1803 {
1804     if ( GetMaster() )
1805     {
1806         GetMaster()->SetUserCall( 0 );
1807         if ( GetMaster()->IsInserted() )
1808         {
1809             ((SwFrmFmt*)GetRegisteredIn())->getIDocumentDrawModelAccess()->GetDrawModel()->GetPage(0)->
1810                                         RemoveObject( GetMaster()->GetOrdNum() );
1811         }
1812     }
1813 }
1814 
1815 // OD 19.06.2003 #108784# - disconnect for a dedicated drawing object -
1816 // could be 'master' or 'virtual'.
1817 // a 'master' drawing object will disconnect a 'virtual' drawing object
1818 // in order to take its place.
1819 // OD 13.10.2003 #i19919# - no special case, if drawing object isn't in
1820 // page header/footer, in order to get drawing objects in repeating table headers
1821 // also working.
1822 void SwDrawContact::DisconnectObjFromLayout( SdrObject* _pDrawObj )
1823 {
1824     if ( _pDrawObj->ISA(SwDrawVirtObj) )
1825     {
1826         SwDrawVirtObj* pDrawVirtObj = static_cast<SwDrawVirtObj*>(_pDrawObj);
1827         pDrawVirtObj->RemoveFromWriterLayout();
1828         pDrawVirtObj->RemoveFromDrawingPage();
1829     }
1830     else
1831     {
1832         std::list<SwDrawVirtObj*>::const_iterator aFoundVirtObjIter =
1833                 std::find_if( maDrawVirtObjs.begin(), maDrawVirtObjs.end(),
1834                               UsedOrUnusedVirtObjPred( true ) );
1835         if ( aFoundVirtObjIter != maDrawVirtObjs.end() )
1836         {
1837             // replace found 'virtual' drawing object by 'master' drawing
1838             // object and disconnect the 'virtual' one
1839             SwDrawVirtObj* pDrawVirtObj = (*aFoundVirtObjIter);
1840             SwFrm* pNewAnchorFrmOfMaster = pDrawVirtObj->AnchorFrm();
1841             // disconnect 'virtual' drawing object
1842             pDrawVirtObj->RemoveFromWriterLayout();
1843             pDrawVirtObj->RemoveFromDrawingPage();
1844             // disconnect 'master' drawing object from current frame
1845             GetAnchorFrm()->RemoveDrawObj( maAnchoredDrawObj );
1846             // re-connect 'master' drawing object to frame of found 'virtual'
1847             // drawing object.
1848             pNewAnchorFrmOfMaster->AppendDrawObj( maAnchoredDrawObj );
1849         }
1850         else
1851         {
1852             // no connected 'virtual' drawing object found. Thus, disconnect
1853             // completely from layout.
1854             DisconnectFromLayout();
1855         }
1856     }
1857 }
1858 
1859 /*************************************************************************
1860 |*
1861 |*	SwDrawContact::ConnectToLayout()
1862 |*
1863 |*	Ersterstellung		MA 09. Jan. 95
1864 |*	Letzte Aenderung	MA 25. Mar. 99
1865 |*
1866 |*************************************************************************/
1867 SwTxtFrm* lcl_GetFlyInCntntAnchor( SwTxtFrm* _pProposedAnchorFrm,
1868                                    const xub_StrLen _nTxtOfs )
1869 {
1870     SwTxtFrm* pAct = _pProposedAnchorFrm;
1871     SwTxtFrm* pTmp;
1872     do
1873     {
1874         pTmp = pAct;
1875         pAct = pTmp->GetFollow();
1876     }
1877     while( pAct && _nTxtOfs >= pAct->GetOfst() );
1878     return pTmp;
1879 }
1880 
1881 void SwDrawContact::ConnectToLayout( const SwFmtAnchor* pAnch )
1882 {
1883     // OD 10.10.2003 #112299# - *no* connect to layout during disconnection from
1884     // layout.
1885     if ( mbDisconnectInProgress )
1886     {
1887         ASSERT( false,
1888                 "<SwDrawContact::ConnectToLayout(..)> called during disconnection.");
1889         return;
1890     }
1891 
1892     // --> OD 2004-09-22 #i33909# - *no* connect to layout, if 'master' drawing
1893     // object isn't inserted in the drawing page
1894     if ( !GetMaster()->IsInserted() )
1895     {
1896         ASSERT( false, "<SwDrawContact::ConnectToLayout(..)> - master drawing object not inserted -> no connect to layout. Please inform od@openoffice.org" );
1897         return;
1898     }
1899     // <--
1900 
1901     SwFrmFmt* pDrawFrmFmt = (SwFrmFmt*)GetRegisteredIn();
1902 
1903     if( !pDrawFrmFmt->getIDocumentLayoutAccess()->GetCurrentViewShell() )
1904 		return;
1905 
1906     // OD 16.05.2003 #108784# - remove 'virtual' drawing objects from writer
1907     // layout and from drawing page, and remove 'master' drawing object from
1908     // writer layout - 'master' object will remain in drawing page.
1909     DisconnectFromLayout( false );
1910 
1911 	if ( !pAnch )
1912     {
1913         pAnch = &(pDrawFrmFmt->GetAnchor());
1914     }
1915 
1916 	switch ( pAnch->GetAnchorId() )
1917 	{
1918         case FLY_AT_PAGE:
1919                 {
1920                 sal_uInt16 nPgNum = pAnch->GetPageNum();
1921                 ViewShell *pShell = pDrawFrmFmt->getIDocumentLayoutAccess()->GetCurrentViewShell();
1922                 if( !pShell )
1923                     break;
1924                 SwRootFrm* pRoot = pShell->GetLayout();
1925                 SwPageFrm *pPage = static_cast<SwPageFrm*>(pRoot->Lower());
1926 
1927                 for ( sal_uInt16 i = 1; i < nPgNum && pPage; ++i )
1928                 {
1929                     pPage = static_cast<SwPageFrm*>(pPage->GetNext());
1930                 }
1931 
1932                 if ( pPage )
1933                 {
1934                     pPage->AppendDrawObj( maAnchoredDrawObj );
1935                 }
1936                 else
1937                     //Sieht doof aus, ist aber erlaubt (vlg. SwFEShell::SetPageObjsNewPage)
1938                     pRoot->SetAssertFlyPages();
1939                 }
1940                 break;
1941 
1942         case FLY_AT_CHAR:
1943         case FLY_AT_PARA:
1944         case FLY_AT_FLY:
1945         case FLY_AS_CHAR:
1946             {
1947                 if ( pAnch->GetAnchorId() == FLY_AS_CHAR )
1948                 {
1949                     ClrContourCache( GetMaster() );
1950                 }
1951                 // OD 16.05.2003 #108784# - support drawing objects in header/footer,
1952                 // but not control objects:
1953                 // anchor at first found frame the 'master' object and
1954                 // at the following frames 'virtual' drawing objects.
1955                 // Note: method is similar to <SwFlyFrmFmt::MakeFrms(..)>
1956                 SwModify *pModify = 0;
1957                 if( pAnch->GetCntntAnchor() )
1958                 {
1959                     if ( pAnch->GetAnchorId() == FLY_AT_FLY )
1960                     {
1961                         SwNodeIndex aIdx( pAnch->GetCntntAnchor()->nNode );
1962                         SwCntntNode* pCNd = pDrawFrmFmt->GetDoc()->GetNodes().GoNext( &aIdx );
1963                         if ( SwIterator<SwFrm,SwCntntNode>::FirstElement( *pCNd ) )
1964                             pModify = pCNd;
1965                         else
1966                         {
1967                             const SwNodeIndex& rIdx = pAnch->GetCntntAnchor()->nNode;
1968                             SwSpzFrmFmts& rFmts = *(pDrawFrmFmt->GetDoc()->GetSpzFrmFmts());
1969                             for( sal_uInt16 i = 0; i < rFmts.Count(); ++i )
1970                             {
1971                                 SwFrmFmt* pFlyFmt = rFmts[i];
1972                                 if( pFlyFmt->GetCntnt().GetCntntIdx() &&
1973                                     rIdx == *(pFlyFmt->GetCntnt().GetCntntIdx()) )
1974                                 {
1975                                     pModify = pFlyFmt;
1976                                     break;
1977                                 }
1978                             }
1979                         }
1980                         // --> OD 2004-06-15 #i29199# - It is possible, that
1981                         // the anchor doesn't exist - E.g., reordering the
1982                         // sub-documents in a master document.
1983                         // Note: The anchor will be inserted later.
1984                         if ( !pModify )
1985                         {
1986                             // break to end of the current switch case.
1987                             break;
1988                         }
1989                     }
1990                     else
1991                     {
1992                         pModify = pAnch->GetCntntAnchor()->nNode.GetNode().GetCntntNode();
1993                     }
1994                 }
1995                 SwIterator<SwFrm,SwModify> aIter( *pModify );
1996                 SwFrm* pAnchorFrmOfMaster = 0;
1997                 for( SwFrm *pFrm = aIter.First(); pFrm; pFrm = aIter.Next() )
1998                 {
1999                     // append drawing object, if
2000                     // (1) proposed anchor frame isn't a follow and
2001                     // (2) drawing object isn't a control object to be anchored
2002                     //     in header/footer.
2003                     const bool bAdd = ( !pFrm->IsCntntFrm() ||
2004                                         !((SwCntntFrm*)pFrm)->IsFollow() ) &&
2005                                       ( !::CheckControlLayer( GetMaster() ) ||
2006                                         !pFrm->FindFooterOrHeader() );
2007 
2008                     if( bAdd )
2009                     {
2010                         if ( FLY_AT_FLY == pAnch->GetAnchorId() && !pFrm->IsFlyFrm() )
2011                         {
2012                             pFrm = pFrm->FindFlyFrm();
2013                             ASSERT( pFrm,
2014                                     "<SwDrawContact::ConnectToLayout(..)> - missing fly frame -> crash." );
2015                         }
2016 
2017                         // OD 2004-01-20 #110582# - find correct follow for
2018                         // as character anchored objects.
2019                         if ((pAnch->GetAnchorId() == FLY_AS_CHAR) &&
2020                              pFrm->IsTxtFrm() )
2021                         {
2022                             pFrm = lcl_GetFlyInCntntAnchor(
2023                                         static_cast<SwTxtFrm*>(pFrm),
2024                                         pAnch->GetCntntAnchor()->nContent.GetIndex() );
2025                         }
2026 
2027                         if ( !pAnchorFrmOfMaster )
2028                         {
2029                             // append 'master' drawing object
2030                             pAnchorFrmOfMaster = pFrm;
2031                             pFrm->AppendDrawObj( maAnchoredDrawObj );
2032                         }
2033                         else
2034                         {
2035                             // append 'virtual' drawing object
2036                             SwDrawVirtObj* pDrawVirtObj = AddVirtObj();
2037                             if ( pAnch->GetAnchorId() == FLY_AS_CHAR )
2038                             {
2039                                 ClrContourCache( pDrawVirtObj );
2040                             }
2041                             pFrm->AppendDrawObj( *(pDrawVirtObj->AnchoredObj()) );
2042 
2043 							// for repaint, use new ActionChanged()
2044                             // pDrawVirtObj->SendRepaintBroadcast();
2045                             pDrawVirtObj->ActionChanged();
2046                         }
2047 
2048                         if ( pAnch->GetAnchorId() == FLY_AS_CHAR )
2049                         {
2050                             pFrm->InvalidatePrt();
2051                         }
2052                     }
2053                 }
2054 			}
2055 			break;
2056         default:
2057             ASSERT( sal_False, "Unknown Anchor." )
2058             break;
2059     }
2060     if ( GetAnchorFrm() )
2061 	{
2062         ::setContextWritingMode( maAnchoredDrawObj.DrawObj(), GetAnchorFrm() );
2063         // OD 2004-04-01 #i26791# - invalidate objects instead of direct positioning
2064         _InvalidateObjs();
2065 	}
2066 }
2067 
2068 // OD 27.06.2003 #108784# - insert 'master' drawing object into drawing page
2069 void SwDrawContact::InsertMasterIntoDrawPage()
2070 {
2071     if ( !GetMaster()->IsInserted() )
2072     {
2073         GetFmt()->getIDocumentDrawModelAccess()->GetDrawModel()->GetPage(0)
2074                 ->InsertObject( GetMaster(), GetMaster()->GetOrdNumDirect() );
2075     }
2076     GetMaster()->SetUserCall( this );
2077 }
2078 
2079 /*************************************************************************
2080 |*
2081 |*	SwDrawContact::FindPage(), ChkPage()
2082 |*
2083 |*	Ersterstellung		MA 21. Mar. 95
2084 |*	Letzte Aenderung	MA 19. Jul. 96
2085 |*
2086 |*************************************************************************/
2087 
2088 SwPageFrm* SwDrawContact::FindPage( const SwRect &rRect )
2089 {
2090     // --> OD 2004-07-01 #i28701# - use method <GetPageFrm()>
2091     SwPageFrm* pPg = GetPageFrm();
2092     if ( !pPg && GetAnchorFrm() )
2093         pPg = GetAnchorFrm()->FindPageFrm();
2094 	if ( pPg )
2095 		pPg = (SwPageFrm*)::FindPage( rRect, pPg );
2096 	return pPg;
2097 }
2098 
2099 void SwDrawContact::ChkPage()
2100 {
2101     // OD 10.10.2003 #112299#
2102     if ( mbDisconnectInProgress )
2103     {
2104         ASSERT( false,
2105                 "<SwDrawContact::ChkPage()> called during disconnection." );
2106         return;
2107     }
2108 
2109     // --> OD 2004-07-01 #i28701#
2110     SwPageFrm* pPg = ( maAnchoredDrawObj.GetAnchorFrm() &&
2111                        maAnchoredDrawObj.GetAnchorFrm()->IsPageFrm() )
2112                      ? GetPageFrm()
2113                      : FindPage( GetMaster()->GetCurrentBoundRect() );
2114     if ( GetPageFrm() != pPg )
2115 	{
2116         // OD 27.06.2003 #108784# - if drawing object is anchor in header/footer
2117         // a change of the page is a dramatic change. Thus, completely re-connect
2118         // to the layout
2119         if ( maAnchoredDrawObj.GetAnchorFrm() &&
2120              maAnchoredDrawObj.GetAnchorFrm()->FindFooterOrHeader() )
2121         {
2122             ConnectToLayout();
2123         }
2124         else
2125         {
2126             // --> OD 2004-07-01 #i28701# - use methods <GetPageFrm()> and <SetPageFrm>
2127             if ( GetPageFrm() )
2128                 GetPageFrm()->RemoveDrawObjFromPage( maAnchoredDrawObj );
2129             pPg->AppendDrawObjToPage( maAnchoredDrawObj );
2130             SetPageFrm( pPg );
2131         }
2132 	}
2133 }
2134 
2135 /*************************************************************************
2136 |*
2137 |*	SwDrawContact::ChangeMasterObject()
2138 |*
2139 |*	Ersterstellung		MA 07. Aug. 95
2140 |*	Letzte Aenderung	MA 20. Apr. 99
2141 |*
2142 |*************************************************************************/
2143 // OD 10.07.2003 #110742# - Important note:
2144 // method is called by method <SwDPage::ReplaceObject(..)>, which called its
2145 // corresponding superclass method <FmFormPage::ReplaceObject(..)>.
2146 // Note: 'master' drawing object *has* to be connected to layout triggered
2147 //       by the caller of this, if method is called.
2148 void SwDrawContact::ChangeMasterObject( SdrObject *pNewMaster )
2149 {
2150     DisconnectFromLayout( false );
2151     // OD 10.07.2003 #110742# - consider 'virtual' drawing objects
2152     RemoveAllVirtObjs();
2153 
2154     GetMaster()->SetUserCall( 0 );
2155 	SetMaster( pNewMaster );
2156 	GetMaster()->SetUserCall( this );
2157 
2158     _InvalidateObjs();
2159 }
2160 
2161 /** get data collection of anchored objects, handled by with contact
2162 
2163     OD 2004-08-23 #110810#
2164 
2165     @author
2166 */
2167 void SwDrawContact::GetAnchoredObjs( std::list<SwAnchoredObject*>& _roAnchoredObjs ) const
2168 {
2169     _roAnchoredObjs.push_back( const_cast<SwAnchoredDrawObject*>(&maAnchoredDrawObj) );
2170 
2171     for ( std::list<SwDrawVirtObj*>::const_iterator aDrawVirtObjsIter = maDrawVirtObjs.begin();
2172           aDrawVirtObjsIter != maDrawVirtObjs.end();
2173           ++aDrawVirtObjsIter )
2174     {
2175         _roAnchoredObjs.push_back( (*aDrawVirtObjsIter)->AnchoredObj() );
2176     }
2177 }
2178 
2179 //////////////////////////////////////////////////////////////////////////////////////
2180 // AW: own sdr::contact::ViewContact (VC) sdr::contact::ViewObjectContact (VOC) needed
2181 // since offset is defined different from SdrVirtObj's sdr::contact::ViewContactOfVirtObj.
2182 // For paint, that offset is used by setting at the OutputDevice; for primitives this is
2183 // not possible since we have no OutputDevice, but define the geometry itself.
2184 
2185 namespace sdr
2186 {
2187 	namespace contact
2188 	{
2189         class VOCOfDrawVirtObj : public ViewObjectContactOfSdrObj
2190 		{
2191 		protected:
2192 			// This method is responsible for creating the graphical visualisation data which is
2193 			// stored/cached in the local primitive. Default gets view-independent Primitive
2194 			// from the ViewContact using ViewContact::getViewIndependentPrimitive2DSequence(), takes care of
2195 			// visibility, handles glue and ghosted.
2196 			// This method will not handle included hierarchies and not check geometric visibility.
2197 			virtual drawinglayer::primitive2d::Primitive2DSequence createPrimitive2DSequence(const DisplayInfo& rDisplayInfo) const;
2198 
2199         public:
2200 			VOCOfDrawVirtObj(ObjectContact& rObjectContact, ViewContact& rViewContact)
2201             :   ViewObjectContactOfSdrObj(rObjectContact, rViewContact)
2202             {
2203             }
2204 
2205 			virtual ~VOCOfDrawVirtObj();
2206 		};
2207 
2208 		class VCOfDrawVirtObj : public ViewContactOfVirtObj
2209 		{
2210         protected:
2211 			// Create a Object-Specific ViewObjectContact, set ViewContact and
2212 			// ObjectContact. Always needs to return something. Default is to create
2213 			// a standard ViewObjectContact containing the given ObjectContact and *this
2214 			virtual ViewObjectContact& CreateObjectSpecificViewObjectContact(ObjectContact& rObjectContact);
2215 
2216         public:
2217 			// basic constructor, used from SdrObject.
2218             VCOfDrawVirtObj(SwDrawVirtObj& rObj)
2219             :   ViewContactOfVirtObj(rObj)
2220             {
2221             }
2222 			virtual ~VCOfDrawVirtObj();
2223 
2224             // access to SwDrawVirtObj
2225             SwDrawVirtObj& GetSwDrawVirtObj() const
2226             {
2227 			    return (SwDrawVirtObj&)mrObject;
2228             }
2229 		};
2230 	} // end of namespace contact
2231 } // end of namespace sdr
2232 
2233 namespace sdr
2234 {
2235 	namespace contact
2236 	{
2237         // recursively collect primitive data from given VOC with given offset
2238         void impAddPrimitivesFromGroup(const ViewObjectContact& rVOC, const basegfx::B2DHomMatrix& rOffsetMatrix, const DisplayInfo& rDisplayInfo, drawinglayer::primitive2d::Primitive2DSequence& rxTarget)
2239         {
2240 			const sal_uInt32 nSubHierarchyCount(rVOC.GetViewContact().GetObjectCount());
2241 
2242 			for(sal_uInt32 a(0L); a < nSubHierarchyCount; a++)
2243 			{
2244 				const ViewObjectContact& rCandidate(rVOC.GetViewContact().GetViewContact(a).GetViewObjectContact(rVOC.GetObjectContact()));
2245 
2246                 if(rCandidate.GetViewContact().GetObjectCount())
2247                 {
2248                     // is a group object itself, call resursively
2249                     impAddPrimitivesFromGroup(rCandidate, rOffsetMatrix, rDisplayInfo, rxTarget);
2250                 }
2251                 else
2252                 {
2253                     // single object, add primitives; check model-view visibility
2254 			        if(rCandidate.isPrimitiveVisible(rDisplayInfo))
2255 			        {
2256                         drawinglayer::primitive2d::Primitive2DSequence aNewSequence(rCandidate.getPrimitive2DSequence(rDisplayInfo));
2257 
2258 				        if(aNewSequence.hasElements())
2259 				        {
2260 					        // get ranges
2261 					        const drawinglayer::geometry::ViewInformation2D& rViewInformation2D(rCandidate.GetObjectContact().getViewInformation2D());
2262 					        const basegfx::B2DRange aViewRange(rViewInformation2D.getViewport());
2263 					        basegfx::B2DRange aObjectRange(rCandidate.getObjectRange());
2264 
2265                             // correct with virtual object's offset
2266                             aObjectRange.transform(rOffsetMatrix);
2267 
2268 					        // check geometrical visibility (with offset)
2269 					        if(!aViewRange.overlaps(aObjectRange))
2270 					        {
2271 						        // not visible, release
2272 						        aNewSequence.realloc(0);
2273 					        }
2274 				        }
2275 
2276 				        if(aNewSequence.hasElements())
2277 				        {
2278                             drawinglayer::primitive2d::appendPrimitive2DSequenceToPrimitive2DSequence(rxTarget, aNewSequence);
2279                         }
2280                     }
2281                 }
2282 			}
2283         }
2284 
2285         drawinglayer::primitive2d::Primitive2DSequence VOCOfDrawVirtObj::createPrimitive2DSequence(const DisplayInfo& rDisplayInfo) const
2286         {
2287 #ifdef DBG_UTIL
2288 			// #i101734#
2289 			static bool bCheckOtherThanTranslate(false);
2290 			static double fShearX(0.0);
2291 			static double fRotation(0.0);
2292 			static double fScaleX(0.0);
2293 			static double fScaleY(0.0);
2294 #endif
2295 
2296 			const VCOfDrawVirtObj& rVC = static_cast< const VCOfDrawVirtObj& >(GetViewContact());
2297             const SdrObject& rReferencedObject = rVC.GetSwDrawVirtObj().GetReferencedObj();
2298 			drawinglayer::primitive2d::Primitive2DSequence xRetval;
2299 
2300 		    // create offset transformation
2301 		    basegfx::B2DHomMatrix aOffsetMatrix;
2302             const Point aLocalOffset(rVC.GetSwDrawVirtObj().GetOffset());
2303 
2304 		    if(aLocalOffset.X() || aLocalOffset.Y())
2305 		    {
2306 #ifdef DBG_UTIL
2307 				// #i101734# added debug code to check more complex transformations
2308 				// than just a translation
2309 				if(bCheckOtherThanTranslate)
2310 				{
2311 					aOffsetMatrix.scale(fScaleX, fScaleY);
2312 					aOffsetMatrix.shearX(tan(fShearX * F_PI180));
2313 					aOffsetMatrix.rotate(fRotation * F_PI180);
2314 				}
2315 #endif
2316 
2317 			    aOffsetMatrix.set(0, 2, aLocalOffset.X());
2318 			    aOffsetMatrix.set(1, 2, aLocalOffset.Y());
2319 
2320 		    }
2321 
2322             if(rReferencedObject.ISA(SdrObjGroup))
2323             {
2324                 // group object. Since the VOC/OC/VC hierarchy does not represent the
2325                 // hierarchy virtual objects when they have group objects
2326                 // (ViewContactOfVirtObj::GetObjectCount() returns null for that purpose)
2327                 // to avoid multiple usages of VOCs (which would not work), the primitives
2328                 // for the sub-hierarchy need to be collected here
2329 
2330                 // Get the VOC of the referenced object (the Group) and fetch primitives from it
2331                 const ViewObjectContact& rVOCOfRefObj = rReferencedObject.GetViewContact().GetViewObjectContact(GetObjectContact());
2332                 impAddPrimitivesFromGroup(rVOCOfRefObj, aOffsetMatrix, rDisplayInfo, xRetval);
2333             }
2334             else
2335             {
2336 			    // single object, use method from referenced object to get the Primitive2DSequence
2337 			    xRetval = rReferencedObject.GetViewContact().getViewIndependentPrimitive2DSequence();
2338             }
2339 
2340             if(xRetval.hasElements())
2341 		    {
2342 			    // create transform primitive
2343 			    const drawinglayer::primitive2d::Primitive2DReference xReference(new drawinglayer::primitive2d::TransformPrimitive2D(aOffsetMatrix, xRetval));
2344                 xRetval = drawinglayer::primitive2d::Primitive2DSequence(&xReference, 1);
2345 		    }
2346 
2347             return xRetval;
2348         }
2349 
2350         VOCOfDrawVirtObj::~VOCOfDrawVirtObj()
2351         {
2352         }
2353 
2354 		ViewObjectContact& VCOfDrawVirtObj::CreateObjectSpecificViewObjectContact(ObjectContact& rObjectContact)
2355         {
2356 			return *(new VOCOfDrawVirtObj(rObjectContact, *this));
2357         }
2358 
2359         VCOfDrawVirtObj::~VCOfDrawVirtObj()
2360         {
2361         }
2362 	} // end of namespace contact
2363 } // end of namespace sdr
2364 
2365 //////////////////////////////////////////////////////////////////////////////////////
2366 
2367 // =============================================================================
2368 /** implementation of class <SwDrawVirtObj>
2369 
2370     OD 14.05.2003 #108784#
2371 
2372     @author OD
2373 */
2374 
2375 TYPEINIT1(SwDrawVirtObj,SdrVirtObj);
2376 
2377 sdr::contact::ViewContact* SwDrawVirtObj::CreateObjectSpecificViewContact()
2378 {
2379 	return new sdr::contact::VCOfDrawVirtObj(*this);
2380 }
2381 
2382 // #108784#
2383 // implemetation of SwDrawVirtObj
2384 SwDrawVirtObj::SwDrawVirtObj( SdrObject&        _rNewObj,
2385                               SwDrawContact&    _rDrawContact )
2386     : SdrVirtObj( _rNewObj ),
2387       // OD 2004-03-29 #i26791# - init new member <maAnchoredDrawObj>
2388       maAnchoredDrawObj(),
2389       mrDrawContact( _rDrawContact )
2390 {
2391     // OD 2004-03-29 #i26791#
2392     maAnchoredDrawObj.SetDrawObj( *this );
2393     // --> OD 2004-11-17 #i35635# - set initial position out of sight
2394     NbcMove( Size( -RECT_EMPTY, -RECT_EMPTY ) );
2395     // <--
2396 }
2397 
2398 SwDrawVirtObj::~SwDrawVirtObj()
2399 {}
2400 
2401 void SwDrawVirtObj::operator=( const SdrObject& rObj )
2402 {
2403 	SdrVirtObj::operator=(rObj);
2404     // Note: Members <maAnchoredDrawObj> and <mrDrawContact>
2405     //       haven't to be considered.
2406 }
2407 
2408 SdrObject* SwDrawVirtObj::Clone() const
2409 {
2410     SwDrawVirtObj* pObj = new SwDrawVirtObj( rRefObj, mrDrawContact );
2411 
2412     if ( pObj )
2413     {
2414         pObj->operator=(static_cast<const SdrObject&>(*this));
2415         // Note: Member <maAnchoredDrawObj> hasn't to be considered.
2416     }
2417 
2418     return pObj;
2419 }
2420 
2421 // --------------------------------------------------------------------
2422 // connection to writer layout: <GetAnchoredObj()>, <SetAnchorFrm(..)>,
2423 // <GetAnchorFrm()>, <SetPageFrm(..)>, <GetPageFrm()> and <RemoveFromWriterLayout()>
2424 // --------------------------------------------------------------------
2425 const SwAnchoredObject* SwDrawVirtObj::GetAnchoredObj() const
2426 {
2427     return &maAnchoredDrawObj;
2428 }
2429 
2430 SwAnchoredObject* SwDrawVirtObj::AnchoredObj()
2431 {
2432     return &maAnchoredDrawObj;
2433 }
2434 
2435 const SwFrm* SwDrawVirtObj::GetAnchorFrm() const
2436 {
2437     // OD 2004-03-29 #i26791# - use new member <maAnchoredDrawObj>
2438     return maAnchoredDrawObj.GetAnchorFrm();
2439 }
2440 
2441 SwFrm* SwDrawVirtObj::AnchorFrm()
2442 {
2443     // OD 2004-03-29 #i26791# - use new member <maAnchoredDrawObj>
2444     return maAnchoredDrawObj.AnchorFrm();
2445 }
2446 
2447 void SwDrawVirtObj::RemoveFromWriterLayout()
2448 {
2449     // remove contact object from frame for 'virtual' drawing object
2450     // OD 2004-03-29 #i26791# - use new member <maAnchoredDrawObj>
2451     if ( maAnchoredDrawObj.GetAnchorFrm() )
2452     {
2453         maAnchoredDrawObj.AnchorFrm()->RemoveDrawObj( maAnchoredDrawObj );
2454     }
2455 }
2456 
2457 // --------------------------------------------------------------------
2458 // connection to writer layout: <AddToDrawingPage()>, <RemoveFromDrawingPage()>
2459 // --------------------------------------------------------------------
2460 void SwDrawVirtObj::AddToDrawingPage()
2461 {
2462     // determine 'master'
2463     SdrObject* pOrgMasterSdrObj = mrDrawContact.GetMaster();
2464 
2465     // insert 'virtual' drawing object into page, set layer and user call.
2466     SdrPage* pDrawPg;
2467     // --> OD 2004-08-16 #i27030# - apply order number of referenced object
2468     if ( 0 != ( pDrawPg = pOrgMasterSdrObj->GetPage() ) )
2469     {
2470         // --> OD 2004-08-16 #i27030# - apply order number of referenced object
2471         pDrawPg->InsertObject( this, GetReferencedObj().GetOrdNum() );
2472     }
2473     else
2474     {
2475         pDrawPg = GetPage();
2476         if ( pDrawPg )
2477         {
2478             pDrawPg->SetObjectOrdNum( GetOrdNumDirect(),
2479                                       GetReferencedObj().GetOrdNum() );
2480         }
2481         else
2482         {
2483             SetOrdNum( GetReferencedObj().GetOrdNum() );
2484         }
2485     }
2486     // <--
2487     SetUserCall( &mrDrawContact );
2488 }
2489 
2490 void SwDrawVirtObj::RemoveFromDrawingPage()
2491 {
2492     SetUserCall( 0 );
2493     if ( GetPage() )
2494     {
2495         GetPage()->RemoveObject( GetOrdNum() );
2496     }
2497 }
2498 
2499 // is 'virtual' drawing object connected to writer layout and to drawing layer.
2500 bool SwDrawVirtObj::IsConnected() const
2501 {
2502     bool bRetVal = GetAnchorFrm() &&
2503                    ( GetPage() && GetUserCall() );
2504 
2505     return bRetVal;
2506 }
2507 
2508 void SwDrawVirtObj::NbcSetAnchorPos(const Point& rPnt)
2509 {
2510     SdrObject::NbcSetAnchorPos( rPnt );
2511 }
2512 
2513 //////////////////////////////////////////////////////////////////////////////
2514 // #i97197#
2515 // the methods relevant for positioning
2516 
2517 const Rectangle& SwDrawVirtObj::GetCurrentBoundRect() const
2518 {
2519     if(aOutRect.IsEmpty())
2520     {
2521         const_cast<SwDrawVirtObj*>(this)->RecalcBoundRect();
2522     }
2523 
2524     return aOutRect;
2525 }
2526 
2527 const Rectangle& SwDrawVirtObj::GetLastBoundRect() const
2528 {
2529 	return aOutRect;
2530 }
2531 
2532 const Point SwDrawVirtObj::GetOffset() const
2533 {
2534     // do NOT use IsEmpty() here, there is already a useful offset
2535     // in the position
2536     if(aOutRect == Rectangle())
2537     {
2538         return Point();
2539     }
2540     else
2541     {
2542         return aOutRect.TopLeft() - GetReferencedObj().GetCurrentBoundRect().TopLeft();
2543     }
2544 }
2545 
2546 void SwDrawVirtObj::SetBoundRectDirty()
2547 {
2548     // do nothing to not lose model information in aOutRect
2549 }
2550 
2551 void SwDrawVirtObj::RecalcBoundRect()
2552 {
2553     // OD 2004-04-05 #i26791# - switch order of calling <GetOffset()> and
2554     // <ReferencedObj().GetCurrentBoundRect()>, because <GetOffset()> calculates
2555     // its value by the 'BoundRect' of the referenced object.
2556     //aOutRect = rRefObj.GetCurrentBoundRect();
2557     //aOutRect += GetOffset();
2558 
2559     const Point aOffset(GetOffset());
2560     aOutRect = ReferencedObj().GetCurrentBoundRect() + aOffset;
2561 }
2562 
2563 basegfx::B2DPolyPolygon SwDrawVirtObj::TakeXorPoly() const
2564 {
2565 	basegfx::B2DPolyPolygon aRetval(rRefObj.TakeXorPoly());
2566 	aRetval.transform(basegfx::tools::createTranslateB2DHomMatrix(GetOffset().X(), GetOffset().Y()));
2567 
2568 	return aRetval;
2569 }
2570 
2571 basegfx::B2DPolyPolygon SwDrawVirtObj::TakeContour() const
2572 {
2573     basegfx::B2DPolyPolygon aRetval(rRefObj.TakeContour());
2574 	aRetval.transform(basegfx::tools::createTranslateB2DHomMatrix(GetOffset().X(), GetOffset().Y()));
2575 
2576 	return aRetval;
2577 }
2578 
2579 SdrHdl* SwDrawVirtObj::GetHdl(sal_uInt32 nHdlNum) const
2580 {
2581 	SdrHdl* pHdl = rRefObj.GetHdl(nHdlNum);
2582     Point aP(pHdl->GetPos() + GetOffset());
2583 	pHdl->SetPos(aP);
2584 
2585 	return pHdl;
2586 }
2587 
2588 SdrHdl* SwDrawVirtObj::GetPlusHdl(const SdrHdl& rHdl, sal_uInt16 nPlNum) const
2589 {
2590 	SdrHdl* pHdl = rRefObj.GetPlusHdl(rHdl, nPlNum);
2591     pHdl->SetPos(pHdl->GetPos() + GetOffset());
2592 
2593 	return pHdl;
2594 }
2595 
2596 void SwDrawVirtObj::NbcMove(const Size& rSiz)
2597 {
2598     SdrObject::NbcMove( rSiz );
2599 }
2600 
2601 void SwDrawVirtObj::NbcResize(const Point& rRef, const Fraction& xFact, const Fraction& yFact)
2602 {
2603     rRefObj.NbcResize(rRef - GetOffset(), xFact, yFact);
2604 	SetRectsDirty();
2605 }
2606 
2607 void SwDrawVirtObj::NbcRotate(const Point& rRef, long nWink, double sn, double cs)
2608 {
2609     rRefObj.NbcRotate(rRef - GetOffset(), nWink, sn, cs);
2610 	SetRectsDirty();
2611 }
2612 
2613 void SwDrawVirtObj::NbcMirror(const Point& rRef1, const Point& rRef2)
2614 {
2615     rRefObj.NbcMirror(rRef1 - GetOffset(), rRef2 - GetOffset());
2616 	SetRectsDirty();
2617 }
2618 
2619 void SwDrawVirtObj::NbcShear(const Point& rRef, long nWink, double tn, FASTBOOL bVShear)
2620 {
2621     rRefObj.NbcShear(rRef - GetOffset(), nWink, tn, bVShear);
2622 	SetRectsDirty();
2623 }
2624 
2625 void SwDrawVirtObj::Move(const Size& rSiz)
2626 {
2627     SdrObject::Move( rSiz );
2628 //    Rectangle aBoundRect0; if(pUserCall) aBoundRect0 = GetLastBoundRect();
2629 //    rRefObj.Move( rSiz );
2630 //    SetRectsDirty();
2631 //    SendUserCall(SDRUSERCALL_RESIZE, aBoundRect0);
2632 }
2633 
2634 void SwDrawVirtObj::Resize(const Point& rRef, const Fraction& xFact, const Fraction& yFact)
2635 {
2636 	if(xFact.GetNumerator() != xFact.GetDenominator() || yFact.GetNumerator() != yFact.GetDenominator())
2637 	{
2638 		Rectangle aBoundRect0; if(pUserCall) aBoundRect0 = GetLastBoundRect();
2639         rRefObj.Resize(rRef - GetOffset(), xFact, yFact);
2640 		SetRectsDirty();
2641 		SendUserCall(SDRUSERCALL_RESIZE, aBoundRect0);
2642 	}
2643 }
2644 
2645 void SwDrawVirtObj::Rotate(const Point& rRef, long nWink, double sn, double cs)
2646 {
2647 	if(nWink)
2648 	{
2649 		Rectangle aBoundRect0; if(pUserCall) aBoundRect0 = GetLastBoundRect();
2650         rRefObj.Rotate(rRef - GetOffset(), nWink, sn, cs);
2651 		SetRectsDirty();
2652 		SendUserCall(SDRUSERCALL_RESIZE, aBoundRect0);
2653 	}
2654 }
2655 
2656 void SwDrawVirtObj::Mirror(const Point& rRef1, const Point& rRef2)
2657 {
2658 	Rectangle aBoundRect0; if(pUserCall) aBoundRect0 = GetLastBoundRect();
2659     rRefObj.Mirror(rRef1 - GetOffset(), rRef2 - GetOffset());
2660 	SetRectsDirty();
2661 	SendUserCall(SDRUSERCALL_RESIZE, aBoundRect0);
2662 }
2663 
2664 void SwDrawVirtObj::Shear(const Point& rRef, long nWink, double tn, FASTBOOL bVShear)
2665 {
2666 	if(nWink)
2667 	{
2668 		Rectangle aBoundRect0; if(pUserCall) aBoundRect0 = GetLastBoundRect();
2669         rRefObj.Shear(rRef - GetOffset(), nWink, tn, bVShear);
2670 		SetRectsDirty();
2671 		SendUserCall(SDRUSERCALL_RESIZE, aBoundRect0);
2672 	}
2673 }
2674 
2675 void SwDrawVirtObj::RecalcSnapRect()
2676 {
2677     aSnapRect = rRefObj.GetSnapRect();
2678     aSnapRect += GetOffset();
2679 }
2680 
2681 const Rectangle& SwDrawVirtObj::GetSnapRect() const
2682 {
2683     ((SwDrawVirtObj*)this)->aSnapRect = rRefObj.GetSnapRect();
2684     ((SwDrawVirtObj*)this)->aSnapRect += GetOffset();
2685 
2686     return aSnapRect;
2687 }
2688 
2689 void SwDrawVirtObj::SetSnapRect(const Rectangle& rRect)
2690 {
2691 	Rectangle aBoundRect0; if(pUserCall) aBoundRect0 = GetLastBoundRect();
2692 	Rectangle aR(rRect);
2693     aR -= GetOffset();
2694 	rRefObj.SetSnapRect(aR);
2695 	SetRectsDirty();
2696 	SendUserCall(SDRUSERCALL_RESIZE, aBoundRect0);
2697 }
2698 
2699 void SwDrawVirtObj::NbcSetSnapRect(const Rectangle& rRect)
2700 {
2701 	Rectangle aR(rRect);
2702     aR -= GetOffset();
2703 	SetRectsDirty();
2704 	rRefObj.NbcSetSnapRect(aR);
2705 }
2706 
2707 const Rectangle& SwDrawVirtObj::GetLogicRect() const
2708 {
2709 	((SwDrawVirtObj*)this)->aSnapRect = rRefObj.GetLogicRect();
2710     ((SwDrawVirtObj*)this)->aSnapRect += GetOffset();
2711 
2712 	return aSnapRect;
2713 }
2714 
2715 void SwDrawVirtObj::SetLogicRect(const Rectangle& rRect)
2716 {
2717 	Rectangle aBoundRect0; if(pUserCall) aBoundRect0 = GetLastBoundRect();
2718 	Rectangle aR(rRect);
2719     aR -= GetOffset();
2720 	rRefObj.SetLogicRect(aR);
2721 	SetRectsDirty();
2722 	SendUserCall(SDRUSERCALL_RESIZE, aBoundRect0);
2723 }
2724 
2725 void SwDrawVirtObj::NbcSetLogicRect(const Rectangle& rRect)
2726 {
2727 	Rectangle aR(rRect);
2728     aR -= GetOffset();
2729 	rRefObj.NbcSetLogicRect(aR);
2730 	SetRectsDirty();
2731 }
2732 
2733 Point SwDrawVirtObj::GetSnapPoint(sal_uInt32 i) const
2734 {
2735 	Point aP(rRefObj.GetSnapPoint(i));
2736     aP += GetOffset();
2737 
2738 	return aP;
2739 }
2740 
2741 Point SwDrawVirtObj::GetPoint(sal_uInt32 i) const
2742 {
2743 	return Point(rRefObj.GetPoint(i) + GetOffset());
2744 }
2745 
2746 void SwDrawVirtObj::NbcSetPoint(const Point& rPnt, sal_uInt32 i)
2747 {
2748 	Point aP(rPnt);
2749     aP -= GetOffset();
2750 	rRefObj.SetPoint(aP, i);
2751 	SetRectsDirty();
2752 }
2753 
2754 // #108784#
2755 FASTBOOL SwDrawVirtObj::HasTextEdit() const
2756 {
2757 	return rRefObj.HasTextEdit();
2758 }
2759 
2760 // OD 18.06.2003 #108784# - overloaded 'layer' methods for 'virtual' drawing
2761 // object to assure, that layer of 'virtual' object is the layer of the referenced
2762 // object.
2763 SdrLayerID SwDrawVirtObj::GetLayer() const
2764 {
2765     return GetReferencedObj().GetLayer();
2766 }
2767 
2768 void SwDrawVirtObj::NbcSetLayer(SdrLayerID nLayer)
2769 {
2770     ReferencedObj().NbcSetLayer( nLayer );
2771     SdrVirtObj::NbcSetLayer( ReferencedObj().GetLayer() );
2772 }
2773 
2774 void SwDrawVirtObj::SetLayer(SdrLayerID nLayer)
2775 {
2776     ReferencedObj().SetLayer( nLayer );
2777     SdrVirtObj::NbcSetLayer( ReferencedObj().GetLayer() );
2778 }
2779 
2780 bool SwDrawVirtObj::supportsFullDrag() const
2781 {
2782     // call parent
2783     return SdrVirtObj::supportsFullDrag();
2784 }
2785 
2786 SdrObject* SwDrawVirtObj::getFullDragClone() const
2787 {
2788     // call parent
2789     return SdrVirtObj::getFullDragClone();
2790 }
2791 
2792 // eof
2793 
2794