merge the formfield patch from ooo-build
[ooovba.git] / sw / source / core / draw / dcontact.cxx
blob93f83256a9bdcf331a417d70ee8c79772316a21f
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: dcontact.cxx,v $
10 * $Revision: 1.61.210.2 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sw.hxx"
33 #include "hintids.hxx"
34 #include <svx/protitem.hxx>
35 #include <svx/opaqitem.hxx>
36 #include <svx/ulspitem.hxx>
37 #include <svx/lrspitem.hxx>
38 #include <svx/svdpage.hxx>
39 #include <svx/fmglob.hxx>
40 #include <svx/svdogrp.hxx>
41 #include <svx/svdotext.hxx>
42 #include <svx/svdmodel.hxx>
43 #include <svx/svdpagv.hxx>
44 #include <svx/svdviter.hxx>
45 #include <svx/svdview.hxx>
46 #include <svx/shapepropertynotifier.hxx>
47 // AW, OD 2004-04-30 #i28501#
48 #include <svx/sdr/contact/objectcontactofobjlistpainter.hxx>
49 #include <svx/sdr/contact/displayinfo.hxx>
50 #include <fmtornt.hxx>
51 #include <viewimp.hxx>
52 #include <fmtsrnd.hxx>
53 #include <fmtanchr.hxx>
54 #include <node.hxx>
55 #include <fmtcntnt.hxx>
56 #include <pagefrm.hxx>
57 #include <rootfrm.hxx>
58 #include <frmtool.hxx> // Notify_Background
59 #include <flyfrm.hxx>
60 #include <frmfmt.hxx>
61 #include <dflyobj.hxx>
62 #include <dcontact.hxx>
63 #include <unodraw.hxx>
64 #ifndef IDOCUMENTDRAWMODELACCESS_HXX_INCLUDED
65 #include <IDocumentDrawModelAccess.hxx>
66 #endif
67 #include <doc.hxx>
68 #include <hints.hxx>
69 #include <txtfrm.hxx>
70 #include <editsh.hxx>
71 #include <docary.hxx>
73 // OD 2004-02-11 #110582#-2
74 #include <flyfrms.hxx>
76 // OD 18.06.2003 #108784#
77 #include <algorithm>
78 // OD 2004-05-24 #i28701#
79 #include <sortedobjs.hxx>
80 #include <basegfx/matrix/b2dhommatrix.hxx>
82 // AW: For VCOfDrawVirtObj and stuff
83 #ifndef _SDR_CONTACT_VIEWCONTACTOFVIRTOBJ_HXX
84 #include <svx/sdr/contact/viewcontactofvirtobj.hxx>
85 #endif
87 #ifndef INCLUDED_DRAWINGLAYER_PRIMITIVE2D_TRANSFORMPRIMITIVE2D_HXX
88 #include <drawinglayer/primitive2d/transformprimitive2d.hxx>
89 #endif
91 #ifndef _SDR_CONTACT_VIEWOBJECTCONTACTOFSDROBJ_HXX
92 #include <svx/sdr/contact/viewobjectcontactofsdrobj.hxx>
93 #endif
95 #include <com/sun/star/text/WritingMode2.hpp>
97 using namespace ::com::sun::star;
100 TYPEINIT1( SwContact, SwClient )
101 TYPEINIT1( SwFlyDrawContact, SwContact )
102 TYPEINIT1( SwDrawContact, SwContact )
104 void setContextWritingMode( SdrObject* pObj, SwFrm* pAnchor )
106 if( pObj && pAnchor )
108 short nWritingDirection = text::WritingMode2::LR_TB;
109 if( pAnchor->IsVertical() )
111 nWritingDirection = text::WritingMode2::TB_RL;
112 } else if( pAnchor->IsRightToLeft() )
114 nWritingDirection = text::WritingMode2::RL_TB;
116 pObj->SetContextWritingMode( nWritingDirection );
121 //Der Umgekehrte Weg: Sucht das Format zum angegebenen Objekt.
122 //Wenn das Object ein SwVirtFlyDrawObj ist so wird das Format von
123 //selbigem besorgt.
124 //Anderfalls ist es eben ein einfaches Zeichenobjekt. Diese hat einen
125 //UserCall und der ist Client vom gesuchten Format.
127 SwFrmFmt *FindFrmFmt( SdrObject *pObj )
129 SwFrmFmt* pRetval = 0L;
131 if ( pObj->ISA(SwVirtFlyDrawObj) )
133 pRetval = ((SwVirtFlyDrawObj*)pObj)->GetFmt();
135 else
137 SwDrawContact* pContact = static_cast<SwDrawContact*>(GetUserCall( pObj ));
138 if ( pContact )
140 pRetval = pContact->GetFmt();
143 /* SJ: after prior consultation with OD we decided to remove this Assertion
144 #if OSL_DEBUG_LEVEL > 1
145 ASSERT( pRetval,
146 "<::FindFrmFmt(..)> - no frame format found for given object. Please inform OD." );
147 #endif
149 return pRetval;
152 sal_Bool HasWrap( const SdrObject* pObj )
154 if ( pObj )
156 const SwFrmFmt* pFmt = ::FindFrmFmt( pObj );
157 if ( pFmt )
159 return SURROUND_THROUGHT != pFmt->GetSurround().GetSurround();
163 return sal_False;
166 /*****************************************************************************
168 * GetBoundRect liefert das BoundRect _inklusive_ Abstand des Objekts.
170 *****************************************************************************/
172 // --> OD 2006-08-15 #i68520# - change naming
173 SwRect GetBoundRectOfAnchoredObj( const SdrObject* pObj )
174 // <--
176 SwRect aRet( pObj->GetCurrentBoundRect() );
177 // --> OD 2006-08-10 #i68520# - call cache of <SwAnchoredObject>
178 SwContact* pContact( GetUserCall( pObj ) );
179 if ( pContact )
181 const SwAnchoredObject* pAnchoredObj( pContact->GetAnchoredObj( pObj ) );
182 if ( pAnchoredObj )
184 aRet = pAnchoredObj->GetObjRectWithSpaces();
187 // <--
188 return aRet;
191 //Liefert den UserCall ggf. vom Gruppenobjekt
192 // OD 2004-03-31 #i26791# - change return type
193 SwContact* GetUserCall( const SdrObject* pObj )
195 SdrObject *pTmp;
196 while ( !pObj->GetUserCall() && 0 != (pTmp = pObj->GetUpGroup()) )
197 pObj = pTmp;
198 ASSERT( !pObj->GetUserCall() || pObj->GetUserCall()->ISA(SwContact),
199 "<::GetUserCall(..)> - wrong type of found object user call." );
200 return static_cast<SwContact*>(pObj->GetUserCall());
203 // liefert TRUE falls das SrdObject ein Marquee-Object (Lauftext) ist
204 BOOL IsMarqueeTextObj( const SdrObject& rObj )
206 SdrTextAniKind eTKind;
207 return SdrInventor == rObj.GetObjInventor() &&
208 OBJ_TEXT == rObj.GetObjIdentifier() &&
209 ( SDRTEXTANI_SCROLL == ( eTKind = ((SdrTextObj&)rObj).GetTextAniKind())
210 || SDRTEXTANI_ALTERNATE == eTKind || SDRTEXTANI_SLIDE == eTKind );
213 /*************************************************************************
215 |* SwContact, Ctor und Dtor
217 |* Ersterstellung AMA 27.Sep.96 18:13
218 |* Letzte Aenderung AMA 27.Sep.96
220 |*************************************************************************/
222 SwContact::SwContact( SwFrmFmt *pToRegisterIn ) :
223 SwClient( pToRegisterIn ),
224 // OD 05.09.2003 #112039# - init member <mbInDTOR>
225 mbInDTOR( false )
228 SwContact::~SwContact()
230 // OD 05.09.2003 #112039# - set <mbInDTOR>
231 SetInDTOR();
234 // OD 05.09.2003 #112039# - accessor for member <mbInDTOR>
235 bool SwContact::IsInDTOR() const
237 return mbInDTOR;
240 // OD 05.09.2003 #112039# - accessor to set member <mbInDTOR>
241 void SwContact::SetInDTOR()
243 mbInDTOR = true;
246 /** method to move drawing object to corresponding visible layer
248 OD 21.08.2003 #i18447#
250 @author OD
252 void SwContact::MoveObjToVisibleLayer( SdrObject* _pDrawObj )
254 // --> OD 2005-06-08 #i46297# - notify background about the arriving of
255 // the object and invalidate its position.
256 const bool bNotify( !GetFmt()->getIDocumentDrawModelAccess()->IsVisibleLayerId( _pDrawObj->GetLayer() ) );
257 // <--
259 _MoveObjToLayer( true, _pDrawObj );
261 // --> OD 2005-05-23 #i46297#
262 if ( bNotify )
264 SwAnchoredObject* pAnchoredObj = GetAnchoredObj( _pDrawObj );
265 ASSERT( pAnchoredObj,
266 "<SwContact::MoveObjToInvisibleLayer(..)> - missing anchored object" );
267 if ( pAnchoredObj )
269 ::setContextWritingMode( _pDrawObj, pAnchoredObj->GetAnchorFrmContainingAnchPos() );
270 // Note: as-character anchored objects aren't registered at a page frame and
271 // a notification of its background isn't needed.
272 if ( pAnchoredObj->GetPageFrm() )
274 ::Notify_Background( _pDrawObj, pAnchoredObj->GetPageFrm(),
275 pAnchoredObj->GetObjRect(), PREP_FLY_ARRIVE, TRUE );
278 pAnchoredObj->InvalidateObjPos();
281 // <--
284 /** method to move drawing object to corresponding invisible layer
286 OD 21.08.2003 #i18447#
288 @author OD
290 void SwContact::MoveObjToInvisibleLayer( SdrObject* _pDrawObj )
292 // --> OD 2005-06-08 #i46297# - notify background about the leaving of the object.
293 const bool bNotify( GetFmt()->getIDocumentDrawModelAccess()->IsVisibleLayerId( _pDrawObj->GetLayer() ) );
294 // <--
296 _MoveObjToLayer( false, _pDrawObj );
298 // --> OD 2005-05-19 #i46297#
299 if ( bNotify )
301 SwAnchoredObject* pAnchoredObj = GetAnchoredObj( _pDrawObj );
302 ASSERT( pAnchoredObj,
303 "<SwContact::MoveObjToInvisibleLayer(..)> - missing anchored object" );
304 // Note: as-character anchored objects aren't registered at a page frame and
305 // a notification of its background isn't needed.
306 if ( pAnchoredObj && pAnchoredObj->GetPageFrm() )
308 ::Notify_Background( _pDrawObj, pAnchoredObj->GetPageFrm(),
309 pAnchoredObj->GetObjRect(), PREP_FLY_LEAVE, TRUE );
312 // <--
315 /** method to move object to visible/invisible layer
317 OD 21.08.2003 #i18447#
318 implementation for the public method <MoveObjToVisibleLayer(..)>
319 and <MoveObjToInvisibleLayer(..)>
321 @author OD
323 void SwContact::_MoveObjToLayer( const bool _bToVisible,
324 SdrObject* _pDrawObj )
326 if ( !_pDrawObj )
328 ASSERT( false, "SwDrawContact::_MoveObjToLayer(..) - no drawing object!" );
329 return;
332 if ( !pRegisteredIn )
334 ASSERT( false, "SwDrawContact::_MoveObjToLayer(..) - no drawing frame format!" );
335 return;
338 const IDocumentDrawModelAccess* pIDDMA = static_cast<SwFrmFmt*>(pRegisteredIn)->getIDocumentDrawModelAccess();
339 if ( !pIDDMA )
341 ASSERT( false, "SwDrawContact::_MoveObjToLayer(..) - no writer document!" );
342 return;
345 SdrLayerID nToHellLayerId =
346 _bToVisible ? pIDDMA->GetHellId() : pIDDMA->GetInvisibleHellId();
347 SdrLayerID nToHeavenLayerId =
348 _bToVisible ? pIDDMA->GetHeavenId() : pIDDMA->GetInvisibleHeavenId();
349 SdrLayerID nToControlLayerId =
350 _bToVisible ? pIDDMA->GetControlsId() : pIDDMA->GetInvisibleControlsId();
351 SdrLayerID nFromHellLayerId =
352 _bToVisible ? pIDDMA->GetInvisibleHellId() : pIDDMA->GetHellId();
353 SdrLayerID nFromHeavenLayerId =
354 _bToVisible ? pIDDMA->GetInvisibleHeavenId() : pIDDMA->GetHeavenId();
355 SdrLayerID nFromControlLayerId =
356 _bToVisible ? pIDDMA->GetInvisibleControlsId() : pIDDMA->GetControlsId();
358 if ( _pDrawObj->ISA( SdrObjGroup ) )
360 // determine layer for group object
362 // proposed layer of a group object is the hell layer
363 SdrLayerID nNewLayerId = nToHellLayerId;
364 if ( ::CheckControlLayer( _pDrawObj ) )
366 // it has to be the control layer, if one of the member
367 // is a control
368 nNewLayerId = nToControlLayerId;
370 else if ( _pDrawObj->GetLayer() == pIDDMA->GetHeavenId() ||
371 _pDrawObj->GetLayer() == pIDDMA->GetInvisibleHeavenId() )
373 // it has to be the heaven layer, if method <GetLayer()> reveals
374 // a heaven layer
375 nNewLayerId = nToHeavenLayerId;
377 // set layer at group object, but do *not* broadcast and
378 // no propagation to the members.
379 // Thus, call <NbcSetLayer(..)> at super class
380 _pDrawObj->SdrObject::NbcSetLayer( nNewLayerId );
383 // call method recursively for group object members
384 const SdrObjList* pLst =
385 static_cast<SdrObjGroup*>(_pDrawObj)->GetSubList();
386 if ( pLst )
388 for ( USHORT i = 0; i < pLst->GetObjCount(); ++i )
390 _MoveObjToLayer( _bToVisible, pLst->GetObj( i ) );
394 else
396 const SdrLayerID nLayerIdOfObj = _pDrawObj->GetLayer();
397 if ( nLayerIdOfObj == nFromHellLayerId )
399 _pDrawObj->SetLayer( nToHellLayerId );
401 else if ( nLayerIdOfObj == nFromHeavenLayerId )
403 _pDrawObj->SetLayer( nToHeavenLayerId );
405 else if ( nLayerIdOfObj == nFromControlLayerId )
407 _pDrawObj->SetLayer( nToControlLayerId );
412 // -------------------------------------------------------------------------
413 // OD 2004-01-16 #110582# - some virtual helper methods for information
414 // about the object (Writer fly frame resp. drawing object)
416 const SwIndex& SwContact::GetCntntAnchorIndex() const
418 return GetCntntAnchor().nContent;
421 /** get minimum order number of anchored objects handled by with contact
423 OD 2004-08-24 #110810#
425 @author
427 sal_uInt32 SwContact::GetMinOrdNum() const
429 sal_uInt32 nMinOrdNum( SAL_MAX_UINT32 );
431 std::vector< SwAnchoredObject* > aObjs;
432 GetAnchoredObjs( aObjs );
434 while ( !aObjs.empty() )
436 sal_uInt32 nTmpOrdNum = aObjs.back()->GetDrawObj()->GetOrdNum();
438 if ( nTmpOrdNum < nMinOrdNum )
440 nMinOrdNum = nTmpOrdNum;
443 aObjs.pop_back();
446 ASSERT( nMinOrdNum != SAL_MAX_UINT32,
447 "<SwContact::GetMinOrdNum()> - no order number found." );
448 return nMinOrdNum;
451 /** get maximum order number of anchored objects handled by with contact
453 OD 2004-08-24 #110810#
455 @author
457 sal_uInt32 SwContact::GetMaxOrdNum() const
459 sal_uInt32 nMaxOrdNum( 0L );
461 std::vector< SwAnchoredObject* > aObjs;
462 GetAnchoredObjs( aObjs );
464 while ( !aObjs.empty() )
466 sal_uInt32 nTmpOrdNum = aObjs.back()->GetDrawObj()->GetOrdNum();
468 if ( nTmpOrdNum > nMaxOrdNum )
470 nMaxOrdNum = nTmpOrdNum;
473 aObjs.pop_back();
476 return nMaxOrdNum;
478 // -------------------------------------------------------------------------
480 /*************************************************************************
482 |* SwFlyDrawContact, Ctor und Dtor
484 |* Ersterstellung OK 23.11.94 18:13
485 |* Letzte Aenderung MA 06. Apr. 95
487 |*************************************************************************/
489 SwFlyDrawContact::SwFlyDrawContact( SwFlyFrmFmt *pToRegisterIn, SdrModel * ) :
490 SwContact( pToRegisterIn )
492 // OD 2004-04-01 #i26791# - class <SwFlyDrawContact> contains the 'master'
493 // drawing object of type <SwFlyDrawObj> on its own.
494 mpMasterObj = new SwFlyDrawObj;
495 mpMasterObj->SetOrdNum( 0xFFFFFFFE );
496 mpMasterObj->SetUserCall( this );
499 SwFlyDrawContact::~SwFlyDrawContact()
501 if ( mpMasterObj )
503 mpMasterObj->SetUserCall( 0 );
504 if ( mpMasterObj->GetPage() )
505 mpMasterObj->GetPage()->RemoveObject( mpMasterObj->GetOrdNum() );
506 delete mpMasterObj;
510 // OD 2004-03-29 #i26791#
511 const SwAnchoredObject* SwFlyDrawContact::GetAnchoredObj( const SdrObject* _pSdrObj ) const
513 ASSERT( _pSdrObj,
514 "<SwFlyDrawContact::GetAnchoredObj(..)> - no object provided" );
515 ASSERT( _pSdrObj->ISA(SwVirtFlyDrawObj),
516 "<SwFlyDrawContact::GetAnchoredObj(..)> - wrong object type object provided" );
517 ASSERT( GetUserCall( _pSdrObj ) == const_cast<SwFlyDrawContact*>(this),
518 "<SwFlyDrawContact::GetAnchoredObj(..)> - provided object doesn't belongs to this contact" );
520 const SwAnchoredObject* pRetAnchoredObj = 0L;
522 if ( _pSdrObj && _pSdrObj->ISA(SwVirtFlyDrawObj) )
524 pRetAnchoredObj = static_cast<const SwVirtFlyDrawObj*>(_pSdrObj)->GetFlyFrm();
527 return pRetAnchoredObj;
530 SwAnchoredObject* SwFlyDrawContact::GetAnchoredObj( SdrObject* _pSdrObj )
532 ASSERT( _pSdrObj,
533 "<SwFlyDrawContact::GetAnchoredObj(..)> - no object provided" );
534 ASSERT( _pSdrObj->ISA(SwVirtFlyDrawObj),
535 "<SwFlyDrawContact::GetAnchoredObj(..)> - wrong object type provided" );
536 ASSERT( GetUserCall( _pSdrObj ) == this,
537 "<SwFlyDrawContact::GetAnchoredObj(..)> - provided object doesn't belongs to this contact" );
539 SwAnchoredObject* pRetAnchoredObj = 0L;
541 if ( _pSdrObj && _pSdrObj->ISA(SwVirtFlyDrawObj) )
543 pRetAnchoredObj = static_cast<SwVirtFlyDrawObj*>(_pSdrObj)->GetFlyFrm();
546 return pRetAnchoredObj;
549 const SdrObject* SwFlyDrawContact::GetMaster() const
551 return mpMasterObj;
554 SdrObject* SwFlyDrawContact::GetMaster()
556 return mpMasterObj;
559 void SwFlyDrawContact::SetMaster( SdrObject* _pNewMaster )
561 ASSERT( _pNewMaster->ISA(SwFlyDrawObj),
562 "<SwFlyDrawContact::SetMaster(..)> - wrong type of new master object" );
563 mpMasterObj = static_cast<SwFlyDrawObj *>(_pNewMaster);
566 /*************************************************************************
568 |* SwFlyDrawContact::CreateNewRef()
570 |* Ersterstellung MA 14. Dec. 94
571 |* Letzte Aenderung MA 24. Apr. 95
573 |*************************************************************************/
575 SwVirtFlyDrawObj *SwFlyDrawContact::CreateNewRef( SwFlyFrm *pFly )
577 SwVirtFlyDrawObj *pDrawObj = new SwVirtFlyDrawObj( *GetMaster(), pFly );
578 pDrawObj->SetModel( GetMaster()->GetModel() );
579 pDrawObj->SetUserCall( this );
581 //Der Reader erzeugt die Master und setzt diese, um die Z-Order zu
582 //transportieren, in die Page ein. Beim erzeugen der ersten Referenz werden
583 //die Master aus der Liste entfernt und fuehren von da an ein
584 //Schattendasein.
585 SdrPage* pPg( 0L );
586 if ( 0 != ( pPg = GetMaster()->GetPage() ) )
588 const UINT32 nOrdNum = GetMaster()->GetOrdNum();
589 pPg->ReplaceObject( pDrawObj, nOrdNum );
591 // --> OD 2004-08-16 #i27030# - insert new <SwVirtFlyDrawObj> instance
592 // into drawing page with correct order number
593 else
595 GetFmt()->getIDocumentDrawModelAccess()->GetDrawModel()->GetPage( 0 )->
596 InsertObject( pDrawObj, _GetOrdNumForNewRef( pFly ) );
598 // <--
599 // --> OD 2004-12-13 #i38889# - assure, that new <SwVirtFlyDrawObj> instance
600 // is in a visible layer.
601 MoveObjToVisibleLayer( pDrawObj );
602 // <--
603 return pDrawObj;
606 /** method to determine new order number for new instance of <SwVirtFlyDrawObj>
608 OD 2004-08-16 #i27030#
609 Used in method <CreateNewRef(..)>
611 @author OD
613 sal_uInt32 SwFlyDrawContact::_GetOrdNumForNewRef( const SwFlyFrm* _pFlyFrm )
615 sal_uInt32 nOrdNum( 0L );
617 // search for another Writer fly frame registered at same frame format
618 SwClientIter aIter( *GetFmt() );
619 const SwFlyFrm* pFlyFrm( 0L );
620 for ( pFlyFrm = (SwFlyFrm*)aIter.First( TYPE(SwFlyFrm) );
621 pFlyFrm;
622 pFlyFrm = (SwFlyFrm*)aIter.Next() )
624 if ( pFlyFrm != _pFlyFrm )
626 break;
630 if ( pFlyFrm )
632 // another Writer fly frame found. Take its order number
633 nOrdNum = pFlyFrm->GetVirtDrawObj()->GetOrdNum();
635 else
637 // no other Writer fly frame found. Take order number of 'master' object
638 // --> OD 2004-11-11 #i35748# - use method <GetOrdNumDirect()> instead
639 // of method <GetOrdNum()> to avoid a recalculation of the order number,
640 // which isn't intended.
641 nOrdNum = GetMaster()->GetOrdNumDirect();
642 // <--
645 return nOrdNum;
648 /*************************************************************************
650 |* SwFlyDrawContact::Modify()
652 |* Ersterstellung OK 08.11.94 10:21
653 |* Letzte Aenderung MA 06. Dec. 94
655 |*************************************************************************/
657 void SwFlyDrawContact::Modify( SfxPoolItem *, SfxPoolItem * )
661 // OD 2004-01-16 #110582# - override method to control Writer fly frames,
662 // which are linked, and to assure that all objects anchored at/inside the
663 // Writer fly frame are also made visible.
664 void SwFlyDrawContact::MoveObjToVisibleLayer( SdrObject* _pDrawObj )
666 ASSERT( _pDrawObj->ISA(SwVirtFlyDrawObj),
667 "<SwFlyDrawContact::MoveObjToVisibleLayer(..)> - wrong SdrObject type -> crash" );
669 if ( GetFmt()->getIDocumentDrawModelAccess()->IsVisibleLayerId( _pDrawObj->GetLayer() ) )
671 // nothing to do
672 return;
675 SwFlyFrm* pFlyFrm = static_cast<SwVirtFlyDrawObj*>(_pDrawObj)->GetFlyFrm();
677 // --> OD 2005-03-09 #i44464# - consider, that Writer fly frame content
678 // already exists - (e.g. WW8 document is inserted into a existing document).
679 if ( !pFlyFrm->Lower() )
681 pFlyFrm->InsertColumns();
682 pFlyFrm->Chain( pFlyFrm->AnchorFrm() );
683 pFlyFrm->InsertCnt();
685 if ( pFlyFrm->GetDrawObjs() )
687 for ( sal_uInt8 i = 0; i < pFlyFrm->GetDrawObjs()->Count(); ++i)
689 // --> OD 2004-07-01 #i28701# - consider type of objects in sorted object list.
690 SdrObject* pObj = (*pFlyFrm->GetDrawObjs())[i]->DrawObj();
691 SwContact* pContact = static_cast<SwContact*>(pObj->GetUserCall());
692 pContact->MoveObjToVisibleLayer( pObj );
696 // make fly frame visible
697 SwContact::MoveObjToVisibleLayer( _pDrawObj );
700 // OD 2004-01-16 #110582# - override method to control Writer fly frames,
701 // which are linked, and to assure that all objects anchored at/inside the
702 // Writer fly frame are also made invisible.
703 void SwFlyDrawContact::MoveObjToInvisibleLayer( SdrObject* _pDrawObj )
705 ASSERT( _pDrawObj->ISA(SwVirtFlyDrawObj),
706 "<SwFlyDrawContact::MoveObjToInvisibleLayer(..)> - wrong SdrObject type -> crash" );
708 if ( !GetFmt()->getIDocumentDrawModelAccess()->IsVisibleLayerId( _pDrawObj->GetLayer() ) )
710 // nothing to do
711 return;
714 SwFlyFrm* pFlyFrm = static_cast<SwVirtFlyDrawObj*>(_pDrawObj)->GetFlyFrm();
716 pFlyFrm->Unchain();
717 pFlyFrm->DeleteCnt();
718 if ( pFlyFrm->GetDrawObjs() )
720 for ( sal_uInt8 i = 0; i < pFlyFrm->GetDrawObjs()->Count(); ++i)
722 // --> OD 2004-07-01 #i28701# - consider type of objects in sorted object list.
723 SdrObject* pObj = (*pFlyFrm->GetDrawObjs())[i]->DrawObj();
724 SwContact* pContact = static_cast<SwContact*>(pObj->GetUserCall());
725 pContact->MoveObjToInvisibleLayer( pObj );
729 // make fly frame invisible
730 SwContact::MoveObjToInvisibleLayer( _pDrawObj );
733 /** get data collection of anchored objects, handled by with contact
735 OD 2004-08-23 #110810#
737 @author
739 void SwFlyDrawContact::GetAnchoredObjs( std::vector<SwAnchoredObject*>& _roAnchoredObjs ) const
741 const SwFrmFmt* pFmt = GetFmt();
743 SwClientIter aIter( *(const_cast<SwFrmFmt*>(pFmt)) );
744 for( SwFlyFrm* pFlyFrm = (SwFlyFrm*)aIter.First( TYPE(SwFlyFrm) );
745 pFlyFrm;
746 pFlyFrm = (SwFlyFrm*)aIter.Next() )
748 _roAnchoredObjs.push_back( pFlyFrm );
752 /*************************************************************************
754 |* SwDrawContact, Ctor+Dtor
756 |* Ersterstellung MA 09. Jan. 95
757 |* Letzte Aenderung MA 22. Jul. 98
759 |*************************************************************************/
760 bool CheckControlLayer( const SdrObject *pObj )
762 if ( FmFormInventor == pObj->GetObjInventor() )
763 return true;
764 if ( pObj->ISA( SdrObjGroup ) )
766 const SdrObjList *pLst = ((SdrObjGroup*)pObj)->GetSubList();
767 for ( USHORT i = 0; i < pLst->GetObjCount(); ++i )
769 if ( ::CheckControlLayer( pLst->GetObj( i ) ) )
771 // OD 21.08.2003 #i18447# - return correct value ;-)
772 return true;
776 return false;
779 SwDrawContact::SwDrawContact( SwFrmFmt* pToRegisterIn, SdrObject* pObj ) :
780 SwContact( pToRegisterIn ),
781 maAnchoredDrawObj(),
782 mbMasterObjCleared( false ),
783 // OD 10.10.2003 #112299#
784 mbDisconnectInProgress( false ),
785 // --> OD 2006-01-18 #129959#
786 mbUserCallActive( false ),
787 // Note: value of <meEventTypeOfCurrentUserCall> isn't of relevance, because
788 // <mbUserCallActive> is FALSE.
789 meEventTypeOfCurrentUserCall( SDRUSERCALL_MOVEONLY )
790 // <--
792 // clear vector containing 'virtual' drawing objects.
793 maDrawVirtObjs.clear();
795 // --> OD 2004-09-22 #i33909# - assure, that drawing object is inserted
796 // in the drawing page.
797 if ( !pObj->IsInserted() )
799 pToRegisterIn->getIDocumentDrawModelAccess()->GetDrawModel()->GetPage(0)->
800 InsertObject( pObj, pObj->GetOrdNumDirect() );
802 // <--
804 //Controls muessen immer im Control-Layer liegen. Das gilt auch fuer
805 //Gruppenobjekte, wenn diese Controls enthalten.
806 if ( ::CheckControlLayer( pObj ) )
808 // OD 25.06.2003 #108784# - set layer of object to corresponding invisible layer.
809 pObj->SetLayer( pToRegisterIn->getIDocumentDrawModelAccess()->GetInvisibleControlsId() );
812 // OD 2004-03-29 #i26791#
813 pObj->SetUserCall( this );
814 maAnchoredDrawObj.SetDrawObj( *pObj );
816 // if there already exists an SwXShape for the object, ensure it knows about us, and the SdrObject
817 // FS 2009-04-07 #i99056#
818 SwXShape::AddExistingShapeToFmt( *pObj );
821 SwDrawContact::~SwDrawContact()
823 // OD 05.09.2003 #112039# - set <mbInDTOR>
824 SetInDTOR();
826 DisconnectFromLayout();
828 // OD 25.06.2003 #108784# - remove 'master' from drawing page
829 RemoveMasterFromDrawPage();
831 // remove and destroy 'virtual' drawing objects.
832 RemoveAllVirtObjs();
834 if ( !mbMasterObjCleared )
836 SdrObject* pObject = const_cast< SdrObject* >( maAnchoredDrawObj.GetDrawObj() );
837 SdrObject::Free( pObject );
841 // OD 2004-03-29 #i26791#
842 const SwAnchoredObject* SwDrawContact::GetAnchoredObj( const SdrObject* _pSdrObj ) const
844 // handle default parameter value
845 if ( !_pSdrObj )
847 _pSdrObj = GetMaster();
850 ASSERT( _pSdrObj,
851 "<SwDrawContact::GetAnchoredObj(..)> - no object provided" );
852 ASSERT( _pSdrObj->ISA(SwDrawVirtObj) ||
853 ( !_pSdrObj->ISA(SdrVirtObj) && !_pSdrObj->ISA(SwDrawVirtObj) ),
854 "<SwDrawContact::GetAnchoredObj(..)> - wrong object type object provided" );
855 ASSERT( GetUserCall( _pSdrObj ) == const_cast<SwDrawContact*>(this) ||
856 _pSdrObj == GetMaster(),
857 "<SwDrawContact::GetAnchoredObj(..)> - provided object doesn't belongs to this contact" );
859 const SwAnchoredObject* pRetAnchoredObj = 0L;
861 if ( _pSdrObj )
863 if ( _pSdrObj->ISA(SwDrawVirtObj) )
865 pRetAnchoredObj = static_cast<const SwDrawVirtObj*>(_pSdrObj)->GetAnchoredObj();
867 else if ( !_pSdrObj->ISA(SdrVirtObj) && !_pSdrObj->ISA(SwDrawVirtObj) )
869 pRetAnchoredObj = &maAnchoredDrawObj;
873 return pRetAnchoredObj;
876 SwAnchoredObject* SwDrawContact::GetAnchoredObj( SdrObject* _pSdrObj )
878 // handle default parameter value
879 if ( !_pSdrObj )
881 _pSdrObj = GetMaster();
884 ASSERT( _pSdrObj,
885 "<SwDrawContact::GetAnchoredObj(..)> - no object provided" );
886 ASSERT( _pSdrObj->ISA(SwDrawVirtObj) ||
887 ( !_pSdrObj->ISA(SdrVirtObj) && !_pSdrObj->ISA(SwDrawVirtObj) ),
888 "<SwDrawContact::GetAnchoredObj(..)> - wrong object type object provided" );
889 ASSERT( GetUserCall( _pSdrObj ) == this || _pSdrObj == GetMaster(),
890 "<SwDrawContact::GetAnchoredObj(..)> - provided object doesn't belongs to this contact" );
892 SwAnchoredObject* pRetAnchoredObj = 0L;
894 if ( _pSdrObj )
896 if ( _pSdrObj->ISA(SwDrawVirtObj) )
898 pRetAnchoredObj = static_cast<SwDrawVirtObj*>(_pSdrObj)->AnchoredObj();
900 else if ( !_pSdrObj->ISA(SdrVirtObj) && !_pSdrObj->ISA(SwDrawVirtObj) )
902 pRetAnchoredObj = &maAnchoredDrawObj;
906 return pRetAnchoredObj;
909 const SdrObject* SwDrawContact::GetMaster() const
911 return !mbMasterObjCleared
912 ? maAnchoredDrawObj.GetDrawObj()
913 : 0L;
916 SdrObject* SwDrawContact::GetMaster()
918 return !mbMasterObjCleared
919 ? maAnchoredDrawObj.DrawObj()
920 : 0L;
923 // OD 16.05.2003 #108784# - overload <SwContact::SetMaster(..)> in order to
924 // assert, if the 'master' drawing object is replaced.
925 // OD 10.07.2003 #110742# - replace of master object correctly handled, if
926 // handled by method <SwDrawContact::ChangeMasterObject(..)>. Thus, assert
927 // only, if a debug level is given.
928 void SwDrawContact::SetMaster( SdrObject* _pNewMaster )
930 if ( _pNewMaster )
932 #if OSL_DEBUG_LEVEL > 1
933 ASSERT( false, "debug notification - master replaced!" );
934 #endif
935 maAnchoredDrawObj.SetDrawObj( *_pNewMaster );
937 else
939 mbMasterObjCleared = true;
943 const SwFrm* SwDrawContact::GetAnchorFrm( const SdrObject* _pDrawObj ) const
945 const SwFrm* pAnchorFrm = 0L;
946 if ( !_pDrawObj ||
947 _pDrawObj == GetMaster() ||
948 ( !_pDrawObj->GetUserCall() &&
949 GetUserCall( _pDrawObj ) == static_cast<const SwContact* const>(this) ) )
951 pAnchorFrm = maAnchoredDrawObj.GetAnchorFrm();
953 else if ( _pDrawObj->ISA(SwDrawVirtObj) )
955 pAnchorFrm = static_cast<const SwDrawVirtObj*>(_pDrawObj)->GetAnchorFrm();
957 else
959 ASSERT( false,
960 "<SwDrawContact::GetAnchorFrm(..)> - unknown drawing object." )
963 return pAnchorFrm;
965 SwFrm* SwDrawContact::GetAnchorFrm( SdrObject* _pDrawObj )
967 SwFrm* pAnchorFrm = 0L;
968 if ( !_pDrawObj ||
969 _pDrawObj == GetMaster() ||
970 ( !_pDrawObj->GetUserCall() &&
971 GetUserCall( _pDrawObj ) == this ) )
973 pAnchorFrm = maAnchoredDrawObj.AnchorFrm();
975 else
977 ASSERT( _pDrawObj->ISA(SwDrawVirtObj),
978 "<SwDrawContact::GetAnchorFrm(..)> - unknown drawing object." )
979 pAnchorFrm = static_cast<SwDrawVirtObj*>(_pDrawObj)->AnchorFrm();
982 return pAnchorFrm;
985 // OD 23.06.2003 #108784# - method to create a new 'virtual' drawing object.
986 SwDrawVirtObj* SwDrawContact::CreateVirtObj()
988 // determine 'master'
989 SdrObject* pOrgMasterSdrObj = GetMaster();
991 // create 'virtual' drawing object
992 SwDrawVirtObj* pNewDrawVirtObj = new SwDrawVirtObj ( *(pOrgMasterSdrObj), *(this) );
994 // add new 'virtual' drawing object managing data structure
995 maDrawVirtObjs.push_back( pNewDrawVirtObj );
997 return pNewDrawVirtObj;
1000 // OD 23.06.2003 #108784# - destroys a given 'virtual' drawing object.
1001 // side effect: 'virtual' drawing object is removed from data structure
1002 // <maDrawVirtObjs>.
1003 void SwDrawContact::DestroyVirtObj( SwDrawVirtObj* _pVirtObj )
1005 if ( _pVirtObj )
1007 delete _pVirtObj;
1008 _pVirtObj = 0;
1012 // OD 16.05.2003 #108784# - add a 'virtual' drawing object to drawing page.
1013 // Use an already created one, which isn't used, or create a new one.
1014 SwDrawVirtObj* SwDrawContact::AddVirtObj()
1016 SwDrawVirtObj* pAddedDrawVirtObj = 0L;
1018 // check, if a disconnected 'virtual' drawing object exist and use it
1019 std::list<SwDrawVirtObj*>::const_iterator aFoundVirtObjIter =
1020 std::find_if( maDrawVirtObjs.begin(), maDrawVirtObjs.end(),
1021 UsedOrUnusedVirtObjPred( false ) );
1023 if ( aFoundVirtObjIter != maDrawVirtObjs.end() )
1025 // use already created, disconnected 'virtual' drawing object
1026 pAddedDrawVirtObj = (*aFoundVirtObjIter);
1028 else
1030 // create new 'virtual' drawing object.
1031 pAddedDrawVirtObj = CreateVirtObj();
1033 pAddedDrawVirtObj->AddToDrawingPage();
1035 return pAddedDrawVirtObj;
1038 // OD 16.05.2003 #108784# - remove 'virtual' drawing objects and destroy them.
1039 void SwDrawContact::RemoveAllVirtObjs()
1041 for ( std::list<SwDrawVirtObj*>::iterator aDrawVirtObjsIter = maDrawVirtObjs.begin();
1042 aDrawVirtObjsIter != maDrawVirtObjs.end();
1043 ++aDrawVirtObjsIter )
1045 // remove and destroy 'virtual object'
1046 SwDrawVirtObj* pDrawVirtObj = (*aDrawVirtObjsIter);
1047 pDrawVirtObj->RemoveFromWriterLayout();
1048 pDrawVirtObj->RemoveFromDrawingPage();
1049 DestroyVirtObj( pDrawVirtObj );
1051 maDrawVirtObjs.clear();
1054 SwDrawContact::VirtObjAnchoredAtFrmPred::VirtObjAnchoredAtFrmPred(
1055 const SwFrm& _rAnchorFrm )
1056 : mpAnchorFrm( &_rAnchorFrm )
1058 if ( mpAnchorFrm->IsCntntFrm() )
1060 const SwCntntFrm* pTmpFrm =
1061 static_cast<const SwCntntFrm*>( mpAnchorFrm );
1062 while ( pTmpFrm->IsFollow() )
1064 pTmpFrm = pTmpFrm->FindMaster();
1066 mpAnchorFrm = pTmpFrm;
1070 // OD 2004-04-14 #i26791# - compare with master frame
1071 bool SwDrawContact::VirtObjAnchoredAtFrmPred::operator() ( const SwDrawVirtObj* _pDrawVirtObj )
1073 const SwFrm* pObjAnchorFrm = _pDrawVirtObj->GetAnchorFrm();
1074 if ( pObjAnchorFrm && pObjAnchorFrm->IsCntntFrm() )
1076 const SwCntntFrm* pTmpFrm =
1077 static_cast<const SwCntntFrm*>( pObjAnchorFrm );
1078 while ( pTmpFrm->IsFollow() )
1080 pTmpFrm = pTmpFrm->FindMaster();
1082 pObjAnchorFrm = pTmpFrm;
1085 return ( pObjAnchorFrm == mpAnchorFrm );
1088 // OD 19.06.2003 #108784# - get drawing object ('master' or 'virtual') by frame.
1089 SdrObject* SwDrawContact::GetDrawObjectByAnchorFrm( const SwFrm& _rAnchorFrm )
1091 SdrObject* pRetDrawObj = 0L;
1093 // OD 2004-04-14 #i26791# - compare master frames instead of direct frames
1094 const SwFrm* pProposedAnchorFrm = &_rAnchorFrm;
1095 if ( pProposedAnchorFrm->IsCntntFrm() )
1097 const SwCntntFrm* pTmpFrm =
1098 static_cast<const SwCntntFrm*>( pProposedAnchorFrm );
1099 while ( pTmpFrm->IsFollow() )
1101 pTmpFrm = pTmpFrm->FindMaster();
1103 pProposedAnchorFrm = pTmpFrm;
1106 const SwFrm* pMasterObjAnchorFrm = GetAnchorFrm();
1107 if ( pMasterObjAnchorFrm && pMasterObjAnchorFrm->IsCntntFrm() )
1109 const SwCntntFrm* pTmpFrm =
1110 static_cast<const SwCntntFrm*>( pMasterObjAnchorFrm );
1111 while ( pTmpFrm->IsFollow() )
1113 pTmpFrm = pTmpFrm->FindMaster();
1115 pMasterObjAnchorFrm = pTmpFrm;
1118 if ( pMasterObjAnchorFrm && pMasterObjAnchorFrm == pProposedAnchorFrm )
1120 pRetDrawObj = GetMaster();
1122 else
1124 std::list<SwDrawVirtObj*>::const_iterator aFoundVirtObjIter =
1125 std::find_if( maDrawVirtObjs.begin(), maDrawVirtObjs.end(),
1126 VirtObjAnchoredAtFrmPred( *pProposedAnchorFrm ) );
1128 if ( aFoundVirtObjIter != maDrawVirtObjs.end() )
1130 pRetDrawObj = (*aFoundVirtObjIter);
1134 return pRetDrawObj;
1137 /*************************************************************************
1139 |* SwDrawContact::Changed
1141 |* Ersterstellung MA 09. Jan. 95
1142 |* Letzte Aenderung MA 29. May. 96
1144 |*************************************************************************/
1146 // OD 03.07.2003 #108784#
1147 void SwDrawContact::NotifyBackgrdOfAllVirtObjs( const Rectangle* pOldBoundRect )
1149 for ( std::list<SwDrawVirtObj*>::iterator aDrawVirtObjIter = maDrawVirtObjs.begin();
1150 aDrawVirtObjIter != maDrawVirtObjs.end();
1151 ++aDrawVirtObjIter )
1153 SwDrawVirtObj* pDrawVirtObj = (*aDrawVirtObjIter);
1154 if ( pDrawVirtObj->GetAnchorFrm() )
1156 // --> OD 2004-10-21 #i34640# - determine correct page frame
1157 SwPageFrm* pPage = pDrawVirtObj->AnchoredObj()->FindPageFrmOfAnchor();
1158 // <--
1159 if( pOldBoundRect && pPage )
1161 SwRect aOldRect( *pOldBoundRect );
1162 aOldRect.Pos() += pDrawVirtObj->GetOffset();
1163 if( aOldRect.HasArea() )
1164 ::Notify_Background( pDrawVirtObj, pPage,
1165 aOldRect, PREP_FLY_LEAVE,TRUE);
1167 // --> OD 2004-10-21 #i34640# - include spacing for wrapping
1168 SwRect aRect( pDrawVirtObj->GetAnchoredObj()->GetObjRectWithSpaces() );
1169 // <--
1170 if( aRect.HasArea() )
1172 // --> OD 2004-10-21 #i34640# - simplify
1173 SwPageFrm* pPg = (SwPageFrm*)::FindPage( aRect, pPage );
1174 // <--
1175 if ( pPg )
1176 ::Notify_Background( pDrawVirtObj, pPg, aRect,
1177 PREP_FLY_ARRIVE, TRUE );
1179 ::ClrContourCache( pDrawVirtObj );
1184 // OD 2004-04-08 #i26791# - local method to notify the background for a drawing object
1185 void lcl_NotifyBackgroundOfObj( SwDrawContact& _rDrawContact,
1186 const SdrObject& _rObj,
1187 const Rectangle* _pOldObjRect )
1189 // --> OD 2004-10-21 #i34640#
1190 SwAnchoredObject* pAnchoredObj =
1191 const_cast<SwAnchoredObject*>(_rDrawContact.GetAnchoredObj( &_rObj ));
1192 if ( pAnchoredObj && pAnchoredObj->GetAnchorFrm() )
1193 // <--
1195 // --> OD 2004-10-21 #i34640# - determine correct page frame
1196 SwPageFrm* pPageFrm = pAnchoredObj->FindPageFrmOfAnchor();
1197 // <--
1198 if( _pOldObjRect && pPageFrm )
1200 SwRect aOldRect( *_pOldObjRect );
1201 if( aOldRect.HasArea() )
1203 // --> OD 2004-10-21 #i34640# - determine correct page frame
1204 SwPageFrm* pOldPageFrm = (SwPageFrm*)::FindPage( aOldRect, pPageFrm );
1205 // <--
1206 ::Notify_Background( &_rObj, pOldPageFrm, aOldRect,
1207 PREP_FLY_LEAVE, TRUE);
1210 // --> OD 2004-10-21 #i34640# - include spacing for wrapping
1211 SwRect aNewRect( pAnchoredObj->GetObjRectWithSpaces() );
1212 // <--
1213 if( aNewRect.HasArea() && pPageFrm )
1215 pPageFrm = (SwPageFrm*)::FindPage( aNewRect, pPageFrm );
1216 ::Notify_Background( &_rObj, pPageFrm, aNewRect,
1217 PREP_FLY_ARRIVE, TRUE );
1219 ClrContourCache( &_rObj );
1223 void SwDrawContact::Changed( const SdrObject& rObj,
1224 SdrUserCallType eType,
1225 const Rectangle& rOldBoundRect )
1227 // OD 2004-06-01 #i26791# - no event handling, if existing <ViewShell>
1228 // is in contruction
1229 SwDoc* pDoc = GetFmt()->GetDoc();
1230 if ( pDoc->GetRootFrm() &&
1231 pDoc->GetRootFrm()->GetCurrShell() &&
1232 pDoc->GetRootFrm()->GetCurrShell()->IsInConstructor() )
1234 return;
1237 // --> OD 2005-03-08 #i44339#
1238 // no event handling, if document is in destruction.
1239 // Exception: It's the SDRUSERCALL_DELETE event
1240 if ( pDoc->IsInDtor() && eType != SDRUSERCALL_DELETE )
1242 return;
1244 // <--
1246 //Action aufsetzen, aber nicht wenn gerade irgendwo eine Action laeuft.
1247 ViewShell *pSh = 0, *pOrg;
1248 if ( pDoc->GetRootFrm() && pDoc->GetRootFrm()->IsCallbackActionEnabled() )
1250 pDoc->GetEditShell( &pOrg );
1251 pSh = pOrg;
1252 if ( pSh )
1254 { if ( pSh->Imp()->IsAction() || pSh->Imp()->IsIdleAction() )
1255 pSh = 0;
1256 else
1257 pSh = (ViewShell*)pSh->GetNext();
1259 } while ( pSh && pSh != pOrg );
1261 if ( pSh )
1262 pDoc->GetRootFrm()->StartAllAction();
1264 SdrObjUserCall::Changed( rObj, eType, rOldBoundRect );
1265 _Changed( rObj, eType, &rOldBoundRect ); //Achtung, ggf. Suizid!
1267 if ( pSh )
1268 pDoc->GetRootFrm()->EndAllAction();
1271 // --> OD 2006-01-18 #129959#
1272 // helper class for method <SwDrawContact::_Changed(..)> for handling nested
1273 // <SdrObjUserCall> events
1274 class NestedUserCallHdl
1276 private:
1277 SwDrawContact* mpDrawContact;
1278 bool mbParentUserCallActive;
1279 SdrUserCallType meParentUserCallEventType;
1281 public:
1282 NestedUserCallHdl( SwDrawContact* _pDrawContact,
1283 SdrUserCallType _eEventType )
1284 : mpDrawContact( _pDrawContact ),
1285 mbParentUserCallActive( _pDrawContact->mbUserCallActive ),
1286 meParentUserCallEventType( _pDrawContact->meEventTypeOfCurrentUserCall )
1288 mpDrawContact->mbUserCallActive = true;
1289 mpDrawContact->meEventTypeOfCurrentUserCall = _eEventType;
1292 ~NestedUserCallHdl()
1294 if ( mpDrawContact )
1296 mpDrawContact->mbUserCallActive = mbParentUserCallActive;
1297 mpDrawContact->meEventTypeOfCurrentUserCall = meParentUserCallEventType;
1301 void DrawContactDeleted()
1303 mpDrawContact = 0;
1306 bool IsNestedUserCall()
1308 return mbParentUserCallActive;
1311 void AssertNestedUserCall()
1313 if ( IsNestedUserCall() )
1315 bool bTmpAssert( true );
1316 // Currently its known, that a nested event SDRUSERCALL_RESIZE
1317 // could occur during parent user call SDRUSERCALL_INSERTED,
1318 // SDRUSERCALL_DELETE and SDRUSERCALL_RESIZE for edge objects.
1319 // Also possible are nested SDRUSERCALL_CHILD_RESIZE events for
1320 // edge objects
1321 // Thus, assert all other combinations
1322 if ( ( meParentUserCallEventType == SDRUSERCALL_INSERTED ||
1323 meParentUserCallEventType == SDRUSERCALL_DELETE ||
1324 meParentUserCallEventType == SDRUSERCALL_RESIZE ) &&
1325 mpDrawContact->meEventTypeOfCurrentUserCall == SDRUSERCALL_RESIZE )
1327 bTmpAssert = false;
1329 else if ( meParentUserCallEventType == SDRUSERCALL_CHILD_RESIZE &&
1330 mpDrawContact->meEventTypeOfCurrentUserCall == SDRUSERCALL_CHILD_RESIZE )
1332 bTmpAssert = false;
1335 if ( bTmpAssert )
1337 ASSERT( false,
1338 "<SwDrawContact::_Changed(..)> - unknown nested <UserCall> event. This is serious, please inform OD." );
1344 // <--
1346 // !!!ACHTUNG!!! The object may commit suicide!!!
1348 void SwDrawContact::_Changed( const SdrObject& rObj,
1349 SdrUserCallType eType,
1350 const Rectangle* pOldBoundRect )
1352 // --> OD 2006-01-18 #129959#
1353 // suppress handling of nested <SdrObjUserCall> events
1354 NestedUserCallHdl aNestedUserCallHdl( this, eType );
1355 if ( aNestedUserCallHdl.IsNestedUserCall() )
1357 aNestedUserCallHdl.AssertNestedUserCall();
1358 return;
1360 // <--
1361 // OD 05.08.2002 #100843# - do *not* notify, if document is destructing
1362 // --> OD 2004-10-21 #i35912# - do *not* notify for as-character anchored
1363 // drawing objects.
1364 // --> OD 2004-11-11 #i35007#
1365 // improvement: determine as-character anchored object flag only once.
1366 const bool bAnchoredAsChar = ObjAnchoredAsChar();
1367 // <--
1368 const bool bNotify = !(GetFmt()->GetDoc()->IsInDtor()) &&
1369 ( SURROUND_THROUGHT != GetFmt()->GetSurround().GetSurround() ) &&
1370 !bAnchoredAsChar;
1371 // <--
1372 switch( eType )
1374 case SDRUSERCALL_DELETE:
1376 if ( bNotify )
1378 lcl_NotifyBackgroundOfObj( *this, rObj, pOldBoundRect );
1379 // --> OD 2004-10-27 #i36181# - background of 'virtual'
1380 // drawing objects have also been notified.
1381 NotifyBackgrdOfAllVirtObjs( pOldBoundRect );
1382 // <--
1384 DisconnectFromLayout( false );
1385 SetMaster( NULL );
1386 delete this;
1387 // --> FME 2006-07-12 #i65784# Prevent memory corruption
1388 aNestedUserCallHdl.DrawContactDeleted();
1389 // <--
1390 break;
1392 case SDRUSERCALL_INSERTED:
1394 // OD 10.10.2003 #112299#
1395 if ( mbDisconnectInProgress )
1397 ASSERT( false,
1398 "<SwDrawContact::_Changed(..)> - Insert event during disconnection from layout is invalid." );
1400 else
1402 ConnectToLayout();
1403 if ( bNotify )
1405 lcl_NotifyBackgroundOfObj( *this, rObj, pOldBoundRect );
1408 break;
1410 case SDRUSERCALL_REMOVED:
1412 if ( bNotify )
1414 lcl_NotifyBackgroundOfObj( *this, rObj, pOldBoundRect );
1416 DisconnectFromLayout( false );
1417 break;
1419 case SDRUSERCALL_MOVEONLY:
1420 case SDRUSERCALL_RESIZE:
1421 case SDRUSERCALL_CHILD_MOVEONLY :
1422 case SDRUSERCALL_CHILD_RESIZE :
1423 case SDRUSERCALL_CHILD_CHGATTR :
1424 case SDRUSERCALL_CHILD_DELETE :
1425 case SDRUSERCALL_CHILD_COPY :
1426 case SDRUSERCALL_CHILD_INSERTED :
1427 case SDRUSERCALL_CHILD_REMOVED :
1429 // --> OD 2004-08-04 #i31698# - improvement:
1430 // get instance <SwAnchoredDrawObject> only once
1431 const SwAnchoredDrawObject* pAnchoredDrawObj =
1432 static_cast<const SwAnchoredDrawObject*>( GetAnchoredObj( &rObj ) );
1433 // <--
1434 // OD 2004-04-06 #i26791# - adjust positioning and alignment attributes,
1435 // if positioning of drawing object isn't in progress.
1436 // --> OD 2005-08-15 #i53320# - no adjust of positioning attributes,
1437 // if drawing object isn't positioned.
1438 if ( !pAnchoredDrawObj->IsPositioningInProgress() &&
1439 !pAnchoredDrawObj->NotYetPositioned() )
1440 // <--
1442 // --> OD 2004-09-29 #i34748# - If no last object rectangle is
1443 // provided by the anchored object, use parameter <pOldBoundRect>.
1444 const Rectangle& aOldObjRect = pAnchoredDrawObj->GetLastObjRect()
1445 ? *(pAnchoredDrawObj->GetLastObjRect())
1446 : *(pOldBoundRect);
1447 // <--
1448 // --> OD 2008-02-18 #i79400#
1449 // always invalidate object rectangle inclusive spaces
1450 pAnchoredDrawObj->InvalidateObjRectWithSpaces();
1451 // <--
1452 // --> OD 2005-01-28 #i41324# - notify background before
1453 // adjusting position
1454 if ( bNotify )
1456 // --> OD 2004-07-20 #i31573# - correction: Only invalidate
1457 // background of given drawing object.
1458 lcl_NotifyBackgroundOfObj( *this, rObj, &aOldObjRect );
1460 // <--
1461 // --> OD 2004-08-04 #i31698# - determine layout direction
1462 // via draw frame format.
1463 SwFrmFmt::tLayoutDir eLayoutDir =
1464 pAnchoredDrawObj->GetFrmFmt().GetLayoutDir();
1465 // <--
1466 // use geometry of drawing object
1467 SwRect aObjRect( rObj.GetSnapRect() );
1468 // If drawing object is a member of a group, the adjustment
1469 // of the positioning and the alignment attributes has to
1470 // be done for the top group object.
1471 if ( rObj.GetUpGroup() )
1473 const SdrObject* pGroupObj = rObj.GetUpGroup();
1474 while ( pGroupObj->GetUpGroup() )
1476 pGroupObj = pGroupObj->GetUpGroup();
1478 // use geometry of drawing object
1479 aObjRect = pGroupObj->GetSnapRect();
1481 SwTwips nXPosDiff(0L);
1482 SwTwips nYPosDiff(0L);
1483 switch ( eLayoutDir )
1485 case SwFrmFmt::HORI_L2R:
1487 nXPosDiff = aObjRect.Left() - aOldObjRect.Left();
1488 nYPosDiff = aObjRect.Top() - aOldObjRect.Top();
1490 break;
1491 case SwFrmFmt::HORI_R2L:
1493 nXPosDiff = aOldObjRect.Right() - aObjRect.Right();
1494 nYPosDiff = aObjRect.Top() - aOldObjRect.Top();
1496 break;
1497 case SwFrmFmt::VERT_R2L:
1499 nXPosDiff = aObjRect.Top() - aOldObjRect.Top();
1500 nYPosDiff = aOldObjRect.Right() - aObjRect.Right();
1502 break;
1503 default:
1505 ASSERT( false,
1506 "<SwDrawContact::_Changed(..)> - unsupported layout direction" );
1509 SfxItemSet aSet( GetFmt()->GetDoc()->GetAttrPool(),
1510 RES_VERT_ORIENT, RES_HORI_ORIENT, 0 );
1511 const SwFmtVertOrient& rVert = GetFmt()->GetVertOrient();
1512 if ( nYPosDiff != 0 )
1515 if ( rVert.GetRelationOrient() == text::RelOrientation::CHAR ||
1516 rVert.GetRelationOrient() == text::RelOrientation::TEXT_LINE )
1518 nYPosDiff = -nYPosDiff;
1520 aSet.Put( SwFmtVertOrient( rVert.GetPos()+nYPosDiff,
1521 text::VertOrientation::NONE,
1522 rVert.GetRelationOrient() ) );
1525 const SwFmtHoriOrient& rHori = GetFmt()->GetHoriOrient();
1526 if ( !bAnchoredAsChar && nXPosDiff != 0 )
1528 aSet.Put( SwFmtHoriOrient( rHori.GetPos()+nXPosDiff,
1529 text::HoriOrientation::NONE,
1530 rHori.GetRelationOrient() ) );
1533 if ( nYPosDiff ||
1534 ( !bAnchoredAsChar && nXPosDiff != 0 ) )
1536 GetFmt()->GetDoc()->SetFlyFrmAttr( *(GetFmt()), aSet );
1537 // keep new object rectangle, to avoid multiple
1538 // changes of the attributes by multiple event from
1539 // the drawing layer - e.g. group objects and its members
1540 // --> OD 2004-09-29 #i34748# - use new method
1541 // <SwAnchoredDrawObject::SetLastObjRect(..)>.
1542 const_cast<SwAnchoredDrawObject*>(pAnchoredDrawObj)
1543 ->SetLastObjRect( aObjRect.SVRect() );
1545 else if ( aObjRect.SSize() != aOldObjRect.GetSize() )
1547 _InvalidateObjs();
1548 // --> OD 2004-11-11 #i35007# - notify anchor frame
1549 // of as-character anchored object
1550 if ( bAnchoredAsChar )
1552 const_cast<SwAnchoredDrawObject*>(pAnchoredDrawObj)
1553 ->AnchorFrm()->Prepare( PREP_FLY_ATTR_CHG, GetFmt() );
1555 // <--
1558 // --> OD 2006-01-18 #129959#
1559 // It reveals that the following code causes several defects -
1560 // on copying or on ungrouping a group shape containing edge objects.
1561 // Testing fix for #i53320# also reveal that the following code
1562 // isn't necessary.
1563 // // --> OD 2005-08-15 #i53320# - reset positioning attributes,
1564 // // if anchored drawing object isn't yet positioned.
1565 // else if ( pAnchoredDrawObj->NotYetPositioned() &&
1566 // static_cast<const SwDrawFrmFmt&>(pAnchoredDrawObj->GetFrmFmt()).IsPosAttrSet() )
1567 // {
1568 // const_cast<SwDrawFrmFmt&>(
1569 // static_cast<const SwDrawFrmFmt&>(pAnchoredDrawObj->GetFrmFmt()))
1570 // .ResetPosAttr();
1571 // }
1572 // // <--
1573 // <--
1575 break;
1576 case SDRUSERCALL_CHGATTR:
1577 if ( bNotify )
1579 lcl_NotifyBackgroundOfObj( *this, rObj, pOldBoundRect );
1581 break;
1582 default:
1583 break;
1587 namespace
1589 static const SwFmtAnchor* lcl_getAnchorFmt( const SfxPoolItem& _rItem )
1591 USHORT nWhich = _rItem.Which();
1592 const SwFmtAnchor* pAnchorFmt = NULL;
1593 if ( RES_ATTRSET_CHG == nWhich )
1595 static_cast<const SwAttrSetChg&>(_rItem).GetChgSet()->
1596 GetItemState( RES_ANCHOR, FALSE, (const SfxPoolItem**)&pAnchorFmt );
1598 else if ( RES_ANCHOR == nWhich )
1600 pAnchorFmt = &static_cast<const SwFmtAnchor&>(_rItem);
1602 return pAnchorFmt;
1606 /*************************************************************************
1608 |* SwDrawContact::Modify()
1610 |* Ersterstellung MA 09. Jan. 95
1611 |* Letzte Aenderung MA 03. Dec. 95
1613 |*************************************************************************/
1615 void SwDrawContact::Modify( SfxPoolItem *pOld, SfxPoolItem *pNew )
1617 // OD 10.10.2003 #112299#
1618 ASSERT( !mbDisconnectInProgress,
1619 "<SwDrawContact::Modify(..)> called during disconnection.");
1621 USHORT nWhich = pNew ? pNew->Which() : 0;
1622 const SwFmtAnchor* pNewAnchorFmt = pNew ? lcl_getAnchorFmt( *pNew ) : NULL;
1624 if ( pNewAnchorFmt )
1626 // JP 10.04.95: nicht auf ein Reset Anchor reagieren !!!!!
1627 if ( SFX_ITEM_SET ==
1628 GetFmt()->GetAttrSet().GetItemState( RES_ANCHOR, FALSE ) )
1630 // OD 10.10.2003 #112299# - no connect to layout during disconnection
1631 if ( !mbDisconnectInProgress )
1633 // determine old object retangle of 'master' drawing object
1634 // for notification
1635 const Rectangle* pOldRect = 0L;
1636 Rectangle aOldRect;
1637 if ( GetAnchorFrm() )
1639 // --> OD 2004-10-27 #i36181# - include spacing in object
1640 // rectangle for notification.
1641 aOldRect = maAnchoredDrawObj.GetObjRectWithSpaces().SVRect();
1642 pOldRect = &aOldRect;
1643 // <--
1645 // re-connect to layout due to anchor format change
1646 ConnectToLayout( pNewAnchorFmt );
1647 // notify background of drawing objects
1648 lcl_NotifyBackgroundOfObj( *this, *GetMaster(), pOldRect );
1649 NotifyBackgrdOfAllVirtObjs( pOldRect );
1651 const SwFmtAnchor* pOldAnchorFmt = pOld ? lcl_getAnchorFmt( *pOld ) : NULL;
1652 if ( !pOldAnchorFmt || ( pOldAnchorFmt->GetAnchorId() != pNewAnchorFmt->GetAnchorId() ) )
1654 ASSERT( maAnchoredDrawObj.DrawObj(), "SwDrawContact::Modify: no draw object here?" );
1655 if ( maAnchoredDrawObj.DrawObj() )
1657 // --> OD 2009-07-10 #i102752#
1658 // assure that a ShapePropertyChangeNotifier exists
1659 maAnchoredDrawObj.DrawObj()->notifyShapePropertyChange( ::svx::eTextShapeAnchorType );
1660 // <--
1665 else
1666 DisconnectFromLayout();
1668 // --> OD 2006-03-17 #i62875# - revised fix for issue #124157#
1669 // no further notification, if not connected to Writer layout
1670 else if ( maAnchoredDrawObj.GetAnchorFrm() &&
1671 maAnchoredDrawObj.GetDrawObj()->GetUserCall() )
1673 // --> OD 2004-07-01 #i28701# - on change of wrapping style, hell|heaven layer,
1674 // or wrapping style influence an update of the <SwSortedObjs> list,
1675 // the drawing object is registered in, has to be performed. This is triggered
1676 // by the 1st parameter of method call <_InvalidateObjs(..)>.
1677 if ( RES_SURROUND == nWhich ||
1678 RES_OPAQUE == nWhich ||
1679 RES_WRAP_INFLUENCE_ON_OBJPOS == nWhich ||
1680 ( RES_ATTRSET_CHG == nWhich &&
1681 ( SFX_ITEM_SET == ((SwAttrSetChg*)pNew)->GetChgSet()->GetItemState(
1682 RES_SURROUND, FALSE ) ||
1683 SFX_ITEM_SET == ((SwAttrSetChg*)pNew)->GetChgSet()->GetItemState(
1684 RES_OPAQUE, FALSE ) ||
1685 SFX_ITEM_SET == ((SwAttrSetChg*)pNew)->GetChgSet()->GetItemState(
1686 RES_WRAP_INFLUENCE_ON_OBJPOS, FALSE ) ) ) )
1688 lcl_NotifyBackgroundOfObj( *this, *GetMaster(), 0L );
1689 NotifyBackgrdOfAllVirtObjs( 0L );
1690 _InvalidateObjs( true );
1692 else if ( RES_UL_SPACE == nWhich || RES_LR_SPACE == nWhich ||
1693 RES_HORI_ORIENT == nWhich || RES_VERT_ORIENT == nWhich ||
1694 // --> OD 2004-07-01 #i28701# - add attribute 'Follow text flow'
1695 RES_FOLLOW_TEXT_FLOW == nWhich ||
1696 ( RES_ATTRSET_CHG == nWhich &&
1697 ( SFX_ITEM_SET == ((SwAttrSetChg*)pNew)->GetChgSet()->GetItemState(
1698 RES_LR_SPACE, FALSE ) ||
1699 SFX_ITEM_SET == ((SwAttrSetChg*)pNew)->GetChgSet()->GetItemState(
1700 RES_UL_SPACE, FALSE ) ||
1701 SFX_ITEM_SET == ((SwAttrSetChg*)pNew)->GetChgSet()->GetItemState(
1702 RES_HORI_ORIENT, FALSE ) ||
1703 SFX_ITEM_SET == ((SwAttrSetChg*)pNew)->GetChgSet()->GetItemState(
1704 RES_VERT_ORIENT, FALSE ) ||
1705 SFX_ITEM_SET == ((SwAttrSetChg*)pNew)->GetChgSet()->GetItemState(
1706 RES_FOLLOW_TEXT_FLOW, FALSE ) ) ) )
1708 lcl_NotifyBackgroundOfObj( *this, *GetMaster(), 0L );
1709 NotifyBackgrdOfAllVirtObjs( 0L );
1710 _InvalidateObjs();
1712 // --> OD 2004-10-26 #i35443#
1713 else if ( RES_ATTRSET_CHG == nWhich )
1715 lcl_NotifyBackgroundOfObj( *this, *GetMaster(), 0L );
1716 NotifyBackgrdOfAllVirtObjs( 0L );
1717 _InvalidateObjs();
1719 // <--
1720 else if ( RES_REMOVE_UNO_OBJECT == nWhich )
1722 // nothing to do
1724 #if OSL_DEBUG_LEVEL > 1
1725 else
1727 ASSERT( false,
1728 "<SwDrawContact::Modify(..)> - unhandled attribute? - please inform od@openoffice.org" );
1730 #endif
1733 // --> OD 2005-07-18 #i51474#
1734 GetAnchoredObj( 0L )->ResetLayoutProcessBools();
1735 // <--
1738 // OD 2004-03-31 #i26791#
1739 // --> OD 2004-07-01 #i28701# - added parameter <_bUpdateSortedObjsList>
1740 void SwDrawContact::_InvalidateObjs( const bool _bUpdateSortedObjsList )
1742 // invalidate position of existing 'virtual' drawing objects
1743 for ( std::list<SwDrawVirtObj*>::iterator aDisconnectIter = maDrawVirtObjs.begin();
1744 aDisconnectIter != maDrawVirtObjs.end();
1745 ++aDisconnectIter )
1747 SwDrawVirtObj* pDrawVirtObj = (*aDisconnectIter);
1748 // --> OD 2004-08-23 #i33313# - invalidation only for connected
1749 // 'virtual' drawing objects
1750 if ( pDrawVirtObj->IsConnected() )
1752 pDrawVirtObj->AnchoredObj()->InvalidateObjPos();
1753 // --> OD 2004-07-01 #i28701#
1754 if ( _bUpdateSortedObjsList )
1756 pDrawVirtObj->AnchoredObj()->UpdateObjInSortedList();
1758 // <--
1760 // <--
1763 // invalidate position of 'master' drawing object
1764 SwAnchoredObject* pAnchoredObj = GetAnchoredObj( 0L );
1765 pAnchoredObj->InvalidateObjPos();
1766 // --> OD 2004-07-01 #i28701#
1767 if ( _bUpdateSortedObjsList )
1769 pAnchoredObj->UpdateObjInSortedList();
1771 // <--
1774 /*************************************************************************
1776 |* SwDrawContact::DisconnectFromLayout()
1778 |* Ersterstellung MA 09. Jan. 95
1779 |* Letzte Aenderung MA 25. Mar. 99
1781 |*************************************************************************/
1783 void SwDrawContact::DisconnectFromLayout( bool _bMoveMasterToInvisibleLayer )
1785 // OD 10.10.2003 #112299#
1786 mbDisconnectInProgress = true;
1788 // --> OD 2004-10-27 #i36181# - notify background of drawing object
1789 if ( _bMoveMasterToInvisibleLayer &&
1790 !(GetFmt()->GetDoc()->IsInDtor()) &&
1791 GetAnchorFrm() )
1793 const Rectangle aOldRect( maAnchoredDrawObj.GetObjRectWithSpaces().SVRect() );
1794 lcl_NotifyBackgroundOfObj( *this, *GetMaster(), &aOldRect );
1795 NotifyBackgrdOfAllVirtObjs( &aOldRect );
1797 // <--
1799 // OD 16.05.2003 #108784# - remove 'virtual' drawing objects from writer
1800 // layout and from drawing page
1801 for ( std::list<SwDrawVirtObj*>::iterator aDisconnectIter = maDrawVirtObjs.begin();
1802 aDisconnectIter != maDrawVirtObjs.end();
1803 ++aDisconnectIter )
1805 SwDrawVirtObj* pDrawVirtObj = (*aDisconnectIter);
1806 pDrawVirtObj->RemoveFromWriterLayout();
1807 pDrawVirtObj->RemoveFromDrawingPage();
1810 if ( maAnchoredDrawObj.GetAnchorFrm() )
1812 maAnchoredDrawObj.AnchorFrm()->RemoveDrawObj( maAnchoredDrawObj );
1815 if ( _bMoveMasterToInvisibleLayer && GetMaster() && GetMaster()->IsInserted() )
1817 SdrViewIter aIter( GetMaster() );
1818 for( SdrView* pView = aIter.FirstView(); pView;
1819 pView = aIter.NextView() )
1821 pView->MarkObj( GetMaster(), pView->GetSdrPageView(), TRUE );
1824 // OD 25.06.2003 #108784# - Instead of removing 'master' object from
1825 // drawing page, move the 'master' drawing object into the corresponding
1826 // invisible layer.
1828 //((SwFrmFmt*)pRegisteredIn)->getIDocumentDrawModelAccess()->GetDrawModel()->GetPage(0)->
1829 // RemoveObject( GetMaster()->GetOrdNum() );
1830 // OD 21.08.2003 #i18447# - in order to consider group object correct
1831 // use new method <SwDrawContact::MoveObjToInvisibleLayer(..)>
1832 MoveObjToInvisibleLayer( GetMaster() );
1836 // OD 10.10.2003 #112299#
1837 mbDisconnectInProgress = false;
1840 // OD 26.06.2003 #108784# - method to remove 'master' drawing object
1841 // from drawing page.
1842 void SwDrawContact::RemoveMasterFromDrawPage()
1844 if ( GetMaster() )
1846 GetMaster()->SetUserCall( 0 );
1847 if ( GetMaster()->IsInserted() )
1849 ((SwFrmFmt*)pRegisteredIn)->getIDocumentDrawModelAccess()->GetDrawModel()->GetPage(0)->
1850 RemoveObject( GetMaster()->GetOrdNum() );
1855 // OD 19.06.2003 #108784# - disconnect for a dedicated drawing object -
1856 // could be 'master' or 'virtual'.
1857 // a 'master' drawing object will disconnect a 'virtual' drawing object
1858 // in order to take its place.
1859 // OD 13.10.2003 #i19919# - no special case, if drawing object isn't in
1860 // page header/footer, in order to get drawing objects in repeating table headers
1861 // also working.
1862 void SwDrawContact::DisconnectObjFromLayout( SdrObject* _pDrawObj )
1864 if ( _pDrawObj->ISA(SwDrawVirtObj) )
1866 SwDrawVirtObj* pDrawVirtObj = static_cast<SwDrawVirtObj*>(_pDrawObj);
1867 pDrawVirtObj->RemoveFromWriterLayout();
1868 pDrawVirtObj->RemoveFromDrawingPage();
1870 else
1872 std::list<SwDrawVirtObj*>::const_iterator aFoundVirtObjIter =
1873 std::find_if( maDrawVirtObjs.begin(), maDrawVirtObjs.end(),
1874 UsedOrUnusedVirtObjPred( true ) );
1875 if ( aFoundVirtObjIter != maDrawVirtObjs.end() )
1877 // replace found 'virtual' drawing object by 'master' drawing
1878 // object and disconnect the 'virtual' one
1879 SwDrawVirtObj* pDrawVirtObj = (*aFoundVirtObjIter);
1880 SwFrm* pNewAnchorFrmOfMaster = pDrawVirtObj->AnchorFrm();
1881 // disconnect 'virtual' drawing object
1882 pDrawVirtObj->RemoveFromWriterLayout();
1883 pDrawVirtObj->RemoveFromDrawingPage();
1884 // disconnect 'master' drawing object from current frame
1885 GetAnchorFrm()->RemoveDrawObj( maAnchoredDrawObj );
1886 // re-connect 'master' drawing object to frame of found 'virtual'
1887 // drawing object.
1888 pNewAnchorFrmOfMaster->AppendDrawObj( maAnchoredDrawObj );
1890 else
1892 // no connected 'virtual' drawing object found. Thus, disconnect
1893 // completely from layout.
1894 DisconnectFromLayout();
1899 /*************************************************************************
1901 |* SwDrawContact::ConnectToLayout()
1903 |* Ersterstellung MA 09. Jan. 95
1904 |* Letzte Aenderung MA 25. Mar. 99
1906 |*************************************************************************/
1907 SwTxtFrm* lcl_GetFlyInCntntAnchor( SwTxtFrm* _pProposedAnchorFrm,
1908 const xub_StrLen _nTxtOfs )
1910 SwTxtFrm* pAct = _pProposedAnchorFrm;
1911 SwTxtFrm* pTmp;
1914 pTmp = pAct;
1915 pAct = pTmp->GetFollow();
1917 while( pAct && _nTxtOfs >= pAct->GetOfst() );
1918 return pTmp;
1921 void SwDrawContact::ConnectToLayout( const SwFmtAnchor* pAnch )
1923 // OD 10.10.2003 #112299# - *no* connect to layout during disconnection from
1924 // layout.
1925 if ( mbDisconnectInProgress )
1927 ASSERT( false,
1928 "<SwDrawContact::ConnectToLayout(..)> called during disconnection.");
1929 return;
1932 // --> OD 2004-09-22 #i33909# - *no* connect to layout, if 'master' drawing
1933 // object isn't inserted in the drawing page
1934 if ( !GetMaster()->IsInserted() )
1936 ASSERT( false, "<SwDrawContact::ConnectToLayout(..)> - master drawing object not inserted -> no connect to layout. Please inform od@openoffice.org" );
1937 return;
1939 // <--
1941 SwFrmFmt* pDrawFrmFmt = (SwFrmFmt*)pRegisteredIn;
1943 SwRootFrm* pRoot = pDrawFrmFmt->getIDocumentLayoutAccess()->GetRootFrm();
1944 if ( !pRoot )
1946 return;
1949 // OD 16.05.2003 #108784# - remove 'virtual' drawing objects from writer
1950 // layout and from drawing page, and remove 'master' drawing object from
1951 // writer layout - 'master' object will remain in drawing page.
1952 DisconnectFromLayout( false );
1954 if ( !pAnch )
1956 pAnch = &(pDrawFrmFmt->GetAnchor());
1959 switch ( pAnch->GetAnchorId() )
1961 case FLY_PAGE:
1963 USHORT nPgNum = pAnch->GetPageNum();
1964 SwPageFrm *pPage = static_cast<SwPageFrm*>(pRoot->Lower());
1966 for ( USHORT i = 1; i < nPgNum && pPage; ++i )
1968 pPage = static_cast<SwPageFrm*>(pPage->GetNext());
1971 if ( pPage )
1973 pPage->AppendDrawObj( maAnchoredDrawObj );
1975 else
1976 //Sieht doof aus, ist aber erlaubt (vlg. SwFEShell::SetPageObjsNewPage)
1977 pRoot->SetAssertFlyPages();
1979 break;
1981 case FLY_AUTO_CNTNT:
1982 case FLY_AT_CNTNT:
1983 case FLY_AT_FLY:
1984 case FLY_IN_CNTNT:
1986 if ( pAnch->GetAnchorId() == FLY_IN_CNTNT )
1988 ClrContourCache( GetMaster() );
1990 // OD 16.05.2003 #108784# - support drawing objects in header/footer,
1991 // but not control objects:
1992 // anchor at first found frame the 'master' object and
1993 // at the following frames 'virtual' drawing objects.
1994 // Note: method is similar to <SwFlyFrmFmt::MakeFrms(..)>
1995 SwModify *pModify = 0;
1996 if( pAnch->GetCntntAnchor() )
1998 if ( pAnch->GetAnchorId() == FLY_AT_FLY )
2000 SwNodeIndex aIdx( pAnch->GetCntntAnchor()->nNode );
2001 SwCntntNode* pCNd = pDrawFrmFmt->GetDoc()->GetNodes().GoNext( &aIdx );
2002 SwClientIter aIter( *pCNd );
2003 if ( aIter.First( TYPE(SwFrm) ) )
2004 pModify = pCNd;
2005 else
2007 const SwNodeIndex& rIdx = pAnch->GetCntntAnchor()->nNode;
2008 SwSpzFrmFmts& rFmts = *(pDrawFrmFmt->GetDoc()->GetSpzFrmFmts());
2009 for( sal_uInt16 i = 0; i < rFmts.Count(); ++i )
2011 SwFrmFmt* pFlyFmt = rFmts[i];
2012 if( pFlyFmt->GetCntnt().GetCntntIdx() &&
2013 rIdx == *(pFlyFmt->GetCntnt().GetCntntIdx()) )
2015 pModify = pFlyFmt;
2016 break;
2020 // --> OD 2004-06-15 #i29199# - It is possible, that
2021 // the anchor doesn't exist - E.g., reordering the
2022 // sub-documents in a master document.
2023 // Note: The anchor will be inserted later.
2024 if ( !pModify )
2026 // break to end of the current switch case.
2027 break;
2030 else
2032 pModify = pAnch->GetCntntAnchor()->nNode.GetNode().GetCntntNode();
2035 SwClientIter aIter( *pModify );
2036 SwFrm* pAnchorFrmOfMaster = 0;
2037 for( SwFrm *pFrm = (SwFrm*)aIter.First( TYPE(SwFrm) );
2038 pFrm;
2039 pFrm = (SwFrm*)aIter.Next() )
2041 // append drawing object, if
2042 // (1) proposed anchor frame isn't a follow and
2043 // (2) drawing object isn't a control object to be anchored
2044 // in header/footer.
2045 const bool bAdd = ( !pFrm->IsCntntFrm() ||
2046 !((SwCntntFrm*)pFrm)->IsFollow() ) &&
2047 ( !::CheckControlLayer( GetMaster() ) ||
2048 !pFrm->FindFooterOrHeader() );
2050 if( bAdd )
2052 if ( FLY_AT_FLY == pAnch->GetAnchorId() && !pFrm->IsFlyFrm() )
2054 pFrm = pFrm->FindFlyFrm();
2055 ASSERT( pFrm,
2056 "<SwDrawContact::ConnectToLayout(..)> - missing fly frame -> crash." );
2059 // OD 2004-01-20 #110582# - find correct follow for
2060 // as character anchored objects.
2061 if ( pAnch->GetAnchorId() == FLY_IN_CNTNT &&
2062 pFrm->IsTxtFrm() )
2064 pFrm = lcl_GetFlyInCntntAnchor(
2065 static_cast<SwTxtFrm*>(pFrm),
2066 pAnch->GetCntntAnchor()->nContent.GetIndex() );
2069 if ( !pAnchorFrmOfMaster )
2071 // append 'master' drawing object
2072 pAnchorFrmOfMaster = pFrm;
2073 pFrm->AppendDrawObj( maAnchoredDrawObj );
2075 else
2077 // append 'virtual' drawing object
2078 SwDrawVirtObj* pDrawVirtObj = AddVirtObj();
2079 if ( pAnch->GetAnchorId() == FLY_IN_CNTNT )
2081 ClrContourCache( pDrawVirtObj );
2083 pFrm->AppendDrawObj( *(pDrawVirtObj->AnchoredObj()) );
2085 // for repaint, use new ActionChanged()
2086 // pDrawVirtObj->SendRepaintBroadcast();
2087 pDrawVirtObj->ActionChanged();
2090 if ( pAnch->GetAnchorId() == FLY_IN_CNTNT )
2092 pFrm->InvalidatePrt();
2097 break;
2098 default:
2099 ASSERT( FALSE, "Unknown Anchor." )
2100 break;
2102 if ( GetAnchorFrm() )
2104 ::setContextWritingMode( maAnchoredDrawObj.DrawObj(), GetAnchorFrm() );
2105 // OD 2004-04-01 #i26791# - invalidate objects instead of direct positioning
2106 _InvalidateObjs();
2110 // OD 27.06.2003 #108784# - insert 'master' drawing object into drawing page
2111 void SwDrawContact::InsertMasterIntoDrawPage()
2113 if ( !GetMaster()->IsInserted() )
2115 GetFmt()->getIDocumentDrawModelAccess()->GetDrawModel()->GetPage(0)
2116 ->InsertObject( GetMaster(), GetMaster()->GetOrdNumDirect() );
2118 GetMaster()->SetUserCall( this );
2121 /*************************************************************************
2123 |* SwDrawContact::FindPage(), ChkPage()
2125 |* Ersterstellung MA 21. Mar. 95
2126 |* Letzte Aenderung MA 19. Jul. 96
2128 |*************************************************************************/
2130 SwPageFrm* SwDrawContact::FindPage( const SwRect &rRect )
2132 // --> OD 2004-07-01 #i28701# - use method <GetPageFrm()>
2133 SwPageFrm* pPg = GetPageFrm();
2134 if ( !pPg && GetAnchorFrm() )
2135 pPg = GetAnchorFrm()->FindPageFrm();
2136 if ( pPg )
2137 pPg = (SwPageFrm*)::FindPage( rRect, pPg );
2138 return pPg;
2141 void SwDrawContact::ChkPage()
2143 // OD 10.10.2003 #112299#
2144 if ( mbDisconnectInProgress )
2146 ASSERT( false,
2147 "<SwDrawContact::ChkPage()> called during disconnection." );
2148 return;
2151 // --> OD 2004-07-01 #i28701#
2152 SwPageFrm* pPg = ( maAnchoredDrawObj.GetAnchorFrm() &&
2153 maAnchoredDrawObj.GetAnchorFrm()->IsPageFrm() )
2154 ? GetPageFrm()
2155 : FindPage( GetMaster()->GetCurrentBoundRect() );
2156 if ( GetPageFrm() != pPg )
2158 // OD 27.06.2003 #108784# - if drawing object is anchor in header/footer
2159 // a change of the page is a dramatic change. Thus, completely re-connect
2160 // to the layout
2161 if ( maAnchoredDrawObj.GetAnchorFrm() &&
2162 maAnchoredDrawObj.GetAnchorFrm()->FindFooterOrHeader() )
2164 ConnectToLayout();
2166 else
2168 // --> OD 2004-07-01 #i28701# - use methods <GetPageFrm()> and <SetPageFrm>
2169 if ( GetPageFrm() )
2170 GetPageFrm()->RemoveDrawObjFromPage( maAnchoredDrawObj );
2171 pPg->AppendDrawObjToPage( maAnchoredDrawObj );
2172 SetPageFrm( pPg );
2177 /*************************************************************************
2179 |* SwDrawContact::ChangeMasterObject()
2181 |* Ersterstellung MA 07. Aug. 95
2182 |* Letzte Aenderung MA 20. Apr. 99
2184 |*************************************************************************/
2185 // OD 10.07.2003 #110742# - Important note:
2186 // method is called by method <SwDPage::ReplaceObject(..)>, which called its
2187 // corresponding superclass method <FmFormPage::ReplaceObject(..)>.
2188 // Note: 'master' drawing object *has* to be connected to layout triggered
2189 // by the caller of this, if method is called.
2190 void SwDrawContact::ChangeMasterObject( SdrObject *pNewMaster )
2192 DisconnectFromLayout( false );
2193 // OD 10.07.2003 #110742# - consider 'virtual' drawing objects
2194 RemoveAllVirtObjs();
2196 GetMaster()->SetUserCall( 0 );
2197 SetMaster( pNewMaster );
2198 GetMaster()->SetUserCall( this );
2200 _InvalidateObjs();
2203 /** get data collection of anchored objects, handled by with contact
2205 OD 2004-08-23 #110810#
2207 @author
2209 void SwDrawContact::GetAnchoredObjs( std::vector<SwAnchoredObject*>& _roAnchoredObjs ) const
2211 _roAnchoredObjs.push_back( const_cast<SwAnchoredDrawObject*>(&maAnchoredDrawObj) );
2213 for ( std::list<SwDrawVirtObj*>::const_iterator aDrawVirtObjsIter = maDrawVirtObjs.begin();
2214 aDrawVirtObjsIter != maDrawVirtObjs.end();
2215 ++aDrawVirtObjsIter )
2217 _roAnchoredObjs.push_back( (*aDrawVirtObjsIter)->AnchoredObj() );
2221 //////////////////////////////////////////////////////////////////////////////////////
2222 // AW: own sdr::contact::ViewContact (VC) sdr::contact::ViewObjectContact (VOC) needed
2223 // since offset is defined different from SdrVirtObj's sdr::contact::ViewContactOfVirtObj.
2224 // For paint, that offset is used by setting at the OutputDevice; for primitives this is
2225 // not possible since we have no OutputDevice, but define the geometry itself.
2227 namespace sdr
2229 namespace contact
2231 class VOCOfDrawVirtObj : public ViewObjectContactOfSdrObj
2233 protected:
2234 // This method is responsible for creating the graphical visualisation data which is
2235 // stored/cached in the local primitive. Default gets view-independent Primitive
2236 // from the ViewContact using ViewContact::getViewIndependentPrimitive2DSequence(), takes care of
2237 // visibility, handles glue and ghosted.
2238 // This method will not handle included hierarchies and not check geometric visibility.
2239 virtual drawinglayer::primitive2d::Primitive2DSequence createPrimitive2DSequence(const DisplayInfo& rDisplayInfo) const;
2241 public:
2242 VOCOfDrawVirtObj(ObjectContact& rObjectContact, ViewContact& rViewContact)
2243 : ViewObjectContactOfSdrObj(rObjectContact, rViewContact)
2247 virtual ~VOCOfDrawVirtObj();
2250 class VCOfDrawVirtObj : public ViewContactOfVirtObj
2252 protected:
2253 // Create a Object-Specific ViewObjectContact, set ViewContact and
2254 // ObjectContact. Always needs to return something. Default is to create
2255 // a standard ViewObjectContact containing the given ObjectContact and *this
2256 virtual ViewObjectContact& CreateObjectSpecificViewObjectContact(ObjectContact& rObjectContact);
2258 public:
2259 // basic constructor, used from SdrObject.
2260 VCOfDrawVirtObj(SwDrawVirtObj& rObj)
2261 : ViewContactOfVirtObj(rObj)
2264 virtual ~VCOfDrawVirtObj();
2266 // access to SwDrawVirtObj
2267 SwDrawVirtObj& GetSwDrawVirtObj() const
2269 return (SwDrawVirtObj&)mrObject;
2272 } // end of namespace contact
2273 } // end of namespace sdr
2275 namespace sdr
2277 namespace contact
2279 // recursively collect primitive data from given VOC with given offset
2280 void impAddPrimitivesFromGroup(const ViewObjectContact& rVOC, const basegfx::B2DHomMatrix& rOffsetMatrix, const DisplayInfo& rDisplayInfo, drawinglayer::primitive2d::Primitive2DSequence& rxTarget)
2282 const sal_uInt32 nSubHierarchyCount(rVOC.GetViewContact().GetObjectCount());
2284 for(sal_uInt32 a(0L); a < nSubHierarchyCount; a++)
2286 const ViewObjectContact& rCandidate(rVOC.GetViewContact().GetViewContact(a).GetViewObjectContact(rVOC.GetObjectContact()));
2288 if(rCandidate.GetViewContact().GetObjectCount())
2290 // is a group object itself, call resursively
2291 impAddPrimitivesFromGroup(rCandidate, rOffsetMatrix, rDisplayInfo, rxTarget);
2293 else
2295 // single object, add primitives; check model-view visibility
2296 if(rCandidate.isPrimitiveVisible(rDisplayInfo))
2298 drawinglayer::primitive2d::Primitive2DSequence aNewSequence(rCandidate.getPrimitive2DSequence(rDisplayInfo));
2300 if(aNewSequence.hasElements())
2302 // get ranges
2303 const drawinglayer::geometry::ViewInformation2D& rViewInformation2D(rCandidate.GetObjectContact().getViewInformation2D());
2304 const basegfx::B2DRange aViewRange(rViewInformation2D.getViewport());
2305 basegfx::B2DRange aObjectRange(rCandidate.getObjectRange());
2307 // correct with virtual object's offset
2308 aObjectRange.transform(rOffsetMatrix);
2310 // check geometrical visibility (with offset)
2311 if(!aViewRange.overlaps(aObjectRange))
2313 // not visible, release
2314 aNewSequence.realloc(0);
2318 if(aNewSequence.hasElements())
2320 drawinglayer::primitive2d::appendPrimitive2DSequenceToPrimitive2DSequence(rxTarget, aNewSequence);
2327 drawinglayer::primitive2d::Primitive2DSequence VOCOfDrawVirtObj::createPrimitive2DSequence(const DisplayInfo& rDisplayInfo) const
2329 #ifdef DBG_UTIL
2330 // #i101734#
2331 static bool bCheckOtherThanTranslate(false);
2332 static double fShearX(0.0);
2333 static double fRotation(0.0);
2334 static double fScaleX(0.0);
2335 static double fScaleY(0.0);
2336 #endif
2338 const VCOfDrawVirtObj& rVC = static_cast< const VCOfDrawVirtObj& >(GetViewContact());
2339 const SdrObject& rReferencedObject = rVC.GetSwDrawVirtObj().GetReferencedObj();
2340 drawinglayer::primitive2d::Primitive2DSequence xRetval;
2342 // create offset transformation
2343 basegfx::B2DHomMatrix aOffsetMatrix;
2344 const Point aLocalOffset(rVC.GetSwDrawVirtObj().GetOffset());
2346 if(aLocalOffset.X() || aLocalOffset.Y())
2348 #ifdef DBG_UTIL
2349 // #i101734# added debug code to check more complex transformations
2350 // than just a translation
2351 if(bCheckOtherThanTranslate)
2353 aOffsetMatrix.scale(fScaleX, fScaleY);
2354 aOffsetMatrix.shearX(tan(fShearX * F_PI180));
2355 aOffsetMatrix.rotate(fRotation * F_PI180);
2357 #endif
2359 aOffsetMatrix.set(0, 2, aLocalOffset.X());
2360 aOffsetMatrix.set(1, 2, aLocalOffset.Y());
2364 if(rReferencedObject.ISA(SdrObjGroup))
2366 // group object. Since the VOC/OC/VC hierarchy does not represent the
2367 // hierarchy virtual objects when they have group objects
2368 // (ViewContactOfVirtObj::GetObjectCount() returns null for that purpose)
2369 // to avoid multiple usages of VOCs (which would not work), the primitives
2370 // for the sub-hierarchy need to be collected here
2372 // Get the VOC of the referenced object (the Group) and fetch primitives from it
2373 const ViewObjectContact& rVOCOfRefObj = rReferencedObject.GetViewContact().GetViewObjectContact(GetObjectContact());
2374 impAddPrimitivesFromGroup(rVOCOfRefObj, aOffsetMatrix, rDisplayInfo, xRetval);
2376 else
2378 // single object, use method from referenced object to get the Primitive2DSequence
2379 xRetval = rReferencedObject.GetViewContact().getViewIndependentPrimitive2DSequence();
2382 if(xRetval.hasElements())
2384 // create transform primitive
2385 const drawinglayer::primitive2d::Primitive2DReference xReference(new drawinglayer::primitive2d::TransformPrimitive2D(aOffsetMatrix, xRetval));
2386 xRetval = drawinglayer::primitive2d::Primitive2DSequence(&xReference, 1);
2389 return xRetval;
2392 VOCOfDrawVirtObj::~VOCOfDrawVirtObj()
2396 ViewObjectContact& VCOfDrawVirtObj::CreateObjectSpecificViewObjectContact(ObjectContact& rObjectContact)
2398 return *(new VOCOfDrawVirtObj(rObjectContact, *this));
2401 VCOfDrawVirtObj::~VCOfDrawVirtObj()
2404 } // end of namespace contact
2405 } // end of namespace sdr
2407 //////////////////////////////////////////////////////////////////////////////////////
2409 // =============================================================================
2410 /** implementation of class <SwDrawVirtObj>
2412 OD 14.05.2003 #108784#
2414 @author OD
2417 TYPEINIT1(SwDrawVirtObj,SdrVirtObj);
2419 sdr::contact::ViewContact* SwDrawVirtObj::CreateObjectSpecificViewContact()
2421 return new sdr::contact::VCOfDrawVirtObj(*this);
2424 // #108784#
2425 // implemetation of SwDrawVirtObj
2426 SwDrawVirtObj::SwDrawVirtObj( SdrObject& _rNewObj,
2427 SwDrawContact& _rDrawContact )
2428 : SdrVirtObj( _rNewObj ),
2429 // OD 2004-03-29 #i26791# - init new member <maAnchoredDrawObj>
2430 maAnchoredDrawObj(),
2431 mrDrawContact( _rDrawContact )
2433 // OD 2004-03-29 #i26791#
2434 maAnchoredDrawObj.SetDrawObj( *this );
2435 // --> OD 2004-11-17 #i35635# - set initial position out of sight
2436 NbcMove( Size( -RECT_EMPTY, -RECT_EMPTY ) );
2437 // <--
2440 SwDrawVirtObj::~SwDrawVirtObj()
2443 void SwDrawVirtObj::operator=( const SdrObject& rObj )
2445 SdrVirtObj::operator=(rObj);
2446 // Note: Members <maAnchoredDrawObj> and <mrDrawContact>
2447 // haven't to be considered.
2450 SdrObject* SwDrawVirtObj::Clone() const
2452 SwDrawVirtObj* pObj = new SwDrawVirtObj( rRefObj, mrDrawContact );
2454 if ( pObj )
2456 pObj->operator=(static_cast<const SdrObject&>(*this));
2457 // Note: Member <maAnchoredDrawObj> hasn't to be considered.
2460 return pObj;
2463 // --------------------------------------------------------------------
2464 // connection to writer layout: <GetAnchoredObj()>, <SetAnchorFrm(..)>,
2465 // <GetAnchorFrm()>, <SetPageFrm(..)>, <GetPageFrm()> and <RemoveFromWriterLayout()>
2466 // --------------------------------------------------------------------
2467 const SwAnchoredObject* SwDrawVirtObj::GetAnchoredObj() const
2469 return &maAnchoredDrawObj;
2472 SwAnchoredObject* SwDrawVirtObj::AnchoredObj()
2474 return &maAnchoredDrawObj;
2477 const SwFrm* SwDrawVirtObj::GetAnchorFrm() const
2479 // OD 2004-03-29 #i26791# - use new member <maAnchoredDrawObj>
2480 return maAnchoredDrawObj.GetAnchorFrm();
2483 SwFrm* SwDrawVirtObj::AnchorFrm()
2485 // OD 2004-03-29 #i26791# - use new member <maAnchoredDrawObj>
2486 return maAnchoredDrawObj.AnchorFrm();
2489 void SwDrawVirtObj::RemoveFromWriterLayout()
2491 // remove contact object from frame for 'virtual' drawing object
2492 // OD 2004-03-29 #i26791# - use new member <maAnchoredDrawObj>
2493 if ( maAnchoredDrawObj.GetAnchorFrm() )
2495 maAnchoredDrawObj.AnchorFrm()->RemoveDrawObj( maAnchoredDrawObj );
2499 // --------------------------------------------------------------------
2500 // connection to writer layout: <AddToDrawingPage()>, <RemoveFromDrawingPage()>
2501 // --------------------------------------------------------------------
2502 void SwDrawVirtObj::AddToDrawingPage()
2504 // determine 'master'
2505 SdrObject* pOrgMasterSdrObj = mrDrawContact.GetMaster();
2507 // insert 'virtual' drawing object into page, set layer and user call.
2508 SdrPage* pDrawPg;
2509 // --> OD 2004-08-16 #i27030# - apply order number of referenced object
2510 if ( 0 != ( pDrawPg = pOrgMasterSdrObj->GetPage() ) )
2512 // --> OD 2004-08-16 #i27030# - apply order number of referenced object
2513 pDrawPg->InsertObject( this, GetReferencedObj().GetOrdNum() );
2515 else
2517 pDrawPg = GetPage();
2518 if ( pDrawPg )
2520 pDrawPg->SetObjectOrdNum( GetOrdNumDirect(),
2521 GetReferencedObj().GetOrdNum() );
2523 else
2525 SetOrdNum( GetReferencedObj().GetOrdNum() );
2528 // <--
2529 SetUserCall( &mrDrawContact );
2532 void SwDrawVirtObj::RemoveFromDrawingPage()
2534 SetUserCall( 0 );
2535 if ( GetPage() )
2537 GetPage()->RemoveObject( GetOrdNum() );
2541 // is 'virtual' drawing object connected to writer layout and to drawing layer.
2542 bool SwDrawVirtObj::IsConnected() const
2544 bool bRetVal = GetAnchorFrm() &&
2545 ( GetPage() && GetUserCall() );
2547 return bRetVal;
2550 void SwDrawVirtObj::NbcSetAnchorPos(const Point& rPnt)
2552 SdrObject::NbcSetAnchorPos( rPnt );
2555 //////////////////////////////////////////////////////////////////////////////
2556 // #i97197#
2557 // the methods relevant for positioning
2559 const Rectangle& SwDrawVirtObj::GetCurrentBoundRect() const
2561 if(aOutRect.IsEmpty())
2563 const_cast<SwDrawVirtObj*>(this)->RecalcBoundRect();
2566 return aOutRect;
2569 const Rectangle& SwDrawVirtObj::GetLastBoundRect() const
2571 return aOutRect;
2574 const Point SwDrawVirtObj::GetOffset() const
2576 // do NOT use IsEmpty() here, there is already a useful offset
2577 // in the position
2578 if(aOutRect == Rectangle())
2580 return Point();
2582 else
2584 return aOutRect.TopLeft() - GetReferencedObj().GetCurrentBoundRect().TopLeft();
2588 void SwDrawVirtObj::SetBoundRectDirty()
2590 // do nothing to not lose model information in aOutRect
2593 void SwDrawVirtObj::RecalcBoundRect()
2595 // OD 2004-04-05 #i26791# - switch order of calling <GetOffset()> and
2596 // <ReferencedObj().GetCurrentBoundRect()>, because <GetOffset()> calculates
2597 // its value by the 'BoundRect' of the referenced object.
2598 //aOutRect = rRefObj.GetCurrentBoundRect();
2599 //aOutRect += GetOffset();
2601 const Point aOffset(GetOffset());
2602 aOutRect = ReferencedObj().GetCurrentBoundRect() + aOffset;
2605 basegfx::B2DPolyPolygon SwDrawVirtObj::TakeXorPoly() const
2607 basegfx::B2DPolyPolygon aRetval(rRefObj.TakeXorPoly());
2608 basegfx::B2DHomMatrix aMatrix;
2609 aMatrix.translate(GetOffset().X(), GetOffset().Y());
2610 aRetval.transform(aMatrix);
2612 return aRetval;
2615 basegfx::B2DPolyPolygon SwDrawVirtObj::TakeContour() const
2617 basegfx::B2DPolyPolygon aRetval(rRefObj.TakeContour());
2618 basegfx::B2DHomMatrix aMatrix;
2619 aMatrix.translate(GetOffset().X(), GetOffset().Y());
2620 aRetval.transform(aMatrix);
2622 return aRetval;
2625 SdrHdl* SwDrawVirtObj::GetHdl(sal_uInt32 nHdlNum) const
2627 SdrHdl* pHdl = rRefObj.GetHdl(nHdlNum);
2628 Point aP(pHdl->GetPos() + GetOffset());
2629 pHdl->SetPos(aP);
2631 return pHdl;
2634 SdrHdl* SwDrawVirtObj::GetPlusHdl(const SdrHdl& rHdl, USHORT nPlNum) const
2636 SdrHdl* pHdl = rRefObj.GetPlusHdl(rHdl, nPlNum);
2637 pHdl->SetPos(pHdl->GetPos() + GetOffset());
2639 return pHdl;
2642 void SwDrawVirtObj::NbcMove(const Size& rSiz)
2644 SdrObject::NbcMove( rSiz );
2647 void SwDrawVirtObj::NbcResize(const Point& rRef, const Fraction& xFact, const Fraction& yFact)
2649 rRefObj.NbcResize(rRef - GetOffset(), xFact, yFact);
2650 SetRectsDirty();
2653 void SwDrawVirtObj::NbcRotate(const Point& rRef, long nWink, double sn, double cs)
2655 rRefObj.NbcRotate(rRef - GetOffset(), nWink, sn, cs);
2656 SetRectsDirty();
2659 void SwDrawVirtObj::NbcMirror(const Point& rRef1, const Point& rRef2)
2661 rRefObj.NbcMirror(rRef1 - GetOffset(), rRef2 - GetOffset());
2662 SetRectsDirty();
2665 void SwDrawVirtObj::NbcShear(const Point& rRef, long nWink, double tn, FASTBOOL bVShear)
2667 rRefObj.NbcShear(rRef - GetOffset(), nWink, tn, bVShear);
2668 SetRectsDirty();
2671 void SwDrawVirtObj::Move(const Size& rSiz)
2673 SdrObject::Move( rSiz );
2674 // Rectangle aBoundRect0; if(pUserCall) aBoundRect0 = GetLastBoundRect();
2675 // rRefObj.Move( rSiz );
2676 // SetRectsDirty();
2677 // SendUserCall(SDRUSERCALL_RESIZE, aBoundRect0);
2680 void SwDrawVirtObj::Resize(const Point& rRef, const Fraction& xFact, const Fraction& yFact)
2682 if(xFact.GetNumerator() != xFact.GetDenominator() || yFact.GetNumerator() != yFact.GetDenominator())
2684 Rectangle aBoundRect0; if(pUserCall) aBoundRect0 = GetLastBoundRect();
2685 rRefObj.Resize(rRef - GetOffset(), xFact, yFact);
2686 SetRectsDirty();
2687 SendUserCall(SDRUSERCALL_RESIZE, aBoundRect0);
2691 void SwDrawVirtObj::Rotate(const Point& rRef, long nWink, double sn, double cs)
2693 if(nWink)
2695 Rectangle aBoundRect0; if(pUserCall) aBoundRect0 = GetLastBoundRect();
2696 rRefObj.Rotate(rRef - GetOffset(), nWink, sn, cs);
2697 SetRectsDirty();
2698 SendUserCall(SDRUSERCALL_RESIZE, aBoundRect0);
2702 void SwDrawVirtObj::Mirror(const Point& rRef1, const Point& rRef2)
2704 Rectangle aBoundRect0; if(pUserCall) aBoundRect0 = GetLastBoundRect();
2705 rRefObj.Mirror(rRef1 - GetOffset(), rRef2 - GetOffset());
2706 SetRectsDirty();
2707 SendUserCall(SDRUSERCALL_RESIZE, aBoundRect0);
2710 void SwDrawVirtObj::Shear(const Point& rRef, long nWink, double tn, FASTBOOL bVShear)
2712 if(nWink)
2714 Rectangle aBoundRect0; if(pUserCall) aBoundRect0 = GetLastBoundRect();
2715 rRefObj.Shear(rRef - GetOffset(), nWink, tn, bVShear);
2716 SetRectsDirty();
2717 SendUserCall(SDRUSERCALL_RESIZE, aBoundRect0);
2721 void SwDrawVirtObj::RecalcSnapRect()
2723 aSnapRect = rRefObj.GetSnapRect();
2724 aSnapRect += GetOffset();
2727 const Rectangle& SwDrawVirtObj::GetSnapRect() const
2729 ((SwDrawVirtObj*)this)->aSnapRect = rRefObj.GetSnapRect();
2730 ((SwDrawVirtObj*)this)->aSnapRect += GetOffset();
2732 return aSnapRect;
2735 void SwDrawVirtObj::SetSnapRect(const Rectangle& rRect)
2737 Rectangle aBoundRect0; if(pUserCall) aBoundRect0 = GetLastBoundRect();
2738 Rectangle aR(rRect);
2739 aR -= GetOffset();
2740 rRefObj.SetSnapRect(aR);
2741 SetRectsDirty();
2742 SendUserCall(SDRUSERCALL_RESIZE, aBoundRect0);
2745 void SwDrawVirtObj::NbcSetSnapRect(const Rectangle& rRect)
2747 Rectangle aR(rRect);
2748 aR -= GetOffset();
2749 SetRectsDirty();
2750 rRefObj.NbcSetSnapRect(aR);
2753 const Rectangle& SwDrawVirtObj::GetLogicRect() const
2755 ((SwDrawVirtObj*)this)->aSnapRect = rRefObj.GetLogicRect();
2756 ((SwDrawVirtObj*)this)->aSnapRect += GetOffset();
2758 return aSnapRect;
2761 void SwDrawVirtObj::SetLogicRect(const Rectangle& rRect)
2763 Rectangle aBoundRect0; if(pUserCall) aBoundRect0 = GetLastBoundRect();
2764 Rectangle aR(rRect);
2765 aR -= GetOffset();
2766 rRefObj.SetLogicRect(aR);
2767 SetRectsDirty();
2768 SendUserCall(SDRUSERCALL_RESIZE, aBoundRect0);
2771 void SwDrawVirtObj::NbcSetLogicRect(const Rectangle& rRect)
2773 Rectangle aR(rRect);
2774 aR -= GetOffset();
2775 rRefObj.NbcSetLogicRect(aR);
2776 SetRectsDirty();
2779 Point SwDrawVirtObj::GetSnapPoint(sal_uInt32 i) const
2781 Point aP(rRefObj.GetSnapPoint(i));
2782 aP += GetOffset();
2784 return aP;
2787 Point SwDrawVirtObj::GetPoint(sal_uInt32 i) const
2789 return Point(rRefObj.GetPoint(i) + GetOffset());
2792 void SwDrawVirtObj::NbcSetPoint(const Point& rPnt, sal_uInt32 i)
2794 Point aP(rPnt);
2795 aP -= GetOffset();
2796 rRefObj.SetPoint(aP, i);
2797 SetRectsDirty();
2800 // #108784#
2801 FASTBOOL SwDrawVirtObj::HasTextEdit() const
2803 return rRefObj.HasTextEdit();
2806 // OD 18.06.2003 #108784# - overloaded 'layer' methods for 'virtual' drawing
2807 // object to assure, that layer of 'virtual' object is the layer of the referenced
2808 // object.
2809 SdrLayerID SwDrawVirtObj::GetLayer() const
2811 return GetReferencedObj().GetLayer();
2814 void SwDrawVirtObj::NbcSetLayer(SdrLayerID nLayer)
2816 ReferencedObj().NbcSetLayer( nLayer );
2817 SdrVirtObj::NbcSetLayer( ReferencedObj().GetLayer() );
2820 void SwDrawVirtObj::SetLayer(SdrLayerID nLayer)
2822 ReferencedObj().SetLayer( nLayer );
2823 SdrVirtObj::NbcSetLayer( ReferencedObj().GetLayer() );
2826 bool SwDrawVirtObj::supportsFullDrag() const
2828 // call parent
2829 return SdrVirtObj::supportsFullDrag();
2832 SdrObject* SwDrawVirtObj::getFullDragClone() const
2834 // call parent
2835 return SdrVirtObj::getFullDragClone();
2838 // eof