summaryrefslogtreecommitdiff
path: root/sw/source/core/layout/fly.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sw/source/core/layout/fly.cxx')
-rw-r--r--sw/source/core/layout/fly.cxx2882
1 files changed, 2882 insertions, 0 deletions
diff --git a/sw/source/core/layout/fly.cxx b/sw/source/core/layout/fly.cxx
new file mode 100644
index 000000000000..5b265942d561
--- /dev/null
+++ b/sw/source/core/layout/fly.cxx
@@ -0,0 +1,2882 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * 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 <svl/itemiter.hxx>
+#include <svtools/imap.hxx>
+#include <vcl/graph.hxx>
+#include <tools/poly.hxx>
+#include <svx/contdlg.hxx>
+#include <editeng/protitem.hxx>
+#include <editeng/opaqitem.hxx>
+#include <editeng/ulspitem.hxx>
+#include <editeng/lrspitem.hxx>
+#include <editeng/frmdiritem.hxx>
+#include <editeng/keepitem.hxx>
+#include <fmtanchr.hxx>
+#include <fmtfsize.hxx>
+#include <fmtclds.hxx>
+#include <fmtcntnt.hxx>
+#include <fmturl.hxx>
+#include <fmtsrnd.hxx>
+#include <fmtornt.hxx>
+#include <fmtpdsc.hxx>
+#include <fmtcnct.hxx>
+#include <layhelp.hxx>
+#include <ndtxt.hxx>
+#include <svx/svdogrp.hxx>
+#include <ndgrf.hxx>
+#include <tolayoutanchoredobjectposition.hxx>
+#include <fmtfollowtextflow.hxx>
+#include <sortedobjs.hxx>
+#include <objectformatter.hxx>
+#include <anchoredobject.hxx>
+#include <ndole.hxx>
+#include <swtable.hxx>
+#include <svx/svdpage.hxx>
+#include "doc.hxx"
+#include "viewsh.hxx"
+#include "layouter.hxx"
+#include "pagefrm.hxx"
+#include "rootfrm.hxx"
+#include "cntfrm.hxx"
+#include "pam.hxx"
+#include "frmatr.hxx"
+#include "viewimp.hxx"
+#include "viewopt.hxx"
+#include "dcontact.hxx"
+#include "dflyobj.hxx"
+#include "dview.hxx"
+#include "flyfrm.hxx"
+#include "frmtool.hxx"
+#include "frmfmt.hxx"
+#include "hints.hxx"
+#include "swregion.hxx"
+#include "tabfrm.hxx"
+#include "txtfrm.hxx"
+#include "ndnotxt.hxx"
+#include "notxtfrm.hxx" // GetGrfArea
+#include "flyfrms.hxx"
+#include "ndindex.hxx" // GetGrfArea
+#include "sectfrm.hxx"
+#include <vcl/svapp.hxx>
+#include <vcl/salbtype.hxx> // FRound
+#include "switerator.hxx"
+
+using namespace ::com::sun::star;
+
+
+// OD 2004-03-23 #i26791
+TYPEINIT2(SwFlyFrm,SwLayoutFrm,SwAnchoredObject);
+
+/*************************************************************************
+|*
+|* SwFlyFrm::SwFlyFrm()
+|*
+|*************************************************************************/
+
+SwFlyFrm::SwFlyFrm( SwFlyFrmFmt *pFmt, SwFrm* pSib, SwFrm *pAnch ) :
+ SwLayoutFrm( pFmt, pSib ),
+ // OD 2004-03-22 #i26791#
+ SwAnchoredObject(),
+ // OD 2004-05-27 #i26791# - moved to <SwAnchoredObject>
+// aRelPos(),
+ pPrevLink( 0 ),
+ pNextLink( 0 ),
+ bInCnt( sal_False ),
+ bAtCnt( sal_False ),
+ bLayout( sal_False ),
+ bAutoPosition( sal_False ),
+ bNoShrink( sal_False ),
+ bLockDeleteContent( sal_False )
+{
+ nType = FRMC_FLY;
+
+ bInvalid = bNotifyBack = sal_True;
+ bLocked = bMinHeight =
+ bHeightClipped = bWidthClipped = bFormatHeightOnly = sal_False;
+
+ //Grosseneinstellung, Fixe groesse ist immer die Breite
+ const SwFmtFrmSize &rFrmSize = pFmt->GetFrmSize();
+ sal_Bool bVert = sal_False;
+ sal_uInt16 nDir =
+ ((SvxFrameDirectionItem&)pFmt->GetFmtAttr( RES_FRAMEDIR )).GetValue();
+ if( FRMDIR_ENVIRONMENT == nDir )
+ {
+ bDerivedVert = 1;
+ bDerivedR2L = 1;
+ if( pAnch && pAnch->IsVertical() )
+ bVert = sal_True;
+ }
+ else
+ {
+ bInvalidVert = 0;
+ bDerivedVert = 0;
+ bDerivedR2L = 0;
+ if( FRMDIR_HORI_LEFT_TOP == nDir || FRMDIR_HORI_RIGHT_TOP == nDir )
+ {
+ //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
+ bVertLR = 0;
+ bVertical = 0;
+ }
+ else
+ {
+ const ViewShell *pSh = getRootFrm() ? getRootFrm()->GetCurrShell() : 0;
+ if( pSh && pSh->GetViewOptions()->getBrowseMode() )
+ {
+ //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
+ bVertLR = 0;
+ bVertical = 0;
+ }
+ else
+ {
+ bVertical = 1;
+ //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
+ if ( FRMDIR_VERT_TOP_LEFT == nDir )
+ bVertLR = 1;
+ else
+ bVertLR = 0;
+ }
+ }
+
+ bVert = bVertical;
+ bInvalidR2L = 0;
+ if( FRMDIR_HORI_RIGHT_TOP == nDir )
+ bRightToLeft = 1;
+ else
+ bRightToLeft = 0;
+ }
+
+ Frm().Width( rFrmSize.GetWidth() );
+ Frm().Height( rFrmSize.GetHeightSizeType() == ATT_VAR_SIZE ? MINFLY : rFrmSize.GetHeight() );
+
+ //Hoehe Fix oder Variabel oder was?
+ if ( rFrmSize.GetHeightSizeType() == ATT_MIN_SIZE )
+ bMinHeight = sal_True;
+ else if ( rFrmSize.GetHeightSizeType() == ATT_FIX_SIZE )
+ bFixSize = sal_True;
+
+ // OD 2004-02-12 #110582#-2 - insert columns, if necessary
+ InsertColumns();
+
+ //Erst das Init, dann den Inhalt, denn zum Inhalt koennen widerum
+ //Objekte/Rahmen gehoeren die dann angemeldet werden.
+ InitDrawObj( sal_False );
+
+ // OD 2004-01-19 #110582#
+ Chain( pAnch );
+
+ // OD 2004-01-19 #110582#
+ InsertCnt();
+
+ //Und erstmal in den Wald stellen die Kiste, damit bei neuen Dokument nicht
+ //unnoetig viel formatiert wird.
+ Frm().Pos().X() = Frm().Pos().Y() = WEIT_WECH;
+}
+
+// OD 2004-01-19 #110582#
+void SwFlyFrm::Chain( SwFrm* _pAnch )
+{
+ // Connect to chain neighboors.
+ // No problem, if a neighboor doesn't exist - the construction of the
+ // neighboor will make the connection
+ const SwFmtChain& rChain = GetFmt()->GetChain();
+ if ( rChain.GetPrev() || rChain.GetNext() )
+ {
+ if ( rChain.GetNext() )
+ {
+ SwFlyFrm* pFollow = FindChainNeighbour( *rChain.GetNext(), _pAnch );
+ if ( pFollow )
+ {
+ OSL_ENSURE( !pFollow->GetPrevLink(), "wrong chain detected" );
+ if ( !pFollow->GetPrevLink() )
+ SwFlyFrm::ChainFrames( this, pFollow );
+ }
+ }
+ if ( rChain.GetPrev() )
+ {
+ SwFlyFrm *pMaster = FindChainNeighbour( *rChain.GetPrev(), _pAnch );
+ if ( pMaster )
+ {
+ OSL_ENSURE( !pMaster->GetNextLink(), "wrong chain detected" );
+ if ( !pMaster->GetNextLink() )
+ SwFlyFrm::ChainFrames( pMaster, this );
+ }
+ }
+ }
+}
+
+// OD 2004-01-19 #110582#
+void SwFlyFrm::InsertCnt()
+{
+ if ( !GetPrevLink() )
+ {
+ const SwFmtCntnt& rCntnt = GetFmt()->GetCntnt();
+ OSL_ENSURE( rCntnt.GetCntntIdx(), ":-( no content prepared." );
+ sal_uLong nIndex = rCntnt.GetCntntIdx()->GetIndex();
+ // Lower() bedeutet SwColumnFrm, eingefuegt werden muss der Inhalt dann in den (Column)BodyFrm
+ ::_InsertCnt( Lower() ? (SwLayoutFrm*)((SwLayoutFrm*)Lower())->Lower() : (SwLayoutFrm*)this,
+ GetFmt()->GetDoc(), nIndex );
+
+ //NoTxt haben immer eine FixHeight.
+ if ( Lower() && Lower()->IsNoTxtFrm() )
+ {
+ bFixSize = sal_True;
+ bMinHeight = sal_False;
+ }
+ }
+}
+
+ // OD 2004-02-12 #110582#-2
+ void SwFlyFrm::InsertColumns()
+ {
+ // --> OD 2009-08-12 #i97379#
+ // Check, if column are allowed.
+ // Columns are not allowed for fly frames, which represent graphics or embedded objects.
+ const SwFmtCntnt& rCntnt = GetFmt()->GetCntnt();
+ OSL_ENSURE( rCntnt.GetCntntIdx(), "<SwFlyFrm::InsertColumns()> - no content prepared." );
+ SwNodeIndex aFirstCntnt( *(rCntnt.GetCntntIdx()), 1 );
+ if ( aFirstCntnt.GetNode().IsNoTxtNode() )
+ {
+ return;
+ }
+ // <--
+
+ const SwFmtCol &rCol = GetFmt()->GetCol();
+ if ( rCol.GetNumCols() > 1 )
+ {
+ //PrtArea ersteinmal so gross wie der Frm, damit die Spalten
+ //vernuenftig eingesetzt werden koennen; das schaukelt sich dann
+ //schon zurecht.
+ Prt().Width( Frm().Width() );
+ Prt().Height( Frm().Height() );
+ const SwFmtCol aOld; //ChgColumns() verlaesst sich darauf, dass auch ein
+ //Old-Wert hereingereicht wird.
+ ChgColumns( aOld, rCol );
+ }
+ }
+
+/*************************************************************************
+|*
+|* SwFlyFrm::~SwFlyFrm()
+|*
+|*************************************************************************/
+
+SwFlyFrm::~SwFlyFrm()
+{
+ // Accessible objects for fly frames will be destroyed in this destructor.
+ // For frames bound as char or frames that don't have an anchor we have
+ // to do that ourselves. For any other frame the call RemoveFly at the
+ // anchor will do that.
+ if( IsAccessibleFrm() && GetFmt() && (IsFlyInCntFrm() || !GetAnchorFrm()) )
+ {
+ SwRootFrm *pRootFrm = getRootFrm();
+ if( pRootFrm && pRootFrm->IsAnyShellAccessible() )
+ {
+ ViewShell *pVSh = pRootFrm->GetCurrShell();
+ if( pVSh && pVSh->Imp() )
+ {
+ // Lowers aren't disposed already, so we have to do a recursive
+ // dispose
+ pVSh->Imp()->DisposeAccessibleFrm( this, sal_True );
+ }
+ }
+ }
+
+ if( GetFmt() && !GetFmt()->GetDoc()->IsInDtor() )
+ {
+ // OD 2004-01-19 #110582#
+ Unchain();
+
+ // OD 2004-01-19 #110582#
+ DeleteCnt();
+
+ //Tschuess sagen.
+ if ( GetAnchorFrm() )
+ AnchorFrm()->RemoveFly( this );
+ }
+
+ FinitDrawObj();
+}
+
+const IDocumentDrawModelAccess* SwFlyFrm::getIDocumentDrawModelAccess()
+{
+ return GetFmt()->getIDocumentDrawModelAccess();
+}
+
+// OD 2004-01-19 #110582#
+void SwFlyFrm::Unchain()
+{
+ if ( GetPrevLink() )
+ UnchainFrames( GetPrevLink(), this );
+ if ( GetNextLink() )
+ UnchainFrames( this, GetNextLink() );
+}
+
+// OD 2004-01-19 #110582#
+void SwFlyFrm::DeleteCnt()
+{
+ // #110582#-2
+ if ( IsLockDeleteContent() )
+ return;
+
+ SwFrm* pFrm = pLower;
+ while ( pFrm )
+ {
+ while ( pFrm->GetDrawObjs() && pFrm->GetDrawObjs()->Count() )
+ {
+ SwAnchoredObject *pAnchoredObj = (*pFrm->GetDrawObjs())[0];
+ if ( pAnchoredObj->ISA(SwFlyFrm) )
+ delete pAnchoredObj;
+ else if ( pAnchoredObj->ISA(SwAnchoredDrawObject) )
+ {
+ // OD 23.06.2003 #108784# - consider 'virtual' drawing objects
+ SdrObject* pObj = pAnchoredObj->DrawObj();
+ if ( pObj->ISA(SwDrawVirtObj) )
+ {
+ SwDrawVirtObj* pDrawVirtObj = static_cast<SwDrawVirtObj*>(pObj);
+ pDrawVirtObj->RemoveFromWriterLayout();
+ pDrawVirtObj->RemoveFromDrawingPage();
+ }
+ else
+ {
+ SwDrawContact* pContact =
+ static_cast<SwDrawContact*>(::GetUserCall( pObj ));
+ if ( pContact )
+ {
+ pContact->DisconnectFromLayout();
+ }
+ }
+ }
+ }
+
+ pFrm->Remove();
+ delete pFrm;
+ pFrm = pLower;
+ }
+
+ InvalidatePage();
+}
+
+/*************************************************************************
+|*
+|* SwFlyFrm::InitDrawObj()
+|*
+|*************************************************************************/
+
+sal_uInt32 SwFlyFrm::_GetOrdNumForNewRef( const SwFlyDrawContact* pContact )
+{
+ sal_uInt32 nOrdNum( 0L );
+
+ // search for another Writer fly frame registered at same frame format
+ SwIterator<SwFlyFrm,SwFmt> aIter( *pContact->GetFmt() );
+ const SwFlyFrm* pFlyFrm( 0L );
+ for ( pFlyFrm = aIter.First(); pFlyFrm; pFlyFrm = aIter.Next() )
+ {
+ if ( pFlyFrm != this )
+ {
+ 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 = pContact->GetMaster()->GetOrdNumDirect();
+ // <--
+ }
+
+ return nOrdNum;
+}
+
+SwVirtFlyDrawObj* SwFlyFrm::CreateNewRef( SwFlyDrawContact *pContact )
+{
+ SwVirtFlyDrawObj *pDrawObj = new SwVirtFlyDrawObj( *pContact->GetMaster(), this );
+ pDrawObj->SetModel( pContact->GetMaster()->GetModel() );
+ pDrawObj->SetUserCall( pContact );
+
+ //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 = pContact->GetMaster()->GetPage() ) )
+ {
+ const sal_uInt32 nOrdNum = pContact->GetMaster()->GetOrdNum();
+ pPg->ReplaceObject( pDrawObj, nOrdNum );
+ }
+ // --> OD 2004-08-16 #i27030# - insert new <SwVirtFlyDrawObj> instance
+ // into drawing page with correct order number
+ else
+ {
+ pContact->GetFmt()->getIDocumentDrawModelAccess()->GetDrawModel()->GetPage( 0 )->
+ InsertObject( pDrawObj, _GetOrdNumForNewRef( pContact ) );
+ }
+ // <--
+ // --> OD 2004-12-13 #i38889# - assure, that new <SwVirtFlyDrawObj> instance
+ // is in a visible layer.
+ pContact->MoveObjToVisibleLayer( pDrawObj );
+ // <--
+ return pDrawObj;
+}
+
+
+
+void SwFlyFrm::InitDrawObj( sal_Bool bNotify )
+{
+ //ContactObject aus dem Format suchen. Wenn bereits eines existiert, so
+ //braucht nur eine neue Ref erzeugt werden, anderfalls ist es jetzt an
+ //der Zeit das Contact zu erzeugen.
+
+ IDocumentDrawModelAccess* pIDDMA = GetFmt()->getIDocumentDrawModelAccess();
+ SwFlyDrawContact *pContact = SwIterator<SwFlyDrawContact,SwFmt>::FirstElement( *GetFmt() );
+ if ( !pContact )
+ {
+ // --> OD 2005-08-08 #i52858# - method name changed
+ pContact = new SwFlyDrawContact( (SwFlyFrmFmt*)GetFmt(),
+ pIDDMA->GetOrCreateDrawModel() );
+ // <--
+ }
+ OSL_ENSURE( pContact, "InitDrawObj failed" );
+ // OD 2004-03-22 #i26791#
+ SetDrawObj( *(CreateNewRef( pContact )) );
+
+ //Den richtigen Layer setzen.
+ // OD 2004-01-19 #110582#
+ SdrLayerID nHeavenId = pIDDMA->GetHeavenId();
+ SdrLayerID nHellId = pIDDMA->GetHellId();
+ // OD 2004-03-22 #i26791#
+ GetVirtDrawObj()->SetLayer( GetFmt()->GetOpaque().GetValue()
+ ? nHeavenId
+ : nHellId );
+ if ( bNotify )
+ NotifyDrawObj();
+}
+
+/*************************************************************************
+|*
+|* SwFlyFrm::FinitDrawObj()
+|*
+|*************************************************************************/
+
+void SwFlyFrm::FinitDrawObj()
+{
+ if ( !GetVirtDrawObj() )
+ return;
+
+ //Bei den SdrPageViews abmelden falls das Objekt dort noch selektiert ist.
+ if ( !GetFmt()->GetDoc()->IsInDtor() )
+ {
+ ViewShell *p1St = getRootFrm()->GetCurrShell();
+ if ( p1St )
+ {
+ ViewShell *pSh = p1St;
+ do
+ { //z.Zt. kann das Drawing nur ein Unmark auf alles, weil das
+ //Objekt bereits Removed wurde.
+ if( pSh->HasDrawView() )
+ pSh->Imp()->GetDrawView()->UnmarkAll();
+ pSh = (ViewShell*)pSh->GetNext();
+
+ } while ( pSh != p1St );
+ }
+ }
+
+ //VirtObject mit in das Grab nehmen. Wenn das letzte VirObject
+ //zerstoert wird, mussen das DrawObject und DrawContact ebenfalls
+ //zerstoert werden.
+ SwFlyDrawContact *pMyContact = 0;
+ if ( GetFmt() )
+ {
+ bool bContinue = true;
+ SwIterator<SwFrm,SwFmt> aFrmIter( *GetFmt() );
+ for ( SwFrm* pFrm = aFrmIter.First(); pFrm; pFrm = aFrmIter.Next() )
+ if ( pFrm != this )
+ {
+ // don't delete Contact if there is still a Frm
+ bContinue = false;
+ break;
+ }
+
+ if ( bContinue )
+ // no Frm left, find Contact object to destroy
+ pMyContact = SwIterator<SwFlyDrawContact,SwFmt>::FirstElement( *GetFmt() );
+ }
+
+ // OD, OS 2004-03-31 #116203# - clear user call of Writer fly frame 'master'
+ // <SdrObject> to assure, that a <SwXFrame::dispose()> doesn't delete the
+ // Writer fly frame again.
+ if ( pMyContact )
+ {
+ pMyContact->GetMaster()->SetUserCall( 0 );
+ }
+ GetVirtDrawObj()->SetUserCall( 0 ); //Ruft sonst Delete des ContactObj
+ delete GetVirtDrawObj(); //Meldet sich selbst beim Master ab.
+ if ( pMyContact )
+ delete pMyContact; //zerstoert den Master selbst.
+}
+
+/*************************************************************************
+|*
+|* SwFlyFrm::ChainFrames()
+|*
+|*************************************************************************/
+
+void SwFlyFrm::ChainFrames( SwFlyFrm *pMaster, SwFlyFrm *pFollow )
+{
+ OSL_ENSURE( pMaster && pFollow, "uncomplete chain" );
+ OSL_ENSURE( !pMaster->GetNextLink(), "link can not be changed" );
+ OSL_ENSURE( !pFollow->GetPrevLink(), "link can not be changed" );
+
+ pMaster->pNextLink = pFollow;
+ pFollow->pPrevLink = pMaster;
+
+ if ( pMaster->ContainsCntnt() )
+ {
+ //Damit ggf. ein Textfluss zustande kommt muss invalidiert werden.
+ SwFrm *pInva = pMaster->FindLastLower();
+ SWRECTFN( pMaster )
+ const long nBottom = (pMaster->*fnRect->fnGetPrtBottom)();
+ while ( pInva )
+ {
+ if( (pInva->Frm().*fnRect->fnBottomDist)( nBottom ) <= 0 )
+ {
+ pInva->InvalidateSize();
+ pInva->Prepare( PREP_CLEAR );
+ pInva = pInva->FindPrev();
+ }
+ else
+ pInva = 0;
+ }
+ }
+
+ if ( pFollow->ContainsCntnt() )
+ {
+ //Es gibt nur noch den Inhalt des Masters, der Inhalt vom Follow
+ //hat keine Frames mehr (sollte immer nur genau ein leerer TxtNode sein).
+ SwFrm *pFrm = pFollow->ContainsCntnt();
+ OSL_ENSURE( !pFrm->IsTabFrm() && !pFrm->FindNext(), "follow in chain contains content" );
+ pFrm->Cut();
+ delete pFrm;
+ }
+
+ // invalidate accessible relation set (accessibility wrapper)
+ ViewShell* pSh = pMaster->getRootFrm()->GetCurrShell();
+ if( pSh )
+ {
+ SwRootFrm* pLayout = pMaster->getRootFrm();
+ if( pLayout && pLayout->IsAnyShellAccessible() )
+ pSh->Imp()->InvalidateAccessibleRelationSet( pMaster, pFollow );
+ }
+}
+
+void SwFlyFrm::UnchainFrames( SwFlyFrm *pMaster, SwFlyFrm *pFollow )
+{
+ pMaster->pNextLink = 0;
+ pFollow->pPrevLink = 0;
+
+ if ( pFollow->ContainsCntnt() )
+ {
+ //Der Master saugt den Inhalt vom Follow auf
+ SwLayoutFrm *pUpper = pMaster;
+ if ( pUpper->Lower()->IsColumnFrm() )
+ {
+ pUpper = static_cast<SwLayoutFrm*>(pUpper->GetLastLower());
+ pUpper = static_cast<SwLayoutFrm*>(pUpper->Lower()); // der (Column)BodyFrm
+ OSL_ENSURE( pUpper && pUpper->IsColBodyFrm(), "Missing ColumnBody" );
+ }
+ SwFlyFrm *pFoll = pFollow;
+ while ( pFoll )
+ {
+ SwFrm *pTmp = ::SaveCntnt( pFoll );
+ if ( pTmp )
+ ::RestoreCntnt( pTmp, pUpper, pMaster->FindLastLower(), true );
+ pFoll->SetCompletePaint();
+ pFoll->InvalidateSize();
+ pFoll = pFoll->GetNextLink();
+ }
+ }
+
+ //Der Follow muss mit seinem eigenen Inhalt versorgt werden.
+ const SwFmtCntnt &rCntnt = pFollow->GetFmt()->GetCntnt();
+ OSL_ENSURE( rCntnt.GetCntntIdx(), ":-( Kein Inhalt vorbereitet." );
+ sal_uLong nIndex = rCntnt.GetCntntIdx()->GetIndex();
+ // Lower() bedeutet SwColumnFrm, dieser beinhaltet wieder einen SwBodyFrm
+ ::_InsertCnt( pFollow->Lower() ? (SwLayoutFrm*)((SwLayoutFrm*)pFollow->Lower())->Lower()
+ : (SwLayoutFrm*)pFollow,
+ pFollow->GetFmt()->GetDoc(), ++nIndex );
+
+ // invalidate accessible relation set (accessibility wrapper)
+ ViewShell* pSh = pMaster->getRootFrm()->GetCurrShell();
+ if( pSh )
+ {
+ SwRootFrm* pLayout = pMaster->getRootFrm();
+ if( pLayout && pLayout->IsAnyShellAccessible() )
+ pSh->Imp()->InvalidateAccessibleRelationSet( pMaster, pFollow );
+}
+}
+
+/*************************************************************************
+|*
+|* SwFlyFrm::FindChainNeighbour()
+|*
+|*************************************************************************/
+
+SwFlyFrm *SwFlyFrm::FindChainNeighbour( SwFrmFmt &rChain, SwFrm *pAnch )
+{
+ //Wir suchen denjenigen Fly, der in dem selben Bereich steht.
+ //Bereiche koennen zunaechst nur Kopf-/Fusszeilen oder Flys sein.
+
+ if ( !pAnch ) //Wenn ein Anchor uebergeben Wurde zaehlt dieser: Ctor!
+ pAnch = AnchorFrm();
+
+ SwLayoutFrm *pLay;
+ if ( pAnch->IsInFly() )
+ pLay = pAnch->FindFlyFrm();
+ else
+ {
+ //FindFooterOrHeader taugt hier nicht, weil evtl. noch keine Verbindung
+ //zum Anker besteht.
+ pLay = pAnch->GetUpper();
+ while ( pLay && !(pLay->GetType() & (FRM_HEADER|FRM_FOOTER)) )
+ pLay = pLay->GetUpper();
+ }
+
+ SwIterator<SwFlyFrm,SwFmt> aIter( rChain );
+ SwFlyFrm *pFly = aIter.First();
+ if ( pLay )
+ {
+ while ( pFly )
+ {
+ if ( pFly->GetAnchorFrm() )
+ {
+ if ( pFly->GetAnchorFrm()->IsInFly() )
+ {
+ if ( pFly->AnchorFrm()->FindFlyFrm() == pLay )
+ break;
+ }
+ else if ( pLay == pFly->FindFooterOrHeader() )
+ break;
+ }
+ pFly = aIter.Next();
+ }
+ }
+ else if ( pFly )
+ {
+ OSL_ENSURE( !aIter.Next(), "chain with more than one inkarnation" );
+ }
+ return pFly;
+}
+
+
+/*************************************************************************
+|*
+|* SwFlyFrm::FindLastLower()
+|*
+|*************************************************************************/
+
+SwFrm *SwFlyFrm::FindLastLower()
+{
+ SwFrm *pRet = ContainsAny();
+ if ( pRet && pRet->IsInTab() )
+ pRet = pRet->FindTabFrm();
+ SwFrm *pNxt = pRet;
+ while ( pNxt && IsAnLower( pNxt ) )
+ { pRet = pNxt;
+ pNxt = pNxt->FindNext();
+ }
+ return pRet;
+}
+
+
+/*************************************************************************
+|*
+|* SwFlyFrm::FrmSizeChg()
+|*
+|*************************************************************************/
+
+sal_Bool SwFlyFrm::FrmSizeChg( const SwFmtFrmSize &rFrmSize )
+{
+ sal_Bool bRet = sal_False;
+ SwTwips nDiffHeight = Frm().Height();
+ if ( rFrmSize.GetHeightSizeType() == ATT_VAR_SIZE )
+ bFixSize = bMinHeight = sal_False;
+ else
+ {
+ if ( rFrmSize.GetHeightSizeType() == ATT_FIX_SIZE )
+ {
+ bFixSize = sal_True;
+ bMinHeight = sal_False;
+ }
+ else if ( rFrmSize.GetHeightSizeType() == ATT_MIN_SIZE )
+ {
+ bFixSize = sal_False;
+ bMinHeight = sal_True;
+ }
+ nDiffHeight -= rFrmSize.GetHeight();
+ }
+ //Wenn der Fly Spalten enthaehlt muessen der Fly und
+ //die Spalten schon einmal auf die Wunschwerte gebracht
+ //werden, sonst haben wir ein kleines Problem.
+ if ( Lower() )
+ {
+ if ( Lower()->IsColumnFrm() )
+ {
+ const SwRect aOld( GetObjRectWithSpaces() );
+ const Size aOldSz( Prt().SSize() );
+ const SwTwips nDiffWidth = Frm().Width() - rFrmSize.GetWidth();
+ aFrm.Height( aFrm.Height() - nDiffHeight );
+ aFrm.Width ( aFrm.Width() - nDiffWidth );
+ // --> OD 2006-08-16 #i68520#
+ InvalidateObjRectWithSpaces();
+ // <--
+ aPrt.Height( aPrt.Height() - nDiffHeight );
+ aPrt.Width ( aPrt.Width() - nDiffWidth );
+ ChgLowersProp( aOldSz );
+ ::Notify( this, FindPageFrm(), aOld );
+ bValidPos = sal_False;
+ bRet = sal_True;
+ }
+ else if ( Lower()->IsNoTxtFrm() )
+ {
+ bFixSize = sal_True;
+ bMinHeight = sal_False;
+ }
+ }
+ return bRet;
+}
+
+/*************************************************************************
+|*
+|* SwFlyFrm::Modify()
+|*
+|*************************************************************************/
+
+void SwFlyFrm::Modify( const SfxPoolItem* pOld, const SfxPoolItem * pNew )
+{
+ sal_uInt8 nInvFlags = 0;
+
+ if( pNew && RES_ATTRSET_CHG == pNew->Which() )
+ {
+ SfxItemIter aNIter( *((SwAttrSetChg*)pNew)->GetChgSet() );
+ SfxItemIter aOIter( *((SwAttrSetChg*)pOld)->GetChgSet() );
+ SwAttrSetChg aOldSet( *(SwAttrSetChg*)pOld );
+ SwAttrSetChg aNewSet( *(SwAttrSetChg*)pNew );
+ while( sal_True )
+ {
+ _UpdateAttr( (SfxPoolItem*)aOIter.GetCurItem(),
+ (SfxPoolItem*)aNIter.GetCurItem(), nInvFlags,
+ &aOldSet, &aNewSet );
+ if( aNIter.IsAtEnd() )
+ break;
+ aNIter.NextItem();
+ aOIter.NextItem();
+ }
+ if ( aOldSet.Count() || aNewSet.Count() )
+ SwLayoutFrm::Modify( &aOldSet, &aNewSet );
+ }
+ else
+ _UpdateAttr( pOld, pNew, nInvFlags );
+
+ if ( nInvFlags != 0 )
+ {
+ _Invalidate();
+ if ( nInvFlags & 0x01 )
+ {
+ _InvalidatePos();
+ // --> OD 2006-08-16 #i68520#
+ InvalidateObjRectWithSpaces();
+ // <--
+ }
+ if ( nInvFlags & 0x02 )
+ {
+ _InvalidateSize();
+ // --> OD 2006-08-16 #i68520#
+ InvalidateObjRectWithSpaces();
+ // <--
+ }
+ if ( nInvFlags & 0x04 )
+ _InvalidatePrt();
+ if ( nInvFlags & 0x08 )
+ SetNotifyBack();
+ if ( nInvFlags & 0x10 )
+ SetCompletePaint();
+ if ( ( nInvFlags & 0x40 ) && Lower() && Lower()->IsNoTxtFrm() )
+ ClrContourCache( GetVirtDrawObj() );
+ SwRootFrm *pRoot;
+ if ( nInvFlags & 0x20 && 0 != (pRoot = getRootFrm()) )
+ pRoot->InvalidateBrowseWidth();
+ // --> OD 2004-06-28 #i28701#
+ if ( nInvFlags & 0x80 )
+ {
+ // update sorted object lists, the Writer fly frame is registered at.
+ UpdateObjInSortedList();
+ }
+ // <--
+ }
+
+ // --> OD 2005-07-18 #i51474# - reset flags for the layout process
+ ResetLayoutProcessBools();
+ // <--
+}
+
+void SwFlyFrm::_UpdateAttr( const SfxPoolItem *pOld, const SfxPoolItem *pNew,
+ sal_uInt8 &rInvFlags,
+ SwAttrSetChg *pOldSet, SwAttrSetChg *pNewSet )
+{
+ sal_Bool bClear = sal_True;
+ const sal_uInt16 nWhich = pOld ? pOld->Which() : pNew ? pNew->Which() : 0;
+ ViewShell *pSh = getRootFrm()->GetCurrShell();
+ switch( nWhich )
+ {
+ case RES_VERT_ORIENT:
+ case RES_HORI_ORIENT:
+ // OD 22.09.2003 #i18732# - consider new option 'follow text flow'
+ case RES_FOLLOW_TEXT_FLOW:
+ {
+ //Achtung! _immer_ Aktion in ChgRePos() mitpflegen.
+ rInvFlags |= 0x09;
+ }
+ break;
+ // OD 2004-07-01 #i28701# - consider new option 'wrap influence on position'
+ case RES_WRAP_INFLUENCE_ON_OBJPOS:
+ {
+ rInvFlags |= 0x89;
+ }
+ break;
+ case RES_SURROUND:
+ {
+ // OD 2004-05-13 #i28701# - invalidate position on change of
+ // wrapping style.
+ //rInvFlags |= 0x40;
+ rInvFlags |= 0x41;
+ //Der Hintergrund muss benachrichtigt und Invalidiert werden.
+ const SwRect aTmp( GetObjRectWithSpaces() );
+ NotifyBackground( FindPageFrm(), aTmp, PREP_FLY_ATTR_CHG );
+
+ // Durch eine Umlaufaenderung von rahmengebundenen Rahmen kann eine
+ // vertikale Ausrichtung aktiviert/deaktiviert werden => MakeFlyPos
+ if( FLY_AT_FLY == GetFmt()->GetAnchor().GetAnchorId() )
+ rInvFlags |= 0x09;
+
+ //Ggf. die Kontur am Node loeschen.
+ if ( Lower() && Lower()->IsNoTxtFrm() &&
+ !GetFmt()->GetSurround().IsContour() )
+ {
+ SwNoTxtNode *pNd = (SwNoTxtNode*)((SwCntntFrm*)Lower())->GetNode();
+ if ( pNd->HasContour() )
+ pNd->SetContour( 0 );
+ }
+ // --> OD 2004-06-28 #i28701# - perform reorder of object lists
+ // at anchor frame and at page frame.
+ rInvFlags |= 0x80;
+ }
+ break;
+
+ case RES_PROTECT:
+ {
+ const SvxProtectItem *pP = (SvxProtectItem*)pNew;
+ GetVirtDrawObj()->SetMoveProtect( pP->IsPosProtected() );
+ GetVirtDrawObj()->SetResizeProtect( pP->IsSizeProtected() );
+ if( pSh )
+ {
+ SwRootFrm* pLayout = getRootFrm();
+ if( pLayout && pLayout->IsAnyShellAccessible() )
+ pSh->Imp()->InvalidateAccessibleEditableState( sal_True, this );
+ }
+ break;
+ }
+
+ case RES_COL:
+ {
+ ChgColumns( *(const SwFmtCol*)pOld, *(const SwFmtCol*)pNew );
+ const SwFmtFrmSize &rNew = GetFmt()->GetFrmSize();
+ if ( FrmSizeChg( rNew ) )
+ NotifyDrawObj();
+ rInvFlags |= 0x1A;
+ break;
+ }
+
+ case RES_FRM_SIZE:
+ case RES_FMT_CHG:
+ {
+ const SwFmtFrmSize &rNew = GetFmt()->GetFrmSize();
+ if ( FrmSizeChg( rNew ) )
+ NotifyDrawObj();
+ rInvFlags |= 0x7F;
+ if ( RES_FMT_CHG == nWhich )
+ {
+ SwRect aNew( GetObjRectWithSpaces() );
+ SwRect aOld( aFrm );
+ const SvxULSpaceItem &rUL = ((SwFmtChg*)pOld)->pChangedFmt->GetULSpace();
+ aOld.Top( Max( aOld.Top() - long(rUL.GetUpper()), 0L ) );
+ aOld.SSize().Height()+= rUL.GetLower();
+ const SvxLRSpaceItem &rLR = ((SwFmtChg*)pOld)->pChangedFmt->GetLRSpace();
+ aOld.Left ( Max( aOld.Left() - long(rLR.GetLeft()), 0L ) );
+ aOld.SSize().Width() += rLR.GetRight();
+ aNew.Union( aOld );
+ NotifyBackground( FindPageFrm(), aNew, PREP_CLEAR );
+
+ //Dummer Fall. Bei der Zusweisung einer Vorlage k?nnen wir uns
+ //nicht auf das alte Spaltenattribut verlassen. Da diese
+ //wenigstens anzahlgemass fuer ChgColumns vorliegen muessen,
+ //bleibt uns nur einen temporaeres Attribut zu basteln.
+ SwFmtCol aCol;
+ if ( Lower() && Lower()->IsColumnFrm() )
+ {
+ sal_uInt16 nCol = 0;
+ SwFrm *pTmp = Lower();
+ do
+ { ++nCol;
+ pTmp = pTmp->GetNext();
+ } while ( pTmp );
+ aCol.Init( nCol, 0, 1000 );
+ }
+ ChgColumns( aCol, GetFmt()->GetCol() );
+ }
+
+ SwFmtURL aURL( GetFmt()->GetURL() );
+ if ( aURL.GetMap() )
+ {
+ const SwFmtFrmSize &rOld = nWhich == RES_FRM_SIZE ?
+ *(SwFmtFrmSize*)pNew :
+ ((SwFmtChg*)pOld)->pChangedFmt->GetFrmSize();
+ //#35091# Kann beim Laden von Vorlagen mal 0 sein
+ if ( rOld.GetWidth() && rOld.GetHeight() )
+ {
+
+ Fraction aScaleX( rOld.GetWidth(), rNew.GetWidth() );
+ Fraction aScaleY( rOld.GetHeight(), rOld.GetHeight() );
+ aURL.GetMap()->Scale( aScaleX, aScaleY );
+ SwFrmFmt *pFmt = GetFmt();
+ pFmt->LockModify();
+ pFmt->SetFmtAttr( aURL );
+ pFmt->UnlockModify();
+ }
+ }
+ const SvxProtectItem &rP = GetFmt()->GetProtect();
+ GetVirtDrawObj()->SetMoveProtect( rP.IsPosProtected() );
+ GetVirtDrawObj()->SetResizeProtect( rP.IsSizeProtected() );
+
+ if ( pSh )
+ pSh->InvalidateWindows( Frm() );
+ const IDocumentDrawModelAccess* pIDDMA = GetFmt()->getIDocumentDrawModelAccess();
+ const sal_uInt8 nId = GetFmt()->GetOpaque().GetValue() ?
+ pIDDMA->GetHeavenId() :
+ pIDDMA->GetHellId();
+ GetVirtDrawObj()->SetLayer( nId );
+
+ if ( Lower() )
+ {
+ //Ggf. die Kontur am Node loeschen.
+ if( Lower()->IsNoTxtFrm() &&
+ !GetFmt()->GetSurround().IsContour() )
+ {
+ SwNoTxtNode *pNd = (SwNoTxtNode*)((SwCntntFrm*)Lower())->GetNode();
+ if ( pNd->HasContour() )
+ pNd->SetContour( 0 );
+ }
+ else if( !Lower()->IsColumnFrm() )
+ {
+ SwFrm* pFrm = GetLastLower();
+ if( pFrm->IsTxtFrm() && ((SwTxtFrm*)pFrm)->IsUndersized() )
+ pFrm->Prepare( PREP_ADJUST_FRM );
+ }
+ }
+
+ // --> OD 2004-06-28 #i28701# - perform reorder of object lists
+ // at anchor frame and at page frame.
+ rInvFlags |= 0x80;
+
+ break;
+ }
+ case RES_UL_SPACE:
+ case RES_LR_SPACE:
+ {
+ rInvFlags |= 0x41;
+ if( pSh && pSh->GetViewOptions()->getBrowseMode() )
+ getRootFrm()->InvalidateBrowseWidth();
+ SwRect aNew( GetObjRectWithSpaces() );
+ SwRect aOld( aFrm );
+ if ( RES_UL_SPACE == nWhich )
+ {
+ const SvxULSpaceItem &rUL = *(SvxULSpaceItem*)pNew;
+ aOld.Top( Max( aOld.Top() - long(rUL.GetUpper()), 0L ) );
+ aOld.SSize().Height()+= rUL.GetLower();
+ }
+ else
+ {
+ const SvxLRSpaceItem &rLR = *(SvxLRSpaceItem*)pNew;
+ aOld.Left ( Max( aOld.Left() - long(rLR.GetLeft()), 0L ) );
+ aOld.SSize().Width() += rLR.GetRight();
+ }
+ aNew.Union( aOld );
+ NotifyBackground( FindPageFrm(), aNew, PREP_CLEAR );
+ }
+ break;
+
+ case RES_BOX:
+ case RES_SHADOW:
+ rInvFlags |= 0x17;
+ break;
+
+ case RES_FRAMEDIR :
+ SetDerivedVert( sal_False );
+ SetDerivedR2L( sal_False );
+ CheckDirChange();
+ break;
+
+ case RES_OPAQUE:
+ {
+ if ( pSh )
+ pSh->InvalidateWindows( Frm() );
+
+ const IDocumentDrawModelAccess* pIDDMA = GetFmt()->getIDocumentDrawModelAccess();
+ const sal_uInt8 nId = ((SvxOpaqueItem*)pNew)->GetValue() ?
+ pIDDMA->GetHeavenId() :
+ pIDDMA->GetHellId();
+ GetVirtDrawObj()->SetLayer( nId );
+ if( pSh )
+ {
+ SwRootFrm* pLayout = getRootFrm();
+ if( pLayout && pLayout->IsAnyShellAccessible() )
+ {
+ pSh->Imp()->DisposeAccessibleFrm( this );
+ pSh->Imp()->AddAccessibleFrm( this );
+ }
+ }
+ // --> OD 2004-06-28 #i28701# - perform reorder of object lists
+ // at anchor frame and at page frame.
+ rInvFlags |= 0x80;
+ }
+ break;
+
+ case RES_URL:
+ //Das Interface arbeitet bei Textrahmen auf der Rahmengroesse,
+ //die Map muss sich aber auf die FrmSize beziehen
+ if ( (!Lower() || !Lower()->IsNoTxtFrm()) &&
+ ((SwFmtURL*)pNew)->GetMap() && ((SwFmtURL*)pOld)->GetMap() )
+ {
+ const SwFmtFrmSize &rSz = GetFmt()->GetFrmSize();
+ if ( rSz.GetHeight() != Frm().Height() ||
+ rSz.GetWidth() != Frm().Width() )
+ {
+ SwFmtURL aURL( GetFmt()->GetURL() );
+ Fraction aScaleX( Frm().Width(), rSz.GetWidth() );
+ Fraction aScaleY( Frm().Height(), rSz.GetHeight() );
+ aURL.GetMap()->Scale( aScaleX, aScaleY );
+ SwFrmFmt *pFmt = GetFmt();
+ pFmt->LockModify();
+ pFmt->SetFmtAttr( aURL );
+ pFmt->UnlockModify();
+ }
+ }
+ /* Keine Invalidierung notwendig */
+ break;
+
+ case RES_CHAIN:
+ {
+ SwFmtChain *pChain = (SwFmtChain*)pNew;
+ if ( pChain->GetNext() )
+ {
+ SwFlyFrm *pFollow = FindChainNeighbour( *pChain->GetNext() );
+ if ( GetNextLink() && pFollow != GetNextLink() )
+ SwFlyFrm::UnchainFrames( this, GetNextLink());
+ if ( pFollow )
+ {
+ if ( pFollow->GetPrevLink() &&
+ pFollow->GetPrevLink() != this )
+ SwFlyFrm::UnchainFrames( pFollow->GetPrevLink(),
+ pFollow );
+ if ( !GetNextLink() )
+ SwFlyFrm::ChainFrames( this, pFollow );
+ }
+ }
+ else if ( GetNextLink() )
+ SwFlyFrm::UnchainFrames( this, GetNextLink() );
+ if ( pChain->GetPrev() )
+ {
+ SwFlyFrm *pMaster = FindChainNeighbour( *pChain->GetPrev() );
+ if ( GetPrevLink() && pMaster != GetPrevLink() )
+ SwFlyFrm::UnchainFrames( GetPrevLink(), this );
+ if ( pMaster )
+ {
+ if ( pMaster->GetNextLink() &&
+ pMaster->GetNextLink() != this )
+ SwFlyFrm::UnchainFrames( pMaster,
+ pMaster->GetNextLink() );
+ if ( !GetPrevLink() )
+ SwFlyFrm::ChainFrames( pMaster, this );
+ }
+ }
+ else if ( GetPrevLink() )
+ SwFlyFrm::UnchainFrames( GetPrevLink(), this );
+ }
+
+ default:
+ bClear = sal_False;
+ }
+ if ( bClear )
+ {
+ if ( pOldSet || pNewSet )
+ {
+ if ( pOldSet )
+ pOldSet->ClearItem( nWhich );
+ if ( pNewSet )
+ pNewSet->ClearItem( nWhich );
+ }
+ else
+ SwLayoutFrm::Modify( pOld, pNew );
+ }
+}
+
+/*************************************************************************
+|*
+|* SwFlyFrm::GetInfo()
+|*
+|* Beschreibung erfragt Informationen
+|*
+*************************************************************************/
+
+ // erfrage vom Modify Informationen
+sal_Bool SwFlyFrm::GetInfo( SfxPoolItem & rInfo ) const
+{
+ if( RES_AUTOFMT_DOCNODE == rInfo.Which() )
+ return sal_False; // es gibt einen FlyFrm also wird er benutzt
+ return sal_True; // weiter suchen
+}
+
+/*************************************************************************
+|*
+|* SwFlyFrm::_Invalidate()
+|*
+|*************************************************************************/
+
+void SwFlyFrm::_Invalidate( SwPageFrm *pPage )
+{
+ InvalidatePage( pPage );
+ bNotifyBack = bInvalid = sal_True;
+
+ SwFlyFrm *pFrm;
+ if ( GetAnchorFrm() && 0 != (pFrm = AnchorFrm()->FindFlyFrm()) )
+ {
+ //Gaanz dumm: Wenn der Fly innerhalb eines Fly gebunden ist, der
+ //Spalten enthaehlt, sollte das Format von diesem ausgehen.
+ if ( !pFrm->IsLocked() && !pFrm->IsColLocked() &&
+ pFrm->Lower() && pFrm->Lower()->IsColumnFrm() )
+ pFrm->InvalidateSize();
+ }
+
+ // --> OD 2008-01-21 #i85216#
+ // if vertical position is oriented at a layout frame inside a ghost section,
+ // assure that the position is invalidated and that the information about
+ // the vertical position oriented frame is cleared
+ if ( GetVertPosOrientFrm() && GetVertPosOrientFrm()->IsLayoutFrm() )
+ {
+ const SwSectionFrm* pSectFrm( GetVertPosOrientFrm()->FindSctFrm() );
+ if ( pSectFrm && pSectFrm->GetSection() == 0 )
+ {
+ InvalidatePos();
+ ClearVertPosOrientFrm();
+ }
+ }
+ // <--
+}
+
+/*************************************************************************
+|*
+|* SwFlyFrm::ChgRelPos()
+|*
+|* Beschreibung Aenderung der relativen Position, die Position wird
+|* damit automatisch Fix, das Attribut wird entprechend angepasst.
+|*
+|*************************************************************************/
+
+void SwFlyFrm::ChgRelPos( const Point &rNewPos )
+{
+ if ( GetCurrRelPos() != rNewPos )
+ {
+ SwFrmFmt *pFmt = GetFmt();
+ const bool bVert = GetAnchorFrm()->IsVertical();
+ const SwTwips nNewY = bVert ? rNewPos.X() : rNewPos.Y();
+ SwTwips nTmpY = nNewY == LONG_MAX ? 0 : nNewY;
+ if( bVert )
+ nTmpY = -nTmpY;
+ SfxItemSet aSet( pFmt->GetDoc()->GetAttrPool(),
+ RES_VERT_ORIENT, RES_HORI_ORIENT);
+
+ SwFmtVertOrient aVert( pFmt->GetVertOrient() );
+ SwTxtFrm *pAutoFrm = NULL;
+ // --> OD 2004-11-12 #i34948# - handle also at-page and at-fly anchored
+ // Writer fly frames
+ const RndStdIds eAnchorType = GetFrmFmt().GetAnchor().GetAnchorId();
+ if ( eAnchorType == FLY_AT_PAGE )
+ {
+ aVert.SetVertOrient( text::VertOrientation::NONE );
+ aVert.SetRelationOrient( text::RelOrientation::PAGE_FRAME );
+ }
+ else if ( eAnchorType == FLY_AT_FLY )
+ {
+ aVert.SetVertOrient( text::VertOrientation::NONE );
+ aVert.SetRelationOrient( text::RelOrientation::FRAME );
+ }
+ // <--
+ else if ( IsFlyAtCntFrm() || text::VertOrientation::NONE != aVert.GetVertOrient() )
+ {
+ if( text::RelOrientation::CHAR == aVert.GetRelationOrient() && IsAutoPos() )
+ {
+ if( LONG_MAX != nNewY )
+ {
+ aVert.SetVertOrient( text::VertOrientation::NONE );
+ xub_StrLen nOfs =
+ pFmt->GetAnchor().GetCntntAnchor()->nContent.GetIndex();
+ OSL_ENSURE( GetAnchorFrm()->IsTxtFrm(), "TxtFrm expected" );
+ pAutoFrm = (SwTxtFrm*)GetAnchorFrm();
+ while( pAutoFrm->GetFollow() &&
+ pAutoFrm->GetFollow()->GetOfst() <= nOfs )
+ {
+ if( pAutoFrm == GetAnchorFrm() )
+ nTmpY += pAutoFrm->GetRelPos().Y();
+ nTmpY -= pAutoFrm->GetUpper()->Prt().Height();
+ pAutoFrm = pAutoFrm->GetFollow();
+ }
+ nTmpY = ((SwFlyAtCntFrm*)this)->GetRelCharY(pAutoFrm)-nTmpY;
+ }
+ else
+ aVert.SetVertOrient( text::VertOrientation::CHAR_BOTTOM );
+ }
+ else
+ {
+ aVert.SetVertOrient( text::VertOrientation::NONE );
+ aVert.SetRelationOrient( text::RelOrientation::FRAME );
+ }
+ }
+ aVert.SetPos( nTmpY );
+ aSet.Put( aVert );
+
+ //Fuer Flys im Cnt ist die horizontale Ausrichtung uninteressant,
+ //den sie ist stets 0.
+ if ( !IsFlyInCntFrm() )
+ {
+ const SwTwips nNewX = bVert ? rNewPos.Y() : rNewPos.X();
+ SwTwips nTmpX = nNewX == LONG_MAX ? 0 : nNewX;
+ SwFmtHoriOrient aHori( pFmt->GetHoriOrient() );
+ // --> OD 2004-11-12 #i34948# - handle also at-page and at-fly anchored
+ // Writer fly frames
+ if ( eAnchorType == FLY_AT_PAGE )
+ {
+ aHori.SetHoriOrient( text::HoriOrientation::NONE );
+ aHori.SetRelationOrient( text::RelOrientation::PAGE_FRAME );
+ aHori.SetPosToggle( sal_False );
+ }
+ else if ( eAnchorType == FLY_AT_FLY )
+ {
+ aHori.SetHoriOrient( text::HoriOrientation::NONE );
+ aHori.SetRelationOrient( text::RelOrientation::FRAME );
+ aHori.SetPosToggle( sal_False );
+ }
+ // <--
+ else if ( IsFlyAtCntFrm() || text::HoriOrientation::NONE != aHori.GetHoriOrient() )
+ {
+ aHori.SetHoriOrient( text::HoriOrientation::NONE );
+ if( text::RelOrientation::CHAR == aHori.GetRelationOrient() && IsAutoPos() )
+ {
+ if( LONG_MAX != nNewX )
+ {
+ if( !pAutoFrm )
+ {
+ xub_StrLen nOfs = pFmt->GetAnchor().GetCntntAnchor()
+ ->nContent.GetIndex();
+ OSL_ENSURE( GetAnchorFrm()->IsTxtFrm(), "TxtFrm expected");
+ pAutoFrm = (SwTxtFrm*)GetAnchorFrm();
+ while( pAutoFrm->GetFollow() &&
+ pAutoFrm->GetFollow()->GetOfst() <= nOfs )
+ pAutoFrm = pAutoFrm->GetFollow();
+ }
+ nTmpX -= ((SwFlyAtCntFrm*)this)->GetRelCharX(pAutoFrm);
+ }
+ }
+ else
+ aHori.SetRelationOrient( text::RelOrientation::FRAME );
+ aHori.SetPosToggle( sal_False );
+ }
+ aHori.SetPos( nTmpX );
+ aSet.Put( aHori );
+ }
+ SetCurrRelPos( rNewPos );
+ pFmt->GetDoc()->SetAttr( aSet, *pFmt );
+ }
+}
+/*************************************************************************
+|*
+|* SwFlyFrm::Format()
+|*
+|* Beschreibung: "Formatiert" den Frame; Frm und PrtArea.
+|* Die Fixsize wird hier nicht eingestellt.
+|*
+|*************************************************************************/
+
+void SwFlyFrm::Format( const SwBorderAttrs *pAttrs )
+{
+ OSL_ENSURE( pAttrs, "FlyFrm::Format, pAttrs ist 0." );
+
+ ColLock();
+
+ if ( !bValidSize )
+ {
+ if ( Frm().Top() == WEIT_WECH && Frm().Left() == WEIT_WECH )
+ {
+ //Sicherheitsschaltung wegnehmen (siehe SwFrm::CTor)
+ Frm().Pos().X() = Frm().Pos().Y() = 0;
+ // --> OD 2006-08-16 #i68520#
+ InvalidateObjRectWithSpaces();
+ // <--
+ }
+
+ //Breite der Spalten pruefen und ggf. einstellen.
+ if ( Lower() && Lower()->IsColumnFrm() )
+ AdjustColumns( 0, sal_False );
+
+ bValidSize = sal_True;
+
+ const SwTwips nUL = pAttrs->CalcTopLine() + pAttrs->CalcBottomLine();
+ const SwTwips nLR = pAttrs->CalcLeftLine() + pAttrs->CalcRightLine();
+ const SwFmtFrmSize &rFrmSz = GetFmt()->GetFrmSize();
+ Size aRelSize( CalcRel( rFrmSz ) );
+
+ OSL_ENSURE( pAttrs->GetSize().Height() != 0 || rFrmSz.GetHeightPercent(), "Hoehe des RahmenAttr ist 0." );
+ OSL_ENSURE( pAttrs->GetSize().Width() != 0 || rFrmSz.GetWidthPercent(), "Breite des RahmenAttr ist 0." );
+
+ SWRECTFN( this )
+ if( !HasFixSize() )
+ {
+ SwTwips nRemaining = 0;
+
+ long nMinHeight = 0;
+ if( IsMinHeight() )
+ nMinHeight = bVert ? aRelSize.Width() : aRelSize.Height();
+
+ if ( Lower() )
+ {
+ if ( Lower()->IsColumnFrm() )
+ {
+ FormatWidthCols( *pAttrs, nUL, nMinHeight );
+ nRemaining = (Lower()->Frm().*fnRect->fnGetHeight)();
+ }
+ else
+ {
+ SwFrm *pFrm = Lower();
+ while ( pFrm )
+ {
+ nRemaining += (pFrm->Frm().*fnRect->fnGetHeight)();
+ if( pFrm->IsTxtFrm() && ((SwTxtFrm*)pFrm)->IsUndersized() )
+ // Dieser TxtFrm waere gern ein bisschen groesser
+ nRemaining += ((SwTxtFrm*)pFrm)->GetParHeight()
+ - (pFrm->Prt().*fnRect->fnGetHeight)();
+ else if( pFrm->IsSctFrm() && ((SwSectionFrm*)pFrm)->IsUndersized() )
+ nRemaining += ((SwSectionFrm*)pFrm)->Undersize();
+ pFrm = pFrm->GetNext();
+ }
+ // --> OD 2006-02-09 #130878#
+ // Do not keep old height, if content has no height.
+ // The old height could be wrong due to wrong layout cache
+ // and isn't corrected in the further formatting, because
+ // the fly frame doesn't become invalid anymore.
+// if( !nRemaining )
+// nRemaining = nOldHeight - nUL;
+ // <--
+ }
+ if ( GetDrawObjs() )
+ {
+ sal_uInt32 nCnt = GetDrawObjs()->Count();
+ SwTwips nTop = (Frm().*fnRect->fnGetTop)();
+ SwTwips nBorder = (Frm().*fnRect->fnGetHeight)() -
+ (Prt().*fnRect->fnGetHeight)();
+ for ( sal_uInt16 i = 0; i < nCnt; ++i )
+ {
+ SwAnchoredObject* pAnchoredObj = (*GetDrawObjs())[i];
+ if ( pAnchoredObj->ISA(SwFlyFrm) )
+ {
+ SwFlyFrm* pFly = static_cast<SwFlyFrm*>(pAnchoredObj);
+ // OD 06.11.2003 #i22305# - consider
+ // only Writer fly frames, which follow the text flow.
+ if ( pFly->IsFlyLayFrm() &&
+ pFly->Frm().Top() != WEIT_WECH &&
+ pFly->GetFmt()->GetFollowTextFlow().GetValue() )
+ {
+ SwTwips nDist = -(pFly->Frm().*fnRect->
+ fnBottomDist)( nTop );
+ if( nDist > nBorder + nRemaining )
+ nRemaining = nDist - nBorder;
+ }
+ }
+ }
+ }
+ }
+
+ if( IsMinHeight() && (nRemaining + nUL) < nMinHeight )
+ nRemaining = nMinHeight - nUL;
+ //Weil das Grow/Shrink der Flys die Groessen nicht direkt
+ //einstellt, sondern indirekt per Invalidate ein Format
+ //ausloesst, muessen die Groessen hier direkt eingestellt
+ //werden. Benachrichtung laeuft bereits mit.
+ //Weil bereits haeufiger 0en per Attribut hereinkamen wehre
+ //ich mich ab sofort dagegen.
+ if ( nRemaining < MINFLY )
+ nRemaining = MINFLY;
+ (Prt().*fnRect->fnSetHeight)( nRemaining );
+ nRemaining -= (Frm().*fnRect->fnGetHeight)();
+ (Frm().*fnRect->fnAddBottom)( nRemaining + nUL );
+ // --> OD 2006-08-16 #i68520#
+ if ( nRemaining + nUL != 0 )
+ {
+ InvalidateObjRectWithSpaces();
+ }
+ // <--
+ bValidSize = sal_True;
+ }
+ else
+ {
+ bValidSize = sal_True; //Fixe Frms formatieren sich nicht.
+ //Flys stellen ihre Groesse anhand des Attr ein.
+ SwTwips nNewSize = bVert ? aRelSize.Width() : aRelSize.Height();
+ nNewSize -= nUL;
+ if( nNewSize < MINFLY )
+ nNewSize = MINFLY;
+ (Prt().*fnRect->fnSetHeight)( nNewSize );
+ nNewSize += nUL - (Frm().*fnRect->fnGetHeight)();
+ (Frm().*fnRect->fnAddBottom)( nNewSize );
+ // --> OD 2006-08-16 #i68520#
+ if ( nNewSize != 0 )
+ {
+ InvalidateObjRectWithSpaces();
+ }
+ // <--
+ }
+
+ if ( !bFormatHeightOnly )
+ {
+ OSL_ENSURE( aRelSize == CalcRel( rFrmSz ), "SwFlyFrm::Format CalcRel problem" );
+ SwTwips nNewSize = bVert ? aRelSize.Height() : aRelSize.Width();
+
+ if ( rFrmSz.GetWidthSizeType() != ATT_FIX_SIZE )
+ {
+ // #i9046# Autowidth for fly frames
+ const SwTwips nAutoWidth = CalcAutoWidth();
+ if ( nAutoWidth )
+ {
+ if( ATT_MIN_SIZE == rFrmSz.GetWidthSizeType() )
+ nNewSize = Max( nNewSize - nLR, nAutoWidth );
+ else
+ nNewSize = nAutoWidth;
+ }
+ }
+ else
+ nNewSize -= nLR;
+
+ if( nNewSize < MINFLY )
+ nNewSize = MINFLY;
+ (Prt().*fnRect->fnSetWidth)( nNewSize );
+ nNewSize += nLR - (Frm().*fnRect->fnGetWidth)();
+ (Frm().*fnRect->fnAddRight)( nNewSize );
+ // --> OD 2006-08-16 #i68520#
+ if ( nNewSize != 0 )
+ {
+ InvalidateObjRectWithSpaces();
+ }
+ // <--
+ }
+ }
+ ColUnlock();
+}
+
+// OD 14.03.2003 #i11760# - change parameter <bNoColl>: type <bool>;
+// default value = false.
+// OD 14.03.2003 #i11760# - add new parameter <bNoCalcFollow> with
+// default value = false.
+// OD 11.04.2003 #108824# - new parameter <bNoCalcFollow> was used by method
+// <FormatWidthCols(..)> to avoid follow formatting
+// for text frames. But, unformatted follows causes
+// problems in method <SwCntntFrm::_WouldFit(..)>,
+// which assumes that the follows are formatted.
+// Thus, <bNoCalcFollow> no longer used by <FormatWidthCols(..)>.
+//void CalcCntnt( SwLayoutFrm *pLay, sal_Bool bNoColl )
+void CalcCntnt( SwLayoutFrm *pLay,
+ bool bNoColl,
+ bool bNoCalcFollow )
+{
+ SwSectionFrm* pSect;
+ sal_Bool bCollect = sal_False;
+ if( pLay->IsSctFrm() )
+ {
+ pSect = (SwSectionFrm*)pLay;
+ if( pSect->IsEndnAtEnd() && !bNoColl )
+ {
+ bCollect = sal_True;
+ SwLayouter::CollectEndnotes( pLay->GetFmt()->GetDoc(), pSect );
+ }
+ pSect->CalcFtnCntnt();
+ }
+ else
+ pSect = NULL;
+ SwFrm *pFrm = pLay->ContainsAny();
+ if ( !pFrm )
+ {
+ if( pSect )
+ {
+ if( pSect->HasFollow() )
+ pFrm = pSect->GetFollow()->ContainsAny();
+ if( !pFrm )
+ {
+ if( pSect->IsEndnAtEnd() )
+ {
+ if( bCollect )
+ pLay->GetFmt()->GetDoc()->GetLayouter()->
+ InsertEndnotes( pSect );
+ sal_Bool bLock = pSect->IsFtnLock();
+ pSect->SetFtnLock( sal_True );
+ pSect->CalcFtnCntnt();
+ pSect->CalcFtnCntnt();
+ pSect->SetFtnLock( bLock );
+ }
+ return;
+ }
+ pFrm->_InvalidatePos();
+ }
+ else
+ return;
+ }
+ pFrm->InvalidatePage();
+
+ do
+ {
+ // local variables to avoid loops caused by anchored object positioning
+ SwAnchoredObject* pAgainObj1 = 0;
+ SwAnchoredObject* pAgainObj2 = 0;
+
+ // FME 2007-08-30 #i81146# new loop control
+ sal_uInt16 nLoopControlRuns = 0;
+ const sal_uInt16 nLoopControlMax = 20;
+ const SwFrm* pLoopControlCond = 0;
+
+ SwFrm* pLast;
+ do
+ {
+ pLast = pFrm;
+ if( pFrm->IsVertical() ?
+ ( pFrm->GetUpper()->Prt().Height() != pFrm->Frm().Height() )
+ : ( pFrm->GetUpper()->Prt().Width() != pFrm->Frm().Width() ) )
+ {
+ pFrm->Prepare( PREP_FIXSIZE_CHG );
+ pFrm->_InvalidateSize();
+ }
+
+ if ( pFrm->IsTabFrm() )
+ {
+ ((SwTabFrm*)pFrm)->bCalcLowers = sal_True;
+ // OD 26.08.2003 #i18103# - lock move backward of follow table,
+ // if no section content is formatted or follow table belongs
+ // to the section, which content is formatted.
+ if ( ((SwTabFrm*)pFrm)->IsFollow() &&
+ ( !pSect || pSect == pFrm->FindSctFrm() ) )
+ {
+ ((SwTabFrm*)pFrm)->bLockBackMove = sal_True;
+ }
+ }
+
+ // OD 14.03.2003 #i11760# - forbid format of follow, if requested.
+ if ( bNoCalcFollow && pFrm->IsTxtFrm() )
+ static_cast<SwTxtFrm*>(pFrm)->ForbidFollowFormat();
+
+ pFrm->Calc();
+
+ // OD 14.03.2003 #i11760# - reset control flag for follow format.
+ if ( pFrm->IsTxtFrm() )
+ {
+ static_cast<SwTxtFrm*>(pFrm)->AllowFollowFormat();
+ }
+
+ // #111937# The keep-attribute can cause the position
+ // of the prev to be invalid:
+ // OD 2004-03-15 #116560# - Do not consider invalid previous frame
+ // due to its keep-attribute, if current frame is a follow or is locked.
+ // --> OD 2005-03-08 #i44049# - do not consider invalid previous
+ // frame due to its keep-attribute, if it can't move forward.
+ // --> OD 2006-01-27 #i57765# - do not consider invalid previous
+ // frame, if current frame has a column/page break before attribute.
+ SwFrm* pTmpPrev = pFrm->FindPrev();
+ SwFlowFrm* pTmpPrevFlowFrm = pTmpPrev && pTmpPrev->IsFlowFrm() ? SwFlowFrm::CastFlowFrm(pTmpPrev) : 0;
+ SwFlowFrm* pTmpFlowFrm = pFrm->IsFlowFrm() ? SwFlowFrm::CastFlowFrm(pFrm) : 0;
+
+ bool bPrevInvalid = pTmpPrevFlowFrm && pTmpFlowFrm &&
+ !pTmpFlowFrm->IsFollow() &&
+ !StackHack::IsLocked() && // #i76382#
+ !pTmpFlowFrm->IsJoinLocked() &&
+ !pTmpPrev->GetValidPosFlag() &&
+ pLay->IsAnLower( pTmpPrev ) &&
+ pTmpPrevFlowFrm->IsKeep( *pTmpPrev->GetAttrSet() ) &&
+ pTmpPrevFlowFrm->IsKeepFwdMoveAllowed();
+ // <--
+
+ // format floating screen objects anchored to the frame.
+ bool bRestartLayoutProcess = false;
+ if ( !bPrevInvalid && pFrm->GetDrawObjs() && pLay->IsAnLower( pFrm ) )
+ {
+ bool bAgain = false;
+ SwPageFrm* pPageFrm = pFrm->FindPageFrm();
+ sal_uInt32 nCnt = pFrm->GetDrawObjs()->Count();
+ for ( sal_uInt16 i = 0; i < nCnt; ++i )
+ {
+ // --> OD 2004-07-01 #i28701#
+ SwAnchoredObject* pAnchoredObj = (*pFrm->GetDrawObjs())[i];
+ // determine, if anchored object has to be formatted.
+ if ( pAnchoredObj->PositionLocked() )
+ {
+ continue;
+ }
+
+ // format anchored object
+ if ( pAnchoredObj->IsFormatPossible() )
+ {
+ // --> OD 2005-05-17 #i43737# - no invalidation of
+ // anchored object needed - causes loops for as-character
+ // anchored objects.
+ //pAnchoredObj->InvalidateObjPos();
+ // <--
+ SwRect aRect( pAnchoredObj->GetObjRect() );
+ if ( !SwObjectFormatter::FormatObj( *pAnchoredObj, pFrm, pPageFrm ) )
+ {
+ bRestartLayoutProcess = true;
+ break;
+ }
+ // --> OD 2004-08-25 #i3317# - restart layout process,
+ // if the position of the anchored object is locked now.
+ if ( pAnchoredObj->PositionLocked() )
+ {
+ bRestartLayoutProcess = true;
+ break;
+ }
+ // <--
+
+ if ( aRect != pAnchoredObj->GetObjRect() )
+ {
+ bAgain = true;
+ if ( pAgainObj2 == pAnchoredObj )
+ {
+ OSL_FAIL( "::CalcCntnt(..) - loop detected, perform attribute changes to avoid the loop" );
+ //Oszillation unterbinden.
+ SwFrmFmt& rFmt = pAnchoredObj->GetFrmFmt();
+ SwFmtSurround aAttr( rFmt.GetSurround() );
+ if( SURROUND_THROUGHT != aAttr.GetSurround() )
+ {
+ // Bei autopositionierten hilft manchmal nur
+ // noch, auf Durchlauf zu schalten
+ if ((rFmt.GetAnchor().GetAnchorId() ==
+ FLY_AT_CHAR) &&
+ (SURROUND_PARALLEL ==
+ aAttr.GetSurround()))
+ {
+ aAttr.SetSurround( SURROUND_THROUGHT );
+ }
+ else
+ {
+ aAttr.SetSurround( SURROUND_PARALLEL );
+ }
+ rFmt.LockModify();
+ rFmt.SetFmtAttr( aAttr );
+ rFmt.UnlockModify();
+ }
+ }
+ else
+ {
+ if ( pAgainObj1 == pAnchoredObj )
+ pAgainObj2 = pAnchoredObj;
+ pAgainObj1 = pAnchoredObj;
+ }
+ }
+
+ if ( !pFrm->GetDrawObjs() )
+ break;
+ if ( pFrm->GetDrawObjs()->Count() < nCnt )
+ {
+ --i;
+ --nCnt;
+ }
+ }
+ }
+
+ // --> OD 2004-06-11 #i28701# - restart layout process, if
+ // requested by floating screen object formatting
+ if ( bRestartLayoutProcess )
+ {
+ pFrm = pLay->ContainsAny();
+ pAgainObj1 = 0L;
+ pAgainObj2 = 0L;
+ continue;
+ }
+
+ // OD 2004-05-17 #i28701# - format anchor frame after its objects
+ // are formatted, if the wrapping style influence has to be considered.
+ if ( pLay->GetFmt()->getIDocumentSettingAccess()->get(IDocumentSettingAccess::CONSIDER_WRAP_ON_OBJECT_POSITION) )
+ {
+ pFrm->Calc();
+ }
+ // <--
+
+ if ( bAgain )
+ {
+ pFrm = pLay->ContainsCntnt();
+ if ( pFrm && pFrm->IsInTab() )
+ pFrm = pFrm->FindTabFrm();
+ if( pFrm && pFrm->IsInSct() )
+ {
+ SwSectionFrm* pTmp = pFrm->FindSctFrm();
+ if( pTmp != pLay && pLay->IsAnLower( pTmp ) )
+ pFrm = pTmp;
+ }
+
+ if ( pFrm == pLoopControlCond )
+ ++nLoopControlRuns;
+ else
+ {
+ nLoopControlRuns = 0;
+ pLoopControlCond = pFrm;
+ }
+
+ if ( nLoopControlRuns < nLoopControlMax )
+ continue;
+
+#if OSL_DEBUG_LEVEL > 1
+ OSL_FAIL( "LoopControl in CalcCntnt" );
+#endif
+ }
+ }
+ if ( pFrm->IsTabFrm() )
+ {
+ if ( ((SwTabFrm*)pFrm)->IsFollow() )
+ ((SwTabFrm*)pFrm)->bLockBackMove = sal_False;
+ }
+
+ pFrm = bPrevInvalid ? pTmpPrev : pFrm->FindNext();
+ if( !bPrevInvalid && pFrm && pFrm->IsSctFrm() && pSect )
+ {
+ // Es koennen hier leere SectionFrms herumspuken
+ while( pFrm && pFrm->IsSctFrm() && !((SwSectionFrm*)pFrm)->GetSection() )
+ pFrm = pFrm->FindNext();
+ // Wenn FindNext den Follow des urspruenglichen Bereichs liefert,
+ // wollen wir mit dessen Inhalt weitermachen, solange dieser
+ // zurueckfliesst.
+ if( pFrm && pFrm->IsSctFrm() && ( pFrm == pSect->GetFollow() ||
+ ((SwSectionFrm*)pFrm)->IsAnFollow( pSect ) ) )
+ {
+ pFrm = ((SwSectionFrm*)pFrm)->ContainsAny();
+ if( pFrm )
+ pFrm->_InvalidatePos();
+ }
+ }
+ // Im pLay bleiben, Ausnahme, bei SectionFrms mit Follow wird der erste
+ // CntntFrm des Follows anformatiert, damit er die Chance erhaelt, in
+ // pLay zu landen. Solange diese Frames in pLay landen, geht's weiter.
+ } while ( pFrm &&
+ ( pLay->IsAnLower( pFrm ) ||
+ ( pSect &&
+ ( ( pSect->HasFollow() &&
+ ( pLay->IsAnLower( pLast ) ||
+ ( pLast->IsInSct() &&
+ pLast->FindSctFrm()->IsAnFollow(pSect) ) ) &&
+ pSect->GetFollow()->IsAnLower( pFrm ) ) ||
+ ( pFrm->IsInSct() &&
+ pFrm->FindSctFrm()->IsAnFollow( pSect ) ) ) ) ) );
+ if( pSect )
+ {
+ if( bCollect )
+ {
+ pLay->GetFmt()->GetDoc()->GetLayouter()->InsertEndnotes(pSect);
+ pSect->CalcFtnCntnt();
+ }
+ if( pSect->HasFollow() )
+ {
+ SwSectionFrm* pNxt = pSect->GetFollow();
+ while( pNxt && !pNxt->ContainsCntnt() )
+ pNxt = pNxt->GetFollow();
+ if( pNxt )
+ pNxt->CalcFtnCntnt();
+ }
+ if( bCollect )
+ {
+ pFrm = pLay->ContainsAny();
+ bCollect = sal_False;
+ if( pFrm )
+ continue;
+ }
+ }
+ break;
+ }
+ while( sal_True );
+}
+
+/*************************************************************************
+|*
+|* SwFlyFrm::MakeFlyPos()
+|*
+|*************************************************************************/
+// OD 2004-03-23 #i26791#
+//void SwFlyFrm::MakeFlyPos()
+void SwFlyFrm::MakeObjPos()
+{
+ if ( !bValidPos )
+ {
+ bValidPos = sal_True;
+
+ // OD 29.10.2003 #113049# - use new class to position object
+ GetAnchorFrm()->Calc();
+ objectpositioning::SwToLayoutAnchoredObjectPosition
+ aObjPositioning( *GetVirtDrawObj() );
+ aObjPositioning.CalcPosition();
+
+ // --> OD 2006-10-05 #i58280#
+ // update relative position
+ SetCurrRelPos( aObjPositioning.GetRelPos() );
+ // <--
+
+ SWRECTFN( GetAnchorFrm() );
+ aFrm.Pos( aObjPositioning.GetRelPos() );
+ aFrm.Pos() += (GetAnchorFrm()->Frm().*fnRect->fnGetPos)();
+ // --> OD 2006-09-11 #i69335#
+ InvalidateObjRectWithSpaces();
+ // <--
+ }
+}
+
+/*************************************************************************
+|*
+|* SwFlyFrm::MakePrtArea()
+|*
+|*************************************************************************/
+void SwFlyFrm::MakePrtArea( const SwBorderAttrs &rAttrs )
+{
+
+ if ( !bValidPrtArea )
+ {
+ bValidPrtArea = sal_True;
+
+ // OD 31.07.2003 #110978# - consider vertical layout
+ SWRECTFN( this )
+ (this->*fnRect->fnSetXMargins)( rAttrs.CalcLeftLine(),
+ rAttrs.CalcRightLine() );
+ (this->*fnRect->fnSetYMargins)( rAttrs.CalcTopLine(),
+ rAttrs.CalcBottomLine() );
+ }
+}
+
+/*************************************************************************
+|*
+|* SwFlyFrm::_Grow(), _Shrink()
+|*
+|*************************************************************************/
+
+SwTwips SwFlyFrm::_Grow( SwTwips nDist, sal_Bool bTst )
+{
+ SWRECTFN( this )
+ if ( Lower() && !IsColLocked() && !HasFixSize() )
+ {
+ SwTwips nSize = (Frm().*fnRect->fnGetHeight)();
+ if( nSize > 0 && nDist > ( LONG_MAX - nSize ) )
+ nDist = LONG_MAX - nSize;
+
+ if ( nDist <= 0L )
+ return 0L;
+
+ if ( Lower()->IsColumnFrm() )
+ { //Bei Spaltigkeit ubernimmt das Format die Kontrolle ueber
+ //das Wachstum (wg. des Ausgleichs).
+ if ( !bTst )
+ {
+ // --> OD 2004-06-09 #i28701# - unlock position of Writer fly frame
+ UnlockPosition();
+ _InvalidatePos();
+ InvalidateSize();
+ }
+ return 0L;
+ }
+
+ if ( !bTst )
+ {
+ const SwRect aOld( GetObjRectWithSpaces() );
+ _InvalidateSize();
+ const sal_Bool bOldLock = bLocked;
+ Unlock();
+ if ( IsFlyFreeFrm() )
+ {
+ // --> OD 2004-11-12 #i37068# - no format of position here
+ // and prevent move in method <CheckClip(..)>.
+ // This is needed to prevent layout loop caused by nested
+ // Writer fly frames - inner Writer fly frames format its
+ // anchor, which grows/shrinks the outer Writer fly frame.
+ // Note: position will be invalidated below.
+ bValidPos = sal_True;
+ // --> OD 2005-10-10 #i55416#
+ // Suppress format of width for autowidth frame, because the
+ // format of the width would call <SwTxtFrm::CalcFitToContent()>
+ // for the lower frame, which initiated this grow.
+ const sal_Bool bOldFormatHeightOnly = bFormatHeightOnly;
+ const SwFmtFrmSize& rFrmSz = GetFmt()->GetFrmSize();
+ if ( rFrmSz.GetWidthSizeType() != ATT_FIX_SIZE )
+ {
+ bFormatHeightOnly = sal_True;
+ }
+ // <--
+ static_cast<SwFlyFreeFrm*>(this)->SetNoMoveOnCheckClip( true );
+ ((SwFlyFreeFrm*)this)->SwFlyFreeFrm::MakeAll();
+ static_cast<SwFlyFreeFrm*>(this)->SetNoMoveOnCheckClip( false );
+ // --> OD 2005-10-10 #i55416#
+ if ( rFrmSz.GetWidthSizeType() != ATT_FIX_SIZE )
+ {
+ bFormatHeightOnly = bOldFormatHeightOnly;
+ }
+ // <--
+ // <--
+ }
+ else
+ MakeAll();
+ _InvalidateSize();
+ InvalidatePos();
+ if ( bOldLock )
+ Lock();
+ const SwRect aNew( GetObjRectWithSpaces() );
+ if ( aOld != aNew )
+ ::Notify( this, FindPageFrm(), aOld );
+ return (aNew.*fnRect->fnGetHeight)()-(aOld.*fnRect->fnGetHeight)();
+ }
+ return nDist;
+ }
+ return 0L;
+}
+
+SwTwips SwFlyFrm::_Shrink( SwTwips nDist, sal_Bool bTst )
+{
+ if( Lower() && !IsColLocked() && !HasFixSize() && !IsNoShrink() )
+ {
+ SWRECTFN( this )
+ SwTwips nHeight = (Frm().*fnRect->fnGetHeight)();
+ if ( nDist > nHeight )
+ nDist = nHeight;
+
+ SwTwips nVal = nDist;
+ if ( IsMinHeight() )
+ {
+ const SwFmtFrmSize& rFmtSize = GetFmt()->GetFrmSize();
+ SwTwips nFmtHeight = bVert ? rFmtSize.GetWidth() : rFmtSize.GetHeight();
+
+ nVal = Min( nDist, nHeight - nFmtHeight );
+ }
+
+ if ( nVal <= 0L )
+ return 0L;
+
+ if ( Lower()->IsColumnFrm() )
+ { //Bei Spaltigkeit ubernimmt das Format die Kontrolle ueber
+ //das Wachstum (wg. des Ausgleichs).
+ if ( !bTst )
+ {
+ SwRect aOld( GetObjRectWithSpaces() );
+ (Frm().*fnRect->fnSetHeight)( nHeight - nVal );
+ // --> OD 2006-08-16 #i68520#
+ if ( nHeight - nVal != 0 )
+ {
+ InvalidateObjRectWithSpaces();
+ }
+ // <--
+ nHeight = (Prt().*fnRect->fnGetHeight)();
+ (Prt().*fnRect->fnSetHeight)( nHeight - nVal );
+ _InvalidatePos();
+ InvalidateSize();
+ ::Notify( this, FindPageFrm(), aOld );
+ NotifyDrawObj();
+ if ( GetAnchorFrm()->IsInFly() )
+ AnchorFrm()->FindFlyFrm()->Shrink( nDist, bTst );
+ }
+ return 0L;
+ }
+
+ if ( !bTst )
+ {
+ const SwRect aOld( GetObjRectWithSpaces() );
+ _InvalidateSize();
+ const sal_Bool bOldLocked = bLocked;
+ Unlock();
+ if ( IsFlyFreeFrm() )
+ {
+ // --> OD 2004-11-12 #i37068# - no format of position here
+ // and prevent move in method <CheckClip(..)>.
+ // This is needed to prevent layout loop caused by nested
+ // Writer fly frames - inner Writer fly frames format its
+ // anchor, which grows/shrinks the outer Writer fly frame.
+ // Note: position will be invalidated below.
+ bValidPos = sal_True;
+ // --> OD 2005-10-10 #i55416#
+ // Suppress format of width for autowidth frame, because the
+ // format of the width would call <SwTxtFrm::CalcFitToContent()>
+ // for the lower frame, which initiated this shrink.
+ const sal_Bool bOldFormatHeightOnly = bFormatHeightOnly;
+ const SwFmtFrmSize& rFrmSz = GetFmt()->GetFrmSize();
+ if ( rFrmSz.GetWidthSizeType() != ATT_FIX_SIZE )
+ {
+ bFormatHeightOnly = sal_True;
+ }
+ // <--
+ static_cast<SwFlyFreeFrm*>(this)->SetNoMoveOnCheckClip( true );
+ ((SwFlyFreeFrm*)this)->SwFlyFreeFrm::MakeAll();
+ static_cast<SwFlyFreeFrm*>(this)->SetNoMoveOnCheckClip( false );
+ // --> OD 2005-10-10 #i55416#
+ if ( rFrmSz.GetWidthSizeType() != ATT_FIX_SIZE )
+ {
+ bFormatHeightOnly = bOldFormatHeightOnly;
+ }
+ // <--
+ // <--
+ }
+ else
+ MakeAll();
+ _InvalidateSize();
+ InvalidatePos();
+ if ( bOldLocked )
+ Lock();
+ const SwRect aNew( GetObjRectWithSpaces() );
+ if ( aOld != aNew )
+ {
+ ::Notify( this, FindPageFrm(), aOld );
+ if ( GetAnchorFrm()->IsInFly() )
+ AnchorFrm()->FindFlyFrm()->Shrink( nDist, bTst );
+ }
+ return (aOld.*fnRect->fnGetHeight)() -
+ (aNew.*fnRect->fnGetHeight)();
+ }
+ return nVal;
+ }
+ return 0L;
+}
+
+/*************************************************************************
+|*
+|* SwFlyFrm::ChgSize()
+|*
+|*************************************************************************/
+
+Size SwFlyFrm::ChgSize( const Size& aNewSize )
+{
+ // --> OD 2006-01-19 #i53298#
+ // If the fly frame anchored at-paragraph or at-character contains an OLE
+ // object, assure that the new size fits into the current clipping area
+ // of the fly frame
+ Size aAdjustedNewSize( aNewSize );
+ {
+ if ( dynamic_cast<SwFlyAtCntFrm*>(this) &&
+ Lower() && dynamic_cast<SwNoTxtFrm*>(Lower()) &&
+ static_cast<SwNoTxtFrm*>(Lower())->GetNode()->GetOLENode() )
+ {
+ SwRect aClipRect;
+ ::CalcClipRect( GetVirtDrawObj(), aClipRect, sal_False );
+ if ( aAdjustedNewSize.Width() > aClipRect.Width() )
+ {
+ aAdjustedNewSize.setWidth( aClipRect.Width() );
+ }
+ if ( aAdjustedNewSize.Height() > aClipRect.Height() )
+ {
+ aAdjustedNewSize.setWidth( aClipRect.Height() );
+ }
+ }
+ }
+ // <--
+ if ( aAdjustedNewSize != Frm().SSize() )
+ {
+ SwFrmFmt *pFmt = GetFmt();
+ SwFmtFrmSize aSz( pFmt->GetFrmSize() );
+ aSz.SetWidth( aAdjustedNewSize.Width() );
+ // --> OD 2006-01-19 #i53298# - no tolerance any more.
+ // If it reveals that the tolerance is still needed, then suppress a
+ // <SetAttr> call, if <aSz> equals the current <SwFmtFrmSize> attribute.
+// if ( Abs(aAdjustedNewSize.Height() - aSz.GetHeight()) > 1 )
+ aSz.SetHeight( aAdjustedNewSize.Height() );
+ // <--
+ // uebers Doc fuers Undo!
+ pFmt->GetDoc()->SetAttr( aSz, *pFmt );
+ return aSz.GetSize();
+ }
+ else
+ return Frm().SSize();
+}
+
+/*************************************************************************
+|*
+|* SwFlyFrm::IsLowerOf()
+|*
+|*************************************************************************/
+
+sal_Bool SwFlyFrm::IsLowerOf( const SwLayoutFrm* pUpperFrm ) const
+{
+ OSL_ENSURE( GetAnchorFrm(), "8-( Fly is lost in Space." );
+ const SwFrm* pFrm = GetAnchorFrm();
+ do
+ {
+ if ( pFrm == pUpperFrm )
+ return sal_True;
+ pFrm = pFrm->IsFlyFrm()
+ ? ((const SwFlyFrm*)pFrm)->GetAnchorFrm()
+ : pFrm->GetUpper();
+ } while ( pFrm );
+ return sal_False;
+}
+
+/*************************************************************************
+|*
+|* SwFlyFrm::Cut()
+|*
+|*************************************************************************/
+
+void SwFlyFrm::Cut()
+{
+}
+
+/*************************************************************************
+|*
+|* SwFrm::AppendFly(), RemoveFly()
+|*
+|*************************************************************************/
+
+void SwFrm::AppendFly( SwFlyFrm *pNew )
+{
+ if ( !pDrawObjs )
+ pDrawObjs = new SwSortedObjs();
+ pDrawObjs->Insert( *pNew );
+ pNew->ChgAnchorFrm( this );
+
+ //Bei der Seite anmelden; kann sein, dass noch keine da ist - die
+ //Anmeldung wird dann in SwPageFrm::PreparePage durch gefuehrt.
+ SwPageFrm *pPage = FindPageFrm();
+ if ( pPage )
+ {
+ if ( pNew->IsFlyAtCntFrm() && pNew->Frm().Top() == WEIT_WECH )
+ {
+ //Versuch die Seitenformatierung von neuen Dokumenten etwas
+ //guenstiger zu gestalten.
+ //Wir haengen die Flys erstenmal nach hinten damit sie bei heftigem
+ //Fluss der Anker nicht unoetig oft formatiert werden.
+ //Damit man noch brauchbar an das Ende des Dokumentes springen
+ //kann werden die Flys nicht ganz an das Ende gehaengt.
+ SwRootFrm *pRoot = (SwRootFrm*)pPage->GetUpper();
+ if( !SwLayHelper::CheckPageFlyCache( pPage, pNew ) )
+ {
+ SwPageFrm *pTmp = pRoot->GetLastPage();
+ if ( pTmp->GetPhyPageNum() > 30 )
+ {
+ for ( sal_uInt16 i = 0; i < 10; ++i )
+ {
+ pTmp = (SwPageFrm*)pTmp->GetPrev();
+ if( pTmp->GetPhyPageNum() <= pPage->GetPhyPageNum() )
+ break; // damit wir nicht vor unserem Anker landen
+ }
+ if ( pTmp->IsEmptyPage() )
+ pTmp = (SwPageFrm*)pTmp->GetPrev();
+ pPage = pTmp;
+ }
+ }
+ pPage->AppendFlyToPage( pNew );
+ }
+ else
+ pPage->AppendFlyToPage( pNew );
+ }
+}
+
+void SwFrm::RemoveFly( SwFlyFrm *pToRemove )
+{
+ //Bei der Seite Abmelden - kann schon passiert sein weil die Seite
+ //bereits destruiert wurde.
+ SwPageFrm *pPage = pToRemove->FindPageFrm();
+ if ( pPage && pPage->GetSortedObjs() )
+ {
+ pPage->RemoveFlyFromPage( pToRemove );
+ }
+ // --> OD 2008-05-19 #i73201#
+ else
+ {
+ if ( pToRemove->IsAccessibleFrm() &&
+ pToRemove->GetFmt() &&
+ !pToRemove->IsFlyInCntFrm() )
+ {
+ SwRootFrm *pRootFrm = getRootFrm();
+ if( pRootFrm && pRootFrm->IsAnyShellAccessible() )
+ {
+ ViewShell *pVSh = pRootFrm->GetCurrShell();
+ if( pVSh && pVSh->Imp() )
+ {
+ pVSh->Imp()->DisposeAccessibleFrm( pToRemove );
+ }
+ }
+ }
+ }
+ // <--
+
+ pDrawObjs->Remove( *pToRemove );
+ if ( !pDrawObjs->Count() )
+ DELETEZ( pDrawObjs );
+
+ pToRemove->ChgAnchorFrm( 0 );
+
+ if ( !pToRemove->IsFlyInCntFrm() && GetUpper() && IsInTab() )//MA_FLY_HEIGHT
+ GetUpper()->InvalidateSize();
+}
+
+/*************************************************************************
+|*
+|* SwFrm::AppendDrawObj(), RemoveDrawObj()
+|*
+|* --> OD 2004-07-06 #i28701# - new methods
+|*
+|*************************************************************************/
+void SwFrm::AppendDrawObj( SwAnchoredObject& _rNewObj )
+{
+ if ( !_rNewObj.ISA(SwAnchoredDrawObject) )
+ {
+ OSL_FAIL( "SwFrm::AppendDrawObj(..) - anchored object of unexcepted type -> object not appended" );
+ return;
+ }
+
+ if ( !_rNewObj.GetDrawObj()->ISA(SwDrawVirtObj) &&
+ _rNewObj.GetAnchorFrm() && _rNewObj.GetAnchorFrm() != this )
+ {
+ // perform disconnect from layout, if 'master' drawing object is appended
+ // to a new frame.
+ static_cast<SwDrawContact*>(::GetUserCall( _rNewObj.GetDrawObj() ))->
+ DisconnectFromLayout( false );
+ }
+
+ if ( _rNewObj.GetAnchorFrm() != this )
+ {
+ if ( !pDrawObjs )
+ pDrawObjs = new SwSortedObjs();
+ pDrawObjs->Insert( _rNewObj );
+ _rNewObj.ChgAnchorFrm( this );
+ }
+
+ // --> OD 2010-09-14 #i113730#
+ // Assure the control objects and group objects containing controls are on the control layer
+ if ( ::CheckControlLayer( _rNewObj.DrawObj() ) )
+ {
+ const IDocumentDrawModelAccess* pIDDMA = getIDocumentDrawModelAccess();
+ const SdrLayerID aCurrentLayer(_rNewObj.DrawObj()->GetLayer());
+ const SdrLayerID aControlLayerID(pIDDMA->GetControlsId());
+ const SdrLayerID aInvisibleControlLayerID(pIDDMA->GetInvisibleControlsId());
+
+ if(aCurrentLayer != aControlLayerID && aCurrentLayer != aInvisibleControlLayerID)
+ {
+ if ( aCurrentLayer == pIDDMA->GetInvisibleHellId() ||
+ aCurrentLayer == pIDDMA->GetInvisibleHeavenId() )
+ {
+ _rNewObj.DrawObj()->SetLayer(aInvisibleControlLayerID);
+ }
+ else
+ {
+ _rNewObj.DrawObj()->SetLayer(aControlLayerID);
+ }
+ }
+ }
+ // <--
+
+ // no direct positioning needed, but invalidate the drawing object position
+ _rNewObj.InvalidateObjPos();
+
+ // register at page frame
+ SwPageFrm* pPage = FindPageFrm();
+ if ( pPage )
+ {
+ pPage->AppendDrawObjToPage( _rNewObj );
+ }
+
+ // Notify accessible layout.
+ ViewShell* pSh = getRootFrm()->GetCurrShell();
+ if( pSh )
+ {
+ SwRootFrm* pLayout = getRootFrm();
+ if( pLayout && pLayout->IsAnyShellAccessible() )
+ pSh->Imp()->AddAccessibleObj( _rNewObj.GetDrawObj() );
+ }
+}
+
+void SwFrm::RemoveDrawObj( SwAnchoredObject& _rToRemoveObj )
+{
+ // Notify accessible layout.
+ ViewShell* pSh = getRootFrm()->GetCurrShell();
+ if( pSh )
+ {
+ SwRootFrm* pLayout = getRootFrm();
+ if( pLayout && pLayout->IsAnyShellAccessible() )
+ pSh->Imp()->DisposeAccessibleObj( _rToRemoveObj.GetDrawObj() );
+ }
+
+ // deregister from page frame
+ SwPageFrm* pPage = _rToRemoveObj.GetPageFrm();
+ if ( pPage && pPage->GetSortedObjs() )
+ pPage->RemoveDrawObjFromPage( _rToRemoveObj );
+
+ pDrawObjs->Remove( _rToRemoveObj );
+ if ( !pDrawObjs->Count() )
+ DELETEZ( pDrawObjs );
+
+ _rToRemoveObj.ChgAnchorFrm( 0 );
+}
+
+/*************************************************************************
+|*
+|* SwFrm::InvalidateObjs()
+|*
+|*************************************************************************/
+// --> OD 2004-07-01 #i28701# - change purpose of method and adjust its name
+void SwFrm::InvalidateObjs( const bool _bInvaPosOnly,
+ const bool _bNoInvaOfAsCharAnchoredObjs )
+{
+ if ( GetDrawObjs() )
+ {
+ // --> OD 2004-10-08 #i26945# - determine page the frame is on,
+ // in order to check, if anchored object is registered at the same
+ // page.
+ const SwPageFrm* pPageFrm = FindPageFrm();
+ // <--
+ // --> OD 2004-07-01 #i28701# - re-factoring
+ sal_uInt32 i = 0;
+ for ( ; i < GetDrawObjs()->Count(); ++i )
+ {
+ SwAnchoredObject* pAnchoredObj = (*GetDrawObjs())[i];
+ if ( _bNoInvaOfAsCharAnchoredObjs &&
+ (pAnchoredObj->GetFrmFmt().GetAnchor().GetAnchorId()
+ == FLY_AS_CHAR) )
+ {
+ continue;
+ }
+ // --> OD 2004-10-08 #i26945# - no invalidation, if anchored object
+ // isn't registered at the same page and instead is registered at
+ // the page, where its anchor character text frame is on.
+ if ( pAnchoredObj->GetPageFrm() &&
+ pAnchoredObj->GetPageFrm() != pPageFrm )
+ {
+ SwTxtFrm* pAnchorCharFrm = pAnchoredObj->FindAnchorCharFrm();
+ if ( pAnchorCharFrm &&
+ pAnchoredObj->GetPageFrm() == pAnchorCharFrm->FindPageFrm() )
+ {
+ continue;
+ }
+ // --> OD 2004-11-24 #115759# - unlock its position, if anchored
+ // object isn't registered at the page, where its anchor
+ // character text frame is on, respectively if it has no
+ // anchor character text frame.
+ else
+ {
+ pAnchoredObj->UnlockPosition();
+ }
+ // <--
+ }
+ // <--
+ // --> OD 2005-07-18 #i51474# - reset flag, that anchored object
+ // has cleared environment, and unlock its position, if the anchored
+ // object is registered at the same page as the anchor frame is on.
+ if ( pAnchoredObj->ClearedEnvironment() &&
+ pAnchoredObj->GetPageFrm() &&
+ pAnchoredObj->GetPageFrm() == pPageFrm )
+ {
+ pAnchoredObj->UnlockPosition();
+ pAnchoredObj->SetClearedEnvironment( false );
+ }
+ // <--
+ // distinguish between writer fly frames and drawing objects
+ if ( pAnchoredObj->ISA(SwFlyFrm) )
+ {
+ SwFlyFrm* pFly = static_cast<SwFlyFrm*>(pAnchoredObj);
+ pFly->_Invalidate();
+ pFly->_InvalidatePos();
+ if ( !_bInvaPosOnly )
+ pFly->_InvalidateSize();
+ }
+ else
+ {
+ pAnchoredObj->InvalidateObjPos();
+ } // end of distinction between writer fly frames and drawing objects
+
+ } // end of loop on objects, which are connected to the frame
+ }
+}
+
+/*************************************************************************
+|*
+|* SwLayoutFrm::NotifyLowerObjs()
+|*
+|*************************************************************************/
+// --> OD 2004-07-01 #i28701# - change purpose of method and its name
+// --> OD 2004-10-08 #i26945# - correct check, if anchored object is a lower
+// of the layout frame. E.g., anchor character text frame can be a follow text
+// frame.
+// --> OD 2005-03-11 #i44016# - add parameter <_bUnlockPosOfObjs> to
+// force an unlockposition call for the lower objects.
+void SwLayoutFrm::NotifyLowerObjs( const bool _bUnlockPosOfObjs )
+{
+ // invalidate lower floating screen objects
+ SwPageFrm* pPageFrm = FindPageFrm();
+ if ( pPageFrm && pPageFrm->GetSortedObjs() )
+ {
+ SwSortedObjs& rObjs = *(pPageFrm->GetSortedObjs());
+ for ( sal_uInt32 i = 0; i < rObjs.Count(); ++i )
+ {
+ SwAnchoredObject* pObj = rObjs[i];
+ // --> OD 2004-10-08 #i26945# - check, if anchored object is a lower
+ // of the layout frame is changed to check, if its anchor frame
+ // is a lower of the layout frame.
+ // determine the anchor frame - usually it's the anchor frame,
+ // for at-character/as-character anchored objects the anchor character
+ // text frame is taken.
+ const SwFrm* pAnchorFrm = pObj->GetAnchorFrmContainingAnchPos();
+ // <--
+ if ( pObj->ISA(SwFlyFrm) )
+ {
+ SwFlyFrm* pFly = static_cast<SwFlyFrm*>(pObj);
+
+ if ( pFly->Frm().Left() == WEIT_WECH )
+ continue;
+
+ if ( pFly->IsAnLower( this ) )
+ continue;
+
+ // --> OD 2004-10-08 #i26945# - use <pAnchorFrm> to check, if
+ // fly frame is lower of layout frame resp. if fly frame is
+ // at a different page registered as its anchor frame is on.
+ const bool bLow = IsAnLower( pAnchorFrm );
+ if ( bLow || pAnchorFrm->FindPageFrm() != pPageFrm )
+ // <--
+ {
+ pFly->_Invalidate( pPageFrm );
+ if ( !bLow || pFly->IsFlyAtCntFrm() )
+ {
+ // --> OD 2005-03-11 #i44016#
+ if ( _bUnlockPosOfObjs )
+ {
+ pFly->UnlockPosition();
+ }
+ // <--
+ pFly->_InvalidatePos();
+ }
+ else
+ pFly->_InvalidatePrt();
+ }
+ }
+ else
+ {
+ OSL_ENSURE( pObj->ISA(SwAnchoredDrawObject),
+ "<SwLayoutFrm::NotifyFlys() - anchored object of unexcepted type" );
+ // --> OD 2004-10-08 #i26945# - use <pAnchorFrm> to check, if
+ // fly frame is lower of layout frame resp. if fly frame is
+ // at a different page registered as its anchor frame is on.
+ if ( IsAnLower( pAnchorFrm ) ||
+ pAnchorFrm->FindPageFrm() != pPageFrm )
+ // <--
+ {
+ // --> OD 2005-03-11 #i44016#
+ if ( _bUnlockPosOfObjs )
+ {
+ pObj->UnlockPosition();
+ }
+ // <--
+ pObj->InvalidateObjPos();
+ }
+ }
+ }
+ }
+}
+
+/*************************************************************************
+|*
+|* SwFlyFrm::NotifyDrawObj()
+|*
+|*************************************************************************/
+
+void SwFlyFrm::NotifyDrawObj()
+{
+ SwVirtFlyDrawObj* pObj = GetVirtDrawObj();
+ pObj->SetRect();
+ pObj->SetRectsDirty();
+ pObj->SetChanged();
+ pObj->BroadcastObjectChange();
+ if ( GetFmt()->GetSurround().IsContour() )
+ ClrContourCache( pObj );
+}
+
+/*************************************************************************
+|*
+|* SwFlyFrm::CalcRel()
+|*
+|*************************************************************************/
+
+Size SwFlyFrm::CalcRel( const SwFmtFrmSize &rSz ) const
+{
+ Size aRet( rSz.GetSize() );
+
+ const SwFrm *pRel = IsFlyLayFrm() ? GetAnchorFrm() : GetAnchorFrm()->GetUpper();
+ if( pRel ) // LAYER_IMPL
+ {
+ long nRelWidth = LONG_MAX, nRelHeight = LONG_MAX;
+ const ViewShell *pSh = getRootFrm()->GetCurrShell();
+ if ( ( pRel->IsBodyFrm() || pRel->IsPageFrm() ) &&
+ pSh && pSh->GetViewOptions()->getBrowseMode() &&
+ pSh->VisArea().HasArea() )
+ {
+ nRelWidth = pSh->GetBrowseWidth();
+ nRelHeight = pSh->VisArea().Height();
+ Size aBorder = pSh->GetOut()->PixelToLogic( pSh->GetBrowseBorder() );
+ long nDiff = nRelWidth - pRel->Prt().Width();
+ if ( nDiff > 0 )
+ nRelWidth -= nDiff;
+ nRelHeight -= 2*aBorder.Height();
+ nDiff = nRelHeight - pRel->Prt().Height();
+ if ( nDiff > 0 )
+ nRelHeight -= nDiff;
+ }
+ nRelWidth = Min( nRelWidth, pRel->Prt().Width() );
+ nRelHeight = Min( nRelHeight, pRel->Prt().Height() );
+ if( !pRel->IsPageFrm() )
+ {
+ const SwPageFrm* pPage = FindPageFrm();
+ if( pPage )
+ {
+ nRelWidth = Min( nRelWidth, pPage->Prt().Width() );
+ nRelHeight = Min( nRelHeight, pPage->Prt().Height() );
+ }
+ }
+
+ if ( rSz.GetWidthPercent() && rSz.GetWidthPercent() != 0xFF )
+ aRet.Width() = nRelWidth * rSz.GetWidthPercent() / 100;
+ if ( rSz.GetHeightPercent() && rSz.GetHeightPercent() != 0xFF )
+ aRet.Height() = nRelHeight * rSz.GetHeightPercent() / 100;
+
+ if ( rSz.GetWidthPercent() == 0xFF )
+ {
+ aRet.Width() *= aRet.Height();
+ aRet.Width() /= rSz.GetHeight();
+ }
+ else if ( rSz.GetHeightPercent() == 0xFF )
+ {
+ aRet.Height() *= aRet.Width();
+ aRet.Height() /= rSz.GetWidth();
+ }
+ }
+ return aRet;
+}
+
+/*************************************************************************
+|*
+|* SwFlyFrm::CalcAutoWidth()
+|*
+|*************************************************************************/
+
+SwTwips lcl_CalcAutoWidth( const SwLayoutFrm& rFrm )
+{
+ SwTwips nRet = 0;
+ SwTwips nMin = 0;
+ const SwFrm* pFrm = rFrm.Lower();
+
+ // No autowidth defined for columned frames
+ if ( !pFrm || pFrm->IsColumnFrm() )
+ return nRet;
+
+ while ( pFrm )
+ {
+ if ( pFrm->IsSctFrm() )
+ {
+ nMin = lcl_CalcAutoWidth( *(SwSectionFrm*)pFrm );
+ }
+ if ( pFrm->IsTxtFrm() )
+ {
+ nMin = ((SwTxtFrm*)pFrm)->CalcFitToContent();
+ const SvxLRSpaceItem &rSpace =
+ ((SwTxtFrm*)pFrm)->GetTxtNode()->GetSwAttrSet().GetLRSpace();
+ nMin += rSpace.GetRight() + rSpace.GetTxtLeft() + rSpace.GetTxtFirstLineOfst();
+ }
+ else if ( pFrm->IsTabFrm() )
+ {
+ const SwFmtFrmSize& rTblFmtSz = ((SwTabFrm*)pFrm)->GetTable()->GetFrmFmt()->GetFrmSize();
+ if ( USHRT_MAX == rTblFmtSz.GetSize().Width() ||
+ text::HoriOrientation::NONE == ((SwTabFrm*)pFrm)->GetFmt()->GetHoriOrient().GetHoriOrient() )
+ {
+ const SwPageFrm* pPage = rFrm.FindPageFrm();
+ // auto width table
+ nMin = pFrm->GetUpper()->IsVertical() ?
+ pPage->Prt().Height() :
+ pPage->Prt().Width();
+ }
+ else
+ {
+ nMin = rTblFmtSz.GetSize().Width();
+ }
+ }
+
+ if ( nMin > nRet )
+ nRet = nMin;
+
+ pFrm = pFrm->GetNext();
+ }
+
+ return nRet;
+}
+
+SwTwips SwFlyFrm::CalcAutoWidth() const
+{
+ return lcl_CalcAutoWidth( *this );
+}
+
+/*************************************************************************
+|*
+|* SwFlyFrm::GetContour()
+|*
+|*************************************************************************/
+/// OD 16.04.2003 #i13147# - If called for paint and the <SwNoTxtFrm> contains
+/// a graphic, load of intrinsic graphic has to be avoided.
+sal_Bool SwFlyFrm::GetContour( PolyPolygon& rContour,
+ const sal_Bool _bForPaint ) const
+{
+ sal_Bool bRet = sal_False;
+ if( GetFmt()->GetSurround().IsContour() && Lower() &&
+ Lower()->IsNoTxtFrm() )
+ {
+ SwNoTxtNode *pNd = (SwNoTxtNode*)((SwCntntFrm*)Lower())->GetNode();
+ // OD 16.04.2003 #i13147# - determine <GraphicObject> instead of <Graphic>
+ // in order to avoid load of graphic, if <SwNoTxtNode> contains a graphic
+ // node and method is called for paint.
+ const GraphicObject* pGrfObj = NULL;
+ sal_Bool bGrfObjCreated = sal_False;
+ const SwGrfNode* pGrfNd = pNd->GetGrfNode();
+ if ( pGrfNd && _bForPaint )
+ {
+ pGrfObj = &(pGrfNd->GetGrfObj());
+ }
+ else
+ {
+ pGrfObj = new GraphicObject( pNd->GetGraphic() );
+ bGrfObjCreated = sal_True;
+ }
+ OSL_ENSURE( pGrfObj, "SwFlyFrm::GetContour() - No Graphic/GraphicObject found at <SwNoTxtNode>." );
+ if ( pGrfObj && pGrfObj->GetType() != GRAPHIC_NONE )
+ {
+ if( !pNd->HasContour() )
+ {
+ // OD 16.04.2003 #i13147# - no <CreateContour> for a graphic
+ // during paint. Thus, return (value of <bRet> should be <sal_False>).
+ if ( pGrfNd && _bForPaint )
+ {
+ OSL_FAIL( "SwFlyFrm::GetContour() - No Contour found at <SwNoTxtNode> during paint." );
+ return bRet;
+ }
+ pNd->CreateContour();
+ }
+ pNd->GetContour( rContour );
+ //Der Node haelt das Polygon passend zur Originalgroesse der Grafik
+ //hier muss die Skalierung einkalkuliert werden.
+ SwRect aClip;
+ SwRect aOrig;
+ Lower()->Calc();
+ ((SwNoTxtFrm*)Lower())->GetGrfArea( aClip, &aOrig, sal_False );
+ // OD 16.04.2003 #i13147# - copy method code <SvxContourDlg::ScaleContour(..)>
+ // in order to avoid that graphic has to be loaded for contour scale.
+ //SvxContourDlg::ScaleContour( rContour, aGrf, MAP_TWIP, aOrig.SSize() );
+ {
+ OutputDevice* pOutDev = Application::GetDefaultDevice();
+ const MapMode aDispMap( MAP_TWIP );
+ const MapMode aGrfMap( pGrfObj->GetPrefMapMode() );
+ const Size aGrfSize( pGrfObj->GetPrefSize() );
+ Size aOrgSize;
+ Point aNewPoint;
+ sal_Bool bPixelMap = aGrfMap.GetMapUnit() == MAP_PIXEL;
+
+ if ( bPixelMap )
+ aOrgSize = pOutDev->PixelToLogic( aGrfSize, aDispMap );
+ else
+ aOrgSize = pOutDev->LogicToLogic( aGrfSize, aGrfMap, aDispMap );
+
+ if ( aOrgSize.Width() && aOrgSize.Height() )
+ {
+ double fScaleX = (double) aOrig.Width() / aOrgSize.Width();
+ double fScaleY = (double) aOrig.Height() / aOrgSize.Height();
+
+ for ( sal_uInt16 j = 0, nPolyCount = rContour.Count(); j < nPolyCount; j++ )
+ {
+ Polygon& rPoly = rContour[ j ];
+
+ for ( sal_uInt16 i = 0, nCount = rPoly.GetSize(); i < nCount; i++ )
+ {
+ if ( bPixelMap )
+ aNewPoint = pOutDev->PixelToLogic( rPoly[ i ], aDispMap );
+ else
+ aNewPoint = pOutDev->LogicToLogic( rPoly[ i ], aGrfMap, aDispMap );
+
+ rPoly[ i ] = Point( FRound( aNewPoint.X() * fScaleX ), FRound( aNewPoint.Y() * fScaleY ) );
+ }
+ }
+ }
+ }
+ // OD 17.04.2003 #i13147# - destroy created <GraphicObject>.
+ if ( bGrfObjCreated )
+ {
+ delete pGrfObj;
+ }
+ rContour.Move( aOrig.Left(), aOrig.Top() );
+ if( !aClip.Width() )
+ aClip.Width( 1 );
+ if( !aClip.Height() )
+ aClip.Height( 1 );
+ rContour.Clip( aClip.SVRect() );
+ rContour.Optimize(POLY_OPTIMIZE_CLOSE);
+ bRet = sal_True;
+ }
+ }
+ return bRet;
+}
+
+// OD 2004-03-25 #i26791#
+const SwVirtFlyDrawObj* SwFlyFrm::GetVirtDrawObj() const
+{
+ return static_cast<const SwVirtFlyDrawObj*>(GetDrawObj());
+}
+SwVirtFlyDrawObj* SwFlyFrm::GetVirtDrawObj()
+{
+ return static_cast<SwVirtFlyDrawObj*>(DrawObj());
+}
+
+// =============================================================================
+// OD 2004-03-24 #i26791# - implementation of pure virtual method declared in
+// base class <SwAnchoredObject>
+// =============================================================================
+void SwFlyFrm::InvalidateObjPos()
+{
+ InvalidatePos();
+ // --> OD 2006-08-10 #i68520#
+ InvalidateObjRectWithSpaces();
+ // <--
+}
+
+SwFrmFmt& SwFlyFrm::GetFrmFmt()
+{
+ OSL_ENSURE( GetFmt(),
+ "<SwFlyFrm::GetFrmFmt()> - missing frame format -> crash." );
+ return *GetFmt();
+}
+const SwFrmFmt& SwFlyFrm::GetFrmFmt() const
+{
+ OSL_ENSURE( GetFmt(),
+ "<SwFlyFrm::GetFrmFmt()> - missing frame format -> crash." );
+ return *GetFmt();
+}
+
+const SwRect SwFlyFrm::GetObjRect() const
+{
+ return Frm();
+}
+
+// --> OD 2006-10-05 #i70122#
+// for Writer fly frames the bounding rectangle equals the object rectangles
+const SwRect SwFlyFrm::GetObjBoundRect() const
+{
+ return GetObjRect();
+}
+// <--
+
+// --> OD 2006-08-10 #i68520#
+bool SwFlyFrm::_SetObjTop( const SwTwips _nTop )
+{
+ const bool bChanged( Frm().Pos().Y() != _nTop );
+
+ Frm().Pos().Y() = _nTop;
+
+ return bChanged;
+}
+bool SwFlyFrm::_SetObjLeft( const SwTwips _nLeft )
+{
+ const bool bChanged( Frm().Pos().X() != _nLeft );
+
+ Frm().Pos().X() = _nLeft;
+
+ return bChanged;
+}
+// <--
+
+/** method to assure that anchored object is registered at the correct
+ page frame
+
+ OD 2004-07-02 #i28701#
+
+ @author OD
+*/
+void SwFlyFrm::RegisterAtCorrectPage()
+{
+ // default behaviour is to do nothing.
+}
+
+/** method to determine, if a <MakeAll()> on the Writer fly frame is possible
+
+ OD 2004-05-11 #i28701#
+
+ @author OD
+*/
+bool SwFlyFrm::IsFormatPossible() const
+{
+ return SwAnchoredObject::IsFormatPossible() &&
+ !IsLocked() && !IsColLocked();
+}
+
+void SwFlyFrm::GetAnchoredObjects( std::list<SwAnchoredObject*>& aList, const SwFmt& rFmt )
+{
+ SwIterator<SwFlyFrm,SwFmt> aIter( rFmt );
+ for( SwFlyFrm* pFlyFrm = aIter.First(); pFlyFrm; pFlyFrm = aIter.Next() )
+ aList.push_back( pFlyFrm );
+}
+
+const SwFlyFrmFmt * SwFlyFrm::GetFmt() const
+{
+ return static_cast< const SwFlyFrmFmt * >( GetDep() );
+}
+
+SwFlyFrmFmt * SwFlyFrm::GetFmt()
+{
+ return static_cast< SwFlyFrmFmt * >( GetDep() );
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */