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