summaryrefslogtreecommitdiff
path: root/sw/source/core/text/frmcrsr.cxx
diff options
context:
space:
mode:
authorJens-Heiner Rechtien <hr@openoffice.org>2000-09-18 23:08:29 +0000
committerJens-Heiner Rechtien <hr@openoffice.org>2000-09-18 23:08:29 +0000
commit84a3db80b4fd66c6854b3135b5f69b61fd828e62 (patch)
tree4475006ca87946e71c44668b20330b2d2729f638 /sw/source/core/text/frmcrsr.cxx
parent7b0b5cdfeed656b279bc32cd929630d5fc25878b (diff)
initial import
Diffstat (limited to 'sw/source/core/text/frmcrsr.cxx')
-rw-r--r--sw/source/core/text/frmcrsr.cxx1240
1 files changed, 1240 insertions, 0 deletions
diff --git a/sw/source/core/text/frmcrsr.cxx b/sw/source/core/text/frmcrsr.cxx
new file mode 100644
index 000000000000..b9646d63870b
--- /dev/null
+++ b/sw/source/core/text/frmcrsr.cxx
@@ -0,0 +1,1240 @@
+/*************************************************************************
+ *
+ * $RCSfile: frmcrsr.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-19 00:08:24 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#include "ndtxt.hxx" // GetNode()
+#include "pam.hxx" // SwPosition
+#include "frmtool.hxx"
+#include "doc.hxx"
+#include "viewopt.hxx"
+#include "paratr.hxx"
+#include "pagefrm.hxx"
+#include "colfrm.hxx"
+#include "txttypes.hxx"
+
+#ifndef _SFX_PRINTER_HXX //autogen
+#include <sfx2/printer.hxx>
+#endif
+
+#ifndef _SVX_LRSPITEM_HXX //autogen
+#include <svx/lrspitem.hxx>
+#endif
+
+#ifndef _SVX_TSPTITEM_HXX //autogen
+#include <svx/tstpitem.hxx>
+#endif
+
+#ifndef _SVX_ULSPITEM_HXX //autogen
+#include <svx/ulspitem.hxx>
+#endif
+
+#include "frmsh.hxx"
+#include "txtcfg.hxx"
+#include "txtfrm.hxx" // SwTxtFrm
+#include "inftxt.hxx" // SwTxtSizeInfo
+#include "itrtxt.hxx" // SwTxtCursor
+#include "crstate.hxx" // SwTxtCursor
+#include "viewsh.hxx" // InvalidateWindows
+#include "swfntcch.hxx" // SwFontAccess
+#include "flyfrm.hxx"
+
+#ifdef DEBUG
+#include "txtpaint.hxx"
+#endif
+
+#define MIN_OFFSET_STEP 10
+
+/*
+ * 1170-SurvivalKit: Wie gelangt man hinter das letzte Zeichen der Zeile.
+ * - RightMargin verzichtet auf den Positionsausgleich mit -1
+ * - GetCharRect liefert bei MV_RIGHTMARGIN ein GetEndCharRect
+ * - GetEndCharRect setzt bRightMargin auf sal_True
+ * - SwTxtCursor::bRightMargin wird per CharCrsrToLine auf sal_False gesetzt
+ */
+
+/*************************************************************************
+ * GetAdjFrmAtPos()
+ *************************************************************************/
+
+SwTxtFrm *GetAdjFrmAtPos( SwTxtFrm *pFrm, const SwPosition &rPos,
+ const sal_Bool bRightMargin )
+{
+ // 8810: vgl. 1170, RightMargin in der letzten Masterzeile...
+ const xub_StrLen nOffset = rPos.nContent.GetIndex();
+ SwTxtFrm *pFrmAtPos = pFrm->GetFrmAtPos( rPos );
+ while( pFrm != pFrmAtPos )
+ {
+ pFrm = pFrmAtPos;
+ pFrm->GetFormatted();
+ pFrmAtPos = (SwTxtFrm*)pFrm->GetFrmAtPos( rPos );
+ }
+
+ if( nOffset && bRightMargin )
+ {
+ while( pFrmAtPos && pFrmAtPos->GetOfst() == nOffset )
+ {
+ pFrmAtPos->GetFormatted();
+ pFrmAtPos = pFrmAtPos->FindMaster();
+ }
+ ASSERT( pFrmAtPos, "+GetCharRect: no frame with my rightmargin" );
+ }
+ return pFrmAtPos ? pFrmAtPos : pFrm;
+}
+
+sal_Bool lcl_ChangeOffset( SwTxtFrm* pFrm, xub_StrLen nNew )
+{
+ // In Bereichen und ausserhalb von Flies wird nicht mehr gescrollt.
+ ASSERT( !pFrm->IsFollow(), "Illegal Scrolling by Follow!" );
+ if( pFrm->GetOfst() != nNew && !pFrm->IsInSct() )
+ {
+ SwFlyFrm *pFly = pFrm->FindFlyFrm();
+ // Vorsicht, wenn z.B. bei einem spaltigen Rahmen die Groesse noch invalide ist,
+ // duerfen wir nicht mal eben herumscrollen
+ if ( ( pFly && pFly->IsValid() &&
+ !pFly->GetNextLink() && !pFly->GetPrevLink() ) ||
+ ( !pFly && pFrm->IsInTab() ) )
+ {
+ ViewShell* pVsh = pFrm->GetShell();
+ if( pVsh )
+ {
+ if( pVsh->GetNext() != pVsh ||
+ ( pFrm->GetDrawObjs() && pFrm->GetDrawObjs()->Count() ) )
+ {
+ if( !pFrm->GetOfst() )
+ return sal_False;
+ nNew = 0;
+ }
+ pFrm->SetOfst( nNew );
+ pFrm->SetPara( 0 );
+ pFrm->GetFormatted();
+ pFrm->GetShell()->InvalidateWindows( pFrm->Frm() );
+ return sal_True;
+ }
+ }
+ }
+ return sal_False;
+}
+
+/*************************************************************************
+ * GetFrmAtOfst(), GetFrmAtPos()
+ *************************************************************************/
+
+SwTxtFrm *SwTxtFrm::GetFrmAtOfst( const xub_StrLen nWhere )
+{
+ SwTxtFrm *pRet = this;
+ while( pRet->HasFollow() && nWhere >= pRet->GetFollow()->GetOfst() )
+ pRet = pRet->GetFollow();
+ return pRet;
+}
+
+SwTxtFrm *SwTxtFrm::GetFrmAtPos( const SwPosition &rPos )
+{
+ SwTxtFrm *pFoll = (SwTxtFrm*)this;
+ while( pFoll->GetFollow() )
+ {
+ if( rPos.nContent.GetIndex() > pFoll->GetFollow()->GetOfst() )
+ pFoll = pFoll->GetFollow();
+ else
+ {
+ if( rPos.nContent.GetIndex() == pFoll->GetFollow()->GetOfst()
+ && !SwTxtCursor::IsRightMargin() )
+ pFoll = pFoll->GetFollow();
+ else
+ break;
+ }
+ }
+ if( rPos.nContent.GetIndex() < pFoll->GetOfst() && !pFoll->IsFollow() )
+ {
+ // Der Offset wird verschoben, bis die gewuenschte Position sichtbar
+ // wird und MIN_OFFSET_STEP weitere Zeichen.
+ xub_StrLen nNew = rPos.nContent.GetIndex();
+ if( nNew < MIN_OFFSET_STEP )
+ nNew = 0;
+ else
+ nNew -= MIN_OFFSET_STEP;
+ lcl_ChangeOffset( pFoll, nNew );
+ }
+ return pFoll;
+}
+
+/*************************************************************************
+ * SwTxtFrm::GetCharRect()
+ *************************************************************************/
+
+/*
+ * GetCharRect() findet die Characterzelle des Characters, dass
+ * durch aPos beschrieben wird. GetCrsrOfst() findet den
+ * umgekehrten Weg: Von einer Dokumentkoordinate zu einem Pam.
+ * Beide sind virtuell in der Framebasisklasse und werden deshalb
+ * immer angezogen.
+ */
+
+sal_Bool SwTxtFrm::GetCharRect( SwRect& rOrig, const SwPosition &rPos,
+ SwCrsrMoveState *pCMS ) const
+{
+ if( IsLocked() || IsHiddenNow() )
+ return sal_False;
+
+ //Erstmal den richtigen Frm finden, dabei muss beachtet werden, dass:
+ //- die gecachten Informationen verworfen sein koennen (GetPara() == 0)
+ //- das ein Follow gemeint sein kann
+ //- das die Kette der Follows dynamisch waechst; der in den wir
+ // schliesslich gelangen muss aber Formatiert sein.
+
+ // opt: reading ahead erspart uns ein GetAdjFrmAtPos
+ const sal_Bool bRightMargin = pCMS && ( MV_RIGHTMARGIN == pCMS->eState );
+ SwTxtFrm *pFrm = GetAdjFrmAtPos( (SwTxtFrm*)this, rPos, bRightMargin );
+
+ pFrm->GetFormatted();
+ const SwFrm* pTmpFrm = (SwFrm*)pFrm->GetUpper();
+ SwTwips nUpperMaxY = pTmpFrm->Frm().Top() + pTmpFrm->Prt().Bottom();
+ SwTwips nMaxY = Min( pFrm->Frm().Top() + pFrm->Prt().Bottom(), nUpperMaxY );
+
+ if ( pFrm->IsEmpty() || !pFrm->Prt().Height() )
+ {
+ Point aPnt1 = pFrm->Frm().Pos() + pFrm->Prt().Pos();
+ SwTxtNode* pTxtNd = ((SwTxtFrm*)this)->GetTxtNode();
+ short nFirstOffset;
+ pTxtNd->GetFirstLineOfsWithNum( nFirstOffset );
+ if( nFirstOffset > 0 )
+ aPnt1.X() += nFirstOffset;
+ if( aPnt1.Y() > nMaxY )
+ aPnt1.Y() = nMaxY;
+ Point aPnt2( aPnt1.X(), aPnt1.Y() + pFrm->Prt().Height() );
+ if( aPnt2.Y() > nMaxY )
+ aPnt2.Y() = nMaxY;
+ rOrig = SwRect( aPnt1, aPnt2 );
+ if ( pCMS )
+ {
+ pCMS->aRealHeight.X() = 0;
+ pCMS->aRealHeight.Y() = rOrig.Height();
+ }
+ return sal_True;
+ }
+ else
+ {
+ if( !pFrm->HasPara() )
+ return sal_False;
+ sal_Bool bGoOn = sal_True;
+ sal_Bool bRet;
+ sal_Bool bPrvLine;
+ xub_StrLen nOffset = rPos.nContent.GetIndex();
+ xub_StrLen nNextOfst;
+ do
+ {
+ {
+ SwTxtSizeInfo aInf( pFrm );
+ SwTxtCursor aLine( pFrm, &aInf );
+ nNextOfst = aLine.GetEnd();
+ // Siehe Kommentar in AdjustFrm
+ // 1170: das letzte Zeichen der Zeile mitnehmen?
+ bRet = bRightMargin ? aLine.GetEndCharRect( &rOrig, nOffset, pCMS, nMaxY )
+ : aLine.GetCharRect( &rOrig, nOffset, pCMS, nMaxY );
+ bPrvLine = pCMS && aLine.GetPrev() && !pFrm->GetNext();
+
+ }
+ if( pFrm->IsUndersized() && bPrvLine && rOrig.Bottom() == nUpperMaxY &&
+ pFrm->GetOfst() < nOffset && !pFrm->IsFollow() )
+ bGoOn = lcl_ChangeOffset( pFrm, nNextOfst );
+ else
+ bGoOn = sal_False;
+ } while ( bGoOn );
+ return bRet;
+ }
+}
+
+/*************************************************************************
+ * SwTxtFrm::GetAutoPos()
+ *************************************************************************/
+
+/*
+ * GetAutoPos() findet die Characterzelle des Characters, dass
+ * durch aPos beschrieben wird und wird von autopositionierten Rahmen genutzt.
+ */
+
+sal_Bool SwTxtFrm::GetAutoPos( SwRect& rOrig, const SwPosition &rPos ) const
+{
+ if( IsHiddenNow() )
+ return sal_False;
+
+ xub_StrLen nOffset = rPos.nContent.GetIndex();
+ SwTxtFrm *pFrm = ((SwTxtFrm*)this)->GetFrmAtOfst( nOffset );
+
+ pFrm->GetFormatted();
+ const SwFrm* pTmpFrm = (SwFrm*)pFrm->GetUpper();
+ SwTwips nUpperMaxY = pTmpFrm->Frm().Top() + pTmpFrm->Prt().Bottom();
+ SwTwips nMaxY = Min( pFrm->Frm().Top() + pFrm->Prt().Bottom(), nUpperMaxY );
+
+ if ( pFrm->IsEmpty() || !pFrm->Prt().Height() )
+ {
+ Point aPnt1 = pFrm->Frm().Pos() + pFrm->Prt().Pos();
+ if( aPnt1.Y() > nMaxY )
+ aPnt1.Y() = nMaxY;
+ Point aPnt2( aPnt1.X(), aPnt1.Y() + pFrm->Prt().Height() );
+ if( aPnt2.Y() > nMaxY )
+ aPnt2.Y() = nMaxY;
+ rOrig = SwRect( aPnt1, aPnt2 );
+ return sal_True;
+ }
+ else
+ {
+ if( !pFrm->HasPara() )
+ return sal_False;
+ SwTxtSizeInfo aInf( pFrm );
+ SwTxtCursor aLine( pFrm, &aInf );
+ return aLine.GetCharRect( &rOrig, nOffset, NULL, nMaxY );
+ }
+}
+
+/*************************************************************************
+ * SwTxtFrm::_GetCrsrOfst()
+ *************************************************************************/
+
+// Minimaler Abstand von nichtleeren Zeilen etwas weniger als 2 cm
+#define FILL_MIN_DIST 1100
+
+struct SwFillData
+{
+ SwRect aFrm;
+ const SwCrsrMoveState *pCMS;
+ SwPosition* pPos;
+ const Point& rPoint;
+ SwTwips nLineWidth;
+ sal_Bool bFirstLine : 1;
+ sal_Bool bInner : 1;
+ sal_Bool bColumn : 1;
+ sal_Bool bEmpty : 1;
+ SwFillData( const SwCrsrMoveState *pC, SwPosition* pP, const SwRect& rR,
+ const Point& rPt ) : aFrm( rR ), pCMS( pC ), pPos( pP ), rPoint( rPt ),
+ nLineWidth( 0 ), bFirstLine( sal_True ), bInner( sal_False ), bColumn( sal_False ),
+ bEmpty( sal_True ){}
+ const SwFillMode Mode() const { return pCMS->pFill->eMode; }
+ const long X() const { return rPoint.X(); }
+ const long Y() const { return rPoint.Y(); }
+ const long Left() const { return aFrm.Left(); }
+ const long Right() const { return aFrm.Right(); }
+ const long Bottom() const { return aFrm.Bottom(); }
+ SwFillCrsrPos &Fill() const { return *pCMS->pFill; }
+ void SetTab( MSHORT nNew ) { pCMS->pFill->nTabCnt = nNew; }
+ void SetSpace( MSHORT nNew ) { pCMS->pFill->nSpaceCnt = nNew; }
+ void SetOrient( const SwHoriOrient eNew ){ pCMS->pFill->eOrient = eNew; }
+};
+
+sal_Bool SwTxtFrm::_GetCrsrOfst(SwPosition* pPos, const Point& rPoint,
+ const sal_Bool bChgFrm, const SwCrsrMoveState* pCMS ) const
+{
+ // 8804: _GetCrsrOfst wird vom GetCrsrOfst und GetKeyCrsrOfst gerufen.
+ // In keinem Fall nur ein return sal_False.
+
+ if( IsLocked() || IsHiddenNow() )
+ return sal_False;
+
+ SwFillData *pFillData = ( pCMS && pCMS->pFill ) ?
+ new SwFillData( pCMS, pPos, Frm(), rPoint ) : NULL;
+
+ ((SwTxtFrm*)this)->GetFormatted();
+ if ( IsEmpty() )
+ {
+ SwTxtNode* pTxtNd = ((SwTxtFrm*)this)->GetTxtNode();
+ pPos->nNode = *pTxtNd;
+ pPos->nContent.Assign( pTxtNd, 0 );
+ if( pCMS && pCMS->bFieldInfo )
+ {
+ SwTwips nDiff = rPoint.X() - Frm().Left() - Prt().Left();
+ if( nDiff > 50 || nDiff < 0 )
+ ((SwCrsrMoveState*)pCMS)->bPosCorr = sal_True;
+ }
+ }
+ else
+ {
+ SwTxtSizeInfo aInf( (SwTxtFrm*)this );
+ SwTxtCursor aLine( ((SwTxtFrm*)this), &aInf );
+
+ // Siehe Kommentar in AdjustFrm()
+ SwTwips nMaxY = Frm().Top() + Prt().Top() + Prt().Height();
+ aLine.TwipsToLine( rPoint.Y() );
+ while( aLine.Y() + aLine.GetLineHeight() > nMaxY )
+ {
+ DBG_LOOP;
+ if( !aLine.Prev() )
+ break;
+ }
+
+ xub_StrLen nOffset = aLine.GetCrsrOfst( pPos, rPoint, bChgFrm, pCMS );
+
+ if( pCMS && pCMS->eState == MV_NONE && aLine.GetEnd() == nOffset )
+ ((SwCrsrMoveState*)pCMS)->eState = MV_RIGHTMARGIN;
+
+ // 6776: pPos ist ein reiner IN-Parameter, der nicht ausgewertet werden darf.
+ // Das pIter->GetCrsrOfst returnt aus einer Verschachtelung mit STRING_LEN.
+ // Wenn SwTxtIter::GetCrsrOfst von sich aus weitere GetCrsrOfst
+ // ruft, so aendert sich nNode der Position. In solchen Faellen
+ // darf pPos nicht berechnet werden.
+ if( STRING_LEN != nOffset )
+ {
+#ifdef USED
+ // 8626: bei Up/Down darf diese Zeile nicht verlassen werden.
+ if( pCMS && MV_UPDOWN == pCMS->eState )
+ {
+ const xub_StrLen nEnd = aLine.GetEnd();
+ if( nOffset >= nEnd && nEnd )
+ {
+ // Man muss hinter das letzte Zeichen kommen duerfen?!
+ nOffset = nEnd - 1; // UnitUp-Korrektur
+ }
+ else
+ if( nOffset < aLine.GetStart() )
+ nOffset = aLine.GetStart(); // UnitDown-Korrektur
+ }
+#endif
+ SwTxtNode* pTxtNd = ((SwTxtFrm*)this)->GetTxtNode();
+ pPos->nNode = *pTxtNd;
+ pPos->nContent.Assign( pTxtNd, nOffset );
+ if( pFillData )
+ {
+ if( pTxtNd->GetTxt().Len() > nOffset ||
+ rPoint.Y() < Frm().Top() )
+ pFillData->bInner = sal_True;
+ pFillData->bFirstLine = aLine.GetLineNr() < 2;
+ if( pTxtNd->GetTxt().Len() )
+ {
+ pFillData->bEmpty = sal_False;
+ pFillData->nLineWidth = aLine.GetCurr()->Width();
+ }
+ }
+
+ }
+ }
+ if( pFillData && FindPageFrm()->Frm().IsInside( rPoint ) )
+ FillCrsrPos( *pFillData );
+ return sal_True;
+}
+
+/*************************************************************************
+ * virtual SwTxtFrm::GetCrsrOfst()
+ *************************************************************************/
+
+sal_Bool SwTxtFrm::GetCrsrOfst(SwPosition* pPos, Point& rPoint,
+ const SwCrsrMoveState* pCMS ) const
+{
+ MSHORT nChgFrm = 2;
+ if( pCMS )
+ {
+ if( MV_UPDOWN == pCMS->eState )
+ nChgFrm = 0;
+ else if( MV_SETONLYTEXT == pCMS->eState ||
+ MV_TBLSEL == pCMS->eState )
+ nChgFrm = 1;
+ }
+ return _GetCrsrOfst( pPos, rPoint, nChgFrm, pCMS );
+}
+
+/*************************************************************************
+ * SwTxtFrm::LeftMargin()
+ *************************************************************************/
+
+/*
+ * Layout-orientierte Cursorbewegungen
+ */
+
+/*
+ * an den Zeilenanfang
+ */
+
+sal_Bool SwTxtFrm::LeftMargin(SwPaM *pPam) const
+{
+ if( ((const SwNode*)pPam->GetNode()) != GetNode() )
+ pPam->pPoint->nNode = *((SwTxtFrm*)this)->GetTxtNode();
+
+ SwTxtFrm *pFrm = GetAdjFrmAtPos( (SwTxtFrm*)this, *(pPam->pPoint),
+ SwTxtCursor::IsRightMargin() );
+ pFrm->GetFormatted();
+ xub_StrLen nIndx;
+ if ( pFrm->IsEmpty() )
+ nIndx = 0;
+ else
+ {
+ SwTxtSizeInfo aInf( pFrm );
+ SwTxtCursor aLine( pFrm, &aInf );
+
+ aLine.CharCrsrToLine(pPam->pPoint->nContent.GetIndex());
+ nIndx = aLine.GetStart();
+ if( pFrm->GetOfst() && !pFrm->IsFollow() && !aLine.GetPrev() )
+ {
+ lcl_ChangeOffset( pFrm, 0 );
+ nIndx = 0;
+ }
+ }
+ pPam->pPoint->nContent = SwIndex( pFrm->GetTxtNode(), nIndx );
+ SwTxtCursor::SetRightMargin( sal_False );
+ return sal_True;
+}
+
+/*************************************************************************
+ * SwTxtFrm::RightMargin()
+ *************************************************************************/
+
+/*
+ * An das Zeilenende:Das ist die Position vor dem letzten
+ * Character in der Zeile. Ausnahme: In der letzten Zeile soll
+ * der Cursor auch hinter dem letzten Character stehen koennen,
+ * um Text anhaengen zu koennen.
+ *
+ */
+
+sal_Bool SwTxtFrm::RightMargin(SwPaM *pPam, sal_Bool bAPI) const
+{
+ if( ((const SwNode*)pPam->GetNode()) != GetNode() )
+ pPam->pPoint->nNode = *((SwTxtFrm*)this)->GetTxtNode();
+
+ SwTxtFrm *pFrm = GetAdjFrmAtPos( (SwTxtFrm*)this, *(pPam->pPoint),
+ SwTxtCursor::IsRightMargin() );
+ pFrm->GetFormatted();
+ xub_StrLen nRightMargin;
+ if ( IsEmpty() )
+ nRightMargin = 0;
+ else
+ {
+ SwTxtSizeInfo aInf( pFrm );
+ SwTxtCursor aLine( pFrm, &aInf );
+
+ aLine.CharCrsrToLine(pPam->pPoint->nContent.GetIndex());
+ nRightMargin = aLine.GetStart() + aLine.GetCurr()->GetLen();
+
+ // Harte Zeilenumbrueche lassen wir hinter uns.
+ if( aLine.GetCurr()->GetLen() &&
+ CH_BREAK == aInf.GetTxt().GetChar( nRightMargin - 1 ) )
+ --nRightMargin;
+ if( !bAPI && (aLine.GetNext() || pFrm->GetFollow()) )
+ {
+ while( nRightMargin > aLine.GetStart() &&
+ ' ' == aInf.GetTxt().GetChar( nRightMargin - 1 ) )
+ --nRightMargin;
+ }
+ }
+ pPam->pPoint->nContent = SwIndex( pFrm->GetTxtNode(), nRightMargin );
+ SwTxtCursor::SetRightMargin( !bAPI );
+ return sal_True;
+}
+
+/*************************************************************************
+ * SwTxtFrm::_UnitUp()
+ *************************************************************************/
+
+//Die beiden folgenden Methoden versuchen zunaechst den Crsr in die
+//nachste/folgende Zeile zu setzen. Gibt es im Frame keine vorhergehende/
+//folgende Zeile, so wird der Aufruf an die Basisklasse weitergeleitet.
+//Die Horizontale Ausrichtung des Crsr wird hinterher von der CrsrShell
+//vorgenommen.
+
+class SwSetToRightMargin
+{
+ sal_Bool bRight;
+public:
+ inline SwSetToRightMargin() : bRight( sal_False ) { }
+ inline ~SwSetToRightMargin() { SwTxtCursor::SetRightMargin( bRight ); }
+ inline void SetRight( const sal_Bool bNew ) { bRight = bNew; }
+};
+
+sal_Bool SwTxtFrm::_UnitUp( SwPaM *pPam, const SwTwips nOffset,
+ sal_Bool bSetInReadOnly ) const
+{
+ // 8626: Im Notfall den RightMargin setzen.
+ SwSetToRightMargin aSet;
+
+ if( IsInTab() &&
+ pPam->GetNode( sal_True )->StartOfSectionNode() !=
+ pPam->GetNode( sal_False )->StartOfSectionNode() )
+ {
+ //Wenn der PaM in unterschiedlichen Boxen sitzt, so handelt es sich um
+ //eine Tabellenselektion; diese wird von der Basisklasse abgearbeitet.
+ return SwCntntFrm::UnitUp( pPam, nOffset, bSetInReadOnly );
+ }
+
+ ((SwTxtFrm*)this)->GetFormatted();
+ const xub_StrLen nPos = pPam->pPoint->nContent.GetIndex();
+ SwRect aCharBox;
+
+ if( !IsEmpty() && !IsHiddenNow() )
+ {
+ xub_StrLen nFormat = STRING_LEN;
+ do
+ {
+ if( nFormat != STRING_LEN && !IsFollow() )
+ lcl_ChangeOffset( ((SwTxtFrm*)this), nFormat );
+
+ SwTxtSizeInfo aInf( (SwTxtFrm*)this );
+ SwTxtCursor aLine( ((SwTxtFrm*)this), &aInf );
+
+ // 8116: Flys ohne Umlauf und IsDummy(); hier wegoptimiert
+ if( nPos )
+ aLine.CharCrsrToLine( nPos );
+ else
+ aLine.Top();
+
+ const SwLineLayout *pPrevLine = aLine.GetPrevLine();
+ if( !pPrevLine && GetOfst() && !IsFollow() )
+ {
+ nFormat = GetOfst();
+ xub_StrLen nDiff = aLine.GetLength();
+ if( !nDiff )
+ nDiff = MIN_OFFSET_STEP;
+ if( nFormat > nDiff )
+ nFormat -= nDiff;
+ else
+ nFormat = 0;
+ continue;
+ }
+ if( pPrevLine && pPrevLine != aLine.GetCurr() )
+ {
+ const xub_StrLen nStart = aLine.GetStart();
+ SwRect aCharBox;
+ aLine.GetCharRect( &aCharBox, nPos );
+ aLine.PrevLine();
+ while ( aLine.GetStart() == nStart &&
+ 0 != ( pPrevLine = aLine.GetPrevLine() ) &&
+ pPrevLine != aLine.GetCurr() )
+ aLine.PrevLine();
+ aCharBox.SSize().Width() /= 2;
+
+ // siehe Kommentar in SwTxtFrm::GetCrsrOfst()
+#ifndef PRODUCT
+ const xub_StrLen nOldNode = pPam->pPoint->nNode.GetIndex();
+#endif
+ // Der Node soll nicht gewechselt werden
+ xub_StrLen nOfst = aLine.GetCrsrOfst( pPam->pPoint,
+ aCharBox.Pos(), sal_False );
+ ASSERT( nOldNode == pPam->pPoint->nNode.GetIndex(),
+ "SwTxtFrm::UnitUp: illegal node change" )
+
+ // 7684: Wir stellen sicher, dass wir uns nach oben bewegen.
+ if( nOfst >= nStart && nStart )
+ {
+ // nOfst = nStart - 1;
+ nOfst = nStart;
+ aSet.SetRight( sal_True );
+ }
+ pPam->pPoint->nContent =
+ SwIndex( ((SwTxtFrm*)this)->GetTxtNode(), nOfst );
+ return sal_True;
+ }
+ if ( IsFollow() )
+ {
+ aLine.GetCharRect( &aCharBox, nPos );
+ aCharBox.SSize().Width() /= 2;
+ }
+ break;
+ } while ( sal_True );
+ }
+ /* Wenn this ein Follow ist und ein Prev miszlang, so
+ * muessen wir in die letzte Zeile des Master ... und der sind wir.
+ * Oder wir sind ein Follow mit Follow, dann muessen wir uns den
+ * Master extra besorgen...
+ */
+ if ( IsFollow() )
+ {
+ const SwTxtFrm *pPrev = FindMaster();
+ xub_StrLen nOffs = GetOfst();
+ if( pPrev )
+ {
+ ViewShell *pSh = GetShell();
+ sal_Bool bProtectedAllowed = pSh && pSh->GetViewOptions()->IsCursorInProtectedArea();
+ const SwTxtFrm *pPrevPrev = pPrev;
+ // Hier werden geschuetzte Frames und Frame ohne Inhalt ausgelassen
+ while( pPrevPrev && ( pPrevPrev->GetOfst() == nOffs ||
+ ( !bProtectedAllowed && pPrevPrev->IsProtected() ) ) )
+ {
+ pPrev = pPrevPrev;
+ nOffs = pPrev->GetOfst();
+ if ( pPrevPrev->IsFollow() )
+ pPrevPrev = pPrev->FindMaster();
+ else
+ pPrevPrev = NULL;
+ }
+ if ( !pPrevPrev )
+ return pPrev->SwCntntFrm::UnitUp( pPam, nOffset, bSetInReadOnly );
+ aCharBox.Pos().Y() = pPrevPrev->Frm().Bottom() - 1;
+ return pPrevPrev->GetKeyCrsrOfst( pPam->pPoint, aCharBox.Pos() );
+ }
+ }
+ return SwCntntFrm::UnitUp( pPam, nOffset, bSetInReadOnly );
+}
+
+/*************************************************************************
+ * SwTxtFrm::_UnitDown()
+ *************************************************************************/
+
+sal_Bool SwTxtFrm::_UnitDown(SwPaM *pPam, const SwTwips nOffset,
+ sal_Bool bSetInReadOnly ) const
+{
+
+ if ( IsInTab() &&
+ pPam->GetNode( sal_True )->StartOfSectionNode() !=
+ pPam->GetNode( sal_False )->StartOfSectionNode() )
+ {
+ //Wenn der PaM in unterschiedlichen Boxen sitzt, so handelt es sich um
+ //eine Tabellenselektion; diese wird von der Basisklasse abgearbeitet.
+ return SwCntntFrm::UnitDown( pPam, nOffset, bSetInReadOnly );
+ }
+ ((SwTxtFrm*)this)->GetFormatted();
+ const xub_StrLen nPos = pPam->pPoint->nContent.GetIndex();
+ SwRect aCharBox;
+ const SwCntntFrm *pFollow;
+ if ( !IsEmpty() && !IsHiddenNow() )
+ {
+ xub_StrLen nFormat = STRING_LEN;
+ do
+ {
+ if( nFormat != STRING_LEN && !IsFollow() &&
+ !lcl_ChangeOffset( ((SwTxtFrm*)this), nFormat ) )
+ break;
+
+ SwTxtSizeInfo aInf( (SwTxtFrm*)this );
+ SwTxtCursor aLine( ((SwTxtFrm*)this), &aInf );
+ nFormat = aLine.GetEnd();
+
+ aLine.CharCrsrToLine( nPos );
+ if( aLine.GetNextLine() )
+ {
+ const xub_StrLen nStart = aLine.GetStart();
+ SwRect aCharBox;
+ aLine.GetCharRect( &aCharBox, nPos );
+ aLine.NextLine();
+ aCharBox.SSize().Width() /= 2;
+#ifndef PRODUCT
+ // siehe Kommentar in SwTxtFrm::GetCrsrOfst()
+ const xub_StrLen nOldNode = pPam->pPoint->nNode.GetIndex();
+#endif
+ xub_StrLen nOfst = aLine.GetCrsrOfst( pPam->pPoint,
+ aCharBox.Pos(), sal_False );
+ ASSERT( nOldNode == pPam->pPoint->nNode.GetIndex(),
+ "SwTxtFrm::UnitDown: illegal node change" )
+
+ // 7684: Wir stellen sicher, dass wir uns nach unten bewegen.
+ if( nOfst <= nStart )
+ nOfst = nStart + 1;
+ pPam->pPoint->nContent =
+ SwIndex( ((SwTxtFrm*)this)->GetTxtNode(), nOfst );
+ return sal_True;
+ }
+ if( 0 != ( pFollow = GetFollow() ) )
+ { // geschuetzte Follows auslassen
+ const SwCntntFrm* pTmp = pFollow;
+ ViewShell *pSh = GetShell();
+ if( !pSh || !pSh->GetViewOptions()->IsCursorInProtectedArea() )
+ {
+ while( pFollow && pFollow->IsProtected() )
+ {
+ pTmp = pFollow;
+ pFollow = pFollow->GetFollow();
+ }
+ }
+ if( !pFollow ) // nur noch geschuetzte
+ return pTmp->SwCntntFrm::UnitDown( pPam, nOffset, bSetInReadOnly );
+ aLine.GetCharRect( &aCharBox, nPos );
+ aCharBox.SSize().Width() /= 2;
+ }
+ else if( !IsFollow() )
+ {
+ xub_StrLen nTmpLen = aInf.GetTxt().Len();
+ if( aLine.GetEnd() < nTmpLen )
+ {
+ if( nFormat <= GetOfst() )
+ {
+ nFormat = Min( xub_StrLen( GetOfst() + MIN_OFFSET_STEP ),
+ nTmpLen );
+ if( nFormat <= GetOfst() )
+ break;
+ }
+ continue;
+ }
+ }
+ break;
+ } while( sal_True );
+ }
+ else
+ pFollow = GetFollow();
+
+ // Bei Follows schlagen wir eine Abkuerzung
+ if( pFollow )
+ {
+ aCharBox.Pos().Y() = pFollow->Frm().Top() + 1;
+ return ((SwTxtFrm*)pFollow)->GetKeyCrsrOfst( pPam->pPoint,
+ aCharBox.Pos() );
+ }
+ return SwCntntFrm::UnitDown( pPam, nOffset, bSetInReadOnly );
+}
+
+/*************************************************************************
+ * virtual SwTxtFrm::UnitUp()
+ *************************************************************************/
+
+sal_Bool SwTxtFrm::UnitUp(SwPaM *pPam, const SwTwips nOffset,
+ sal_Bool bSetInReadOnly ) const
+{
+ /* Im CrsrSh::Up() wird CntntNode::GetFrm() gerufen.
+ * Dies liefert _immer_ den Master zurueck.
+ * Um das Cursortravelling nicht zu belasten, korrigieren wir
+ * hier im SwTxtFrm.
+ * Wir ermittelt UnitUp fuer pFrm, pFrm ist entweder ein Master (=this)
+ * oder ein Follow (!=this)
+ */
+ const SwTxtFrm *pFrm = GetAdjFrmAtPos( (SwTxtFrm*)this, *(pPam->GetPoint()),
+ SwTxtCursor::IsRightMargin() );
+ const sal_Bool bRet = pFrm->_UnitUp( pPam, nOffset, bSetInReadOnly );
+
+ // 8626: kein SwTxtCursor::SetRightMargin( sal_False );
+ // statt dessen steht ein SwSetToRightMargin im _UnitUp
+ return bRet;
+}
+
+/*************************************************************************
+ * virtual SwTxtFrm::UnitDown()
+ *************************************************************************/
+
+sal_Bool SwTxtFrm::UnitDown(SwPaM *pPam, const SwTwips nOffset,
+ sal_Bool bSetInReadOnly ) const
+{
+ const SwTxtFrm *pFrm = GetAdjFrmAtPos((SwTxtFrm*)this, *(pPam->GetPoint()),
+ SwTxtCursor::IsRightMargin() );
+ const sal_Bool bRet = pFrm->_UnitDown( pPam, nOffset, bSetInReadOnly );
+ SwTxtCursor::SetRightMargin( sal_False );
+ return bRet;
+}
+
+void SwTxtFrm::FillCrsrPos( SwFillData& rFill ) const
+{
+ if( !rFill.bColumn && GetUpper()->IsColBodyFrm() ) // ColumnFrms jetzt mit BodyFrm
+ {
+ const SwColumnFrm* pTmp =
+ (SwColumnFrm*)GetUpper()->GetUpper()->GetUpper()->Lower(); // die 1. Spalte
+ // der erste SwFrm im BodyFrm der ersten Spalte
+ const SwFrm* pFrm = ((SwLayoutFrm*)pTmp->Lower())->Lower();
+ MSHORT nNextCol = 0;
+ // In welcher Spalte landen wir?
+ while( rFill.X() > pTmp->Frm().Right() && pTmp->GetNext() )
+ {
+ pTmp = (SwColumnFrm*)pTmp->GetNext();
+ if( ((SwLayoutFrm*)pTmp->Lower())->Lower() ) // ColumnFrms jetzt mit BodyFrm
+ {
+ pFrm = ((SwLayoutFrm*)pTmp->Lower())->Lower();
+ nNextCol = 0;
+ }
+ else
+ ++nNextCol; // leere Spalten erfordern Spaltenumbrueche
+ }
+ if( pTmp != GetUpper()->GetUpper() ) // Sind wir in einer anderen Spalte gelandet?
+ {
+ if( !pFrm )
+ return;
+ if( nNextCol )
+ {
+ while( pFrm->GetNext() )
+ pFrm = pFrm->GetNext();
+ }
+ else
+ {
+ while( pFrm->GetNext() && pFrm->Frm().Bottom() < rFill.Y() )
+ pFrm = pFrm->GetNext();
+ }
+ // Kein Fuellen, wenn als letzter Frame in der anvisierten
+ // Spalte kein Absatz, sondern z.B. eine Tabelle steht
+ if( pFrm->IsTxtFrm() )
+ {
+ rFill.Fill().nColumnCnt = nNextCol;
+ rFill.bColumn = sal_True;
+ if( rFill.pPos )
+ {
+ SwTxtNode* pTxtNd = ((SwTxtFrm*)pFrm)->GetTxtNode();
+ rFill.pPos->nNode = *pTxtNd;
+ rFill.pPos->nContent.Assign( pTxtNd, pTxtNd->GetTxt().Len() );
+ }
+ if( nNextCol )
+ {
+ rFill.aFrm = pTmp->Prt();
+ rFill.aFrm += pTmp->Frm().Pos();
+ }
+ else
+ rFill.aFrm = pFrm->Frm();
+ ((SwTxtFrm*)pFrm)->FillCrsrPos( rFill );
+ }
+ return;
+ }
+ }
+ sal_Bool bFill = sal_True;
+ SwFont *pFnt;
+ SwTxtFmtColl* pColl = GetTxtNode()->GetTxtColl();
+ MSHORT nFirst = GetTxtNode()->GetSwAttrSet().GetULSpace().GetLower();
+ SwTwips nDiff = rFill.Y() - Frm().Bottom();
+ if( nDiff < nFirst )
+ nDiff = -1;
+ else
+ pColl = &pColl->GetNextTxtFmtColl();
+ SwAttrSet aSet( ((SwDoc*)GetTxtNode()->GetDoc())->GetAttrPool(), aTxtFmtCollSetRange );
+ const SwAttrSet* pSet = &pColl->GetAttrSet();
+ ViewShell *pSh = GetShell();
+ if( GetTxtNode()->HasSwAttrSet() )
+ {
+ aSet.Put( *GetTxtNode()->GetpSwAttrSet() );
+ aSet.SetParent( pSet );
+ pSet = &aSet;
+ pFnt = new SwFont( pSet );
+ }
+ else
+ {
+ SwFontAccess aFontAccess( pColl, pSh );
+ pFnt = new SwFont( *aFontAccess.Get()->GetFont() );
+ pFnt->ChkMagic( pSh, pFnt->GetActual() );
+ }
+ OutputDevice *pOut = pSh->GetOut();
+ if ( !GetTxtNode()->GetDoc()->IsBrowseMode() ||
+ ( pSh->GetViewOptions()->IsPrtFormat() ) )
+ {
+ Printer *pPrt = GetTxtNode()->GetDoc()->GetPrt();
+ if ( pPrt && pPrt->IsValid() )
+ pOut = pPrt;
+ }
+ pFnt->SetFntChg( sal_True );
+ pFnt->ChgPhysFnt( pSh, pOut );
+
+ SwTwips nLineHeight = pFnt->GetHeight( pSh, pOut );
+
+ if( nLineHeight )
+ {
+ const SvxULSpaceItem &rUL = pSet->GetULSpace();
+ SwTwips nDist = Max( rUL.GetLower(), rUL.GetUpper() );
+ if( rFill.Fill().nColumnCnt )
+ {
+ rFill.aFrm.Height( nLineHeight );
+ nDiff = rFill.Y() - rFill.Bottom();
+ nFirst = 0;
+ }
+ else if( nDist < nFirst )
+ nFirst -= nDist;
+ else
+ nFirst = 0;
+ nDist = Max( nDist, long( GetLineSpace() ) );
+ nDist += nLineHeight;
+ nDiff -= nFirst;
+
+ if( nDiff > 0 )
+ {
+ nDiff /= nDist;
+ rFill.Fill().nParaCnt = nDiff + 1;
+ rFill.nLineWidth = 0;
+ rFill.bInner = sal_False;
+ rFill.bEmpty = sal_True;
+ rFill.SetOrient( HORI_LEFT );
+ }
+ else
+ nDiff = -1;
+ if( rFill.bInner )
+ bFill = sal_False;
+ else
+ {
+ const SvxTabStopItem &rRuler = pSet->GetTabStops();
+ const SvxLRSpaceItem &rLRSpace = pSet->GetLRSpace();
+
+ SwRect &rRect = rFill.Fill().aCrsr;
+ rRect.Top( rFill.Bottom() + (nDiff+1) * nDist - nLineHeight );
+ if( nFirst && nDiff > -1 )
+ rRect.Top( rRect.Top() + nFirst );
+ rRect.Height( nLineHeight );
+ SwTwips nLeft = rFill.Left() + rLRSpace.GetLeft() +
+ GetTxtNode()->GetLeftMarginWithNum( sal_False );
+ SwTwips nRight = rFill.Right() - rLRSpace.GetRight();
+ SwTwips nCenter = ( nLeft + nRight ) / 2;
+ rRect.Left( nLeft );
+ if( FILL_MARGIN == rFill.Mode() )
+ {
+ if( rFill.bEmpty )
+ {
+ rFill.SetOrient( HORI_LEFT );
+ if( rFill.X() < nCenter )
+ {
+ if( rFill.X() > ( nLeft + 2 * nCenter ) / 3 )
+ {
+ rFill.SetOrient( HORI_CENTER );
+ rRect.Left( nCenter );
+ }
+ }
+ else if( rFill.X() > ( nRight + 2 * nCenter ) / 3 )
+ {
+ rFill.SetOrient( HORI_RIGHT );
+ rRect.Left( nRight );
+ }
+ else
+ {
+ rFill.SetOrient( HORI_CENTER );
+ rRect.Left( nCenter );
+ }
+ }
+ else
+ bFill = sal_False;
+ }
+ else
+ {
+ SwTwips nSpace;
+ if( FILL_TAB != rFill.Mode() )
+ {
+static sal_Char __READONLY_DATA sDoubleSpace[] = " ";
+ const XubString aTmp( sDoubleSpace, RTL_TEXTENCODING_MS_1252 );
+ nSpace = pFnt->_GetTxtSize( pSh, pOut, aTmp, 0, 2 ).Width()/2;
+ }
+ if( rFill.X() >= nRight )
+ {
+ if( FILL_INDENT != rFill.Mode() && ( rFill.bEmpty ||
+ rFill.X() > rFill.nLineWidth + FILL_MIN_DIST ) )
+ {
+ rFill.SetOrient( HORI_RIGHT );
+ rRect.Left( nRight );
+ }
+ else
+ bFill = sal_False;
+ }
+ else if( FILL_INDENT == rFill.Mode() )
+ {
+ SwTwips nIndent = rFill.X();
+ if( !rFill.bEmpty || nIndent > nRight )
+ bFill = sal_False;
+ else
+ {
+ nIndent -= rFill.Left();
+ if( nIndent >= 0 && nSpace )
+ {
+ nIndent /= nSpace;
+ nIndent *= nSpace;
+ rFill.SetTab( MSHORT( nIndent ) );
+ rRect.Left( nIndent + rFill.Left() );
+ }
+ else
+ bFill = sal_False;
+ }
+ }
+ else if( rFill.X() > nLeft )
+ {
+ SwTwips nTxtLeft = rFill.Left() + rLRSpace.GetTxtLeft() +
+ GetTxtNode()->GetLeftMarginWithNum( sal_True );
+ rFill.nLineWidth += rFill.bFirstLine ? nLeft : nTxtLeft;
+ SwTwips nLeftTab = nLeft;
+ SwTwips nRightTab = nLeft;
+ MSHORT nSpaceCnt = 0;
+ MSHORT nTabCnt = 0;
+ MSHORT nIdx = 0;
+ do
+ {
+ nLeftTab = nRightTab;
+ if( nIdx < rRuler.Count() )
+ {
+ const SvxTabStop &rTabStop = rRuler.operator[](nIdx);
+ nRightTab = nTxtLeft + rTabStop.GetTabPos();
+ if( nLeftTab < nTxtLeft && nRightTab > nTxtLeft )
+ nRightTab = nTxtLeft;
+ else
+ ++nIdx;
+ if( nRightTab > rFill.nLineWidth )
+ ++nTabCnt;
+ }
+ else
+ {
+ const SvxTabStopItem& rTab =
+ (const SvxTabStopItem &)pSet->
+ GetPool()->GetDefaultItem( RES_PARATR_TABSTOP );
+ MSHORT nDefTabDist = (MSHORT)rTab.GetStart()->GetTabPos();
+ nRightTab = nLeftTab - nTxtLeft;
+ nRightTab /= nDefTabDist;
+ nRightTab = nRightTab * nDefTabDist + nTxtLeft;
+ while ( nRightTab <= nLeftTab )
+ nRightTab += nDefTabDist;
+ if( nRightTab > rFill.nLineWidth )
+ ++nTabCnt;
+ while ( nRightTab < rFill.X() )
+ {
+ nRightTab += nDefTabDist;
+ if( nRightTab > rFill.nLineWidth )
+ ++nTabCnt;
+ }
+ if( nLeftTab < nRightTab - nDefTabDist )
+ nLeftTab = nRightTab - nDefTabDist;
+ }
+ if( nRightTab > nRight )
+ nRightTab = nRight;
+ }
+ while( rFill.X() > nRightTab );
+ --nTabCnt;
+ if( FILL_TAB != rFill.Mode() )
+ {
+ if( nSpace > 0 )
+ {
+ if( !nTabCnt )
+ nLeftTab = rFill.nLineWidth;
+ while( nLeftTab < rFill.X() )
+ {
+ nLeftTab += nSpace;
+ ++nSpaceCnt;
+ }
+ if( nSpaceCnt )
+ {
+ nLeftTab -= nSpace;
+ --nSpaceCnt;
+ }
+ if( rFill.X() - nLeftTab > nRightTab - rFill.X() )
+ {
+ nSpaceCnt = 0;
+ ++nTabCnt;
+ rRect.Left( nRightTab );
+ }
+ else
+ {
+ if( rFill.X() - nLeftTab > nSpace/2 )
+ {
+ ++nSpaceCnt;
+ rRect.Left( nLeftTab + nSpace );
+ }
+ else
+ rRect.Left( nLeftTab );
+ }
+ }
+ else if( rFill.X() - nLeftTab < nRightTab - rFill.X() )
+ rRect.Left( nLeftTab );
+ else
+ {
+ if( nRightTab >= nRight )
+ {
+ rFill.SetOrient( HORI_RIGHT );
+ rRect.Left( nRight );
+ nTabCnt = 0;
+ nSpaceCnt = 0;
+ }
+ else
+ {
+ rRect.Left( nRightTab );
+ ++nTabCnt;
+ }
+ }
+ }
+ else
+ {
+ if( rFill.X() - nLeftTab < nRightTab - rFill.X() )
+ rRect.Left( nLeftTab );
+ else
+ {
+ if( nRightTab >= nRight )
+ {
+ rFill.SetOrient( HORI_RIGHT );
+ rRect.Left( nRight );
+ nTabCnt = 0;
+ nSpaceCnt = 0;
+ }
+ else
+ {
+ rRect.Left( nRightTab );
+ ++nTabCnt;
+ }
+ }
+ }
+ rFill.SetTab( nTabCnt );
+ rFill.SetSpace( nSpaceCnt );
+ if( bFill )
+ {
+ if( Abs( rFill.X() - nCenter ) <=
+ Abs( rFill.X() - rRect.Left() ) )
+ {
+ rFill.SetOrient( HORI_CENTER );
+ rFill.SetTab( 0 );
+ rFill.SetSpace( 0 );
+ rRect.Left( nCenter );
+ }
+ if( !rFill.bEmpty )
+ rFill.nLineWidth += FILL_MIN_DIST;
+ if( rRect.Left() < rFill.nLineWidth )
+ bFill = sal_False;
+ }
+ }
+ }
+ // Gehen wir ueber die Unterkante der Seite/Spalte etc. hinaus?
+ const SwFrm* pUp = GetUpper();
+ if( pUp->IsInSct() )
+ {
+ if( pUp->IsSctFrm() )
+ pUp = pUp->GetUpper();
+ else if( pUp->IsColBodyFrm() &&
+ pUp->GetUpper()->GetUpper()->IsSctFrm() )
+ pUp = pUp->GetUpper()->GetUpper()->GetUpper();
+ }
+ if( pUp->Frm().Top() + pUp->Prt().Bottom() < rRect.Bottom() )
+ bFill = sal_False;
+ else
+ rRect.Width( 1 );
+ }
+ }
+ else
+ bFill = sal_False;
+ ((SwCrsrMoveState*)rFill.pCMS)->bFillRet = bFill;
+ delete pFnt;
+}
+
+