| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the 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; |
| sal_Bool bAct; |
| public: |
| inline ShellMoveCrsr( SwWrtShell* pWrtSh, sal_Bool bSel ) |
| { |
| bAct = !pWrtSh->ActionPend() && (pWrtSh->GetFrmType(0,sal_False) & FRMTYPE_FLY_ANY); |
| ( pSh = pWrtSh )->MoveCrsr( sal_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( sal_Bool bWithSelect ) |
| { |
| ResetCursorStack(); |
| if ( IsGCAttr() ) |
| { |
| GCAttr(); |
| ClearGCAttr(); |
| } |
| if ( bWithSelect ) |
| SttSelect(); |
| else |
| { |
| EndSelect(); |
| (this->*fnKillSel)( 0, sal_False ); |
| } |
| } |
| |
| sal_Bool SwWrtShell::SimpleMove( FNSimpleMove FnSimpleMove, sal_Bool bSelect ) |
| { |
| sal_Bool nRet; |
| if( bSelect ) |
| { |
| SttCrsrMove(); |
| MoveCrsr( sal_True ); |
| nRet = (this->*FnSimpleMove)(); |
| EndCrsrMove(); |
| } |
| else if( 0 != ( nRet = (this->*FnSimpleMove)() ) ) |
| MoveCrsr( sal_False ); |
| return nRet; |
| } |
| |
| |
| sal_Bool SwWrtShell::Left( sal_uInt16 nMode, sal_Bool bSelect, |
| sal_uInt16 nCount, sal_Bool bBasicCall, sal_Bool bVisual ) |
| { |
| if ( !bSelect && !bBasicCall && IsCrsrReadonly() && !GetViewOptions()->IsSelectionInReadonly()) |
| { |
| Point aTmp( VisArea().Pos() ); |
| aTmp.X() -= VisArea().Width() * nReadOnlyScrollOfst / 100; |
| rView.SetVisArea( aTmp ); |
| return sal_True; |
| } |
| else |
| { |
| ShellMoveCrsr aTmp( this, bSelect ); |
| return SwCrsrShell::Left( nCount, nMode, bVisual ); |
| } |
| } |
| |
| |
| |
| sal_Bool SwWrtShell::Right( sal_uInt16 nMode, sal_Bool bSelect, |
| sal_uInt16 nCount, sal_Bool bBasicCall, sal_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 sal_True; |
| } |
| else |
| { |
| ShellMoveCrsr aTmp( this, bSelect ); |
| return SwCrsrShell::Right( nCount, nMode, bVisual ); |
| } |
| } |
| |
| |
| |
| sal_Bool SwWrtShell::Up( sal_Bool bSelect, sal_uInt16 nCount, sal_Bool bBasicCall ) |
| { |
| if ( !bSelect && !bBasicCall && IsCrsrReadonly() && !GetViewOptions()->IsSelectionInReadonly()) |
| { |
| Point aTmp( VisArea().Pos() ); |
| aTmp.Y() -= VisArea().Height() * nReadOnlyScrollOfst / 100; |
| rView.SetVisArea( aTmp ); |
| return sal_True; |
| } |
| else |
| { |
| ShellMoveCrsr aTmp( this, bSelect ); |
| return SwCrsrShell::Up( nCount ); |
| } |
| } |
| |
| |
| |
| sal_Bool SwWrtShell::Down( sal_Bool bSelect, sal_uInt16 nCount, sal_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 sal_True; |
| } |
| else |
| { |
| ShellMoveCrsr aTmp( this, bSelect ); |
| return SwCrsrShell::Down( nCount ); |
| } |
| } |
| |
| |
| |
| sal_Bool SwWrtShell::LeftMargin( sal_Bool bSelect, sal_Bool bBasicCall ) |
| { |
| if ( !bSelect && !bBasicCall && IsCrsrReadonly() ) |
| { |
| Point aTmp( VisArea().Pos() ); |
| aTmp.X() = DOCUMENTBORDER; |
| rView.SetVisArea( aTmp ); |
| return sal_True; |
| } |
| else |
| { |
| ShellMoveCrsr aTmp( this, bSelect ); |
| return SwCrsrShell::LeftMargin(); |
| } |
| } |
| |
| |
| |
| sal_Bool SwWrtShell::RightMargin( sal_Bool bSelect, sal_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 sal_True; |
| } |
| else |
| { |
| ShellMoveCrsr aTmp( this, bSelect ); |
| return SwCrsrShell::RightMargin(bBasicCall); |
| } |
| } |
| |
| |
| |
| sal_Bool SwWrtShell::GoStart( sal_Bool bKeepArea, sal_Bool *pMoveTable, |
| sal_Bool bSelect, sal_Bool bDontMoveRegion ) |
| { |
| if ( IsCrsrInTbl() ) |
| { |
| const sal_Bool bBoxSelection = HasBoxSelection(); |
| if( !bBlockMode ) |
| { |
| if ( !bSelect ) |
| EnterStdMode(); |
| else |
| SttSelect(); |
| } |
| // Tabellenzelle? |
| if ( !bBoxSelection && (MoveSection( fnSectionCurr, fnSectionStart) |
| || bDontMoveRegion)) |
| { |
| if ( pMoveTable ) |
| *pMoveTable = sal_False; |
| return sal_True; |
| } |
| if( MoveTable( fnTableCurr, fnTableStart ) || bDontMoveRegion ) |
| { |
| if ( pMoveTable ) |
| *pMoveTable = sal_True; |
| return sal_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 = sal_True; |
| return sal_True; |
| } |
| } |
| |
| if( !bBlockMode ) |
| { |
| if ( !bSelect ) |
| EnterStdMode(); |
| else |
| SttSelect(); |
| } |
| const sal_uInt16 nFrmType = GetFrmType(0,sal_False); |
| if ( FRMTYPE_FLY_ANY & nFrmType ) |
| { |
| if( MoveSection( fnSectionCurr, fnSectionStart ) ) |
| return sal_True; |
| else if ( FRMTYPE_FLY_FREE & nFrmType || bDontMoveRegion ) |
| return sal_False; |
| } |
| if(( FRMTYPE_HEADER | FRMTYPE_FOOTER | FRMTYPE_FOOTNOTE ) & nFrmType ) |
| { |
| if ( MoveSection( fnSectionCurr, fnSectionStart ) ) |
| return sal_True; |
| else if ( bKeepArea ) |
| return sal_True; |
| } |
| // Bereiche ??? |
| return SwCrsrShell::MoveRegion( fnRegionCurrAndSkip, fnRegionStart ) || |
| SwCrsrShell::SttEndDoc(sal_True); |
| } |
| |
| |
| |
| sal_Bool SwWrtShell::GoEnd(sal_Bool bKeepArea, sal_Bool *pMoveTable) |
| { |
| if ( pMoveTable && *pMoveTable ) |
| return MoveTable( fnTableCurr, fnTableEnd ); |
| |
| if ( IsCrsrInTbl() ) |
| { |
| if ( MoveSection( fnSectionCurr, fnSectionEnd ) || |
| MoveTable( fnTableCurr, fnTableEnd ) ) |
| return sal_True; |
| } |
| else |
| { |
| const sal_uInt16 nFrmType = GetFrmType(0,sal_False); |
| if ( FRMTYPE_FLY_ANY & nFrmType ) |
| { |
| if ( MoveSection( fnSectionCurr, fnSectionEnd ) ) |
| return sal_True; |
| else if ( FRMTYPE_FLY_FREE & nFrmType ) |
| return sal_False; |
| } |
| if(( FRMTYPE_HEADER | FRMTYPE_FOOTER | FRMTYPE_FOOTNOTE ) & nFrmType ) |
| { |
| if ( MoveSection( fnSectionCurr, fnSectionEnd) ) |
| return sal_True; |
| else if ( bKeepArea ) |
| return sal_True; |
| } |
| } |
| // Bereiche ??? |
| return SwCrsrShell::MoveRegion( fnRegionCurrAndSkip, fnRegionEnd ) || |
| SwCrsrShell::SttEndDoc(sal_False); |
| } |
| |
| |
| |
| sal_Bool SwWrtShell::SttDoc( sal_Bool bSelect ) |
| { |
| ShellMoveCrsr aTmp( this, bSelect ); |
| return GoStart(sal_False, 0, bSelect ); |
| } |
| |
| |
| |
| sal_Bool SwWrtShell::EndDoc( sal_Bool bSelect) |
| { |
| ShellMoveCrsr aTmp( this, bSelect ); |
| return GoEnd(); |
| } |
| |
| |
| sal_Bool SwWrtShell::SttNxtPg( sal_Bool bSelect ) |
| { |
| ShellMoveCrsr aTmp( this, bSelect ); |
| return MovePage( fnPageNext, fnPageStart ); |
| } |
| |
| |
| |
| sal_Bool SwWrtShell::SttPrvPg( sal_Bool bSelect ) |
| { |
| ShellMoveCrsr aTmp( this, bSelect ); |
| return MovePage( fnPagePrev, fnPageStart ); |
| } |
| |
| |
| |
| sal_Bool SwWrtShell::EndNxtPg( sal_Bool bSelect ) |
| { |
| ShellMoveCrsr aTmp( this, bSelect ); |
| return MovePage( fnPageNext, fnPageEnd ); |
| } |
| |
| |
| |
| sal_Bool SwWrtShell::EndPrvPg( sal_Bool bSelect ) |
| { |
| ShellMoveCrsr aTmp( this, bSelect ); |
| return MovePage( fnPagePrev, fnPageEnd ); |
| } |
| |
| |
| |
| sal_Bool SwWrtShell::SttPg( sal_Bool bSelect ) |
| { |
| ShellMoveCrsr aTmp( this, bSelect ); |
| return MovePage( fnPageCurr, fnPageStart ); |
| } |
| |
| |
| |
| sal_Bool SwWrtShell::EndPg( sal_Bool bSelect ) |
| { |
| ShellMoveCrsr aTmp( this, bSelect ); |
| return MovePage( fnPageCurr, fnPageEnd ); |
| } |
| |
| |
| |
| sal_Bool SwWrtShell::SttPara( sal_Bool bSelect ) |
| { |
| ShellMoveCrsr aTmp( this, bSelect ); |
| return MovePara( fnParaCurr, fnParaStart ); |
| } |
| |
| |
| |
| sal_Bool SwWrtShell::EndPara( sal_Bool bSelect ) |
| { |
| ShellMoveCrsr aTmp( this, bSelect ); |
| return MovePara(fnParaCurr,fnParaEnd); |
| } |
| |
| |
| /*------------------------------------------------------------------------ |
| Beschreibung: Spaltenweises Springen |
| Parameter: mit oder ohne SSelection |
| Return: Erfolg oder Misserfolg |
| ------------------------------------------------------------------------*/ |
| |
| |
| |
| sal_Bool SwWrtShell::StartOfColumn( sal_Bool bSelect ) |
| { |
| ShellMoveCrsr aTmp( this, bSelect); |
| return MoveColumn(fnColumnCurr, fnColumnStart); |
| } |
| |
| |
| |
| sal_Bool SwWrtShell::EndOfColumn( sal_Bool bSelect ) |
| { |
| ShellMoveCrsr aTmp( this, bSelect); |
| return MoveColumn(fnColumnCurr, fnColumnEnd); |
| } |
| |
| |
| |
| sal_Bool SwWrtShell::StartOfNextColumn( sal_Bool bSelect ) |
| { |
| ShellMoveCrsr aTmp( this, bSelect); |
| return MoveColumn( fnColumnNext, fnColumnStart); |
| } |
| |
| |
| |
| sal_Bool SwWrtShell::EndOfNextColumn( sal_Bool bSelect ) |
| { |
| ShellMoveCrsr aTmp( this, bSelect); |
| return MoveColumn(fnColumnNext, fnColumnEnd); |
| } |
| |
| |
| |
| sal_Bool SwWrtShell::StartOfPrevColumn( sal_Bool bSelect ) |
| { |
| ShellMoveCrsr aTmp( this, bSelect); |
| return MoveColumn(fnColumnPrev, fnColumnStart); |
| } |
| |
| |
| |
| sal_Bool SwWrtShell::EndOfPrevColumn( sal_Bool bSelect ) |
| { |
| ShellMoveCrsr aTmp( this, bSelect); |
| return MoveColumn(fnColumnPrev, fnColumnEnd); |
| } |
| |
| |
| |
| sal_Bool SwWrtShell::PushCrsr(SwTwips lOffset, sal_Bool bSelect) |
| { |
| sal_Bool bDiff = sal_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 = sal_True; |
| } |
| |
| //falls wir eine Rahmenselektion hatten, muss diese nach dem |
| //fnSetCrsr entfernt werden und damit wir da wieder hinkommen |
| //auf dem Stack gemerkt werden. |
| sal_Bool bIsFrmSel = sal_False; |
| |
| sal_Bool bIsObjSel = sal_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, sal_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 = sal_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; |
| } |
| |
| |
| |
| sal_Bool SwWrtShell::PopCrsr(sal_Bool bUpdate, sal_Bool bSelect) |
| { |
| if( 0 == pCrsrStack) |
| return sal_False; |
| |
| const sal_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 sal_False; |
| } |
| } |
| CrsrStack *pTmp = pCrsrStack; |
| pCrsrStack = pCrsrStack->pNext; |
| delete pTmp; |
| if( 0 == pCrsrStack ) |
| { |
| ePageMove = MV_NO; |
| bDestOnStack = sal_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 = sal_False; |
| } |
| /************** |
| |
| falls kein Stack existiert --> Selektionen aufheben |
| falls Stack && Richtungswechsel |
| --> Cursor poppen und return |
| sonst |
| --> Cursor pushen |
| Cursor umsetzen |
| |
| ***************/ |
| |
| |
| |
| sal_Bool SwWrtShell::PageCrsr(SwTwips lOffset, sal_Bool bSelect) |
| { |
| // nichts tun, wenn ein Offset von 0 angegeben wurde |
| if(!lOffset) return sal_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( sal_True, bSelect )) |
| return sal_True; |
| |
| const sal_Bool bRet = PushCrsr(lOffset, bSelect); |
| ePageMove = eDir; |
| return bRet; |
| } |
| |
| |
| |
| sal_Bool SwWrtShell::GotoPage(sal_uInt16 nPage, sal_Bool bRecord) |
| { |
| ShellMoveCrsr aTmp( this, sal_False); |
| if( SwCrsrShell::GotoPage(nPage) && bRecord) |
| { |
| if(IsSelFrmMode()) |
| { |
| UnSelectFrm(); |
| LeaveSelFrmMode(); |
| } |
| return sal_True; |
| } |
| return sal_False; |
| } |
| |
| |
| |
| sal_Bool SwWrtShell::GotoMark( const ::sw::mark::IMark* const pMark, sal_Bool bSelect, sal_Bool bStart ) |
| { |
| ShellMoveCrsr aTmp( this, bSelect ); |
| return SwCrsrShell::GotoMark( pMark, bStart ); |
| } |
| |
| |
| |
| sal_Bool SwWrtShell::SelectTxtAttr( sal_uInt16 nWhich, const SwTxtAttr* pAttr ) |
| { |
| sal_Bool bRet; |
| { |
| MV_KONTEXT(this); |
| SttSelect(); |
| bRet = SwCrsrShell::SelectTxtAttr( nWhich, sal_False, pAttr ); |
| } |
| EndSelect(); |
| return bRet; |
| } |
| |
| |
| |