summaryrefslogtreecommitdiff
path: root/sw/source/core/layout/frmtool.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sw/source/core/layout/frmtool.cxx')
-rw-r--r--sw/source/core/layout/frmtool.cxx3604
1 files changed, 3604 insertions, 0 deletions
diff --git a/sw/source/core/layout/frmtool.cxx b/sw/source/core/layout/frmtool.cxx
new file mode 100644
index 000000000000..56059a4aaf26
--- /dev/null
+++ b/sw/source/core/layout/frmtool.cxx
@@ -0,0 +1,3604 @@
+/* -*- 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 <tools/bigint.hxx>
+#include <svx/svdmodel.hxx>
+#include <svx/svdpage.hxx>
+#include <editeng/brshitem.hxx>
+#include <editeng/keepitem.hxx>
+#include <editeng/shaditem.hxx>
+#include <editeng/ulspitem.hxx>
+#include <editeng/lrspitem.hxx>
+#include <editeng/boxitem.hxx>
+#include <sfx2/printer.hxx>
+#include <editeng/lspcitem.hxx>
+
+#include <fmtornt.hxx>
+#include <fmtanchr.hxx>
+#include <fmthdft.hxx>
+#include <fmtcntnt.hxx>
+#include <fmtfsize.hxx>
+#include <fmtsrnd.hxx>
+#include <docary.hxx>
+#include <lineinfo.hxx>
+#include <swmodule.hxx>
+#include "pagefrm.hxx"
+#include "colfrm.hxx"
+#include "doc.hxx"
+#include "fesh.hxx"
+#include "viewimp.hxx"
+#include "viewopt.hxx"
+#include "pam.hxx"
+#include "dflyobj.hxx"
+#include "dcontact.hxx"
+#include "frmtool.hxx"
+#include "docsh.hxx"
+#include "tabfrm.hxx"
+#include "rowfrm.hxx"
+#include "ftnfrm.hxx"
+#include "txtfrm.hxx"
+#include "notxtfrm.hxx"
+#include "flyfrms.hxx"
+#include "layact.hxx"
+#include "pagedesc.hxx"
+#include "section.hxx"
+#include "sectfrm.hxx"
+#include "node2lay.hxx"
+#include "ndole.hxx"
+#include "ndtxt.hxx"
+#include "swtable.hxx"
+#include "hints.hxx"
+#include <layhelp.hxx>
+#include <laycache.hxx>
+#include <rootfrm.hxx>
+#include "mdiexp.hxx"
+#include "statstr.hrc"
+#include <paratr.hxx>
+#include <sortedobjs.hxx>
+#include <objectformatter.hxx>
+#include <switerator.hxx>
+
+// ftnfrm.cxx:
+void lcl_RemoveFtns( SwFtnBossFrm* pBoss, sal_Bool bPageOnly, sal_Bool bEndNotes );
+
+using namespace ::com::sun::star;
+
+
+sal_Bool bObjsDirect = sal_True;
+sal_Bool bDontCreateObjects = sal_False;
+sal_Bool bSetCompletePaintOnInvalidate = sal_False;
+
+sal_uInt8 StackHack::nCnt = 0;
+sal_Bool StackHack::bLocked = sal_False;
+
+
+
+/*************************************************************************/
+
+SwFrmNotify::SwFrmNotify( SwFrm *pF ) :
+ pFrm( pF ),
+ aFrm( pF->Frm() ),
+ aPrt( pF->Prt() ),
+ bInvaKeep( sal_False ),
+ bValidSize( pF->GetValidSizeFlag() ),
+ mbFrmDeleted( false ) // #i49383#
+{
+ if ( pF->IsTxtFrm() )
+ {
+ mnFlyAnchorOfst = ((SwTxtFrm*)pF)->GetBaseOfstForFly( sal_True );
+ mnFlyAnchorOfstNoWrap = ((SwTxtFrm*)pF)->GetBaseOfstForFly( sal_False );
+ }
+ else
+ {
+ mnFlyAnchorOfst = 0;
+ mnFlyAnchorOfstNoWrap = 0;
+ }
+
+ bHadFollow = pF->IsCntntFrm() ?
+ (((SwCntntFrm*)pF)->GetFollow() ? sal_True : sal_False) :
+ sal_False;
+}
+
+/*************************************************************************/
+
+SwFrmNotify::~SwFrmNotify()
+{
+ // #i49383#
+ if ( mbFrmDeleted )
+ {
+ return;
+ }
+
+ SWRECTFN( pFrm )
+ const sal_Bool bAbsP = POS_DIFF( aFrm, pFrm->Frm() );
+ const sal_Bool bChgWidth =
+ (aFrm.*fnRect->fnGetWidth)() != (pFrm->Frm().*fnRect->fnGetWidth)();
+ const sal_Bool bChgHeight =
+ (aFrm.*fnRect->fnGetHeight)()!=(pFrm->Frm().*fnRect->fnGetHeight)();
+ const sal_Bool bChgFlyBasePos = pFrm->IsTxtFrm() &&
+ ( ( mnFlyAnchorOfst != ((SwTxtFrm*)pFrm)->GetBaseOfstForFly( sal_True ) ) ||
+ ( mnFlyAnchorOfstNoWrap != ((SwTxtFrm*)pFrm)->GetBaseOfstForFly( sal_False ) ) );
+
+ if ( pFrm->IsFlowFrm() && !pFrm->IsInFtn() )
+ {
+ SwFlowFrm *pFlow = SwFlowFrm::CastFlowFrm( pFrm );
+
+ if ( !pFlow->IsFollow() )
+ {
+ if ( !pFrm->GetIndPrev() )
+ {
+ if ( bInvaKeep )
+ {
+ SwFrm *pPre = pFrm->FindPrev();
+ if ( pPre && pPre->IsFlowFrm() )
+ {
+ // 1. pPre wants to keep with me:
+ bool bInvalidPrePos = SwFlowFrm::CastFlowFrm( pPre )->IsKeep( *pPre->GetAttrSet() ) && pPre->GetIndPrev();
+
+ // 2. pPre is a table and the last row wants to keep with me:
+ if ( !bInvalidPrePos && pPre->IsTabFrm() )
+ {
+ SwTabFrm* pPreTab = static_cast<SwTabFrm*>(pPre);
+ if ( pPreTab->GetFmt()->GetDoc()->get(IDocumentSettingAccess::TABLE_ROW_KEEP) )
+ {
+ SwRowFrm* pLastRow = static_cast<SwRowFrm*>(pPreTab->GetLastLower());
+ if ( pLastRow && pLastRow->ShouldRowKeepWithNext() )
+ bInvalidPrePos = true;
+ }
+ }
+
+ if ( bInvalidPrePos )
+ pPre->InvalidatePos();
+ }
+ }
+ }
+ else if ( !pFlow->HasFollow() )
+ {
+ long nOldHeight = (aFrm.*fnRect->fnGetHeight)();
+ long nNewHeight = (pFrm->Frm().*fnRect->fnGetHeight)();
+ if( (nOldHeight > nNewHeight) || (!nOldHeight && nNewHeight) )
+ pFlow->CheckKeep();
+ }
+ }
+ }
+
+ if ( bAbsP )
+ {
+ pFrm->SetCompletePaint();
+
+ SwFrm* pNxt = pFrm->GetIndNext();
+ // #121888# - skip empty section frames
+ while ( pNxt &&
+ pNxt->IsSctFrm() && !static_cast<SwSectionFrm*>(pNxt)->GetSection() )
+ {
+ pNxt = pNxt->GetIndNext();
+ }
+
+ if ( pNxt )
+ pNxt->InvalidatePos();
+ else
+ {
+ // #104100# - correct condition for setting retouche
+ // flag for vertical layout.
+ if( pFrm->IsRetoucheFrm() &&
+ (aFrm.*fnRect->fnTopDist)( (pFrm->Frm().*fnRect->fnGetTop)() ) > 0 )
+ {
+ pFrm->SetRetouche();
+ }
+
+ // A fresh follow frame does not have to be invalidated, because
+ // it is already formatted:
+ if ( bHadFollow || !pFrm->IsCntntFrm() || !((SwCntntFrm*)pFrm)->GetFollow() )
+ {
+ if ( !pFrm->IsTabFrm() || !((SwTabFrm*)pFrm)->GetFollow() )
+ pFrm->InvalidateNextPos();
+ }
+ }
+ }
+
+ //Fuer Hintergrundgrafiken muss bei Groessenaenderungen ein Repaint her.
+ const sal_Bool bPrtWidth =
+ (aPrt.*fnRect->fnGetWidth)() != (pFrm->Prt().*fnRect->fnGetWidth)();
+ const sal_Bool bPrtHeight =
+ (aPrt.*fnRect->fnGetHeight)()!=(pFrm->Prt().*fnRect->fnGetHeight)();
+ if ( bPrtWidth || bPrtHeight )
+ {
+ const SvxGraphicPosition ePos = pFrm->GetAttrSet()->GetBackground().GetGraphicPos();
+ if ( GPOS_NONE != ePos && GPOS_TILED != ePos )
+ pFrm->SetCompletePaint();
+ }
+ else
+ {
+ // #97597# - consider case that *only* margins between
+ // frame and printing area has changed. Then, frame has to be repainted,
+ // in order to force paint of the margin areas.
+ if ( !bAbsP && (bChgWidth || bChgHeight) )
+ {
+ pFrm->SetCompletePaint();
+ }
+ }
+
+ const sal_Bool bPrtP = POS_DIFF( aPrt, pFrm->Prt() );
+ if ( bAbsP || bPrtP || bChgWidth || bChgHeight ||
+ bPrtWidth || bPrtHeight || bChgFlyBasePos )
+ {
+ if( pFrm->IsAccessibleFrm() )
+ {
+ SwRootFrm *pRootFrm = pFrm->getRootFrm();
+ if( pRootFrm && pRootFrm->IsAnyShellAccessible() &&
+ pRootFrm->GetCurrShell() )
+ {
+ pRootFrm->GetCurrShell()->Imp()->MoveAccessibleFrm( pFrm, aFrm );
+ }
+ }
+
+ // Notification of anchored objects
+ if ( pFrm->GetDrawObjs() )
+ {
+ const SwSortedObjs &rObjs = *pFrm->GetDrawObjs();
+ SwPageFrm* pPageFrm = 0;
+ for ( sal_uInt32 i = 0; i < rObjs.Count(); ++i )
+ {
+ // OD 2004-03-31 #i26791# - no general distinction between
+ // Writer fly frames and drawing objects
+ bool bNotify = false;
+ bool bNotifySize = false;
+ SwAnchoredObject* pObj = rObjs[i];
+ SwContact* pContact = ::GetUserCall( pObj->GetDrawObj() );
+ // --> OD 2004-12-08 #115759#
+ const bool bAnchoredAsChar = pContact->ObjAnchoredAsChar();
+ if ( !bAnchoredAsChar )
+ // <--
+ {
+ // Notify object, which aren't anchored as-character:
+
+ // always notify objects, if frame position has changed
+ // or if the object is to-page|to-fly anchored.
+ if ( bAbsP ||
+ pContact->ObjAnchoredAtPage() ||
+ pContact->ObjAnchoredAtFly() )
+ {
+ bNotify = true;
+
+ // assure that to-fly anchored Writer fly frames are
+ // registered at the correct page frame, if frame
+ // position has changed.
+ if ( bAbsP && pContact->ObjAnchoredAtFly() &&
+ pObj->ISA(SwFlyFrm) )
+ {
+ // determine to-fly anchored Writer fly frame
+ SwFlyFrm* pFlyFrm = static_cast<SwFlyFrm*>(pObj);
+ // determine page frame of to-fly anchored
+ // Writer fly frame
+ SwPageFrm* pFlyPageFrm = pFlyFrm->FindPageFrm();
+ // determine page frame, if needed.
+ if ( !pPageFrm )
+ {
+ pPageFrm = pFrm->FindPageFrm();
+ }
+ if ( pPageFrm != pFlyPageFrm )
+ {
+ OSL_ENSURE( pFlyPageFrm, "~SwFrmNotify: Fly from Nowhere" );
+ if( pFlyPageFrm )
+ pFlyPageFrm->MoveFly( pFlyFrm, pPageFrm );
+ else
+ pPageFrm->AppendFlyToPage( pFlyFrm );
+ }
+ }
+ }
+ // otherwise the objects are notified in dependence to
+ // its positioning and alignment
+ else
+ {
+ const SwFmtVertOrient& rVert =
+ pContact->GetFmt()->GetVertOrient();
+ if ( ( rVert.GetVertOrient() == text::VertOrientation::CENTER ||
+ rVert.GetVertOrient() == text::VertOrientation::BOTTOM ||
+ rVert.GetRelationOrient() == text::RelOrientation::PRINT_AREA ) &&
+ ( bChgHeight || bPrtHeight ) )
+ {
+ bNotify = true;
+ }
+ if ( !bNotify )
+ {
+ const SwFmtHoriOrient& rHori =
+ pContact->GetFmt()->GetHoriOrient();
+ if ( ( rHori.GetHoriOrient() != text::HoriOrientation::NONE ||
+ rHori.GetRelationOrient()== text::RelOrientation::PRINT_AREA ||
+ rHori.GetRelationOrient()== text::RelOrientation::FRAME ) &&
+ ( bChgWidth || bPrtWidth || bChgFlyBasePos ) )
+ {
+ bNotify = true;
+ }
+ }
+ }
+ }
+ else if ( bPrtWidth )
+ {
+ // Notify as-character anchored objects, if printing area
+ // width has changed.
+ bNotify = true;
+ bNotifySize = true;
+ }
+
+ // perform notification via the corresponding invalidations
+ if ( bNotify )
+ {
+ if ( pObj->ISA(SwFlyFrm) )
+ {
+ SwFlyFrm* pFlyFrm = static_cast<SwFlyFrm*>(pObj);
+ if ( bNotifySize )
+ pFlyFrm->_InvalidateSize();
+ // --> OD 2004-12-08 #115759# - no invalidation of
+ // position for as-character anchored objects.
+ if ( !bAnchoredAsChar )
+ {
+ pFlyFrm->_InvalidatePos();
+ }
+ // <--
+ pFlyFrm->_Invalidate();
+ }
+ else if ( pObj->ISA(SwAnchoredDrawObject) )
+ {
+ // --> OD 2004-12-08 #115759# - no invalidation of
+ // position for as-character anchored objects.
+ if ( !bAnchoredAsChar )
+ {
+ pObj->InvalidateObjPos();
+ }
+ // <--
+ }
+ else
+ {
+ OSL_FAIL( "<SwCntntNotify::~SwCntntNotify()> - unknown anchored object type. Please inform OD." );
+ }
+ }
+ }
+ }
+ }
+ else if( pFrm->IsTxtFrm() && bValidSize != pFrm->GetValidSizeFlag() )
+ {
+ SwRootFrm *pRootFrm = pFrm->getRootFrm();
+ if( pRootFrm && pRootFrm->IsAnyShellAccessible() &&
+ pRootFrm->GetCurrShell() )
+ {
+ pRootFrm->GetCurrShell()->Imp()->InvalidateAccessibleFrmContent( pFrm );
+ }
+ }
+
+ // #i9046# Automatic frame width
+ SwFlyFrm* pFly = 0;
+ // --> FME 2004-10-21 #i35879# Do not trust the inf flags. pFrm does not
+ // necessarily have to have an upper!
+ if ( !pFrm->IsFlyFrm() && 0 != ( pFly = pFrm->ImplFindFlyFrm() ) )
+ // <--
+ {
+ // --> OD 2006-05-08 #i61999#
+ // no invalidation of columned Writer fly frames, because automatic
+ // width doesn't make sense for such Writer fly frames.
+ if ( pFly->Lower() && !pFly->Lower()->IsColumnFrm() )
+ {
+ const SwFmtFrmSize &rFrmSz = pFly->GetFmt()->GetFrmSize();
+
+ // This could be optimized. Basically the fly frame only has to
+ // be invalidated, if the first line of pFrm (if pFrm is a content
+ // frame, for other frame types its the print area) has changed its
+ // size and pFrm was responsible for the current width of pFly. On
+ // the other hand, this is only rarely used and re-calculation of
+ // the fly frame does not cause too much trouble. So we keep it this
+ // way:
+ if ( ATT_FIX_SIZE != rFrmSz.GetWidthSizeType() )
+ {
+ // --> OD 2005-07-29 #i50668#, #i50998# - invalidation of position
+ // of as-character anchored fly frames not needed and can cause
+ // layout loops
+ if ( !pFly->ISA(SwFlyInCntFrm) )
+ {
+ pFly->InvalidatePos();
+ }
+ // <--
+ pFly->InvalidateSize();
+ }
+ }
+ // <--
+ }
+}
+
+/*************************************************************************/
+
+SwLayNotify::SwLayNotify( SwLayoutFrm *pLayFrm ) :
+ SwFrmNotify( pLayFrm ),
+ bLowersComplete( sal_False )
+{
+}
+
+/*************************************************************************/
+
+// OD 2004-05-11 #i28701# - local method to invalidate the position of all
+// frames inclusive its floating screen objects, which are lowers of the given
+// layout frame
+void lcl_InvalidatePosOfLowers( SwLayoutFrm& _rLayoutFrm )
+{
+ if( _rLayoutFrm.IsFlyFrm() && _rLayoutFrm.GetDrawObjs() )
+ {
+ _rLayoutFrm.InvalidateObjs( true, false );
+ }
+
+ SwFrm* pLowerFrm = _rLayoutFrm.Lower();
+ while ( pLowerFrm )
+ {
+ pLowerFrm->InvalidatePos();
+ if ( pLowerFrm->IsTxtFrm() )
+ {
+ static_cast<SwTxtFrm*>(pLowerFrm)->Prepare( PREP_POS_CHGD );
+ }
+ else if ( pLowerFrm->IsTabFrm() )
+ {
+ pLowerFrm->InvalidatePrt();
+ }
+
+ pLowerFrm->InvalidateObjs( true, false );
+
+ pLowerFrm = pLowerFrm->GetNext();
+ };
+}
+
+SwLayNotify::~SwLayNotify()
+{
+ // --> OD 2005-07-29 #i49383#
+ if ( mbFrmDeleted )
+ {
+ return;
+ }
+ // <--
+
+ SwLayoutFrm *pLay = GetLay();
+ SWRECTFN( pLay )
+ sal_Bool bNotify = sal_False;
+ if ( pLay->Prt().SSize() != aPrt.SSize() )
+ {
+ if ( !IsLowersComplete() )
+ {
+ sal_Bool bInvaPercent;
+
+ if ( pLay->IsRowFrm() )
+ {
+ bInvaPercent = sal_True;
+ long nNew = (pLay->Prt().*fnRect->fnGetHeight)();
+ if( nNew != (aPrt.*fnRect->fnGetHeight)() )
+ ((SwRowFrm*)pLay)->AdjustCells( nNew, sal_True);
+ if( (pLay->Prt().*fnRect->fnGetWidth)()
+ != (aPrt.*fnRect->fnGetWidth)() )
+ ((SwRowFrm*)pLay)->AdjustCells( 0, sal_False );
+ }
+ else
+ {
+ //Proportionale Anpassung der innenliegenden.
+ //1. Wenn der Formatierte kein Fly ist
+ //2. Wenn er keine Spalten enthaelt
+ //3. Wenn der Fly eine feste Hoehe hat und die Spalten in der
+ // Hoehe danebenliegen.
+ //4. niemals bei SectionFrms.
+ sal_Bool bLow;
+ if( pLay->IsFlyFrm() )
+ {
+ if ( pLay->Lower() )
+ {
+ bLow = !pLay->Lower()->IsColumnFrm() ||
+ (pLay->Lower()->Frm().*fnRect->fnGetHeight)()
+ != (pLay->Prt().*fnRect->fnGetHeight)();
+ }
+ else
+ bLow = sal_False;
+ }
+ else if( pLay->IsSctFrm() )
+ {
+ if ( pLay->Lower() )
+ {
+ if( pLay->Lower()->IsColumnFrm() && pLay->Lower()->GetNext() )
+ bLow = pLay->Lower()->Frm().Height() != pLay->Prt().Height();
+ else
+ bLow = pLay->Prt().Width() != aPrt.Width();
+ }
+ else
+ bLow = sal_False;
+ }
+ else if( pLay->IsFooterFrm() && !pLay->HasFixSize() )
+ bLow = pLay->Prt().Width() != aPrt.Width();
+ else
+ bLow = sal_True;
+ bInvaPercent = bLow;
+ if ( bLow )
+ {
+ pLay->ChgLowersProp( aPrt.SSize() );
+ }
+ //Wenn die PrtArea gewachsen ist, so ist es moeglich, dass die
+ //Kette der Untergeordneten einen weiteren Frm aufnehmen kann,
+ //mithin muss also der 'moeglicherweise passende' Invalidiert werden.
+ //Das invalidieren lohnt nur, wenn es sich beim mir bzw. meinen
+ //Uppers um eine Moveable-Section handelt.
+ //Die PrtArea ist gewachsen, wenn die Breite oder die Hoehe groesser
+ //geworden ist.
+ if ( (pLay->Prt().Height() > aPrt.Height() ||
+ pLay->Prt().Width() > aPrt.Width()) &&
+ (pLay->IsMoveable() || pLay->IsFlyFrm()) )
+ {
+ SwFrm *pTmpFrm = pLay->Lower();
+ if ( pTmpFrm && pTmpFrm->IsFlowFrm() )
+ {
+ while ( pTmpFrm->GetNext() )
+ pTmpFrm = pTmpFrm->GetNext();
+ pTmpFrm->InvalidateNextPos();
+ }
+ }
+ }
+ bNotify = sal_True;
+ //TEUER!! aber wie macht man es geschickter?
+ if( bInvaPercent )
+ pLay->InvaPercentLowers( pLay->Prt().Height() - aPrt.Height() );
+ }
+ if ( pLay->IsTabFrm() )
+ //Damit _nur_ der Shatten bei Groessenaenderungen gemalt wird.
+ ((SwTabFrm*)pLay)->SetComplete();
+ else
+ {
+ const ViewShell *pSh = pLay->getRootFrm()->GetCurrShell();
+ if( !( pSh && pSh->GetViewOptions()->getBrowseMode() ) ||
+ !(pLay->GetType() & (FRM_BODY | FRM_PAGE)) )
+ //Damit die untergeordneten sauber retouchiert werden.
+ //Problembsp: Flys an den Henkeln packen und verkleinern.
+ //Nicht fuer Body und Page, sonst flackerts beim HTML-Laden.
+ pLay->SetCompletePaint();
+ }
+ }
+ //Lower benachrichtigen wenn sich die Position veraendert hat.
+ const sal_Bool bPrtPos = POS_DIFF( aPrt, pLay->Prt() );
+ const sal_Bool bPos = bPrtPos || POS_DIFF( aFrm, pLay->Frm() );
+ const sal_Bool bSize = pLay->Frm().SSize() != aFrm.SSize();
+
+ if ( bPos && pLay->Lower() && !IsLowersComplete() )
+ pLay->Lower()->InvalidatePos();
+
+ if ( bPrtPos )
+ pLay->SetCompletePaint();
+
+ //Nachfolger benachrichtigen wenn sich die SSize geaendert hat.
+ if ( bSize )
+ {
+ if( pLay->GetNext() )
+ {
+ if ( pLay->GetNext()->IsLayoutFrm() )
+ pLay->GetNext()->_InvalidatePos();
+ else
+ pLay->GetNext()->InvalidatePos();
+ }
+ else if( pLay->IsSctFrm() )
+ pLay->InvalidateNextPos();
+ }
+ if ( !IsLowersComplete() &&
+ !(pLay->GetType()&(FRM_FLY|FRM_SECTION) &&
+ pLay->Lower() && pLay->Lower()->IsColumnFrm()) &&
+ (bPos || bNotify) && !(pLay->GetType() & 0x1823) ) //Tab, Row, FtnCont, Root, Page
+ {
+ // --> OD 2005-03-11 #i44016# - force unlock of position of lower objects.
+ // --> OD 2005-03-30 #i43913# - no unlock of position of objects,
+ // if <pLay> is a cell frame, and its table frame resp. its parent table
+ // frame is locked.
+ // --> OD 2005-04-15 #i47458# - force unlock of position of lower objects,
+ // only if position of layout frame has changed.
+ bool bUnlockPosOfObjs( bPos );
+ if ( bUnlockPosOfObjs && pLay->IsCellFrm() )
+ {
+ SwTabFrm* pTabFrm( pLay->FindTabFrm() );
+ if ( pTabFrm &&
+ ( pTabFrm->IsJoinLocked() ||
+ ( pTabFrm->IsFollow() &&
+ pTabFrm->FindMaster()->IsJoinLocked() ) ) )
+ {
+ bUnlockPosOfObjs = false;
+ }
+ }
+ // --> OD 2005-05-18 #i49383# - check for footnote frame, if unlock
+ // of position of lower objects is allowed.
+ else if ( bUnlockPosOfObjs && pLay->IsFtnFrm() )
+ {
+ bUnlockPosOfObjs = static_cast<SwFtnFrm*>(pLay)->IsUnlockPosOfLowerObjs();
+ }
+ // <--
+ // --> OD 2005-07-29 #i51303# - no unlock of object positions for sections
+ else if ( bUnlockPosOfObjs && pLay->IsSctFrm() )
+ {
+ bUnlockPosOfObjs = false;
+ }
+ // <--
+ pLay->NotifyLowerObjs( bUnlockPosOfObjs );
+ // <--
+ }
+ if ( bPos && pLay->IsFtnFrm() && pLay->Lower() )
+ {
+ // OD 2004-05-11 #i28701#
+ ::lcl_InvalidatePosOfLowers( *pLay );
+ }
+ if( ( bPos || bSize ) && pLay->IsFlyFrm() && ((SwFlyFrm*)pLay)->GetAnchorFrm()
+ && ((SwFlyFrm*)pLay)->GetAnchorFrm()->IsFlyFrm() )
+ ((SwFlyFrm*)pLay)->AnchorFrm()->InvalidateSize();
+}
+
+/*************************************************************************/
+
+SwFlyNotify::SwFlyNotify( SwFlyFrm *pFlyFrm ) :
+ SwLayNotify( pFlyFrm ),
+ // --> OD 2004-11-24 #115759# - keep correct page frame - the page frame
+ // the Writer fly frame is currently registered at.
+ pOldPage( pFlyFrm->GetPageFrm() ),
+ // <--
+ aFrmAndSpace( pFlyFrm->GetObjRectWithSpaces() )
+{
+}
+
+/*************************************************************************/
+
+SwFlyNotify::~SwFlyNotify()
+{
+ // --> OD 2005-07-29 #i49383#
+ if ( mbFrmDeleted )
+ {
+ return;
+ }
+ // <--
+
+ SwFlyFrm *pFly = GetFly();
+ if ( pFly->IsNotifyBack() )
+ {
+ ViewShell *pSh = pFly->getRootFrm()->GetCurrShell();
+ SwViewImp *pImp = pSh ? pSh->Imp() : 0;
+ if ( !pImp || !pImp->IsAction() || !pImp->GetLayAction().IsAgain() )
+ {
+ //Wenn in der LayAction das IsAgain gesetzt ist kann es sein,
+ //dass die alte Seite inzwischen vernichtet wurde!
+ ::Notify( pFly, pOldPage, aFrmAndSpace, &aPrt );
+ // --> OD 2004-10-20 #i35640# - additional notify anchor text frame,
+ // if Writer fly frame has changed its page
+ if ( pFly->GetAnchorFrm()->IsTxtFrm() &&
+ pFly->GetPageFrm() != pOldPage )
+ {
+ pFly->AnchorFrm()->Prepare( PREP_FLY_LEAVE );
+ }
+ // <--
+ }
+ pFly->ResetNotifyBack();
+ }
+
+ //Haben sich Groesse oder Position geaendert, so sollte die View
+ //das wissen.
+ SWRECTFN( pFly )
+ const bool bPosChgd = POS_DIFF( aFrm, pFly->Frm() );
+ const bool bFrmChgd = pFly->Frm().SSize() != aFrm.SSize();
+ const bool bPrtChgd = aPrt != pFly->Prt();
+ if ( bPosChgd || bFrmChgd || bPrtChgd )
+ {
+ pFly->NotifyDrawObj();
+ }
+ if ( bPosChgd && aFrm.Pos().X() != WEIT_WECH )
+ {
+ // OD 2004-05-10 #i28701# - no direct move of lower Writer fly frames.
+ // reason: New positioning and alignment (e.g. to-paragraph anchored,
+ // but aligned at page) are introduced.
+ // <SwLayNotify::~SwLayNotify()> takes care of invalidation of lower
+ // floating screen objects by calling method <SwLayoutFrm::NotifyLowerObjs()>.
+
+ if ( pFly->IsFlyAtCntFrm() )
+ {
+ SwFrm *pNxt = pFly->AnchorFrm()->FindNext();
+ if ( pNxt )
+ {
+ pNxt->InvalidatePos();
+ }
+ }
+
+ // --> OD 2004-11-05 #i26945# - notify anchor.
+ // Needed for negative positioned Writer fly frames
+ if ( pFly->GetAnchorFrm()->IsTxtFrm() )
+ {
+ pFly->AnchorFrm()->Prepare( PREP_FLY_LEAVE );
+ }
+ // <--
+ }
+
+ // OD 2004-05-13 #i28701#
+ // --> OD 2005-03-21 #i45180# - no adjustment of layout process flags and
+ // further notifications/invalidations, if format is called by grow/shrink
+ if ( pFly->ConsiderObjWrapInfluenceOnObjPos() &&
+ ( !pFly->ISA(SwFlyFreeFrm) ||
+ !static_cast<SwFlyFreeFrm*>(pFly)->IsNoMoveOnCheckClip() ) )
+ // <--
+ {
+ // --> OD 2005-09-05 #i54138# - suppress restart of the layout process
+ // on changed frame height.
+ // Note: It doesn't seem to be necessary and can cause layout loops.
+ if ( bPosChgd )
+ // <--
+ {
+ // indicate a restart of the layout process
+ pFly->SetRestartLayoutProcess( true );
+ }
+ else
+ {
+ // lock position
+ pFly->LockPosition();
+
+ if ( !pFly->ConsiderForTextWrap() )
+ {
+ // indicate that object has to be considered for text wrap
+ pFly->SetConsiderForTextWrap( true );
+ // invalidate 'background' in order to allow its 'background'
+ // to wrap around it.
+ pFly->NotifyBackground( pFly->GetPageFrm(),
+ pFly->GetObjRectWithSpaces(),
+ PREP_FLY_ARRIVE );
+ // invalidate position of anchor frame in order to force
+ // a re-format of the anchor frame, which also causes a
+ // re-format of the invalid previous frames of the anchor frame.
+ pFly->AnchorFrm()->InvalidatePos();
+ }
+ }
+ }
+}
+
+/*************************************************************************/
+
+SwCntntNotify::SwCntntNotify( SwCntntFrm *pCntntFrm ) :
+ SwFrmNotify( pCntntFrm ),
+ // OD 08.01.2004 #i11859#
+ mbChkHeightOfLastLine( false ),
+ mnHeightOfLastLine( 0L ),
+ // OD 2004-02-26 #i25029#
+ mbInvalidatePrevPrtArea( false ),
+ mbBordersJoinedWithPrev( false )
+{
+ // OD 08.01.2004 #i11859#
+ if ( pCntntFrm->IsTxtFrm() )
+ {
+ SwTxtFrm* pTxtFrm = static_cast<SwTxtFrm*>(pCntntFrm);
+ if ( !pTxtFrm->GetTxtNode()->getIDocumentSettingAccess()->get(IDocumentSettingAccess::OLD_LINE_SPACING) )
+ {
+ const SwAttrSet* pSet = pTxtFrm->GetAttrSet();
+ const SvxLineSpacingItem &rSpace = pSet->GetLineSpacing();
+ if ( rSpace.GetInterLineSpaceRule() == SVX_INTER_LINE_SPACE_PROP )
+ {
+ mbChkHeightOfLastLine = true;
+ mnHeightOfLastLine = pTxtFrm->GetHeightOfLastLine();
+ }
+ }
+ }
+}
+
+/*************************************************************************/
+
+SwCntntNotify::~SwCntntNotify()
+{
+ // --> OD 2005-07-29 #i49383#
+ if ( mbFrmDeleted )
+ {
+ return;
+ }
+ // <--
+
+ SwCntntFrm *pCnt = GetCnt();
+ if ( bSetCompletePaintOnInvalidate )
+ pCnt->SetCompletePaint();
+
+ SWRECTFN( pCnt )
+ if ( pCnt->IsInTab() && ( POS_DIFF( pCnt->Frm(), aFrm ) ||
+ pCnt->Frm().SSize() != aFrm.SSize()))
+ {
+ SwLayoutFrm* pCell = pCnt->GetUpper();
+ while( !pCell->IsCellFrm() && pCell->GetUpper() )
+ pCell = pCell->GetUpper();
+ OSL_ENSURE( pCell->IsCellFrm(), "Where's my cell?" );
+ if ( text::VertOrientation::NONE != pCell->GetFmt()->GetVertOrient().GetVertOrient() )
+ pCell->InvalidatePrt(); //fuer vertikale Ausrichtung.
+ }
+
+ // OD 2004-02-26 #i25029#
+ if ( mbInvalidatePrevPrtArea && mbBordersJoinedWithPrev &&
+ pCnt->IsTxtFrm() &&
+ !pCnt->IsFollow() && !pCnt->GetIndPrev() )
+ {
+ // determine previous frame
+ SwFrm* pPrevFrm = pCnt->FindPrev();
+ // skip empty section frames and hidden text frames
+ {
+ while ( pPrevFrm &&
+ ( ( pPrevFrm->IsSctFrm() &&
+ !static_cast<SwSectionFrm*>(pPrevFrm)->GetSection() ) ||
+ ( pPrevFrm->IsTxtFrm() &&
+ static_cast<SwTxtFrm*>(pPrevFrm)->IsHiddenNow() ) ) )
+ {
+ pPrevFrm = pPrevFrm->FindPrev();
+ }
+ }
+
+ // Invalidate printing area of found previous frame
+ if ( pPrevFrm )
+ {
+ if ( pPrevFrm->IsSctFrm() )
+ {
+ if ( pCnt->IsInSct() )
+ {
+ // Note: found previous frame is a section frame and
+ // <pCnt> is also inside a section.
+ // Thus due to <mbBordersJoinedWithPrev>,
+ // <pCnt> had joined its borders/shadow with the
+ // last content of the found section.
+ // Invalidate printing area of last content in found section.
+ SwFrm* pLstCntntOfSctFrm =
+ static_cast<SwSectionFrm*>(pPrevFrm)->FindLastCntnt();
+ if ( pLstCntntOfSctFrm )
+ {
+ pLstCntntOfSctFrm->InvalidatePrt();
+ }
+ }
+ }
+ else
+ {
+ pPrevFrm->InvalidatePrt();
+ }
+ }
+ }
+
+ sal_Bool bFirst = (aFrm.*fnRect->fnGetWidth)() == 0;
+
+ if ( pCnt->IsNoTxtFrm() )
+ {
+ //Aktive PlugIn's oder OLE-Objekte sollten etwas von der Veraenderung
+ //mitbekommen, damit sie Ihr Window entsprechend verschieben.
+ ViewShell *pSh = pCnt->getRootFrm()->GetCurrShell();
+ if ( pSh )
+ {
+ SwOLENode *pNd;
+ if ( 0 != (pNd = pCnt->GetNode()->GetOLENode()) &&
+ (pNd->GetOLEObj().IsOleRef() ||
+ pNd->IsOLESizeInvalid()) )
+ {
+ OSL_ENSURE( pCnt->IsInFly(), "OLE not in FlyFrm" );
+ SwFlyFrm *pFly = pCnt->FindFlyFrm();
+ svt::EmbeddedObjectRef& xObj = pNd->GetOLEObj().GetObject();
+ SwFEShell *pFESh = 0;
+ ViewShell *pTmp = pSh;
+ do
+ { if ( pTmp->ISA( SwCrsrShell ) )
+ {
+ pFESh = (SwFEShell*)pTmp;
+ // #108369#: Here used to be the condition if (!bFirst).
+ // I think this should mean "do not call CalcAndSetScale"
+ // if the frame is formatted for the first time.
+ // Unfortunately this is not valid anymore since the
+ // SwNoTxtFrm already gets a width during CalcLowerPreps.
+ // Nevertheless, the indention of !bFirst seemed to be
+ // to assure that the OLE objects have already been notified
+ // if necessary before calling CalcAndSetScale.
+ // So I replaced !bFirst by !IsOLESizeInvalid. There is
+ // one additional problem specific to the word import:
+ // The layout is calculated _before_ calling PrtOLENotify,
+ // and the OLE objects are not invalidated during import.
+ // Therefore I added the condition !IsUpdateExpFld,
+ // have a look at the occurrence of CalcLayout in
+ // uiview/view.cxx.
+ if ( !pNd->IsOLESizeInvalid() &&
+ !pSh->GetDoc()->IsUpdateExpFld() )
+ pFESh->CalcAndSetScale( xObj, &pFly->Prt(), &pFly->Frm());
+ }
+ pTmp = (ViewShell*)pTmp->GetNext();
+ } while ( pTmp != pSh );
+
+ if ( pFESh && pNd->IsOLESizeInvalid() )
+ {
+ pNd->SetOLESizeInvalid( sal_False );
+ //TODO/LATER: needs OnDocumentPrinterChanged
+ //xObj->OnDocumentPrinterChanged( pNd->GetDoc()->getPrinter( false ) );
+ pFESh->CalcAndSetScale( xObj );//Client erzeugen lassen.
+ }
+ }
+ //dito Animierte Grafiken
+ if ( Frm().HasArea() && ((SwNoTxtFrm*)pCnt)->HasAnimation() )
+ {
+ ((SwNoTxtFrm*)pCnt)->StopAnimation();
+ pSh->InvalidateWindows( Frm() );
+ }
+ }
+ }
+
+ if ( bFirst )
+ {
+ pCnt->SetRetouche(); //fix(13870)
+
+ SwDoc *pDoc = pCnt->GetNode()->GetDoc();
+ if ( pDoc->GetSpzFrmFmts()->Count() &&
+ !pDoc->IsLoaded() && !pDoc->IsNewDoc() )
+ {
+ //Der Frm wurde wahrscheinlich zum ersten mal formatiert.
+ //Wenn ein Filter Flys oder Zeichenobjekte einliest und diese
+ //Seitengebunden sind, hat er ein Problem, weil er i.d.R. die
+ //Seitennummer nicht kennt. Er weiss lediglich welches der Inhalt
+ //(CntntNode) an dieser Stelle ist.
+ //Die Filter stellen dazu das Ankerattribut der Objekte so ein, dass
+ //sie vom Typ zwar Seitengebunden sind, aber der Index des Ankers
+ //auf diesen CntntNode zeigt.
+ //Hier werden diese vorlauefigen Verbindungen aufgeloest.
+
+ const SwPageFrm *pPage = 0;
+ SwNodeIndex *pIdx = 0;
+ SwSpzFrmFmts *pTbl = pDoc->GetSpzFrmFmts();
+
+ for ( sal_uInt16 i = 0; i < pTbl->Count(); ++i )
+ {
+ if ( !pPage )
+ pPage = pCnt->FindPageFrm();
+ SwFrmFmt *pFmt = (*pTbl)[i];
+ const SwFmtAnchor &rAnch = pFmt->GetAnchor();
+
+ if ((FLY_AT_PAGE != rAnch.GetAnchorId()) &&
+ (FLY_AT_PARA != rAnch.GetAnchorId()))
+ {
+ continue; //#60878# nicht etwa zeichengebundene.
+ }
+
+ if ( rAnch.GetCntntAnchor() )
+ {
+ if ( !pIdx )
+ {
+ pIdx = new SwNodeIndex( *pCnt->GetNode() );
+ }
+ if ( rAnch.GetCntntAnchor()->nNode == *pIdx )
+ {
+ if (FLY_AT_PAGE == rAnch.GetAnchorId())
+ {
+ OSL_FAIL( "<SwCntntNotify::~SwCntntNotify()> - to page anchored object with content position. Please inform OD." );
+ SwFmtAnchor aAnch( rAnch );
+ aAnch.SetAnchor( 0 );
+ aAnch.SetPageNum( pPage->GetPhyPageNum() );
+ pFmt->SetFmtAttr( aAnch );
+ if ( RES_DRAWFRMFMT != pFmt->Which() )
+ pFmt->MakeFrms();
+ }
+ }
+ }
+ }
+ delete pIdx;
+ }
+ }
+
+ // OD 12.01.2004 #i11859# - invalidate printing area of following frame,
+ // if height of last line has changed.
+ if ( pCnt->IsTxtFrm() && mbChkHeightOfLastLine )
+ {
+ if ( mnHeightOfLastLine != static_cast<SwTxtFrm*>(pCnt)->GetHeightOfLastLine() )
+ {
+ pCnt->InvalidateNextPrtArea();
+ }
+ }
+
+ // --> OD 2005-03-07 #i44049#
+ if ( pCnt->IsTxtFrm() && POS_DIFF( aFrm, pCnt->Frm() ) )
+ {
+ pCnt->InvalidateObjs( true );
+ }
+ // <--
+
+ // --> OD 2005-04-12 #i43255# - move code to invalidate at-character
+ // anchored objects due to a change of its anchor character from
+ // method <SwTxtFrm::Format(..)>.
+ if ( pCnt->IsTxtFrm() )
+ {
+ SwTxtFrm* pMasterFrm = pCnt->IsFollow()
+ ? static_cast<SwTxtFrm*>(pCnt)->FindMaster()
+ : static_cast<SwTxtFrm*>(pCnt);
+ if ( pMasterFrm && !pMasterFrm->IsFlyLock() &&
+ pMasterFrm->GetDrawObjs() )
+ {
+ SwSortedObjs* pObjs = pMasterFrm->GetDrawObjs();
+ for ( sal_uInt32 i = 0; i < pObjs->Count(); ++i )
+ {
+ SwAnchoredObject* pAnchoredObj = (*pObjs)[i];
+ if ( pAnchoredObj->GetFrmFmt().GetAnchor().GetAnchorId()
+ == FLY_AT_CHAR )
+ {
+ pAnchoredObj->CheckCharRectAndTopOfLine( !pMasterFrm->IsEmpty() );
+ }
+ }
+ }
+ }
+ // <--
+}
+
+/*************************************************************************/
+
+void AppendObjs( const SwSpzFrmFmts *pTbl, sal_uLong nIndex,
+ SwFrm *pFrm, SwPageFrm *pPage )
+{
+ for ( sal_uInt16 i = 0; i < pTbl->Count(); ++i )
+ {
+ SwFrmFmt *pFmt = (SwFrmFmt*)(*pTbl)[i];
+ const SwFmtAnchor &rAnch = pFmt->GetAnchor();
+ if ( rAnch.GetCntntAnchor() &&
+ (rAnch.GetCntntAnchor()->nNode.GetIndex() == nIndex) )
+ {
+ const bool bFlyAtFly = rAnch.GetAnchorId() == FLY_AT_FLY; // LAYER_IMPL
+ //Wird ein Rahmen oder ein SdrObject beschrieben?
+ const bool bSdrObj = RES_DRAWFRMFMT == pFmt->Which();
+ // OD 23.06.2003 #108784# - append also drawing objects anchored
+ // as character.
+ const bool bDrawObjInCntnt = bSdrObj &&
+ (rAnch.GetAnchorId() == FLY_AS_CHAR);
+
+ if( bFlyAtFly ||
+ (rAnch.GetAnchorId() == FLY_AT_PARA) ||
+ (rAnch.GetAnchorId() == FLY_AT_CHAR) ||
+ bDrawObjInCntnt )
+ {
+ SdrObject* pSdrObj = 0;
+ if ( bSdrObj && 0 == (pSdrObj = pFmt->FindSdrObject()) )
+ {
+ OSL_ENSURE( !bSdrObj, "DrawObject not found." );
+ pFmt->GetDoc()->DelFrmFmt( pFmt );
+ --i;
+ continue;
+ }
+ if ( pSdrObj )
+ {
+ if ( !pSdrObj->GetPage() )
+ {
+ pFmt->getIDocumentDrawModelAccess()->GetDrawModel()->GetPage(0)->
+ InsertObject(pSdrObj, pSdrObj->GetOrdNumDirect());
+ }
+
+ SwDrawContact* pNew =
+ static_cast<SwDrawContact*>(GetUserCall( pSdrObj ));
+ if ( !pNew->GetAnchorFrm() )
+ {
+ pFrm->AppendDrawObj( *(pNew->GetAnchoredObj( 0L )) );
+ }
+ // OD 19.06.2003 #108784# - add 'virtual' drawing object,
+ // if necessary. But control objects have to be excluded.
+ else if ( !::CheckControlLayer( pSdrObj ) &&
+ pNew->GetAnchorFrm() != pFrm &&
+ !pNew->GetDrawObjectByAnchorFrm( *pFrm ) )
+ {
+ SwDrawVirtObj* pDrawVirtObj = pNew->AddVirtObj();
+ pFrm->AppendDrawObj( *(pNew->GetAnchoredObj( pDrawVirtObj )) );
+
+ // for repaint, use new ActionChanged()
+ // pDrawVirtObj->SendRepaintBroadcast();
+ pDrawVirtObj->ActionChanged();
+ }
+
+ }
+ else
+ {
+ SwFlyFrm *pFly;
+ if( bFlyAtFly )
+ pFly = new SwFlyLayFrm( (SwFlyFrmFmt*)pFmt, pFrm, pFrm );
+ else
+ pFly = new SwFlyAtCntFrm( (SwFlyFrmFmt*)pFmt, pFrm, pFrm );
+ pFly->Lock();
+ pFrm->AppendFly( pFly );
+ pFly->Unlock();
+ if ( pPage )
+ ::RegistFlys( pPage, pFly );
+ }
+ }
+ }
+ }
+}
+
+bool lcl_ObjConnected( SwFrmFmt *pFmt, const SwFrm* pSib )
+{
+ SwIterator<SwFlyFrm,SwFmt> aIter( *pFmt );
+ if ( RES_FLYFRMFMT == pFmt->Which() )
+ {
+ const SwRootFrm* pRoot = pSib ? pSib->getRootFrm() : 0;
+ const SwFlyFrm* pTmpFrm;
+ for( pTmpFrm = aIter.First(); pTmpFrm; pTmpFrm = aIter.Next() )
+ {
+ if(! pRoot || pRoot == pTmpFrm->getRootFrm() )
+ return true;
+ }
+ }
+ else
+ {
+ SwDrawContact *pContact = SwIterator<SwDrawContact,SwFmt>::FirstElement(*pFmt);
+ if ( pContact )
+ return pContact->GetAnchorFrm() != 0;
+ }
+ return false;
+}
+
+/** helper method to determine, if a <SwFrmFmt>, which has an object connected,
+ is located in header or footer.
+
+ OD 23.06.2003 #108784#
+
+ @author OD
+*/
+bool lcl_InHeaderOrFooter( SwFrmFmt& _rFmt )
+{
+ bool bRetVal = false;
+
+ const SwFmtAnchor& rAnch = _rFmt.GetAnchor();
+
+ if (rAnch.GetAnchorId() != FLY_AT_PAGE)
+ {
+ bRetVal = _rFmt.GetDoc()->IsInHeaderFooter( rAnch.GetCntntAnchor()->nNode );
+ }
+
+ return bRetVal;
+}
+
+void AppendAllObjs( const SwSpzFrmFmts *pTbl, const SwFrm* pSib )
+{
+ //Verbinden aller Objekte, die in der SpzTbl beschrieben sind mit dem
+ //Layout.
+ //Wenn sich nix mehr tut hoeren wir auf. Dann koennen noch Formate
+ //uebrigbleiben, weil wir weder zeichengebunde Rahmen verbinden noch
+ //Objecte die in zeichengebundenen verankert sind.
+
+ SwSpzFrmFmts aCpy( 255, 255 );
+ aCpy.Insert( pTbl, 0 );
+
+ sal_uInt16 nOldCnt = USHRT_MAX;
+
+ while ( aCpy.Count() && aCpy.Count() != nOldCnt )
+ {
+ nOldCnt = aCpy.Count();
+ for ( int i = 0; i < int(aCpy.Count()); ++i )
+ {
+ SwFrmFmt *pFmt = (SwFrmFmt*)aCpy[ sal_uInt16(i) ];
+ const SwFmtAnchor &rAnch = pFmt->GetAnchor();
+ sal_Bool bRemove = sal_False;
+ if ((rAnch.GetAnchorId() == FLY_AT_PAGE) ||
+ (rAnch.GetAnchorId() == FLY_AS_CHAR))
+ {
+ //Seitengebunde sind bereits verankert, zeichengebundene
+ //will ich hier nicht.
+ bRemove = sal_True;
+ }
+ else if ( sal_False == (bRemove = ::lcl_ObjConnected( pFmt, pSib )) ||
+ ::lcl_InHeaderOrFooter( *pFmt ) )
+ {
+ // OD 23.06.2003 #108784# - correction: for objects in header
+ // or footer create frames, in spite of the fact that an connected
+ // objects already exists.
+ //Fuer Flys und DrawObjs nur dann ein MakeFrms rufen wenn noch
+ //keine abhaengigen Existieren, andernfalls, oder wenn das
+ //MakeFrms keine abhaengigen erzeugt, entfernen.
+ pFmt->MakeFrms();
+ bRemove = ::lcl_ObjConnected( pFmt, pSib );
+ }
+ if ( bRemove )
+ {
+ aCpy.Remove( sal_uInt16(i) );
+ --i;
+ }
+ }
+ }
+ aCpy.Remove( 0, aCpy.Count() );
+}
+
+/** local method to set 'working' position for newly inserted frames
+
+ OD 12.08.2003 #i17969#
+
+ @author OD
+*/
+void lcl_SetPos( SwFrm& _rNewFrm,
+ const SwLayoutFrm& _rLayFrm )
+{
+ SWRECTFN( (&_rLayFrm) )
+ (_rNewFrm.Frm().*fnRect->fnSetPos)( (_rLayFrm.Frm().*fnRect->fnGetPos)() );
+ // move position by one SwTwip in text flow direction in order to get
+ // notifications for a new calculated position after its formatting.
+ if ( bVert )
+ _rNewFrm.Frm().Pos().X() -= 1;
+ else
+ _rNewFrm.Frm().Pos().Y() += 1;
+}
+
+void MA_FASTCALL _InsertCnt( SwLayoutFrm *pLay, SwDoc *pDoc,
+ sal_uLong nIndex, sal_Bool bPages, sal_uLong nEndIndex,
+ SwFrm *pPrv )
+{
+ pDoc->BlockIdling();
+ SwRootFrm* pLayout = pLay->getRootFrm();
+ const sal_Bool bOldCallbackActionEnabled = pLayout ? pLayout->IsCallbackActionEnabled() : sal_False;
+ if( bOldCallbackActionEnabled )
+ pLayout->SetCallbackActionEnabled( sal_False );
+
+ //Bei der Erzeugung des Layouts wird bPages mit sal_True uebergeben. Dann
+ //werden schon mal alle x Absaetze neue Seiten angelegt. Bei umbruechen
+ //und/oder Pagedescriptorwechseln werden gleich die entsprechenden Seiten
+ //angelegt.
+ //Vorteil ist, das einerseits schon eine annaehernd realistische Zahl von
+ //Seiten angelegt wird, vor allem aber gibt es nicht mehr eine schier
+ //lange Kette von Absaetzen teuer verschoben werden muss, bis sie sich auf
+ //ertraegliches mass reduziert hat.
+ //Wir gehen mal davon aus, da? 20 Absaetze auf eine Seite passen
+ //Damit es in extremen Faellen nicht gar so heftig rechenen wir je nach
+ //Node noch etwas drauf.
+ //Wenn in der DocStatistik eine brauchebare Seitenzahl angegeben ist
+ //(wird beim Schreiben gepflegt), so wird von dieser Seitenanzahl
+ //ausgegengen.
+ const sal_Bool bStartPercent = bPages && !nEndIndex;
+
+ SwPageFrm *pPage = pLay->FindPageFrm();
+ const SwSpzFrmFmts *pTbl = pDoc->GetSpzFrmFmts();
+ SwFrm *pFrm = 0;
+ sal_Bool bBreakAfter = sal_False;
+
+ SwActualSection *pActualSection = 0;
+ SwLayHelper *pPageMaker;
+
+ //Wenn das Layout erzeugt wird (bPages == sal_True) steuern wir den Progress
+ //an. Flys und DrawObjekte werden dann nicht gleich verbunden, dies
+ //passiert erst am Ende der Funktion.
+ if ( bPages )
+ {
+ // Attention: the SwLayHelper class uses references to the content-,
+ // page-, layout-frame etc. and may change them!
+ pPageMaker = new SwLayHelper( pDoc, pFrm, pPrv, pPage, pLay,
+ pActualSection, bBreakAfter, nIndex, 0 == nEndIndex );
+ if( bStartPercent )
+ {
+ const sal_uLong nPageCount = pPageMaker->CalcPageCount();
+ if( nPageCount )
+ bObjsDirect = sal_False;
+ }
+ }
+ else
+ pPageMaker = NULL;
+
+ if( pLay->IsInSct() &&
+ ( pLay->IsSctFrm() || pLay->GetUpper() ) ) // Hierdurch werden Frischlinge
+ // abgefangen, deren Flags noch nicht ermittelt werden koennen,
+ // so z.B. beim Einfuegen einer Tabelle
+ {
+ SwSectionFrm* pSct = pLay->FindSctFrm();
+ // Wenn Inhalt in eine Fussnote eingefuegt wird, die in einem spaltigen
+ // Bereich liegt, so darf der spaltige Bereich nicht aufgebrochen werden.
+ // Nur wenn im Innern der Fussnote ein Bereich liegt, ist dies ein
+ // Kandidat fuer pActualSection.
+ // Gleiches gilt fuer Bereiche in Tabellen, wenn innerhalb einer Tabelle
+ // eingefuegt wird, duerfen nur Bereiche, die ebenfalls im Innern liegen,
+ // aufgebrochen werden.
+ if( ( !pLay->IsInFtn() || pSct->IsInFtn() ) &&
+ ( !pLay->IsInTab() || pSct->IsInTab() ) )
+ {
+ pActualSection = new SwActualSection( 0, pSct, 0 );
+ OSL_ENSURE( !pLay->Lower() || !pLay->Lower()->IsColumnFrm(),
+ "_InsertCnt: Wrong Call" );
+ }
+ }
+
+ //If a section is "open", the pActualSection points to an SwActualSection.
+ //If the page breaks, for "open" sections a follow will created.
+ //For nested sections (which have, however, not a nested layout),
+ //the SwActualSection class has a member, which points to an upper(section).
+ //When the "inner" section finishs, the upper will used instead.
+
+ while( sal_True )
+ {
+ SwNode *pNd = pDoc->GetNodes()[nIndex];
+ if ( pNd->IsCntntNode() )
+ {
+ SwCntntNode* pNode = (SwCntntNode*)pNd;
+ pFrm = pNode->IsTxtNode() ? new SwTxtFrm( (SwTxtNode*)pNode, pLay ) :
+ pNode->MakeFrm( pLay );
+ if( pPageMaker )
+ pPageMaker->CheckInsert( nIndex );
+
+ pFrm->InsertBehind( pLay, pPrv );
+ // --> OD 2005-12-01 #i27138#
+ // notify accessibility paragraphs objects about changed
+ // CONTENT_FLOWS_FROM/_TO relation.
+ // Relation CONTENT_FLOWS_FROM for next paragraph will change
+ // and relation CONTENT_FLOWS_TO for previous paragraph will change.
+ if ( pFrm->IsTxtFrm() )
+ {
+ ViewShell* pViewShell( pFrm->getRootFrm()->GetCurrShell() );
+ // no notification, if <ViewShell> is in construction
+ if ( pViewShell && !pViewShell->IsInConstructor() &&
+ pViewShell->GetLayout() &&
+ pViewShell->GetLayout()->IsAnyShellAccessible() )
+ {
+ pViewShell->InvalidateAccessibleParaFlowRelation(
+ dynamic_cast<SwTxtFrm*>(pFrm->FindNextCnt( true )),
+ dynamic_cast<SwTxtFrm*>(pFrm->FindPrevCnt( true )) );
+ // --> OD 2006-08-28 #i68958#
+ // The information flags of the text frame are validated
+ // in methods <FindNextCnt(..)> and <FindPrevCnt(..)>.
+ // The information flags have to be invalidated, because
+ // it is possible, that the one of its upper frames
+ // isn't inserted into the layout.
+ pFrm->InvalidateInfFlags();
+ // <--
+ }
+ }
+ // <--
+ // OD 12.08.2003 #i17969# - consider horizontal/vertical layout
+ // for setting position at newly inserted frame
+ lcl_SetPos( *pFrm, *pLay );
+ pPrv = pFrm;
+
+ if ( pTbl->Count() && bObjsDirect && !bDontCreateObjects )
+ AppendObjs( pTbl, nIndex, pFrm, pPage );
+ }
+ else if ( pNd->IsTableNode() )
+ { //Sollten wir auf eine Tabelle gestossen sein?
+ SwTableNode *pTblNode = (SwTableNode*)pNd;
+
+ // #108116# loading may produce table structures that GCLines
+ // needs to clean up. To keep table formulas correct, change
+ // all table formulas to internal (BOXPTR) representation.
+ SwTableFmlUpdate aMsgHnt( &pTblNode->GetTable() );
+ aMsgHnt.eFlags = TBL_BOXPTR;
+ pDoc->UpdateTblFlds( &aMsgHnt );
+ pTblNode->GetTable().GCLines();
+
+ pFrm = pTblNode->MakeFrm( pLay );
+
+ if( pPageMaker )
+ pPageMaker->CheckInsert( nIndex );
+
+ pFrm->InsertBehind( pLay, pPrv );
+ // --> OD 2005-12-01 #i27138#
+ // notify accessibility paragraphs objects about changed
+ // CONTENT_FLOWS_FROM/_TO relation.
+ // Relation CONTENT_FLOWS_FROM for next paragraph will change
+ // and relation CONTENT_FLOWS_TO for previous paragraph will change.
+ {
+ ViewShell* pViewShell( pFrm->getRootFrm()->GetCurrShell() );
+ // no notification, if <ViewShell> is in construction
+ if ( pViewShell && !pViewShell->IsInConstructor() &&
+ pViewShell->GetLayout() &&
+ pViewShell->GetLayout()->IsAnyShellAccessible() )
+ {
+ pViewShell->InvalidateAccessibleParaFlowRelation(
+ dynamic_cast<SwTxtFrm*>(pFrm->FindNextCnt( true )),
+ dynamic_cast<SwTxtFrm*>(pFrm->FindPrevCnt( true )) );
+ }
+ }
+ // <--
+ if ( bObjsDirect && pTbl->Count() )
+ ((SwTabFrm*)pFrm)->RegistFlys();
+ // OD 12.08.2003 #i17969# - consider horizontal/vertical layout
+ // for setting position at newly inserted frame
+ lcl_SetPos( *pFrm, *pLay );
+
+ pPrv = pFrm;
+ //Index auf den Endnode der Tabellensection setzen.
+ nIndex = pTblNode->EndOfSectionIndex();
+
+ SwTabFrm* pTmpFrm = (SwTabFrm*)pFrm;
+ while ( pTmpFrm )
+ {
+ pTmpFrm->CheckDirChange();
+ pTmpFrm = pTmpFrm->IsFollow() ? pTmpFrm->FindMaster() : NULL;
+ }
+
+ }
+ else if ( pNd->IsSectionNode() )
+ {
+ SwSectionNode *pNode = (SwSectionNode*)pNd;
+ if( pNode->GetSection().CalcHiddenFlag() )
+ // ist versteckt, ueberspringe den Bereich
+ nIndex = pNode->EndOfSectionIndex();
+ else
+ {
+ pFrm = pNode->MakeFrm( pLay );
+ pActualSection = new SwActualSection( pActualSection,
+ (SwSectionFrm*)pFrm, pNode );
+ if ( pActualSection->GetUpper() )
+ {
+ //Hinter den Upper einsetzen, beim EndNode wird der "Follow"
+ //des Uppers erzeugt.
+ SwSectionFrm *pTmp = pActualSection->GetUpper()->GetSectionFrm();
+ pFrm->InsertBehind( pTmp->GetUpper(), pTmp );
+ // OD 25.03.2003 #108339# - direct initialization of section
+ // after insertion in the layout
+ static_cast<SwSectionFrm*>(pFrm)->Init();
+ }
+ else
+ {
+ pFrm->InsertBehind( pLay, pPrv );
+ // OD 25.03.2003 #108339# - direct initialization of section
+ // after insertion in the layout
+ static_cast<SwSectionFrm*>(pFrm)->Init();
+
+ // --> FME 2004-09-08 #i33963#
+ // Do not trust the IsInFtn flag. If we are currently
+ // building up a table, the upper of pPrv may be a cell
+ // frame, but the cell frame does not have an upper yet.
+ if( pPrv && 0 != pPrv->ImplFindFtnFrm() )
+ // <--
+ {
+ if( pPrv->IsSctFrm() )
+ pPrv = ((SwSectionFrm*)pPrv)->ContainsCntnt();
+ if( pPrv && pPrv->IsTxtFrm() )
+ ((SwTxtFrm*)pPrv)->Prepare( PREP_QUOVADIS, 0, sal_False );
+ }
+ }
+ // --> OD 2005-12-01 #i27138#
+ // notify accessibility paragraphs objects about changed
+ // CONTENT_FLOWS_FROM/_TO relation.
+ // Relation CONTENT_FLOWS_FROM for next paragraph will change
+ // and relation CONTENT_FLOWS_TO for previous paragraph will change.
+ {
+ ViewShell* pViewShell( pFrm->getRootFrm()->GetCurrShell() );
+ // no notification, if <ViewShell> is in construction
+ if ( pViewShell && !pViewShell->IsInConstructor() &&
+ pViewShell->GetLayout() &&
+ pViewShell->GetLayout()->IsAnyShellAccessible() )
+ {
+ pViewShell->InvalidateAccessibleParaFlowRelation(
+ dynamic_cast<SwTxtFrm*>(pFrm->FindNextCnt( true )),
+ dynamic_cast<SwTxtFrm*>(pFrm->FindPrevCnt( true )) );
+ }
+ }
+ // <--
+ pFrm->CheckDirChange();
+
+ // OD 12.08.2003 #i17969# - consider horizontal/vertical layout
+ // for setting position at newly inserted frame
+ lcl_SetPos( *pFrm, *pLay );
+
+ // OD 20.11.2002 #105405# - no page, no invalidate.
+ if ( pPage )
+ {
+ // OD 18.09.2002 #100522#
+ // invalidate page in order to force format and paint of
+ // inserted section frame
+ pFrm->InvalidatePage( pPage );
+
+ // FME 10.11.2003 #112243#
+ // Invalidate fly content flag:
+ if ( pFrm->IsInFly() )
+ pPage->InvalidateFlyCntnt();
+
+ // OD 14.11.2002 #104684# - invalidate page content in order to
+ // force format and paint of section content.
+ pPage->InvalidateCntnt();
+ }
+
+ pLay = (SwLayoutFrm*)pFrm;
+ if ( pLay->Lower() && pLay->Lower()->IsLayoutFrm() )
+ pLay = pLay->GetNextLayoutLeaf();
+ pPrv = 0;
+ }
+ }
+ else if ( pNd->IsEndNode() && pNd->StartOfSectionNode()->IsSectionNode() )
+ {
+ OSL_ENSURE( pActualSection, "Sectionende ohne Anfang?" );
+ OSL_ENSURE( pActualSection->GetSectionNode() == pNd->StartOfSectionNode(),
+ "Sectionende mit falschen Start Node?" );
+
+ //Section schliessen, ggf. die umgebende Section wieder
+ //aktivieren.
+ SwActualSection *pTmp = pActualSection->GetUpper();
+ delete pActualSection;
+ pLay = pLay->FindSctFrm();
+ if ( 0 != (pActualSection = pTmp) )
+ {
+ //Koennte noch sein, das der letzte SectionFrm leer geblieben
+ //ist. Dann ist es jetzt an der Zeit ihn zu entfernen.
+ if ( !pLay->ContainsCntnt() )
+ {
+ SwFrm *pTmpFrm = pLay;
+ pLay = pTmpFrm->GetUpper();
+ pPrv = pTmpFrm->GetPrev();
+ pTmpFrm->Remove();
+ delete pTmpFrm;
+ }
+ else
+ {
+ pPrv = pLay;
+ pLay = pLay->GetUpper();
+ }
+
+ // new section frame
+ pFrm = pActualSection->GetSectionNode()->MakeFrm( pLay );
+ pFrm->InsertBehind( pLay, pPrv );
+ static_cast<SwSectionFrm*>(pFrm)->Init();
+
+ // OD 12.08.2003 #i17969# - consider horizontal/vertical layout
+ // for setting position at newly inserted frame
+ lcl_SetPos( *pFrm, *pLay );
+
+ SwSectionFrm* pOuterSectionFrm = pActualSection->GetSectionFrm();
+
+ // a follow has to be appended to the new section frame
+ SwSectionFrm* pFollow = pOuterSectionFrm->GetFollow();
+ if ( pFollow )
+ {
+ pOuterSectionFrm->SetFollow( NULL );
+ pOuterSectionFrm->InvalidateSize();
+ ((SwSectionFrm*)pFrm)->SetFollow( pFollow );
+ }
+
+ // Wir wollen keine leeren Teile zuruecklassen
+ if( ! pOuterSectionFrm->IsColLocked() &&
+ ! pOuterSectionFrm->ContainsCntnt() )
+ {
+ pOuterSectionFrm->DelEmpty( sal_True );
+ delete pOuterSectionFrm;
+ }
+ pActualSection->SetSectionFrm( (SwSectionFrm*)pFrm );
+
+ pLay = (SwLayoutFrm*)pFrm;
+ if ( pLay->Lower() && pLay->Lower()->IsLayoutFrm() )
+ pLay = pLay->GetNextLayoutLeaf();
+ pPrv = 0;
+ }
+ else
+ {
+ //Nix mehr mit Sections, es geht direkt hinter dem SectionFrame
+ //weiter.
+ pPrv = pLay;
+ pLay = pLay->GetUpper();
+ }
+ }
+ else if( pNd->IsStartNode() &&
+ SwFlyStartNode == ((SwStartNode*)pNd)->GetStartNodeType() )
+ {
+ if ( pTbl->Count() && bObjsDirect && !bDontCreateObjects )
+ {
+ SwFlyFrm* pFly = pLay->FindFlyFrm();
+ if( pFly )
+ AppendObjs( pTbl, nIndex, pFly, pPage );
+ }
+ }
+ else
+ // Weder Cntnt noch Tabelle noch Section,
+ // also muessen wir fertig sein.
+ break;
+
+ ++nIndex;
+ // Der Endnode wird nicht mehr mitgenommen, es muss vom
+ // Aufrufenden (Section/MakeFrms()) sichergestellt sein, dass das Ende
+ // des Bereichs vor dem EndIndex liegt!
+ if ( nEndIndex && nIndex >= nEndIndex )
+ break;
+ }
+
+ if ( pActualSection )
+ {
+ //Kann passieren, dass noch eine leere (Follow-)Section uebrig geblieben ist.
+ if ( !(pLay = pActualSection->GetSectionFrm())->ContainsCntnt() )
+ {
+ pLay->Remove();
+ delete pLay;
+ }
+ delete pActualSection;
+ }
+
+ if ( bPages ) //Jetzt noch die Flys verbinden lassen.
+ {
+ if ( !bDontCreateObjects )
+ AppendAllObjs( pTbl, pLayout );
+ bObjsDirect = sal_True;
+ }
+
+ if( pPageMaker )
+ {
+ pPageMaker->CheckFlyCache( pPage );
+ delete pPageMaker;
+ if( pDoc->GetLayoutCache() )
+ {
+#if OSL_DEBUG_LEVEL > 1
+ pDoc->GetLayoutCache()->CompareLayout( *pDoc );
+#endif
+ pDoc->GetLayoutCache()->ClearImpl();
+ }
+ }
+
+ pDoc->UnblockIdling();
+ if( bOldCallbackActionEnabled )
+ pLayout->SetCallbackActionEnabled( bOldCallbackActionEnabled );
+}
+
+
+void MakeFrms( SwDoc *pDoc, const SwNodeIndex &rSttIdx,
+ const SwNodeIndex &rEndIdx )
+{
+ bObjsDirect = sal_False;
+
+ SwNodeIndex aTmp( rSttIdx );
+ sal_uLong nEndIdx = rEndIdx.GetIndex();
+ SwNode* pNd = pDoc->GetNodes().FindPrvNxtFrmNode( aTmp,
+ pDoc->GetNodes()[ nEndIdx-1 ]);
+ if ( pNd )
+ {
+ sal_Bool bApres = aTmp < rSttIdx;
+ SwNode2Layout aNode2Layout( *pNd, rSttIdx.GetIndex() );
+ SwFrm* pFrm;
+ while( 0 != (pFrm = aNode2Layout.NextFrm()) )
+ {
+ SwLayoutFrm *pUpper = pFrm->GetUpper();
+ SwFtnFrm* pFtnFrm = pUpper->FindFtnFrm();
+ sal_Bool bOldLock, bOldFtn;
+ if( pFtnFrm )
+ {
+ bOldFtn = pFtnFrm->IsColLocked();
+ pFtnFrm->ColLock();
+ }
+ else
+ bOldFtn = sal_True;
+ SwSectionFrm* pSct = pUpper->FindSctFrm();
+ // Es sind innerhalb von Fussnoten nur die Bereiche interessant,
+ // die in den Fussnoten liegen, nicht etwa die (spaltigen) Bereiche,
+ // in denen die Fussnoten(Container) liegen.
+ // #109767# Table frame is in section, insert section in cell frame.
+ if( pSct && ((pFtnFrm && !pSct->IsInFtn()) || pUpper->IsCellFrm()) )
+ pSct = NULL;
+ if( pSct )
+ { // damit der SectionFrm nicht zerstoert wird durch pTmp->MoveFwd()
+ bOldLock = pSct->IsColLocked();
+ pSct->ColLock();
+ }
+ else
+ bOldLock = sal_True;
+
+ // Wenn pFrm sich nicht bewegen kann, koennen wir auch niemanden
+ // auf die naechste Seite schieben. Innerhalb eines Rahmens auch
+ // nicht ( in der 1. Spalte eines Rahmens waere pFrm Moveable()! )
+ // Auch in spaltigen Bereichen in Tabellen waere pFrm Moveable.
+ sal_Bool bMoveNext = nEndIdx - rSttIdx.GetIndex() > 120;
+ sal_Bool bAllowMove = !pFrm->IsInFly() && pFrm->IsMoveable() &&
+ (!pFrm->IsInTab() || pFrm->IsTabFrm() );
+ if ( bMoveNext && bAllowMove )
+ {
+ SwFrm *pMove = pFrm;
+ SwFrm *pPrev = pFrm->GetPrev();
+ SwFlowFrm *pTmp = SwFlowFrm::CastFlowFrm( pMove );
+ OSL_ENSURE( pTmp, "Missing FlowFrm" );
+
+ if ( bApres )
+ {
+ // Wir wollen, dass der Rest der Seite leer ist, d.h.
+ // der naechste muss auf die naechste Seite wandern.
+ // Dieser kann auch in der naechsten Spalte stehen!
+ OSL_ENSURE( !pTmp->HasFollow(), "Follows forbidden" );
+ pPrev = pFrm;
+ // Wenn unser umgebender SectionFrm einen Next besitzt,
+ // so soll dieser ebenfalls gemoved werden!
+ pMove = pFrm->GetIndNext();
+ SwColumnFrm* pCol = (SwColumnFrm*)pFrm->FindColFrm();
+ if( pCol )
+ pCol = (SwColumnFrm*)pCol->GetNext();
+ do
+ {
+ if( pCol && !pMove )
+ { // Bisher haben wir keinen Nachfolger gefunden
+ // jetzt gucken wir in die naechste Spalte
+ pMove = pCol->ContainsAny();
+ if( pCol->GetNext() )
+ pCol = (SwColumnFrm*)pCol->GetNext();
+ else if( pCol->IsInSct() )
+ { // Wenn es keine naechste Spalte gibt, wir aber
+ // innerhalb eines spaltigen Bereichs sind,
+ // koennte es noch ausserhalb des Bereich
+ // (Seiten-)Spalten geben
+ pCol = (SwColumnFrm*)pCol->FindSctFrm()->FindColFrm();
+ if( pCol )
+ pCol = (SwColumnFrm*)pCol->GetNext();
+ }
+ else
+ pCol = NULL;
+ }
+ // Falls hier verschrottete SectionFrms herumgammeln,
+ // muessen diese uebersprungen werden.
+ while( pMove && pMove->IsSctFrm() &&
+ !((SwSectionFrm*)pMove)->GetSection() )
+ pMove = pMove->GetNext();
+ } while( !pMove && pCol );
+
+ if( pMove )
+ {
+ if ( pMove->IsCntntFrm() )
+ pTmp = (SwCntntFrm*)pMove;
+ else if ( pMove->IsTabFrm() )
+ pTmp = (SwTabFrm*)pMove;
+ else if ( pMove->IsSctFrm() )
+ {
+ pMove = ((SwSectionFrm*)pMove)->ContainsAny();
+ if( pMove )
+ pTmp = SwFlowFrm::CastFlowFrm( pMove );
+ else
+ pTmp = NULL;
+ }
+ }
+ else
+ pTmp = 0;
+ }
+ else
+ {
+ OSL_ENSURE( !pTmp->IsFollow(), "Follows really forbidden" );
+ // Bei Bereichen muss natuerlich der Inhalt auf die Reise
+ // geschickt werden.
+ if( pMove->IsSctFrm() )
+ {
+ while( pMove && pMove->IsSctFrm() &&
+ !((SwSectionFrm*)pMove)->GetSection() )
+ pMove = pMove->GetNext();
+ if( pMove && pMove->IsSctFrm() )
+ pMove = ((SwSectionFrm*)pMove)->ContainsAny();
+ if( pMove )
+ pTmp = SwFlowFrm::CastFlowFrm( pMove );
+ else
+ pTmp = NULL;
+ }
+ }
+
+ if( pTmp )
+ {
+ SwFrm* pOldUp = pTmp->GetFrm()->GetUpper();
+ // MoveFwd==sal_True bedeutet, dass wir auf der gleichen
+ // Seite geblieben sind, wir wollen aber die Seite wechseln,
+ // sofern dies moeglich ist
+ sal_Bool bTmpOldLock = pTmp->IsJoinLocked();
+ pTmp->LockJoin();
+ while( pTmp->MoveFwd( sal_True, sal_False, sal_True ) )
+ {
+ if( pOldUp == pTmp->GetFrm()->GetUpper() )
+ break;
+ pOldUp = pTmp->GetFrm()->GetUpper();
+ }
+ if( !bTmpOldLock )
+ pTmp->UnlockJoin();
+ }
+ ::_InsertCnt( pUpper, pDoc, rSttIdx.GetIndex(),
+ pFrm->IsInDocBody(), nEndIdx, pPrev );
+ }
+ else
+ {
+ sal_Bool bSplit;
+ SwFrm* pPrv = bApres ? pFrm : pFrm->GetPrev();
+ // Wenn in einen SectionFrm ein anderer eingefuegt wird,
+ // muss dieser aufgebrochen werden
+ if( pSct && rSttIdx.GetNode().IsSectionNode() )
+ {
+ bSplit = pSct->SplitSect( pFrm, bApres );
+ // Wenn pSct nicht aufgespalten werden konnte
+ if( !bSplit && !bApres )
+ {
+ pUpper = pSct->GetUpper();
+ pPrv = pSct->GetPrev();
+ }
+ }
+ else
+ bSplit = sal_False;
+ ::_InsertCnt( pUpper, pDoc, rSttIdx.GetIndex(), sal_False,
+ nEndIdx, pPrv );
+ // OD 23.06.2003 #108784# - correction: append objects doesn't
+ // depend on value of <bAllowMove>
+ if( !bDontCreateObjects )
+ {
+ const SwSpzFrmFmts *pTbl = pDoc->GetSpzFrmFmts();
+ if( pTbl->Count() )
+ AppendAllObjs( pTbl, pUpper );
+ }
+
+ // Wenn nichts eingefuegt wurde, z.B. ein ausgeblendeter Bereich,
+ // muss das Splitten rueckgaengig gemacht werden
+ if( bSplit && pSct && pSct->GetNext()
+ && pSct->GetNext()->IsSctFrm() )
+ pSct->MergeNext( (SwSectionFrm*)pSct->GetNext() );
+ if( pFrm->IsInFly() )
+ pFrm->FindFlyFrm()->_Invalidate();
+ if( pFrm->IsInTab() )
+ pFrm->InvalidateSize();
+ }
+
+ SwPageFrm *pPage = pUpper->FindPageFrm();
+ SwFrm::CheckPageDescs( pPage, sal_False );
+ if( !bOldFtn )
+ pFtnFrm->ColUnlock();
+ if( !bOldLock )
+ {
+ pSct->ColUnlock();
+ // Zum Beispiel beim Einfuegen von gelinkten Bereichen,
+ // die wiederum Bereiche enthalten, kann pSct jetzt leer sein
+ // und damit ruhig zerstoert werden.
+ if( !pSct->ContainsCntnt() )
+ {
+ pSct->DelEmpty( sal_True );
+ pUpper->getRootFrm()->RemoveFromList( pSct );
+ delete pSct;
+ }
+ }
+ }
+ }
+
+ bObjsDirect = sal_True;
+}
+
+
+/*************************************************************************/
+
+SwBorderAttrs::SwBorderAttrs( const SwModify *pMod, const SwFrm *pConstructor ) :
+ SwCacheObj( pMod ),
+ rAttrSet( pConstructor->IsCntntFrm()
+ ? ((SwCntntFrm*)pConstructor)->GetNode()->GetSwAttrSet()
+ : ((SwLayoutFrm*)pConstructor)->GetFmt()->GetAttrSet() ),
+ rUL ( rAttrSet.GetULSpace() ),
+ // --> OD 2008-12-04 #i96772#
+ // LRSpaceItem is copied due to the possibility that it is adjusted - see below
+ rLR ( rAttrSet.GetLRSpace() ),
+ // <--
+ rBox ( rAttrSet.GetBox() ),
+ rShadow ( rAttrSet.GetShadow() ),
+ aFrmSize( rAttrSet.GetFrmSize().GetSize() )
+{
+ // --> OD 2008-12-02 #i96772#
+ const SwTxtFrm* pTxtFrm = dynamic_cast<const SwTxtFrm*>(pConstructor);
+ if ( pTxtFrm )
+ {
+ pTxtFrm->GetTxtNode()->ClearLRSpaceItemDueToListLevelIndents( rLR );
+ }
+
+ //Achtung: Die USHORTs fuer die gecache'ten Werte werden absichtlich
+ //nicht initialisiert!
+
+ //Muessen alle einmal berechnet werden:
+ bTopLine = bBottomLine = bLeftLine = bRightLine =
+ bTop = bBottom = bLine = sal_True;
+
+ bCacheGetLine = bCachedGetTopLine = bCachedGetBottomLine = sal_False;
+ // OD 21.05.2003 #108789# - init cache status for values <bJoinedWithPrev>
+ // and <bJoinedWithNext>, which aren't initialized by default.
+ bCachedJoinedWithPrev = sal_False;
+ bCachedJoinedWithNext = sal_False;
+
+ bBorderDist = 0 != (pConstructor->GetType() & (FRM_CELL));
+}
+
+SwBorderAttrs::~SwBorderAttrs()
+{
+ ((SwModify*)pOwner)->SetInCache( sal_False );
+}
+
+/*************************************************************************
+|*
+|* SwBorderAttrs::CalcTop(), CalcBottom(), CalcLeft(), CalcRight()
+|*
+|* Beschreibung Die Calc-Methoden errechnen zusaetzlich zu den
+|* von den Attributen vorgegebenen Groessen einen Sicherheitsabstand.
+|* der Sicherheitsabstand wird nur einkalkuliert, wenn Umrandung und/oder
+|* Schatten im Spiel sind; er soll vermeiden, dass aufgrund der
+|* groben physikalischen Gegebenheiten Raender usw. uebermalt werden.
+|*
+|*************************************************************************/
+
+void SwBorderAttrs::_CalcTop()
+{
+ nTop = CalcTopLine() + rUL.GetUpper();
+ bTop = sal_False;
+}
+
+void SwBorderAttrs::_CalcBottom()
+{
+ nBottom = CalcBottomLine() + rUL.GetLower();
+ bBottom = sal_False;
+}
+
+long SwBorderAttrs::CalcRight( const SwFrm* pCaller ) const
+{
+ long nRight=0;
+
+ if (!pCaller->IsTxtFrm() || !((SwTxtFrm*)pCaller)->GetTxtNode()->GetDoc()->get(IDocumentSettingAccess::INVERT_BORDER_SPACING)) {
+ // OD 23.01.2003 #106895# - for cell frame in R2L text direction the left
+ // and right border are painted on the right respectively left.
+ if ( pCaller->IsCellFrm() && pCaller->IsRightToLeft() )
+ nRight = CalcLeftLine();
+ else
+ nRight = CalcRightLine();
+
+ }
+ // for paragraphs, "left" is "before text" and "right" is "after text"
+ if ( pCaller->IsTxtFrm() && pCaller->IsRightToLeft() )
+ nRight += rLR.GetLeft();
+ else
+ nRight += rLR.GetRight();
+
+ // correction: retrieve left margin for numbering in R2L-layout
+ if ( pCaller->IsTxtFrm() && pCaller->IsRightToLeft() )
+ {
+ nRight += ((SwTxtFrm*)pCaller)->GetTxtNode()->GetLeftMarginWithNum();
+ }
+
+ return nRight;
+}
+
+long SwBorderAttrs::CalcLeft( const SwFrm *pCaller ) const
+{
+ long nLeft=0;
+
+ if (!pCaller->IsTxtFrm() || !((SwTxtFrm*)pCaller)->GetTxtNode()->GetDoc()->get(IDocumentSettingAccess::INVERT_BORDER_SPACING)) {
+ // OD 23.01.2003 #106895# - for cell frame in R2L text direction the left
+ // and right border are painted on the right respectively left.
+ if ( pCaller->IsCellFrm() && pCaller->IsRightToLeft() )
+ nLeft = CalcRightLine();
+ else
+ nLeft = CalcLeftLine();
+ }
+
+ // for paragraphs, "left" is "before text" and "right" is "after text"
+ if ( pCaller->IsTxtFrm() && pCaller->IsRightToLeft() )
+ nLeft += rLR.GetRight();
+ else
+ nLeft += rLR.GetLeft();
+
+
+ // correction: do not retrieve left margin for numbering in R2L-layout
+// if ( pCaller->IsTxtFrm() )
+ if ( pCaller->IsTxtFrm() && !pCaller->IsRightToLeft() )
+ {
+ nLeft += ((SwTxtFrm*)pCaller)->GetTxtNode()->GetLeftMarginWithNum();
+ }
+
+ return nLeft;
+}
+
+/*************************************************************************
+|*
+|* SwBorderAttrs::CalcTopLine(), CalcBottomLine(),
+|* CalcLeftLine(), CalcRightLine()
+|*
+|* Beschreibung Berechnung der Groessen fuer Umrandung und Schatten.
+|* Es kann auch ohne Linien ein Abstand erwuenscht sein,
+|* dieser wird dann nicht vom Attribut sondern hier
+|* beruecksichtigt (bBorderDist, z.B. fuer Zellen).
+|*
+|*************************************************************************/
+
+void SwBorderAttrs::_CalcTopLine()
+{
+ nTopLine = (bBorderDist && !rBox.GetTop())
+ ? rBox.GetDistance (BOX_LINE_TOP)
+ : rBox.CalcLineSpace(BOX_LINE_TOP);
+ nTopLine = nTopLine + rShadow.CalcShadowSpace(SHADOW_TOP);
+ bTopLine = sal_False;
+}
+
+void SwBorderAttrs::_CalcBottomLine()
+{
+ nBottomLine = (bBorderDist && !rBox.GetBottom())
+ ? rBox.GetDistance (BOX_LINE_BOTTOM)
+ : rBox.CalcLineSpace(BOX_LINE_BOTTOM);
+ nBottomLine = nBottomLine + rShadow.CalcShadowSpace(SHADOW_BOTTOM);
+ bBottomLine = sal_False;
+}
+
+void SwBorderAttrs::_CalcLeftLine()
+{
+ nLeftLine = (bBorderDist && !rBox.GetLeft())
+ ? rBox.GetDistance (BOX_LINE_LEFT)
+ : rBox.CalcLineSpace(BOX_LINE_LEFT);
+ nLeftLine = nLeftLine + rShadow.CalcShadowSpace(SHADOW_LEFT);
+ bLeftLine = sal_False;
+}
+
+void SwBorderAttrs::_CalcRightLine()
+{
+ nRightLine = (bBorderDist && !rBox.GetRight())
+ ? rBox.GetDistance (BOX_LINE_RIGHT)
+ : rBox.CalcLineSpace(BOX_LINE_RIGHT);
+ nRightLine = nRightLine + rShadow.CalcShadowSpace(SHADOW_RIGHT);
+ bRightLine = sal_False;
+}
+
+/*************************************************************************/
+
+void SwBorderAttrs::_IsLine()
+{
+ bIsLine = rBox.GetTop() || rBox.GetBottom() ||
+ rBox.GetLeft()|| rBox.GetRight();
+ bLine = sal_False;
+}
+
+/*************************************************************************
+|*
+|* SwBorderAttrs::CmpLeftRightLine(), IsTopLine(), IsBottomLine()
+|*
+|* Die Umrandungen benachbarter Absaetze werden nach folgendem
+|* Algorithmus zusammengefasst:
+|*
+|* 1. Die Umrandung oben faellt weg, wenn der Vorgaenger dieselbe
+|* Umrandung oben aufweist und 3. Zutrifft.
+|* Zusaetzlich muss der Absatz mindestens rechts oder links oder
+|* unten eine Umrandung haben.
+|* 2. Die Umrandung unten faellt weg, wenn der Nachfolger dieselbe
+|* Umrandung untern aufweist und 3. Zustrifft.
+|* Zusaetzlich muss der Absatz mindestens rechts oder links oder
+|* oben eine Umrandung haben.
+|* 3. Die Umrandungen links und rechts vor Vorgaenger bzw. Nachfolger
+|* sind identisch.
+|*
+|*************************************************************************/
+inline int CmpLines( const editeng::SvxBorderLine *pL1, const editeng::SvxBorderLine *pL2 )
+{
+ return ( ((pL1 && pL2) && (*pL1 == *pL2)) || (!pL1 && !pL2) );
+}
+
+// OD 21.05.2003 #108789# - change name of 1st parameter - "rAttrs" -> "rCmpAttrs"
+// OD 21.05.2003 #108789# - compare <CalcRight()> and <rCmpAttrs.CalcRight()>
+// instead of only the right LR-spacing, because R2L-layout has to be
+// considered.
+sal_Bool SwBorderAttrs::CmpLeftRight( const SwBorderAttrs &rCmpAttrs,
+ const SwFrm *pCaller,
+ const SwFrm *pCmp ) const
+{
+ return ( CmpLines( rCmpAttrs.GetBox().GetLeft(), GetBox().GetLeft() ) &&
+ CmpLines( rCmpAttrs.GetBox().GetRight(),GetBox().GetRight() ) &&
+ CalcLeft( pCaller ) == rCmpAttrs.CalcLeft( pCmp ) &&
+ // OD 21.05.2003 #108789# - compare <CalcRight> with <rCmpAttrs.CalcRight>.
+ CalcRight( pCaller ) == rCmpAttrs.CalcRight( pCmp ) );
+}
+
+sal_Bool SwBorderAttrs::_JoinWithCmp( const SwFrm& _rCallerFrm,
+ const SwFrm& _rCmpFrm ) const
+{
+ sal_Bool bReturnVal = sal_False;
+
+ SwBorderAttrAccess aCmpAccess( SwFrm::GetCache(), &_rCmpFrm );
+ const SwBorderAttrs &rCmpAttrs = *aCmpAccess.Get();
+ if ( rShadow == rCmpAttrs.GetShadow() &&
+ CmpLines( rBox.GetTop(), rCmpAttrs.GetBox().GetTop() ) &&
+ CmpLines( rBox.GetBottom(), rCmpAttrs.GetBox().GetBottom() ) &&
+ CmpLeftRight( rCmpAttrs, &_rCallerFrm, &_rCmpFrm )
+ )
+ {
+ bReturnVal = sal_True;
+ }
+
+ return bReturnVal;
+}
+
+// OD 21.05.2003 #108789# - method to determine, if borders are joined with
+// previous frame. Calculated value saved in cached value <bJoinedWithPrev>
+// OD 2004-02-26 #i25029# - add 2nd parameter <_pPrevFrm>
+void SwBorderAttrs::_CalcJoinedWithPrev( const SwFrm& _rFrm,
+ const SwFrm* _pPrevFrm )
+{
+ // set default
+ bJoinedWithPrev = sal_False;
+
+ if ( _rFrm.IsTxtFrm() )
+ {
+ // text frame can potentially join with previous text frame, if
+ // corresponding attribute set is set at previous text frame.
+ // OD 2004-02-26 #i25029# - If parameter <_pPrevFrm> is set, take this
+ // one as previous frame.
+ const SwFrm* pPrevFrm = _pPrevFrm ? _pPrevFrm : _rFrm.GetPrev();
+ // OD 2004-02-13 #i25029# - skip hidden text frames.
+ while ( pPrevFrm && pPrevFrm->IsTxtFrm() &&
+ static_cast<const SwTxtFrm*>(pPrevFrm)->IsHiddenNow() )
+ {
+ pPrevFrm = pPrevFrm->GetPrev();
+ }
+ if ( pPrevFrm && pPrevFrm->IsTxtFrm() &&
+ pPrevFrm->GetAttrSet()->GetParaConnectBorder().GetValue()
+ )
+ {
+ bJoinedWithPrev = _JoinWithCmp( _rFrm, *(pPrevFrm) );
+ }
+ }
+
+ // valid cache status, if demanded
+ // OD 2004-02-26 #i25029# - Do not validate cache, if parameter <_pPrevFrm>
+ // is set.
+ bCachedJoinedWithPrev = bCacheGetLine && !_pPrevFrm;
+}
+
+// OD 21.05.2003 #108789# - method to determine, if borders are joined with
+// next frame. Calculated value saved in cached value <bJoinedWithNext>
+void SwBorderAttrs::_CalcJoinedWithNext( const SwFrm& _rFrm )
+{
+ // set default
+ bJoinedWithNext = sal_False;
+
+ if ( _rFrm.IsTxtFrm() )
+ {
+ // text frame can potentially join with next text frame, if
+ // corresponding attribute set is set at current text frame.
+ // OD 2004-02-13 #i25029# - get next frame, but skip hidden text frames.
+ const SwFrm* pNextFrm = _rFrm.GetNext();
+ while ( pNextFrm && pNextFrm->IsTxtFrm() &&
+ static_cast<const SwTxtFrm*>(pNextFrm)->IsHiddenNow() )
+ {
+ pNextFrm = pNextFrm->GetNext();
+ }
+ if ( pNextFrm && pNextFrm->IsTxtFrm() &&
+ _rFrm.GetAttrSet()->GetParaConnectBorder().GetValue()
+ )
+ {
+ bJoinedWithNext = _JoinWithCmp( _rFrm, *(pNextFrm) );
+ }
+ }
+
+ // valid cache status, if demanded
+ bCachedJoinedWithNext = bCacheGetLine;
+}
+
+// OD 21.05.2003 #108789# - accessor for cached values <bJoinedWithPrev>
+// OD 2004-02-26 #i25029# - add 2nd parameter <_pPrevFrm>, which is passed to
+// method <_CalcJoindWithPrev(..)>.
+sal_Bool SwBorderAttrs::JoinedWithPrev( const SwFrm& _rFrm,
+ const SwFrm* _pPrevFrm ) const
+{
+ if ( !bCachedJoinedWithPrev || _pPrevFrm )
+ {
+ // OD 2004-02-26 #i25029# - pass <_pPrevFrm> as 2nd parameter
+ const_cast<SwBorderAttrs*>(this)->_CalcJoinedWithPrev( _rFrm, _pPrevFrm );
+ }
+
+ return bJoinedWithPrev;
+}
+
+sal_Bool SwBorderAttrs::JoinedWithNext( const SwFrm& _rFrm ) const
+{
+ if ( !bCachedJoinedWithNext )
+ {
+ const_cast<SwBorderAttrs*>(this)->_CalcJoinedWithNext( _rFrm );
+ }
+
+ return bJoinedWithNext;
+}
+
+// OD 2004-02-26 #i25029# - added 2nd parameter <_pPrevFrm>, which is passed to
+// method <JoinedWithPrev>
+void SwBorderAttrs::_GetTopLine( const SwFrm& _rFrm,
+ const SwFrm* _pPrevFrm )
+{
+ sal_uInt16 nRet = CalcTopLine();
+
+ // OD 21.05.2003 #108789# - use new method <JoinWithPrev()>
+ // OD 2004-02-26 #i25029# - add 2nd parameter
+ if ( JoinedWithPrev( _rFrm, _pPrevFrm ) )
+ {
+ nRet = 0;
+ }
+
+ bCachedGetTopLine = bCacheGetLine;
+
+ nGetTopLine = nRet;
+}
+
+void SwBorderAttrs::_GetBottomLine( const SwFrm& _rFrm )
+{
+ sal_uInt16 nRet = CalcBottomLine();
+
+ // OD 21.05.2003 #108789# - use new method <JoinWithPrev()>
+ if ( JoinedWithNext( _rFrm ) )
+ {
+ nRet = 0;
+ }
+
+ bCachedGetBottomLine = bCacheGetLine;
+
+ nGetBottomLine = nRet;
+}
+
+/*************************************************************************/
+
+SwBorderAttrAccess::SwBorderAttrAccess( SwCache &rCach, const SwFrm *pFrm ) :
+ SwCacheAccess( rCach, (pFrm->IsCntntFrm() ?
+ (void*)((SwCntntFrm*)pFrm)->GetNode() :
+ (void*)((SwLayoutFrm*)pFrm)->GetFmt()),
+ (sal_Bool)(pFrm->IsCntntFrm() ?
+ ((SwModify*)((SwCntntFrm*)pFrm)->GetNode())->IsInCache() :
+ ((SwModify*)((SwLayoutFrm*)pFrm)->GetFmt())->IsInCache()) ),
+ pConstructor( pFrm )
+{
+}
+
+/*************************************************************************/
+
+SwCacheObj *SwBorderAttrAccess::NewObj()
+{
+ ((SwModify*)pOwner)->SetInCache( sal_True );
+ return new SwBorderAttrs( (SwModify*)pOwner, pConstructor );
+}
+
+SwBorderAttrs *SwBorderAttrAccess::Get()
+{
+ return (SwBorderAttrs*)SwCacheAccess::Get();
+}
+
+/*************************************************************************/
+
+SwOrderIter::SwOrderIter( const SwPageFrm *pPg, sal_Bool bFlys ) :
+ pPage( pPg ),
+ pCurrent( 0 ),
+ bFlysOnly( bFlys )
+{
+}
+
+/*************************************************************************/
+
+const SdrObject *SwOrderIter::Top()
+{
+ pCurrent = 0;
+ if ( pPage->GetSortedObjs() )
+ {
+ const SwSortedObjs *pObjs = pPage->GetSortedObjs();
+ if ( pObjs->Count() )
+ {
+ sal_uInt32 nTopOrd = 0;
+ (*pObjs)[0]->GetDrawObj()->GetOrdNum(); //Aktualisieren erzwingen!
+ for ( sal_uInt16 i = 0; i < pObjs->Count(); ++i )
+ {
+ const SdrObject* pObj = (*pObjs)[i]->GetDrawObj();
+ if ( bFlysOnly && !pObj->ISA(SwVirtFlyDrawObj) )
+ continue;
+ sal_uInt32 nTmp = pObj->GetOrdNumDirect();
+ if ( nTmp >= nTopOrd )
+ {
+ nTopOrd = nTmp;
+ pCurrent = pObj;
+ }
+ }
+ }
+ }
+ return pCurrent;
+}
+
+/*************************************************************************/
+
+const SdrObject *SwOrderIter::Bottom()
+{
+ pCurrent = 0;
+ if ( pPage->GetSortedObjs() )
+ {
+ sal_uInt32 nBotOrd = USHRT_MAX;
+ const SwSortedObjs *pObjs = pPage->GetSortedObjs();
+ if ( pObjs->Count() )
+ {
+ (*pObjs)[0]->GetDrawObj()->GetOrdNum(); //Aktualisieren erzwingen!
+ for ( sal_uInt16 i = 0; i < pObjs->Count(); ++i )
+ {
+ const SdrObject* pObj = (*pObjs)[i]->GetDrawObj();
+ if ( bFlysOnly && !pObj->ISA(SwVirtFlyDrawObj) )
+ continue;
+ sal_uInt32 nTmp = pObj->GetOrdNumDirect();
+ if ( nTmp < nBotOrd )
+ {
+ nBotOrd = nTmp;
+ pCurrent = pObj;
+ }
+ }
+ }
+ }
+ return pCurrent;
+}
+
+/*************************************************************************/
+
+const SdrObject *SwOrderIter::Next()
+{
+ const sal_uInt32 nCurOrd = pCurrent ? pCurrent->GetOrdNumDirect() : 0;
+ pCurrent = 0;
+ if ( pPage->GetSortedObjs() )
+ {
+ sal_uInt32 nOrd = USHRT_MAX;
+ const SwSortedObjs *pObjs = pPage->GetSortedObjs();
+ if ( pObjs->Count() )
+ {
+ (*pObjs)[0]->GetDrawObj()->GetOrdNum(); //Aktualisieren erzwingen!
+ for ( sal_uInt16 i = 0; i < pObjs->Count(); ++i )
+ {
+ const SdrObject* pObj = (*pObjs)[i]->GetDrawObj();
+ if ( bFlysOnly && !pObj->ISA(SwVirtFlyDrawObj) )
+ continue;
+ sal_uInt32 nTmp = pObj->GetOrdNumDirect();
+ if ( nTmp > nCurOrd && nTmp < nOrd )
+ {
+ nOrd = nTmp;
+ pCurrent = pObj;
+ }
+ }
+ }
+ }
+ return pCurrent;
+}
+
+/*************************************************************************/
+
+const SdrObject *SwOrderIter::Prev()
+{
+ const sal_uInt32 nCurOrd = pCurrent ? pCurrent->GetOrdNumDirect() : 0;
+ pCurrent = 0;
+ if ( pPage->GetSortedObjs() )
+ {
+ const SwSortedObjs *pObjs = pPage->GetSortedObjs();
+ if ( pObjs->Count() )
+ {
+ sal_uInt32 nOrd = 0;
+ (*pObjs)[0]->GetDrawObj()->GetOrdNum(); //Aktualisieren erzwingen!
+ for ( sal_uInt16 i = 0; i < pObjs->Count(); ++i )
+ {
+ const SdrObject* pObj = (*pObjs)[i]->GetDrawObj();
+ if ( bFlysOnly && !pObj->ISA(SwVirtFlyDrawObj) )
+ continue;
+ sal_uInt32 nTmp = pObj->GetOrdNumDirect();
+ if ( nTmp < nCurOrd && nTmp >= nOrd )
+ {
+ nOrd = nTmp;
+ pCurrent = pObj;
+ }
+ }
+ }
+ }
+ return pCurrent;
+}
+
+/*************************************************************************/
+
+//Unterstruktur eines LayoutFrms fuer eine Aktion aufheben und wieder
+//restaurieren.
+//Neuer Algorithmus: Es ist unuetz jeden Nachbarn einzeln zu betrachten und
+//die Pointer sauber zu setzen (Upper, Nachbarn, usw.)
+//Es reicht vollkommen jeweils eine Einzelkette zu loesen, und mit dem
+//Letzen der Einzelkette nachzuschauen ob noch eine weitere Kette
+//angeheangt werden muss. Es brauchen nur die Pointer korrigiert werden,
+//die zur Verkettung notwendig sind. So koennen Beipspielsweise die Pointer
+//auf die Upper auf den alten Uppern stehenbleiben. Korrigiert werden die
+//Pointer dann im RestoreCntnt. Zwischenzeitlich ist sowieso jeder Zugriff
+//verboten.
+//Unterwegs werden die Flys bei der Seite abgemeldet.
+
+// --> OD 2004-11-29 #115759# - 'remove' also drawing object from page and
+// at-fly anchored objects from page
+void MA_FASTCALL lcl_RemoveObjsFromPage( SwFrm* _pFrm )
+{
+ OSL_ENSURE( _pFrm->GetDrawObjs(), "Keine DrawObjs fuer lcl_RemoveFlysFromPage." );
+ SwSortedObjs &rObjs = *_pFrm->GetDrawObjs();
+ for ( sal_uInt16 i = 0; i < rObjs.Count(); ++i )
+ {
+ SwAnchoredObject* pObj = rObjs[i];
+ // --> OD 2004-11-29 #115759# - reset member, at which the anchored
+ // object orients its vertical position
+ pObj->ClearVertPosOrientFrm();
+ // <--
+ // --> OD 2005-03-03 #i43913#
+ pObj->ResetLayoutProcessBools();
+ // <--
+ // --> OD 2004-11-29 #115759# - remove also lower objects of as-character
+ // anchored Writer fly frames from page
+ if ( pObj->ISA(SwFlyFrm) )
+ {
+ SwFlyFrm* pFlyFrm = static_cast<SwFlyFrm*>(pObj);
+
+ // --> OD 2004-11-29 #115759# - remove also direct lowers of Writer
+ // fly frame from page
+ if ( pFlyFrm->GetDrawObjs() )
+ {
+ ::lcl_RemoveObjsFromPage( pFlyFrm );
+ }
+ // <--
+
+ SwCntntFrm* pCnt = pFlyFrm->ContainsCntnt();
+ while ( pCnt )
+ {
+ if ( pCnt->GetDrawObjs() )
+ ::lcl_RemoveObjsFromPage( pCnt );
+ pCnt = pCnt->GetNextCntntFrm();
+ }
+ if ( pFlyFrm->IsFlyFreeFrm() )
+ {
+ // --> OD 2004-06-30 #i28701# - use new method <GetPageFrm()>
+ pFlyFrm->GetPageFrm()->RemoveFlyFromPage( pFlyFrm );
+ }
+ }
+ // <--
+ // --> OD 2004-11-29 #115759# - remove also drawing objects from page
+ else if ( pObj->ISA(SwAnchoredDrawObject) )
+ {
+ if (pObj->GetFrmFmt().GetAnchor().GetAnchorId() != FLY_AS_CHAR)
+ {
+ pObj->GetPageFrm()->RemoveDrawObjFromPage(
+ *(static_cast<SwAnchoredDrawObject*>(pObj)) );
+ }
+ }
+ // <--
+ }
+}
+
+SwFrm *SaveCntnt( SwLayoutFrm *pLay, SwFrm *pStart )
+{
+ if( pLay->IsSctFrm() && pLay->Lower() && pLay->Lower()->IsColumnFrm() )
+ lcl_RemoveFtns( (SwColumnFrm*)pLay->Lower(), sal_True, sal_True );
+
+ SwFrm *pSav;
+ if ( 0 == (pSav = pLay->ContainsAny()) )
+ return 0;
+
+ if( pSav->IsInFtn() && !pLay->IsInFtn() )
+ {
+ do
+ pSav = pSav->FindNext();
+ while( pSav && pSav->IsInFtn() );
+ if( !pSav || !pLay->IsAnLower( pSav ) )
+ return NULL;
+ }
+
+ // Tables should be saved as a whole, expection:
+ // The contents of a section or a cell inside a table should be saved
+ if ( pSav->IsInTab() && !( ( pLay->IsSctFrm() || pLay->IsCellFrm() ) && pLay->IsInTab() ) )
+ while ( !pSav->IsTabFrm() )
+ pSav = pSav->GetUpper();
+
+ if( pSav->IsInSct() )
+ { // Jetzt wird der oberste Bereich gesucht, der innerhalb von pLay ist.
+ SwFrm* pSect = pLay->FindSctFrm();
+ SwFrm *pTmp = pSav;
+ do
+ {
+ pSav = pTmp;
+ pTmp = pSav->GetUpper() ? pSav->GetUpper()->FindSctFrm() : NULL;
+ } while ( pTmp != pSect );
+ }
+
+ SwFrm *pFloat = pSav;
+ if( !pStart )
+ pStart = pSav;
+ sal_Bool bGo = pStart == pSav;
+ do
+ {
+ if( bGo )
+ pFloat->GetUpper()->pLower = 0; //Die Teilkette ausklinken.
+
+ //Das Ende der Teilkette suchen, unterwegs die Flys abmelden.
+ do
+ {
+ if( bGo )
+ {
+ if ( pFloat->IsCntntFrm() )
+ {
+ if ( pFloat->GetDrawObjs() )
+ ::lcl_RemoveObjsFromPage( (SwCntntFrm*)pFloat );
+ }
+ else if ( pFloat->IsTabFrm() || pFloat->IsSctFrm() )
+ {
+ SwCntntFrm *pCnt = ((SwLayoutFrm*)pFloat)->ContainsCntnt();
+ if( pCnt )
+ {
+ do
+ { if ( pCnt->GetDrawObjs() )
+ ::lcl_RemoveObjsFromPage( pCnt );
+ pCnt = pCnt->GetNextCntntFrm();
+ } while ( pCnt && ((SwLayoutFrm*)pFloat)->IsAnLower( pCnt ) );
+ }
+ }
+ else {
+ OSL_ENSURE( !pFloat, "Neuer Float-Frame?" );
+ }
+ }
+ if ( pFloat->GetNext() )
+ {
+ if( bGo )
+ pFloat->pUpper = NULL;
+ pFloat = pFloat->GetNext();
+ if( !bGo && pFloat == pStart )
+ {
+ bGo = sal_True;
+ pFloat->pPrev->pNext = NULL;
+ pFloat->pPrev = NULL;
+ }
+ }
+ else
+ break;
+
+ } while ( pFloat );
+
+ //Die naechste Teilkette suchen und die Ketten miteinander verbinden.
+ SwFrm *pTmp = pFloat->FindNext();
+ if( bGo )
+ pFloat->pUpper = NULL;
+
+ if( !pLay->IsInFtn() )
+ while( pTmp && pTmp->IsInFtn() )
+ pTmp = pTmp->FindNext();
+
+ if ( !pLay->IsAnLower( pTmp ) )
+ pTmp = 0;
+
+ if ( pTmp && bGo )
+ {
+ pFloat->pNext = pTmp; //Die beiden Ketten verbinden.
+ pFloat->pNext->pPrev = pFloat;
+ }
+ pFloat = pTmp;
+ bGo = bGo || ( pStart == pFloat );
+ } while ( pFloat );
+
+ return bGo ? pStart : NULL;
+}
+
+// --> OD 2004-11-29 #115759# - add also drawing objects to page and at-fly
+// anchored objects to page
+void MA_FASTCALL lcl_AddObjsToPage( SwFrm* _pFrm, SwPageFrm* _pPage )
+{
+ OSL_ENSURE( _pFrm->GetDrawObjs(), "Keine DrawObjs fuer lcl_AddFlysToPage." );
+ SwSortedObjs &rObjs = *_pFrm->GetDrawObjs();
+ for ( sal_uInt16 i = 0; i < rObjs.Count(); ++i )
+ {
+ SwAnchoredObject* pObj = rObjs[i];
+
+ // --> OD 2004-11-29 #115759# - unlock position of anchored object
+ // in order to get the object's position calculated.
+ pObj->UnlockPosition();
+ // <--
+ // --> OD 2004-11-29 #115759# - add also lower objects of as-character
+ // anchored Writer fly frames from page
+ if ( pObj->ISA(SwFlyFrm) )
+ {
+ SwFlyFrm* pFlyFrm = static_cast<SwFlyFrm*>(pObj);
+ if ( pObj->ISA(SwFlyFreeFrm) )
+ {
+ _pPage->AppendFlyToPage( pFlyFrm );
+ }
+ pFlyFrm->_InvalidatePos();
+ pFlyFrm->_InvalidateSize();
+ pFlyFrm->InvalidatePage( _pPage );
+
+ // --> OD 2004-11-29 #115759# - add also at-fly anchored objects
+ // to page
+ if ( pFlyFrm->GetDrawObjs() )
+ {
+ ::lcl_AddObjsToPage( pFlyFrm, _pPage );
+ }
+ // <--
+
+ SwCntntFrm *pCnt = pFlyFrm->ContainsCntnt();
+ while ( pCnt )
+ {
+ if ( pCnt->GetDrawObjs() )
+ ::lcl_AddObjsToPage( pCnt, _pPage );
+ pCnt = pCnt->GetNextCntntFrm();
+ }
+ }
+ // <--
+ // --> OD 2004-11-29 #115759# - remove also drawing objects from page
+ else if ( pObj->ISA(SwAnchoredDrawObject) )
+ {
+ if (pObj->GetFrmFmt().GetAnchor().GetAnchorId() != FLY_AS_CHAR)
+ {
+ pObj->InvalidateObjPos();
+ _pPage->AppendDrawObjToPage(
+ *(static_cast<SwAnchoredDrawObject*>(pObj)) );
+ }
+ }
+ // <--
+ }
+}
+
+void RestoreCntnt( SwFrm *pSav, SwLayoutFrm *pParent, SwFrm *pSibling, bool bGrow )
+{
+ OSL_ENSURE( pSav && pParent, "Kein Save oder Parent fuer Restore." );
+ SWRECTFN( pParent )
+
+ //Wenn es bereits FlowFrms unterhalb des neuen Parent gibt, so wird die
+ //Kette, beginnend mit pSav, hinter dem letzten angehaengt.
+ //Die Teile werden kurzerhand insertet und geeignet invalidiert.
+ //Unterwegs werden die Flys der CntntFrms bei der Seite angemeldet.
+
+ SwPageFrm *pPage = pParent->FindPageFrm();
+
+ if ( pPage )
+ pPage->InvalidatePage( pPage ); //Invalides Layout anmelden.
+
+ //Vorgaenger festellen und die Verbindung herstellen bzw. initialisieren.
+ pSav->pPrev = pSibling;
+ SwFrm* pNxt;
+ if ( pSibling )
+ {
+ pNxt = pSibling->pNext;
+ pSibling->pNext = pSav;
+ pSibling->_InvalidatePrt();
+ ((SwCntntFrm*)pSibling)->InvalidatePage( pPage );//Invaliden Cntnt anmelden.
+ if ( ((SwCntntFrm*)pSibling)->GetFollow() )
+ pSibling->Prepare( PREP_CLEAR, 0, sal_False );
+ }
+ else
+ { pNxt = pParent->pLower;
+ pParent->pLower = pSav;
+ pSav->pUpper = pParent; //Schon mal setzen, sonst ist fuer das
+ //invalidate der Parent (z.B. ein Fly) nicht klar.
+ //Invaliden Cntnt anmelden.
+ if ( pSav->IsCntntFrm() )
+ ((SwCntntFrm*)pSav)->InvalidatePage( pPage );
+ else
+ { // pSav koennte auch ein leerer SectFrm sein
+ SwCntntFrm* pCnt = pParent->ContainsCntnt();
+ if( pCnt )
+ pCnt->InvalidatePage( pPage );
+ }
+ }
+
+ //Der Parent muss entsprechend gegrow'ed werden.
+ SwTwips nGrowVal = 0;
+ SwFrm* pLast;
+ do
+ { pSav->pUpper = pParent;
+ nGrowVal += (pSav->Frm().*fnRect->fnGetHeight)();
+ pSav->_InvalidateAll();
+
+ //Jetzt die Flys anmelden, fuer TxtFrms gleich geeignet invalidieren.
+ if ( pSav->IsCntntFrm() )
+ {
+ if ( pSav->IsTxtFrm() &&
+ ((SwTxtFrm*)pSav)->GetCacheIdx() != USHRT_MAX )
+ ((SwTxtFrm*)pSav)->Init(); //Ich bin sein Freund.
+
+ if ( pPage && pSav->GetDrawObjs() )
+ ::lcl_AddObjsToPage( (SwCntntFrm*)pSav, pPage );
+ }
+ else
+ { SwCntntFrm *pBlub = ((SwLayoutFrm*)pSav)->ContainsCntnt();
+ if( pBlub )
+ {
+ do
+ { if ( pPage && pBlub->GetDrawObjs() )
+ ::lcl_AddObjsToPage( pBlub, pPage );
+ if( pBlub->IsTxtFrm() && ((SwTxtFrm*)pBlub)->HasFtn() &&
+ ((SwTxtFrm*)pBlub)->GetCacheIdx() != USHRT_MAX )
+ ((SwTxtFrm*)pBlub)->Init(); //Ich bin sein Freund.
+ pBlub = pBlub->GetNextCntntFrm();
+ } while ( pBlub && ((SwLayoutFrm*)pSav)->IsAnLower( pBlub ));
+ }
+ }
+ pLast = pSav;
+ pSav = pSav->GetNext();
+
+ } while ( pSav );
+
+ if( pNxt )
+ {
+ pLast->pNext = pNxt;
+ pNxt->pPrev = pLast;
+ }
+
+ if ( bGrow )
+ pParent->Grow( nGrowVal );
+}
+
+/*************************************************************************
+|*
+|* SqRt() Berechnung der Quadratwurzel, damit die math.lib
+|* nicht auch noch dazugelinkt werden muss.
+|*
+|*************************************************************************/
+
+sal_uLong MA_FASTCALL SqRt( BigInt nX )
+{
+ BigInt nErg = 1;
+
+ if ( !nX.IsNeg() )
+ {
+ BigInt nOldErg = 1;
+ for ( int i = 0; i <= 5; i++ )
+ {
+ nErg = (nOldErg + (nX / nOldErg)) / BigInt(2);
+ nOldErg = nErg;
+ }
+ }
+ return nErg >= BigInt(SAL_MAX_UINT32) ? ULONG_MAX : (sal_uLong)nErg;
+}
+
+/*************************************************************************/
+
+SwPageFrm * MA_FASTCALL InsertNewPage( SwPageDesc &rDesc, SwFrm *pUpper,
+ sal_Bool bOdd, sal_Bool bInsertEmpty, sal_Bool bFtn,
+ SwFrm *pSibling )
+{
+ SwPageFrm *pRet;
+ SwDoc *pDoc = ((SwLayoutFrm*)pUpper)->GetFmt()->GetDoc();
+ SwFrmFmt *pFmt = bOdd ? rDesc.GetRightFmt() : rDesc.GetLeftFmt();
+ //Wenn ich kein FrmFmt fuer die Seite gefunden habe, muss ich eben
+ //eine Leerseite einfuegen.
+ if ( !pFmt )
+ {
+ pFmt = bOdd ? rDesc.GetLeftFmt() : rDesc.GetRightFmt();
+ OSL_ENSURE( pFmt, "Descriptor without any format?!" );
+ bInsertEmpty = !bInsertEmpty;
+ }
+ if( bInsertEmpty )
+ {
+ SwPageDesc *pTmpDesc = pSibling && pSibling->GetPrev() ?
+ ((SwPageFrm*)pSibling->GetPrev())->GetPageDesc() : &rDesc;
+ pRet = new SwPageFrm( pDoc->GetEmptyPageFmt(), pUpper, pTmpDesc );
+ pRet->Paste( pUpper, pSibling );
+ pRet->PreparePage( bFtn );
+ }
+ pRet = new SwPageFrm( pFmt, pUpper, &rDesc );
+ pRet->Paste( pUpper, pSibling );
+ pRet->PreparePage( bFtn );
+ if ( pRet->GetNext() )
+ ((SwRootFrm*)pRet->GetUpper())->AssertPageFlys( pRet );
+ return pRet;
+}
+
+
+/*************************************************************************
+|*
+|* RegistFlys(), Regist() Die beiden folgenden Methoden durchsuchen rekursiv
+|* eine Layoutstruktur und melden alle FlyFrms, die einen beliebigen Frm
+|* innerhalb der Struktur als Anker haben bei der Seite an.
+|*
+|*************************************************************************/
+
+void MA_FASTCALL lcl_Regist( SwPageFrm *pPage, const SwFrm *pAnch )
+{
+ SwSortedObjs *pObjs = (SwSortedObjs*)pAnch->GetDrawObjs();
+ for ( sal_uInt16 i = 0; i < pObjs->Count(); ++i )
+ {
+ SwAnchoredObject* pObj = (*pObjs)[i];
+ if ( pObj->ISA(SwFlyFrm) )
+ {
+ SwFlyFrm *pFly = static_cast<SwFlyFrm*>(pObj);
+ //Ggf. ummelden, nicht anmelden wenn bereits bekannt.
+ // --> OD 2004-06-30 #i28701# - use new method <GetPageFrm()>
+ SwPageFrm *pPg = pFly->IsFlyFreeFrm()
+ ? pFly->GetPageFrm() : pFly->FindPageFrm();
+ if ( pPg != pPage )
+ {
+ if ( pPg )
+ pPg->RemoveFlyFromPage( pFly );
+ pPage->AppendFlyToPage( pFly );
+ }
+ ::RegistFlys( pPage, pFly );
+ }
+ else
+ {
+ // --> OD 2008-04-22 #i87493#
+ if ( pPage != pObj->GetPageFrm() )
+ {
+ // --> OD 2004-07-02 #i28701#
+ if ( pObj->GetPageFrm() )
+ pObj->GetPageFrm()->RemoveDrawObjFromPage( *pObj );
+ pPage->AppendDrawObjToPage( *pObj );
+ // <--
+ }
+ // <--
+ }
+
+ const SwFlyFrm* pFly = pAnch->FindFlyFrm();
+ if ( pFly &&
+ pObj->GetDrawObj()->GetOrdNum() < pFly->GetVirtDrawObj()->GetOrdNum() &&
+ pObj->GetDrawObj()->GetPage() )
+ {
+ pObj->DrawObj()->GetPage()->SetObjectOrdNum(
+ pObj->GetDrawObj()->GetOrdNumDirect(),
+ pFly->GetVirtDrawObj()->GetOrdNumDirect() + 1 );
+ }
+ }
+}
+
+void RegistFlys( SwPageFrm *pPage, const SwLayoutFrm *pLay )
+{
+ if ( pLay->GetDrawObjs() )
+ ::lcl_Regist( pPage, pLay );
+ const SwFrm *pFrm = pLay->Lower();
+ while ( pFrm )
+ {
+ if ( pFrm->IsLayoutFrm() )
+ ::RegistFlys( pPage, (const SwLayoutFrm*)pFrm );
+ else if ( pFrm->GetDrawObjs() )
+ ::lcl_Regist( pPage, pFrm );
+ pFrm = pFrm->GetNext();
+ }
+}
+
+/*************************************************************************
+|*
+|* void Notify()
+|*
+|* Beschreibung Benachrichtigt den Hintergrund je nach der
+|* Veraenderung zwischen altem und neuem Rechteckt.
+|*
+|*************************************************************************/
+
+void Notify( SwFlyFrm *pFly, SwPageFrm *pOld, const SwRect &rOld,
+ const SwRect* pOldPrt )
+{
+ const SwRect aFrm( pFly->GetObjRectWithSpaces() );
+ if ( rOld.Pos() != aFrm.Pos() )
+ { //Positionsaenderung, alten und neuen Bereich invalidieren
+ if ( rOld.HasArea() &&
+ rOld.Left()+pFly->GetFmt()->GetLRSpace().GetLeft() < WEIT_WECH )
+ {
+ pFly->NotifyBackground( pOld, rOld, PREP_FLY_LEAVE );
+ }
+ pFly->NotifyBackground( pFly->FindPageFrm(), aFrm, PREP_FLY_ARRIVE );
+ }
+ else if ( rOld.SSize() != aFrm.SSize() )
+ { //Groessenaenderung, den Bereich der Verlassen wurde bzw. jetzt
+ //ueberdeckt wird invalidieren.
+ //Der Einfachheit halber wird hier bewusst jeweils ein Twip
+ //unnoetig invalidiert.
+
+ ViewShell *pSh = pFly->getRootFrm()->GetCurrShell();
+ if( pSh && rOld.HasArea() )
+ pSh->InvalidateWindows( rOld );
+
+ // --> OD 2005-08-19 #i51941# - consider case that fly frame isn't
+ // registered at the old page <pOld>
+ SwPageFrm* pPageFrm = pFly->FindPageFrm();
+ if ( pOld != pPageFrm )
+ {
+ pFly->NotifyBackground( pPageFrm, aFrm, PREP_FLY_ARRIVE );
+ }
+ // <--
+
+ if ( rOld.Left() != aFrm.Left() )
+ {
+ SwRect aTmp( rOld );
+ aTmp.Union( aFrm );
+ aTmp.Left( Min(aFrm.Left(), rOld.Left()) );
+ aTmp.Right( Max(aFrm.Left(), rOld.Left()) );
+ pFly->NotifyBackground( pOld, aTmp, PREP_FLY_CHGD );
+ }
+ SwTwips nOld = rOld.Right();
+ SwTwips nNew = aFrm.Right();
+ if ( nOld != nNew )
+ {
+ SwRect aTmp( rOld );
+ aTmp.Union( aFrm );
+ aTmp.Left( Min(nNew, nOld) );
+ aTmp.Right( Max(nNew, nOld) );
+ pFly->NotifyBackground( pOld, aTmp, PREP_FLY_CHGD );
+ }
+ if ( rOld.Top() != aFrm.Top() )
+ {
+ SwRect aTmp( rOld );
+ aTmp.Union( aFrm );
+ aTmp.Top( Min(aFrm.Top(), rOld.Top()) );
+ aTmp.Bottom( Max(aFrm.Top(), rOld.Top()) );
+ pFly->NotifyBackground( pOld, aTmp, PREP_FLY_CHGD );
+ }
+ nOld = rOld.Bottom();
+ nNew = aFrm.Bottom();
+ if ( nOld != nNew )
+ {
+ SwRect aTmp( rOld );
+ aTmp.Union( aFrm );
+ aTmp.Top( Min(nNew, nOld) );
+ aTmp.Bottom( Max(nNew, nOld) );
+ pFly->NotifyBackground( pOld, aTmp, PREP_FLY_CHGD );
+ }
+ }
+ else if ( pOldPrt && *pOldPrt != pFly->Prt() &&
+ pFly->GetFmt()->GetSurround().IsContour() )
+ {
+ // #i24097#
+ pFly->NotifyBackground( pFly->FindPageFrm(), aFrm, PREP_FLY_ARRIVE );
+ }
+}
+
+/*************************************************************************/
+
+void lcl_CheckFlowBack( SwFrm* pFrm, const SwRect &rRect )
+{
+ SwTwips nBottom = rRect.Bottom();
+ while( pFrm )
+ {
+ if( pFrm->IsLayoutFrm() )
+ {
+ if( rRect.IsOver( pFrm->Frm() ) )
+ lcl_CheckFlowBack( ((SwLayoutFrm*)pFrm)->Lower(), rRect );
+ }
+ else if( !pFrm->GetNext() && nBottom > pFrm->Frm().Bottom() )
+ {
+ if( pFrm->IsCntntFrm() && ((SwCntntFrm*)pFrm)->HasFollow() )
+ pFrm->InvalidateSize();
+ else
+ pFrm->InvalidateNextPos();
+ }
+ pFrm = pFrm->GetNext();
+ }
+}
+
+void MA_FASTCALL lcl_NotifyCntnt( const SdrObject *pThis, SwCntntFrm *pCnt,
+ const SwRect &rRect, const PrepareHint eHint )
+{
+ if ( pCnt->IsTxtFrm() )
+ {
+ SwRect aCntPrt( pCnt->Prt() );
+ aCntPrt.Pos() += pCnt->Frm().Pos();
+ if ( eHint == PREP_FLY_ATTR_CHG )
+ {
+ // --> OD 2004-10-20 #i35640# - use given rectangle <rRect> instead
+ // of current bound rectangle
+ if ( aCntPrt.IsOver( rRect ) )
+ // <--
+ pCnt->Prepare( PREP_FLY_ATTR_CHG );
+ }
+ // --> OD 2004-11-01 #i23129# - only invalidate, if the text frame
+ // printing area overlaps with the given rectangle.
+ else if ( aCntPrt.IsOver( rRect ) )
+ // <--
+ pCnt->Prepare( eHint, (void*)&aCntPrt._Intersection( rRect ) );
+ if ( pCnt->GetDrawObjs() )
+ {
+ const SwSortedObjs &rObjs = *pCnt->GetDrawObjs();
+ for ( sal_uInt16 i = 0; i < rObjs.Count(); ++i )
+ {
+ SwAnchoredObject* pObj = rObjs[i];
+ if ( pObj->ISA(SwFlyFrm) )
+ {
+ SwFlyFrm *pFly = static_cast<SwFlyFrm*>(pObj);
+ if ( pFly->IsFlyInCntFrm() )
+ {
+ SwCntntFrm *pCntnt = pFly->ContainsCntnt();
+ while ( pCntnt )
+ {
+ ::lcl_NotifyCntnt( pThis, pCntnt, rRect, eHint );
+ pCntnt = pCntnt->GetNextCntntFrm();
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+void Notify_Background( const SdrObject* pObj,
+ SwPageFrm* pPage,
+ const SwRect& rRect,
+ const PrepareHint eHint,
+ const sal_Bool bInva )
+{
+
+ //Wenn der Frm gerade erstmalig sinnvoll positioniert wurde, braucht der
+ //alte Bereich nicht benachrichtigt werden.
+ if ( eHint == PREP_FLY_LEAVE && rRect.Top() == WEIT_WECH )
+ return;
+
+ SwLayoutFrm* pArea;
+ SwFlyFrm *pFlyFrm = 0;
+ SwFrm* pAnchor;
+ if( pObj->ISA(SwVirtFlyDrawObj) )
+ {
+ pFlyFrm = ((SwVirtFlyDrawObj*)pObj)->GetFlyFrm();
+ pAnchor = pFlyFrm->AnchorFrm();
+ }
+ else
+ {
+ pFlyFrm = NULL;
+ pAnchor = const_cast<SwFrm*>(
+ GetUserCall(pObj)->GetAnchoredObj( pObj )->GetAnchorFrm() );
+ }
+ if( PREP_FLY_LEAVE != eHint && pAnchor->IsInFly() )
+ pArea = pAnchor->FindFlyFrm();
+ else
+ pArea = pPage;
+ SwCntntFrm *pCnt = 0;
+ if ( pArea )
+ {
+ if( PREP_FLY_ARRIVE != eHint )
+ lcl_CheckFlowBack( pArea, rRect );
+
+ //Es reagieren sowieso nur die auf den Anker folgenden auf den Fly, also
+ //brauchen diese nicht abgeklappert werden.
+ //Ausnahme sind ist natuerlich das LEAVE, denn der Fly koennte ja von
+ //"oben" kommen.
+ // Wenn der Anker auf der vorhergehenden Seite liegt, muss ebenfalls
+ // die gesamte Seite abgearbeitet werden. (47722)
+ // OD 2004-05-13 #i28701# - If the wrapping style has to be considered
+ // on the object positioning, the complete area has to be processed,
+ // because content frames before the anchor frame also have to consider
+ // the object for the text wrapping.
+ // --> OD 2004-08-25 #i3317# - The complete area has always been
+ // processed.
+ {
+ pCnt = pArea->ContainsCntnt();
+ }
+ // <--
+ }
+ SwFrm *pLastTab = 0;
+
+ while ( pCnt && pArea && pArea->IsAnLower( pCnt ) )
+ {
+ ::lcl_NotifyCntnt( pObj, pCnt, rRect, eHint );
+ if ( pCnt->IsInTab() )
+ {
+ SwLayoutFrm* pCell = pCnt->GetUpper();
+ // --> OD 2005-01-14 #i40606# - use <GetLastBoundRect()>
+ // instead of <GetCurrentBoundRect()>, because a recalculation
+ // of the bounding rectangle isn't intended here.
+ if ( pCell->IsCellFrm() &&
+ ( pCell->Frm().IsOver( pObj->GetLastBoundRect() ) ||
+ pCell->Frm().IsOver( rRect ) ) )
+ // <--
+ {
+ const SwFmtVertOrient &rOri = pCell->GetFmt()->GetVertOrient();
+ if ( text::VertOrientation::NONE != rOri.GetVertOrient() )
+ pCell->InvalidatePrt();
+ }
+ SwTabFrm *pTab = pCnt->FindTabFrm();
+ if ( pTab != pLastTab )
+ {
+ pLastTab = pTab;
+ // --> OD 2005-01-14 #i40606# - use <GetLastBoundRect()>
+ // instead of <GetCurrentBoundRect()>, because a recalculation
+ // of the bounding rectangle isn't intended here.
+ if ( pTab->Frm().IsOver( pObj->GetLastBoundRect() ) ||
+ pTab->Frm().IsOver( rRect ) )
+ // <--
+ {
+ if ( !pFlyFrm || !pFlyFrm->IsLowerOf( pTab ) )
+ pTab->InvalidatePrt();
+ }
+ }
+ }
+ pCnt = pCnt->GetNextCntntFrm();
+ }
+// #108745# Sorry, but this causes nothing but trouble. I remove these lines
+// taking the risk that the footer frame will have a wrong height
+// if( pPage->Lower() )
+// {
+// SwFrm* pFrm = pPage->Lower();
+// while( pFrm->GetNext() )
+// pFrm = pFrm->GetNext();
+// if( pFrm->IsFooterFrm() &&
+// ( ( pFrm->Frm().IsOver( pObj->GetBoundRect() ) ||
+// pFrm->Frm().IsOver( rRect ) ) ) )
+// pFrm->InvalidateSize();
+// }
+ // --> OD 2007-07-24 #128702# - make code robust
+ if ( pPage && pPage->GetSortedObjs() )
+ // <--
+ {
+ pObj->GetOrdNum();
+ const SwSortedObjs &rObjs = *pPage->GetSortedObjs();
+ for ( sal_uInt16 i = 0; i < rObjs.Count(); ++i )
+ {
+ SwAnchoredObject* pAnchoredObj = rObjs[i];
+ if ( pAnchoredObj->ISA(SwFlyFrm) )
+ {
+ if( pAnchoredObj->GetDrawObj() == pObj )
+ continue;
+ SwFlyFrm *pFly = static_cast<SwFlyFrm*>(pAnchoredObj);
+ if ( pFly->Frm().Top() == WEIT_WECH )
+ continue;
+
+ if ( !pFlyFrm ||
+ (!pFly->IsLowerOf( pFlyFrm ) &&
+ pFly->GetVirtDrawObj()->GetOrdNumDirect() < pObj->GetOrdNumDirect()))
+ {
+ pCnt = pFly->ContainsCntnt();
+ while ( pCnt )
+ {
+ ::lcl_NotifyCntnt( pObj, pCnt, rRect, eHint );
+ pCnt = pCnt->GetNextCntntFrm();
+ }
+ }
+ if( pFly->IsFlyLayFrm() )
+ {
+ if( pFly->Lower() && pFly->Lower()->IsColumnFrm() &&
+ pFly->Frm().Bottom() >= rRect.Top() &&
+ pFly->Frm().Top() <= rRect.Bottom() &&
+ pFly->Frm().Right() >= rRect.Left() &&
+ pFly->Frm().Left() <= rRect.Right() )
+ {
+ pFly->InvalidateSize();
+ }
+ }
+ //Flys, die ueber mir liegen muessen/mussten evtl.
+ //ausweichen, wenn sie eine automatische Ausrichtung haben.
+ //das ist unabhaengig von meinem Attribut, weil dies sich
+ //gerade geaendert haben kann und eben deshalb
+ //umformatiert wurde.
+ else if ( pFly->IsFlyAtCntFrm() &&
+ pObj->GetOrdNumDirect() <
+ pFly->GetVirtDrawObj()->GetOrdNumDirect() &&
+ pFlyFrm && !pFly->IsLowerOf( pFlyFrm ) )
+ {
+ const SwFmtHoriOrient &rH = pFly->GetFmt()->GetHoriOrient();
+ if ( text::HoriOrientation::NONE != rH.GetHoriOrient() &&
+ text::HoriOrientation::CENTER != rH.GetHoriOrient() &&
+ ( !pFly->IsAutoPos() || text::RelOrientation::CHAR != rH.GetRelationOrient() ) &&
+ (pFly->Frm().Bottom() >= rRect.Top() &&
+ pFly->Frm().Top() <= rRect.Bottom()) )
+ pFly->InvalidatePos();
+ }
+ }
+ }
+ }
+ if ( pFlyFrm && pAnchor->GetUpper() && pAnchor->IsInTab() )//MA_FLY_HEIGHT
+ pAnchor->GetUpper()->InvalidateSize();
+
+ // --> OD 2008-01-30 #i82258# - make code robust
+ ViewShell* pSh = 0;
+ if ( bInva && pPage &&
+ 0 != (pSh = pPage->getRootFrm()->GetCurrShell()) )
+ {
+ pSh->InvalidateWindows( rRect );
+ }
+ // <--
+}
+
+/*************************************************************************
+|*
+|* GetVirtualUpper() liefert bei absatzgebundenen Objekten den Upper
+|* des Ankers. Falls es sich dabei um verkettete Rahmen oder
+|* Fussnoten handelt, wird ggf. der "virtuelle" Upper ermittelt.
+|*
+|*************************************************************************/
+
+const SwFrm* GetVirtualUpper( const SwFrm* pFrm, const Point& rPos )
+{
+ if( pFrm->IsTxtFrm() )
+ {
+ pFrm = pFrm->GetUpper();
+ if( !pFrm->Frm().IsInside( rPos ) )
+ {
+ if( pFrm->IsFtnFrm() )
+ {
+ const SwFtnFrm* pTmp = ((SwFtnFrm*)pFrm)->GetFollow();
+ while( pTmp )
+ {
+ if( pTmp->Frm().IsInside( rPos ) )
+ return pTmp;
+ pTmp = pTmp->GetFollow();
+ }
+ }
+ else
+ {
+ SwFlyFrm* pTmp = (SwFlyFrm*)pFrm->FindFlyFrm();
+ while( pTmp )
+ {
+ if( pTmp->Frm().IsInside( rPos ) )
+ return pTmp;
+ pTmp = pTmp->GetNextLink();
+ }
+ }
+ }
+ }
+ return pFrm;
+}
+
+/*************************************************************************/
+
+sal_Bool Is_Lower_Of( const SwFrm *pCurrFrm, const SdrObject* pObj )
+{
+ Point aPos;
+ const SwFrm* pFrm;
+ if( pObj->ISA(SwVirtFlyDrawObj) )
+ {
+ const SwFlyFrm* pFly = ( (SwVirtFlyDrawObj*)pObj )->GetFlyFrm();
+ pFrm = pFly->GetAnchorFrm();
+ aPos = pFly->Frm().Pos();
+ }
+ else
+ {
+ pFrm = ( (SwDrawContact*)GetUserCall(pObj) )->GetAnchorFrm(pObj);
+ aPos = pObj->GetCurrentBoundRect().TopLeft();
+ }
+ OSL_ENSURE( pFrm, "8-( Fly is lost in Space." );
+ pFrm = GetVirtualUpper( pFrm, aPos );
+ do
+ { if ( pFrm == pCurrFrm )
+ return sal_True;
+ if( pFrm->IsFlyFrm() )
+ {
+ aPos = pFrm->Frm().Pos();
+ pFrm = GetVirtualUpper( ((const SwFlyFrm*)pFrm)->GetAnchorFrm(), aPos );
+ }
+ else
+ pFrm = pFrm->GetUpper();
+ } while ( pFrm );
+ return sal_False;
+}
+
+const SwFrm *FindKontext( const SwFrm *pFrm, sal_uInt16 nAdditionalKontextTyp )
+{
+ //Liefert die Umgebung des Frm in die kein Fly aus einer anderen
+ //Umgebung hineinragen kann.
+ const sal_uInt16 nTyp = FRM_ROOT | FRM_HEADER | FRM_FOOTER | FRM_FTNCONT |
+ FRM_FTN | FRM_FLY |
+ FRM_TAB | FRM_ROW | FRM_CELL |
+ nAdditionalKontextTyp;
+ do
+ { if ( pFrm->GetType() & nTyp )
+ break;
+ pFrm = pFrm->GetUpper();
+ } while( pFrm );
+ return pFrm;
+}
+
+sal_Bool IsFrmInSameKontext( const SwFrm *pInnerFrm, const SwFrm *pFrm )
+{
+ const SwFrm *pKontext = FindKontext( pInnerFrm, 0 );
+
+ const sal_uInt16 nTyp = FRM_ROOT | FRM_HEADER | FRM_FOOTER | FRM_FTNCONT |
+ FRM_FTN | FRM_FLY |
+ FRM_TAB | FRM_ROW | FRM_CELL;
+ do
+ { if ( pFrm->GetType() & nTyp )
+ {
+ if( pFrm == pKontext )
+ return sal_True;
+ if( pFrm->IsCellFrm() )
+ return sal_False;
+ }
+ if( pFrm->IsFlyFrm() )
+ {
+ Point aPos( pFrm->Frm().Pos() );
+ pFrm = GetVirtualUpper( ((const SwFlyFrm*)pFrm)->GetAnchorFrm(), aPos );
+ }
+ else
+ pFrm = pFrm->GetUpper();
+ } while( pFrm );
+
+ return sal_False;
+}
+
+
+//---------------------------------
+
+SwTwips MA_FASTCALL lcl_CalcCellRstHeight( SwLayoutFrm *pCell )
+{
+ if ( pCell->Lower()->IsCntntFrm() || pCell->Lower()->IsSctFrm() )
+ {
+ SwFrm *pLow = pCell->Lower();
+ long nHeight = 0, nFlyAdd = 0;
+ do
+ {
+ long nLow = pLow->Frm().Height();
+ if( pLow->IsTxtFrm() && ((SwTxtFrm*)pLow)->IsUndersized() )
+ nLow += ((SwTxtFrm*)pLow)->GetParHeight()-pLow->Prt().Height();
+ else if( pLow->IsSctFrm() && ((SwSectionFrm*)pLow)->IsUndersized() )
+ nLow += ((SwSectionFrm*)pLow)->Undersize();
+ nFlyAdd = Max( 0L, nFlyAdd - nLow );
+ nFlyAdd = Max( nFlyAdd, ::CalcHeightWidthFlys( pLow ) );
+ nHeight += nLow;
+ pLow = pLow->GetNext();
+ } while ( pLow );
+ if ( nFlyAdd )
+ nHeight += nFlyAdd;
+
+ //Der Border will natuerlich auch mitspielen, er kann leider nicht
+ //aus PrtArea und Frm errechnet werden, da diese in beliebiger
+ //Kombination ungueltig sein koennen.
+ SwBorderAttrAccess aAccess( SwFrm::GetCache(), pCell );
+ const SwBorderAttrs &rAttrs = *aAccess.Get();
+ nHeight += rAttrs.CalcTop() + rAttrs.CalcBottom();
+
+ return pCell->Frm().Height() - nHeight;
+ }
+ else
+ {
+ long nRstHeight = 0;
+ SwFrm *pLow = pCell->Lower();
+ do
+ { nRstHeight += ::CalcRowRstHeight( (SwLayoutFrm*)pLow );
+ pLow = pLow->GetNext();
+
+ } while ( pLow );
+
+ return nRstHeight;
+ }
+}
+
+SwTwips MA_FASTCALL CalcRowRstHeight( SwLayoutFrm *pRow )
+{
+ SwTwips nRstHeight = LONG_MAX;
+ SwLayoutFrm *pLow = (SwLayoutFrm*)pRow->Lower();
+ while ( pLow )
+ {
+ nRstHeight = Min( nRstHeight, ::lcl_CalcCellRstHeight( pLow ) );
+ pLow = (SwLayoutFrm*)pLow->GetNext();
+ }
+ return nRstHeight;
+}
+
+const SwFrm* MA_FASTCALL FindPage( const SwRect &rRect, const SwFrm *pPage )
+{
+ if ( !rRect.IsOver( pPage->Frm() ) )
+ {
+ const SwRootFrm* pRootFrm = static_cast<const SwRootFrm*>(pPage->GetUpper());
+ const SwFrm* pTmpPage = pRootFrm ? pRootFrm->GetPageAtPos( rRect.TopLeft(), &rRect.SSize(), true ) : 0;
+ if ( pTmpPage )
+ pPage = pTmpPage;
+ }
+
+ return pPage;
+}
+
+#include <svl/smplhint.hxx>
+class SwFrmHolder : private SfxListener
+{
+ SwFrm* pFrm;
+ bool bSet;
+ virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint );
+public:
+ SwFrmHolder() : pFrm(0), bSet(false) {}
+ void SetFrm( SwFrm* pHold );
+ SwFrm* GetFrm() { return pFrm; }
+ void Reset();
+ bool IsSet() { return bSet; }
+};
+
+void SwFrmHolder::SetFrm( SwFrm* pHold )
+{
+ bSet = true;
+ pFrm = pHold;
+ StartListening(*pHold);
+}
+
+void SwFrmHolder::Reset()
+{
+ if (pFrm)
+ EndListening(*pFrm);
+ bSet = false;
+ pFrm = 0;
+}
+
+void SwFrmHolder::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
+{
+ if ( rHint.IsA(TYPE(SfxSimpleHint)) )
+ {
+ if ( ( (SfxSimpleHint&) rHint ).GetId() == SFX_HINT_DYING && &rBC == pFrm )
+ pFrm = 0;
+ }
+}
+
+SwFrm* GetFrmOfModify( const SwRootFrm* pLayout, SwModify const& rMod, sal_uInt16 const nFrmType,
+ const Point* pPoint, const SwPosition *pPos, const sal_Bool bCalcFrm )
+{
+ SwFrm *pMinFrm = 0, *pTmpFrm;
+ SwFrmHolder aHolder;
+ SwRect aCalcRect;
+ bool bClientIterChanged = false;
+
+ SwIterator<SwFrm,SwModify> aIter( rMod );
+ do {
+ pMinFrm = 0;
+ aHolder.Reset();
+ sal_uInt64 nMinDist = 0;
+ bClientIterChanged = false;
+
+ for( pTmpFrm = aIter.First(); pTmpFrm; pTmpFrm = aIter.Next() )
+ {
+ if( pTmpFrm->GetType() & nFrmType &&
+ ( !pLayout || pLayout == pTmpFrm->getRootFrm() ) &&
+ (!pTmpFrm->IsFlowFrm() ||
+ !SwFlowFrm::CastFlowFrm( pTmpFrm )->IsFollow() ))
+ {
+ if( pPoint )
+ {
+ // watch for Frm being deleted
+ if ( pMinFrm )
+ aHolder.SetFrm( pMinFrm );
+ else
+ aHolder.Reset();
+
+ if( bCalcFrm )
+ {
+ // --> OD 2005-03-04 #b6234250# - format parent Writer
+ // fly frame, if it isn't been formatted yet.
+ // Note: The Writer fly frame could be the frame itself.
+ SwFlyFrm* pFlyFrm( pTmpFrm->FindFlyFrm() );
+ if ( pFlyFrm &&
+ pFlyFrm->Frm().Pos().X() == WEIT_WECH &&
+ pFlyFrm->Frm().Pos().Y() == WEIT_WECH )
+ {
+ SwObjectFormatter::FormatObj( *pFlyFrm );
+ }
+ // <--
+ pTmpFrm->Calc();
+ }
+
+ // #127369#
+ // aIter.IsChanged checks if the current pTmpFrm has been deleted while
+ // it is the current iterator
+ // FrmHolder watches for deletion of the current pMinFrm
+ if( aIter.IsChanged() || ( aHolder.IsSet() && !aHolder.GetFrm() ) )
+ {
+ // restart iteration
+ bClientIterChanged = true;
+ break;
+ }
+
+ // bei Flys ggfs. ueber den Parent gehen wenn sie selbst
+ // nocht nicht "formatiert" sind
+ if( !bCalcFrm && nFrmType & FRM_FLY &&
+ ((SwFlyFrm*)pTmpFrm)->GetAnchorFrm() &&
+ WEIT_WECH == pTmpFrm->Frm().Pos().X() &&
+ WEIT_WECH == pTmpFrm->Frm().Pos().Y() )
+ aCalcRect = ((SwFlyFrm*)pTmpFrm)->GetAnchorFrm()->Frm();
+ else
+ aCalcRect = pTmpFrm->Frm();
+
+ if ( aCalcRect.IsInside( *pPoint ) )
+ {
+ pMinFrm = pTmpFrm;
+ break;
+ }
+
+ // Point not in rectangle. Compare distances:
+ const Point aCalcRectCenter = aCalcRect.Center();
+ const Point aDiff = aCalcRectCenter - *pPoint;
+ const sal_uInt64 nCurrentDist = aDiff.X() * aDiff.X() + aDiff.Y() * aDiff.Y(); // opt: no sqrt
+ if ( !pMinFrm || nCurrentDist < nMinDist )
+ {
+ pMinFrm = pTmpFrm;
+ nMinDist = nCurrentDist;
+ }
+ }
+ else
+ {
+ // Wenn kein pPoint angegeben ist, dann reichen
+ // wir irgendeinen raus: den ersten!
+ pMinFrm = pTmpFrm;
+ break;
+ }
+ }
+ }
+ } while( bClientIterChanged );
+
+ if( pPos && pMinFrm && pMinFrm->IsTxtFrm() )
+ return ((SwTxtFrm*)pMinFrm)->GetFrmAtPos( *pPos );
+
+ return pMinFrm;
+}
+
+sal_Bool IsExtraData( const SwDoc *pDoc )
+{
+ const SwLineNumberInfo &rInf = pDoc->GetLineNumberInfo();
+ return rInf.IsPaintLineNumbers() ||
+ rInf.IsCountInFlys() ||
+ ((sal_Int16)SW_MOD()->GetRedlineMarkPos() != text::HoriOrientation::NONE &&
+ pDoc->GetRedlineTbl().Count());
+}
+
+// OD 22.09.2003 #110978#
+const SwRect SwPageFrm::PrtWithoutHeaderAndFooter() const
+{
+ SwRect aPrtWithoutHeaderFooter( Prt() );
+ aPrtWithoutHeaderFooter.Pos() += Frm().Pos();
+
+ const SwFrm* pLowerFrm = Lower();
+ while ( pLowerFrm )
+ {
+ // Note: independent on text direction page header and page footer are
+ // always at top respectively at bottom of the page frame.
+ if ( pLowerFrm->IsHeaderFrm() )
+ {
+ aPrtWithoutHeaderFooter.Top( aPrtWithoutHeaderFooter.Top() +
+ pLowerFrm->Frm().Height() );
+ }
+ if ( pLowerFrm->IsFooterFrm() )
+ {
+ aPrtWithoutHeaderFooter.Bottom( aPrtWithoutHeaderFooter.Bottom() -
+ pLowerFrm->Frm().Height() );
+ }
+
+ pLowerFrm = pLowerFrm->GetNext();
+ }
+
+ return aPrtWithoutHeaderFooter;
+}
+
+/** method to determine the spacing values of a frame
+
+ OD 2004-03-10 #i28701#
+ OD 2009-08-28 #i102458#
+ Add output parameter <obIsLineSpacingProportional>
+
+ @author OD
+*/
+void GetSpacingValuesOfFrm( const SwFrm& rFrm,
+ SwTwips& onLowerSpacing,
+ SwTwips& onLineSpacing,
+ bool& obIsLineSpacingProportional )
+{
+ if ( !rFrm.IsFlowFrm() )
+ {
+ onLowerSpacing = 0;
+ onLineSpacing = 0;
+ }
+ else
+ {
+ const SvxULSpaceItem& rULSpace = rFrm.GetAttrSet()->GetULSpace();
+ onLowerSpacing = rULSpace.GetLower();
+
+ onLineSpacing = 0;
+ obIsLineSpacingProportional = false;
+ if ( rFrm.IsTxtFrm() )
+ {
+ onLineSpacing = static_cast<const SwTxtFrm&>(rFrm).GetLineSpace();
+ obIsLineSpacingProportional =
+ onLineSpacing != 0 &&
+ static_cast<const SwTxtFrm&>(rFrm).GetLineSpace( true ) == 0;
+ }
+
+ OSL_ENSURE( onLowerSpacing >= 0 && onLineSpacing >= 0,
+ "<GetSpacingValuesOfFrm(..)> - spacing values aren't positive!" );
+ }
+}
+
+/** method to get the content of the table cell, skipping content from nested tables
+*/
+const SwCntntFrm* GetCellCntnt( const SwLayoutFrm& rCell )
+{
+ const SwCntntFrm* pCntnt = rCell.ContainsCntnt();
+ const SwTabFrm* pTab = rCell.FindTabFrm();
+
+ while ( pCntnt && rCell.IsAnLower( pCntnt ) )
+ {
+ const SwTabFrm* pTmpTab = pCntnt->FindTabFrm();
+ if ( pTmpTab != pTab )
+ {
+ pCntnt = pTmpTab->FindLastCntnt();
+ if ( pCntnt )
+
+ pCntnt = pCntnt->FindNextCnt();
+
+ }
+ else
+ break;
+ }
+ return pCntnt;
+}
+
+/** Can be used to check if a frame has been deleted
+ */
+bool SwDeletionChecker::HasBeenDeleted()
+{
+ if ( !mpFrm || !mpRegIn )
+ return false;
+
+ SwIterator<SwFrm,SwModify> aIter(*mpRegIn);
+ SwFrm* pLast = aIter.First();
+ while ( pLast )
+ {
+ if ( pLast == mpFrm )
+ return false;
+ pLast = aIter.Next();
+ }
+
+ return true;
+}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */