summaryrefslogtreecommitdiff
path: root/sw/source/ui/wrtsh/move.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sw/source/ui/wrtsh/move.cxx')
-rw-r--r--sw/source/ui/wrtsh/move.cxx691
1 files changed, 691 insertions, 0 deletions
diff --git a/sw/source/ui/wrtsh/move.cxx b/sw/source/ui/wrtsh/move.cxx
new file mode 100644
index 000000000000..dc196de9d9da
--- /dev/null
+++ b/sw/source/ui/wrtsh/move.cxx
@@ -0,0 +1,691 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sw.hxx"
+
+
+#include <sfx2/bindings.hxx>
+#include <wrtsh.hxx>
+#ifndef _VIEW_HXX
+#include <view.hxx>
+#endif
+#include <viewopt.hxx>
+#include <crsskip.hxx>
+
+/* Immer:
+ - Zuruecksetzen des Cursorstacks
+ - Timer nachtriggern
+ - gfs. GCAttr
+
+ bei Selektion
+ - SttSelect()
+
+ sonst
+ - EndSelect()
+ */
+
+const long nReadOnlyScrollOfst = 10;
+
+class ShellMoveCrsr
+{
+ SwWrtShell* pSh;
+ BOOL bAct;
+public:
+ inline ShellMoveCrsr( SwWrtShell* pWrtSh, BOOL bSel )
+ {
+ bAct = !pWrtSh->ActionPend() && (pWrtSh->GetFrmType(0,FALSE) & FRMTYPE_FLY_ANY);
+ ( pSh = pWrtSh )->MoveCrsr( BOOL(bSel) );
+ pWrtSh->GetView().GetViewFrame()->GetBindings().Invalidate(SID_HYPERLINK_GETLINK);
+ }
+ inline ~ShellMoveCrsr()
+ {
+ if( bAct )
+ {
+ //Die Action wird fuer das Scrollen in "einabsaetzigen" Rahmen mit
+ //fester Hoehe gebraucht.
+ pSh->StartAllAction();
+ pSh->EndAllAction();
+ }
+ }
+};
+
+void SwWrtShell::MoveCrsr( BOOL bWithSelect )
+{
+ ResetCursorStack();
+ if ( IsGCAttr() )
+ {
+ GCAttr();
+ ClearGCAttr();
+ }
+ if ( bWithSelect )
+ SttSelect();
+ else
+ {
+ EndSelect();
+ (this->*fnKillSel)( 0, FALSE );
+ }
+}
+
+BOOL SwWrtShell::SimpleMove( FNSimpleMove FnSimpleMove, BOOL bSelect )
+{
+ BOOL nRet;
+ if( bSelect )
+ {
+ SttCrsrMove();
+ MoveCrsr( TRUE );
+ nRet = (this->*FnSimpleMove)();
+ EndCrsrMove();
+ }
+ else if( 0 != ( nRet = (this->*FnSimpleMove)() ) )
+ MoveCrsr( FALSE );
+ return nRet;
+}
+
+
+BOOL SwWrtShell::Left( USHORT nMode, BOOL bSelect,
+ USHORT nCount, BOOL bBasicCall, BOOL bVisual )
+{
+ if ( !bSelect && !bBasicCall && IsCrsrReadonly() && !GetViewOptions()->IsSelectionInReadonly())
+ {
+ Point aTmp( VisArea().Pos() );
+ aTmp.X() -= VisArea().Width() * nReadOnlyScrollOfst / 100;
+ rView.SetVisArea( aTmp );
+ return TRUE;
+ }
+ else
+ {
+ ShellMoveCrsr aTmp( this, bSelect );
+ return SwCrsrShell::Left( nCount, nMode, bVisual );
+ }
+}
+
+
+
+BOOL SwWrtShell::Right( USHORT nMode, BOOL bSelect,
+ USHORT nCount, BOOL bBasicCall, BOOL bVisual )
+{
+ if ( !bSelect && !bBasicCall && IsCrsrReadonly() && !GetViewOptions()->IsSelectionInReadonly() )
+ {
+ Point aTmp( VisArea().Pos() );
+ aTmp.X() += VisArea().Width() * nReadOnlyScrollOfst / 100;
+ aTmp.X() = rView.SetHScrollMax( aTmp.X() );
+ rView.SetVisArea( aTmp );
+ return TRUE;
+ }
+ else
+ {
+ ShellMoveCrsr aTmp( this, bSelect );
+ return SwCrsrShell::Right( nCount, nMode, bVisual );
+ }
+}
+
+
+
+BOOL SwWrtShell::Up( BOOL bSelect, USHORT nCount, BOOL bBasicCall )
+{
+ if ( !bSelect && !bBasicCall && IsCrsrReadonly() && !GetViewOptions()->IsSelectionInReadonly())
+ {
+ Point aTmp( VisArea().Pos() );
+ aTmp.Y() -= VisArea().Height() * nReadOnlyScrollOfst / 100;
+ rView.SetVisArea( aTmp );
+ return TRUE;
+ }
+ else
+ {
+ ShellMoveCrsr aTmp( this, bSelect );
+ return SwCrsrShell::Up( nCount );
+ }
+}
+
+
+
+BOOL SwWrtShell::Down( BOOL bSelect, USHORT nCount, BOOL bBasicCall )
+{
+ if ( !bSelect && !bBasicCall && IsCrsrReadonly() && !GetViewOptions()->IsSelectionInReadonly())
+ {
+ Point aTmp( VisArea().Pos() );
+ aTmp.Y() += VisArea().Height() * nReadOnlyScrollOfst / 100;
+ aTmp.Y() = rView.SetVScrollMax( aTmp.Y() );
+ rView.SetVisArea( aTmp );
+ return TRUE;
+ }
+ else
+ {
+ ShellMoveCrsr aTmp( this, bSelect );
+ return SwCrsrShell::Down( nCount );
+ }
+}
+
+
+
+BOOL SwWrtShell::LeftMargin( BOOL bSelect, BOOL bBasicCall )
+{
+ if ( !bSelect && !bBasicCall && IsCrsrReadonly() )
+ {
+ Point aTmp( VisArea().Pos() );
+ aTmp.X() = DOCUMENTBORDER;
+ rView.SetVisArea( aTmp );
+ return TRUE;
+ }
+ else
+ {
+ ShellMoveCrsr aTmp( this, bSelect );
+ return SwCrsrShell::LeftMargin();
+ }
+}
+
+
+
+BOOL SwWrtShell::RightMargin( BOOL bSelect, BOOL bBasicCall )
+{
+ if ( !bSelect && !bBasicCall && IsCrsrReadonly() )
+ {
+ Point aTmp( VisArea().Pos() );
+ aTmp.X() = GetDocSize().Width() - VisArea().Width() + DOCUMENTBORDER;
+ if( DOCUMENTBORDER > aTmp.X() )
+ aTmp.X() = DOCUMENTBORDER;
+ rView.SetVisArea( aTmp );
+ return TRUE;
+ }
+ else
+ {
+ ShellMoveCrsr aTmp( this, bSelect );
+ return SwCrsrShell::RightMargin(bBasicCall);
+ }
+}
+
+
+
+BOOL SwWrtShell::GoStart( BOOL bKeepArea, BOOL *pMoveTable,
+ BOOL bSelect, BOOL bDontMoveRegion )
+{
+ if ( IsCrsrInTbl() )
+ {
+ const BOOL bBoxSelection = HasBoxSelection();
+ if( !bBlockMode )
+ {
+ if ( !bSelect )
+ EnterStdMode();
+ else
+ SttSelect();
+ }
+ // Tabellenzelle?
+ if ( !bBoxSelection && (MoveSection( fnSectionCurr, fnSectionStart)
+ || bDontMoveRegion))
+ {
+ if ( pMoveTable )
+ *pMoveTable = FALSE;
+ return TRUE;
+ }
+ if( MoveTable( fnTableCurr, fnTableStart ) || bDontMoveRegion )
+ {
+ if ( pMoveTable )
+ *pMoveTable = TRUE;
+ return TRUE;
+ }
+ else if( bBoxSelection && pMoveTable )
+ {
+ // JP 09.01.96: wir haben eine Boxselektion (oder leere Zelle)
+ // und wollen selektieren (pMoveTable wird im
+ // SelAll gesetzt). Dann darf die Tabelle nicht
+ // verlassen werden; sonst ist keine Selektion der
+ // gesamten Tabelle moeglich!
+ *pMoveTable = TRUE;
+ return TRUE;
+ }
+ }
+
+ if( !bBlockMode )
+ {
+ if ( !bSelect )
+ EnterStdMode();
+ else
+ SttSelect();
+ }
+ const USHORT nFrmType = GetFrmType(0,FALSE);
+ if ( FRMTYPE_FLY_ANY & nFrmType )
+ {
+ if( MoveSection( fnSectionCurr, fnSectionStart ) )
+ return TRUE;
+ else if ( FRMTYPE_FLY_FREE & nFrmType || bDontMoveRegion )
+ return FALSE;
+ }
+ if(( FRMTYPE_HEADER | FRMTYPE_FOOTER | FRMTYPE_FOOTNOTE ) & nFrmType )
+ {
+ if ( MoveSection( fnSectionCurr, fnSectionStart ) )
+ return TRUE;
+ else if ( bKeepArea )
+ return TRUE;
+ }
+ // Bereiche ???
+ return SwCrsrShell::MoveRegion( fnRegionCurrAndSkip, fnRegionStart ) ||
+ SwCrsrShell::SttEndDoc(TRUE);
+}
+
+
+
+BOOL SwWrtShell::GoEnd(BOOL bKeepArea, BOOL *pMoveTable)
+{
+ if ( pMoveTable && *pMoveTable )
+ return MoveTable( fnTableCurr, fnTableEnd );
+
+ if ( IsCrsrInTbl() )
+ {
+ if ( MoveSection( fnSectionCurr, fnSectionEnd ) ||
+ MoveTable( fnTableCurr, fnTableEnd ) )
+ return TRUE;
+ }
+ else
+ {
+ const USHORT nFrmType = GetFrmType(0,FALSE);
+ if ( FRMTYPE_FLY_ANY & nFrmType )
+ {
+ if ( MoveSection( fnSectionCurr, fnSectionEnd ) )
+ return TRUE;
+ else if ( FRMTYPE_FLY_FREE & nFrmType )
+ return FALSE;
+ }
+ if(( FRMTYPE_HEADER | FRMTYPE_FOOTER | FRMTYPE_FOOTNOTE ) & nFrmType )
+ {
+ if ( MoveSection( fnSectionCurr, fnSectionEnd) )
+ return TRUE;
+ else if ( bKeepArea )
+ return TRUE;
+ }
+ }
+ // Bereiche ???
+ return SwCrsrShell::MoveRegion( fnRegionCurrAndSkip, fnRegionEnd ) ||
+ SwCrsrShell::SttEndDoc(FALSE);
+}
+
+
+
+BOOL SwWrtShell::SttDoc( BOOL bSelect )
+{
+ ShellMoveCrsr aTmp( this, bSelect );
+ return GoStart(FALSE, 0, bSelect );
+}
+
+
+
+BOOL SwWrtShell::EndDoc( BOOL bSelect)
+{
+ ShellMoveCrsr aTmp( this, bSelect );
+ return GoEnd();
+}
+
+
+BOOL SwWrtShell::SttNxtPg( BOOL bSelect )
+{
+ ShellMoveCrsr aTmp( this, bSelect );
+ return MovePage( fnPageNext, fnPageStart );
+}
+
+
+
+BOOL SwWrtShell::SttPrvPg( BOOL bSelect )
+{
+ ShellMoveCrsr aTmp( this, bSelect );
+ return MovePage( fnPagePrev, fnPageStart );
+}
+
+
+
+BOOL SwWrtShell::EndNxtPg( BOOL bSelect )
+{
+ ShellMoveCrsr aTmp( this, bSelect );
+ return MovePage( fnPageNext, fnPageEnd );
+}
+
+
+
+BOOL SwWrtShell::EndPrvPg( BOOL bSelect )
+{
+ ShellMoveCrsr aTmp( this, bSelect );
+ return MovePage( fnPagePrev, fnPageEnd );
+}
+
+
+
+BOOL SwWrtShell::SttPg( BOOL bSelect )
+{
+ ShellMoveCrsr aTmp( this, bSelect );
+ return MovePage( fnPageCurr, fnPageStart );
+}
+
+
+
+BOOL SwWrtShell::EndPg( BOOL bSelect )
+{
+ ShellMoveCrsr aTmp( this, bSelect );
+ return MovePage( fnPageCurr, fnPageEnd );
+}
+
+
+
+BOOL SwWrtShell::SttPara( BOOL bSelect )
+{
+ ShellMoveCrsr aTmp( this, bSelect );
+ return MovePara( fnParaCurr, fnParaStart );
+}
+
+
+
+BOOL SwWrtShell::EndPara( BOOL bSelect )
+{
+ ShellMoveCrsr aTmp( this, bSelect );
+ return MovePara(fnParaCurr,fnParaEnd);
+}
+
+
+/*------------------------------------------------------------------------
+ Beschreibung: Spaltenweises Springen
+ Parameter: mit oder ohne SSelection
+ Return: Erfolg oder Misserfolg
+------------------------------------------------------------------------*/
+
+
+
+BOOL SwWrtShell::StartOfColumn( BOOL bSelect )
+{
+ ShellMoveCrsr aTmp( this, bSelect);
+ return MoveColumn(fnColumnCurr, fnColumnStart);
+}
+
+
+
+BOOL SwWrtShell::EndOfColumn( BOOL bSelect )
+{
+ ShellMoveCrsr aTmp( this, bSelect);
+ return MoveColumn(fnColumnCurr, fnColumnEnd);
+}
+
+
+
+BOOL SwWrtShell::StartOfNextColumn( BOOL bSelect )
+{
+ ShellMoveCrsr aTmp( this, bSelect);
+ return MoveColumn( fnColumnNext, fnColumnStart);
+}
+
+
+
+BOOL SwWrtShell::EndOfNextColumn( BOOL bSelect )
+{
+ ShellMoveCrsr aTmp( this, bSelect);
+ return MoveColumn(fnColumnNext, fnColumnEnd);
+}
+
+
+
+BOOL SwWrtShell::StartOfPrevColumn( BOOL bSelect )
+{
+ ShellMoveCrsr aTmp( this, bSelect);
+ return MoveColumn(fnColumnPrev, fnColumnStart);
+}
+
+
+
+BOOL SwWrtShell::EndOfPrevColumn( BOOL bSelect )
+{
+ ShellMoveCrsr aTmp( this, bSelect);
+ return MoveColumn(fnColumnPrev, fnColumnEnd);
+}
+
+
+
+BOOL SwWrtShell::PushCrsr(SwTwips lOffset, BOOL bSelect)
+{
+ BOOL bDiff = FALSE;
+ SwRect aOldRect( GetCharRect() ), aTmpArea( VisArea() );
+
+ //bDestOnStack besagt, ob ich den Cursor nicht an die aktuelle Position
+ //setzen konnte, da in diesem Bereich kein Inhalt vorhanden ist.
+ if( !bDestOnStack )
+ {
+ Point aPt( aOldRect.Center() );
+
+ if( !IsCrsrVisible() )
+ // set CrsrPos to top-/bottom left pos. So the pagescroll is not
+ // be dependent on the current cursor, but on the visarea.
+ aPt.Y() = aTmpArea.Top() + aTmpArea.Height() / 2;
+
+ aPt.Y() += lOffset;
+ aDest = GetCntntPos(aPt,lOffset > 0);
+ aDest.X() = aPt.X();
+ bDestOnStack = TRUE;
+ }
+
+ //falls wir eine Rahmenselektion hatten, muss diese nach dem
+ //fnSetCrsr entfernt werden und damit wir da wieder hinkommen
+ //auf dem Stack gemerkt werden.
+ BOOL bIsFrmSel = FALSE;
+
+ BOOL bIsObjSel = FALSE;
+
+ //Zielposition liegt jetzt innerhalb des sichtbaren Bereiches -->
+ //Cursor an die Zielposition setzen; merken, dass keine Ziel-
+ //position mehr auf dem Stack steht.
+ //Der neue sichtbare Bereich wird zuvor ermittelt.
+ aTmpArea.Pos().Y() += lOffset;
+ if( aTmpArea.IsInside(aDest) )
+ {
+ if( bSelect )
+ SttSelect();
+ else
+ EndSelect();
+
+ bIsFrmSel = IsFrmSelected();
+ bIsObjSel = 0 != IsObjSelected();
+
+ // Rahmenselektion aufheben
+ if( bIsFrmSel || bIsObjSel )
+ {
+ UnSelectFrm();
+ LeaveSelFrmMode();
+ if ( bIsObjSel )
+ {
+ GetView().SetDrawFuncPtr( NULL );
+ GetView().LeaveDrawCreate();
+ }
+
+ CallChgLnk();
+ }
+
+ (this->*fnSetCrsr)( &aDest, TRUE );
+
+ bDiff = aOldRect != GetCharRect();
+
+ if( bIsFrmSel )
+ {
+// CallChgLnk();
+ // bei Frames immer nur die obere Ecke nehmen, damit dieser
+ // wieder selektiert werden kann
+ aOldRect.SSize( 5, 5 );
+ }
+
+ // Zuruecksetzen des Dest. SPoint Flags
+ bDestOnStack = FALSE;
+ }
+
+ // Position auf den Stack; bDiff besagt, ob ein Unterschied zwischen
+ // der alten und der neuen Cursorposition besteht.
+ pCrsrStack = new CrsrStack( bDiff, bIsFrmSel, aOldRect.Center(),
+ lOffset, pCrsrStack );
+ return !bDestOnStack && bDiff;
+}
+
+
+
+BOOL SwWrtShell::PopCrsr(BOOL bUpdate, BOOL bSelect)
+{
+ if( 0 == pCrsrStack)
+ return FALSE;
+
+ const BOOL bValidPos = pCrsrStack->bValidCurPos;
+ if( bUpdate && bValidPos )
+ {
+ // falls ein Vorgaenger auf dem Stack steht, dessen Flag fuer eine
+ // gueltige Position verwenden.
+ SwRect aTmpArea(VisArea());
+ aTmpArea.Pos().Y() -= pCrsrStack->lOffset;
+ if( aTmpArea.IsInside( pCrsrStack->aDocPos ) )
+ {
+ if( bSelect )
+ SttSelect();
+ else
+ EndSelect();
+
+ (this->*fnSetCrsr)(&pCrsrStack->aDocPos, !pCrsrStack->bIsFrmSel);
+ if( pCrsrStack->bIsFrmSel && IsObjSelectable(pCrsrStack->aDocPos))
+ {
+ HideCrsr();
+ SelectObj( pCrsrStack->aDocPos );
+ EnterSelFrmMode( &pCrsrStack->aDocPos );
+ }
+ }
+ // Falls eine Verschiebung zwischen dem sichtbaren Bereich
+ // und der gemerkten Cursorpositionen auftritt, werden
+ // alle gemerkten Positionen weggeschmissen
+ else
+ {
+ _ResetCursorStack();
+ return FALSE;
+ }
+ }
+ CrsrStack *pTmp = pCrsrStack;
+ pCrsrStack = pCrsrStack->pNext;
+ delete pTmp;
+ if( 0 == pCrsrStack )
+ {
+ ePageMove = MV_NO;
+ bDestOnStack = FALSE;
+ }
+ return bValidPos;
+}
+
+/*
+ * Zuruecksetzen aller gepushten Cursorpositionen; dieser werden nicht
+ * zur Anzeige gebracht ( --> Kein Start-/EndAction!!)
+ */
+
+
+
+void SwWrtShell::_ResetCursorStack()
+{
+ CrsrStack *pTmp = pCrsrStack;
+ while(pCrsrStack)
+ {
+ pTmp = pCrsrStack->pNext;
+ delete pCrsrStack;
+ pCrsrStack = pTmp;
+ }
+ ePageMove = MV_NO;
+ bDestOnStack = FALSE;
+}
+/**************
+
+ falls kein Stack existiert --> Selektionen aufheben
+ falls Stack && Richtungswechsel
+ --> Cursor poppen und return
+ sonst
+ --> Cursor pushen
+ Cursor umsetzen
+
+***************/
+
+
+
+BOOL SwWrtShell::PageCrsr(SwTwips lOffset, BOOL bSelect)
+{
+ // nichts tun, wenn ein Offset von 0 angegeben wurde
+ if(!lOffset) return FALSE;
+ // Diente mal dazu, eine Neuformatierung fuer das Layout
+ // zu erzwingen.
+ // Hat so nicht funktioniert, da der Cursor nicht gesetzt
+ // wurde, da dies innerhalb einer Start- / EndActionklammerung
+ // nicht geschieht.
+ // Da am Ende nur ViewShell::EndAction() gerufen wird,
+ // findet auch hier keine Aktualisierung der Anzeige
+ // der Cursorposition statt.
+ // Die CrsrShell- Actionklammerung kann nicht verwendet werden,
+ // da sie immer zu einer Anzeige des Cursors fuehrt, also auch,
+ // wenn nach dem Blaettern in einen Bereich ohne gueltige Position
+ // geblaettert wurde.
+ // ViewShell::StartAction();
+ PageMove eDir = lOffset > 0? MV_PAGE_DOWN: MV_PAGE_UP;
+ // Richtungswechsel und Stack vorhanden
+ if( eDir != ePageMove && ePageMove != MV_NO && PopCrsr( TRUE, bSelect ))
+ return TRUE;
+
+ const BOOL bRet = PushCrsr(lOffset, bSelect);
+ ePageMove = eDir;
+ return bRet;
+}
+
+
+
+BOOL SwWrtShell::GotoPage(USHORT nPage, BOOL bRecord)
+{
+ ShellMoveCrsr aTmp( this, FALSE);
+ if( SwCrsrShell::GotoPage(nPage) && bRecord)
+ {
+ if(IsSelFrmMode())
+ {
+ UnSelectFrm();
+ LeaveSelFrmMode();
+ }
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+
+BOOL SwWrtShell::GotoMark( const ::sw::mark::IMark* const pMark, BOOL bSelect, BOOL bStart )
+{
+ ShellMoveCrsr aTmp( this, bSelect );
+ return SwCrsrShell::GotoMark( pMark, bStart );
+}
+
+
+
+BOOL SwWrtShell::SelectTxtAttr( USHORT nWhich, const SwTxtAttr* pAttr )
+{
+ BOOL bRet;
+ {
+ MV_KONTEXT(this);
+ SttSelect();
+ bRet = SwCrsrShell::SelectTxtAttr( nWhich, FALSE, pAttr );
+ }
+ EndSelect();
+ return bRet;
+}
+
+
+