diff options
Diffstat (limited to 'binfilter/bf_sw/source/core/text/sw_txtfrm.cxx')
-rw-r--r-- | binfilter/bf_sw/source/core/text/sw_txtfrm.cxx | 2064 |
1 files changed, 2064 insertions, 0 deletions
diff --git a/binfilter/bf_sw/source/core/text/sw_txtfrm.cxx b/binfilter/bf_sw/source/core/text/sw_txtfrm.cxx new file mode 100644 index 000000000000..72d912a0e6ff --- /dev/null +++ b/binfilter/bf_sw/source/core/text/sw_txtfrm.cxx @@ -0,0 +1,2064 @@ +/* -*- 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. + * + ************************************************************************/ + + +#ifdef _MSC_VER +#pragma hdrstop +#endif + +#include <hintids.hxx> + +#include <bf_sfx2/printer.hxx> +#include <bf_svx/lspcitem.hxx> +#include <bf_svx/lrspitem.hxx> +#include <bf_svx/brshitem.hxx> +#include <bf_svx/pgrditem.hxx> + +#include <horiornt.hxx> + +#include <doc.hxx> // GetDoc() +#include <pagefrm.hxx> // InvalidateSpelling +#include <viewsh.hxx> // ViewShell +#include <paratr.hxx> +#include <hints.hxx> // SwInsChr +#include <viewopt.hxx> +#include <dflyobj.hxx> +#include <flyfrm.hxx> +#include <tabfrm.hxx> +#include <frmtool.hxx> +#include <pagedesc.hxx> // SwPageDesc +#include <tgrditem.hxx> +#include <dbg_lay.hxx> +#include <fmtfld.hxx> +#include <fmtftn.hxx> +#include <txtfld.hxx> +#include <txtftn.hxx> +#include <ftninfo.hxx> +#include <fmtline.hxx> +#include <sectfrm.hxx> // SwSectFrm +#include <itrform2.hxx> // Iteratoren +#include <widorp.hxx> // SwFrmBreak +#include <txtcache.hxx> +#include <fntcache.hxx> // GetLineSpace benutzt pLastFont +#include <frmsh.hxx> +#include <wrong.hxx> // SwWrongList +#include <lineinfo.hxx> + +#if OSL_DEBUG_LEVEL > 1 +namespace binfilter { +extern const sal_Char *GetPrepName( const enum PrepareHint ePrep ); +} //STRIP008 +#endif +namespace binfilter { +/*N*/ TYPEINIT1( SwTxtFrm, SwCntntFrm ); + +// Switches width and height of the text frame +/*N*/ void SwTxtFrm::SwapWidthAndHeight() +/*N*/ { +/*N*/ if ( ! bIsSwapped ) +/*N*/ { +/*N*/ const long nPrtOfstX = Prt().Pos().X(); +/*N*/ Prt().Pos().X() = Prt().Pos().Y(); +/*N*/ Prt().Pos().Y() = Frm().Width() - ( nPrtOfstX + Prt().Width() ); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ const long nPrtOfstY = Prt().Pos().Y(); +/*N*/ Prt().Pos().Y() = Prt().Pos().X(); +/*N*/ Prt().Pos().X() = Frm().Height() - ( nPrtOfstY + Prt().Height() ); +/*N*/ } +/*N*/ +/*N*/ const long nFrmWidth = Frm().Width(); +/*N*/ Frm().Width( Frm().Height() ); +/*N*/ Frm().Height( nFrmWidth ); +/*N*/ const long nPrtWidth = Prt().Width(); +/*N*/ Prt().Width( Prt().Height() ); +/*N*/ Prt().Height( nPrtWidth ); +/*N*/ +/*N*/ bIsSwapped = ! bIsSwapped; +/*N*/ } + +// Calculates the coordinates of a rectangle when switching from +// horizontal to vertical layout. + +// Calculates the coordinates of a point when switching from +// horizontal to vertical layout. + +// Calculates the a limit value when switching from +// horizontal to vertical layout. + +// Calculates the coordinates of a rectangle when switching from +// vertical to horizontal layout. +/*N*/ void SwTxtFrm::SwitchVerticalToHorizontal( SwRect& rRect ) const +/*N*/ { +/*N*/ long nOfstX; +/*N*/ +/*N*/ // calc offset inside frame +/*N*/ if ( bIsSwapped ) +/*N*/ nOfstX = Frm().Left() + Frm().Height() - ( rRect.Left() + rRect.Width() ); +/*N*/ else +/*N*/ nOfstX = Frm().Left() + Frm().Width() - ( rRect.Left() + rRect.Width() ); +/*N*/ +/*N*/ const long nOfstY = rRect.Top() - Frm().Top(); +/*N*/ const long nWidth = rRect.Height(); +/*N*/ const long nHeight = rRect.Width(); +/*N*/ +/*N*/ // calc rotated coords +/*N*/ rRect.Left( Frm().Left() + nOfstY ); +/*N*/ rRect.Top( Frm().Top() + nOfstX ); +/*N*/ rRect.Width( nWidth ); +/*N*/ rRect.Height( nHeight ); +/*N*/ } + +// Calculates the coordinates of a point when switching from +// vertical to horizontal layout. +/*N*/ void SwTxtFrm::SwitchVerticalToHorizontal( Point& rPoint ) const +/*N*/ { +/*N*/ long nOfstX; +/*N*/ +/*N*/ // calc offset inside frame +/*N*/ if ( bIsSwapped ) +/*N*/ nOfstX = Frm().Left() + Frm().Height() - rPoint.X(); +/*N*/ else +/*N*/ nOfstX = Frm().Left() + Frm().Width() - rPoint.X(); +/*N*/ +/*N*/ const long nOfstY = rPoint.Y() - Frm().Top(); +/*N*/ +/*N*/ // calc rotated coords +/*N*/ rPoint.X() = Frm().Left() + nOfstY; +/*N*/ rPoint.Y() = Frm().Top() + nOfstX; +/*N*/ } +/*N*/ +/*N*/ SwFrmSwapper::SwFrmSwapper( const SwTxtFrm* pTxtFrm, sal_Bool bSwapIfNotSwapped ) +/*N*/ : pFrm( pTxtFrm ), bUndo( sal_False ) +/*N*/ { +/*N*/ if ( pFrm->IsVertical() && +/*N*/ ( ( bSwapIfNotSwapped && ! pFrm->IsSwapped() ) || +/*N*/ ( ! bSwapIfNotSwapped && pFrm->IsSwapped() ) ) ) +/*N*/ { +/*?*/ bUndo = sal_True; +/*?*/ ((SwTxtFrm*)pFrm)->SwapWidthAndHeight(); +/*N*/ } +/*N*/ } + +/*N*/ SwFrmSwapper::~SwFrmSwapper() +/*N*/ { +/*N*/ if ( bUndo ) +/*?*/ ((SwTxtFrm*)pFrm)->SwapWidthAndHeight(); +/*N*/ } + +#ifdef BIDI + +/*N*/ void SwTxtFrm::SwitchLTRtoRTL( Point& rPoint ) const +/*N*/ { +/*N*/ SWAP_IF_NOT_SWAPPED( this ) +/*N*/ +/*N*/ rPoint.X() = 2 * ( Frm().Left() + Prt().Left() ) + Prt().Width() - rPoint.X() - 1; +/*N*/ +/*N*/ UNDO_SWAP( this ) +/*N*/ } + +/*N*/ SwLayoutModeModifier::SwLayoutModeModifier( const OutputDevice& rOutp ) : +/*N*/ rOut( rOutp ), nOldLayoutMode( rOutp.GetLayoutMode() ) +/*N*/ { +/*N*/ } +/*N*/ +/*N*/ SwLayoutModeModifier::~SwLayoutModeModifier() +/*N*/ { +/*N*/ ((OutputDevice&)rOut).SetLayoutMode( nOldLayoutMode ); +/*N*/ } + + +/*N*/ void SwLayoutModeModifier::SetAuto() +/*N*/ { +/*N*/ const ULONG nNewLayoutMode = nOldLayoutMode & ~TEXT_LAYOUT_BIDI_STRONG; +/*N*/ ((OutputDevice&)rOut).SetLayoutMode( nNewLayoutMode ); +/*N*/ } + +#endif + +/************************************************************************* + * SwTxtFrm::Init() + *************************************************************************/ + +/*N*/ void SwTxtFrm::Init() +/*N*/ { +/*N*/ ASSERT( !IsLocked(), "+SwTxtFrm::Init: this ist locked." ); +/*N*/ if( !IsLocked() ) +/*N*/ { +/*N*/ ClearPara(); +/*N*/ ResetBlinkPor(); +/*N*/ //Die Flags direkt setzen um ResetPreps und damit ein unnuetzes GetPara +/*N*/ //einzusparen. +/*N*/ // Nicht bOrphan, bLocked oder bWait auf sal_False setzen ! +/*N*/ // bOrphan = bFlag7 = bFlag8 = sal_False; +/*N*/ } +/*N*/ } + +/************************************************************************* +|* SwTxtFrm::CTORen/DTOR +|*************************************************************************/ + +/*N*/ void SwTxtFrm::InitCtor() +/*N*/ { +/*N*/ nCacheIdx = MSHRT_MAX; +/*N*/ nOfst = 0; +/*N*/ nAllLines = 0; +/*N*/ nThisLines = 0; +/*N*/ mnFlyAnchorOfst = 0; +/*N*/ mnFlyAnchorOfstNoWrap = 0; +/*N*/ +/*N*/ nType = FRMC_TXT; +/*N*/ bLocked = bFormatted = bWidow = bUndersized = bJustWidow = +/*N*/ bEmpty = bInFtnConnect = bFtn = bRepaint = bBlinkPor = +/*N*/ bFieldFollow = bHasAnimation = bIsSwapped = sal_False; + // OD 14.03.2003 #i11760# +/*N*/ mbFollowFormatAllowed = sal_True; +/*N*/ } + + +/*N*/ SwTxtFrm::SwTxtFrm(SwTxtNode * const pNode) +/*N*/ : SwCntntFrm(pNode) +/*N*/ { +/*N*/ InitCtor(); +/*N*/ } +/*N*/ +/*N*/ const XubString& SwTxtFrm::GetTxt() const +/*N*/ { +/*N*/ return GetTxtNode()->GetTxt(); +/*N*/ } +/*N*/ +/*N*/ void SwTxtFrm::ResetPreps() +/*N*/ { +/*N*/ if ( GetCacheIdx() != MSHRT_MAX ) +/*N*/ { +/*N*/ SwParaPortion *pPara; +/*N*/ if( 0 != (pPara = GetPara()) ) +/*N*/ pPara->ResetPreps(); +/*N*/ } +/*N*/ } + +/************************************************************************* + * SwTxtFrm::IsHiddenNow() + *************************************************************************/ +// liefert nur sal_True zurueck, wenn das Outputdevice ein Printer ist +// und bHidden gesetzt ist. + +/*N*/ sal_Bool SwTxtFrm::IsHiddenNow() const +/*N*/ { +/*N*/ SwFrmSwapper aSwapper( this, sal_True ); +/*N*/ +/*N*/ if( !Frm().Width() && IsValid() && GetUpper()->IsValid() ) +/*N*/ //bei Stackueberlauf (StackHack) invalid! +/*N*/ { +/*N*/ ASSERT( Frm().Width(), "SwTxtFrm::IsHiddenNow: thin frame" ); +/*N*/ return sal_True; +/*N*/ } +/*N*/ +/*N*/ if( !GetTxtNode()->IsVisible() ) +/*N*/ { +/*N*/ const ViewShell *pVsh = GetShell(); +/*N*/ if ( !pVsh ) +/*N*/ return sal_False; +/*N*/ +/*N*/ return ! pVsh->GetWin() || +/*N*/ (!pVsh->GetViewOptions()->IsShowHiddenPara() && +/*N*/ !pVsh->GetViewOptions()->IsFldName()); +/*N*/ } +/*N*/ else +/*N*/ return sal_False; +/*N*/ } + + +/************************************************************************* + * SwTxtFrm::HideHidden() + *************************************************************************/ +// Entfernt die Anhaengsel des Textfrms wenn dieser hidden ist + +/*N*/ void SwTxtFrm::HideHidden() +/*N*/ {DBG_BF_ASSERT(0, "STRIP"); //STRIP001 +/*N*/ } + + +/************************************************************************* + * SwTxtFrm::FindBrk() + * + * Liefert die erste Trennmoeglichkeit in der aktuellen Zeile zurueck. + * Die Methode wird in SwTxtFrm::Format() benutzt, um festzustellen, ob + * die Vorgaengerzeile mitformatiert werden muss. + * nFound ist <= nEndLine. + *************************************************************************/ + +/*N*/ xub_StrLen SwTxtFrm::FindBrk( const XubString &rTxt, +/*N*/ const xub_StrLen nStart, const xub_StrLen nEnd ) const +/*N*/ { +/*N*/ xub_StrLen nFound = nStart; +/*N*/ const xub_StrLen nEndLine = Min( nEnd, rTxt.Len() ); +/*N*/ +/*N*/ // Wir ueberlesen erst alle Blanks am Anfang der Zeile (vgl. Bug 2235). +/*N*/ while( nFound <= nEndLine && ' ' == rTxt.GetChar( nFound ) ) +/*N*/ ++nFound; +/*N*/ +/*N*/ // Eine knifflige Sache mit den TxtAttr-Dummy-Zeichen (hier "$"): +/*N*/ // "Dr.$Meyer" am Anfang der zweiten Zeile. Dahinter ein Blank eingegeben +/*N*/ // und das Wort rutscht nicht in die erste Zeile, obwohl es ginge. +/*N*/ // Aus diesem Grund nehmen wir das Dummy-Zeichen noch mit. +/*N*/ while( nFound <= nEndLine && ' ' != rTxt.GetChar( nFound ) ) +/*N*/ ++nFound; +/*N*/ +/*N*/ return nFound; +/*N*/ } + +/************************************************************************* + * SwTxtFrm::IsIdxInside() + *************************************************************************/ + +/*N*/ sal_Bool SwTxtFrm::IsIdxInside( const xub_StrLen nPos, const xub_StrLen nLen ) const +/*N*/ { +/*N*/ if( GetOfst() > nPos + nLen ) // d.h., der Bereich liegt komplett vor uns. +/*N*/ return sal_False; +/*N*/ +/*N*/ if( !GetFollow() ) // der Bereich liegt nicht komplett vor uns, +/*N*/ return sal_True; // nach uns kommt niemand mehr. +/*N*/ +/*N*/ const xub_StrLen nMax = GetFollow()->GetOfst(); +/*N*/ +/*N*/ // der Bereich liegt nicht komplett hinter uns bzw. +/*N*/ // unser Text ist geloescht worden. +/*N*/ if( nMax > nPos || nMax > GetTxt().Len() ) +/*N*/ return sal_True; +/*N*/ +/*N*/ // changes made in the first line of a follow can modify the master +/*N*/ const SwParaPortion* pPara = GetFollow()->GetPara(); +/*N*/ return pPara && ( nPos <= nMax + pPara->GetLen() ); +/*N*/ } + +/************************************************************************* + * SwTxtFrm::InvalidateRange() + *************************************************************************/ +/*N*/ inline void SwTxtFrm::InvalidateRange(const SwCharRange &aRange, const long nD) +/*N*/ { +/*N*/ if ( IsIdxInside( aRange.Start(), aRange.Len() ) ) +/*N*/ _InvalidateRange( aRange, nD ); +/*N*/ } + +/************************************************************************* + * SwTxtFrm::_InvalidateRange() + *************************************************************************/ + +/*N*/ void SwTxtFrm::_InvalidateRange( const SwCharRange &aRange, const long nD) +/*N*/ { +/*N*/ if ( !HasPara() ) +/*N*/ { InvalidateSize(); +/*N*/ return; +/*N*/ } +/*N*/ +/*N*/ SetWidow( sal_False ); +/*N*/ SwParaPortion *pPara = GetPara(); +/*N*/ +/*N*/ sal_Bool bInv = sal_False; +/*N*/ if( 0 != nD ) +/*N*/ { +/*N*/ //Auf nDelta werden die Differenzen zwischen alter und +/*N*/ //neuer Zeilenlaenge aufaddiert, deshalb ist es negativ, +/*N*/ //wenn Zeichen eingefuegt wurden, positiv, wenn Zeichen +/*N*/ //geloescht wurden. +/*N*/ *(pPara->GetDelta()) += nD; +/*N*/ bInv = sal_True; +/*N*/ } +/*N*/ SwCharRange &rReformat = *(pPara->GetReformat()); +/*N*/ if(aRange != rReformat) { +/*N*/ if( STRING_LEN == rReformat.Len() ) +/*N*/ rReformat = aRange; +/*N*/ else +/*N*/ rReformat += aRange; +/*N*/ bInv = sal_True; +/*N*/ } +/*N*/ if(bInv) +/*N*/ { +/*N*/ // 90365: nD is passed to a follow two times +/*N*/ // if( GetFollow() ) +/*N*/ // ((SwTxtFrm*)GetFollow())->InvalidateRange( aRange, nD ); +/*N*/ InvalidateSize(); +/*N*/ } +/*N*/ } + +/************************************************************************* + * SwTxtFrm::CalcLineSpace() + *************************************************************************/ + +/*N*/ void SwTxtFrm::CalcLineSpace() +/*N*/ { +/*N*/ ASSERT( ! IsVertical() || ! IsSwapped(), +/*N*/ "SwTxtFrm::CalcLineSpace with swapped frame!" ) +/*N*/ +/*N*/ if( IsLocked() || !HasPara() ) +/*N*/ return; +/*N*/ +/*N*/ SwParaPortion *pPara; +/*N*/ if( GetDrawObjs() || +/*N*/ GetTxtNode()->GetSwAttrSet().GetLRSpace().IsAutoFirst() || +/*N*/ ( pPara = GetPara() )->IsFixLineHeight() ) +/*N*/ { +/*?*/ Init(); +/*?*/ return; +/*N*/ } +/*N*/ +/*N*/ Size aNewSize( Prt().SSize() ); +/*N*/ +/*N*/ SwTxtFormatInfo aInf( this ); +/*N*/ SwTxtFormatter aLine( this, &aInf ); +/*N*/ if( aLine.GetDropLines() ) +/*N*/ { +/*N*/ Init(); +/*N*/ return; +/*N*/ } +/*N*/ +/*N*/ aLine.Top(); +/*N*/ aLine.RecalcRealHeight(); +/*N*/ +/*N*/ aNewSize.Height() = (aLine.Y() - Frm().Top()) + aLine.GetLineHeight(); +/*N*/ +/*N*/ SwTwips nDelta = aNewSize.Height() - Prt().Height(); +/*N*/ // 4291: Unterlauf bei Flys +/*N*/ if( aInf.GetTxtFly()->IsOn() ) +/*N*/ { +/*N*/ SwRect aFrm( Frm() ); +/*N*/ if( nDelta < 0 ) +/*N*/ aFrm.Height( Prt().Height() ); +/*N*/ else +/*N*/ aFrm.Height( aNewSize.Height() ); +/*N*/ if( aInf.GetTxtFly()->Relax( aFrm ) ) +/*N*/ { +/*?*/ Init(); +/*?*/ return; +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ if( nDelta ) +/*N*/ { +/*N*/ SwTxtFrmBreak aBreak( this ); +/*N*/ if( GetFollow() || aBreak.IsBreakNow( aLine ) ) +/*N*/ { +/*N*/ // Wenn es einen Follow() gibt, oder wenn wir an dieser +/*N*/ // Stelle aufbrechen muessen, so wird neu formatiert. +/*N*/ Init(); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ // Alles nimmt seinen gewohnten Gang ... +/*N*/ pPara->SetPrepAdjust(); +/*N*/ pPara->SetPrep(); +/*N*/ #ifdef USED +/*N*/ if (nDelta > 0) +/*N*/ Grow(nDelta,pHeight); +/*N*/ else +/*N*/ Shrink(-nDelta,pHeight); +/*N*/ ASSERT( GetPara(), "+SwTxtFrm::CalcLineSpace: missing format information" ); +/*N*/ if( pPara ) +/*N*/ pPara->GetRepaint()->SSize( Prt().SSize() ); +/*N*/ #endif +/*N*/ } +/*N*/ } +/*N*/ } + +#define SET_WRONG( nPos, nCnt, fnFunc ) \ +{ \ + if ( !IsFollow() ) \ + { \ + if( GetTxtNode()->GetWrong() ) \ + GetTxtNode()->GetWrong()->fnFunc( nPos, nCnt ); \ + else if ( ! GetTxtNode()->IsWrongDirty() ) \ + { \ + GetTxtNode()->SetWrong( new SwWrongList() ); \ + GetTxtNode()->GetWrong()->SetInvalid( nPos, nPos + ( nCnt > 0 ? nCnt : 1 ) ); \ + } \ + GetNode()->SetWrongDirty( sal_True ); \ + GetNode()->SetAutoCompleteWordDirty( sal_True ); \ + } \ + SwPageFrm *pPage = FindPageFrm(); \ + if( pPage ) \ + { \ + pPage->InvalidateSpelling(); \ + pPage->InvalidateAutoCompleteWords(); \ + } \ +} + +#define SET_SCRIPT_INVAL( nPos )\ +{ \ + if( GetPara() ) \ + GetPara()->GetScriptInfo().SetInvalidity( nPos ); \ +} + +/*N*/ void lcl_ModifyOfst( SwTxtFrm* pFrm, xub_StrLen nPos, xub_StrLen nLen ) +/*N*/ { +/*N*/ if( nLen < 0 ) +/*N*/ nPos -= nLen; +/*N*/ while( pFrm && pFrm->GetOfst() <= nPos ) +/*N*/ pFrm = pFrm->GetFollow(); +/*N*/ while( pFrm ) +/*N*/ { +/*N*/ pFrm->ManipOfst( pFrm->GetOfst() + nLen ); +/*N*/ pFrm = pFrm->GetFollow(); +/*N*/ } +/*N*/ } + +/************************************************************************* + * SwTxtFrm::Modify() + *************************************************************************/ + +/*M*/ void SwTxtFrm::Modify( SfxPoolItem *pOld, SfxPoolItem *pNew ) +/*M*/ { +/*M*/ const MSHORT nWhich = pOld ? pOld->Which() : pNew ? pNew->Which() : 0; +/*M*/ +/*M*/ //Wuensche die FrmAttribute betreffen werden von der Basisklasse +/*M*/ //verarbeitet. +/*M*/ if( IsInRange( aFrmFmtSetRange, nWhich ) || RES_FMT_CHG == nWhich ) +/*M*/ { +/*M*/ SwCntntFrm::Modify( pOld, pNew ); +/*M*/ if( nWhich == RES_FMT_CHG && GetShell() ) +/*M*/ { +/*M*/ // Collection hat sich geaendert +/*M*/ Prepare( PREP_CLEAR ); +/*M*/ _InvalidatePrt(); +/*M*/ SET_WRONG( 0, STRING_LEN, Invalidate ); +/*N*/ SetDerivedR2L( sal_False ); +/*N*/ CheckDirChange(); +/*N*/ // OD 09.12.2002 #105576# - Force complete paint due to existing +/*N*/ // indents. +/*N*/ SetCompletePaint(); +/*M*/ InvalidateLineNum(); +/*M*/ } +/*M*/ return; +/*M*/ } +/*M*/ +/*M*/ // Im gelockten Zustand werden keine Bestellungen angenommen. +/*M*/ if( IsLocked() ) +/*M*/ return; +/*M*/ +/*M*/ // Dies spart Stack, man muss nur aufpassen, +/*M*/ // dass sie Variablen gesetzt werden. +/*M*/ xub_StrLen nPos, nLen; +/*M*/ sal_Bool bSetFldsDirty = sal_False; +/*M*/ sal_Bool bRecalcFtnFlag = sal_False; +/*M*/ +/*M*/ switch( nWhich ) +/*M*/ { +/*M*/ case RES_LINENUMBER: +/*M*/ { +/*M*/ InvalidateLineNum(); +/*M*/ } +/*M*/ break; +/*M*/ case RES_INS_CHR: +/*M*/ { +/*M*/ nPos = ((SwInsChr*)pNew)->nPos; +/*M*/ InvalidateRange( SwCharRange( nPos, 1 ), 1 ); +/*M*/ SET_WRONG( nPos, 1, Move ) +/*M*/ SET_SCRIPT_INVAL( nPos ) +/*M*/ bSetFldsDirty = sal_True; +/*M*/ if( HasFollow() ) +/*M*/ lcl_ModifyOfst( this, nPos, 1 ); +/*M*/ } +/*M*/ break; +/*M*/ case RES_INS_TXT: +/*M*/ { +/*M*/ nPos = ((SwInsTxt*)pNew)->nPos; +/*M*/ nLen = ((SwInsTxt*)pNew)->nLen; +/*M*/ if( IsIdxInside( nPos, nLen ) ) +/*M*/ { +/*M*/ if( !nLen ) +/*M*/ { +/*M*/ // 6969: Aktualisierung der NumPortions auch bei leeren Zeilen! +/*M*/ if( nPos ) +/*M*/ InvalidateSize(); +/*M*/ else +/*M*/ Prepare( PREP_CLEAR ); +/*M*/ } +/*M*/ else +/*M*/ _InvalidateRange( SwCharRange( nPos, nLen ), nLen ); +/*M*/ } +/*M*/ SET_WRONG( nPos, nLen, Move ) +/*M*/ SET_SCRIPT_INVAL( nPos ) +/*M*/ bSetFldsDirty = sal_True; +/*M*/ if( HasFollow() ) +/*M*/ lcl_ModifyOfst( this, nPos, nLen ); +/*M*/ } +/*M*/ break; +/*M*/ case RES_DEL_CHR: +/*M*/ { +/*M*/ nPos = ((SwDelChr*)pNew)->nPos; +/*M*/ InvalidateRange( SwCharRange( nPos, 1 ), -1 ); +/*M*/ SET_WRONG( nPos, -1, Move ) +/*M*/ SET_SCRIPT_INVAL( nPos ) +/*M*/ bSetFldsDirty = bRecalcFtnFlag = sal_True; +/*M*/ if( HasFollow() ) +/*M*/ lcl_ModifyOfst( this, nPos, -1 ); +/*M*/ } +/*M*/ break; +/*M*/ case RES_DEL_TXT: +/*M*/ { +/*M*/ nPos = ((SwDelTxt*)pNew)->nStart; +/*M*/ nLen = ((SwDelTxt*)pNew)->nLen; +/*M*/ long m = nLen; +/*M*/ m *= -1; +/*M*/ if( IsIdxInside( nPos, nLen ) ) +/*M*/ { +/*M*/ if( !nLen ) +/*M*/ InvalidateSize(); +/*M*/ else +/*M*/ InvalidateRange( SwCharRange( nPos, 1 ), m ); +/*M*/ } +/*M*/ SET_WRONG( nPos, m, Move ) +/*M*/ SET_SCRIPT_INVAL( nPos ) +/*M*/ bSetFldsDirty = bRecalcFtnFlag = sal_True; +/*M*/ if( HasFollow() ) +/*M*/ lcl_ModifyOfst( this, nPos, nLen ); +/*M*/ } +/*M*/ break; +/*M*/ case RES_UPDATE_ATTR: +/*M*/ { +/*M*/ nPos = ((SwUpdateAttr*)pNew)->nStart; +/*M*/ nLen = ((SwUpdateAttr*)pNew)->nEnd - nPos; +/*M*/ if( IsIdxInside( nPos, nLen ) ) +/*M*/ { +/*M*/ // Es muss in jedem Fall neu formatiert werden, +/*M*/ // auch wenn der invalidierte Bereich null ist. +/*M*/ // Beispiel: leere Zeile, 14Pt einstellen ! +/*M*/ // if( !nLen ) nLen = 1; +/*M*/ +/*M*/ // 6680: FtnNummern muessen formatiert werden. +/*M*/ if( !nLen ) +/*M*/ nLen = 1; +/*M*/ +/*M*/ _InvalidateRange( SwCharRange( nPos, nLen) ); +/*M*/ MSHORT nTmp = ((SwUpdateAttr*)pNew)->nWhichAttr; +/*M*/ +/*M*/ if( ! nTmp || RES_TXTATR_CHARFMT == nTmp || +/*M*/ RES_FMT_CHG == nTmp || RES_ATTRSET_CHG == nTmp ) +/*M*/ { +/*M*/ SET_WRONG( nPos, nPos + nLen, Invalidate ) +/*M*/ SET_SCRIPT_INVAL( nPos ) +/*M*/ } +/*N*/ else if ( RES_CHRATR_LANGUAGE == nTmp || +/*N*/ RES_CHRATR_CJK_LANGUAGE == nTmp || +/*N*/ RES_CHRATR_CTL_LANGUAGE == nTmp ) +/*M*/ SET_WRONG( nPos, nPos + nLen, Invalidate ) +/*M*/ else if ( RES_CHRATR_FONT == nTmp || RES_CHRATR_CJK_FONT == nTmp || +/*M*/ RES_CHRATR_CTL_FONT == nTmp ) +/*M*/ SET_SCRIPT_INVAL( nPos ) +/*M*/ } +/*M*/ } +/*M*/ break; +/*M*/ case RES_OBJECTDYING: +/*M*/ break; +/*M*/ +/*M*/ case RES_PARATR_LINESPACING: +/*M*/ { +/*M*/ CalcLineSpace(); +/*M*/ InvalidateSize(); +/*M*/ _InvalidatePrt(); +/*M*/ if( IsInSct() && !GetPrev() ) +/*M*/ { +/*M*/ SwSectionFrm *pSect = FindSctFrm(); +/*M*/ if( pSect->ContainsAny() == this ) +/*M*/ pSect->InvalidatePrt(); +/*M*/ } +/*M*/ SwFrm* pNxt; +/*M*/ if ( 0 != ( pNxt = GetIndNext() ) ) +/*M*/ { +/*M*/ pNxt->_InvalidatePrt(); +/*M*/ if ( pNxt->IsLayoutFrm() ) +/*M*/ pNxt->InvalidatePage(); +/*M*/ } +/*M*/ SetCompletePaint(); +/*M*/ } +/*M*/ break; +/*M*/ case RES_TXTATR_FIELD: +/*M*/ { +/*M*/ nPos = *((SwFmtFld*)pNew)->GetTxtFld()->GetStart(); +/*M*/ if( IsIdxInside( nPos, 1 ) ) +/*M*/ { +/*M*/ if( pNew == pOld ) +/*M*/ { +/*M*/ // Nur repainten +/*M*/ // opt: invalidate aufs Window ? +/*M*/ InvalidatePage(); +/*M*/ SetCompletePaint(); +/*M*/ } +/*M*/ else +/*M*/ _InvalidateRange( SwCharRange( nPos, 1 ) ); +/*M*/ } +/*M*/ bSetFldsDirty = sal_True; +/*M*/ } +/*M*/ break; +/*M*/ case RES_TXTATR_FTN : +/*M*/ { +/*M*/ nPos = *((SwFmtFtn*)pNew)->GetTxtFtn()->GetStart(); +/*M*/ if( IsInFtn() || IsIdxInside( nPos, 1 ) ) +/*M*/ Prepare( PREP_FTN, ((SwFmtFtn*)pNew)->GetTxtFtn() ); +/*M*/ break; +/*M*/ } +/*M*/ +/*M*/ case RES_ATTRSET_CHG: +/*M*/ { +/*M*/ InvalidateLineNum(); +/*M*/ +/*M*/ SwAttrSet& rNewSet = *((SwAttrSetChg*)pNew)->GetChgSet(); +/*M*/ const SfxPoolItem* pItem; +/*M*/ int nClear = 0; +/*M*/ MSHORT nCount = rNewSet.Count(); +/*M*/ +/*M*/ if( SFX_ITEM_SET == rNewSet.GetItemState( RES_TXTATR_FTN, +/*M*/ sal_False, &pItem )) +/*M*/ { +/*M*/ nPos = *((SwFmtFtn*)pItem)->GetTxtFtn()->GetStart(); +/*M*/ if( IsIdxInside( nPos, 1 ) ) +/*M*/ Prepare( PREP_FTN, pNew ); +/*M*/ nClear = 0x01; +/*M*/ --nCount; +/*M*/ } +/*M*/ +/*M*/ if( SFX_ITEM_SET == rNewSet.GetItemState( RES_TXTATR_FIELD, +/*M*/ sal_False, &pItem )) +/*M*/ { +/*M*/ nPos = *((SwFmtFld*)pItem)->GetTxtFld()->GetStart(); +/*M*/ if( IsIdxInside( nPos, 1 ) ) +/*M*/ { +/*M*/ const SfxPoolItem& rOldItem = ((SwAttrSetChg*)pOld)-> +/*M*/ GetChgSet()->Get( RES_TXTATR_FIELD ); +/*M*/ if( pItem == &rOldItem ) +/*M*/ { +/*M*/ // Nur repainten +/*M*/ // opt: invalidate aufs Window ? +/*M*/ InvalidatePage(); +/*M*/ SetCompletePaint(); +/*M*/ } +/*M*/ else +/*M*/ _InvalidateRange( SwCharRange( nPos, 1 ) ); +/*M*/ } +/*M*/ nClear |= 0x02; +/*M*/ --nCount; +/*M*/ } +/*M*/ sal_Bool bLineSpace = SFX_ITEM_SET == rNewSet.GetItemState( +/*M*/ RES_PARATR_LINESPACING, sal_False ), +/*M*/ bRegister = SFX_ITEM_SET == rNewSet.GetItemState( +/*M*/ RES_PARATR_REGISTER, sal_False ); +/*M*/ if ( bLineSpace || bRegister ) +/*M*/ { +/*M*/ Prepare( bRegister ? PREP_REGISTER : PREP_ADJUST_FRM ); +/*M*/ CalcLineSpace(); +/*M*/ InvalidateSize(); +/*M*/ _InvalidatePrt(); +/*M*/ SwFrm* pNxt; +/*M*/ if ( 0 == ( pNxt = GetIndNext() ) && +/*M*/ bLineSpace && IsInFtn() ) +/*M*/ pNxt = FindNext(); +/*M*/ if( pNxt ) +/*M*/ { +/*M*/ pNxt->_InvalidatePrt(); +/*M*/ if ( pNxt->IsLayoutFrm() ) +/*M*/ { +/*M*/ if( pNxt->IsSctFrm() ) +/*M*/ { +/*M*/ SwFrm* pCnt = ((SwSectionFrm*)pNxt)->ContainsAny(); +/*M*/ if( pCnt ) +/*M*/ pCnt->_InvalidatePrt(); +/*M*/ } +/*M*/ pNxt->InvalidatePage(); +/*M*/ } +/*M*/ } +/*M*/ +/*M*/ SetCompletePaint(); +/*M*/ nClear |= 0x04; +/*M*/ if ( bLineSpace ) +/*M*/ { +/*M*/ --nCount; +/*M*/ if( IsInSct() && !GetPrev() ) +/*M*/ { +/*M*/ SwSectionFrm *pSect = FindSctFrm(); +/*M*/ if( pSect->ContainsAny() == this ) +/*M*/ pSect->InvalidatePrt(); +/*M*/ } +/*M*/ } +/*M*/ if ( bRegister ) +/*M*/ --nCount; +/*M*/ } +/*M*/ if ( SFX_ITEM_SET == rNewSet.GetItemState( RES_PARATR_SPLIT, +/*M*/ sal_False )) +/*M*/ { +/*M*/ if ( GetPrev() ) +/*M*/ CheckKeep(); +/*M*/ Prepare( PREP_CLEAR ); +/*M*/ InvalidateSize(); +/*M*/ nClear |= 0x08; +/*M*/ --nCount; +/*M*/ } +/*M*/ +/*M*/ if( SFX_ITEM_SET == rNewSet.GetItemState( RES_BACKGROUND, sal_False) +/*M*/ && !IsFollow() && GetDrawObjs() ) +/*M*/ { +/*M*/ SwDrawObjs *pObjs = GetDrawObjs(); +/*M*/ for ( int i = 0; GetDrawObjs() && i < int(pObjs->Count()); ++i ) +/*M*/ { +/*M*/ SdrObject *pO = (*pObjs)[MSHORT(i)]; +/*M*/ if ( pO->IsWriterFlyFrame() ) +/*M*/ { +/*M*/ SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pO)->GetFlyFrm(); +/*M*/ if( !pFly->IsFlyInCntFrm() ) +/*M*/ { +/*M*/ const SvxBrushItem &rBack = +/*M*/ pFly->GetAttrSet()->GetBackground(); +/*M*/ /// OD 20.08.2002 #99657# #GetTransChg# +/*M*/ /// following condition determines, if the fly frame +/*M*/ /// "inherites" the background color of text frame. +/*M*/ /// This is the case, if fly frame background +/*M*/ /// color is "no fill"/"auto fill" and if the fly frame +/*M*/ /// has no background graphic. +/*M*/ /// Thus, check complete fly frame background +/*M*/ /// color and *not* only its transparency value +/*M*/ if ( (rBack.GetColor() == COL_TRANSPARENT) && +/*M*/ ///if( rBack.GetColor().GetTransparency() && +/*M*/ rBack.GetGraphicPos() == GPOS_NONE ) +/*M*/ { +/*M*/ pFly->SetCompletePaint(); +/*M*/ pFly->InvalidatePage(); +/*M*/ } +/*M*/ } +/*M*/ } +/*M*/ } +/*M*/ } +/*M*/ +/*M*/ if ( SFX_ITEM_SET == +/*M*/ rNewSet.GetItemState( RES_TXTATR_CHARFMT, sal_False ) ) +/*M*/ { +/*M*/ SET_WRONG( 0, STRING_LEN, Invalidate ) +/*M*/ SET_SCRIPT_INVAL( 0 ) +/*M*/ } +/*M*/ else if ( SFX_ITEM_SET == +/*N*/ rNewSet.GetItemState( RES_CHRATR_LANGUAGE, sal_False ) || +/*N*/ SFX_ITEM_SET == +/*N*/ rNewSet.GetItemState( RES_CHRATR_CJK_LANGUAGE, sal_False ) || +/*N*/ SFX_ITEM_SET == +/*N*/ rNewSet.GetItemState( RES_CHRATR_CTL_LANGUAGE, sal_False ) ) +/*M*/ SET_WRONG( 0, STRING_LEN, Invalidate ) +/*M*/ else if ( SFX_ITEM_SET == +/*M*/ rNewSet.GetItemState( RES_CHRATR_FONT, sal_False ) || +/*M*/ SFX_ITEM_SET == +/*M*/ rNewSet.GetItemState( RES_CHRATR_CJK_FONT, sal_False ) || +/*M*/ SFX_ITEM_SET == +/*M*/ rNewSet.GetItemState( RES_CHRATR_CTL_FONT, sal_False ) ) +/*M*/ SET_SCRIPT_INVAL( 0 ) +/*M*/ else if ( SFX_ITEM_SET == +/*M*/ rNewSet.GetItemState( RES_FRAMEDIR, sal_False ) ) +/*M*/ { +/*M*/ SetDerivedR2L( sal_False ); +/*M*/ CheckDirChange(); +/*N*/ // OD 09.12.2002 #105576# - Force complete paint due to existing +/*N*/ // indents. +/*N*/ SetCompletePaint(); +/*M*/ } +/*M*/ +/*M*/ +/*M*/ if( nCount ) +/*M*/ { +/*M*/ if( GetShell() ) +/*M*/ { +/*M*/ Prepare( PREP_CLEAR ); +/*M*/ _InvalidatePrt(); +/*M*/ } +/*M*/ +/*M*/ if( nClear ) +/*M*/ { +/*M*/ SwAttrSetChg aOldSet( *(SwAttrSetChg*)pOld ); +/*M*/ SwAttrSetChg aNewSet( *(SwAttrSetChg*)pNew ); +/*M*/ +/*M*/ if( 0x01 & nClear ) +/*M*/ { +/*M*/ aOldSet.ClearItem( RES_TXTATR_FTN ); +/*M*/ aNewSet.ClearItem( RES_TXTATR_FTN ); +/*M*/ } +/*M*/ if( 0x02 & nClear ) +/*M*/ { +/*M*/ aOldSet.ClearItem( RES_TXTATR_FIELD ); +/*M*/ aNewSet.ClearItem( RES_TXTATR_FIELD ); +/*M*/ } +/*M*/ if ( 0x04 & nClear ) +/*M*/ { +/*M*/ if ( bLineSpace ) +/*M*/ { +/*M*/ aOldSet.ClearItem( RES_PARATR_LINESPACING ); +/*M*/ aNewSet.ClearItem( RES_PARATR_LINESPACING ); +/*M*/ } +/*M*/ if ( bRegister ) +/*M*/ { +/*M*/ aOldSet.ClearItem( RES_PARATR_REGISTER ); +/*M*/ aNewSet.ClearItem( RES_PARATR_REGISTER ); +/*M*/ } +/*M*/ } +/*M*/ if ( 0x08 & nClear ) +/*M*/ { +/*M*/ aOldSet.ClearItem( RES_PARATR_SPLIT ); +/*M*/ aNewSet.ClearItem( RES_PARATR_SPLIT ); +/*M*/ } +/*M*/ SwCntntFrm::Modify( &aOldSet, &aNewSet ); +/*M*/ } +/*M*/ else +/*M*/ SwCntntFrm::Modify( pOld, pNew ); +/*M*/ } +/*M*/ } +/*M*/ break; +/*M*/ +/* Seit dem neuen Blocksatz muessen wir immer neu formatieren: + case RES_PARATR_ADJUST: + { + if( GetShell() ) + { + Prepare( PREP_CLEAR ); + } + break; + } +*/ +/*M*/ // 6870: SwDocPosUpdate auswerten. +/*M*/ case RES_DOCPOS_UPDATE: +/*M*/ { +/*M*/ if( pOld && pNew ) +/*M*/ { +/*M*/ const SwDocPosUpdate *pDocPos = (const SwDocPosUpdate*)pOld; +/*M*/ if( pDocPos->nDocPos <= aFrm.Top() ) +/*M*/ { +/*M*/ const SwFmtFld *pFld = (const SwFmtFld *)pNew; +/*M*/ InvalidateRange( +/*M*/ SwCharRange( *pFld->GetTxtFld()->GetStart(), 1 ) ); +/*M*/ } +/*M*/ } +/*M*/ break; +/*M*/ } +/*M*/ case RES_PARATR_SPLIT: +/*M*/ if ( GetPrev() ) +/*M*/ CheckKeep(); +/*M*/ Prepare( PREP_CLEAR ); +/*M*/ bSetFldsDirty = sal_True; +/*M*/ break; +/*M*/ case RES_FRAMEDIR : +/*M*/ SetDerivedR2L( sal_False ); +/*M*/ CheckDirChange(); +/*M*/ break; +/*M*/ default: +/*M*/ { +/*M*/ Prepare( PREP_CLEAR ); +/*M*/ _InvalidatePrt(); +/*M*/ if ( !nWhich ) +/*M*/ { +/*M*/ //Wird z.B. bei HiddenPara mit 0 gerufen. +/*M*/ SwFrm *pNxt; +/*M*/ if ( 0 != (pNxt = FindNext()) ) +/*M*/ pNxt->InvalidatePrt(); +/*M*/ } +/*M*/ } +/*M*/ } // switch +/*M*/ +/*M*/ if( bSetFldsDirty ) +/*M*/ GetNode()->GetDoc()->SetFieldsDirty( sal_True, GetNode(), 1 ); +/*M*/ +/*M*/ if ( bRecalcFtnFlag ) +/*M*/ CalcFtnFlag(); +/*M*/ } + +/*M*/ sal_Bool SwTxtFrm::GetInfo( SfxPoolItem &rHnt ) const +/*M*/ { +/*M*/ if ( RES_VIRTPAGENUM_INFO == rHnt.Which() && IsInDocBody() && ! IsFollow() ) +/*M*/ { +/*M*/ SwVirtPageNumInfo &rInfo = (SwVirtPageNumInfo&)rHnt; +/*M*/ const SwPageFrm *pPage = FindPageFrm(); +/*M*/ if ( pPage ) +/*M*/ { +/*M*/ if ( pPage == rInfo.GetOrigPage() && !GetPrev() ) +/*M*/ { +/*M*/ //Das sollte er sein (kann allenfalls temporaer anders sein, +/*M*/ // sollte uns das beunruhigen?) +/*M*/ rInfo.SetInfo( pPage, this ); +/*M*/ return sal_False; +/*M*/ } +/*M*/ if ( pPage->GetPhyPageNum() < rInfo.GetOrigPage()->GetPhyPageNum() && +/*M*/ (!rInfo.GetPage() || pPage->GetPhyPageNum() > rInfo.GetPage()->GetPhyPageNum())) +/*M*/ { +/*M*/ //Das koennte er sein. +/*M*/ rInfo.SetInfo( pPage, this ); +/*M*/ } +/*M*/ } +/*M*/ } +/*M*/ return sal_True; +/*M*/ } + +/************************************************************************* + * SwTxtFrm::PrepWidows() + *************************************************************************/ + +/*M*/ void SwTxtFrm::PrepWidows( const MSHORT nNeed, sal_Bool bNotify ) +/*M*/ { +/*M*/ ASSERT(GetFollow() && nNeed, "+SwTxtFrm::Prepare: lost all friends"); +/*M*/ +/*M*/ SwParaPortion *pPara = GetPara(); +/*M*/ if ( !pPara ) +/*M*/ return; +/*M*/ pPara->SetPrepWidows( sal_True ); +/*M*/ +/*M*/ // These two lines of code have been deleted for #102340#. +/*M*/ // Obviously the widow control does not work if we have a +/*M*/ // pMaster->pFollow->pFollow situation: +/*M*/ +/*M*/ // returnen oder nicht ist hier die Frage. +/*M*/ // Ohne IsLocked() ist 5156 gefaehrlich, +/*M*/ // ohne IsFollow() werden die Orphans unterdrueckt: 6968. +/*M*/ // Abfrage auf IsLocked erst hier, weil das Flag gesetzt werden soll. +/*M*/ // if( IsLocked() && IsFollow() ) +/*M*/ // return; +/*M*/ +/*M*/ MSHORT nHave = nNeed; +/*M*/ +/*M*/ // Wir geben ein paar Zeilen ab und schrumpfen im CalcPreps() +/*M*/ SWAP_IF_NOT_SWAPPED( this ) +/*M*/ +/*M*/ SwTxtSizeInfo aInf( this ); +/*M*/ SwTxtMargin aLine( this, &aInf ); +/*M*/ aLine.Bottom(); +/*M*/ xub_StrLen nTmpLen = aLine.GetCurr()->GetLen(); +/*M*/ while( nHave && aLine.PrevLine() ) +/*M*/ { +/*M*/ if( nTmpLen ) +/*M*/ --nHave; +/*M*/ nTmpLen = aLine.GetCurr()->GetLen(); +/*M*/ } +/*M*/ // In dieser Ecke tummelten sich einige Bugs: 7513, 7606. +/*M*/ // Wenn feststeht, dass Zeilen abgegeben werden koennen, +/*M*/ // muss der Master darueber hinaus die Widow-Regel ueberpruefen. +/*M*/ if( !nHave ) +/*M*/ { +/*M*/ sal_Bool bSplit; +/*M*/ if( !IsFollow() ) //Nur ein Master entscheidet ueber Orphans +/*M*/ { +/*M*/ const WidowsAndOrphans aWidOrp( this ); +/*M*/ bSplit = ( aLine.GetLineNr() >= aWidOrp.GetOrphansLines() && +/*M*/ aLine.GetLineNr() >= aLine.GetDropLines() ); +/*M*/ } +/*M*/ else +/*M*/ bSplit = sal_True; +/*M*/ +/*M*/ if( bSplit ) +/*M*/ { +/*M*/ GetFollow()->SetOfst( aLine.GetEnd() ); +/*M*/ aLine.TruncLines( sal_True ); +/*M*/ if( pPara->IsFollowField() ) +/*M*/ GetFollow()->SetFieldFollow( sal_True ); +/*M*/ } +/*M*/ } +/*M*/ if ( bNotify ) +/*M*/ { +/*M*/ _InvalidateSize(); +/*M*/ InvalidatePage(); +/*M*/ } +/*M*/ +/*M*/ UNDO_SWAP( this ) +/*M*/ } + +/************************************************************************* + * SwTxtFrm::Prepare + *************************************************************************/ + +/*N*/ sal_Bool lcl_ErgoVadis( SwTxtFrm* pFrm, xub_StrLen &rPos, const PrepareHint ePrep ) +/*N*/ { +/*N*/ const SwFtnInfo &rFtnInfo = pFrm->GetNode()->GetDoc()->GetFtnInfo(); +/*N*/ if( ePrep == PREP_ERGOSUM ) +/*N*/ { +/*?*/ if( !rFtnInfo.aErgoSum.Len() ) +/*?*/ return sal_False;; +/*?*/ rPos = pFrm->GetOfst(); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ if( !rFtnInfo.aQuoVadis.Len() ) +/*N*/ return sal_False; +/*?*/ if( pFrm->HasFollow() ) +/*?*/ rPos = pFrm->GetFollow()->GetOfst(); +/*?*/ else +/*?*/ rPos = pFrm->GetTxt().Len(); +/*?*/ if( rPos ) +/*?*/ --rPos; // unser letztes Zeichen +/*N*/ } +/*N*/ return sal_True; +/*N*/ } + +/*N*/ void SwTxtFrm::Prepare( const PrepareHint ePrep, const void* pVoid, +/*N*/ sal_Bool bNotify ) +/*N*/ { +/*N*/ SwFrmSwapper aSwapper( this, sal_False ); +/*N*/ +/*N*/ #if OSL_DEBUG_LEVEL > 1 +/*N*/ const SwTwips nDbgY = Frm().Top(); +/*N*/ #endif +/*N*/ +/*N*/ if ( IsEmpty() ) +/*N*/ { +/*N*/ switch ( ePrep ) +/*N*/ { +/*N*/ case PREP_BOSS_CHGD: +/*N*/ SetInvalidVert( TRUE ); // Test +/*N*/ case PREP_WIDOWS_ORPHANS: +/*N*/ case PREP_WIDOWS: +/*N*/ case PREP_FTN_GONE : return; +/*N*/ +/*N*/ case PREP_POS_CHGD : +/*N*/ { +/*N*/ // Auch in (spaltigen) Bereichen ist ein InvalidateSize notwendig, +/*N*/ // damit formatiert wird und ggf. das bUndersized gesetzt wird. +/*N*/ if( IsInFly() || IsInSct() ) +/*N*/ { +/*N*/ SwTwips nTmpBottom = GetUpper()->Frm().Top() + +/*N*/ GetUpper()->Prt().Bottom(); +/*N*/ if( nTmpBottom < Frm().Bottom() ) +/*N*/ break; +/*N*/ } +/*N*/ // Gibt es ueberhaupt Flys auf der Seite ? +/*N*/ SwTxtFly aTxtFly( this ); +/*N*/ if( aTxtFly.IsOn() ) +/*N*/ { +/*N*/ // Ueberlappt irgendein Fly ? +/*N*/ aTxtFly.Relax(); +/*N*/ if ( aTxtFly.IsOn() || IsUndersized() ) +/*N*/ break; +/*N*/ } +/*N*/ if( GetTxtNode()->GetSwAttrSet().GetRegister().GetValue()) +/*N*/ break; +/*N*/ +/*N*/ GETGRID( FindPageFrm() ) +/*N*/ if ( pGrid && GetTxtNode()->GetSwAttrSet().GetParaGrid().GetValue() ) +/*N*/ break; +/*N*/ +/*N*/ return; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ if( !HasPara() && PREP_MUST_FIT != ePrep ) +/*N*/ { +/*N*/ SetInvalidVert( TRUE ); // Test +/*N*/ ASSERT( !IsLocked(), "SwTxtFrm::Prepare: three of a perfect pair" ); +/*N*/ if ( bNotify ) +/*N*/ InvalidateSize(); +/*N*/ else +/*N*/ _InvalidateSize(); +/*N*/ return; +/*N*/ } +/*N*/ +/*N*/ //Objekt mit Locking aus dem Cache holen. +/*N*/ SwTxtLineAccess aAccess( this ); +/*N*/ SwParaPortion *pPara = aAccess.GetPara(); +/*N*/ +/*N*/ switch( ePrep ) +/*N*/ { +/*?*/ case PREP_MOVEFTN : Frm().Height(0); +/*?*/ Prt().Height(0); +/*?*/ _InvalidatePrt(); +/*?*/ _InvalidateSize(); +/*N*/ // KEIN break +/*N*/ case PREP_ADJUST_FRM : pPara->SetPrepAdjust( sal_True ); +/*N*/ if( IsFtnNumFrm() != pPara->IsFtnNum() || +/*N*/ IsUndersized() ) +/*N*/ { +/*N*/ InvalidateRange( SwCharRange( 0, 1 ), 1); +/*N*/ if( GetOfst() && !IsFollow() ) +/*?*/ _SetOfst( 0 ); +/*N*/ } +/*N*/ break; +/*?*/ case PREP_MUST_FIT : pPara->SetPrepMustFit( sal_True ); +/*N*/ /* no break here */ +/*N*/ case PREP_WIDOWS_ORPHANS : pPara->SetPrepAdjust( sal_True ); +/*N*/ break; +/*N*/ +/*N*/ case PREP_WIDOWS : +/*N*/ // MustFit ist staerker als alles anderes +/*N*/ if( pPara->IsPrepMustFit() ) +/*N*/ return; +/*N*/ // Siehe Kommentar in WidowsAndOrphans::FindOrphans und CalcPreps() +/*N*/ PrepWidows( *(const MSHORT *)pVoid, bNotify ); +/*N*/ break; +/*N*/ +/*N*/ case PREP_FTN : +/*N*/ { +/*N*/ SwTxtFtn *pFtn = (SwTxtFtn *)pVoid; +/*N*/ if( IsInFtn() ) +/*N*/ { +/*N*/ // Bin ich der erste TxtFrm einer Fussnote ? +/*N*/ if( !GetPrev() ) +/*N*/ // Wir sind also ein TxtFrm der Fussnote, die +/*N*/ // die Fussnotenzahl zur Anzeige bringen muss. +/*N*/ // Oder den ErgoSum-Text... +/*N*/ InvalidateRange( SwCharRange( 0, 1 ), 1); +/*N*/ +/*N*/ if( !GetNext() ) +/*N*/ { +/*N*/ // Wir sind der letzte Ftn, jetzt muessten die +/*N*/ // QuoVadis-Texte geupdated werden. +/*N*/ const SwFtnInfo &rFtnInfo = GetNode()->GetDoc()->GetFtnInfo(); +/*N*/ if( !pPara->UpdateQuoVadis( rFtnInfo.aQuoVadis ) ) +/*N*/ { +/*N*/ xub_StrLen nPos = pPara->GetParLen(); +/*N*/ if( nPos ) +/*N*/ --nPos; +/*N*/ InvalidateRange( SwCharRange( nPos, 1 ), 1); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ // Wir sind also der TxtFrm _mit_ der Fussnote +/*N*/ const xub_StrLen nPos = *pFtn->GetStart(); +/*N*/ InvalidateRange( SwCharRange( nPos, 1 ), 1); +/*N*/ } +/*N*/ break; +/*N*/ } +/*N*/ case PREP_BOSS_CHGD : +/*N*/ { +/*N*/ // Test +/*N*/ { +/*N*/ SetInvalidVert( FALSE ); +/*N*/ BOOL bOld = IsVertical(); +/*N*/ SetInvalidVert( TRUE ); +/*N*/ if( bOld != IsVertical() ) +/*?*/ InvalidateRange( SwCharRange( GetOfst(), STRING_LEN ) ); +/*N*/ } +/*N*/ +/*N*/ if( HasFollow() ) +/*N*/ { +/*N*/ xub_StrLen nNxtOfst = GetFollow()->GetOfst(); +/*N*/ if( nNxtOfst ) +/*N*/ --nNxtOfst; +/*N*/ InvalidateRange( SwCharRange( nNxtOfst, 1 ), 1); +/*N*/ } +/*N*/ if( IsInFtn() ) +/*N*/ { +/*N*/ xub_StrLen nPos; +/*?*/ if( lcl_ErgoVadis( this, nPos, PREP_QUOVADIS ) ) +/*?*/ InvalidateRange( SwCharRange( nPos, 1 ), 0 ); +/*?*/ if( lcl_ErgoVadis( this, nPos, PREP_ERGOSUM ) ) +/*?*/ InvalidateRange( SwCharRange( nPos, 1 ), 0 ); +/*N*/ } +/*N*/ // 4739: Wenn wir ein Seitennummernfeld besitzen, muessen wir +/*N*/ // die Stellen invalidieren. +/*N*/ SwpHints *pHints = GetTxtNode()->GetpSwpHints(); +/*N*/ if( pHints ) +/*N*/ { +/*N*/ const MSHORT nSize = pHints->Count(); +/*N*/ const xub_StrLen nEnd = GetFollow() ? +/*N*/ GetFollow()->GetOfst() : STRING_LEN; +/*N*/ for( MSHORT i = 0; i < nSize; ++i ) +/*N*/ { +/*N*/ const SwTxtAttr *pHt = (*pHints)[i]; +/*N*/ const xub_StrLen nStart = *pHt->GetStart(); +/*N*/ if( nStart >= GetOfst() ) +/*N*/ { +/*N*/ if( nStart >= nEnd ) +/*N*/ i = nSize; // fuehrt das Ende herbei +/*N*/ else +/*N*/ { +/*N*/ // 4029: wenn wir zurueckfliessen und eine Ftn besitzen, so +/*N*/ // fliesst die Ftn in jedem Fall auch mit. Damit sie nicht im +/*N*/ // Weg steht, schicken wir uns ein ADJUST_FRM. +/*N*/ // pVoid != 0 bedeutet MoveBwd() +/*N*/ const MSHORT nWhich = pHt->Which(); +/*N*/ if( RES_TXTATR_FIELD == nWhich || +/*N*/ (HasFtn() && pVoid && RES_TXTATR_FTN == nWhich)) +/*N*/ InvalidateRange( SwCharRange( nStart, 1 ), 1 ); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ // A new boss, a new chance for growing +/*N*/ if( IsUndersized() ) +/*N*/ { +/*?*/ _InvalidateSize(); +/*?*/ InvalidateRange( SwCharRange( GetOfst(), 1 ), 1); +/*N*/ } +/*N*/ break; +/*N*/ } +/*N*/ +/*N*/ case PREP_POS_CHGD : +/*N*/ { +/*N*/ if ( GetValidPrtAreaFlag() ) +/*N*/ { +/*N*/ GETGRID( FindPageFrm() ) +/*N*/ if ( pGrid && GetTxtNode()->GetSwAttrSet().GetParaGrid().GetValue() ) +/*?*/ InvalidatePrt(); +/*N*/ } +/*N*/ +/*N*/ // Falls wir mit niemandem ueberlappen: +/*N*/ // Ueberlappte irgendein Fly _vor_ der Positionsaenderung ? +/*N*/ sal_Bool bFormat = pPara->HasFly(); +/*N*/ if( !bFormat ) +/*N*/ { +/*N*/ if( IsInFly() ) +/*N*/ { +/*N*/ SwTwips nTmpBottom = GetUpper()->Frm().Top() + +/*N*/ GetUpper()->Prt().Bottom(); +/*N*/ if( nTmpBottom < Frm().Bottom() ) +/*N*/ bFormat = sal_True; +/*N*/ } +/*N*/ if( !bFormat ) +/*N*/ { +/*N*/ if ( GetDrawObjs() ) +/*N*/ { +/*N*/ MSHORT nCnt = GetDrawObjs()->Count(); +/*N*/ for ( MSHORT i = 0; i < nCnt; ++i ) +/*N*/ { +/*N*/ SdrObject *pO = (*GetDrawObjs())[i]; +/*N*/ if ( pO->IsWriterFlyFrame() ) +/*N*/ { +/*N*/ SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pO)->GetFlyFrm(); +/*N*/ if( pFly->IsAutoPos() ) +/*N*/ { +/*?*/ bFormat = sal_True; +/*?*/ break; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ if( !bFormat ) +/*N*/ { +/*N*/ // Gibt es ueberhaupt Flys auf der Seite ? +/*N*/ SwTxtFly aTxtFly( this ); +/*N*/ if( aTxtFly.IsOn() ) +/*N*/ { +/*N*/ // Ueberlappt irgendein Fly ? +/*N*/ aTxtFly.Relax(); +/*N*/ bFormat = aTxtFly.IsOn() || IsUndersized(); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ if( bFormat ) +/*N*/ { +/*N*/ if( !IsLocked() ) +/*N*/ { +/*N*/ if( pPara->GetRepaint()->HasArea() ) +/*N*/ SetCompletePaint(); +/*N*/ Init(); +/*N*/ pPara = 0; +/*N*/ _InvalidateSize(); +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ if( GetTxtNode()->GetSwAttrSet().GetRegister().GetValue() ) +/*N*/ Prepare( PREP_REGISTER, 0, bNotify ); +/*N*/ // Durch Positionsverschiebungen mit Ftns muessen die +/*N*/ // Frames neu adjustiert werden. +/*N*/ else if( HasFtn() ) +/*N*/ { +/*N*/ Prepare( PREP_ADJUST_FRM, 0, bNotify ); +/*N*/ _InvalidateSize(); +/*N*/ } +/*N*/ else +/*N*/ return; // damit kein SetPrep() erfolgt. +/*N*/ } +/*N*/ break; +/*N*/ } +/*N*/ case PREP_REGISTER: +/*N*/ if( GetTxtNode()->GetSwAttrSet().GetRegister().GetValue() ) +/*N*/ { +/*N*/ pPara->SetPrepAdjust( sal_True ); +/*N*/ CalcLineSpace(); +/*N*/ InvalidateSize(); +/*N*/ _InvalidatePrt(); +/*N*/ SwFrm* pNxt; +/*N*/ if ( 0 != ( pNxt = GetIndNext() ) ) +/*N*/ { +/*N*/ pNxt->_InvalidatePrt(); +/*N*/ if ( pNxt->IsLayoutFrm() ) +/*N*/ pNxt->InvalidatePage(); +/*N*/ } +/*N*/ SetCompletePaint(); +/*N*/ } +/*N*/ break; +/*?*/ case PREP_FTN_GONE : +/*?*/ { +/*?*/ // Wenn ein Follow uns ruft, weil eine Fussnote geloescht wird, muss unsere +/*?*/ // letzte Zeile formatiert werden, damit ggf. die erste Zeile des Follows +/*?*/ // hochrutschen kann, die extra auf die naechste Seite gerutscht war, um mit +/*?*/ // der Fussnote zusammen zu sein, insbesondere bei spaltigen Bereichen. +/*?*/ ASSERT( GetFollow(), "PREP_FTN_GONE darf nur vom Follow gerufen werden" ); +/*?*/ xub_StrLen nPos = GetFollow()->GetOfst(); +/*?*/ if( IsFollow() && GetOfst() == nPos ) // falls wir gar keine Textmasse besitzen, +/*?*/ FindMaster()->Prepare( PREP_FTN_GONE ); // rufen wir das Prepare unseres Masters +/*?*/ if( nPos ) +/*?*/ --nPos; // das Zeichen vor unserem Follow +/*?*/ InvalidateRange( SwCharRange( nPos, 1 ), 0 ); +/*?*/ return; +/*?*/ } +/*N*/ case PREP_ERGOSUM: +/*N*/ case PREP_QUOVADIS: +/*N*/ { +/*N*/ xub_StrLen nPos; +/*N*/ if( lcl_ErgoVadis( this, nPos, ePrep ) ) +/*?*/ InvalidateRange( SwCharRange( nPos, 1 ), 0 ); +/*N*/ } +/*N*/ break; +/*N*/ case PREP_FLY_ATTR_CHG: +/*N*/ { +/*N*/ if( pVoid ) +/*N*/ { +/*N*/ xub_StrLen nWhere = CalcFlyPos( (SwFrmFmt*)pVoid ); +/*N*/ ASSERT( STRING_LEN != nWhere, "Prepare: Why me?" ); +/*N*/ InvalidateRange( SwCharRange( nWhere, 1 ) ); +/*N*/ return; +/*N*/ } +/*N*/ // else ... Laufe in den Default-Switch +/*N*/ } +/*N*/ case PREP_CLEAR: +/*N*/ default: +/*N*/ { +/*N*/ if( IsLocked() ) +/*N*/ { +/*N*/ if( PREP_FLY_ARRIVE == ePrep || PREP_FLY_LEAVE == ePrep ) +/*N*/ { +/*N*/ xub_StrLen nLen = ( GetFollow() ? GetFollow()->GetOfst() : +/*N*/ STRING_LEN ) - GetOfst(); +/*N*/ InvalidateRange( SwCharRange( GetOfst(), nLen ), 0 ); +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ if( pPara->GetRepaint()->HasArea() ) +/*N*/ SetCompletePaint(); +/*N*/ Init(); +/*N*/ pPara = 0; +/*N*/ if( GetOfst() && !IsFollow() ) +/*?*/ _SetOfst( 0 ); +/*N*/ if ( bNotify ) +/*N*/ InvalidateSize(); +/*N*/ else +/*N*/ _InvalidateSize(); +/*N*/ } +/*N*/ return; // damit kein SetPrep() erfolgt. +/*N*/ } +/*N*/ } +/*N*/ if( pPara ) +/*N*/ pPara->SetPrep( sal_True ); +/*N*/ } + +/* -----------------11.02.99 17:56------------------- + * Kleine Hilfsklasse mit folgender Funktion: + * Sie soll eine Probeformatierung vorbereiten. + * Der Frame wird in Groesse und Position angepasst, sein SwParaPortion zur Seite + * gestellt und eine neue erzeugt, dazu wird formatiert mit gesetztem bTestFormat. + * Im Dtor wird der TxtFrm wieder in seinen alten Zustand zurueckversetzt. + * + * --------------------------------------------------*/ + +class SwTestFormat +{ + SwTxtFrm *pFrm; + SwParaPortion *pOldPara; + SwRect aOldFrm, aOldPrt; +public: + SwTestFormat( SwTxtFrm* pTxtFrm, const SwFrm* pPrv, SwTwips nMaxHeight ); + ~SwTestFormat(); +}; + +/*N*/ SwTestFormat::SwTestFormat( SwTxtFrm* pTxtFrm, const SwFrm* pPre, SwTwips nMaxHeight ) +/*N*/ : pFrm( pTxtFrm ) +/*N*/ { +/*N*/ aOldFrm = pFrm->Frm(); +/*N*/ aOldPrt = pFrm->Prt(); +/*N*/ +/*N*/ SWRECTFN( pFrm ) +/*N*/ SwTwips nLower = (pFrm->*fnRect->fnGetBottomMargin)(); +/*N*/ +/*N*/ pFrm->Frm() = pFrm->GetUpper()->Prt(); +/*N*/ pFrm->Frm() += pFrm->GetUpper()->Frm().Pos(); +/*N*/ +/*N*/ (pFrm->Frm().*fnRect->fnSetHeight)( nMaxHeight ); +/*N*/ if( pFrm->GetPrev() ) +/*N*/ (pFrm->Frm().*fnRect->fnSetPosY)( +/*N*/ (pFrm->GetPrev()->Frm().*fnRect->fnGetBottom)() - +/*N*/ ( bVert ? nMaxHeight + 1 : 0 ) ); +/*N*/ +/*N*/ SwBorderAttrAccess aAccess( SwFrm::GetCache(), pFrm ); +/*N*/ const SwBorderAttrs &rAttrs = *aAccess.Get(); +/*N*/ (pFrm->Prt().*fnRect->fnSetPosX)( rAttrs.CalcLeft( pFrm ) ); +/*N*/ +/*N*/ if( pPre ) +/*N*/ { +/*N*/ SwTwips nUpper = pFrm->CalcUpperSpace( &rAttrs, pPre ); +/*N*/ (pFrm->Prt().*fnRect->fnSetPosY)( nUpper ); +/*N*/ } +/*N*/ (pFrm->Prt().*fnRect->fnSetHeight)( +/*N*/ Max( 0L , (pFrm->Frm().*fnRect->fnGetHeight)() - +/*N*/ (pFrm->Prt().*fnRect->fnGetTop)() - nLower ) ); +/*N*/ (pFrm->Prt().*fnRect->fnSetWidth)( +/*N*/ (pFrm->Frm().*fnRect->fnGetWidth)() - +/*N*/ // OD 23.01.2003 #106895# - add 1st param to <SwBorderAttrs::CalcRight(..)> +/*N*/ ( rAttrs.CalcLeft( pFrm ) + rAttrs.CalcRight( pFrm ) ) ); +/*N*/ pOldPara = pFrm->HasPara() ? pFrm->GetPara() : NULL; +/*N*/ pFrm->SetPara( new SwParaPortion(), sal_False ); +/*N*/ +/*N*/ ASSERT( ! pFrm->IsSwapped(), "A frame is swapped before _Format" ); +/*N*/ +/*N*/ if ( pFrm->IsVertical() ) +/*?*/ pFrm->SwapWidthAndHeight(); +/*N*/ +/*N*/ SwTxtFormatInfo aInf( pFrm, sal_False, sal_True, sal_True ); +/*N*/ SwTxtFormatter aLine( pFrm, &aInf ); +/*N*/ +/*N*/ pFrm->_Format( aLine, aInf ); +/*N*/ +/*N*/ if ( pFrm->IsVertical() ) +/*?*/ pFrm->SwapWidthAndHeight(); +/*N*/ +/*N*/ ASSERT( ! pFrm->IsSwapped(), "A frame is swapped after _Format" ); +/*N*/ } + +/*N*/ SwTestFormat::~SwTestFormat() +/*N*/ { +/*N*/ pFrm->Frm() = aOldFrm; +/*N*/ pFrm->Prt() = aOldPrt; +/*N*/ pFrm->SetPara( pOldPara ); +/*N*/ } + +/*N*/ sal_Bool SwTxtFrm::TestFormat( const SwFrm* pPrv, SwTwips &rMaxHeight, sal_Bool &bSplit ) +/*N*/ { +/*N*/ PROTOCOL_ENTER( this, PROT_TESTFORMAT, 0, 0 ) +/*N*/ +/*N*/ if( IsLocked() && GetUpper()->Prt().Width() <= 0 ) +/*N*/ return sal_False; +/*N*/ +/*N*/ SwTestFormat aSave( this, pPrv, rMaxHeight ); +/*N*/ +/*N*/ return SwTxtFrm::WouldFit( rMaxHeight, bSplit ); +/*N*/ } + + +/************************************************************************* + * SwTxtFrm::WouldFit() + *************************************************************************/ + +/* SwTxtFrm::WouldFit() + * sal_True: wenn ich aufspalten kann. + * Es soll und braucht nicht neu formatiert werden. + * Wir gehen davon aus, dass bereits formatiert wurde und dass + * die Formatierungsdaten noch aktuell sind. + * Wir gehen davon aus, dass die Framebreiten des evtl. Masters und + * Follows gleich sind. Deswegen wird kein FindBreak() mit FindOrphans() + * gerufen. + * Die benoetigte Hoehe wird von nMaxHeight abgezogen! + */ + +/*N*/ sal_Bool SwTxtFrm::WouldFit( SwTwips &rMaxHeight, sal_Bool &bSplit ) +/*N*/ { +/*N*/ ASSERT( ! IsVertical() || ! IsSwapped(), +/*N*/ "SwTxtFrm::WouldFit with swapped frame" ); +/*N*/ SWRECTFN( this ); +/*N*/ +/*N*/ if( IsLocked() ) +/*N*/ return sal_False; +/*N*/ +/*N*/ //Kann gut sein, dass mir der IdleCollector mir die gecachten +/*N*/ //Informationen entzogen hat. +/*N*/ if( !IsEmpty() ) +/*N*/ GetFormatted(); +/*N*/ +/*N*/ if ( IsEmpty() ) +/*N*/ { +/*N*/ bSplit = sal_False; +/*N*/ SwTwips nHeight = bVert ? Prt().SSize().Width() : Prt().SSize().Height(); +/*N*/ if( rMaxHeight < nHeight ) +/*N*/ return sal_False; +/*N*/ else +/*N*/ { +/*N*/ rMaxHeight -= nHeight; +/*N*/ return sal_True; +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ // In sehr unguenstigen Faellen kann GetPara immer noch 0 sein. +/*N*/ // Dann returnen wir sal_True, um auf der neuen Seite noch einmal +/*N*/ // anformatiert zu werden. +/*N*/ ASSERT( HasPara() || IsHiddenNow(), "WouldFit: GetFormatted() and then !HasPara()" ); +/*N*/ if( !HasPara() || ( !(Frm().*fnRect->fnGetHeight)() && IsHiddenNow() ) ) +/*N*/ return sal_True; +/*N*/ +/*N*/ // Da das Orphan-Flag nur sehr fluechtig existiert, wird als zweite +/*N*/ // Bedingung ueberprueft, ob die Rahmengroesse durch CalcPreps +/*N*/ // auf riesengross gesetzt wird, um ein MoveFwd zu erzwingen. +/*N*/ if( IsWidow() || ( bVert ? +/*N*/ ( 0 == Frm().Left() ) : +/*N*/ ( LONG_MAX - 20000 < Frm().Bottom() ) ) ) +/*N*/ { +/*?*/ SetWidow(sal_False); +/*?*/ if ( GetFollow() ) +/*?*/ { +/*?*/ // Wenn wir hier durch eine Widow-Anforderung unseres Follows gelandet +/*?*/ // sind, wird ueberprueft, ob es ueberhaupt einen Follow mit einer +/*?*/ // echten Hoehe gibt, andernfalls (z.B. in neu angelegten SctFrms) +/*?*/ // ignorieren wir das IsWidow() und pruefen doch noch, ob wir +/*?*/ // genung Platz finden. +/*?*/ if( ( ( ! bVert && LONG_MAX - 20000 >= Frm().Bottom() ) || +/*?*/ ( bVert && 0 < Frm().Left() ) ) && +/*?*/ ( GetFollow()->IsVertical() ? +/*?*/ !GetFollow()->Frm().Width() : +/*?*/ !GetFollow()->Frm().Height() ) ) +/*?*/ { +/*?*/ SwTxtFrm* pFoll = GetFollow()->GetFollow(); +/*?*/ while( pFoll && +/*?*/ ( pFoll->IsVertical() ? +/*?*/ !pFoll->Frm().Width() : +/*?*/ !pFoll->Frm().Height() ) ) +/*?*/ pFoll = pFoll->GetFollow(); +/*?*/ if( pFoll ) +/*?*/ return sal_False; +/*?*/ } +/*?*/ else +/*?*/ return sal_False; +/*?*/ } +/*N*/ } +/*N*/ +/*N*/ SWAP_IF_NOT_SWAPPED( this ); +/*N*/ +/*N*/ SwTxtSizeInfo aInf( this ); +/*N*/ SwTxtMargin aLine( this, &aInf ); +/*N*/ +/*N*/ WidowsAndOrphans aFrmBreak( this, rMaxHeight, bSplit ); +/*N*/ +/*N*/ register sal_Bool bRet = sal_True; +/*N*/ +/*N*/ aLine.Bottom(); +/*N*/ // Ist Aufspalten ueberhaupt notwendig? +/*N*/ if ( 0 != ( bSplit = !aFrmBreak.IsInside( aLine ) ) ) +/*N*/ bRet = !aFrmBreak.IsKeepAlways() && aFrmBreak.WouldFit( aLine, rMaxHeight ); +/*N*/ else +/*N*/ { +/*N*/ //Wir brauchen die Gesamthoehe inklusive der aktuellen Zeile +/*N*/ aLine.Top(); +/*N*/ do +/*N*/ { +/*N*/ rMaxHeight -= aLine.GetLineHeight(); +/*N*/ } while ( aLine.Next() ); +/*N*/ } +/*N*/ +/*N*/ UNDO_SWAP( this ) +/*N*/ +/*N*/ return bRet; +/*N*/ } + + +/************************************************************************* + * SwTxtFrm::GetParHeight() + *************************************************************************/ + +/*N*/ KSHORT SwTxtFrm::GetParHeight() const +/*N*/ { +/*N*/ ASSERT( ! IsVertical() || ! IsSwapped(), +/*N*/ "SwTxtFrm::GetParHeight with swapped frame" ) +/*N*/ +/*N*/ if( !HasPara() ) +/*N*/ { // Fuer nichtleere Absaetze ist dies ein Sonderfall, da koennen wir +/*N*/ // bei UnderSized ruhig nur 1 Twip mehr anfordern. +/*N*/ KSHORT nRet = (KSHORT)Prt().SSize().Height(); +/*N*/ if( IsUndersized() ) +/*N*/ { +/*N*/ if( IsEmpty() ) +/*N*/ nRet = (KSHORT)EmptyHeight(); +/*N*/ else +/*N*/ ++nRet; +/*N*/ } +/*N*/ return nRet; +/*N*/ } +/*N*/ +/*N*/ SWAP_IF_NOT_SWAPPED( this ) +/*N*/ +/*N*/ SwTxtFrm *pThis = (SwTxtFrm*)this; +/*N*/ SwTxtSizeInfo aInf( pThis ); +/*N*/ SwTxtIter aLine( pThis, &aInf ); +/*N*/ KSHORT nHeight = aLine.GetLineHeight(); +/*N*/ if( GetOfst() && !IsFollow() ) // Ist dieser Absatz gescrollt? Dann ist unsere +/*?*/ nHeight += aLine.GetLineHeight(); // bisherige Hoehe mind. eine Zeilenhoehe zu gering +/*N*/ while( aLine.Next() ) +/*N*/ nHeight += aLine.GetLineHeight(); +/*N*/ +/*N*/ UNDO_SWAP( this ) +/*N*/ +/*N*/ return nHeight; +/*N*/ } + + +/************************************************************************* + * SwTxtFrm::GetFormatted() + *************************************************************************/ + +// returnt this _immer_ im formatierten Zustand! +/*N*/ SwTxtFrm *SwTxtFrm::GetFormatted() +/*N*/ { +/*N*/ SWAP_IF_SWAPPED( this ) +/*N*/ +/*N*/ //Kann gut sein, dass mir der IdleCollector mir die gecachten +/*N*/ //Informationen entzogen hat. Calc() ruft unser Format. +/*N*/ //Nicht bei leeren Absaetzen! +/*N*/ if( !HasPara() && !(IsValid() && IsEmpty()) ) +/*N*/ { +/*N*/ // Calc() muss gerufen werden, weil unsere Frameposition +/*N*/ // nicht stimmen muss. +/*N*/ const sal_Bool bFormat = GetValidSizeFlag(); +/*N*/ Calc(); +/*N*/ // Es kann durchaus sein, dass Calc() das Format() +/*N*/ // nicht anstiess (weil wir einst vom Idle-Zerstoerer +/*N*/ // aufgefordert wurden unsere Formatinformationen wegzuschmeissen). +/*N*/ // 6995: Optimierung mit FormatQuick() +/*N*/ if( bFormat && !FormatQuick() ) +/*N*/ Format(); +/*N*/ } +/*N*/ +/*N*/ UNDO_SWAP( this ) +/*N*/ +/*N*/ return this; +/*N*/ } + +/************************************************************************* + * SwTxtFrm::CalcFitToContent() + *************************************************************************/ + + +/************************************************************************* + * SwTxtFrm::GetLineSpace() + *************************************************************************/ + +/*N*/ KSHORT SwTxtFrm::GetLineSpace() const +/*N*/ { +/*N*/ KSHORT nRet = 0; +/*N*/ long nTmp; +/*N*/ +/*N*/ const SwAttrSet* pSet = GetAttrSet(); +/*N*/ const SvxLineSpacingItem &rSpace = pSet->GetLineSpacing(); +/*N*/ +/*N*/ switch( rSpace.GetInterLineSpaceRule() ) +/*N*/ { +/*N*/ case SVX_INTER_LINE_SPACE_PROP: +/*N*/ { +/*N*/ ViewShell* pVsh = (ViewShell*)GetShell(); +/*N*/ if ( !pVsh ) +/*N*/ break; +/*N*/ OutputDevice *pOut = pVsh->GetOut(); +/*N*/ if( !pVsh->GetDoc()->IsBrowseMode() || +/*N*/ pVsh->GetViewOptions()->IsPrtFormat() ) +/*N*/ { +/*N*/ pOut = &GetTxtNode()->GetDoc()->GetRefDev(); +/*N*/ } +/*N*/ SwFont aFont( pSet, GetTxtNode()->GetDoc() ); +/*N*/ // Wir muessen dafuer sorgen, dass am OutputDevice der Font +/*N*/ // korrekt restauriert wird, sonst droht ein Last!=Owner. +/*N*/ if ( pLastFont ) +/*N*/ { +/*N*/ SwFntObj *pOldFont = pLastFont; +/*N*/ pLastFont = NULL; +/*N*/ aFont.SetFntChg( sal_True ); +/*N*/ aFont.ChgPhysFnt( pVsh, pOut ); +/*N*/ nRet = aFont.GetHeight( pVsh, pOut ); +/*N*/ pLastFont->Unlock(); +/*N*/ pLastFont = pOldFont; +/*N*/ pLastFont->SetDevFont( pVsh, pOut ); +/*N*/ } +/*N*/ else +/*N*/ { +/*?*/ Font aOldFont = pOut->GetFont(); +/*?*/ aFont.SetFntChg( sal_True ); +/*?*/ aFont.ChgPhysFnt( pVsh, pOut ); +/*?*/ nRet = aFont.GetHeight( pVsh, pOut ); +/*?*/ pLastFont->Unlock(); +/*?*/ pLastFont = NULL; +/*?*/ pOut->SetFont( aOldFont ); +/*N*/ } +/*N*/ nTmp = nRet; +/*N*/ nTmp *= rSpace.GetPropLineSpace(); +/*N*/ nTmp /= 100; +/*N*/ nTmp -= nRet; +/*N*/ if ( nTmp > 0 ) +/*N*/ nRet = (KSHORT)nTmp; +/*N*/ else +/*N*/ nRet = 0; +/*N*/ } +/*N*/ break; +/*?*/ case SVX_INTER_LINE_SPACE_FIX: +/*?*/ if ( rSpace.GetInterLineSpace() > 0 ) +/*?*/ nRet = (KSHORT)rSpace.GetInterLineSpace(); +/*N*/ } +/*N*/ return nRet; +/*N*/ } + +/************************************************************************* + * SwTxtFrm::FirstLineHeight() + *************************************************************************/ + +/*N*/ KSHORT SwTxtFrm::FirstLineHeight() const +/*N*/ { +/*N*/ if ( !HasPara() ) +/*N*/ { +/*N*/ if( IsEmpty() && IsValid() ) +/*?*/ return IsVertical() ? (KSHORT)Prt().Width() : (KSHORT)Prt().Height(); +/*N*/ return KSHRT_MAX; +/*N*/ } +/*N*/ const SwParaPortion *pPara = GetPara(); +/*N*/ if ( !pPara ) +/*N*/ return KSHRT_MAX; +/*N*/ +/*N*/ return pPara->Height(); +/*N*/ } + + +/*N*/ void SwTxtFrm::ChgThisLines() +/*N*/ { +/*N*/ //not necassary to format here (GerFormatted etc.), because we have to come from there! +/*N*/ +/*N*/ ULONG nNew = 0; +/*N*/ const SwLineNumberInfo &rInf = GetNode()->GetDoc()->GetLineNumberInfo(); +/*N*/ if ( GetTxt().Len() && HasPara() ) +/*N*/ { +/*N*/ SwTxtSizeInfo aInf( this ); +/*N*/ SwTxtMargin aLine( this, &aInf ); +/*N*/ if ( rInf.IsCountBlankLines() ) +/*N*/ { +/*N*/ aLine.Bottom(); +/*N*/ nNew = (ULONG)aLine.GetLineNr(); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ do +/*N*/ { +/*?*/ if( aLine.GetCurr()->HasCntnt() ) +/*?*/ ++nNew; +/*N*/ } while ( aLine.NextLine() ); +/*N*/ } +/*N*/ } +/*N*/ else if ( rInf.IsCountBlankLines() ) +/*N*/ nNew = 1; +/*N*/ +/*N*/ if ( nNew != nThisLines ) +/*N*/ { +/*N*/ if ( !IsInTab() && GetAttrSet()->GetLineNumber().IsCount() ) +/*N*/ { +/*N*/ nAllLines -= nThisLines; +/*N*/ nThisLines = nNew; +/*N*/ nAllLines += nThisLines; +/*N*/ SwFrm *pNxt = GetNextCntntFrm(); +/*N*/ while( pNxt && pNxt->IsInTab() ) +/*N*/ { +/*N*/ if( 0 != (pNxt = pNxt->FindTabFrm()) ) +/*N*/ pNxt = pNxt->FindNextCnt(); +/*N*/ } +/*N*/ if( pNxt ) +/*N*/ pNxt->InvalidateLineNum(); +/*N*/ +/*N*/ //Extend repaint to the bottom. +/*N*/ if ( HasPara() ) +/*N*/ { +/*N*/ SwRepaint *pRepaint = GetPara()->GetRepaint(); +/*N*/ pRepaint->Bottom( Max( pRepaint->Bottom(), +/*N*/ Frm().Top()+Prt().Bottom())); +/*N*/ } +/*N*/ } +/*N*/ else //Paragraphs which are not counted should not manipulate the AllLines. +/*N*/ nThisLines = nNew; +/*N*/ } +/*N*/ } + + +/*N*/ void SwTxtFrm::RecalcAllLines() +/*N*/ { +/*N*/ ValidateLineNum(); +/*N*/ +/*N*/ const SwAttrSet *pAttrSet = GetAttrSet(); +/*N*/ +/*N*/ if ( !IsInTab() ) +/*N*/ { +/*N*/ const ULONG nOld = GetAllLines(); +/*N*/ const SwFmtLineNumber &rLineNum = pAttrSet->GetLineNumber(); +/*N*/ ULONG nNewNum; +/*N*/ +/*N*/ if ( !IsFollow() && rLineNum.GetStartValue() && rLineNum.IsCount() ) +/*?*/ nNewNum = rLineNum.GetStartValue() - 1; +/*N*/ //If it is a follow or not has not be considered if it is a restart at each page; the +/*N*/ //restart should also take affekt at follows. +/*N*/ else if ( pAttrSet->GetDoc()->GetLineNumberInfo().IsRestartEachPage() && +/*N*/ FindPageFrm()->FindFirstBodyCntnt() == this ) +/*N*/ { +/*N*/ nNewNum = 0; +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ SwCntntFrm *pPrv = GetPrevCntntFrm(); +/*N*/ while ( pPrv && +/*N*/ (pPrv->IsInTab() || pPrv->IsInDocBody() != IsInDocBody()) ) +/*N*/ pPrv = pPrv->GetPrevCntntFrm(); +/*N*/ +/*N*/ nNewNum = pPrv ? ((SwTxtFrm*)pPrv)->GetAllLines() : 0; +/*N*/ } +/*N*/ if ( rLineNum.IsCount() ) +/*N*/ nNewNum += GetThisLines(); +/*N*/ +/*N*/ if ( nOld != nNewNum ) +/*N*/ { +/*N*/ nAllLines = nNewNum; +/*N*/ SwCntntFrm *pNxt = GetNextCntntFrm(); +/*N*/ while ( pNxt && +/*N*/ (pNxt->IsInTab() || pNxt->IsInDocBody() != IsInDocBody()) ) +/*N*/ pNxt = pNxt->GetNextCntntFrm(); +/*N*/ if ( pNxt ) +/*N*/ { +/*N*/ if ( pNxt->GetUpper() != GetUpper() ) +/*N*/ pNxt->InvalidateLineNum(); +/*N*/ else +/*N*/ pNxt->_InvalidateLineNum(); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } + + + +/************************************************************************* + * SwTxtFrm::GetScriptInfo() + *************************************************************************/ + +/*N*/ const SwScriptInfo* SwTxtFrm::GetScriptInfo() const +/*N*/ { +/*N*/ const SwParaPortion* pPara = GetPara(); +/*N*/ return pPara ? &pPara->GetScriptInfo() : 0; +/*N*/ } + +/************************************************************************* + * lcl_CalcFlyBasePos() + * Helper function for SwTxtFrm::CalcBasePosForFly() + *************************************************************************/ + +SwTwips lcl_CalcFlyBasePos( const SwTxtFrm& rFrm, SwRect aFlyRect, + SwTxtFly& rTxtFly ) +{ + SWRECTFN( (&rFrm) ) + SwTwips nRet = rFrm.IsRightToLeft() ? + (rFrm.Frm().*fnRect->fnGetRight)() : + (rFrm.Frm().*fnRect->fnGetLeft)(); + + do + { + SwRect aRect = rTxtFly.GetFrm( aFlyRect ); + if ( 0 != (aRect.*fnRect->fnGetWidth)() ) + { + if ( rFrm.IsRightToLeft() ) + { + if ( (aRect.*fnRect->fnGetRight)() - + (aFlyRect.*fnRect->fnGetRight)() >= 0 ) + { + (aFlyRect.*fnRect->fnSetRight)( + (aRect.*fnRect->fnGetLeft)() ); + nRet = (aRect.*fnRect->fnGetLeft)(); + } + else + break; + } + else + { + if ( (aFlyRect.*fnRect->fnGetLeft)() - + (aRect.*fnRect->fnGetLeft)() >= 0 ) + { + (aFlyRect.*fnRect->fnSetLeft)( + (aRect.*fnRect->fnGetRight)() + 1 ); + nRet = (aRect.*fnRect->fnGetRight)(); + } + else + break; + } + } + else + break; + } + while ( sal_True ); + + return nRet; +} + +/************************************************************************* + * SwTxtFrm::CalcBasePosForFly() + *************************************************************************/ + +void SwTxtFrm::CalcBaseOfstForFly() +{ + ASSERT( !IsVertical() || !IsSwapped(), + "SwTxtFrm::CalcBasePosForFly with swapped frame!" ) + + const SwNode* pNode = GetTxtNode(); + const SwDoc* pDoc = pNode->GetDoc(); + if ( !pDoc->IsAddFlyOffsets() ) + return; + + SWRECTFN( this ) + + SwTwips nTop = 0; + SwTwips nLineHeight = 200; + SwRect aFlyRect( Frm().Pos() + Prt().Pos(), Prt().SSize() ); + + // Get first 'real' line + const SwLineLayout* pLay = GetPara(); + while( pLay && pLay->IsDummy() ) + { + nTop += pLay->Height(); + pLay = pLay->GetNext(); + } + if ( pLay ) + nLineHeight = pLay->Height(); + + SwTwips nNewTop = (aFlyRect.*fnRect->fnGetTop)() + + ( bVert ? -nTop : nTop ); + (aFlyRect.*fnRect->fnSetTopAndHeight)( nNewTop, nLineHeight ); + + SwTxtFly aTxtFly( this ); + aTxtFly.SetIgnoreCurrentFrame( sal_True ); + aTxtFly.SetIgnoreContour( sal_True ); + SwTwips nRet1 = lcl_CalcFlyBasePos( *this, aFlyRect, aTxtFly ); + aTxtFly.SetIgnoreCurrentFrame( sal_False ); + SwTwips nRet2 = lcl_CalcFlyBasePos( *this, aFlyRect, aTxtFly ); + + // make values relative to frame start position + SwTwips nLeft = IsRightToLeft() ? + (Frm().*fnRect->fnGetRight)() : + (Frm().*fnRect->fnGetLeft)(); + + mnFlyAnchorOfst = nRet1 - nLeft; + mnFlyAnchorOfstNoWrap = nRet2 - nLeft; +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |