summaryrefslogtreecommitdiff
path: root/binfilter/bf_sw/source/core/crsr/sw_crsrsh.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'binfilter/bf_sw/source/core/crsr/sw_crsrsh.cxx')
-rw-r--r--binfilter/bf_sw/source/core/crsr/sw_crsrsh.cxx960
1 files changed, 960 insertions, 0 deletions
diff --git a/binfilter/bf_sw/source/core/crsr/sw_crsrsh.cxx b/binfilter/bf_sw/source/core/crsr/sw_crsrsh.cxx
new file mode 100644
index 000000000000..fd12f53b377e
--- /dev/null
+++ b/binfilter/bf_sw/source/core/crsr/sw_crsrsh.cxx
@@ -0,0 +1,960 @@
+/* -*- 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>
+
+
+#ifdef BIDI
+#include <bf_svx/frmdiritem.hxx>
+#endif
+
+#include <horiornt.hxx>
+
+#include <doc.hxx>
+#include <rootfrm.hxx>
+#include <pagefrm.hxx>
+#include <viewimp.hxx>
+#include <flyfrm.hxx>
+#include <dview.hxx>
+#include <viewopt.hxx>
+#include <crsrsh.hxx>
+#include <txtfrm.hxx>
+#include <callnk.hxx>
+#include <viscrs.hxx>
+#include <section.hxx>
+#include <globdoc.hxx>
+#include <fmteiro.hxx>
+namespace binfilter {
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::util;
+
+/*N*/ TYPEINIT2(SwCrsrShell,ViewShell,SwModify);
+
+
+// Funktion loescht, alle ueberlappenden Cursor aus einem Cursor-Ring
+/*N*/ void CheckRange( SwCursor* );
+
+//-----------------------------------------------------------------------
+
+/*
+ * Ueberpruefe ob der pCurCrsr in einen schon bestehenden Bereich zeigt.
+ * Wenn ja, dann hebe den alten Bereich auf.
+ */
+
+
+/*N*/ void CheckRange( SwCursor* pCurCrsr )
+/*N*/ {
+/*N*/ const SwPosition *pStt = pCurCrsr->Start(),
+/*N*/ *pEnd = pCurCrsr->GetPoint() == pStt ? pCurCrsr->GetMark() : pCurCrsr->GetPoint();
+/*N*/
+/*N*/ SwPaM *pTmpDel = 0,
+/*N*/ *pTmp = (SwPaM*)pCurCrsr->GetNext();
+/*N*/
+/*N*/ // durchsuche den gesamten Ring
+/*N*/ while( pTmp != pCurCrsr )
+/*N*/ {
+/*?*/ const SwPosition *pTmpStt = pTmp->Start(),
+/*?*/ *pTmpEnd = pTmp->GetPoint() == pTmpStt ?
+/*?*/ pTmp->GetMark() : pTmp->GetPoint();
+/*?*/ if( *pStt <= *pTmpStt )
+/*?*/ {
+/*?*/ if( *pEnd > *pTmpStt ||
+/*?*/ ( *pEnd == *pTmpStt && *pEnd == *pTmpEnd ))
+/*?*/ pTmpDel = pTmp;
+/*?*/ }
+/*?*/ else
+/*?*/ if( *pStt < *pTmpEnd )
+/*?*/ pTmpDel = pTmp;
+ /*
+ * liegt ein SPoint oder GetMark innerhalb vom Crsr-Bereich
+ * muss der alte Bereich aufgehoben werden.
+ * Beim Vergleich ist darauf zu achten, das SPoint nicht mehr zum
+ * Bereich gehoert !
+ */
+/*?*/ pTmp = (SwPaM*)pTmp->GetNext();
+/*?*/ if( pTmpDel )
+/*?*/ {
+/*?*/ delete pTmpDel; // hebe alten Bereich auf
+/*?*/ pTmpDel = 0;
+/*?*/ }
+/*N*/ }
+/*N*/ }
+
+// -------------- Methoden von der SwCrsrShell -------------
+
+
+// gebe den aktuellen zurueck
+
+/*N*/ SwPaM* SwCrsrShell::GetCrsr( FASTBOOL bMakeTblCrsr ) const
+/*N*/ {
+/*N*/ if( pTblCrsr )
+/*N*/ {
+DBG_BF_ASSERT(0, "STRIP"); //STRIP001 /*?*/ if( bMakeTblCrsr && pTblCrsr->IsCrsrMovedUpdt() )
+/*N*/ }
+/*N*/ return pCurCrsr;
+/*N*/ }
+
+
+/*N*/ void SwCrsrShell::StartAction()
+/*N*/ {
+/*N*/ if( !ActionPend() )
+/*N*/ {
+/*N*/ // fuer das Update des Ribbon-Bars merken
+/*N*/ const SwNode& rNd = pCurCrsr->GetPoint()->nNode.GetNode();
+/*N*/ nAktNode = rNd.GetIndex();
+/*N*/ nAktCntnt = pCurCrsr->GetPoint()->nContent.GetIndex();
+/*N*/ nAktNdTyp = rNd.GetNodeType();
+/*N*/ bAktSelection = *pCurCrsr->GetPoint() != *pCurCrsr->GetMark();
+/*N*/ if( ND_TEXTNODE & nAktNdTyp )
+/*N*/ nLeftFrmPos = SwCallLink::GetFrm( (SwTxtNode&)rNd, nAktCntnt, TRUE );
+/*N*/ else
+/*?*/ nLeftFrmPos = 0;
+/*N*/ }
+/*N*/ ViewShell::StartAction(); // zur ViewShell
+/*N*/ }
+
+
+/*N*/ void SwCrsrShell::EndAction( const BOOL bIdleEnd )
+/*N*/ {
+/*
+//OS: Wird z.B. eine Basic-Action im Hintergrund ausgefuehrt, geht es so nicht
+ if( !bHasFocus )
+ {
+ // hat die Shell nicht den Focus, dann nur das EndAction an
+ // die ViewShell weitergeben.
+ ViewShell::EndAction( bIdleEnd );
+ return;
+ }
+*/
+
+/*N*/ FASTBOOL bVis = bSVCrsrVis;
+
+ // Idle-Formatierung ?
+/*N*/ if( bIdleEnd && Imp()->GetRegion() )
+/*N*/ {
+/*?*/ pCurCrsr->Hide();
+
+/*?*/ #ifdef SHOW_IDLE_REGION
+/*?*/ if( GetWin() )
+/*?*/ {
+/*?*/ GetWin()->Push();
+/*?*/ GetWin()->ChangePen( Pen( Color( COL_YELLOW )));
+/*?*/ for( USHORT n = 0; n < aPntReg.Count(); ++n )
+/*?*/ {
+/*?*/ SwRect aIRect( aPntReg[n] );
+/*?*/ GetWin()->DrawRect( aIRect.SVRect() );
+/*?*/ }
+/*?*/ GetWin()->Pop();
+/*?*/ }
+/*?*/ #endif
+
+/*N*/ }
+
+ // vor der letzten Action alle invaliden Numerierungen updaten
+/*N*/ if( 1 == nStartAction )
+/*N*/ GetDoc()->UpdateNumRule();
+/*N*/
+/*N*/ // Task: 76923: dont show the cursor in the ViewShell::EndAction() - call.
+/*N*/ // Only the UpdateCrsr shows the cursor.
+/*N*/ BOOL bSavSVCrsrVis = bSVCrsrVis;
+/*N*/ bSVCrsrVis = FALSE;
+/*N*/
+/*N*/ ViewShell::EndAction( bIdleEnd ); //der ViewShell den Vortritt lassen
+/*N*/
+/*N*/ bSVCrsrVis = bSavSVCrsrVis;
+/*N*/
+/*N*/ if( ActionPend() )
+/*N*/ {
+/*N*/ if( bVis ) // auch SV-Cursor wieder anzeigen
+/*N*/ pVisCrsr->Show();
+/*N*/
+/*N*/ // falls noch ein ChgCall vorhanden ist und nur noch die Basic
+/*N*/ // Klammerung vorhanden ist, dann rufe ihn. Dadurch wird die interne
+/*N*/ // mit der Basic-Klammerung entkoppelt; die Shells werden umgeschaltet
+/*N*/ if( !BasicActionPend() )
+/*N*/ {
+/*?*/ //JP 12.01.98: Bug #46496# - es muss innerhalb einer BasicAction
+/*?*/ // der Cursor geupdatet werden; um z.B. den
+/*?*/ // TabellenCursor zu erzeugen. Im UpdateCrsr wird
+/*?*/ // das jetzt beruecksichtigt!
+DBG_BF_ASSERT(0, "STRIP"); //STRIP001 /*?*/ UpdateCrsr( SwCrsrShell::CHKRANGE, bIdleEnd );
+/*N*/ }
+/*N*/ return;
+/*N*/ }
+
+/*N*/ USHORT nParm = SwCrsrShell::CHKRANGE;
+/*N*/ if ( !bIdleEnd )
+/*N*/ nParm |= SwCrsrShell::SCROLLWIN;
+/*N*/ UpdateCrsr( nParm, bIdleEnd ); // Cursor-Aenderungen anzeigen
+/*N*/
+/*N*/ {
+/*N*/ SwCallLink aLk( *this ); // Crsr-Moves ueberwachen,
+/*N*/ aLk.nNode = nAktNode; // evt. Link callen
+/*N*/ aLk.nNdTyp = (BYTE)nAktNdTyp;
+/*N*/ aLk.nCntnt = nAktCntnt;
+/*N*/ aLk.nLeftFrmPos = nLeftFrmPos;
+/*N*/
+/*N*/ if( !nCrsrMove ||
+/*N*/ ( 1 == nCrsrMove && bInCMvVisportChgd ) )
+/*N*/ ShowCrsrs( bSVCrsrVis ? TRUE : FALSE ); // Cursor & Selektionen wieder anzeigen
+/*N*/ }
+/*N*/ // falls noch ein ChgCall vorhanden ist, dann rufe ihn
+/*N*/ if( bCallChgLnk && bChgCallFlag && aChgLnk.IsSet() )
+/*N*/ {
+/*N*/ aChgLnk.Call( this );
+/*N*/ bChgCallFlag = FALSE; // Flag zuruecksetzen
+/*N*/ }
+/*N*/ }
+
+
+/*?*/ #if defined(DBG_UTIL)
+/*?*/
+/*?*/ void SwCrsrShell::SttCrsrMove()
+/*?*/ {
+/*?*/ ASSERT( nCrsrMove < USHRT_MAX, "To many nested CrsrMoves." );
+/*?*/ ++nCrsrMove;
+/*?*/ StartAction();
+/*?*/ }
+/*?*/
+/*?*/ void SwCrsrShell::EndCrsrMove( const BOOL bIdleEnd )
+/*?*/ {
+/*?*/ ASSERT( nCrsrMove, "EndCrsrMove() ohne SttCrsrMove()." );
+/*?*/ EndAction( bIdleEnd );
+/*?*/ if( !--nCrsrMove )
+/*?*/ bInCMvVisportChgd = FALSE;
+/*?*/ }
+/*?*/
+/*?*/ #endif
+
+
+/*N*/ void SwCrsrShell::UpdateCrsrPos()
+/*N*/ {
+/*N*/ SET_CURR_SHELL( this );
+/*N*/ ++nStartAction;
+/*N*/ Size aOldSz( GetLayout()->Frm().SSize() );
+/*N*/ SwCntntNode *pCNode = pCurCrsr->GetCntntNode();
+/*N*/ SwCntntFrm *pFrm = pCNode ?
+/*N*/ pCNode->GetFrm( &pCurCrsr->GetPtPos(), pCurCrsr->GetPoint() ) :0;
+/*N*/ if( !pFrm || (pFrm->IsTxtFrm() && ((SwTxtFrm*)pFrm)->IsHiddenNow()) )
+/*N*/ {
+/*?*/ SwCrsrMoveState aTmpState( MV_NONE );
+/*?*/ aTmpState.bSetInReadOnly = IsReadOnlyAvailable();
+/*?*/ GetLayout()->GetCrsrOfst( pCurCrsr->GetPoint(), pCurCrsr->GetPtPos(),
+/*?*/ &aTmpState );
+/*?*/ if( pCurCrsr->HasMark())
+/*?*/ pCurCrsr->DeleteMark();
+/*N*/ }
+/*N*/ --nStartAction;
+/*N*/ if( aOldSz != GetLayout()->Frm().SSize() )
+/*N*/ SizeChgNotify( GetLayout()->Frm().SSize() );
+/*N*/ }
+
+
+
+// JP 30.04.99: Bug 65475 - falls Point/Mark in versteckten Bereichen
+// stehen, so mussen diese daraus verschoben werden
+
+/*M*/ void SwCrsrShell::UpdateCrsr( USHORT eFlags, BOOL bIdleEnd )
+/*M*/ {
+/*M*/ SET_CURR_SHELL( this );
+/*M*/
+/*N*/ ClearUpCrsrs();
+/*M*/
+/*M*/ // erfrage den Count fuer die Start-/End-Actions und ob die Shell
+/*M*/ // ueberhaupt den Focus hat
+/*M*/ // if( ActionPend() /*|| !bHasFocus*/ )
+/*M*/ //JP 12.01.98: Bug #46496# - es muss innerhalb einer BasicAction der
+/*M*/ // Cursor geupdatet werden; um z.B. den TabellenCursor zu
+/*M*/ // erzeugen. Im EndAction wird jetzt das UpdateCrsr gerufen!
+/*M*/ if( ActionPend() && BasicActionPend() )
+/*M*/ {
+/*M*/ if ( eFlags & SwCrsrShell::READONLY )
+/*M*/ bIgnoreReadonly = TRUE;
+/*M*/ return; // wenn nicht, dann kein Update !!
+/*M*/ }
+/*M*/
+/*M*/ if ( bIgnoreReadonly )
+/*M*/ {
+/*M*/ bIgnoreReadonly = FALSE;
+/*M*/ eFlags |= SwCrsrShell::READONLY;
+/*M*/ }
+/*M*/
+/*M*/ if( eFlags & SwCrsrShell::CHKRANGE ) // alle Cursor-Bewegungen auf
+/*M*/ CheckRange( pCurCrsr ); // ueberlappende Bereiche testen
+/*M*/
+/*M*/ if( !bIdleEnd )
+/*M*/ CheckTblBoxCntnt();
+/*M*/
+/*M*/ // steht der akt. Crsr in einer Tabelle und in unterschiedlichen Boxen
+/*M*/ // (oder ist noch TabellenMode), dann gilt der Tabellen Mode
+/*M*/ SwPaM* pTstCrsr = pTblCrsr ? pTblCrsr : pCurCrsr;
+/*M*/ if( ( pTstCrsr->HasMark() &&
+/*M*/ pDoc->IsIdxInTbl( pTstCrsr->GetPoint()->nNode ) &&
+/*M*/ ( pTblCrsr ||
+/*M*/ pTstCrsr->GetNode( TRUE )->FindStartNode() !=
+/*M*/ pTstCrsr->GetNode( FALSE )->FindStartNode() ))
+/*M*/ /*|| ( !pTblCrsr && lcl_IsInValueBox( *pTstCrsr, *this ) )*/ )
+/*M*/ {DBG_BF_ASSERT(0, "STRIP"); //STRIP001
+/*M*/ }
+/*M*/
+/*M*/ if( pTblCrsr )
+/*M*/ {
+/*M*/ // Cursor Ring loeschen
+/*M*/ while( pCurCrsr->GetNext() != pCurCrsr )
+/*M*/ delete pCurCrsr->GetNext();
+/*M*/ pCurCrsr->DeleteMark();
+/*M*/ *pCurCrsr->GetPoint() = *pTblCrsr->GetPoint();
+/*M*/ pCurCrsr->GetPtPos() = pTblCrsr->GetPtPos();
+/*M*/ delete pTblCrsr, pTblCrsr = 0;
+/*M*/ }
+/*M*/
+/*M*/ pVisCrsr->Hide(); // sichtbaren Cursor immer verstecken
+/*M*/
+/*M*/ // sind wir vielleicht in einer geschuetzten/versteckten Section ?
+/*M*/ {
+/*M*/ BOOL bChgState = TRUE;
+/*M*/ const SwSectionNode* pSectNd = pCurCrsr->GetNode()->FindSectionNode();
+/*M*/ if( pSectNd && ( pSectNd->GetSection().IsHiddenFlag() ||
+/*M*/ ( !IsReadOnlyAvailable() &&
+/*M*/ pSectNd->GetSection().IsProtectFlag() &&
+/*M*/ ( !pDoc->GetDocShell() ||
+/*M*/ !pDoc->GetDocShell()->IsReadOnly() || bAllProtect )) ) )
+/*M*/ {DBG_BF_ASSERT(0, "STRIP"); //STRIP001
+/*M*/ }
+/*M*/ if( bChgState )
+/*M*/ {
+/*M*/ BOOL bWasAllProtect = bAllProtect;
+/*M*/ bAllProtect = FALSE;
+/*M*/ if( bWasAllProtect && GetDoc()->GetDocShell() &&
+/*M*/ GetDoc()->GetDocShell()->IsReadOnlyUI() )
+/*M*/ {DBG_BF_ASSERT(0, "STRIP"); //STRIP001
+/*M*/ }
+/*M*/ }
+/*M*/ }
+/*M*/
+/*M*/ UpdateCrsrPos();
+/*M*/
+/*M*/
+/*M*/ // #100722# The cursor must always point into content; there's some code
+/*M*/ // that relies on this. (E.g. in SwEditShell::GetScriptType, which always
+/*M*/ // loops _behind_ the last node in the selection, which always works if you
+/*M*/ // are in content.) To achieve this, we'll force cursor(s) to point into
+/*M*/ // content, if UpdateCrsrPos() hasn't already done so.
+/*M*/ SwPaM* pCmp = pCurCrsr;
+/*M*/ do
+/*M*/ {
+/*M*/ // start will move forwards, end will move backwards
+/*M*/ bool bPointIsStart = ( pCmp->Start() == pCmp->GetPoint() );
+/*M*/
+/*M*/ // move point; forward if it's the start, backwards if it's the end
+/*M*/ if( ! pCmp->GetPoint()->nNode.GetNode().IsCntntNode() )
+/*M*/ pCmp->Move( bPointIsStart ? fnMoveForward : fnMoveBackward,
+/*M*/ fnGoCntnt );
+/*M*/
+/*M*/ // move mark (if exists); forward if it's the start, else backwards
+/*M*/ if( pCmp->HasMark() )
+/*M*/ {
+/*M*/ if( ! pCmp->GetMark()->nNode.GetNode().IsCntntNode() )
+/*M*/ {
+/*M*/ pCmp->Exchange();
+/*M*/ pCmp->Move( !bPointIsStart ? fnMoveForward : fnMoveBackward,
+/*M*/ fnGoCntnt );
+/*M*/ pCmp->Exchange();
+/*M*/ }
+/*M*/ }
+/*M*/
+/*M*/ // iterate to next PaM in ring
+/*M*/ pCmp = static_cast<SwPaM*>( pCmp->GetNext() );
+/*M*/ }
+/*M*/ while( pCmp != pCurCrsr );
+/*M*/
+/*M*/
+/*M*/ SwRect aOld( aCharRect );
+/*M*/ FASTBOOL bFirst = TRUE;
+/*M*/ SwCntntFrm *pFrm;
+/*M*/ int nLoopCnt = 100;
+/*M*/
+/*M*/ do {
+/*M*/ BOOL bAgainst;
+/*M*/ do {
+/*M*/ bAgainst = FALSE;
+/*M*/ pFrm = pCurCrsr->GetCntntNode()->GetFrm(
+/*M*/ &pCurCrsr->GetPtPos(), pCurCrsr->GetPoint() );
+/*M*/ // ist der Frm nicht mehr vorhanden, dann muss das gesamte Layout
+/*M*/ // erzeugt werden, weil ja mal hier einer vorhanden war !!
+/*M*/ if ( !pFrm )
+/*M*/ {
+/*M*/ do
+/*M*/ {
+/*M*/ CalcLayout();
+/*M*/ pFrm = pCurCrsr->GetCntntNode()->GetFrm(
+/*M*/ &pCurCrsr->GetPtPos(), pCurCrsr->GetPoint() );
+/*M*/ } while( !pFrm );
+/*M*/ }
+/*M*/ else if ( Imp()->IsIdleAction() )
+/*M*/ //Wir stellen sicher, dass anstaendig Formatiert wurde #42224#
+/*?*/ {DBG_BF_ASSERT(0, "STRIP"); }//STRIP001 pFrm->PrepareCrsr();
+/*M*/
+/*M*/ // im geschuetzten Fly? aber bei Rahmenselektion ignorieren
+/*M*/ if( !IsReadOnlyAvailable() && pFrm->IsProtected() &&
+/*M*/ ( !Imp()->GetDrawView() ||
+/*M*/ !Imp()->GetDrawView()->GetMarkList().GetMarkCount() ) &&
+/*M*/ (!pDoc->GetDocShell() ||
+/*M*/ !pDoc->GetDocShell()->IsReadOnly() || bAllProtect ) )
+/*M*/ {DBG_BF_ASSERT(0, "STRIP"); //STRIP001
+/*M*/ }
+/*M*/ } while( bAgainst );
+/*M*/
+/*M*/ if( !( eFlags & SwCrsrShell::NOCALRECT ))
+/*M*/ {
+/*M*/ SwCrsrMoveState aTmpState( eMvState );
+/*M*/ aTmpState.bSetInReadOnly = IsReadOnlyAvailable();
+/*M*/ aTmpState.bRealHeight = TRUE;
+/*M*/ aTmpState.bRealWidth = IsOverwriteCrsr();
+/*N*/ aTmpState.nCursorBidiLevel = pCurCrsr->GetCrsrBidiLevel();
+/*M*/ if( !pFrm->GetCharRect( aCharRect, *pCurCrsr->GetPoint(), &aTmpState ) )
+/*M*/ {
+/*N*/ Point& rPt = pCurCrsr->GetPtPos();
+/*N*/ rPt = aCharRect.Center();
+/*N*/ pFrm->GetCrsrOfst( pCurCrsr->GetPoint(), rPt, &aTmpState );
+/*N*/ #ifndef VERTICAL_LAYOUT
+/*N*/ if ( !pFrm->GetCharRect(aCharRect, *pCurCrsr->GetPoint(), &aTmpState) )
+/*N*/ ASSERT( !this, "GetCharRect failed." );
+/*N*/ #endif
+/*M*/ }
+/*M*/ // ALIGNRECT( aCharRect );
+/*M*/
+/*M*/ if( !pCurCrsr->HasMark() )
+/*M*/ aCrsrHeight = aTmpState.aRealHeight;
+/*M*/ else
+/*M*/ {
+/*M*/ aCrsrHeight.X() = 0;
+/*M*/ aCrsrHeight.Y() = aTmpState.aRealHeight.Y() < 0 ?
+/*M*/ -aCharRect.Width() : aCharRect.Height();
+/*M*/ }
+/*M*/ }
+/*M*/ else
+/*M*/ {
+/*M*/ aCrsrHeight.X() = 0;
+/*M*/ aCrsrHeight.Y() = aCharRect.Height();
+/*M*/ }
+/*M*/
+/*M*/ if( !bFirst && aOld == aCharRect )
+/*M*/ break;
+/*M*/
+/*M*/ // falls das Layout meint, nach dem 100 durchlauf ist man immer noch
+/*M*/ // im Fluss, sollte man die akt. Pos. als gegeben hinnehmen!
+/*M*/ // siehe Bug: 29658
+/*M*/ if( !--nLoopCnt )
+/*M*/ {
+/*M*/ ASSERT( !this, "Endlosschleife? CharRect != OldCharRect ");
+/*M*/ break;
+/*M*/ }
+/*M*/ aOld = aCharRect;
+/*M*/ bFirst = FALSE;
+/*M*/
+/*M*/ // Cursor-Points auf die neuen Positionen setzen
+/*M*/ pCurCrsr->GetPtPos().X() = aCharRect.Left();
+/*M*/ pCurCrsr->GetPtPos().Y() = aCharRect.Top();
+/*M*/
+/*M*/ if( !(eFlags & SwCrsrShell::UPDOWN )) // alte Pos. von Up/Down loeschen
+/*M*/ {
+/*M*/ pFrm->Calc();
+/*M*/ #ifdef VERTICAL_LAYOUT
+/*M*/ nUpDownX = pFrm->IsVertical() ?
+/*M*/ aCharRect.Top() - pFrm->Frm().Top() :
+/*M*/ aCharRect.Left() - pFrm->Frm().Left();
+/*M*/ #else
+/*M*/ nUpDownX = aCharRect.Left() - pFrm->Frm().Left();
+/*M*/ #endif
+/*M*/ }
+/*M*/
+/*M*/ // Curosr in den sichtbaren Bereich scrollen
+/*M*/ if( bHasFocus && eFlags & SwCrsrShell::SCROLLWIN &&
+/*M*/ (HasSelection() || eFlags & SwCrsrShell::READONLY ||
+/*M*/ !IsCrsrReadonly() || GetViewOptions()->IsSelectionInReadonly()) )
+/*M*/ {
+/*M*/ //JP 30.04.99: damit das EndAction, beim evtuellen Scrollen, den
+/*M*/ // SV-Crsr nicht wieder sichtbar macht, wird hier das Flag
+/*M*/ // gesichert und zurueckgesetzt.
+/*M*/ BOOL bSav = bSVCrsrVis; bSVCrsrVis = FALSE;
+/*M*/ MakeSelVisible();
+/*M*/ bSVCrsrVis = bSav;
+/*M*/ }
+/*M*/
+/*M*/ } while( eFlags & SwCrsrShell::SCROLLWIN );
+/*M*/
+/*M*/ if( !bIdleEnd && bHasFocus && !bBasicHideCrsr )
+/*M*/ pCurCrsr->SwSelPaintRects::Show();
+/*M*/
+/*M*/ //Ggf. gescrollten Bereicht korrigieren (Alignment).
+/*M*/ //Nur wenn gescrollt wurde, und wenn keine Selektion existiert.
+/*M*/ if( pFrm && Imp()->IsScrolled() &&
+/*M*/ pCurCrsr->GetNext() == pCurCrsr && !pCurCrsr->HasMark() )
+/*?*/ {DBG_BF_ASSERT(0, "STRIP"); }//STRIP001 Imp()->RefreshScrolledArea( aCharRect );
+/*M*/
+/*M*/
+/*M*/ eMvState = MV_NONE; // Status fuers Crsr-Travelling - GetCrsrOfst
+/*M*/
+/*M*/ #ifdef ACCESSIBLE_LAYOUT
+/*M*/ #endif
+/*M*/
+/*M*/ #ifndef REMOTE_APPSERVER
+/*M*/
+/*M*/ // switch from blinking cursor to read-only-text-selection cursor
+/*M*/ long nBlinkTime = GetOut()->GetSettings().GetStyleSettings().
+/*M*/ GetCursorBlinkTime();
+/*M*/
+/*M*/ if ( (IsCrsrReadonly() && GetViewOptions()->IsSelectionInReadonly()) ==
+/*M*/ ( nBlinkTime != STYLE_CURSOR_NOBLINKTIME ) )
+/*M*/ {
+/*M*/ // non blinking cursor in read only - text selection mode
+/*M*/ AllSettings aSettings = GetOut()->GetSettings();
+/*M*/ StyleSettings aStyleSettings = aSettings.GetStyleSettings();
+/*M*/ long nNewBlinkTime = nBlinkTime == STYLE_CURSOR_NOBLINKTIME ?
+/*M*/ 500 :
+/*M*/ STYLE_CURSOR_NOBLINKTIME;
+/*M*/ aStyleSettings.SetCursorBlinkTime( nNewBlinkTime );
+/*M*/ aSettings.SetStyleSettings( aStyleSettings );
+/*M*/ GetOut()->SetSettings( aSettings );
+/*M*/ }
+/*M*/
+/*M*/ #endif
+/*M*/
+/*M*/ if( bSVCrsrVis )
+/*M*/ pVisCrsr->Show(); // wieder anzeigen
+/*M*/ }
+
+
+
+// erzeuge eine Kopie vom Cursor und speicher diese im Stack
+
+
+
+/*
+ * Loescht einen Cursor (gesteuert durch bOldCrsr)
+ * - vom Stack oder ( bOldCrsr = TRUE )
+ * - den aktuellen und der auf dem Stack stehende wird zum aktuellen
+ *
+ * Return: es war auf dem Stack noch einer vorhanden
+ */
+
+
+
+/*
+ * Verbinde zwei Cursor miteinander.
+ * Loesche vom Stack den obersten und setzen dessen GetMark im Aktuellen.
+ */
+
+
+
+
+
+
+
+/*N*/ void SwCrsrShell::ShowCrsrs( BOOL bCrsrVis )
+/*N*/ {
+/*N*/ if( !bHasFocus || bAllProtect || bBasicHideCrsr )
+/*?*/ return;
+
+/*N*/ SET_CURR_SHELL( this );
+/*N*/ SwShellCrsr* pAktCrsr = pTblCrsr ? pTblCrsr : pCurCrsr;
+/*N*/ pAktCrsr->Show();
+/*N*/
+/*N*/ if( bSVCrsrVis && bCrsrVis ) // auch SV-Cursor wieder anzeigen
+/*N*/ pVisCrsr->Show();
+/*N*/ }
+
+
+/*N*/ SwCntntFrm *SwCrsrShell::GetCurrFrm( const BOOL bCalcFrm ) const
+/*N*/ {
+/*N*/ SET_CURR_SHELL( (ViewShell*)this );
+/*N*/ SwCntntFrm *pRet = 0;
+/*N*/ SwCntntNode *pNd = pCurCrsr->GetCntntNode();
+/*N*/ if ( pNd )
+/*N*/ {
+/*N*/ if ( bCalcFrm )
+/*N*/ {
+/*N*/ const USHORT* pST = &nStartAction;
+/*N*/ ++(*((USHORT*)pST));
+/*N*/ const Size aOldSz( GetLayout()->Frm().SSize() );
+/*N*/ pRet = pNd->GetFrm( &pCurCrsr->GetPtPos(), pCurCrsr->GetPoint() );
+/*N*/ --(*((USHORT*)pST));
+/*N*/ if( aOldSz != GetLayout()->Frm().SSize() )
+/*N*/ ((SwCrsrShell*)this)->SizeChgNotify( GetLayout()->Frm().SSize() );
+/*N*/ }
+/*N*/ else
+/*N*/ pRet = pNd->GetFrm( &pCurCrsr->GetPtPos(), pCurCrsr->GetPoint(), FALSE);
+/*N*/ }
+/*N*/ return pRet;
+/*N*/ }
+
+
+// alle Attribut/Format-Aenderungen am akt. Node werden an den
+// Link weitergeleitet.
+
+
+/*N*/ void SwCrsrShell::Modify( SfxPoolItem* pOld, SfxPoolItem* pNew )
+/*N*/ {
+/*N*/ USHORT nWhich = pOld ? pOld->Which()
+/*N*/ : pNew ? pNew->Which()
+/*N*/ : RES_MSG_BEGIN;
+/*N*/ if( bCallChgLnk &&
+/*N*/ ( nWhich < RES_MSG_BEGIN || nWhich >= RES_MSG_END ||
+/*N*/ nWhich == RES_FMT_CHG || nWhich == RES_UPDATE_ATTR ||
+/*N*/ nWhich == RES_ATTRSET_CHG ))
+/*N*/ // die Messages werden nicht weitergemeldet
+/*N*/ //MA 07. Apr. 94 fix(6681): RES_UPDATE_ATTR wird implizit vom
+/*N*/ //SwTxtNode::Insert(SwTxtHint*, USHORT) abgesetzt; hier wird reagiert und
+/*N*/ //vom Insert brauch nicht mehr die Keule RES_FMT_CHG versandt werden.
+/*N*/ CallChgLnk();
+/*N*/
+/*N*/ if( aGrfArrivedLnk.IsSet() &&
+/*N*/ ( RES_GRAPHIC_ARRIVED == nWhich || RES_GRAPHIC_SWAPIN == nWhich ))
+/*?*/ aGrfArrivedLnk.Call( this );
+/*N*/ }
+
+
+// Abfrage, ob der aktuelle Cursor eine Selektion aufspannt,
+// also, ob GetMark gesetzt und SPoint und GetMark unterschiedlich sind.
+
+
+/*N*/ FASTBOOL SwCrsrShell::HasSelection() const
+/*N*/ {
+/*N*/ SwPaM* pCrsr = IsTableMode() ? pTblCrsr : pCurCrsr;
+/*N*/ return( IsTableMode() || ( pCurCrsr->HasMark() &&
+/*N*/ *pCurCrsr->GetPoint() != *pCrsr->GetMark())
+/*N*/ ? TRUE : FALSE );
+/*N*/ }
+
+
+/*N*/ void SwCrsrShell::CallChgLnk()
+/*N*/ {
+/*N*/ // innerhalb von Start-/End-Action kein Call, sondern nur merken,
+/*N*/ // das sich etwas geaendert hat. Wird bei EndAction beachtet.
+/*N*/ if( BasicActionPend() )
+/*N*/ bChgCallFlag = TRUE; // das Change merken
+/*N*/ else if( aChgLnk.IsSet() )
+/*N*/ {
+/*N*/ if( bCallChgLnk )
+/*N*/ aChgLnk.Call( this );
+/*N*/ bChgCallFlag = FALSE; // Flag zuruecksetzen
+/*N*/ }
+/*N*/ }
+
+// loesche alle erzeugten Crsr, setze den Tabellen-Crsr und den letzten
+// Cursor auf seinen TextNode (oder StartNode?).
+// Beim naechsten ::GetCrsr werden sie wieder alle erzeugt
+// Wird fuers Drag&Drop / ClipBorad-Paste in Tabellen benoetigt.
+
+/*N*/ SwCrsrShell::~SwCrsrShell()
+/*N*/ {
+/*N*/ // wenn es nicht die letzte View so sollte zu mindest das
+/*N*/ // Feld noch geupdatet werden.
+/*N*/ if( GetNext() != this )
+/*?*/ CheckTblBoxCntnt( pCurCrsr->GetPoint() );
+/*N*/ else
+/*N*/ ClearTblBoxCntnt();
+/*N*/
+/*N*/ delete pVisCrsr;
+/*N*/ delete pTblCrsr;
+/*N*/
+ /*
+ * Freigabe der Cursor
+ */
+/*N*/ while(pCurCrsr->GetNext() != pCurCrsr)
+/*?*/ delete pCurCrsr->GetNext();
+/*N*/ delete pCurCrsr;
+/*N*/
+/*N*/ // Stack freigeben
+/*N*/ if( pCrsrStk )
+/*N*/ {
+/*?*/ while( pCrsrStk->GetNext() != pCrsrStk )
+/*?*/ delete pCrsrStk->GetNext();
+/*?*/ delete pCrsrStk;
+/*N*/ }
+
+ // JP 27.07.98: Bug 54025 - ggfs. den HTML-Parser, der als Client in
+ // der CursorShell haengt keine Chance geben, sich an den
+ // TextNode zu haengen.
+/*N*/ if( GetRegisteredIn() )
+/*N*/ pRegisteredIn->Remove( this );
+/*N*/ }
+
+
+
+//Sollte fuer das Clipboard der WaitPtr geschaltet werden?
+//Warten bei TableMode, Mehrfachselektion und mehr als x Selektieren Absaetzen.
+
+
+
+
+
+// steht der Curor auf einem "Symbol"-Zeichen
+
+
+// zeige das akt. selektierte "Object" an
+/*N*/ void SwCrsrShell::MakeSelVisible()
+/*N*/ {
+/*N*/ ASSERT( bHasFocus, "kein Focus aber Cursor sichtbar machen?" );
+/*N*/ if( aCrsrHeight.Y() < aCharRect.Height() && aCharRect.Height() > VisArea().Height() )
+/*N*/ {
+/*N*/ SwRect aTmp( aCharRect );
+/*N*/ long nDiff = aCharRect.Height() - VisArea().Height();
+/*N*/ if( nDiff < aCrsrHeight.X() )
+/*?*/ aTmp.Top( nDiff + aCharRect.Top() );
+/*N*/ else
+/*N*/ {
+/*N*/ aTmp.Top( aCrsrHeight.X() + aCharRect.Top() );
+/*N*/ aTmp.Height( aCrsrHeight.Y() );
+/*N*/ }
+/*N*/ if( !aTmp.HasArea() )
+/*N*/ {
+/*?*/ aTmp.SSize().Height() += 1;
+/*?*/ aTmp.SSize().Width() += 1;
+/*N*/ }
+/*N*/ MakeVisible( aTmp );
+/*N*/ }
+/*N*/ else
+/*N*/ {
+/*N*/ if( aCharRect.HasArea() )
+/*N*/ MakeVisible( aCharRect );
+/*N*/ else
+/*N*/ {
+/*?*/ SwRect aTmp( aCharRect );
+/*?*/ aTmp.SSize().Height() += 1; aTmp.SSize().Width() += 1;
+/*?*/ MakeVisible( aTmp );
+/*N*/ }
+/*N*/ }
+/*N*/ }
+
+
+// suche eine gueltige ContentPosition (nicht geschuetzt/nicht versteckt)
+
+
+
+
+/*N*/ FASTBOOL SwCrsrShell::IsCrsrReadonly() const
+/*N*/ {
+/*N*/ if ( GetViewOptions()->IsReadonly() )
+/*N*/ {
+/*N*/ SwFrm *pFrm = GetCurrFrm( FALSE );
+/*N*/ SwFlyFrm *pFly;
+/*N*/ if( pFrm && pFrm->IsInFly() &&
+/*N*/ (pFly = pFrm->FindFlyFrm())->GetFmt()->GetEditInReadonly().GetValue() &&
+/*N*/ pFly->Lower() &&
+/*N*/ !pFly->Lower()->IsNoTxtFrm() &&
+/*N*/ !GetDrawView()->GetMarkList().GetMarkCount() )
+/*N*/ {
+/*N*/ return FALSE;
+/*N*/ }
+/*N*/ return TRUE;
+/*N*/ }
+/*N*/ return FALSE;
+/*N*/ }
+
+// SwCursor - Methode !!!!
+/*N*/ FASTBOOL SwCursor::IsReadOnlyAvailable() const
+/*N*/ {
+/*N*/ const SwShellCrsr* pShCrsr = *this;
+/*N*/ const SwUnoCrsr* pUnoCrsr = *this;
+/*N*/ return pShCrsr ? pShCrsr->GetShell()->IsReadOnlyAvailable() :
+/*N*/ pUnoCrsr ? TRUE : FALSE;
+/*N*/ }
+
+
+#if defined(DBG_UTIL) || defined(WIN)
+
+
+
+/*N*/ SwCursor* SwCrsrShell::GetSwCrsr( FASTBOOL bMakeTblCrsr ) const
+/*N*/ {
+/*N*/ return (SwCursor*)GetCrsr( bMakeTblCrsr );
+/*N*/ }
+
+// gebe den Stack Cursor zurueck
+/*N*/ SwPaM * SwCrsrShell::GetStkCrsr() const { return pCrsrStk; }
+
+// gebe den TabellenCrsr zurueck
+/*N*/ const SwPaM* SwCrsrShell::GetTblCrs() const { return pTblCrsr; }
+/*N*/ SwPaM* SwCrsrShell::GetTblCrs() { return pTblCrsr; }
+
+// Abfrage, ob ueberhaupt eine Selektion existiert, sprich der akt. Cursor
+// aufgespannt oder nicht der einzigste ist.
+
+/*N*/ FASTBOOL SwCrsrShell::IsSelection() const
+/*N*/ {
+/*N*/ return IsTableMode() || pCurCrsr->HasMark() ||
+/*N*/ pCurCrsr->GetNext() != pCurCrsr;
+/*N*/ }
+// returns if multiple cursors are available
+/*N*/ FASTBOOL SwCrsrShell::IsMultiSelection() const
+/*N*/ {
+/*N*/ return pCurCrsr->GetNext() != pCurCrsr;
+/*N*/ }
+
+// pruefe ob vom aktuellen Crsr der SPoint/Mark in einer Tabelle stehen
+/*N*/ const SwTableNode* SwCrsrShell::IsCrsrInTbl( BOOL bIsPtInTbl ) const
+/*N*/ {
+/*N*/ return pCurCrsr->GetNode( bIsPtInTbl )->FindTableNode();
+/*N*/ }
+
+
+/*?*/ FASTBOOL SwCrsrShell::IsCrsrPtAtEnd() const
+/*?*/ {
+/*?*/ return pCurCrsr->End() == pCurCrsr->GetPoint();
+/*?*/ }
+
+
+/*?*/ Point& SwCrsrShell::GetCrsrDocPos( BOOL bPoint ) const
+/*?*/ {
+/*?*/ return bPoint ? pCurCrsr->GetPtPos() : pCurCrsr->GetMkPos();
+/*?*/ }
+
+
+/*?*/ void SwCrsrShell::UnSetVisCrsr()
+/*?*/ {
+/*?*/ pVisCrsr->Hide();
+/*?*/ pVisCrsr->SetDragCrsr( FALSE );
+/*?*/ }
+
+
+/*?*/ FASTBOOL SwCrsrShell::IsSelOnePara() const
+/*?*/ {
+/*?*/ return pCurCrsr == pCurCrsr->GetNext() &&
+/*?*/ pCurCrsr->GetPoint()->nNode ==
+/*?*/ pCurCrsr->GetMark()->nNode;
+/*?*/ }
+
+/*?*/ SwMoveFnCollection* SwCrsrShell::MakeFindRange(
+/*?*/ USHORT nStt, USHORT nEnd, SwPaM* pPam ) const
+/*?*/ {
+/*?*/ DBG_BF_ASSERT(0, "STRIP"); return NULL;//STRIP001 return pCurCrsr->MakeFindRange( (SwDocPositions)nStt,
+/*?*/ }
+#endif
+
+/**
+ Checks if a position is valid. To be valid the position's node must
+ be a content node and the content must not be unregistered.
+
+ @param aPos the position to check.
+*/
+/*N*/ static bool lcl_PosOk(SwPosition & aPos)
+/*N*/ {
+/*N*/ bool bResult = true;
+/*N*/ SwPosition aTmpPos(aPos);
+/*N*/ aTmpPos.nContent.Assign(0, 0);
+/*N*/
+/*N*/ if (aPos.nNode.GetNode().GetCntntNode() == NULL ||
+/*N*/ aPos.nContent.GetIdxReg() == aTmpPos.nContent.GetIdxReg())
+/*N*/ bResult = false;
+/*N*/
+/*N*/ return bResult;
+/*N*/ }
+
+/**
+ Checks if a PaM is valid. For a PaM to be valid its point must be
+ valid. Additionaly if the PaM has a mark this has to be valid, too.
+
+ @param aPam the PaM to check
+*/
+/*N*/ static bool lcl_CrsrOk(SwPaM & aPam)
+/*N*/ {
+/*N*/ return lcl_PosOk(*aPam.GetPoint()) && (! aPam.HasMark()
+/*N*/ || lcl_PosOk(*aPam.GetMark()));
+/*N*/ }
+
+/*N*/ void SwCrsrShell::ClearUpCrsrs()
+/*N*/ {
+/*N*/ // start of the ring
+/*N*/ SwPaM * pStartCrsr = GetCrsr();
+/*N*/ // start loop with second entry of the ring
+/*N*/ SwPaM * pCrsr = (SwPaM *) pStartCrsr->GetNext();
+/*N*/ SwPaM * pTmpCrsr;
+/*N*/ bool bChanged = false;
+/*N*/
+ /*
+ For all entries in the ring except the start entry delete the
+ entry if it is invalid.
+ */
+/*N*/ while (pCrsr != pStartCrsr)
+/*N*/ {
+/*?*/ pTmpCrsr = (SwPaM *) pCrsr->GetNext();
+/*?*/
+/*?*/ if ( ! lcl_CrsrOk(*pCrsr))
+/*?*/ {
+/*?*/ delete pCrsr;
+/*?*/
+/*?*/ bChanged = true;
+/*N*/ }
+/*N*/
+/*N*/ pCrsr = pTmpCrsr;
+/*N*/ }
+/*N*/
+ /*
+ If the start entry of the ring is invalid replace it with a
+ cursor pointing to the beginning of the first content node in
+ the document.
+ */
+/*N*/ if (! lcl_CrsrOk(*pStartCrsr))
+/*N*/ {
+/*?*/ SwNodes & aNodes = GetDoc()->GetNodes();
+/*?*/ SwNodeIndex aIdx(*(aNodes.GetEndOfContent().StartOfSectionNode()));
+/*?*/
+/*?*/ SwNode * pNode = aNodes.GoNext(&aIdx);
+/*?*/ bool bFound = (pNode != NULL);
+/*?*/
+/*?*/ ASSERT(bFound, "no content node found");
+/*?*/
+/*?*/ if (bFound)
+/*?*/ {
+/*?*/ SwPaM aTmpPam(*pNode);
+/*?*/ *pStartCrsr = aTmpPam;
+/*?*/ }
+/*?*/
+/*?*/ bChanged = true;
+/*N*/ }
+
+ /*
+ If at least one of the cursors in the ring have been deleted or
+ replaced, remove the table cursor.
+ */
+/*N*/ if (pTblCrsr != NULL && bChanged)
+/*?*/ {DBG_BF_ASSERT(0, "STRIP"); }//STRIP001 TblCrsrToCursor();
+/*N*/ }
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */