summaryrefslogtreecommitdiff
path: root/sw/source/core/draw/dcontact.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sw/source/core/draw/dcontact.cxx')
-rw-r--r--sw/source/core/draw/dcontact.cxx2815
1 files changed, 2815 insertions, 0 deletions
diff --git a/sw/source/core/draw/dcontact.cxx b/sw/source/core/draw/dcontact.cxx
new file mode 100644
index 000000000000..2e19d482fc70
--- /dev/null
+++ b/sw/source/core/draw/dcontact.cxx
@@ -0,0 +1,2815 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sw.hxx"
+#include "hintids.hxx"
+#include <editeng/protitem.hxx>
+#include <editeng/opaqitem.hxx>
+#include <editeng/ulspitem.hxx>
+#include <editeng/lrspitem.hxx>
+#include <svx/svdpage.hxx>
+#include <svx/fmglob.hxx>
+#include <svx/svdogrp.hxx>
+#include <svx/svdotext.hxx>
+#include <svx/svdmodel.hxx>
+#include <svx/svdpagv.hxx>
+#include <svx/svdviter.hxx>
+#include <svx/svdview.hxx>
+#include <svx/shapepropertynotifier.hxx>
+#include <svx/sdr/contact/objectcontactofobjlistpainter.hxx>
+#include <svx/sdr/contact/displayinfo.hxx>
+#include <fmtornt.hxx>
+#include <viewimp.hxx>
+#include <fmtsrnd.hxx>
+#include <fmtanchr.hxx>
+#include <node.hxx>
+#include <fmtcntnt.hxx>
+#include <pagefrm.hxx>
+#include <rootfrm.hxx>
+#include <frmtool.hxx> // Notify_Background
+#include <flyfrm.hxx>
+#include <frmfmt.hxx>
+#include <dflyobj.hxx>
+#include <dcontact.hxx>
+#include <unodraw.hxx>
+#include <IDocumentDrawModelAccess.hxx>
+#include <doc.hxx>
+#include <hints.hxx>
+#include <txtfrm.hxx>
+#include <editsh.hxx>
+#include <docary.hxx>
+#include <flyfrms.hxx>
+#include <sortedobjs.hxx>
+#include <basegfx/matrix/b2dhommatrix.hxx>
+#include <basegfx/matrix/b2dhommatrixtools.hxx>
+#include <svx/sdr/contact/viewcontactofvirtobj.hxx>
+#include <drawinglayer/primitive2d/transformprimitive2d.hxx>
+#include <svx/sdr/contact/viewobjectcontactofsdrobj.hxx>
+#include <com/sun/star/text/WritingMode2.hpp>
+
+#include <algorithm>
+
+using namespace ::com::sun::star;
+
+
+TYPEINIT1( SwContact, SwClient )
+TYPEINIT1( SwFlyDrawContact, SwContact )
+TYPEINIT1( SwDrawContact, SwContact )
+
+void setContextWritingMode( SdrObject* pObj, SwFrm* pAnchor )
+{
+ if( pObj && pAnchor )
+ {
+ short nWritingDirection = text::WritingMode2::LR_TB;
+ if( pAnchor->IsVertical() )
+ {
+ nWritingDirection = text::WritingMode2::TB_RL;
+ } else if( pAnchor->IsRightToLeft() )
+ {
+ nWritingDirection = text::WritingMode2::RL_TB;
+ }
+ pObj->SetContextWritingMode( nWritingDirection );
+ }
+}
+
+
+//Der Umgekehrte Weg: Sucht das Format zum angegebenen Objekt.
+//Wenn das Object ein SwVirtFlyDrawObj ist so wird das Format von
+//selbigem besorgt.
+//Anderfalls ist es eben ein einfaches Zeichenobjekt. Diese hat einen
+//UserCall und der ist Client vom gesuchten Format.
+
+SwFrmFmt *FindFrmFmt( SdrObject *pObj )
+{
+ SwFrmFmt* pRetval = 0L;
+
+ if ( pObj->ISA(SwVirtFlyDrawObj) )
+ {
+ pRetval = ((SwVirtFlyDrawObj*)pObj)->GetFmt();
+ }
+ else
+ {
+ SwDrawContact* pContact = static_cast<SwDrawContact*>(GetUserCall( pObj ));
+ if ( pContact )
+ {
+ pRetval = pContact->GetFmt();
+ }
+ }
+/* SJ: after prior consultation with OD we decided to remove this Assertion
+#if OSL_DEBUG_LEVEL > 1
+ ASSERT( pRetval,
+ "<::FindFrmFmt(..)> - no frame format found for given object. Please inform OD." );
+#endif
+*/
+ return pRetval;
+}
+
+sal_Bool HasWrap( const SdrObject* pObj )
+{
+ if ( pObj )
+ {
+ const SwFrmFmt* pFmt = ::FindFrmFmt( pObj );
+ if ( pFmt )
+ {
+ return SURROUND_THROUGHT != pFmt->GetSurround().GetSurround();
+ }
+ }
+
+ return sal_False;
+}
+
+/*****************************************************************************
+ *
+ * GetBoundRect liefert das BoundRect _inklusive_ Abstand des Objekts.
+ *
+ *****************************************************************************/
+
+// --> OD 2006-08-15 #i68520# - change naming
+SwRect GetBoundRectOfAnchoredObj( const SdrObject* pObj )
+// <--
+{
+ SwRect aRet( pObj->GetCurrentBoundRect() );
+ // --> OD 2006-08-10 #i68520# - call cache of <SwAnchoredObject>
+ SwContact* pContact( GetUserCall( pObj ) );
+ if ( pContact )
+ {
+ const SwAnchoredObject* pAnchoredObj( pContact->GetAnchoredObj( pObj ) );
+ if ( pAnchoredObj )
+ {
+ aRet = pAnchoredObj->GetObjRectWithSpaces();
+ }
+ }
+ // <--
+ return aRet;
+}
+
+//Liefert den UserCall ggf. vom Gruppenobjekt
+// OD 2004-03-31 #i26791# - change return type
+SwContact* GetUserCall( const SdrObject* pObj )
+{
+ SdrObject *pTmp;
+ while ( !pObj->GetUserCall() && 0 != (pTmp = pObj->GetUpGroup()) )
+ pObj = pTmp;
+ ASSERT( !pObj->GetUserCall() || pObj->GetUserCall()->ISA(SwContact),
+ "<::GetUserCall(..)> - wrong type of found object user call." );
+ return static_cast<SwContact*>(pObj->GetUserCall());
+}
+
+// liefert TRUE falls das SrdObject ein Marquee-Object (Lauftext) ist
+BOOL IsMarqueeTextObj( const SdrObject& rObj )
+{
+ SdrTextAniKind eTKind;
+ return SdrInventor == rObj.GetObjInventor() &&
+ OBJ_TEXT == rObj.GetObjIdentifier() &&
+ ( SDRTEXTANI_SCROLL == ( eTKind = ((SdrTextObj&)rObj).GetTextAniKind())
+ || SDRTEXTANI_ALTERNATE == eTKind || SDRTEXTANI_SLIDE == eTKind );
+}
+
+/*************************************************************************
+|*
+|* SwContact, Ctor und Dtor
+|*
+|* Ersterstellung AMA 27.Sep.96 18:13
+|* Letzte Aenderung AMA 27.Sep.96
+|*
+|*************************************************************************/
+
+SwContact::SwContact( SwFrmFmt *pToRegisterIn ) :
+ SwClient( pToRegisterIn ),
+ // OD 05.09.2003 #112039# - init member <mbInDTOR>
+ mbInDTOR( false )
+{}
+
+SwContact::~SwContact()
+{
+ // OD 05.09.2003 #112039# - set <mbInDTOR>
+ SetInDTOR();
+}
+
+// OD 05.09.2003 #112039# - accessor for member <mbInDTOR>
+bool SwContact::IsInDTOR() const
+{
+ return mbInDTOR;
+}
+
+// OD 05.09.2003 #112039# - accessor to set member <mbInDTOR>
+void SwContact::SetInDTOR()
+{
+ mbInDTOR = true;
+}
+
+/** method to move drawing object to corresponding visible layer
+
+ OD 21.08.2003 #i18447#
+
+ @author OD
+*/
+void SwContact::MoveObjToVisibleLayer( SdrObject* _pDrawObj )
+{
+ // --> OD 2005-06-08 #i46297# - notify background about the arriving of
+ // the object and invalidate its position.
+ const bool bNotify( !GetFmt()->getIDocumentDrawModelAccess()->IsVisibleLayerId( _pDrawObj->GetLayer() ) );
+ // <--
+
+ _MoveObjToLayer( true, _pDrawObj );
+
+ // --> OD 2005-05-23 #i46297#
+ if ( bNotify )
+ {
+ SwAnchoredObject* pAnchoredObj = GetAnchoredObj( _pDrawObj );
+ ASSERT( pAnchoredObj,
+ "<SwContact::MoveObjToInvisibleLayer(..)> - missing anchored object" );
+ if ( pAnchoredObj )
+ {
+ ::setContextWritingMode( _pDrawObj, pAnchoredObj->GetAnchorFrmContainingAnchPos() );
+ // Note: as-character anchored objects aren't registered at a page frame and
+ // a notification of its background isn't needed.
+ if ( pAnchoredObj->GetPageFrm() )
+ {
+ ::Notify_Background( _pDrawObj, pAnchoredObj->GetPageFrm(),
+ pAnchoredObj->GetObjRect(), PREP_FLY_ARRIVE, TRUE );
+ }
+
+ pAnchoredObj->InvalidateObjPos();
+ }
+ }
+ // <--
+}
+
+/** method to move drawing object to corresponding invisible layer
+
+ OD 21.08.2003 #i18447#
+
+ @author OD
+*/
+void SwContact::MoveObjToInvisibleLayer( SdrObject* _pDrawObj )
+{
+ // --> OD 2005-06-08 #i46297# - notify background about the leaving of the object.
+ const bool bNotify( GetFmt()->getIDocumentDrawModelAccess()->IsVisibleLayerId( _pDrawObj->GetLayer() ) );
+ // <--
+
+ _MoveObjToLayer( false, _pDrawObj );
+
+ // --> OD 2005-05-19 #i46297#
+ if ( bNotify )
+ {
+ SwAnchoredObject* pAnchoredObj = GetAnchoredObj( _pDrawObj );
+ ASSERT( pAnchoredObj,
+ "<SwContact::MoveObjToInvisibleLayer(..)> - missing anchored object" );
+ // Note: as-character anchored objects aren't registered at a page frame and
+ // a notification of its background isn't needed.
+ if ( pAnchoredObj && pAnchoredObj->GetPageFrm() )
+ {
+ ::Notify_Background( _pDrawObj, pAnchoredObj->GetPageFrm(),
+ pAnchoredObj->GetObjRect(), PREP_FLY_LEAVE, TRUE );
+ }
+ }
+ // <--
+}
+
+/** method to move object to visible/invisible layer
+
+ OD 21.08.2003 #i18447#
+ implementation for the public method <MoveObjToVisibleLayer(..)>
+ and <MoveObjToInvisibleLayer(..)>
+
+ @author OD
+*/
+void SwContact::_MoveObjToLayer( const bool _bToVisible,
+ SdrObject* _pDrawObj )
+{
+ if ( !_pDrawObj )
+ {
+ ASSERT( false, "SwDrawContact::_MoveObjToLayer(..) - no drawing object!" );
+ return;
+ }
+
+ if ( !pRegisteredIn )
+ {
+ ASSERT( false, "SwDrawContact::_MoveObjToLayer(..) - no drawing frame format!" );
+ return;
+ }
+
+ const IDocumentDrawModelAccess* pIDDMA = static_cast<SwFrmFmt*>(pRegisteredIn)->getIDocumentDrawModelAccess();
+ if ( !pIDDMA )
+ {
+ ASSERT( false, "SwDrawContact::_MoveObjToLayer(..) - no writer document!" );
+ return;
+ }
+
+ SdrLayerID nToHellLayerId =
+ _bToVisible ? pIDDMA->GetHellId() : pIDDMA->GetInvisibleHellId();
+ SdrLayerID nToHeavenLayerId =
+ _bToVisible ? pIDDMA->GetHeavenId() : pIDDMA->GetInvisibleHeavenId();
+ SdrLayerID nToControlLayerId =
+ _bToVisible ? pIDDMA->GetControlsId() : pIDDMA->GetInvisibleControlsId();
+ SdrLayerID nFromHellLayerId =
+ _bToVisible ? pIDDMA->GetInvisibleHellId() : pIDDMA->GetHellId();
+ SdrLayerID nFromHeavenLayerId =
+ _bToVisible ? pIDDMA->GetInvisibleHeavenId() : pIDDMA->GetHeavenId();
+ SdrLayerID nFromControlLayerId =
+ _bToVisible ? pIDDMA->GetInvisibleControlsId() : pIDDMA->GetControlsId();
+
+ if ( _pDrawObj->ISA( SdrObjGroup ) )
+ {
+ // determine layer for group object
+ {
+ // proposed layer of a group object is the hell layer
+ SdrLayerID nNewLayerId = nToHellLayerId;
+ if ( ::CheckControlLayer( _pDrawObj ) )
+ {
+ // it has to be the control layer, if one of the member
+ // is a control
+ nNewLayerId = nToControlLayerId;
+ }
+ else if ( _pDrawObj->GetLayer() == pIDDMA->GetHeavenId() ||
+ _pDrawObj->GetLayer() == pIDDMA->GetInvisibleHeavenId() )
+ {
+ // it has to be the heaven layer, if method <GetLayer()> reveals
+ // a heaven layer
+ nNewLayerId = nToHeavenLayerId;
+ }
+ // set layer at group object, but do *not* broadcast and
+ // no propagation to the members.
+ // Thus, call <NbcSetLayer(..)> at super class
+ _pDrawObj->SdrObject::NbcSetLayer( nNewLayerId );
+ }
+
+ // call method recursively for group object members
+ const SdrObjList* pLst =
+ static_cast<SdrObjGroup*>(_pDrawObj)->GetSubList();
+ if ( pLst )
+ {
+ for ( USHORT i = 0; i < pLst->GetObjCount(); ++i )
+ {
+ _MoveObjToLayer( _bToVisible, pLst->GetObj( i ) );
+ }
+ }
+ }
+ else
+ {
+ const SdrLayerID nLayerIdOfObj = _pDrawObj->GetLayer();
+ if ( nLayerIdOfObj == nFromHellLayerId )
+ {
+ _pDrawObj->SetLayer( nToHellLayerId );
+ }
+ else if ( nLayerIdOfObj == nFromHeavenLayerId )
+ {
+ _pDrawObj->SetLayer( nToHeavenLayerId );
+ }
+ else if ( nLayerIdOfObj == nFromControlLayerId )
+ {
+ _pDrawObj->SetLayer( nToControlLayerId );
+ }
+ }
+}
+
+// -------------------------------------------------------------------------
+// OD 2004-01-16 #110582# - some virtual helper methods for information
+// about the object (Writer fly frame resp. drawing object)
+
+const SwIndex& SwContact::GetCntntAnchorIndex() const
+{
+ return GetCntntAnchor().nContent;
+}
+
+/** get minimum order number of anchored objects handled by with contact
+
+ OD 2004-08-24 #110810#
+
+ @author
+*/
+sal_uInt32 SwContact::GetMinOrdNum() const
+{
+ sal_uInt32 nMinOrdNum( SAL_MAX_UINT32 );
+
+ std::vector< SwAnchoredObject* > aObjs;
+ GetAnchoredObjs( aObjs );
+
+ while ( !aObjs.empty() )
+ {
+ sal_uInt32 nTmpOrdNum = aObjs.back()->GetDrawObj()->GetOrdNum();
+
+ if ( nTmpOrdNum < nMinOrdNum )
+ {
+ nMinOrdNum = nTmpOrdNum;
+ }
+
+ aObjs.pop_back();
+ }
+
+ ASSERT( nMinOrdNum != SAL_MAX_UINT32,
+ "<SwContact::GetMinOrdNum()> - no order number found." );
+ return nMinOrdNum;
+}
+
+/** get maximum order number of anchored objects handled by with contact
+
+ OD 2004-08-24 #110810#
+
+ @author
+*/
+sal_uInt32 SwContact::GetMaxOrdNum() const
+{
+ sal_uInt32 nMaxOrdNum( 0L );
+
+ std::vector< SwAnchoredObject* > aObjs;
+ GetAnchoredObjs( aObjs );
+
+ while ( !aObjs.empty() )
+ {
+ sal_uInt32 nTmpOrdNum = aObjs.back()->GetDrawObj()->GetOrdNum();
+
+ if ( nTmpOrdNum > nMaxOrdNum )
+ {
+ nMaxOrdNum = nTmpOrdNum;
+ }
+
+ aObjs.pop_back();
+ }
+
+ return nMaxOrdNum;
+}
+// -------------------------------------------------------------------------
+
+/*************************************************************************
+|*
+|* SwFlyDrawContact, Ctor und Dtor
+|*
+|* Ersterstellung OK 23.11.94 18:13
+|* Letzte Aenderung MA 06. Apr. 95
+|*
+|*************************************************************************/
+
+SwFlyDrawContact::SwFlyDrawContact( SwFlyFrmFmt *pToRegisterIn, SdrModel * ) :
+ SwContact( pToRegisterIn )
+{
+ // OD 2004-04-01 #i26791# - class <SwFlyDrawContact> contains the 'master'
+ // drawing object of type <SwFlyDrawObj> on its own.
+ mpMasterObj = new SwFlyDrawObj;
+ mpMasterObj->SetOrdNum( 0xFFFFFFFE );
+ mpMasterObj->SetUserCall( this );
+}
+
+SwFlyDrawContact::~SwFlyDrawContact()
+{
+ if ( mpMasterObj )
+ {
+ mpMasterObj->SetUserCall( 0 );
+ if ( mpMasterObj->GetPage() )
+ mpMasterObj->GetPage()->RemoveObject( mpMasterObj->GetOrdNum() );
+ delete mpMasterObj;
+ }
+}
+
+// OD 2004-03-29 #i26791#
+const SwAnchoredObject* SwFlyDrawContact::GetAnchoredObj( const SdrObject* _pSdrObj ) const
+{
+ ASSERT( _pSdrObj,
+ "<SwFlyDrawContact::GetAnchoredObj(..)> - no object provided" );
+ ASSERT( _pSdrObj->ISA(SwVirtFlyDrawObj),
+ "<SwFlyDrawContact::GetAnchoredObj(..)> - wrong object type object provided" );
+ ASSERT( GetUserCall( _pSdrObj ) == const_cast<SwFlyDrawContact*>(this),
+ "<SwFlyDrawContact::GetAnchoredObj(..)> - provided object doesn't belongs to this contact" );
+
+ const SwAnchoredObject* pRetAnchoredObj = 0L;
+
+ if ( _pSdrObj && _pSdrObj->ISA(SwVirtFlyDrawObj) )
+ {
+ pRetAnchoredObj = static_cast<const SwVirtFlyDrawObj*>(_pSdrObj)->GetFlyFrm();
+ }
+
+ return pRetAnchoredObj;
+}
+
+SwAnchoredObject* SwFlyDrawContact::GetAnchoredObj( SdrObject* _pSdrObj )
+{
+ ASSERT( _pSdrObj,
+ "<SwFlyDrawContact::GetAnchoredObj(..)> - no object provided" );
+ ASSERT( _pSdrObj->ISA(SwVirtFlyDrawObj),
+ "<SwFlyDrawContact::GetAnchoredObj(..)> - wrong object type provided" );
+ ASSERT( GetUserCall( _pSdrObj ) == this,
+ "<SwFlyDrawContact::GetAnchoredObj(..)> - provided object doesn't belongs to this contact" );
+
+ SwAnchoredObject* pRetAnchoredObj = 0L;
+
+ if ( _pSdrObj && _pSdrObj->ISA(SwVirtFlyDrawObj) )
+ {
+ pRetAnchoredObj = static_cast<SwVirtFlyDrawObj*>(_pSdrObj)->GetFlyFrm();
+ }
+
+ return pRetAnchoredObj;
+}
+
+const SdrObject* SwFlyDrawContact::GetMaster() const
+{
+ return mpMasterObj;
+}
+
+SdrObject* SwFlyDrawContact::GetMaster()
+{
+ return mpMasterObj;
+}
+
+void SwFlyDrawContact::SetMaster( SdrObject* _pNewMaster )
+{
+ ASSERT( _pNewMaster->ISA(SwFlyDrawObj),
+ "<SwFlyDrawContact::SetMaster(..)> - wrong type of new master object" );
+ mpMasterObj = static_cast<SwFlyDrawObj *>(_pNewMaster);
+}
+
+/*************************************************************************
+|*
+|* SwFlyDrawContact::CreateNewRef()
+|*
+|* Ersterstellung MA 14. Dec. 94
+|* Letzte Aenderung MA 24. Apr. 95
+|*
+|*************************************************************************/
+
+SwVirtFlyDrawObj *SwFlyDrawContact::CreateNewRef( SwFlyFrm *pFly )
+{
+ SwVirtFlyDrawObj *pDrawObj = new SwVirtFlyDrawObj( *GetMaster(), pFly );
+ pDrawObj->SetModel( GetMaster()->GetModel() );
+ pDrawObj->SetUserCall( this );
+
+ //Der Reader erzeugt die Master und setzt diese, um die Z-Order zu
+ //transportieren, in die Page ein. Beim erzeugen der ersten Referenz werden
+ //die Master aus der Liste entfernt und fuehren von da an ein
+ //Schattendasein.
+ SdrPage* pPg( 0L );
+ if ( 0 != ( pPg = GetMaster()->GetPage() ) )
+ {
+ const UINT32 nOrdNum = GetMaster()->GetOrdNum();
+ pPg->ReplaceObject( pDrawObj, nOrdNum );
+ }
+ // --> OD 2004-08-16 #i27030# - insert new <SwVirtFlyDrawObj> instance
+ // into drawing page with correct order number
+ else
+ {
+ GetFmt()->getIDocumentDrawModelAccess()->GetDrawModel()->GetPage( 0 )->
+ InsertObject( pDrawObj, _GetOrdNumForNewRef( pFly ) );
+ }
+ // <--
+ // --> OD 2004-12-13 #i38889# - assure, that new <SwVirtFlyDrawObj> instance
+ // is in a visible layer.
+ MoveObjToVisibleLayer( pDrawObj );
+ // <--
+ return pDrawObj;
+}
+
+/** method to determine new order number for new instance of <SwVirtFlyDrawObj>
+
+ OD 2004-08-16 #i27030#
+ Used in method <CreateNewRef(..)>
+
+ @author OD
+*/
+sal_uInt32 SwFlyDrawContact::_GetOrdNumForNewRef( const SwFlyFrm* _pFlyFrm )
+{
+ sal_uInt32 nOrdNum( 0L );
+
+ // search for another Writer fly frame registered at same frame format
+ SwClientIter aIter( *GetFmt() );
+ const SwFlyFrm* pFlyFrm( 0L );
+ for ( pFlyFrm = (SwFlyFrm*)aIter.First( TYPE(SwFlyFrm) );
+ pFlyFrm;
+ pFlyFrm = (SwFlyFrm*)aIter.Next() )
+ {
+ if ( pFlyFrm != _pFlyFrm )
+ {
+ break;
+ }
+ }
+
+ if ( pFlyFrm )
+ {
+ // another Writer fly frame found. Take its order number
+ nOrdNum = pFlyFrm->GetVirtDrawObj()->GetOrdNum();
+ }
+ else
+ {
+ // no other Writer fly frame found. Take order number of 'master' object
+ // --> OD 2004-11-11 #i35748# - use method <GetOrdNumDirect()> instead
+ // of method <GetOrdNum()> to avoid a recalculation of the order number,
+ // which isn't intended.
+ nOrdNum = GetMaster()->GetOrdNumDirect();
+ // <--
+ }
+
+ return nOrdNum;
+}
+
+/*************************************************************************
+|*
+|* SwFlyDrawContact::Modify()
+|*
+|* Ersterstellung OK 08.11.94 10:21
+|* Letzte Aenderung MA 06. Dec. 94
+|*
+|*************************************************************************/
+
+void SwFlyDrawContact::Modify( SfxPoolItem *, SfxPoolItem * )
+{
+}
+
+// OD 2004-01-16 #110582# - override method to control Writer fly frames,
+// which are linked, and to assure that all objects anchored at/inside the
+// Writer fly frame are also made visible.
+void SwFlyDrawContact::MoveObjToVisibleLayer( SdrObject* _pDrawObj )
+{
+ ASSERT( _pDrawObj->ISA(SwVirtFlyDrawObj),
+ "<SwFlyDrawContact::MoveObjToVisibleLayer(..)> - wrong SdrObject type -> crash" );
+
+ if ( GetFmt()->getIDocumentDrawModelAccess()->IsVisibleLayerId( _pDrawObj->GetLayer() ) )
+ {
+ // nothing to do
+ return;
+ }
+
+ SwFlyFrm* pFlyFrm = static_cast<SwVirtFlyDrawObj*>(_pDrawObj)->GetFlyFrm();
+
+ // --> OD 2005-03-09 #i44464# - consider, that Writer fly frame content
+ // already exists - (e.g. WW8 document is inserted into a existing document).
+ if ( !pFlyFrm->Lower() )
+ {
+ pFlyFrm->InsertColumns();
+ pFlyFrm->Chain( pFlyFrm->AnchorFrm() );
+ pFlyFrm->InsertCnt();
+ }
+ if ( pFlyFrm->GetDrawObjs() )
+ {
+ for ( sal_uInt8 i = 0; i < pFlyFrm->GetDrawObjs()->Count(); ++i)
+ {
+ // --> OD 2004-07-01 #i28701# - consider type of objects in sorted object list.
+ SdrObject* pObj = (*pFlyFrm->GetDrawObjs())[i]->DrawObj();
+ SwContact* pContact = static_cast<SwContact*>(pObj->GetUserCall());
+ pContact->MoveObjToVisibleLayer( pObj );
+ }
+ }
+
+ // make fly frame visible
+ SwContact::MoveObjToVisibleLayer( _pDrawObj );
+}
+
+// OD 2004-01-16 #110582# - override method to control Writer fly frames,
+// which are linked, and to assure that all objects anchored at/inside the
+// Writer fly frame are also made invisible.
+void SwFlyDrawContact::MoveObjToInvisibleLayer( SdrObject* _pDrawObj )
+{
+ ASSERT( _pDrawObj->ISA(SwVirtFlyDrawObj),
+ "<SwFlyDrawContact::MoveObjToInvisibleLayer(..)> - wrong SdrObject type -> crash" );
+
+ if ( !GetFmt()->getIDocumentDrawModelAccess()->IsVisibleLayerId( _pDrawObj->GetLayer() ) )
+ {
+ // nothing to do
+ return;
+ }
+
+ SwFlyFrm* pFlyFrm = static_cast<SwVirtFlyDrawObj*>(_pDrawObj)->GetFlyFrm();
+
+ pFlyFrm->Unchain();
+ pFlyFrm->DeleteCnt();
+ if ( pFlyFrm->GetDrawObjs() )
+ {
+ for ( sal_uInt8 i = 0; i < pFlyFrm->GetDrawObjs()->Count(); ++i)
+ {
+ // --> OD 2004-07-01 #i28701# - consider type of objects in sorted object list.
+ SdrObject* pObj = (*pFlyFrm->GetDrawObjs())[i]->DrawObj();
+ SwContact* pContact = static_cast<SwContact*>(pObj->GetUserCall());
+ pContact->MoveObjToInvisibleLayer( pObj );
+ }
+ }
+
+ // make fly frame invisible
+ SwContact::MoveObjToInvisibleLayer( _pDrawObj );
+}
+
+/** get data collection of anchored objects, handled by with contact
+
+ OD 2004-08-23 #110810#
+
+ @author
+*/
+void SwFlyDrawContact::GetAnchoredObjs( std::vector<SwAnchoredObject*>& _roAnchoredObjs ) const
+{
+ const SwFrmFmt* pFmt = GetFmt();
+
+ SwClientIter aIter( *(const_cast<SwFrmFmt*>(pFmt)) );
+ for( SwFlyFrm* pFlyFrm = (SwFlyFrm*)aIter.First( TYPE(SwFlyFrm) );
+ pFlyFrm;
+ pFlyFrm = (SwFlyFrm*)aIter.Next() )
+ {
+ _roAnchoredObjs.push_back( pFlyFrm );
+ }
+}
+
+/*************************************************************************
+|*
+|* SwDrawContact, Ctor+Dtor
+|*
+|* Ersterstellung MA 09. Jan. 95
+|* Letzte Aenderung MA 22. Jul. 98
+|*
+|*************************************************************************/
+bool CheckControlLayer( const SdrObject *pObj )
+{
+ if ( FmFormInventor == pObj->GetObjInventor() )
+ return true;
+ if ( pObj->ISA( SdrObjGroup ) )
+ {
+ const SdrObjList *pLst = ((SdrObjGroup*)pObj)->GetSubList();
+ for ( USHORT i = 0; i < pLst->GetObjCount(); ++i )
+ {
+ if ( ::CheckControlLayer( pLst->GetObj( i ) ) )
+ {
+ // OD 21.08.2003 #i18447# - return correct value ;-)
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+SwDrawContact::SwDrawContact( SwFrmFmt* pToRegisterIn, SdrObject* pObj ) :
+ SwContact( pToRegisterIn ),
+ maAnchoredDrawObj(),
+ mbMasterObjCleared( false ),
+ // OD 10.10.2003 #112299#
+ mbDisconnectInProgress( false ),
+ // --> OD 2006-01-18 #129959#
+ mbUserCallActive( false ),
+ // Note: value of <meEventTypeOfCurrentUserCall> isn't of relevance, because
+ // <mbUserCallActive> is FALSE.
+ meEventTypeOfCurrentUserCall( SDRUSERCALL_MOVEONLY )
+ // <--
+{
+ // clear vector containing 'virtual' drawing objects.
+ maDrawVirtObjs.clear();
+
+ // --> OD 2004-09-22 #i33909# - assure, that drawing object is inserted
+ // in the drawing page.
+ if ( !pObj->IsInserted() )
+ {
+ pToRegisterIn->getIDocumentDrawModelAccess()->GetDrawModel()->GetPage(0)->
+ InsertObject( pObj, pObj->GetOrdNumDirect() );
+ }
+ // <--
+
+ //Controls muessen immer im Control-Layer liegen. Das gilt auch fuer
+ //Gruppenobjekte, wenn diese Controls enthalten.
+ if ( ::CheckControlLayer( pObj ) )
+ {
+ // OD 25.06.2003 #108784# - set layer of object to corresponding invisible layer.
+ pObj->SetLayer( pToRegisterIn->getIDocumentDrawModelAccess()->GetInvisibleControlsId() );
+ }
+
+ // OD 2004-03-29 #i26791#
+ pObj->SetUserCall( this );
+ maAnchoredDrawObj.SetDrawObj( *pObj );
+
+ // if there already exists an SwXShape for the object, ensure it knows about us, and the SdrObject
+ // FS 2009-04-07 #i99056#
+ SwXShape::AddExistingShapeToFmt( *pObj );
+}
+
+SwDrawContact::~SwDrawContact()
+{
+ // OD 05.09.2003 #112039# - set <mbInDTOR>
+ SetInDTOR();
+
+ DisconnectFromLayout();
+
+ // OD 25.06.2003 #108784# - remove 'master' from drawing page
+ RemoveMasterFromDrawPage();
+
+ // remove and destroy 'virtual' drawing objects.
+ RemoveAllVirtObjs();
+
+ if ( !mbMasterObjCleared )
+ {
+ SdrObject* pObject = const_cast< SdrObject* >( maAnchoredDrawObj.GetDrawObj() );
+ SdrObject::Free( pObject );
+ }
+}
+
+// OD 2004-03-29 #i26791#
+const SwAnchoredObject* SwDrawContact::GetAnchoredObj( const SdrObject* _pSdrObj ) const
+{
+ // handle default parameter value
+ if ( !_pSdrObj )
+ {
+ _pSdrObj = GetMaster();
+ }
+
+ ASSERT( _pSdrObj,
+ "<SwDrawContact::GetAnchoredObj(..)> - no object provided" );
+ ASSERT( _pSdrObj->ISA(SwDrawVirtObj) ||
+ ( !_pSdrObj->ISA(SdrVirtObj) && !_pSdrObj->ISA(SwDrawVirtObj) ),
+ "<SwDrawContact::GetAnchoredObj(..)> - wrong object type object provided" );
+ ASSERT( GetUserCall( _pSdrObj ) == const_cast<SwDrawContact*>(this) ||
+ _pSdrObj == GetMaster(),
+ "<SwDrawContact::GetAnchoredObj(..)> - provided object doesn't belongs to this contact" );
+
+ const SwAnchoredObject* pRetAnchoredObj = 0L;
+
+ if ( _pSdrObj )
+ {
+ if ( _pSdrObj->ISA(SwDrawVirtObj) )
+ {
+ pRetAnchoredObj = static_cast<const SwDrawVirtObj*>(_pSdrObj)->GetAnchoredObj();
+ }
+ else if ( !_pSdrObj->ISA(SdrVirtObj) && !_pSdrObj->ISA(SwDrawVirtObj) )
+ {
+ pRetAnchoredObj = &maAnchoredDrawObj;
+ }
+ }
+
+ return pRetAnchoredObj;
+}
+
+SwAnchoredObject* SwDrawContact::GetAnchoredObj( SdrObject* _pSdrObj )
+{
+ // handle default parameter value
+ if ( !_pSdrObj )
+ {
+ _pSdrObj = GetMaster();
+ }
+
+ ASSERT( _pSdrObj,
+ "<SwDrawContact::GetAnchoredObj(..)> - no object provided" );
+ ASSERT( _pSdrObj->ISA(SwDrawVirtObj) ||
+ ( !_pSdrObj->ISA(SdrVirtObj) && !_pSdrObj->ISA(SwDrawVirtObj) ),
+ "<SwDrawContact::GetAnchoredObj(..)> - wrong object type object provided" );
+ ASSERT( GetUserCall( _pSdrObj ) == this || _pSdrObj == GetMaster(),
+ "<SwDrawContact::GetAnchoredObj(..)> - provided object doesn't belongs to this contact" );
+
+ SwAnchoredObject* pRetAnchoredObj = 0L;
+
+ if ( _pSdrObj )
+ {
+ if ( _pSdrObj->ISA(SwDrawVirtObj) )
+ {
+ pRetAnchoredObj = static_cast<SwDrawVirtObj*>(_pSdrObj)->AnchoredObj();
+ }
+ else if ( !_pSdrObj->ISA(SdrVirtObj) && !_pSdrObj->ISA(SwDrawVirtObj) )
+ {
+ pRetAnchoredObj = &maAnchoredDrawObj;
+ }
+ }
+
+ return pRetAnchoredObj;
+}
+
+const SdrObject* SwDrawContact::GetMaster() const
+{
+ return !mbMasterObjCleared
+ ? maAnchoredDrawObj.GetDrawObj()
+ : 0L;
+}
+
+SdrObject* SwDrawContact::GetMaster()
+{
+ return !mbMasterObjCleared
+ ? maAnchoredDrawObj.DrawObj()
+ : 0L;
+}
+
+// OD 16.05.2003 #108784# - overload <SwContact::SetMaster(..)> in order to
+// assert, if the 'master' drawing object is replaced.
+// OD 10.07.2003 #110742# - replace of master object correctly handled, if
+// handled by method <SwDrawContact::ChangeMasterObject(..)>. Thus, assert
+// only, if a debug level is given.
+void SwDrawContact::SetMaster( SdrObject* _pNewMaster )
+{
+ if ( _pNewMaster )
+ {
+#if OSL_DEBUG_LEVEL > 1
+ ASSERT( false, "debug notification - master replaced!" );
+#endif
+ maAnchoredDrawObj.SetDrawObj( *_pNewMaster );
+ }
+ else
+ {
+ mbMasterObjCleared = true;
+ }
+}
+
+const SwFrm* SwDrawContact::GetAnchorFrm( const SdrObject* _pDrawObj ) const
+{
+ const SwFrm* pAnchorFrm = 0L;
+ if ( !_pDrawObj ||
+ _pDrawObj == GetMaster() ||
+ ( !_pDrawObj->GetUserCall() &&
+ GetUserCall( _pDrawObj ) == static_cast<const SwContact* const>(this) ) )
+ {
+ pAnchorFrm = maAnchoredDrawObj.GetAnchorFrm();
+ }
+ else if ( _pDrawObj->ISA(SwDrawVirtObj) )
+ {
+ pAnchorFrm = static_cast<const SwDrawVirtObj*>(_pDrawObj)->GetAnchorFrm();
+ }
+ else
+ {
+ ASSERT( false,
+ "<SwDrawContact::GetAnchorFrm(..)> - unknown drawing object." )
+ }
+
+ return pAnchorFrm;
+}
+SwFrm* SwDrawContact::GetAnchorFrm( SdrObject* _pDrawObj )
+{
+ SwFrm* pAnchorFrm = 0L;
+ if ( !_pDrawObj ||
+ _pDrawObj == GetMaster() ||
+ ( !_pDrawObj->GetUserCall() &&
+ GetUserCall( _pDrawObj ) == this ) )
+ {
+ pAnchorFrm = maAnchoredDrawObj.AnchorFrm();
+ }
+ else
+ {
+ ASSERT( _pDrawObj->ISA(SwDrawVirtObj),
+ "<SwDrawContact::GetAnchorFrm(..)> - unknown drawing object." )
+ pAnchorFrm = static_cast<SwDrawVirtObj*>(_pDrawObj)->AnchorFrm();
+ }
+
+ return pAnchorFrm;
+}
+
+// OD 23.06.2003 #108784# - method to create a new 'virtual' drawing object.
+SwDrawVirtObj* SwDrawContact::CreateVirtObj()
+{
+ // determine 'master'
+ SdrObject* pOrgMasterSdrObj = GetMaster();
+
+ // create 'virtual' drawing object
+ SwDrawVirtObj* pNewDrawVirtObj = new SwDrawVirtObj ( *(pOrgMasterSdrObj), *(this) );
+
+ // add new 'virtual' drawing object managing data structure
+ maDrawVirtObjs.push_back( pNewDrawVirtObj );
+
+ return pNewDrawVirtObj;
+}
+
+// OD 23.06.2003 #108784# - destroys a given 'virtual' drawing object.
+// side effect: 'virtual' drawing object is removed from data structure
+// <maDrawVirtObjs>.
+void SwDrawContact::DestroyVirtObj( SwDrawVirtObj* _pVirtObj )
+{
+ if ( _pVirtObj )
+ {
+ delete _pVirtObj;
+ _pVirtObj = 0;
+ }
+}
+
+// OD 16.05.2003 #108784# - add a 'virtual' drawing object to drawing page.
+// Use an already created one, which isn't used, or create a new one.
+SwDrawVirtObj* SwDrawContact::AddVirtObj()
+{
+ SwDrawVirtObj* pAddedDrawVirtObj = 0L;
+
+ // check, if a disconnected 'virtual' drawing object exist and use it
+ std::list<SwDrawVirtObj*>::const_iterator aFoundVirtObjIter =
+ std::find_if( maDrawVirtObjs.begin(), maDrawVirtObjs.end(),
+ UsedOrUnusedVirtObjPred( false ) );
+
+ if ( aFoundVirtObjIter != maDrawVirtObjs.end() )
+ {
+ // use already created, disconnected 'virtual' drawing object
+ pAddedDrawVirtObj = (*aFoundVirtObjIter);
+ }
+ else
+ {
+ // create new 'virtual' drawing object.
+ pAddedDrawVirtObj = CreateVirtObj();
+ }
+ pAddedDrawVirtObj->AddToDrawingPage();
+
+ return pAddedDrawVirtObj;
+}
+
+// OD 16.05.2003 #108784# - remove 'virtual' drawing objects and destroy them.
+void SwDrawContact::RemoveAllVirtObjs()
+{
+ for ( std::list<SwDrawVirtObj*>::iterator aDrawVirtObjsIter = maDrawVirtObjs.begin();
+ aDrawVirtObjsIter != maDrawVirtObjs.end();
+ ++aDrawVirtObjsIter )
+ {
+ // remove and destroy 'virtual object'
+ SwDrawVirtObj* pDrawVirtObj = (*aDrawVirtObjsIter);
+ pDrawVirtObj->RemoveFromWriterLayout();
+ pDrawVirtObj->RemoveFromDrawingPage();
+ DestroyVirtObj( pDrawVirtObj );
+ }
+ maDrawVirtObjs.clear();
+}
+
+SwDrawContact::VirtObjAnchoredAtFrmPred::VirtObjAnchoredAtFrmPred(
+ const SwFrm& _rAnchorFrm )
+ : mpAnchorFrm( &_rAnchorFrm )
+{
+ if ( mpAnchorFrm->IsCntntFrm() )
+ {
+ const SwCntntFrm* pTmpFrm =
+ static_cast<const SwCntntFrm*>( mpAnchorFrm );
+ while ( pTmpFrm->IsFollow() )
+ {
+ pTmpFrm = pTmpFrm->FindMaster();
+ }
+ mpAnchorFrm = pTmpFrm;
+ }
+}
+
+// OD 2004-04-14 #i26791# - compare with master frame
+bool SwDrawContact::VirtObjAnchoredAtFrmPred::operator() ( const SwDrawVirtObj* _pDrawVirtObj )
+{
+ const SwFrm* pObjAnchorFrm = _pDrawVirtObj->GetAnchorFrm();
+ if ( pObjAnchorFrm && pObjAnchorFrm->IsCntntFrm() )
+ {
+ const SwCntntFrm* pTmpFrm =
+ static_cast<const SwCntntFrm*>( pObjAnchorFrm );
+ while ( pTmpFrm->IsFollow() )
+ {
+ pTmpFrm = pTmpFrm->FindMaster();
+ }
+ pObjAnchorFrm = pTmpFrm;
+ }
+
+ return ( pObjAnchorFrm == mpAnchorFrm );
+}
+
+// OD 19.06.2003 #108784# - get drawing object ('master' or 'virtual') by frame.
+SdrObject* SwDrawContact::GetDrawObjectByAnchorFrm( const SwFrm& _rAnchorFrm )
+{
+ SdrObject* pRetDrawObj = 0L;
+
+ // OD 2004-04-14 #i26791# - compare master frames instead of direct frames
+ const SwFrm* pProposedAnchorFrm = &_rAnchorFrm;
+ if ( pProposedAnchorFrm->IsCntntFrm() )
+ {
+ const SwCntntFrm* pTmpFrm =
+ static_cast<const SwCntntFrm*>( pProposedAnchorFrm );
+ while ( pTmpFrm->IsFollow() )
+ {
+ pTmpFrm = pTmpFrm->FindMaster();
+ }
+ pProposedAnchorFrm = pTmpFrm;
+ }
+
+ const SwFrm* pMasterObjAnchorFrm = GetAnchorFrm();
+ if ( pMasterObjAnchorFrm && pMasterObjAnchorFrm->IsCntntFrm() )
+ {
+ const SwCntntFrm* pTmpFrm =
+ static_cast<const SwCntntFrm*>( pMasterObjAnchorFrm );
+ while ( pTmpFrm->IsFollow() )
+ {
+ pTmpFrm = pTmpFrm->FindMaster();
+ }
+ pMasterObjAnchorFrm = pTmpFrm;
+ }
+
+ if ( pMasterObjAnchorFrm && pMasterObjAnchorFrm == pProposedAnchorFrm )
+ {
+ pRetDrawObj = GetMaster();
+ }
+ else
+ {
+ std::list<SwDrawVirtObj*>::const_iterator aFoundVirtObjIter =
+ std::find_if( maDrawVirtObjs.begin(), maDrawVirtObjs.end(),
+ VirtObjAnchoredAtFrmPred( *pProposedAnchorFrm ) );
+
+ if ( aFoundVirtObjIter != maDrawVirtObjs.end() )
+ {
+ pRetDrawObj = (*aFoundVirtObjIter);
+ }
+ }
+
+ return pRetDrawObj;
+}
+
+/*************************************************************************
+|*
+|* SwDrawContact::Changed
+|*
+|* Ersterstellung MA 09. Jan. 95
+|* Letzte Aenderung MA 29. May. 96
+|*
+|*************************************************************************/
+
+// OD 03.07.2003 #108784#
+void SwDrawContact::NotifyBackgrdOfAllVirtObjs( const Rectangle* pOldBoundRect )
+{
+ for ( std::list<SwDrawVirtObj*>::iterator aDrawVirtObjIter = maDrawVirtObjs.begin();
+ aDrawVirtObjIter != maDrawVirtObjs.end();
+ ++aDrawVirtObjIter )
+ {
+ SwDrawVirtObj* pDrawVirtObj = (*aDrawVirtObjIter);
+ if ( pDrawVirtObj->GetAnchorFrm() )
+ {
+ // --> OD 2004-10-21 #i34640# - determine correct page frame
+ SwPageFrm* pPage = pDrawVirtObj->AnchoredObj()->FindPageFrmOfAnchor();
+ // <--
+ if( pOldBoundRect && pPage )
+ {
+ SwRect aOldRect( *pOldBoundRect );
+ aOldRect.Pos() += pDrawVirtObj->GetOffset();
+ if( aOldRect.HasArea() )
+ ::Notify_Background( pDrawVirtObj, pPage,
+ aOldRect, PREP_FLY_LEAVE,TRUE);
+ }
+ // --> OD 2004-10-21 #i34640# - include spacing for wrapping
+ SwRect aRect( pDrawVirtObj->GetAnchoredObj()->GetObjRectWithSpaces() );
+ // <--
+ if( aRect.HasArea() )
+ {
+ // --> OD 2004-10-21 #i34640# - simplify
+ SwPageFrm* pPg = (SwPageFrm*)::FindPage( aRect, pPage );
+ // <--
+ if ( pPg )
+ ::Notify_Background( pDrawVirtObj, pPg, aRect,
+ PREP_FLY_ARRIVE, TRUE );
+ }
+ ::ClrContourCache( pDrawVirtObj );
+ }
+ }
+}
+
+// OD 2004-04-08 #i26791# - local method to notify the background for a drawing object
+void lcl_NotifyBackgroundOfObj( SwDrawContact& _rDrawContact,
+ const SdrObject& _rObj,
+ const Rectangle* _pOldObjRect )
+{
+ // --> OD 2004-10-21 #i34640#
+ SwAnchoredObject* pAnchoredObj =
+ const_cast<SwAnchoredObject*>(_rDrawContact.GetAnchoredObj( &_rObj ));
+ if ( pAnchoredObj && pAnchoredObj->GetAnchorFrm() )
+ // <--
+ {
+ // --> OD 2004-10-21 #i34640# - determine correct page frame
+ SwPageFrm* pPageFrm = pAnchoredObj->FindPageFrmOfAnchor();
+ // <--
+ if( _pOldObjRect && pPageFrm )
+ {
+ SwRect aOldRect( *_pOldObjRect );
+ if( aOldRect.HasArea() )
+ {
+ // --> OD 2004-10-21 #i34640# - determine correct page frame
+ SwPageFrm* pOldPageFrm = (SwPageFrm*)::FindPage( aOldRect, pPageFrm );
+ // <--
+ ::Notify_Background( &_rObj, pOldPageFrm, aOldRect,
+ PREP_FLY_LEAVE, TRUE);
+ }
+ }
+ // --> OD 2004-10-21 #i34640# - include spacing for wrapping
+ SwRect aNewRect( pAnchoredObj->GetObjRectWithSpaces() );
+ // <--
+ if( aNewRect.HasArea() && pPageFrm )
+ {
+ pPageFrm = (SwPageFrm*)::FindPage( aNewRect, pPageFrm );
+ ::Notify_Background( &_rObj, pPageFrm, aNewRect,
+ PREP_FLY_ARRIVE, TRUE );
+ }
+ ClrContourCache( &_rObj );
+ }
+}
+
+void SwDrawContact::Changed( const SdrObject& rObj,
+ SdrUserCallType eType,
+ const Rectangle& rOldBoundRect )
+{
+ // OD 2004-06-01 #i26791# - no event handling, if existing <ViewShell>
+ // is in contruction
+ SwDoc* pDoc = GetFmt()->GetDoc();
+ if ( pDoc->GetRootFrm() &&
+ pDoc->GetRootFrm()->GetCurrShell() &&
+ pDoc->GetRootFrm()->GetCurrShell()->IsInConstructor() )
+ {
+ return;
+ }
+
+ // --> OD 2005-03-08 #i44339#
+ // no event handling, if document is in destruction.
+ // Exception: It's the SDRUSERCALL_DELETE event
+ if ( pDoc->IsInDtor() && eType != SDRUSERCALL_DELETE )
+ {
+ return;
+ }
+ // <--
+
+ //Action aufsetzen, aber nicht wenn gerade irgendwo eine Action laeuft.
+ ViewShell *pSh = 0, *pOrg;
+ if ( pDoc->GetRootFrm() && pDoc->GetRootFrm()->IsCallbackActionEnabled() )
+ {
+ pDoc->GetEditShell( &pOrg );
+ pSh = pOrg;
+ if ( pSh )
+ do
+ { if ( pSh->Imp()->IsAction() || pSh->Imp()->IsIdleAction() )
+ pSh = 0;
+ else
+ pSh = (ViewShell*)pSh->GetNext();
+
+ } while ( pSh && pSh != pOrg );
+
+ if ( pSh )
+ pDoc->GetRootFrm()->StartAllAction();
+ }
+ SdrObjUserCall::Changed( rObj, eType, rOldBoundRect );
+ _Changed( rObj, eType, &rOldBoundRect ); //Achtung, ggf. Suizid!
+
+ if ( pSh )
+ pDoc->GetRootFrm()->EndAllAction();
+}
+
+// --> OD 2006-01-18 #129959#
+// helper class for method <SwDrawContact::_Changed(..)> for handling nested
+// <SdrObjUserCall> events
+class NestedUserCallHdl
+{
+ private:
+ SwDrawContact* mpDrawContact;
+ bool mbParentUserCallActive;
+ SdrUserCallType meParentUserCallEventType;
+
+ public:
+ NestedUserCallHdl( SwDrawContact* _pDrawContact,
+ SdrUserCallType _eEventType )
+ : mpDrawContact( _pDrawContact ),
+ mbParentUserCallActive( _pDrawContact->mbUserCallActive ),
+ meParentUserCallEventType( _pDrawContact->meEventTypeOfCurrentUserCall )
+ {
+ mpDrawContact->mbUserCallActive = true;
+ mpDrawContact->meEventTypeOfCurrentUserCall = _eEventType;
+ }
+
+ ~NestedUserCallHdl()
+ {
+ if ( mpDrawContact )
+ {
+ mpDrawContact->mbUserCallActive = mbParentUserCallActive;
+ mpDrawContact->meEventTypeOfCurrentUserCall = meParentUserCallEventType;
+ }
+ }
+
+ void DrawContactDeleted()
+ {
+ mpDrawContact = 0;
+ }
+
+ bool IsNestedUserCall()
+ {
+ return mbParentUserCallActive;
+ }
+
+ void AssertNestedUserCall()
+ {
+ if ( IsNestedUserCall() )
+ {
+ bool bTmpAssert( true );
+ // Currently its known, that a nested event SDRUSERCALL_RESIZE
+ // could occur during parent user call SDRUSERCALL_INSERTED,
+ // SDRUSERCALL_DELETE and SDRUSERCALL_RESIZE for edge objects.
+ // Also possible are nested SDRUSERCALL_CHILD_RESIZE events for
+ // edge objects
+ // Thus, assert all other combinations
+ if ( ( meParentUserCallEventType == SDRUSERCALL_INSERTED ||
+ meParentUserCallEventType == SDRUSERCALL_DELETE ||
+ meParentUserCallEventType == SDRUSERCALL_RESIZE ) &&
+ mpDrawContact->meEventTypeOfCurrentUserCall == SDRUSERCALL_RESIZE )
+ {
+ bTmpAssert = false;
+ }
+ else if ( meParentUserCallEventType == SDRUSERCALL_CHILD_RESIZE &&
+ mpDrawContact->meEventTypeOfCurrentUserCall == SDRUSERCALL_CHILD_RESIZE )
+ {
+ bTmpAssert = false;
+ }
+
+ if ( bTmpAssert )
+ {
+ ASSERT( false,
+ "<SwDrawContact::_Changed(..)> - unknown nested <UserCall> event. This is serious, please inform OD." );
+ }
+ }
+ }
+};
+
+// <--
+//
+// !!!ACHTUNG!!! The object may commit suicide!!!
+//
+void SwDrawContact::_Changed( const SdrObject& rObj,
+ SdrUserCallType eType,
+ const Rectangle* pOldBoundRect )
+{
+ // --> OD 2006-01-18 #129959#
+ // suppress handling of nested <SdrObjUserCall> events
+ NestedUserCallHdl aNestedUserCallHdl( this, eType );
+ if ( aNestedUserCallHdl.IsNestedUserCall() )
+ {
+ aNestedUserCallHdl.AssertNestedUserCall();
+ return;
+ }
+ // <--
+ // OD 05.08.2002 #100843# - do *not* notify, if document is destructing
+ // --> OD 2004-10-21 #i35912# - do *not* notify for as-character anchored
+ // drawing objects.
+ // --> OD 2004-11-11 #i35007#
+ // improvement: determine as-character anchored object flag only once.
+ const bool bAnchoredAsChar = ObjAnchoredAsChar();
+ // <--
+ const bool bNotify = !(GetFmt()->GetDoc()->IsInDtor()) &&
+ ( SURROUND_THROUGHT != GetFmt()->GetSurround().GetSurround() ) &&
+ !bAnchoredAsChar;
+ // <--
+ switch( eType )
+ {
+ case SDRUSERCALL_DELETE:
+ {
+ if ( bNotify )
+ {
+ lcl_NotifyBackgroundOfObj( *this, rObj, pOldBoundRect );
+ // --> OD 2004-10-27 #i36181# - background of 'virtual'
+ // drawing objects have also been notified.
+ NotifyBackgrdOfAllVirtObjs( pOldBoundRect );
+ // <--
+ }
+ DisconnectFromLayout( false );
+ SetMaster( NULL );
+ delete this;
+ // --> FME 2006-07-12 #i65784# Prevent memory corruption
+ aNestedUserCallHdl.DrawContactDeleted();
+ // <--
+ break;
+ }
+ case SDRUSERCALL_INSERTED:
+ {
+ // OD 10.10.2003 #112299#
+ if ( mbDisconnectInProgress )
+ {
+ ASSERT( false,
+ "<SwDrawContact::_Changed(..)> - Insert event during disconnection from layout is invalid." );
+ }
+ else
+ {
+ ConnectToLayout();
+ if ( bNotify )
+ {
+ lcl_NotifyBackgroundOfObj( *this, rObj, pOldBoundRect );
+ }
+ }
+ break;
+ }
+ case SDRUSERCALL_REMOVED:
+ {
+ if ( bNotify )
+ {
+ lcl_NotifyBackgroundOfObj( *this, rObj, pOldBoundRect );
+ }
+ DisconnectFromLayout( false );
+ break;
+ }
+ case SDRUSERCALL_MOVEONLY:
+ case SDRUSERCALL_RESIZE:
+ case SDRUSERCALL_CHILD_MOVEONLY :
+ case SDRUSERCALL_CHILD_RESIZE :
+ case SDRUSERCALL_CHILD_CHGATTR :
+ case SDRUSERCALL_CHILD_DELETE :
+ case SDRUSERCALL_CHILD_COPY :
+ case SDRUSERCALL_CHILD_INSERTED :
+ case SDRUSERCALL_CHILD_REMOVED :
+ {
+ // --> OD 2004-08-04 #i31698# - improvement:
+ // get instance <SwAnchoredDrawObject> only once
+ const SwAnchoredDrawObject* pAnchoredDrawObj =
+ static_cast<const SwAnchoredDrawObject*>( GetAnchoredObj( &rObj ) );
+ // <--
+ // OD 2004-04-06 #i26791# - adjust positioning and alignment attributes,
+ // if positioning of drawing object isn't in progress.
+ // --> OD 2005-08-15 #i53320# - no adjust of positioning attributes,
+ // if drawing object isn't positioned.
+ if ( !pAnchoredDrawObj->IsPositioningInProgress() &&
+ !pAnchoredDrawObj->NotYetPositioned() )
+ // <--
+ {
+ // --> OD 2004-09-29 #i34748# - If no last object rectangle is
+ // provided by the anchored object, use parameter <pOldBoundRect>.
+ const Rectangle& aOldObjRect = pAnchoredDrawObj->GetLastObjRect()
+ ? *(pAnchoredDrawObj->GetLastObjRect())
+ : *(pOldBoundRect);
+ // <--
+ // --> OD 2008-02-18 #i79400#
+ // always invalidate object rectangle inclusive spaces
+ pAnchoredDrawObj->InvalidateObjRectWithSpaces();
+ // <--
+ // --> OD 2005-01-28 #i41324# - notify background before
+ // adjusting position
+ if ( bNotify )
+ {
+ // --> OD 2004-07-20 #i31573# - correction: Only invalidate
+ // background of given drawing object.
+ lcl_NotifyBackgroundOfObj( *this, rObj, &aOldObjRect );
+ }
+ // <--
+ // --> OD 2004-08-04 #i31698# - determine layout direction
+ // via draw frame format.
+ SwFrmFmt::tLayoutDir eLayoutDir =
+ pAnchoredDrawObj->GetFrmFmt().GetLayoutDir();
+ // <--
+ // use geometry of drawing object
+ SwRect aObjRect( rObj.GetSnapRect() );
+ // If drawing object is a member of a group, the adjustment
+ // of the positioning and the alignment attributes has to
+ // be done for the top group object.
+ if ( rObj.GetUpGroup() )
+ {
+ const SdrObject* pGroupObj = rObj.GetUpGroup();
+ while ( pGroupObj->GetUpGroup() )
+ {
+ pGroupObj = pGroupObj->GetUpGroup();
+ }
+ // use geometry of drawing object
+ aObjRect = pGroupObj->GetSnapRect();
+ }
+ SwTwips nXPosDiff(0L);
+ SwTwips nYPosDiff(0L);
+ switch ( eLayoutDir )
+ {
+ case SwFrmFmt::HORI_L2R:
+ {
+ nXPosDiff = aObjRect.Left() - aOldObjRect.Left();
+ nYPosDiff = aObjRect.Top() - aOldObjRect.Top();
+ }
+ break;
+ case SwFrmFmt::HORI_R2L:
+ {
+ nXPosDiff = aOldObjRect.Right() - aObjRect.Right();
+ nYPosDiff = aObjRect.Top() - aOldObjRect.Top();
+ }
+ break;
+ case SwFrmFmt::VERT_R2L:
+ {
+ nXPosDiff = aObjRect.Top() - aOldObjRect.Top();
+ nYPosDiff = aOldObjRect.Right() - aObjRect.Right();
+ }
+ break;
+ default:
+ {
+ ASSERT( false,
+ "<SwDrawContact::_Changed(..)> - unsupported layout direction" );
+ }
+ }
+ SfxItemSet aSet( GetFmt()->GetDoc()->GetAttrPool(),
+ RES_VERT_ORIENT, RES_HORI_ORIENT, 0 );
+ const SwFmtVertOrient& rVert = GetFmt()->GetVertOrient();
+ if ( nYPosDiff != 0 )
+ {
+
+ if ( rVert.GetRelationOrient() == text::RelOrientation::CHAR ||
+ rVert.GetRelationOrient() == text::RelOrientation::TEXT_LINE )
+ {
+ nYPosDiff = -nYPosDiff;
+ }
+ aSet.Put( SwFmtVertOrient( rVert.GetPos()+nYPosDiff,
+ text::VertOrientation::NONE,
+ rVert.GetRelationOrient() ) );
+ }
+
+ const SwFmtHoriOrient& rHori = GetFmt()->GetHoriOrient();
+ if ( !bAnchoredAsChar && nXPosDiff != 0 )
+ {
+ aSet.Put( SwFmtHoriOrient( rHori.GetPos()+nXPosDiff,
+ text::HoriOrientation::NONE,
+ rHori.GetRelationOrient() ) );
+ }
+
+ if ( nYPosDiff ||
+ ( !bAnchoredAsChar && nXPosDiff != 0 ) )
+ {
+ GetFmt()->GetDoc()->SetFlyFrmAttr( *(GetFmt()), aSet );
+ // keep new object rectangle, to avoid multiple
+ // changes of the attributes by multiple event from
+ // the drawing layer - e.g. group objects and its members
+ // --> OD 2004-09-29 #i34748# - use new method
+ // <SwAnchoredDrawObject::SetLastObjRect(..)>.
+ const_cast<SwAnchoredDrawObject*>(pAnchoredDrawObj)
+ ->SetLastObjRect( aObjRect.SVRect() );
+ }
+ else if ( aObjRect.SSize() != aOldObjRect.GetSize() )
+ {
+ _InvalidateObjs();
+ // --> OD 2004-11-11 #i35007# - notify anchor frame
+ // of as-character anchored object
+ if ( bAnchoredAsChar )
+ {
+ const_cast<SwAnchoredDrawObject*>(pAnchoredDrawObj)
+ ->AnchorFrm()->Prepare( PREP_FLY_ATTR_CHG, GetFmt() );
+ }
+ // <--
+ }
+ }
+ // --> OD 2006-01-18 #129959#
+ // It reveals that the following code causes several defects -
+ // on copying or on ungrouping a group shape containing edge objects.
+ // Testing fix for #i53320# also reveal that the following code
+ // isn't necessary.
+// // --> OD 2005-08-15 #i53320# - reset positioning attributes,
+// // if anchored drawing object isn't yet positioned.
+// else if ( pAnchoredDrawObj->NotYetPositioned() &&
+// static_cast<const SwDrawFrmFmt&>(pAnchoredDrawObj->GetFrmFmt()).IsPosAttrSet() )
+// {
+// const_cast<SwDrawFrmFmt&>(
+// static_cast<const SwDrawFrmFmt&>(pAnchoredDrawObj->GetFrmFmt()))
+// .ResetPosAttr();
+// }
+// // <--
+ // <--
+ }
+ break;
+ case SDRUSERCALL_CHGATTR:
+ if ( bNotify )
+ {
+ lcl_NotifyBackgroundOfObj( *this, rObj, pOldBoundRect );
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+namespace
+{
+ static const SwFmtAnchor* lcl_getAnchorFmt( const SfxPoolItem& _rItem )
+ {
+ USHORT nWhich = _rItem.Which();
+ const SwFmtAnchor* pAnchorFmt = NULL;
+ if ( RES_ATTRSET_CHG == nWhich )
+ {
+ static_cast<const SwAttrSetChg&>(_rItem).GetChgSet()->
+ GetItemState( RES_ANCHOR, FALSE, (const SfxPoolItem**)&pAnchorFmt );
+ }
+ else if ( RES_ANCHOR == nWhich )
+ {
+ pAnchorFmt = &static_cast<const SwFmtAnchor&>(_rItem);
+ }
+ return pAnchorFmt;
+ }
+}
+
+/*************************************************************************
+|*
+|* SwDrawContact::Modify()
+|*
+|* Ersterstellung MA 09. Jan. 95
+|* Letzte Aenderung MA 03. Dec. 95
+|*
+|*************************************************************************/
+
+void SwDrawContact::Modify( SfxPoolItem *pOld, SfxPoolItem *pNew )
+{
+ // OD 10.10.2003 #112299#
+ ASSERT( !mbDisconnectInProgress,
+ "<SwDrawContact::Modify(..)> called during disconnection.");
+
+ USHORT nWhich = pNew ? pNew->Which() : 0;
+ const SwFmtAnchor* pNewAnchorFmt = pNew ? lcl_getAnchorFmt( *pNew ) : NULL;
+
+ if ( pNewAnchorFmt )
+ {
+ // JP 10.04.95: nicht auf ein Reset Anchor reagieren !!!!!
+ if ( SFX_ITEM_SET ==
+ GetFmt()->GetAttrSet().GetItemState( RES_ANCHOR, FALSE ) )
+ {
+ // OD 10.10.2003 #112299# - no connect to layout during disconnection
+ if ( !mbDisconnectInProgress )
+ {
+ // determine old object retangle of 'master' drawing object
+ // for notification
+ const Rectangle* pOldRect = 0L;
+ Rectangle aOldRect;
+ if ( GetAnchorFrm() )
+ {
+ // --> OD 2004-10-27 #i36181# - include spacing in object
+ // rectangle for notification.
+ aOldRect = maAnchoredDrawObj.GetObjRectWithSpaces().SVRect();
+ pOldRect = &aOldRect;
+ // <--
+ }
+ // re-connect to layout due to anchor format change
+ ConnectToLayout( pNewAnchorFmt );
+ // notify background of drawing objects
+ lcl_NotifyBackgroundOfObj( *this, *GetMaster(), pOldRect );
+ NotifyBackgrdOfAllVirtObjs( pOldRect );
+
+ const SwFmtAnchor* pOldAnchorFmt = pOld ? lcl_getAnchorFmt( *pOld ) : NULL;
+ if ( !pOldAnchorFmt || ( pOldAnchorFmt->GetAnchorId() != pNewAnchorFmt->GetAnchorId() ) )
+ {
+ ASSERT( maAnchoredDrawObj.DrawObj(), "SwDrawContact::Modify: no draw object here?" );
+ if ( maAnchoredDrawObj.DrawObj() )
+ {
+ // --> OD 2009-07-10 #i102752#
+ // assure that a ShapePropertyChangeNotifier exists
+ maAnchoredDrawObj.DrawObj()->notifyShapePropertyChange( ::svx::eTextShapeAnchorType );
+ // <--
+ }
+ }
+ }
+ }
+ else
+ DisconnectFromLayout();
+ }
+ // --> OD 2006-03-17 #i62875# - revised fix for issue #124157#
+ // no further notification, if not connected to Writer layout
+ else if ( maAnchoredDrawObj.GetAnchorFrm() &&
+ maAnchoredDrawObj.GetDrawObj()->GetUserCall() )
+ {
+ // --> OD 2004-07-01 #i28701# - on change of wrapping style, hell|heaven layer,
+ // or wrapping style influence an update of the <SwSortedObjs> list,
+ // the drawing object is registered in, has to be performed. This is triggered
+ // by the 1st parameter of method call <_InvalidateObjs(..)>.
+ if ( RES_SURROUND == nWhich ||
+ RES_OPAQUE == nWhich ||
+ RES_WRAP_INFLUENCE_ON_OBJPOS == nWhich ||
+ ( RES_ATTRSET_CHG == nWhich &&
+ ( SFX_ITEM_SET == ((SwAttrSetChg*)pNew)->GetChgSet()->GetItemState(
+ RES_SURROUND, FALSE ) ||
+ SFX_ITEM_SET == ((SwAttrSetChg*)pNew)->GetChgSet()->GetItemState(
+ RES_OPAQUE, FALSE ) ||
+ SFX_ITEM_SET == ((SwAttrSetChg*)pNew)->GetChgSet()->GetItemState(
+ RES_WRAP_INFLUENCE_ON_OBJPOS, FALSE ) ) ) )
+ {
+ lcl_NotifyBackgroundOfObj( *this, *GetMaster(), 0L );
+ NotifyBackgrdOfAllVirtObjs( 0L );
+ _InvalidateObjs( true );
+ }
+ else if ( RES_UL_SPACE == nWhich || RES_LR_SPACE == nWhich ||
+ RES_HORI_ORIENT == nWhich || RES_VERT_ORIENT == nWhich ||
+ // --> OD 2004-07-01 #i28701# - add attribute 'Follow text flow'
+ RES_FOLLOW_TEXT_FLOW == nWhich ||
+ ( RES_ATTRSET_CHG == nWhich &&
+ ( SFX_ITEM_SET == ((SwAttrSetChg*)pNew)->GetChgSet()->GetItemState(
+ RES_LR_SPACE, FALSE ) ||
+ SFX_ITEM_SET == ((SwAttrSetChg*)pNew)->GetChgSet()->GetItemState(
+ RES_UL_SPACE, FALSE ) ||
+ SFX_ITEM_SET == ((SwAttrSetChg*)pNew)->GetChgSet()->GetItemState(
+ RES_HORI_ORIENT, FALSE ) ||
+ SFX_ITEM_SET == ((SwAttrSetChg*)pNew)->GetChgSet()->GetItemState(
+ RES_VERT_ORIENT, FALSE ) ||
+ SFX_ITEM_SET == ((SwAttrSetChg*)pNew)->GetChgSet()->GetItemState(
+ RES_FOLLOW_TEXT_FLOW, FALSE ) ) ) )
+ {
+ lcl_NotifyBackgroundOfObj( *this, *GetMaster(), 0L );
+ NotifyBackgrdOfAllVirtObjs( 0L );
+ _InvalidateObjs();
+ }
+ // --> OD 2004-10-26 #i35443#
+ else if ( RES_ATTRSET_CHG == nWhich )
+ {
+ lcl_NotifyBackgroundOfObj( *this, *GetMaster(), 0L );
+ NotifyBackgrdOfAllVirtObjs( 0L );
+ _InvalidateObjs();
+ }
+ // <--
+ else if ( RES_REMOVE_UNO_OBJECT == nWhich )
+ {
+ // nothing to do
+ }
+#if OSL_DEBUG_LEVEL > 1
+ else
+ {
+ ASSERT( false,
+ "<SwDrawContact::Modify(..)> - unhandled attribute? - please inform od@openoffice.org" );
+ }
+#endif
+ }
+
+ // --> OD 2005-07-18 #i51474#
+ GetAnchoredObj( 0L )->ResetLayoutProcessBools();
+ // <--
+}
+
+// OD 2004-03-31 #i26791#
+// --> OD 2004-07-01 #i28701# - added parameter <_bUpdateSortedObjsList>
+void SwDrawContact::_InvalidateObjs( const bool _bUpdateSortedObjsList )
+{
+ // invalidate position of existing 'virtual' drawing objects
+ for ( std::list<SwDrawVirtObj*>::iterator aDisconnectIter = maDrawVirtObjs.begin();
+ aDisconnectIter != maDrawVirtObjs.end();
+ ++aDisconnectIter )
+ {
+ SwDrawVirtObj* pDrawVirtObj = (*aDisconnectIter);
+ // --> OD 2004-08-23 #i33313# - invalidation only for connected
+ // 'virtual' drawing objects
+ if ( pDrawVirtObj->IsConnected() )
+ {
+ pDrawVirtObj->AnchoredObj()->InvalidateObjPos();
+ // --> OD 2004-07-01 #i28701#
+ if ( _bUpdateSortedObjsList )
+ {
+ pDrawVirtObj->AnchoredObj()->UpdateObjInSortedList();
+ }
+ // <--
+ }
+ // <--
+ }
+
+ // invalidate position of 'master' drawing object
+ SwAnchoredObject* pAnchoredObj = GetAnchoredObj( 0L );
+ pAnchoredObj->InvalidateObjPos();
+ // --> OD 2004-07-01 #i28701#
+ if ( _bUpdateSortedObjsList )
+ {
+ pAnchoredObj->UpdateObjInSortedList();
+ }
+ // <--
+}
+
+/*************************************************************************
+|*
+|* SwDrawContact::DisconnectFromLayout()
+|*
+|* Ersterstellung MA 09. Jan. 95
+|* Letzte Aenderung MA 25. Mar. 99
+|*
+|*************************************************************************/
+
+void SwDrawContact::DisconnectFromLayout( bool _bMoveMasterToInvisibleLayer )
+{
+ // OD 10.10.2003 #112299#
+ mbDisconnectInProgress = true;
+
+ // --> OD 2004-10-27 #i36181# - notify background of drawing object
+ if ( _bMoveMasterToInvisibleLayer &&
+ !(GetFmt()->GetDoc()->IsInDtor()) &&
+ GetAnchorFrm() )
+ {
+ const Rectangle aOldRect( maAnchoredDrawObj.GetObjRectWithSpaces().SVRect() );
+ lcl_NotifyBackgroundOfObj( *this, *GetMaster(), &aOldRect );
+ NotifyBackgrdOfAllVirtObjs( &aOldRect );
+ }
+ // <--
+
+ // OD 16.05.2003 #108784# - remove 'virtual' drawing objects from writer
+ // layout and from drawing page
+ for ( std::list<SwDrawVirtObj*>::iterator aDisconnectIter = maDrawVirtObjs.begin();
+ aDisconnectIter != maDrawVirtObjs.end();
+ ++aDisconnectIter )
+ {
+ SwDrawVirtObj* pDrawVirtObj = (*aDisconnectIter);
+ pDrawVirtObj->RemoveFromWriterLayout();
+ pDrawVirtObj->RemoveFromDrawingPage();
+ }
+
+ if ( maAnchoredDrawObj.GetAnchorFrm() )
+ {
+ maAnchoredDrawObj.AnchorFrm()->RemoveDrawObj( maAnchoredDrawObj );
+ }
+
+ if ( _bMoveMasterToInvisibleLayer && GetMaster() && GetMaster()->IsInserted() )
+ {
+ SdrViewIter aIter( GetMaster() );
+ for( SdrView* pView = aIter.FirstView(); pView;
+ pView = aIter.NextView() )
+ {
+ pView->MarkObj( GetMaster(), pView->GetSdrPageView(), TRUE );
+ }
+
+ // OD 25.06.2003 #108784# - Instead of removing 'master' object from
+ // drawing page, move the 'master' drawing object into the corresponding
+ // invisible layer.
+ {
+ //((SwFrmFmt*)pRegisteredIn)->getIDocumentDrawModelAccess()->GetDrawModel()->GetPage(0)->
+ // RemoveObject( GetMaster()->GetOrdNum() );
+ // OD 21.08.2003 #i18447# - in order to consider group object correct
+ // use new method <SwDrawContact::MoveObjToInvisibleLayer(..)>
+ MoveObjToInvisibleLayer( GetMaster() );
+ }
+ }
+
+ // OD 10.10.2003 #112299#
+ mbDisconnectInProgress = false;
+}
+
+// OD 26.06.2003 #108784# - method to remove 'master' drawing object
+// from drawing page.
+void SwDrawContact::RemoveMasterFromDrawPage()
+{
+ if ( GetMaster() )
+ {
+ GetMaster()->SetUserCall( 0 );
+ if ( GetMaster()->IsInserted() )
+ {
+ ((SwFrmFmt*)pRegisteredIn)->getIDocumentDrawModelAccess()->GetDrawModel()->GetPage(0)->
+ RemoveObject( GetMaster()->GetOrdNum() );
+ }
+ }
+}
+
+// OD 19.06.2003 #108784# - disconnect for a dedicated drawing object -
+// could be 'master' or 'virtual'.
+// a 'master' drawing object will disconnect a 'virtual' drawing object
+// in order to take its place.
+// OD 13.10.2003 #i19919# - no special case, if drawing object isn't in
+// page header/footer, in order to get drawing objects in repeating table headers
+// also working.
+void SwDrawContact::DisconnectObjFromLayout( SdrObject* _pDrawObj )
+{
+ if ( _pDrawObj->ISA(SwDrawVirtObj) )
+ {
+ SwDrawVirtObj* pDrawVirtObj = static_cast<SwDrawVirtObj*>(_pDrawObj);
+ pDrawVirtObj->RemoveFromWriterLayout();
+ pDrawVirtObj->RemoveFromDrawingPage();
+ }
+ else
+ {
+ std::list<SwDrawVirtObj*>::const_iterator aFoundVirtObjIter =
+ std::find_if( maDrawVirtObjs.begin(), maDrawVirtObjs.end(),
+ UsedOrUnusedVirtObjPred( true ) );
+ if ( aFoundVirtObjIter != maDrawVirtObjs.end() )
+ {
+ // replace found 'virtual' drawing object by 'master' drawing
+ // object and disconnect the 'virtual' one
+ SwDrawVirtObj* pDrawVirtObj = (*aFoundVirtObjIter);
+ SwFrm* pNewAnchorFrmOfMaster = pDrawVirtObj->AnchorFrm();
+ // disconnect 'virtual' drawing object
+ pDrawVirtObj->RemoveFromWriterLayout();
+ pDrawVirtObj->RemoveFromDrawingPage();
+ // disconnect 'master' drawing object from current frame
+ GetAnchorFrm()->RemoveDrawObj( maAnchoredDrawObj );
+ // re-connect 'master' drawing object to frame of found 'virtual'
+ // drawing object.
+ pNewAnchorFrmOfMaster->AppendDrawObj( maAnchoredDrawObj );
+ }
+ else
+ {
+ // no connected 'virtual' drawing object found. Thus, disconnect
+ // completely from layout.
+ DisconnectFromLayout();
+ }
+ }
+}
+
+/*************************************************************************
+|*
+|* SwDrawContact::ConnectToLayout()
+|*
+|* Ersterstellung MA 09. Jan. 95
+|* Letzte Aenderung MA 25. Mar. 99
+|*
+|*************************************************************************/
+SwTxtFrm* lcl_GetFlyInCntntAnchor( SwTxtFrm* _pProposedAnchorFrm,
+ const xub_StrLen _nTxtOfs )
+{
+ SwTxtFrm* pAct = _pProposedAnchorFrm;
+ SwTxtFrm* pTmp;
+ do
+ {
+ pTmp = pAct;
+ pAct = pTmp->GetFollow();
+ }
+ while( pAct && _nTxtOfs >= pAct->GetOfst() );
+ return pTmp;
+}
+
+void SwDrawContact::ConnectToLayout( const SwFmtAnchor* pAnch )
+{
+ // OD 10.10.2003 #112299# - *no* connect to layout during disconnection from
+ // layout.
+ if ( mbDisconnectInProgress )
+ {
+ ASSERT( false,
+ "<SwDrawContact::ConnectToLayout(..)> called during disconnection.");
+ return;
+ }
+
+ // --> OD 2004-09-22 #i33909# - *no* connect to layout, if 'master' drawing
+ // object isn't inserted in the drawing page
+ if ( !GetMaster()->IsInserted() )
+ {
+ ASSERT( false, "<SwDrawContact::ConnectToLayout(..)> - master drawing object not inserted -> no connect to layout. Please inform od@openoffice.org" );
+ return;
+ }
+ // <--
+
+ SwFrmFmt* pDrawFrmFmt = (SwFrmFmt*)pRegisteredIn;
+
+ SwRootFrm* pRoot = pDrawFrmFmt->getIDocumentLayoutAccess()->GetRootFrm();
+ if ( !pRoot )
+ {
+ return;
+ }
+
+ // OD 16.05.2003 #108784# - remove 'virtual' drawing objects from writer
+ // layout and from drawing page, and remove 'master' drawing object from
+ // writer layout - 'master' object will remain in drawing page.
+ DisconnectFromLayout( false );
+
+ if ( !pAnch )
+ {
+ pAnch = &(pDrawFrmFmt->GetAnchor());
+ }
+
+ switch ( pAnch->GetAnchorId() )
+ {
+ case FLY_AT_PAGE:
+ {
+ USHORT nPgNum = pAnch->GetPageNum();
+ SwPageFrm *pPage = static_cast<SwPageFrm*>(pRoot->Lower());
+
+ for ( USHORT i = 1; i < nPgNum && pPage; ++i )
+ {
+ pPage = static_cast<SwPageFrm*>(pPage->GetNext());
+ }
+
+ if ( pPage )
+ {
+ pPage->AppendDrawObj( maAnchoredDrawObj );
+ }
+ else
+ //Sieht doof aus, ist aber erlaubt (vlg. SwFEShell::SetPageObjsNewPage)
+ pRoot->SetAssertFlyPages();
+ }
+ break;
+
+ case FLY_AT_CHAR:
+ case FLY_AT_PARA:
+ case FLY_AT_FLY:
+ case FLY_AS_CHAR:
+ {
+ if ( pAnch->GetAnchorId() == FLY_AS_CHAR )
+ {
+ ClrContourCache( GetMaster() );
+ }
+ // OD 16.05.2003 #108784# - support drawing objects in header/footer,
+ // but not control objects:
+ // anchor at first found frame the 'master' object and
+ // at the following frames 'virtual' drawing objects.
+ // Note: method is similar to <SwFlyFrmFmt::MakeFrms(..)>
+ SwModify *pModify = 0;
+ if( pAnch->GetCntntAnchor() )
+ {
+ if ( pAnch->GetAnchorId() == FLY_AT_FLY )
+ {
+ SwNodeIndex aIdx( pAnch->GetCntntAnchor()->nNode );
+ SwCntntNode* pCNd = pDrawFrmFmt->GetDoc()->GetNodes().GoNext( &aIdx );
+ SwClientIter aIter( *pCNd );
+ if ( aIter.First( TYPE(SwFrm) ) )
+ pModify = pCNd;
+ else
+ {
+ const SwNodeIndex& rIdx = pAnch->GetCntntAnchor()->nNode;
+ SwSpzFrmFmts& rFmts = *(pDrawFrmFmt->GetDoc()->GetSpzFrmFmts());
+ for( sal_uInt16 i = 0; i < rFmts.Count(); ++i )
+ {
+ SwFrmFmt* pFlyFmt = rFmts[i];
+ if( pFlyFmt->GetCntnt().GetCntntIdx() &&
+ rIdx == *(pFlyFmt->GetCntnt().GetCntntIdx()) )
+ {
+ pModify = pFlyFmt;
+ break;
+ }
+ }
+ }
+ // --> OD 2004-06-15 #i29199# - It is possible, that
+ // the anchor doesn't exist - E.g., reordering the
+ // sub-documents in a master document.
+ // Note: The anchor will be inserted later.
+ if ( !pModify )
+ {
+ // break to end of the current switch case.
+ break;
+ }
+ }
+ else
+ {
+ pModify = pAnch->GetCntntAnchor()->nNode.GetNode().GetCntntNode();
+ }
+ }
+ SwClientIter aIter( *pModify );
+ SwFrm* pAnchorFrmOfMaster = 0;
+ for( SwFrm *pFrm = (SwFrm*)aIter.First( TYPE(SwFrm) );
+ pFrm;
+ pFrm = (SwFrm*)aIter.Next() )
+ {
+ // append drawing object, if
+ // (1) proposed anchor frame isn't a follow and
+ // (2) drawing object isn't a control object to be anchored
+ // in header/footer.
+ const bool bAdd = ( !pFrm->IsCntntFrm() ||
+ !((SwCntntFrm*)pFrm)->IsFollow() ) &&
+ ( !::CheckControlLayer( GetMaster() ) ||
+ !pFrm->FindFooterOrHeader() );
+
+ if( bAdd )
+ {
+ if ( FLY_AT_FLY == pAnch->GetAnchorId() && !pFrm->IsFlyFrm() )
+ {
+ pFrm = pFrm->FindFlyFrm();
+ ASSERT( pFrm,
+ "<SwDrawContact::ConnectToLayout(..)> - missing fly frame -> crash." );
+ }
+
+ // OD 2004-01-20 #110582# - find correct follow for
+ // as character anchored objects.
+ if ((pAnch->GetAnchorId() == FLY_AS_CHAR) &&
+ pFrm->IsTxtFrm() )
+ {
+ pFrm = lcl_GetFlyInCntntAnchor(
+ static_cast<SwTxtFrm*>(pFrm),
+ pAnch->GetCntntAnchor()->nContent.GetIndex() );
+ }
+
+ if ( !pAnchorFrmOfMaster )
+ {
+ // append 'master' drawing object
+ pAnchorFrmOfMaster = pFrm;
+ pFrm->AppendDrawObj( maAnchoredDrawObj );
+ }
+ else
+ {
+ // append 'virtual' drawing object
+ SwDrawVirtObj* pDrawVirtObj = AddVirtObj();
+ if ( pAnch->GetAnchorId() == FLY_AS_CHAR )
+ {
+ ClrContourCache( pDrawVirtObj );
+ }
+ pFrm->AppendDrawObj( *(pDrawVirtObj->AnchoredObj()) );
+
+ // for repaint, use new ActionChanged()
+ // pDrawVirtObj->SendRepaintBroadcast();
+ pDrawVirtObj->ActionChanged();
+ }
+
+ if ( pAnch->GetAnchorId() == FLY_AS_CHAR )
+ {
+ pFrm->InvalidatePrt();
+ }
+ }
+ }
+ }
+ break;
+ default:
+ ASSERT( FALSE, "Unknown Anchor." )
+ break;
+ }
+ if ( GetAnchorFrm() )
+ {
+ ::setContextWritingMode( maAnchoredDrawObj.DrawObj(), GetAnchorFrm() );
+ // OD 2004-04-01 #i26791# - invalidate objects instead of direct positioning
+ _InvalidateObjs();
+ }
+}
+
+// OD 27.06.2003 #108784# - insert 'master' drawing object into drawing page
+void SwDrawContact::InsertMasterIntoDrawPage()
+{
+ if ( !GetMaster()->IsInserted() )
+ {
+ GetFmt()->getIDocumentDrawModelAccess()->GetDrawModel()->GetPage(0)
+ ->InsertObject( GetMaster(), GetMaster()->GetOrdNumDirect() );
+ }
+ GetMaster()->SetUserCall( this );
+}
+
+/*************************************************************************
+|*
+|* SwDrawContact::FindPage(), ChkPage()
+|*
+|* Ersterstellung MA 21. Mar. 95
+|* Letzte Aenderung MA 19. Jul. 96
+|*
+|*************************************************************************/
+
+SwPageFrm* SwDrawContact::FindPage( const SwRect &rRect )
+{
+ // --> OD 2004-07-01 #i28701# - use method <GetPageFrm()>
+ SwPageFrm* pPg = GetPageFrm();
+ if ( !pPg && GetAnchorFrm() )
+ pPg = GetAnchorFrm()->FindPageFrm();
+ if ( pPg )
+ pPg = (SwPageFrm*)::FindPage( rRect, pPg );
+ return pPg;
+}
+
+void SwDrawContact::ChkPage()
+{
+ // OD 10.10.2003 #112299#
+ if ( mbDisconnectInProgress )
+ {
+ ASSERT( false,
+ "<SwDrawContact::ChkPage()> called during disconnection." );
+ return;
+ }
+
+ // --> OD 2004-07-01 #i28701#
+ SwPageFrm* pPg = ( maAnchoredDrawObj.GetAnchorFrm() &&
+ maAnchoredDrawObj.GetAnchorFrm()->IsPageFrm() )
+ ? GetPageFrm()
+ : FindPage( GetMaster()->GetCurrentBoundRect() );
+ if ( GetPageFrm() != pPg )
+ {
+ // OD 27.06.2003 #108784# - if drawing object is anchor in header/footer
+ // a change of the page is a dramatic change. Thus, completely re-connect
+ // to the layout
+ if ( maAnchoredDrawObj.GetAnchorFrm() &&
+ maAnchoredDrawObj.GetAnchorFrm()->FindFooterOrHeader() )
+ {
+ ConnectToLayout();
+ }
+ else
+ {
+ // --> OD 2004-07-01 #i28701# - use methods <GetPageFrm()> and <SetPageFrm>
+ if ( GetPageFrm() )
+ GetPageFrm()->RemoveDrawObjFromPage( maAnchoredDrawObj );
+ pPg->AppendDrawObjToPage( maAnchoredDrawObj );
+ SetPageFrm( pPg );
+ }
+ }
+}
+
+/*************************************************************************
+|*
+|* SwDrawContact::ChangeMasterObject()
+|*
+|* Ersterstellung MA 07. Aug. 95
+|* Letzte Aenderung MA 20. Apr. 99
+|*
+|*************************************************************************/
+// OD 10.07.2003 #110742# - Important note:
+// method is called by method <SwDPage::ReplaceObject(..)>, which called its
+// corresponding superclass method <FmFormPage::ReplaceObject(..)>.
+// Note: 'master' drawing object *has* to be connected to layout triggered
+// by the caller of this, if method is called.
+void SwDrawContact::ChangeMasterObject( SdrObject *pNewMaster )
+{
+ DisconnectFromLayout( false );
+ // OD 10.07.2003 #110742# - consider 'virtual' drawing objects
+ RemoveAllVirtObjs();
+
+ GetMaster()->SetUserCall( 0 );
+ SetMaster( pNewMaster );
+ GetMaster()->SetUserCall( this );
+
+ _InvalidateObjs();
+}
+
+/** get data collection of anchored objects, handled by with contact
+
+ OD 2004-08-23 #110810#
+
+ @author
+*/
+void SwDrawContact::GetAnchoredObjs( std::vector<SwAnchoredObject*>& _roAnchoredObjs ) const
+{
+ _roAnchoredObjs.push_back( const_cast<SwAnchoredDrawObject*>(&maAnchoredDrawObj) );
+
+ for ( std::list<SwDrawVirtObj*>::const_iterator aDrawVirtObjsIter = maDrawVirtObjs.begin();
+ aDrawVirtObjsIter != maDrawVirtObjs.end();
+ ++aDrawVirtObjsIter )
+ {
+ _roAnchoredObjs.push_back( (*aDrawVirtObjsIter)->AnchoredObj() );
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////////////
+// AW: own sdr::contact::ViewContact (VC) sdr::contact::ViewObjectContact (VOC) needed
+// since offset is defined different from SdrVirtObj's sdr::contact::ViewContactOfVirtObj.
+// For paint, that offset is used by setting at the OutputDevice; for primitives this is
+// not possible since we have no OutputDevice, but define the geometry itself.
+
+namespace sdr
+{
+ namespace contact
+ {
+ class VOCOfDrawVirtObj : public ViewObjectContactOfSdrObj
+ {
+ protected:
+ // This method is responsible for creating the graphical visualisation data which is
+ // stored/cached in the local primitive. Default gets view-independent Primitive
+ // from the ViewContact using ViewContact::getViewIndependentPrimitive2DSequence(), takes care of
+ // visibility, handles glue and ghosted.
+ // This method will not handle included hierarchies and not check geometric visibility.
+ virtual drawinglayer::primitive2d::Primitive2DSequence createPrimitive2DSequence(const DisplayInfo& rDisplayInfo) const;
+
+ public:
+ VOCOfDrawVirtObj(ObjectContact& rObjectContact, ViewContact& rViewContact)
+ : ViewObjectContactOfSdrObj(rObjectContact, rViewContact)
+ {
+ }
+
+ virtual ~VOCOfDrawVirtObj();
+ };
+
+ class VCOfDrawVirtObj : public ViewContactOfVirtObj
+ {
+ protected:
+ // Create a Object-Specific ViewObjectContact, set ViewContact and
+ // ObjectContact. Always needs to return something. Default is to create
+ // a standard ViewObjectContact containing the given ObjectContact and *this
+ virtual ViewObjectContact& CreateObjectSpecificViewObjectContact(ObjectContact& rObjectContact);
+
+ public:
+ // basic constructor, used from SdrObject.
+ VCOfDrawVirtObj(SwDrawVirtObj& rObj)
+ : ViewContactOfVirtObj(rObj)
+ {
+ }
+ virtual ~VCOfDrawVirtObj();
+
+ // access to SwDrawVirtObj
+ SwDrawVirtObj& GetSwDrawVirtObj() const
+ {
+ return (SwDrawVirtObj&)mrObject;
+ }
+ };
+ } // end of namespace contact
+} // end of namespace sdr
+
+namespace sdr
+{
+ namespace contact
+ {
+ // recursively collect primitive data from given VOC with given offset
+ void impAddPrimitivesFromGroup(const ViewObjectContact& rVOC, const basegfx::B2DHomMatrix& rOffsetMatrix, const DisplayInfo& rDisplayInfo, drawinglayer::primitive2d::Primitive2DSequence& rxTarget)
+ {
+ const sal_uInt32 nSubHierarchyCount(rVOC.GetViewContact().GetObjectCount());
+
+ for(sal_uInt32 a(0L); a < nSubHierarchyCount; a++)
+ {
+ const ViewObjectContact& rCandidate(rVOC.GetViewContact().GetViewContact(a).GetViewObjectContact(rVOC.GetObjectContact()));
+
+ if(rCandidate.GetViewContact().GetObjectCount())
+ {
+ // is a group object itself, call resursively
+ impAddPrimitivesFromGroup(rCandidate, rOffsetMatrix, rDisplayInfo, rxTarget);
+ }
+ else
+ {
+ // single object, add primitives; check model-view visibility
+ if(rCandidate.isPrimitiveVisible(rDisplayInfo))
+ {
+ drawinglayer::primitive2d::Primitive2DSequence aNewSequence(rCandidate.getPrimitive2DSequence(rDisplayInfo));
+
+ if(aNewSequence.hasElements())
+ {
+ // get ranges
+ const drawinglayer::geometry::ViewInformation2D& rViewInformation2D(rCandidate.GetObjectContact().getViewInformation2D());
+ const basegfx::B2DRange aViewRange(rViewInformation2D.getViewport());
+ basegfx::B2DRange aObjectRange(rCandidate.getObjectRange());
+
+ // correct with virtual object's offset
+ aObjectRange.transform(rOffsetMatrix);
+
+ // check geometrical visibility (with offset)
+ if(!aViewRange.overlaps(aObjectRange))
+ {
+ // not visible, release
+ aNewSequence.realloc(0);
+ }
+ }
+
+ if(aNewSequence.hasElements())
+ {
+ drawinglayer::primitive2d::appendPrimitive2DSequenceToPrimitive2DSequence(rxTarget, aNewSequence);
+ }
+ }
+ }
+ }
+ }
+
+ drawinglayer::primitive2d::Primitive2DSequence VOCOfDrawVirtObj::createPrimitive2DSequence(const DisplayInfo& rDisplayInfo) const
+ {
+#ifdef DBG_UTIL
+ // #i101734#
+ static bool bCheckOtherThanTranslate(false);
+ static double fShearX(0.0);
+ static double fRotation(0.0);
+ static double fScaleX(0.0);
+ static double fScaleY(0.0);
+#endif
+
+ const VCOfDrawVirtObj& rVC = static_cast< const VCOfDrawVirtObj& >(GetViewContact());
+ const SdrObject& rReferencedObject = rVC.GetSwDrawVirtObj().GetReferencedObj();
+ drawinglayer::primitive2d::Primitive2DSequence xRetval;
+
+ // create offset transformation
+ basegfx::B2DHomMatrix aOffsetMatrix;
+ const Point aLocalOffset(rVC.GetSwDrawVirtObj().GetOffset());
+
+ if(aLocalOffset.X() || aLocalOffset.Y())
+ {
+#ifdef DBG_UTIL
+ // #i101734# added debug code to check more complex transformations
+ // than just a translation
+ if(bCheckOtherThanTranslate)
+ {
+ aOffsetMatrix.scale(fScaleX, fScaleY);
+ aOffsetMatrix.shearX(tan(fShearX * F_PI180));
+ aOffsetMatrix.rotate(fRotation * F_PI180);
+ }
+#endif
+
+ aOffsetMatrix.set(0, 2, aLocalOffset.X());
+ aOffsetMatrix.set(1, 2, aLocalOffset.Y());
+
+ }
+
+ if(rReferencedObject.ISA(SdrObjGroup))
+ {
+ // group object. Since the VOC/OC/VC hierarchy does not represent the
+ // hierarchy virtual objects when they have group objects
+ // (ViewContactOfVirtObj::GetObjectCount() returns null for that purpose)
+ // to avoid multiple usages of VOCs (which would not work), the primitives
+ // for the sub-hierarchy need to be collected here
+
+ // Get the VOC of the referenced object (the Group) and fetch primitives from it
+ const ViewObjectContact& rVOCOfRefObj = rReferencedObject.GetViewContact().GetViewObjectContact(GetObjectContact());
+ impAddPrimitivesFromGroup(rVOCOfRefObj, aOffsetMatrix, rDisplayInfo, xRetval);
+ }
+ else
+ {
+ // single object, use method from referenced object to get the Primitive2DSequence
+ xRetval = rReferencedObject.GetViewContact().getViewIndependentPrimitive2DSequence();
+ }
+
+ if(xRetval.hasElements())
+ {
+ // create transform primitive
+ const drawinglayer::primitive2d::Primitive2DReference xReference(new drawinglayer::primitive2d::TransformPrimitive2D(aOffsetMatrix, xRetval));
+ xRetval = drawinglayer::primitive2d::Primitive2DSequence(&xReference, 1);
+ }
+
+ return xRetval;
+ }
+
+ VOCOfDrawVirtObj::~VOCOfDrawVirtObj()
+ {
+ }
+
+ ViewObjectContact& VCOfDrawVirtObj::CreateObjectSpecificViewObjectContact(ObjectContact& rObjectContact)
+ {
+ return *(new VOCOfDrawVirtObj(rObjectContact, *this));
+ }
+
+ VCOfDrawVirtObj::~VCOfDrawVirtObj()
+ {
+ }
+ } // end of namespace contact
+} // end of namespace sdr
+
+//////////////////////////////////////////////////////////////////////////////////////
+
+// =============================================================================
+/** implementation of class <SwDrawVirtObj>
+
+ OD 14.05.2003 #108784#
+
+ @author OD
+*/
+
+TYPEINIT1(SwDrawVirtObj,SdrVirtObj);
+
+sdr::contact::ViewContact* SwDrawVirtObj::CreateObjectSpecificViewContact()
+{
+ return new sdr::contact::VCOfDrawVirtObj(*this);
+}
+
+// #108784#
+// implemetation of SwDrawVirtObj
+SwDrawVirtObj::SwDrawVirtObj( SdrObject& _rNewObj,
+ SwDrawContact& _rDrawContact )
+ : SdrVirtObj( _rNewObj ),
+ // OD 2004-03-29 #i26791# - init new member <maAnchoredDrawObj>
+ maAnchoredDrawObj(),
+ mrDrawContact( _rDrawContact )
+{
+ // OD 2004-03-29 #i26791#
+ maAnchoredDrawObj.SetDrawObj( *this );
+ // --> OD 2004-11-17 #i35635# - set initial position out of sight
+ NbcMove( Size( -RECT_EMPTY, -RECT_EMPTY ) );
+ // <--
+}
+
+SwDrawVirtObj::~SwDrawVirtObj()
+{}
+
+void SwDrawVirtObj::operator=( const SdrObject& rObj )
+{
+ SdrVirtObj::operator=(rObj);
+ // Note: Members <maAnchoredDrawObj> and <mrDrawContact>
+ // haven't to be considered.
+}
+
+SdrObject* SwDrawVirtObj::Clone() const
+{
+ SwDrawVirtObj* pObj = new SwDrawVirtObj( rRefObj, mrDrawContact );
+
+ if ( pObj )
+ {
+ pObj->operator=(static_cast<const SdrObject&>(*this));
+ // Note: Member <maAnchoredDrawObj> hasn't to be considered.
+ }
+
+ return pObj;
+}
+
+// --------------------------------------------------------------------
+// connection to writer layout: <GetAnchoredObj()>, <SetAnchorFrm(..)>,
+// <GetAnchorFrm()>, <SetPageFrm(..)>, <GetPageFrm()> and <RemoveFromWriterLayout()>
+// --------------------------------------------------------------------
+const SwAnchoredObject* SwDrawVirtObj::GetAnchoredObj() const
+{
+ return &maAnchoredDrawObj;
+}
+
+SwAnchoredObject* SwDrawVirtObj::AnchoredObj()
+{
+ return &maAnchoredDrawObj;
+}
+
+const SwFrm* SwDrawVirtObj::GetAnchorFrm() const
+{
+ // OD 2004-03-29 #i26791# - use new member <maAnchoredDrawObj>
+ return maAnchoredDrawObj.GetAnchorFrm();
+}
+
+SwFrm* SwDrawVirtObj::AnchorFrm()
+{
+ // OD 2004-03-29 #i26791# - use new member <maAnchoredDrawObj>
+ return maAnchoredDrawObj.AnchorFrm();
+}
+
+void SwDrawVirtObj::RemoveFromWriterLayout()
+{
+ // remove contact object from frame for 'virtual' drawing object
+ // OD 2004-03-29 #i26791# - use new member <maAnchoredDrawObj>
+ if ( maAnchoredDrawObj.GetAnchorFrm() )
+ {
+ maAnchoredDrawObj.AnchorFrm()->RemoveDrawObj( maAnchoredDrawObj );
+ }
+}
+
+// --------------------------------------------------------------------
+// connection to writer layout: <AddToDrawingPage()>, <RemoveFromDrawingPage()>
+// --------------------------------------------------------------------
+void SwDrawVirtObj::AddToDrawingPage()
+{
+ // determine 'master'
+ SdrObject* pOrgMasterSdrObj = mrDrawContact.GetMaster();
+
+ // insert 'virtual' drawing object into page, set layer and user call.
+ SdrPage* pDrawPg;
+ // --> OD 2004-08-16 #i27030# - apply order number of referenced object
+ if ( 0 != ( pDrawPg = pOrgMasterSdrObj->GetPage() ) )
+ {
+ // --> OD 2004-08-16 #i27030# - apply order number of referenced object
+ pDrawPg->InsertObject( this, GetReferencedObj().GetOrdNum() );
+ }
+ else
+ {
+ pDrawPg = GetPage();
+ if ( pDrawPg )
+ {
+ pDrawPg->SetObjectOrdNum( GetOrdNumDirect(),
+ GetReferencedObj().GetOrdNum() );
+ }
+ else
+ {
+ SetOrdNum( GetReferencedObj().GetOrdNum() );
+ }
+ }
+ // <--
+ SetUserCall( &mrDrawContact );
+}
+
+void SwDrawVirtObj::RemoveFromDrawingPage()
+{
+ SetUserCall( 0 );
+ if ( GetPage() )
+ {
+ GetPage()->RemoveObject( GetOrdNum() );
+ }
+}
+
+// is 'virtual' drawing object connected to writer layout and to drawing layer.
+bool SwDrawVirtObj::IsConnected() const
+{
+ bool bRetVal = GetAnchorFrm() &&
+ ( GetPage() && GetUserCall() );
+
+ return bRetVal;
+}
+
+void SwDrawVirtObj::NbcSetAnchorPos(const Point& rPnt)
+{
+ SdrObject::NbcSetAnchorPos( rPnt );
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// #i97197#
+// the methods relevant for positioning
+
+const Rectangle& SwDrawVirtObj::GetCurrentBoundRect() const
+{
+ if(aOutRect.IsEmpty())
+ {
+ const_cast<SwDrawVirtObj*>(this)->RecalcBoundRect();
+ }
+
+ return aOutRect;
+}
+
+const Rectangle& SwDrawVirtObj::GetLastBoundRect() const
+{
+ return aOutRect;
+}
+
+const Point SwDrawVirtObj::GetOffset() const
+{
+ // do NOT use IsEmpty() here, there is already a useful offset
+ // in the position
+ if(aOutRect == Rectangle())
+ {
+ return Point();
+ }
+ else
+ {
+ return aOutRect.TopLeft() - GetReferencedObj().GetCurrentBoundRect().TopLeft();
+ }
+}
+
+void SwDrawVirtObj::SetBoundRectDirty()
+{
+ // do nothing to not lose model information in aOutRect
+}
+
+void SwDrawVirtObj::RecalcBoundRect()
+{
+ // OD 2004-04-05 #i26791# - switch order of calling <GetOffset()> and
+ // <ReferencedObj().GetCurrentBoundRect()>, because <GetOffset()> calculates
+ // its value by the 'BoundRect' of the referenced object.
+ //aOutRect = rRefObj.GetCurrentBoundRect();
+ //aOutRect += GetOffset();
+
+ const Point aOffset(GetOffset());
+ aOutRect = ReferencedObj().GetCurrentBoundRect() + aOffset;
+}
+
+basegfx::B2DPolyPolygon SwDrawVirtObj::TakeXorPoly() const
+{
+ basegfx::B2DPolyPolygon aRetval(rRefObj.TakeXorPoly());
+ aRetval.transform(basegfx::tools::createTranslateB2DHomMatrix(GetOffset().X(), GetOffset().Y()));
+
+ return aRetval;
+}
+
+basegfx::B2DPolyPolygon SwDrawVirtObj::TakeContour() const
+{
+ basegfx::B2DPolyPolygon aRetval(rRefObj.TakeContour());
+ aRetval.transform(basegfx::tools::createTranslateB2DHomMatrix(GetOffset().X(), GetOffset().Y()));
+
+ return aRetval;
+}
+
+SdrHdl* SwDrawVirtObj::GetHdl(sal_uInt32 nHdlNum) const
+{
+ SdrHdl* pHdl = rRefObj.GetHdl(nHdlNum);
+ Point aP(pHdl->GetPos() + GetOffset());
+ pHdl->SetPos(aP);
+
+ return pHdl;
+}
+
+SdrHdl* SwDrawVirtObj::GetPlusHdl(const SdrHdl& rHdl, USHORT nPlNum) const
+{
+ SdrHdl* pHdl = rRefObj.GetPlusHdl(rHdl, nPlNum);
+ pHdl->SetPos(pHdl->GetPos() + GetOffset());
+
+ return pHdl;
+}
+
+void SwDrawVirtObj::NbcMove(const Size& rSiz)
+{
+ SdrObject::NbcMove( rSiz );
+}
+
+void SwDrawVirtObj::NbcResize(const Point& rRef, const Fraction& xFact, const Fraction& yFact)
+{
+ rRefObj.NbcResize(rRef - GetOffset(), xFact, yFact);
+ SetRectsDirty();
+}
+
+void SwDrawVirtObj::NbcRotate(const Point& rRef, long nWink, double sn, double cs)
+{
+ rRefObj.NbcRotate(rRef - GetOffset(), nWink, sn, cs);
+ SetRectsDirty();
+}
+
+void SwDrawVirtObj::NbcMirror(const Point& rRef1, const Point& rRef2)
+{
+ rRefObj.NbcMirror(rRef1 - GetOffset(), rRef2 - GetOffset());
+ SetRectsDirty();
+}
+
+void SwDrawVirtObj::NbcShear(const Point& rRef, long nWink, double tn, FASTBOOL bVShear)
+{
+ rRefObj.NbcShear(rRef - GetOffset(), nWink, tn, bVShear);
+ SetRectsDirty();
+}
+
+void SwDrawVirtObj::Move(const Size& rSiz)
+{
+ SdrObject::Move( rSiz );
+// Rectangle aBoundRect0; if(pUserCall) aBoundRect0 = GetLastBoundRect();
+// rRefObj.Move( rSiz );
+// SetRectsDirty();
+// SendUserCall(SDRUSERCALL_RESIZE, aBoundRect0);
+}
+
+void SwDrawVirtObj::Resize(const Point& rRef, const Fraction& xFact, const Fraction& yFact)
+{
+ if(xFact.GetNumerator() != xFact.GetDenominator() || yFact.GetNumerator() != yFact.GetDenominator())
+ {
+ Rectangle aBoundRect0; if(pUserCall) aBoundRect0 = GetLastBoundRect();
+ rRefObj.Resize(rRef - GetOffset(), xFact, yFact);
+ SetRectsDirty();
+ SendUserCall(SDRUSERCALL_RESIZE, aBoundRect0);
+ }
+}
+
+void SwDrawVirtObj::Rotate(const Point& rRef, long nWink, double sn, double cs)
+{
+ if(nWink)
+ {
+ Rectangle aBoundRect0; if(pUserCall) aBoundRect0 = GetLastBoundRect();
+ rRefObj.Rotate(rRef - GetOffset(), nWink, sn, cs);
+ SetRectsDirty();
+ SendUserCall(SDRUSERCALL_RESIZE, aBoundRect0);
+ }
+}
+
+void SwDrawVirtObj::Mirror(const Point& rRef1, const Point& rRef2)
+{
+ Rectangle aBoundRect0; if(pUserCall) aBoundRect0 = GetLastBoundRect();
+ rRefObj.Mirror(rRef1 - GetOffset(), rRef2 - GetOffset());
+ SetRectsDirty();
+ SendUserCall(SDRUSERCALL_RESIZE, aBoundRect0);
+}
+
+void SwDrawVirtObj::Shear(const Point& rRef, long nWink, double tn, FASTBOOL bVShear)
+{
+ if(nWink)
+ {
+ Rectangle aBoundRect0; if(pUserCall) aBoundRect0 = GetLastBoundRect();
+ rRefObj.Shear(rRef - GetOffset(), nWink, tn, bVShear);
+ SetRectsDirty();
+ SendUserCall(SDRUSERCALL_RESIZE, aBoundRect0);
+ }
+}
+
+void SwDrawVirtObj::RecalcSnapRect()
+{
+ aSnapRect = rRefObj.GetSnapRect();
+ aSnapRect += GetOffset();
+}
+
+const Rectangle& SwDrawVirtObj::GetSnapRect() const
+{
+ ((SwDrawVirtObj*)this)->aSnapRect = rRefObj.GetSnapRect();
+ ((SwDrawVirtObj*)this)->aSnapRect += GetOffset();
+
+ return aSnapRect;
+}
+
+void SwDrawVirtObj::SetSnapRect(const Rectangle& rRect)
+{
+ Rectangle aBoundRect0; if(pUserCall) aBoundRect0 = GetLastBoundRect();
+ Rectangle aR(rRect);
+ aR -= GetOffset();
+ rRefObj.SetSnapRect(aR);
+ SetRectsDirty();
+ SendUserCall(SDRUSERCALL_RESIZE, aBoundRect0);
+}
+
+void SwDrawVirtObj::NbcSetSnapRect(const Rectangle& rRect)
+{
+ Rectangle aR(rRect);
+ aR -= GetOffset();
+ SetRectsDirty();
+ rRefObj.NbcSetSnapRect(aR);
+}
+
+const Rectangle& SwDrawVirtObj::GetLogicRect() const
+{
+ ((SwDrawVirtObj*)this)->aSnapRect = rRefObj.GetLogicRect();
+ ((SwDrawVirtObj*)this)->aSnapRect += GetOffset();
+
+ return aSnapRect;
+}
+
+void SwDrawVirtObj::SetLogicRect(const Rectangle& rRect)
+{
+ Rectangle aBoundRect0; if(pUserCall) aBoundRect0 = GetLastBoundRect();
+ Rectangle aR(rRect);
+ aR -= GetOffset();
+ rRefObj.SetLogicRect(aR);
+ SetRectsDirty();
+ SendUserCall(SDRUSERCALL_RESIZE, aBoundRect0);
+}
+
+void SwDrawVirtObj::NbcSetLogicRect(const Rectangle& rRect)
+{
+ Rectangle aR(rRect);
+ aR -= GetOffset();
+ rRefObj.NbcSetLogicRect(aR);
+ SetRectsDirty();
+}
+
+Point SwDrawVirtObj::GetSnapPoint(sal_uInt32 i) const
+{
+ Point aP(rRefObj.GetSnapPoint(i));
+ aP += GetOffset();
+
+ return aP;
+}
+
+Point SwDrawVirtObj::GetPoint(sal_uInt32 i) const
+{
+ return Point(rRefObj.GetPoint(i) + GetOffset());
+}
+
+void SwDrawVirtObj::NbcSetPoint(const Point& rPnt, sal_uInt32 i)
+{
+ Point aP(rPnt);
+ aP -= GetOffset();
+ rRefObj.SetPoint(aP, i);
+ SetRectsDirty();
+}
+
+// #108784#
+FASTBOOL SwDrawVirtObj::HasTextEdit() const
+{
+ return rRefObj.HasTextEdit();
+}
+
+// OD 18.06.2003 #108784# - overloaded 'layer' methods for 'virtual' drawing
+// object to assure, that layer of 'virtual' object is the layer of the referenced
+// object.
+SdrLayerID SwDrawVirtObj::GetLayer() const
+{
+ return GetReferencedObj().GetLayer();
+}
+
+void SwDrawVirtObj::NbcSetLayer(SdrLayerID nLayer)
+{
+ ReferencedObj().NbcSetLayer( nLayer );
+ SdrVirtObj::NbcSetLayer( ReferencedObj().GetLayer() );
+}
+
+void SwDrawVirtObj::SetLayer(SdrLayerID nLayer)
+{
+ ReferencedObj().SetLayer( nLayer );
+ SdrVirtObj::NbcSetLayer( ReferencedObj().GetLayer() );
+}
+
+bool SwDrawVirtObj::supportsFullDrag() const
+{
+ // call parent
+ return SdrVirtObj::supportsFullDrag();
+}
+
+SdrObject* SwDrawVirtObj::getFullDragClone() const
+{
+ // call parent
+ return SdrVirtObj::getFullDragClone();
+}
+
+// eof
+