1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: crsrsh.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sw.hxx"
33 #include <com/sun/star/util/SearchOptions.hpp>
34 #include <com/sun/star/text/XTextRange.hpp>
35 #include <hintids.hxx>
36 #include <svx/svdmodel.hxx>
37 #include <svx/frmdiritem.hxx>
39 #include <SwSmartTagMgr.hxx>
41 #include <rootfrm.hxx>
42 #include <pagefrm.hxx>
44 #include <viewimp.hxx>
46 #include <swselectionlist.hxx>
47 #include <IBlockCursor.hxx>
48 #include "BlockCursor.hxx"
52 #include <viewopt.hxx>
53 #include <frmtool.hxx>
57 #include <sectfrm.hxx>
58 #include <swtable.hxx>
61 #include <section.hxx>
63 #include <scriptinfo.hxx>
64 #include <globdoc.hxx>
66 #include <mdiexp.hxx> // ...Percent()
67 #include <fmteiro.hxx>
68 #include <wrong.hxx> // SMARTTAGS
69 #include <unoobj.hxx> // SMARTTAGS
70 #include <vcl/svapp.hxx>
71 #include <numrule.hxx>
72 #include <IGrammarContact.hxx>
74 #include <globals.hrc>
76 #include <comcore.hrc>
78 using namespace com::sun::star
;
81 TYPEINIT2(SwCrsrShell
,ViewShell
,SwModify
);
84 // Funktion loescht, alle ueberlappenden Cursor aus einem Cursor-Ring
85 void CheckRange( SwCursor
* );
87 //-----------------------------------------------------------------------
90 * Ueberpruefe ob der pCurCrsr in einen schon bestehenden Bereich zeigt.
91 * Wenn ja, dann hebe den alten Bereich auf.
95 void CheckRange( SwCursor
* pCurCrsr
)
97 const SwPosition
*pStt
= pCurCrsr
->Start(),
98 *pEnd
= pCurCrsr
->GetPoint() == pStt
? pCurCrsr
->GetMark() : pCurCrsr
->GetPoint();
101 *pTmp
= (SwPaM
*)pCurCrsr
->GetNext();
103 // durchsuche den gesamten Ring
104 while( pTmp
!= pCurCrsr
)
106 const SwPosition
*pTmpStt
= pTmp
->Start(),
107 *pTmpEnd
= pTmp
->GetPoint() == pTmpStt
?
108 pTmp
->GetMark() : pTmp
->GetPoint();
109 if( *pStt
<= *pTmpStt
)
111 if( *pEnd
> *pTmpStt
||
112 ( *pEnd
== *pTmpStt
&& *pEnd
== *pTmpEnd
))
116 if( *pStt
< *pTmpEnd
)
119 * liegt ein SPoint oder GetMark innerhalb vom Crsr-Bereich
120 * muss der alte Bereich aufgehoben werden.
121 * Beim Vergleich ist darauf zu achten, das SPoint nicht mehr zum
124 pTmp
= (SwPaM
*)pTmp
->GetNext();
127 delete pTmpDel
; // hebe alten Bereich auf
133 // -------------- Methoden von der SwCrsrShell -------------
135 SwPaM
* SwCrsrShell::CreateCrsr()
137 // Innerhalb der Tabellen-SSelection keinen neuen Crsr anlegen
138 ASSERT( !IsTableMode(), "in Tabellen SSelection" );
140 // neuen Cursor als Kopie vom akt. und in den Ring aufnehmen
141 // Verkettung zeigt immer auf den zuerst erzeugten, also vorwaerts
142 SwShellCrsr
* pNew
= new SwShellCrsr( *pCurCrsr
);
144 // hier den akt. Pam nur logisch Hiden, weil sonst die Invertierung
145 // vom kopierten Pam aufgehoben wird !!
147 // #i75172# to be able to make a complete content swap, i moved this to a method
148 // pNew->Insert( pCurCrsr, 0 );
149 // pCurCrsr->Remove( 0, pCurCrsr->Count() );
150 pNew
->swapContent(*pCurCrsr
);
152 pCurCrsr
->DeleteMark();
154 UpdateCrsr( SwCrsrShell::SCROLLWIN
);
159 // loesche den aktuellen Cursor und der folgende wird zum Aktuellen
162 BOOL
SwCrsrShell::DestroyCrsr()
164 // Innerhalb der Tabellen-SSelection keinen neuen Crsr loeschen
165 ASSERT( !IsTableMode(), "in Tabellen SSelection" );
167 // ist ueberhaupt ein naechtser vorhanden ?
168 if(pCurCrsr
->GetNext() == pCurCrsr
)
171 SwCallLink
aLk( *this ); // Crsr-Moves ueberwachen,
172 SwCursor
* pNextCrsr
= (SwCursor
*)pCurCrsr
->GetNext();
174 pCurCrsr
= dynamic_cast<SwShellCrsr
*>(pNextCrsr
);
180 // gebe den aktuellen zurueck
182 SwPaM
* SwCrsrShell::GetCrsr( BOOL bMakeTblCrsr
) const
186 if( bMakeTblCrsr
&& pTblCrsr
->IsCrsrMovedUpdt() )
188 // geparkte Cursor werden nicht wieder erzeugt
189 const SwCntntNode
* pCNd
;
190 if( pTblCrsr
->GetPoint()->nNode
.GetIndex() &&
191 pTblCrsr
->GetMark()->nNode
.GetIndex() &&
192 0 != ( pCNd
= pTblCrsr
->GetCntntNode() ) && pCNd
->GetFrm() &&
193 0 != ( pCNd
= pTblCrsr
->GetCntntNode(FALSE
) ) && pCNd
->GetFrm())
195 SwShellTableCrsr
* pTC
= (SwShellTableCrsr
*)pTblCrsr
;
196 GetLayout()->MakeTblCrsrs( *pTC
);
200 if( pTblCrsr
->IsChgd() )
202 const_cast<SwCrsrShell
*>(this)->pCurCrsr
=
203 dynamic_cast<SwShellCrsr
*>(pTblCrsr
->MakeBoxSels( pCurCrsr
));
210 void SwCrsrShell::StartAction()
214 // fuer das Update des Ribbon-Bars merken
215 const SwNode
& rNd
= pCurCrsr
->GetPoint()->nNode
.GetNode();
216 nAktNode
= rNd
.GetIndex();
217 nAktCntnt
= pCurCrsr
->GetPoint()->nContent
.GetIndex();
218 nAktNdTyp
= rNd
.GetNodeType();
219 bAktSelection
= *pCurCrsr
->GetPoint() != *pCurCrsr
->GetMark();
220 if( ND_TEXTNODE
& nAktNdTyp
)
221 nLeftFrmPos
= SwCallLink::GetFrm( (SwTxtNode
&)rNd
, nAktCntnt
, TRUE
);
225 ViewShell::StartAction(); // zur ViewShell
229 void SwCrsrShell::EndAction( const BOOL bIdleEnd
)
232 //OS: Wird z.B. eine Basic-Action im Hintergrund ausgefuehrt, geht es so nicht
235 // hat die Shell nicht den Focus, dann nur das EndAction an
236 // die ViewShell weitergeben.
237 ViewShell::EndAction( bIdleEnd );
242 BOOL bVis
= bSVCrsrVis
;
244 // Idle-Formatierung ?
245 if( bIdleEnd
&& Imp()->GetRegion() )
249 #ifdef SHOW_IDLE_REGION
253 GetWin()->ChangePen( Pen( Color( COL_YELLOW
)));
254 for( USHORT n
= 0; n
< aPntReg
.Count(); ++n
)
256 SwRect
aIRect( aPntReg
[n
] );
257 GetWin()->DrawRect( aIRect
.SVRect() );
265 // vor der letzten Action alle invaliden Numerierungen updaten
266 if( 1 == nStartAction
)
267 GetDoc()->UpdateNumRule();
269 // Task: 76923: dont show the cursor in the ViewShell::EndAction() - call.
270 // Only the UpdateCrsr shows the cursor.
271 BOOL bSavSVCrsrVis
= bSVCrsrVis
;
274 ViewShell::EndAction( bIdleEnd
); //der ViewShell den Vortritt lassen
276 bSVCrsrVis
= bSavSVCrsrVis
;
280 if( bVis
) // auch SV-Cursor wieder anzeigen
283 // falls noch ein ChgCall vorhanden ist und nur noch die Basic
284 // Klammerung vorhanden ist, dann rufe ihn. Dadurch wird die interne
285 // mit der Basic-Klammerung entkoppelt; die Shells werden umgeschaltet
286 if( !BasicActionPend() )
288 //JP 12.01.98: Bug #46496# - es muss innerhalb einer BasicAction
289 // der Cursor geupdatet werden; um z.B. den
290 // TabellenCursor zu erzeugen. Im UpdateCrsr wird
291 // das jetzt beruecksichtigt!
292 UpdateCrsr( SwCrsrShell::CHKRANGE
, bIdleEnd
);
295 // Crsr-Moves ueberwachen, evt. Link callen
296 // der DTOR ist das interressante!!
297 SwCallLink
aLk( *this, nAktNode
, nAktCntnt
, (BYTE
)nAktNdTyp
,
298 nLeftFrmPos
, bAktSelection
);
301 if( bCallChgLnk
&& bChgCallFlag
&& aChgLnk
.IsSet() )
303 aChgLnk
.Call( this );
304 bChgCallFlag
= FALSE
; // Flag zuruecksetzen
310 USHORT nParm
= SwCrsrShell::CHKRANGE
;
312 nParm
|= SwCrsrShell::SCROLLWIN
;
313 UpdateCrsr( nParm
, bIdleEnd
); // Cursor-Aenderungen anzeigen
316 SwCallLink
aLk( *this ); // Crsr-Moves ueberwachen,
317 aLk
.nNode
= nAktNode
; // evt. Link callen
318 aLk
.nNdTyp
= (BYTE
)nAktNdTyp
;
319 aLk
.nCntnt
= nAktCntnt
;
320 aLk
.nLeftFrmPos
= nLeftFrmPos
;
323 ( 1 == nCrsrMove
&& bInCMvVisportChgd
) )
324 ShowCrsrs( bSVCrsrVis
? TRUE
: FALSE
); // Cursor & Selektionen wieder anzeigen
326 // falls noch ein ChgCall vorhanden ist, dann rufe ihn
327 if( bCallChgLnk
&& bChgCallFlag
&& aChgLnk
.IsSet() )
329 aChgLnk
.Call( this );
330 bChgCallFlag
= FALSE
; // Flag zuruecksetzen
335 #if !defined( PRODUCT )
337 void SwCrsrShell::SttCrsrMove()
339 ASSERT( nCrsrMove
< USHRT_MAX
, "To many nested CrsrMoves." );
344 void SwCrsrShell::EndCrsrMove( const BOOL bIdleEnd
)
346 ASSERT( nCrsrMove
, "EndCrsrMove() ohne SttCrsrMove()." );
347 EndAction( bIdleEnd
);
349 bInCMvVisportChgd
= FALSE
;
355 BOOL
SwCrsrShell::LeftRight( BOOL bLeft
, USHORT nCnt
, USHORT nMode
,
356 BOOL bVisualAllowed
)
359 return bLeft
? GoPrevCell() : GoNextCell();
361 SwCallLink
aLk( *this ); // Crsr-Moves ueberwachen, evt. Link callen
364 // #i27615# Handle cursor in front of label.
365 const SwTxtNode
* pTxtNd
= 0;
368 pBlockCrsr
->clearPoints();
371 // 1. CASE: Cursor is in front of label. A move to the right
372 // will simply reset the bInFrontOfLabel flag:
374 SwShellCrsr
* pShellCrsr
= getShellCrsr( true );
375 if ( !bLeft
&& pShellCrsr
->IsInFrontOfLabel() )
377 SetInFrontOfLabel( FALSE
);
381 // 2. CASE: Cursor is at beginning of numbered paragraph. A move
382 // to the left will simply set the bInFrontOfLabel flag:
384 else if ( bLeft
&& 0 == pShellCrsr
->GetPoint()->nContent
.GetIndex() &&
385 !pShellCrsr
->IsInFrontOfLabel() && !pShellCrsr
->HasMark() &&
386 0 != ( pTxtNd
= pShellCrsr
->GetNode()->GetTxtNode() ) &&
387 pTxtNd
->HasVisibleNumberingOrBullet() )
389 SetInFrontOfLabel( TRUE
);
393 // 3. CASE: Regular cursor move. Reset the bInFrontOfLabel flag:
397 const BOOL bSkipHidden
= !GetViewOptions()->IsShowHiddenChar();
398 bRet
= SetInFrontOfLabel( FALSE
);
399 bRet
= pShellCrsr
->LeftRight( bLeft
, nCnt
, nMode
, bVisualAllowed
,
401 !IsOverwriteCrsr() ) || bRet
;
411 // --> OD 2008-04-02 #refactorlists#
412 void SwCrsrShell::MarkListLevel( const String
& sListId
,
413 const int nListLevel
)
415 if ( sListId
!= sMarkedListId
||
416 nListLevel
!= nMarkedListLevel
)
418 if ( sMarkedListId
.Len() > 0 )
419 pDoc
->MarkListLevel( sMarkedListId
, nMarkedListLevel
, FALSE
);
421 if ( sListId
.Len() > 0 )
423 pDoc
->MarkListLevel( sListId
, nListLevel
, TRUE
);
426 sMarkedListId
= sListId
;
427 nMarkedListLevel
= nListLevel
;
431 void SwCrsrShell::UpdateMarkedListLevel()
433 SwTxtNode
* pTxtNd
= _GetCrsr()->GetNode()->GetTxtNode();
437 if ( !pTxtNd
->IsNumbered() )
439 pCurCrsr
->_SetInFrontOfLabel( FALSE
);
440 MarkListLevel( String(), 0 );
442 else if ( pCurCrsr
->IsInFrontOfLabel() )
444 if ( pTxtNd
->IsInList() )
446 ASSERT( pTxtNd
->GetActualListLevel() >= 0 &&
447 pTxtNd
->GetActualListLevel() < MAXLEVEL
, "Which level?")
448 MarkListLevel( pTxtNd
->GetListId(),
449 pTxtNd
->GetActualListLevel() );
454 MarkListLevel( String(), 0 );
460 BOOL
SwCrsrShell::UpDown( BOOL bUp
, USHORT nCnt
)
462 SET_CURR_SHELL( this );
463 SwCallLink
aLk( *this ); // Crsr-Moves ueberwachen, evt. Link callen
465 BOOL bTableMode
= IsTableMode();
466 SwShellCrsr
* pTmpCrsr
= getShellCrsr( true );
468 BOOL bRet
= pTmpCrsr
->UpDown( bUp
, nCnt
);
469 // --> FME 2005-01-10 #i40019# UpDown should always reset the
470 // bInFrontOfLabel flag:
471 bRet
= SetInFrontOfLabel(FALSE
) || bRet
;
475 pBlockCrsr
->clearPoints();
479 eMvState
= MV_UPDOWN
; // Status fuers Crsr-Travelling - GetCrsrOfst
482 CrsrFlag eUpdtMode
= SwCrsrShell::SCROLLWIN
;
484 eUpdtMode
= (CrsrFlag
) (eUpdtMode
485 | SwCrsrShell::UPDOWN
| SwCrsrShell::CHKRANGE
);
486 UpdateCrsr( static_cast<USHORT
>(eUpdtMode
) );
493 BOOL
SwCrsrShell::LRMargin( BOOL bLeft
, BOOL bAPI
)
495 SwCallLink
aLk( *this ); // Crsr-Moves ueberwachen, evt. Link callen
496 SET_CURR_SHELL( this );
497 eMvState
= MV_LEFTMARGIN
; // Status fuers Crsr-Travelling - GetCrsrOfst
499 const BOOL bTableMode
= IsTableMode();
500 SwShellCrsr
* pTmpCrsr
= getShellCrsr( true );
503 pBlockCrsr
->clearPoints();
505 const BOOL bWasAtLM
=
506 ( 0 == _GetCrsr()->GetPoint()->nContent
.GetIndex() );
508 BOOL bRet
= pTmpCrsr
->LeftRightMargin( bLeft
, bAPI
);
510 if ( bLeft
&& !bTableMode
&& bRet
&& bWasAtLM
&& !_GetCrsr()->HasMark() )
512 const SwTxtNode
* pTxtNd
= _GetCrsr()->GetNode()->GetTxtNode();
513 if ( pTxtNd
&& pTxtNd
->HasVisibleNumberingOrBullet() )
514 SetInFrontOfLabel( TRUE
);
518 bRet
= SetInFrontOfLabel( FALSE
) || bRet
;
528 BOOL
SwCrsrShell::IsAtLRMargin( BOOL bLeft
, BOOL bAPI
) const
530 const SwShellCrsr
* pTmpCrsr
= getShellCrsr( true );
531 return pTmpCrsr
->IsAtLeftRightMargin( bLeft
, bAPI
);
535 BOOL
SwCrsrShell::SttEndDoc( BOOL bStt
)
537 SwCallLink
aLk( *this ); // Crsr-Moves ueberwachen, evt. Link callen
539 SwShellCrsr
* pTmpCrsr
= pBlockCrsr
? &pBlockCrsr
->getShellCrsr() : pCurCrsr
;
540 BOOL bRet
= pTmpCrsr
->SttEndDoc( bStt
);
544 pTmpCrsr
->GetPtPos().Y() = 0; // expl. 0 setzen (TabellenHeader)
547 pBlockCrsr
->clearPoints();
548 RefreshBlockCursor();
551 UpdateCrsr(SwCrsrShell::SCROLLWIN
|SwCrsrShell::CHKRANGE
|SwCrsrShell::READONLY
);
556 void SwCrsrShell::ExtendedSelectAll()
558 SwNodes
& rNodes
= GetDoc()->GetNodes();
559 SwPosition
* pPos
= pCurCrsr
->GetPoint();
560 pPos
->nNode
= rNodes
.GetEndOfPostIts();
561 pPos
->nContent
.Assign( rNodes
.GoNext( &pPos
->nNode
), 0 );
562 pPos
= pCurCrsr
->GetMark();
563 pPos
->nNode
= rNodes
.GetEndOfContent();
564 SwCntntNode
* pCNd
= rNodes
.GoPrevious( &pPos
->nNode
);
565 pPos
->nContent
.Assign( pCNd
, pCNd
? pCNd
->Len() : 0 );
568 BOOL
SwCrsrShell::MovePage( SwWhichPage fnWhichPage
, SwPosPage fnPosPage
)
572 // Springe beim Selektieren nie ueber Section-Grenzen !!
573 if( !pCurCrsr
->HasMark() || !pCurCrsr
->IsNoCntnt() )
575 SwCallLink
aLk( *this ); // Crsr-Moves ueberwachen, evt. Link callen
576 SET_CURR_SHELL( this );
578 SwCrsrSaveState
aSaveState( *pCurCrsr
);
579 Point
& rPt
= pCurCrsr
->GetPtPos();
580 SwCntntFrm
* pFrm
= pCurCrsr
->GetCntntNode()->
581 GetFrm( &rPt
, pCurCrsr
->GetPoint() );
582 if( pFrm
&& TRUE
== ( bRet
= GetFrmInPage( pFrm
, fnWhichPage
,
583 fnPosPage
, pCurCrsr
) ) &&
584 !pCurCrsr
->IsSelOvr( nsSwCursorSelOverFlags::SELOVER_TOGGLE
|
585 nsSwCursorSelOverFlags::SELOVER_CHANGEPOS
))
594 BOOL
SwCrsrShell::MovePara(SwWhichPara fnWhichPara
, SwPosPara fnPosPara
)
596 SwCallLink
aLk( *this ); // Crsr-Moves ueberwachen, evt. Link callen
597 SwCursor
* pTmpCrsr
= getShellCrsr( true );
598 BOOL bRet
= pTmpCrsr
->MovePara( fnWhichPara
, fnPosPara
);
605 BOOL
SwCrsrShell::MoveSection( SwWhichSection fnWhichSect
,
606 SwPosSection fnPosSect
)
608 SwCallLink
aLk( *this ); // Crsr-Moves ueberwachen, evt. Link callen
609 SwCursor
* pTmpCrsr
= getShellCrsr( true );
610 BOOL bRet
= pTmpCrsr
->MoveSection( fnWhichSect
, fnPosSect
);
618 // Positionieren des Cursors
621 SwFrm
* lcl_IsInHeaderFooter( const SwNodeIndex
& rIdx
, Point
& rPt
)
624 SwCntntNode
* pCNd
= rIdx
.GetNode().GetCntntNode();
627 pFrm
= pCNd
->GetFrm( &rPt
, 0, FALSE
)->GetUpper();
628 while( pFrm
&& !pFrm
->IsHeaderFrm() && !pFrm
->IsFooterFrm() )
629 pFrm
= pFrm
->IsFlyFrm() ? ((SwFlyFrm
*)pFrm
)->AnchorFrm()
635 BOOL
SwCrsrShell::IsInHeaderFooter( BOOL
* pbInHeader
) const
638 SwFrm
* pFrm
= ::lcl_IsInHeaderFooter( pCurCrsr
->GetPoint()->nNode
, aPt
);
639 if( pFrm
&& pbInHeader
)
640 *pbInHeader
= pFrm
->IsHeaderFrm();
644 int SwCrsrShell::SetCrsr( const Point
&rLPt
, BOOL bOnlyText
, bool bBlock
)
646 SET_CURR_SHELL( this );
648 SwShellCrsr
* pCrsr
= getShellCrsr( bBlock
);
649 SwPosition
aPos( *pCrsr
->GetPoint() );
651 Point
& rAktCrsrPt
= pCrsr
->GetPtPos();
652 SwCrsrMoveState
aTmpState( IsTableMode() ? MV_TBLSEL
:
653 bOnlyText
? MV_SETONLYTEXT
: MV_NONE
);
654 aTmpState
.bSetInReadOnly
= IsReadOnlyAvailable();
656 SwTxtNode
* pTxtNd
= pCrsr
->GetNode()->GetTxtNode();
658 if ( pTxtNd
&& !IsTableMode() &&
659 // --> FME 2004-11-25 #i37515# No bInFrontOfLabel during selection
662 pTxtNd
->HasVisibleNumberingOrBullet() )
664 aTmpState
.bInFrontOfLabel
= TRUE
; // #i27615#
668 aTmpState
.bInFrontOfLabel
= FALSE
;
671 int bRet
= CRSR_POSOLD
|
672 ( GetLayout()->GetCrsrOfst( &aPos
, aPt
, &aTmpState
)
675 const bool bOldInFrontOfLabel
= IsInFrontOfLabel();
676 const bool bNewInFrontOfLabel
= aTmpState
.bInFrontOfLabel
;
678 pCrsr
->SetCrsrBidiLevel( aTmpState
.nCursorBidiLevel
);
680 if( MV_RIGHTMARGIN
== aTmpState
.eState
)
681 eMvState
= MV_RIGHTMARGIN
;
682 // steht neu Pos im Header/Footer ?
683 SwFrm
* pFrm
= lcl_IsInHeaderFooter( aPos
.nNode
, aPt
);
684 if( IsTableMode() && !pFrm
&& aPos
.nNode
.GetNode().StartOfSectionNode() ==
685 pCrsr
->GetPoint()->nNode
.GetNode().StartOfSectionNode() )
686 // gleiche Tabellenzelle und nicht im Header/Footer
690 if( pBlockCrsr
&& bBlock
)
692 pBlockCrsr
->setEndPoint( rLPt
);
693 if( !pCrsr
->HasMark() )
694 pBlockCrsr
->setStartPoint( rLPt
);
695 else if( !pBlockCrsr
->getStartPoint() )
696 pBlockCrsr
->setStartPoint( pCrsr
->GetMkPos() );
698 if( !pCrsr
->HasMark() )
700 // steht an der gleichen Position und wenn im Header/Footer,
702 if( aPos
== *pCrsr
->GetPoint() &&
703 bOldInFrontOfLabel
== bNewInFrontOfLabel
)
707 if( pFrm
->Frm().IsInside( rAktCrsrPt
))
710 else if( aPos
.nNode
.GetNode().IsCntntNode() )
712 // im gleichen Frame gelandet?
713 SwFrm
* pOld
= ((SwCntntNode
&)aPos
.nNode
.GetNode()).GetFrm(
714 &aCharRect
.Pos(), 0, FALSE
);
715 SwFrm
* pNew
= ((SwCntntNode
&)aPos
.nNode
.GetNode()).GetFrm(
724 // SSelection ueber nicht erlaubte Sections oder wenn im Header/Footer
725 // dann in verschiedene
726 if( !CheckNodesRange( aPos
.nNode
, pCrsr
->GetMark()->nNode
, TRUE
)
727 || ( pFrm
&& !pFrm
->Frm().IsInside( pCrsr
->GetMkPos() ) ))
730 // steht an der gleichen Position und nicht im Header/Footer
731 if( aPos
== *pCrsr
->GetPoint() )
735 SwCallLink
aLk( *this ); // Crsr-Moves ueberwachen, evt. Link callen
736 SwCrsrSaveState
aSaveState( *pCrsr
);
738 *pCrsr
->GetPoint() = aPos
;
741 // --> FME 2005-01-31 #i41424# Only update the marked number levels if necessary
742 // Force update of marked number levels if necessary.
743 if ( bNewInFrontOfLabel
|| bOldInFrontOfLabel
)
744 pCurCrsr
->_SetInFrontOfLabel( !bNewInFrontOfLabel
);
745 SetInFrontOfLabel( bNewInFrontOfLabel
);
748 if( !pCrsr
->IsSelOvr( nsSwCursorSelOverFlags::SELOVER_CHANGEPOS
) )
750 USHORT nFlag
= SwCrsrShell::SCROLLWIN
| SwCrsrShell::CHKRANGE
;
752 bRet
&= ~CRSR_POSOLD
;
754 else if( bOnlyText
&& !pCurCrsr
->HasMark() )
756 if( FindValidCntntNode( bOnlyText
) )
758 // Cursor in einen gueltigen Content stellen
759 if( aPos
== *pCrsr
->GetPoint() )
763 UpdateCrsr( SwCrsrShell::SCROLLWIN
| SwCrsrShell::CHKRANGE
);
764 bRet
&= ~CRSR_POSOLD
;
769 // es gibt keinen gueltigen Inhalt -> Cursor verstecken
770 pVisCrsr
->Hide(); // sichtbaren Cursor immer verstecken
771 eMvState
= MV_NONE
; // Status fuers Crsr-Travelling
773 if( GetDoc()->GetDocShell() )
775 GetDoc()->GetDocShell()->SetReadOnlyUI( TRUE
);
776 CallChgLnk(); // UI bescheid sagen!
785 void SwCrsrShell::TblCrsrToCursor()
787 ASSERT( pTblCrsr
, "TblCrsrToCursor: Why?" );
788 delete pTblCrsr
, pTblCrsr
= 0;
791 void SwCrsrShell::BlockCrsrToCrsr()
793 ASSERT( pBlockCrsr
, "BlockCrsrToCrsr: Why?" );
794 if( pBlockCrsr
&& !HasSelection() )
796 SwPaM
& rPam
= pBlockCrsr
->getShellCrsr();
798 *pCurCrsr
->GetPoint() = *rPam
.GetPoint();
800 *pCurCrsr
->GetMark() = *rPam
.GetMark();
802 pCurCrsr
->DeleteMark();
804 delete pBlockCrsr
, pBlockCrsr
= 0;
807 void SwCrsrShell::CrsrToBlockCrsr()
811 SwPosition
aPos( *pCurCrsr
->GetPoint() );
812 pBlockCrsr
= createBlockCursor( *this, aPos
);
813 SwShellCrsr
&rBlock
= pBlockCrsr
->getShellCrsr();
814 rBlock
.GetPtPos() = pCurCrsr
->GetPtPos();
815 if( pCurCrsr
->HasMark() )
818 *rBlock
.GetMark() = *pCurCrsr
->GetMark();
819 rBlock
.GetMkPos() = pCurCrsr
->GetMkPos();
822 pBlockCrsr
->clearPoints();
823 RefreshBlockCursor();
826 void SwCrsrShell::ClearMark()
828 // ist ueberhaupt ein GetMark gesetzt ?
831 while( pCurCrsr
->GetNext() != pCurCrsr
)
832 delete pCurCrsr
->GetNext();
833 pTblCrsr
->DeleteMark();
835 if( pCurCrsr
->HasMark() )
837 // falls doch nicht alle Indizies richtig verschoben werden
838 // (z.B.: Kopf-/Fusszeile loeschen) den Content-Anteil vom
839 // Mark aufs Nodes-Array setzen
840 SwPosition
& rPos
= *pCurCrsr
->GetMark();
841 rPos
.nNode
.Assign( pDoc
->GetNodes(), 0 );
842 rPos
.nContent
.Assign( 0, 0 );
843 pCurCrsr
->DeleteMark();
846 *pCurCrsr
->GetPoint() = *pTblCrsr
->GetPoint();
847 pCurCrsr
->GetPtPos() = pTblCrsr
->GetPtPos();
848 delete pTblCrsr
, pTblCrsr
= 0;
849 pCurCrsr
->SwSelPaintRects::Show();
853 if( !pCurCrsr
->HasMark() )
855 // falls doch nicht alle Indizies richtig verschoben werden
856 // (z.B.: Kopf-/Fusszeile loeschen) den Content-Anteil vom
857 // Mark aufs Nodes-Array setzen
858 SwPosition
& rPos
= *pCurCrsr
->GetMark();
859 rPos
.nNode
.Assign( pDoc
->GetNodes(), 0 );
860 rPos
.nContent
.Assign( 0, 0 );
861 pCurCrsr
->DeleteMark();
863 pCurCrsr
->SwSelPaintRects::Show();
868 void SwCrsrShell::NormalizePam(BOOL bPointFirst
)
870 SwCallLink
aLk( *this ); // Crsr-Moves ueberwachen, evt. Link callen
871 pCurCrsr
->Normalize(bPointFirst
);
874 void SwCrsrShell::SwapPam()
876 SwCallLink
aLk( *this ); // Crsr-Moves ueberwachen, evt. Link callen
877 pCurCrsr
->Exchange();
881 // suche innerhalb der Selektierten-Bereiche nach einer Selektion, die
882 // den angebenen SPoint umschliesst
883 // Ist das Flag bTstOnly gesetzt, dann wird nur getestet, ob dort eine
884 // SSelection besteht; des akt. Cursr wird nicht umgesetzt!
885 // Ansonsten wird er auf die gewaehlte SSelection gesetzt.
888 BOOL
SwCrsrShell::ChgCurrPam( const Point
& rPt
,
889 BOOL bTstOnly
, BOOL bTstHit
)
891 SET_CURR_SHELL( this );
893 // Pruefe ob der SPoint in einer Tabellen-Selektion liegt
894 if( bTstOnly
&& pTblCrsr
)
895 return pTblCrsr
->IsInside( rPt
);
897 SwCallLink
aLk( *this ); // Crsr-Moves ueberwachen, evt. Link callen
898 // Suche die Position rPt im Dokument
899 SwPosition
aPtPos( *pCurCrsr
->GetPoint() );
902 SwCrsrMoveState
aTmpState( MV_NONE
);
903 aTmpState
.bSetInReadOnly
= IsReadOnlyAvailable();
904 if ( !GetLayout()->GetCrsrOfst( &aPtPos
, aPt
, &aTmpState
) && bTstHit
)
907 // suche in allen Selektionen nach dieser Position
908 SwShellCrsr
* pCmp
= (SwShellCrsr
*)pCurCrsr
; // sicher den Pointer auf Cursor
910 if( pCmp
->HasMark() &&
911 *pCmp
->Start() <= aPtPos
&& *pCmp
->End() > aPtPos
)
913 if( bTstOnly
|| pCurCrsr
== pCmp
) // ist der aktuelle.
914 return TRUE
; // return ohne Update
917 UpdateCrsr(); // Cursor steht schon richtig
921 ( pCmp
= dynamic_cast<SwShellCrsr
*>(pCmp
->GetNext()) ) );
926 void SwCrsrShell::KillPams()
928 // keiner zum loeschen vorhanden?
929 if( !pTblCrsr
&& !pBlockCrsr
&& pCurCrsr
->GetNext() == pCurCrsr
)
932 while( pCurCrsr
->GetNext() != pCurCrsr
)
933 delete pCurCrsr
->GetNext();
934 pCurCrsr
->SetColumnSelection( false );
938 // Cursor Ring loeschen
939 pCurCrsr
->DeleteMark();
940 *pCurCrsr
->GetPoint() = *pTblCrsr
->GetPoint();
941 pCurCrsr
->GetPtPos() = pTblCrsr
->GetPtPos();
945 else if( pBlockCrsr
)
947 // delete the ring of cursors
948 pCurCrsr
->DeleteMark();
949 SwShellCrsr
&rBlock
= pBlockCrsr
->getShellCrsr();
950 *pCurCrsr
->GetPoint() = *rBlock
.GetPoint();
951 pCurCrsr
->GetPtPos() = rBlock
.GetPtPos();
953 pBlockCrsr
->clearPoints();
955 UpdateCrsr( SwCrsrShell::SCROLLWIN
);
959 int SwCrsrShell::CompareCursor( CrsrCompareType eType
) const
962 const SwPosition
*pFirst
= 0, *pSecond
= 0;
963 const SwPaM
*pCur
= GetCrsr(), *pStk
= pCrsrStk
;
964 if( CurrPtCurrMk
!= eType
&& pStk
)
969 pFirst
= pStk
->GetPoint();
970 pSecond
= pStk
->GetMark();
973 pFirst
= pStk
->GetPoint();
974 pSecond
= pCur
->GetPoint();
977 pFirst
= pStk
->GetPoint();
978 pSecond
= pCur
->GetMark();
981 pFirst
= pStk
->GetMark();
982 pSecond
= pCur
->GetPoint();
985 pFirst
= pStk
->GetMark();
986 pSecond
= pStk
->GetMark();
989 pFirst
= pCur
->GetPoint();
990 pSecond
= pCur
->GetMark();
994 if( !pFirst
|| !pSecond
)
996 else if( *pFirst
< *pSecond
)
998 else if( *pFirst
== *pSecond
)
1006 BOOL
SwCrsrShell::IsSttPara() const
1007 { return( pCurCrsr
->GetPoint()->nContent
== 0 ? TRUE
: FALSE
); }
1010 BOOL
SwCrsrShell::IsEndPara() const
1011 { return( pCurCrsr
->GetPoint()->nContent
== pCurCrsr
->GetCntntNode()->Len() ? TRUE
: FALSE
); }
1014 BOOL
SwCrsrShell::IsInFrontOfLabel() const
1016 return pCurCrsr
->IsInFrontOfLabel();
1019 bool SwCrsrShell::SetInFrontOfLabel( BOOL bNew
)
1021 if ( bNew
!= IsInFrontOfLabel() )
1023 pCurCrsr
->_SetInFrontOfLabel( bNew
);
1024 UpdateMarkedListLevel();
1030 BOOL
SwCrsrShell::GotoPage( USHORT nPage
)
1032 SET_CURR_SHELL( this );
1033 SwCallLink
aLk( *this ); // Crsr-Moves ueberwachen, evt. Link callen
1034 SwCrsrSaveState
aSaveState( *pCurCrsr
);
1035 BOOL bRet
= GetLayout()->SetCurrPage( pCurCrsr
, nPage
) &&
1036 !pCurCrsr
->IsSelOvr( nsSwCursorSelOverFlags::SELOVER_TOGGLE
|
1037 nsSwCursorSelOverFlags::SELOVER_CHANGEPOS
);
1039 UpdateCrsr(SwCrsrShell::SCROLLWIN
|SwCrsrShell::CHKRANGE
|SwCrsrShell::READONLY
);
1044 void SwCrsrShell::GetPageNum( USHORT
&rnPhyNum
, USHORT
&rnVirtNum
,
1045 BOOL bAtCrsrPos
, const BOOL bCalcFrm
)
1047 SET_CURR_SHELL( this );
1048 // Seitennummer: die erste sichtbare Seite oder die am Cursor
1049 const SwCntntFrm
* pCFrm
;
1050 const SwPageFrm
*pPg
= 0;
1052 if( !bAtCrsrPos
|| 0 == (pCFrm
= GetCurrFrm( bCalcFrm
)) ||
1053 0 == (pPg
= pCFrm
->FindPageFrm()) )
1055 pPg
= Imp()->GetFirstVisPage();
1056 while( pPg
&& pPg
->IsEmptyPage() )
1057 pPg
= (const SwPageFrm
*)pPg
->GetNext();
1059 // Abfrage auf pPg muss fuer den Sonderfall Writerstart mit
1060 // standard.vor sein.
1061 rnPhyNum
= pPg
? pPg
->GetPhyPageNum() : 1;
1062 rnVirtNum
= pPg
? pPg
->GetVirtPageNum() : 1;
1066 USHORT
SwCrsrShell::GetNextPrevPageNum( BOOL bNext
)
1068 SET_CURR_SHELL( this );
1070 // Seitennummer: die erste sichtbare Seite oder die am Cursor
1071 const SwPageFrm
*pPg
= Imp()->GetFirstVisPage();
1074 const SwTwips nPageTop
= pPg
->Frm().Top();
1078 // go to next view layout row:
1081 pPg
= (const SwPageFrm
*)pPg
->GetNext();
1083 while( pPg
&& pPg
->Frm().Top() == nPageTop
);
1085 while( pPg
&& pPg
->IsEmptyPage() )
1086 pPg
= (const SwPageFrm
*)pPg
->GetNext();
1090 // go to previous view layout row:
1093 pPg
= (const SwPageFrm
*)pPg
->GetPrev();
1095 while( pPg
&& pPg
->Frm().Top() == nPageTop
);
1097 while( pPg
&& pPg
->IsEmptyPage() )
1098 pPg
= (const SwPageFrm
*)pPg
->GetPrev();
1101 // Abfrage auf pPg muss fuer den Sonderfall Writerstart mit
1102 // standard.vor sein.
1103 return pPg
? pPg
->GetPhyPageNum() : USHRT_MAX
;
1107 USHORT
SwCrsrShell::GetPageCnt()
1109 SET_CURR_SHELL( this );
1110 // gebe die Anzahl der Seiten zurueck
1111 return GetLayout()->GetPageNum();
1114 // Gehe zur naechsten SSelection
1117 BOOL
SwCrsrShell::GoNextCrsr()
1119 // besteht ueberhaupt ein Ring ?
1120 if( pCurCrsr
->GetNext() == pCurCrsr
)
1123 SET_CURR_SHELL( this );
1124 SwCallLink
aLk( *this ); // Crsr-Moves ueberwachen, evt. Link callen
1125 pCurCrsr
= dynamic_cast<SwShellCrsr
*>(pCurCrsr
->GetNext());
1127 // Bug 24086: auch alle anderen anzeigen
1136 // gehe zur vorherigen SSelection
1139 BOOL
SwCrsrShell::GoPrevCrsr()
1141 // besteht ueberhaupt ein Ring ?
1142 if( pCurCrsr
->GetNext() == pCurCrsr
)
1145 SET_CURR_SHELL( this );
1146 SwCallLink
aLk( *this ); // Crsr-Moves ueberwachen, evt. Link callen
1147 pCurCrsr
= dynamic_cast<SwShellCrsr
*>(pCurCrsr
->GetPrev());
1149 // Bug 24086: auch alle anderen anzeigen
1160 void SwCrsrShell::Paint( const Rectangle
&rRect
)
1162 SET_CURR_SHELL( this );
1164 // beim Painten immer alle Cursor ausschalten
1165 SwRect
aRect( rRect
);
1168 // ist Cursor sichtbar, dann verstecke den SV-Cursor
1169 if( pVisCrsr
->IsVisible() && !aRect
.IsOver( aCharRect
) ) //JP 18.06.97: ???
1175 // Bereich neu painten
1176 ViewShell::Paint( rRect
);
1178 if( bHasFocus
&& !bBasicHideCrsr
)
1180 SwShellCrsr
* pAktCrsr
= pTblCrsr
? pTblCrsr
: pCurCrsr
;
1181 // pAktCrsr->Invalidate( aRect );
1184 // damit nicht rechts/unten die Raender abgeschnitten werden
1185 pAktCrsr
->Invalidate( VisArea() );
1189 pAktCrsr
->Invalidate( aRect
);
1192 if( bSVCrsrVis
&& bVis
) // auch SV-Cursor wieder anzeigen
1198 void SwCrsrShell::VisPortChgd( const SwRect
& rRect
)
1200 SET_CURR_SHELL( this );
1201 BOOL bVis
; // beim Scrollen immer alle Cursor ausschalten
1203 // ist Cursor sichtbar, dann verstecke den SV-Cursor
1204 if( TRUE
== ( bVis
= pVisCrsr
->IsVisible() ))
1207 bVisPortChgd
= TRUE
;
1208 aOldRBPos
.X() = VisArea().Right();
1209 aOldRBPos
.Y() = VisArea().Bottom();
1211 //Damit es es keine Probleme mit dem SV-Cursor gibt, wird in
1212 //ViewShell::VisPo.. ein Update() auf das Window gerufen.
1213 //Waehrend des Paintens duerfen aber nun wieder keine Selectionen
1214 //angezeigt werden, deshalb wird der Aufruf hier geklammert.
1215 ViewShell::VisPortChgd( rRect
); // Bereich verschieben
1218 SwRect aRect( rRect );
1219 if( VisArea().IsOver( aRect ) )
1220 pCurCrsr->Invalidate( aRect );
1223 if( bSVCrsrVis
&& bVis
) // auch SV-Cursor wieder anzeigen
1227 bInCMvVisportChgd
= TRUE
;
1229 bVisPortChgd
= FALSE
;
1232 // aktualisiere den Crsrs, d.H. setze ihn wieder in den Content.
1233 // Das sollte nur aufgerufen werden, wenn der Cursor z.B. beim
1234 // Loeschen von Rahmen irgendwohin gesetzt wurde. Die Position
1235 // ergibt sich aus seiner aktuellen Position im Layout !!
1238 void SwCrsrShell::UpdateCrsrPos()
1240 SET_CURR_SHELL( this );
1242 SwShellCrsr
* pShellCrsr
= getShellCrsr( true );
1243 Size
aOldSz( GetDocSize() );
1244 SwCntntNode
*pCNode
= pShellCrsr
->GetCntntNode();
1245 SwCntntFrm
*pFrm
= pCNode
?
1246 pCNode
->GetFrm( &pShellCrsr
->GetPtPos(), pShellCrsr
->GetPoint() ) :0;
1247 if( !pFrm
|| (pFrm
->IsTxtFrm() && ((SwTxtFrm
*)pFrm
)->IsHiddenNow()) )
1249 SwCrsrMoveState
aTmpState( MV_NONE
);
1250 aTmpState
.bSetInReadOnly
= IsReadOnlyAvailable();
1251 GetLayout()->GetCrsrOfst( pShellCrsr
->GetPoint(), pShellCrsr
->GetPtPos(),
1253 if( pShellCrsr
->HasMark())
1254 pShellCrsr
->DeleteMark();
1256 IGrammarContact
*pGrammarContact
= GetDoc() ? GetDoc()->getGrammarContact() : 0;
1257 if( pGrammarContact
)
1258 pGrammarContact
->updateCursorPosition( *pCurCrsr
->GetPoint() );
1260 if( aOldSz
!= GetDocSize() )
1264 // JP 30.04.99: Bug 65475 - falls Point/Mark in versteckten Bereichen
1265 // stehen, so mussen diese daraus verschoben werden
1266 static void lcl_CheckHiddenSection( SwNodeIndex
& rIdx
)
1268 const SwSectionNode
* pSectNd
= rIdx
.GetNode().FindSectionNode();
1269 if( pSectNd
&& pSectNd
->GetSection().IsHiddenFlag() )
1271 SwNodeIndex
aTmp( *pSectNd
);
1272 #if OSL_DEBUG_LEVEL > 1
1273 const SwNode
* pFrmNd
=
1275 rIdx
.GetNodes().FindPrvNxtFrmNode( aTmp
, pSectNd
->EndOfSectionNode() );
1277 #if OSL_DEBUG_LEVEL > 1
1279 ASSERT( pFrmNd
, "keinen Node mit Frames gefunden" );
1285 // Try to set the cursor to the next visible content node.
1286 static void lcl_CheckHiddenPara( SwPosition
& rPos
)
1288 SwNodeIndex
aTmp( rPos
.nNode
);
1289 SwTxtNode
* pTxtNd
= aTmp
.GetNode().GetTxtNode();
1290 while( pTxtNd
&& pTxtNd
->HasHiddenCharAttribute( true ) )
1292 SwCntntNode
* pCntnt
= aTmp
.GetNodes().GoNext( &aTmp
);
1293 if ( pCntnt
&& pCntnt
->IsTxtNode() )
1294 pTxtNd
= (SwTxtNode
*)pCntnt
;
1300 rPos
= SwPosition( aTmp
, SwIndex( pTxtNd
, 0 ) );
1303 // --> OD 2005-12-14 #i27301# - helper class, which notifies the accessibility
1304 // about invalid text selections in its destructor
1305 class SwNotifyAccAboutInvalidTextSelections
1308 SwCrsrShell
& mrCrsrSh
;
1311 SwNotifyAccAboutInvalidTextSelections( SwCrsrShell
& _rCrsrSh
)
1312 : mrCrsrSh( _rCrsrSh
)
1315 ~SwNotifyAccAboutInvalidTextSelections()
1317 mrCrsrSh
.InvalidateAccessibleParaTextSelection();
1321 void SwCrsrShell::UpdateCrsr( USHORT eFlags
, BOOL bIdleEnd
)
1323 SET_CURR_SHELL( this );
1327 // erfrage den Count fuer die Start-/End-Actions und ob die Shell
1328 // ueberhaupt den Focus hat
1329 // if( ActionPend() /*|| !bHasFocus*/ )
1330 //JP 12.01.98: Bug #46496# - es muss innerhalb einer BasicAction der
1331 // Cursor geupdatet werden; um z.B. den TabellenCursor zu
1332 // erzeugen. Im EndAction wird jetzt das UpdateCrsr gerufen!
1333 if( ActionPend() && BasicActionPend() )
1335 if ( eFlags
& SwCrsrShell::READONLY
)
1336 bIgnoreReadonly
= TRUE
;
1337 return; // wenn nicht, dann kein Update !!
1340 // --> OD 2005-12-14 #i27301#
1341 SwNotifyAccAboutInvalidTextSelections
aInvalidateTextSelections( *this );
1344 if ( bIgnoreReadonly
)
1346 bIgnoreReadonly
= FALSE
;
1347 eFlags
|= SwCrsrShell::READONLY
;
1350 if( eFlags
& SwCrsrShell::CHKRANGE
) // alle Cursor-Bewegungen auf
1351 CheckRange( pCurCrsr
); // ueberlappende Bereiche testen
1356 // steht der akt. Crsr in einer Tabelle und in unterschiedlichen Boxen
1357 // (oder ist noch TabellenMode), dann gilt der Tabellen Mode
1358 SwPaM
* pTstCrsr
= getShellCrsr( true );
1359 if( pTstCrsr
->HasMark() && !pBlockCrsr
&&
1360 pDoc
->IsIdxInTbl( pTstCrsr
->GetPoint()->nNode
) &&
1362 pTstCrsr
->GetNode( TRUE
)->StartOfSectionNode() !=
1363 pTstCrsr
->GetNode( FALSE
)->StartOfSectionNode() ) )
1365 SwShellCrsr
* pITmpCrsr
= getShellCrsr( true );
1366 Point
aTmpPt( pITmpCrsr
->GetPtPos() );
1367 Point
aTmpMk( pITmpCrsr
->GetMkPos() );
1368 SwPosition
* pPos
= pITmpCrsr
->GetPoint();
1370 // JP 30.04.99: Bug 65475 - falls Point/Mark in versteckten Bereichen
1371 // stehen, so mussen diese daraus verschoben werden
1372 lcl_CheckHiddenSection( pPos
->nNode
);
1373 lcl_CheckHiddenSection( pITmpCrsr
->GetMark()->nNode
);
1375 // Move cursor out of hidden paragraphs
1376 if ( !GetViewOptions()->IsShowHiddenChar() )
1378 lcl_CheckHiddenPara( *pPos
);
1379 lcl_CheckHiddenPara( *pITmpCrsr
->GetMark() );
1382 SwCntntFrm
*pTblFrm
= pPos
->nNode
.GetNode().GetCntntNode()->
1383 GetFrm( &aTmpPt
, pPos
);
1385 ASSERT( pTblFrm
, "Tabelle Crsr nicht im Content ??" );
1387 // --> FME 2005-12-02 #126107# Make code robust. The table
1388 // cursor may point to a table in a currently inactive header.
1389 SwTabFrm
*pTab
= pTblFrm
? pTblFrm
->FindTabFrm() : 0;
1392 if ( pTab
&& pTab
->GetTable()->GetRowsToRepeat() > 0 )
1394 // First check if point is in repeated headline:
1395 bool bInRepeatedHeadline
= pTab
->IsFollow() && pTab
->IsInHeadline( *pTblFrm
);
1397 // Second check if mark is in repeated headline:
1398 if ( !bInRepeatedHeadline
)
1400 SwCntntFrm
* pMarkTblFrm
= pITmpCrsr
->GetCntntNode( FALSE
)->GetFrm( &aTmpMk
, pITmpCrsr
->GetMark() );
1401 ASSERT( pMarkTblFrm
, "Tabelle Crsr nicht im Content ??" );
1405 SwTabFrm
* pMarkTab
= pMarkTblFrm
->FindTabFrm();
1406 ASSERT( pMarkTab
, "Tabelle Crsr nicht im Content ??" );
1408 // --> FME 2005-11-28 #120360# Make code robust:
1411 bInRepeatedHeadline
= pMarkTab
->IsFollow() && pMarkTab
->IsInHeadline( *pMarkTblFrm
);
1417 // No table cursor in repeaded headlines:
1418 if ( bInRepeatedHeadline
)
1422 SwPosSection fnPosSect
= *pPos
< *pITmpCrsr
->GetMark()
1426 // dann nur innerhalb der Box selektieren
1429 pCurCrsr
->SetMark();
1430 *pCurCrsr
->GetMark() = *pTblCrsr
->GetMark();
1431 pCurCrsr
->GetMkPos() = pTblCrsr
->GetMkPos();
1432 pTblCrsr
->DeleteMark();
1433 pTblCrsr
->SwSelPaintRects::Hide();
1436 *pCurCrsr
->GetPoint() = *pCurCrsr
->GetMark();
1437 (*fnSectionCurr
)( *pCurCrsr
, fnPosSect
);
1441 // wir wollen wirklich eine Tabellen-Selektion
1442 if( pTab
&& pTblFrm
)
1446 pTblCrsr
= new SwShellTableCrsr( *this,
1447 *pCurCrsr
->GetMark(), pCurCrsr
->GetMkPos(),
1449 pCurCrsr
->DeleteMark();
1450 pCurCrsr
->SwSelPaintRects::Hide();
1455 SwCrsrMoveState
aTmpState( MV_NONE
);
1456 aTmpState
.bRealHeight
= TRUE
;
1457 if( !pTblFrm
->GetCharRect( aCharRect
, *pTblCrsr
->GetPoint(), &aTmpState
) )
1459 Point
aCentrPt( aCharRect
.Center() );
1460 aTmpState
.bSetInReadOnly
= IsReadOnlyAvailable();
1461 pTblFrm
->GetCrsrOfst( pTblCrsr
->GetPoint(), aCentrPt
, &aTmpState
);
1463 pTblFrm
->GetCharRect( aCharRect
, *pTblCrsr
->GetPoint() );
1465 if ( !pTblFrm
->GetCharRect( aCharRect
, *pTblCrsr
->GetPoint() ) )
1466 ASSERT( !this, "GetCharRect failed." );
1469 // ALIGNRECT( aCharRect );
1471 pVisCrsr
->Hide(); // sichtbaren Cursor immer verstecken
1472 // Curosr in den sichtbaren Bereich scrollen
1473 if( (eFlags
& SwCrsrShell::SCROLLWIN
) &&
1474 (HasSelection() || eFlags
& SwCrsrShell::READONLY
||
1475 !IsCrsrReadonly()) )
1477 SwFrm
* pBoxFrm
= pTblFrm
;
1478 while( pBoxFrm
&& !pBoxFrm
->IsCellFrm() )
1479 pBoxFrm
= pBoxFrm
->GetUpper();
1480 if( pBoxFrm
&& pBoxFrm
->Frm().HasArea() )
1481 MakeVisible( pBoxFrm
->Frm() );
1483 MakeVisible( aCharRect
);
1486 // lasse vom Layout die Crsr in den Boxen erzeugen
1487 if( pTblCrsr
->IsCrsrMovedUpdt() )
1488 GetLayout()->MakeTblCrsrs( *pTblCrsr
);
1489 if( bHasFocus
&& !bBasicHideCrsr
)
1492 // Cursor-Points auf die neuen Positionen setzen
1493 pTblCrsr
->GetPtPos().X() = aCharRect
.Left();
1494 pTblCrsr
->GetPtPos().Y() = aCharRect
.Top();
1498 aCrsrHeight
.X() = 0;
1499 aCrsrHeight
.Y() = aTmpState
.aRealHeight
.Y() < 0 ?
1500 -aCharRect
.Width() : aCharRect
.Height();
1501 pVisCrsr
->Show(); // wieder anzeigen
1503 eMvState
= MV_NONE
; // Status fuers Crsr-Travelling - GetCrsrOfst
1504 if( pTblFrm
&& Imp()->IsAccessible() )
1505 Imp()->InvalidateAccessibleCursorPosition( pTblFrm
);
1512 // Cursor Ring loeschen
1513 while( pCurCrsr
->GetNext() != pCurCrsr
)
1514 delete pCurCrsr
->GetNext();
1515 pCurCrsr
->DeleteMark();
1516 *pCurCrsr
->GetPoint() = *pTblCrsr
->GetPoint();
1517 pCurCrsr
->GetPtPos() = pTblCrsr
->GetPtPos();
1518 delete pTblCrsr
, pTblCrsr
= 0;
1521 pVisCrsr
->Hide(); // sichtbaren Cursor immer verstecken
1523 // sind wir vielleicht in einer geschuetzten/versteckten Section ?
1525 SwShellCrsr
* pShellCrsr
= getShellCrsr( true );
1526 BOOL bChgState
= TRUE
;
1527 const SwSectionNode
* pSectNd
= pShellCrsr
->GetNode()->FindSectionNode();
1528 if( pSectNd
&& ( pSectNd
->GetSection().IsHiddenFlag() ||
1529 ( !IsReadOnlyAvailable() &&
1530 pSectNd
->GetSection().IsProtectFlag() &&
1531 ( !pDoc
->GetDocShell() ||
1532 !pDoc
->GetDocShell()->IsReadOnly() || bAllProtect
)) ) )
1534 if( !FindValidCntntNode( !HasDrawView() ||
1535 0 == Imp()->GetDrawView()->GetMarkedObjectList().GetMarkCount()))
1537 // alles ist geschuetzt / versteckt -> besonderer Mode
1538 if( bAllProtect
&& !IsReadOnlyAvailable() &&
1539 pSectNd
->GetSection().IsProtectFlag() )
1543 eMvState
= MV_NONE
; // Status fuers Crsr-Travelling
1545 if( GetDoc()->GetDocShell() )
1547 GetDoc()->GetDocShell()->SetReadOnlyUI( TRUE
);
1548 CallChgLnk(); // UI bescheid sagen!
1556 BOOL bWasAllProtect
= bAllProtect
;
1557 bAllProtect
= FALSE
;
1558 if( bWasAllProtect
&& GetDoc()->GetDocShell() &&
1559 GetDoc()->GetDocShell()->IsReadOnlyUI() )
1561 GetDoc()->GetDocShell()->SetReadOnlyUI( FALSE
);
1562 CallChgLnk(); // UI bescheid sagen!
1569 // #100722# The cursor must always point into content; there's some code
1570 // that relies on this. (E.g. in SwEditShell::GetScriptType, which always
1571 // loops _behind_ the last node in the selection, which always works if you
1572 // are in content.) To achieve this, we'll force cursor(s) to point into
1573 // content, if UpdateCrsrPos() hasn't already done so.
1574 SwPaM
* pCmp
= pCurCrsr
;
1577 // start will move forwards, end will move backwards
1578 bool bPointIsStart
= ( pCmp
->Start() == pCmp
->GetPoint() );
1580 // move point; forward if it's the start, backwards if it's the end
1581 if( ! pCmp
->GetPoint()->nNode
.GetNode().IsCntntNode() )
1582 pCmp
->Move( bPointIsStart
? fnMoveForward
: fnMoveBackward
,
1585 // move mark (if exists); forward if it's the start, else backwards
1586 if( pCmp
->HasMark() )
1588 if( ! pCmp
->GetMark()->nNode
.GetNode().IsCntntNode() )
1591 pCmp
->Move( !bPointIsStart
? fnMoveForward
: fnMoveBackward
,
1597 // iterate to next PaM in ring
1598 pCmp
= static_cast<SwPaM
*>( pCmp
->GetNext() );
1600 while( pCmp
!= pCurCrsr
);
1603 SwRect
aOld( aCharRect
);
1607 SwShellCrsr
* pShellCrsr
= getShellCrsr( true );
1613 pFrm
= pShellCrsr
->GetCntntNode()->GetFrm(
1614 &pShellCrsr
->GetPtPos(), pShellCrsr
->GetPoint() );
1615 // ist der Frm nicht mehr vorhanden, dann muss das gesamte Layout
1616 // erzeugt werden, weil ja mal hier einer vorhanden war !!
1622 pFrm
= pShellCrsr
->GetCntntNode()->GetFrm(
1623 &pShellCrsr
->GetPtPos(), pShellCrsr
->GetPoint() );
1626 else if ( Imp()->IsIdleAction() )
1627 //Wir stellen sicher, dass anstaendig Formatiert wurde #42224#
1628 pFrm
->PrepareCrsr();
1630 // im geschuetzten Fly? aber bei Rahmenselektion ignorieren
1631 if( !IsReadOnlyAvailable() && pFrm
->IsProtected() &&
1632 ( !Imp()->GetDrawView() ||
1633 !Imp()->GetDrawView()->GetMarkedObjectList().GetMarkCount() ) &&
1634 (!pDoc
->GetDocShell() ||
1635 !pDoc
->GetDocShell()->IsReadOnly() || bAllProtect
) )
1637 // dann suche eine gueltige Position
1638 BOOL bChgState
= TRUE
;
1639 if( !FindValidCntntNode(!HasDrawView() ||
1640 0 == Imp()->GetDrawView()->GetMarkedObjectList().GetMarkCount()))
1642 // alles ist geschuetzt / versteckt -> besonderer Mode
1647 eMvState
= MV_NONE
; // Status fuers Crsr-Travelling
1649 if( GetDoc()->GetDocShell() )
1651 GetDoc()->GetDocShell()->SetReadOnlyUI( TRUE
);
1652 CallChgLnk(); // UI bescheid sagen!
1660 BOOL bWasAllProtect
= bAllProtect
;
1661 bAllProtect
= FALSE
;
1662 if( bWasAllProtect
&& GetDoc()->GetDocShell() &&
1663 GetDoc()->GetDocShell()->IsReadOnlyUI() )
1665 GetDoc()->GetDocShell()->SetReadOnlyUI( FALSE
);
1666 CallChgLnk(); // UI bescheid sagen!
1668 bAllProtect
= FALSE
;
1669 bAgainst
= TRUE
; // nochmal den richigen Frm suchen
1672 } while( bAgainst
);
1674 if( !( eFlags
& SwCrsrShell::NOCALRECT
))
1676 SwCrsrMoveState
aTmpState( eMvState
);
1677 aTmpState
.bSetInReadOnly
= IsReadOnlyAvailable();
1678 aTmpState
.bRealHeight
= TRUE
;
1679 aTmpState
.bRealWidth
= IsOverwriteCrsr();
1680 aTmpState
.nCursorBidiLevel
= pShellCrsr
->GetCrsrBidiLevel();
1682 // #i27615#,#i30453#
1683 SwSpecialPos aSpecialPos
;
1684 aSpecialPos
.nExtendRange
= SP_EXTEND_RANGE_BEFORE
;
1685 if (pShellCrsr
->IsInFrontOfLabel())
1687 aTmpState
.pSpecialPos
= &aSpecialPos
;
1690 if( !pFrm
->GetCharRect( aCharRect
, *pShellCrsr
->GetPoint(), &aTmpState
) )
1692 Point
& rPt
= pShellCrsr
->GetPtPos();
1693 rPt
= aCharRect
.Center();
1694 pFrm
->GetCrsrOfst( pShellCrsr
->GetPoint(), rPt
, &aTmpState
);
1696 // ALIGNRECT( aCharRect );
1698 if( !pShellCrsr
->HasMark() )
1699 aCrsrHeight
= aTmpState
.aRealHeight
;
1702 aCrsrHeight
.X() = 0;
1703 aCrsrHeight
.Y() = aTmpState
.aRealHeight
.Y() < 0 ?
1704 -aCharRect
.Width() : aCharRect
.Height();
1709 aCrsrHeight
.X() = 0;
1710 aCrsrHeight
.Y() = aCharRect
.Height();
1713 if( !bFirst
&& aOld
== aCharRect
)
1716 // falls das Layout meint, nach dem 100 durchlauf ist man immer noch
1717 // im Fluss, sollte man die akt. Pos. als gegeben hinnehmen!
1721 ASSERT( !this, "Endlosschleife? CharRect != OldCharRect ");
1727 // Cursor-Points auf die neuen Positionen setzen
1728 pShellCrsr
->GetPtPos().X() = aCharRect
.Left();
1729 pShellCrsr
->GetPtPos().Y() = aCharRect
.Top();
1731 if( !(eFlags
& SwCrsrShell::UPDOWN
)) // alte Pos. von Up/Down loeschen
1734 nUpDownX
= pFrm
->IsVertical() ?
1735 aCharRect
.Top() - pFrm
->Frm().Top() :
1736 aCharRect
.Left() - pFrm
->Frm().Left();
1739 // Curosr in den sichtbaren Bereich scrollen
1740 if( bHasFocus
&& eFlags
& SwCrsrShell::SCROLLWIN
&&
1741 (HasSelection() || eFlags
& SwCrsrShell::READONLY
||
1742 !IsCrsrReadonly() || GetViewOptions()->IsSelectionInReadonly()) )
1744 //JP 30.04.99: damit das EndAction, beim evtuellen Scrollen, den
1745 // SV-Crsr nicht wieder sichtbar macht, wird hier das Flag
1746 // gesichert und zurueckgesetzt.
1747 BOOL bSav
= bSVCrsrVis
; bSVCrsrVis
= FALSE
;
1752 } while( eFlags
& SwCrsrShell::SCROLLWIN
);
1755 RefreshBlockCursor();
1757 if( !bIdleEnd
&& bHasFocus
&& !bBasicHideCrsr
)
1760 pTblCrsr
->SwSelPaintRects::Show();
1763 pCurCrsr
->SwSelPaintRects::Show();
1766 SwShellCrsr
* pNxt
= dynamic_cast<SwShellCrsr
*>(pCurCrsr
->GetNext());
1767 while( pNxt
&& pNxt
!= pCurCrsr
)
1769 pNxt
->SwSelPaintRects::Show();
1770 pNxt
= dynamic_cast<SwShellCrsr
*>(pNxt
->GetNext());
1776 //Ggf. gescrollten Bereicht korrigieren (Alignment).
1777 //Nur wenn gescrollt wurde, und wenn keine Selektion existiert.
1778 if( pFrm
&& Imp()->IsScrolled() &&
1779 pShellCrsr
->GetNext() == pShellCrsr
&& !pShellCrsr
->HasMark() )
1780 Imp()->RefreshScrolledArea( aCharRect
);
1783 eMvState
= MV_NONE
; // Status fuers Crsr-Travelling - GetCrsrOfst
1785 if( pFrm
&& Imp()->IsAccessible() )
1786 Imp()->InvalidateAccessibleCursorPosition( pFrm
);
1788 // switch from blinking cursor to read-only-text-selection cursor
1789 static const long nNoBlinkTime
= STYLE_CURSOR_NOBLINKTIME
;
1790 const long nBlinkTime
= GetOut()->GetSettings().GetStyleSettings().
1791 GetCursorBlinkTime();
1793 if ( (IsCrsrReadonly() && GetViewOptions()->IsSelectionInReadonly()) ==
1794 ( nBlinkTime
!= nNoBlinkTime
) )
1796 // non blinking cursor in read only - text selection mode
1797 AllSettings aSettings
= GetOut()->GetSettings();
1798 StyleSettings aStyleSettings
= aSettings
.GetStyleSettings();
1799 const long nNewBlinkTime
= nBlinkTime
== nNoBlinkTime
?
1800 Application::GetSettings().GetStyleSettings().GetCursorBlinkTime() :
1802 aStyleSettings
.SetCursorBlinkTime( nNewBlinkTime
);
1803 aSettings
.SetStyleSettings( aStyleSettings
);
1804 GetOut()->SetSettings( aSettings
);
1808 pVisCrsr
->Show(); // wieder anzeigen
1811 void SwCrsrShell::RefreshBlockCursor()
1813 ASSERT( pBlockCrsr
, "Don't call me without a block cursor" );
1814 SwShellCrsr
&rBlock
= pBlockCrsr
->getShellCrsr();
1815 Point aPt
= rBlock
.GetPtPos();
1816 SwCntntFrm
* pFrm
= rBlock
.GetCntntNode()->GetFrm( &aPt
, rBlock
.GetPoint() );
1818 if( pBlockCrsr
->getEndPoint() && pBlockCrsr
->getStartPoint() )
1820 aPt
= *pBlockCrsr
->getStartPoint();
1821 aMk
= *pBlockCrsr
->getEndPoint();
1825 aPt
= rBlock
.GetPtPos();
1828 if( pFrm
->IsVertical() )
1829 aPt
.Y() = pFrm
->Frm().Top() + GetUpDownX();
1831 aPt
.X() = pFrm
->Frm().Left() + GetUpDownX();
1833 aMk
= rBlock
.GetMkPos();
1835 SwRect
aRect( aMk
, aPt
);
1837 SwSelectionList
aSelList( pFrm
);
1839 if( GetLayout()->FillSelection( aSelList
, aRect
) )
1841 SwCursor
* pNxt
= (SwCursor
*)pCurCrsr
->GetNext();
1842 while( pNxt
!= pCurCrsr
)
1845 pNxt
= (SwCursor
*)pCurCrsr
->GetNext();
1848 std::list
<SwPaM
*>::iterator pStart
= aSelList
.getStart();
1849 std::list
<SwPaM
*>::iterator pPam
= aSelList
.getEnd();
1850 ASSERT( pPam
!= pStart
, "FillSelection should deliver at least one PaM" )
1851 pCurCrsr
->SetMark();
1853 // If there is only one text portion inside the rectangle, a simple
1854 // selection is created
1855 if( pPam
== pStart
)
1857 *pCurCrsr
->GetPoint() = *(*pPam
)->GetPoint();
1858 if( (*pPam
)->HasMark() )
1859 *pCurCrsr
->GetMark() = *(*pPam
)->GetMark();
1861 pCurCrsr
->DeleteMark();
1863 pCurCrsr
->SetColumnSelection( false );
1867 // The order of the SwSelectionList has to be preserved but
1868 // the order inside the ring created by CreateCrsr() is not like
1869 // exspected => First create the selections before the last one
1870 // downto the first selection.
1871 // At least create the cursor for the last selection
1873 *pCurCrsr
->GetPoint() = *(*pPam
)->GetPoint(); // n-1 (if n == number of selections)
1874 if( (*pPam
)->HasMark() )
1875 *pCurCrsr
->GetMark() = *(*pPam
)->GetMark();
1877 pCurCrsr
->DeleteMark();
1879 pCurCrsr
->SetColumnSelection( true );
1880 while( pPam
!= pStart
)
1884 SwShellCrsr
* pNew
= new SwShellCrsr( *pCurCrsr
);
1885 pNew
->Insert( pCurCrsr
, 0 );
1886 pCurCrsr
->Remove( 0, pCurCrsr
->Count() );
1887 pCurCrsr
->DeleteMark();
1889 *pCurCrsr
->GetPoint() = *(*pPam
)->GetPoint(); // n-2, n-3, .., 2, 1
1890 if( (*pPam
)->HasMark() )
1892 pCurCrsr
->SetMark();
1893 *pCurCrsr
->GetMark() = *(*pPam
)->GetMark();
1896 pCurCrsr
->DeleteMark();
1897 pCurCrsr
->SetColumnSelection( true );
1901 SwShellCrsr
* pNew
= new SwShellCrsr( *pCurCrsr
);
1902 pNew
->Insert( pCurCrsr
, 0 );
1903 pCurCrsr
->Remove( 0, pCurCrsr
->Count() );
1904 pCurCrsr
->DeleteMark();
1906 pPam
= aSelList
.getEnd();
1908 *pCurCrsr
->GetPoint() = *(*pPam
)->GetPoint(); // n, the last selection
1909 if( (*pPam
)->HasMark() )
1911 pCurCrsr
->SetMark();
1912 *pCurCrsr
->GetMark() = *(*pPam
)->GetMark();
1915 pCurCrsr
->DeleteMark();
1916 pCurCrsr
->SetColumnSelection( true );
1922 // erzeuge eine Kopie vom Cursor und speicher diese im Stack
1925 void SwCrsrShell::Push()
1927 pCrsrStk
= new SwShellCrsr( *this, *pCurCrsr
->GetPoint(),
1928 pCurCrsr
->GetPtPos(), pCrsrStk
);
1930 if( pCurCrsr
->HasMark() )
1932 pCrsrStk
->SetMark();
1933 *pCrsrStk
->GetMark() = *pCurCrsr
->GetMark();
1938 * Loescht einen Cursor (gesteuert durch bOldCrsr)
1939 * - vom Stack oder ( bOldCrsr = TRUE )
1940 * - den aktuellen und der auf dem Stack stehende wird zum aktuellen
1942 * Return: es war auf dem Stack noch einer vorhanden
1946 BOOL
SwCrsrShell::Pop( BOOL bOldCrsr
)
1948 SwCallLink
aLk( *this ); // Crsr-Moves ueberwachen, evt. Link callen
1950 // noch weitere vorhanden ?
1954 SwShellCrsr
*pTmp
= 0, *pOldStk
= pCrsrStk
;
1956 // der Nachfolger wird der Aktuelle
1957 if( pCrsrStk
->GetNext() != pCrsrStk
)
1959 pTmp
= dynamic_cast<SwShellCrsr
*>(pCrsrStk
->GetNext());
1962 if( bOldCrsr
) // loesche vom Stack
1965 pCrsrStk
= pTmp
; // neu zuweisen
1969 SwCrsrSaveState
aSaveState( *pCurCrsr
);
1971 // wurde die sichtbare SSelection nicht veraendert
1972 if( pOldStk
->GetPtPos() == pCurCrsr
->GetPtPos() ||
1973 pOldStk
->GetPtPos() == pCurCrsr
->GetMkPos() )
1975 // "Selektions-Rechtecke" verschieben
1976 pCurCrsr
->Insert( pOldStk
, 0 );
1977 pOldStk
->Remove( 0, pOldStk
->Count() );
1980 if( pOldStk
->HasMark() )
1982 pCurCrsr
->SetMark();
1983 *pCurCrsr
->GetMark() = *pOldStk
->GetMark();
1984 pCurCrsr
->GetMkPos() = pOldStk
->GetMkPos();
1987 // keine Selection also alte aufheben und auf die alte Pos setzen
1988 pCurCrsr
->DeleteMark();
1989 *pCurCrsr
->GetPoint() = *pOldStk
->GetPoint();
1990 pCurCrsr
->GetPtPos() = pOldStk
->GetPtPos();
1993 if( !pCurCrsr
->IsInProtectTable( TRUE
) &&
1994 !pCurCrsr
->IsSelOvr( nsSwCursorSelOverFlags::SELOVER_TOGGLE
|
1995 nsSwCursorSelOverFlags::SELOVER_CHANGEPOS
) )
1996 UpdateCrsr(); // akt. Cursor Updaten
2002 * Verbinde zwei Cursor miteinander.
2003 * Loesche vom Stack den obersten und setzen dessen GetMark im Aktuellen.
2007 void SwCrsrShell::Combine()
2009 // noch weitere vorhanden ?
2013 SwCallLink
aLk( *this ); // Crsr-Moves ueberwachen, evt. Link callen
2014 SwCrsrSaveState
aSaveState( *pCurCrsr
);
2015 if( pCrsrStk
->HasMark() ) // nur wenn GetMark gesetzt wurde
2018 CheckNodesRange( pCrsrStk
->GetMark()->nNode
, pCurCrsr
->GetPoint()->nNode
, TRUE
);
2020 if( !CheckNodesRange( pCrsrStk
->GetMark()->nNode
, pCurCrsr
->GetPoint()->nNode
, TRUE
))
2021 ASSERT( !this, "StackCrsr & akt. Crsr nicht in gleicher Section." );
2023 // kopiere das GetMark
2024 if( !pCurCrsr
->HasMark() )
2025 pCurCrsr
->SetMark();
2026 *pCurCrsr
->GetMark() = *pCrsrStk
->GetMark();
2027 pCurCrsr
->GetMkPos() = pCrsrStk
->GetMkPos();
2030 SwShellCrsr
* pTmp
= 0;
2031 if( pCrsrStk
->GetNext() != pCrsrStk
)
2033 pTmp
= dynamic_cast<SwShellCrsr
*>(pCrsrStk
->GetNext());
2037 if( !pCurCrsr
->IsInProtectTable( TRUE
) &&
2038 !pCurCrsr
->IsSelOvr( nsSwCursorSelOverFlags::SELOVER_TOGGLE
|
2039 nsSwCursorSelOverFlags::SELOVER_CHANGEPOS
) )
2040 UpdateCrsr(); // akt. Cursor Updaten
2044 void SwCrsrShell::HideCrsrs()
2046 if( !bHasFocus
|| bBasicHideCrsr
)
2049 // ist Cursor sichtbar, dann verstecke den SV-Cursor
2050 if( pVisCrsr
->IsVisible() )
2052 SET_CURR_SHELL( this );
2055 // hebe die Invertierung der SSelection auf
2056 SwShellCrsr
* pAktCrsr
= pTblCrsr
? pTblCrsr
: pCurCrsr
;
2062 void SwCrsrShell::ShowCrsrs( BOOL bCrsrVis
)
2064 if( !bHasFocus
|| bAllProtect
|| bBasicHideCrsr
)
2067 SET_CURR_SHELL( this );
2068 SwShellCrsr
* pAktCrsr
= pTblCrsr
? pTblCrsr
: pCurCrsr
;
2071 if( bSVCrsrVis
&& bCrsrVis
) // auch SV-Cursor wieder anzeigen
2075 // Methoden zum Anzeigen bzw. Verstecken des sichtbaren Text-Cursors
2078 void SwCrsrShell::ShowCrsr()
2080 if( !bBasicHideCrsr
)
2088 void SwCrsrShell::HideCrsr()
2090 if( !bBasicHideCrsr
)
2093 // evt. die sel. Bereiche aufheben !!
2094 SET_CURR_SHELL( this );
2100 void SwCrsrShell::ShLooseFcs()
2102 if( !bBasicHideCrsr
)
2108 void SwCrsrShell::ShGetFcs( BOOL bUpdate
)
2111 if( !bBasicHideCrsr
&& VisArea().Width() )
2113 UpdateCrsr( static_cast<USHORT
>( bUpdate
?
2114 SwCrsrShell::CHKRANGE
|SwCrsrShell::SCROLLWIN
2115 : SwCrsrShell::CHKRANGE
) );
2116 ShowCrsrs( bSVCrsrVis
? TRUE
: FALSE
);
2120 // gebe den aktuellen Frame, in dem der Cursor steht, zurueck
2122 SwCntntFrm
*SwCrsrShell::GetCurrFrm( const BOOL bCalcFrm
) const
2124 SET_CURR_SHELL( (ViewShell
*)this );
2125 SwCntntFrm
*pRet
= 0;
2126 SwCntntNode
*pNd
= pCurCrsr
->GetCntntNode();
2131 const USHORT
* pST
= &nStartAction
;
2132 ++(*((USHORT
*)pST
));
2133 const Size
aOldSz( GetDocSize() );
2134 pRet
= pNd
->GetFrm( &pCurCrsr
->GetPtPos(), pCurCrsr
->GetPoint() );
2135 --(*((USHORT
*)pST
));
2136 if( aOldSz
!= GetDocSize() )
2137 ((SwCrsrShell
*)this)->SizeChgNotify();
2140 pRet
= pNd
->GetFrm( &pCurCrsr
->GetPtPos(), pCurCrsr
->GetPoint(), FALSE
);
2146 // alle Attribut/Format-Aenderungen am akt. Node werden an den
2147 // Link weitergeleitet.
2150 void SwCrsrShell::Modify( SfxPoolItem
* pOld
, SfxPoolItem
* pNew
)
2152 const USHORT nWhich
= pOld
?
2156 sal::static_int_cast
<USHORT
>(RES_MSG_BEGIN
);
2159 ( nWhich
< RES_MSG_BEGIN
|| nWhich
>= RES_MSG_END
||
2160 nWhich
== RES_FMT_CHG
|| nWhich
== RES_UPDATE_ATTR
||
2161 nWhich
== RES_ATTRSET_CHG
))
2162 // die Messages werden nicht weitergemeldet
2163 //MA 07. Apr. 94 fix(6681): RES_UPDATE_ATTR wird implizit vom
2164 //SwTxtNode::Insert(SwTxtHint*, USHORT) abgesetzt; hier wird reagiert und
2165 //vom Insert brauch nicht mehr die Keule RES_FMT_CHG versandt werden.
2168 if( aGrfArrivedLnk
.IsSet() &&
2169 ( RES_GRAPHIC_ARRIVED
== nWhich
|| RES_GRAPHIC_SWAPIN
== nWhich
))
2170 aGrfArrivedLnk
.Call( this );
2174 // Abfrage, ob der aktuelle Cursor eine Selektion aufspannt,
2175 // also, ob GetMark gesetzt und SPoint und GetMark unterschiedlich sind.
2178 BOOL
SwCrsrShell::HasSelection() const
2180 const SwPaM
* pCrsr
= getShellCrsr( true );
2181 return( IsTableMode() || ( pCrsr
->HasMark() &&
2182 *pCrsr
->GetPoint() != *pCrsr
->GetMark())
2187 void SwCrsrShell::CallChgLnk()
2189 // innerhalb von Start-/End-Action kein Call, sondern nur merken,
2190 // das sich etwas geaendert hat. Wird bei EndAction beachtet.
2191 if( BasicActionPend() )
2192 bChgCallFlag
= TRUE
; // das Change merken
2193 else if( aChgLnk
.IsSet() )
2196 aChgLnk
.Call( this );
2197 bChgCallFlag
= FALSE
; // Flag zuruecksetzen
2201 // returne den am akt.Cursor selektierten Text eines Nodes.
2204 String
SwCrsrShell::GetSelTxt() const
2207 if( pCurCrsr
->GetPoint()->nNode
.GetIndex() ==
2208 pCurCrsr
->GetMark()->nNode
.GetIndex() )
2210 SwTxtNode
* pTxtNd
= pCurCrsr
->GetNode()->GetTxtNode();
2213 xub_StrLen nStt
= pCurCrsr
->Start()->nContent
.GetIndex();
2214 aTxt
= pTxtNd
->GetExpandTxt( nStt
,
2215 pCurCrsr
->End()->nContent
.GetIndex() - nStt
);
2221 // gebe nur den Text ab der akt. Cursor Position zurueck (bis zum NodeEnde)
2224 String
SwCrsrShell::GetText() const
2227 if( pCurCrsr
->GetPoint()->nNode
.GetIndex() ==
2228 pCurCrsr
->GetMark()->nNode
.GetIndex() )
2230 SwTxtNode
* pTxtNd
= pCurCrsr
->GetNode()->GetTxtNode();
2232 aTxt
= pTxtNd
->GetTxt().Copy(
2233 pCurCrsr
->GetPoint()->nContent
.GetIndex() );
2238 // hole vom Start/Ende der akt. SSelection das nte Zeichen
2239 sal_Unicode
SwCrsrShell::GetChar( BOOL bEnd
, long nOffset
)
2241 if( IsTableMode() ) // im TabelleMode nicht moeglich
2244 const SwPosition
* pPos
= !pCurCrsr
->HasMark() ? pCurCrsr
->GetPoint()
2245 : bEnd
? pCurCrsr
->End() : pCurCrsr
->Start();
2246 SwTxtNode
* pTxtNd
= pPos
->nNode
.GetNode().GetTxtNode();
2250 xub_StrLen nPos
= pPos
->nContent
.GetIndex();
2251 const String
& rStr
= pTxtNd
->GetTxt();
2252 sal_Unicode cCh
= 0;
2254 if( ((nPos
+nOffset
) >= 0 ) && (nPos
+nOffset
) < rStr
.Len() )
2255 cCh
= rStr
.GetChar( static_cast<xub_StrLen
>(nPos
+nOffset
) );
2260 // erweiter die akt. SSelection am Anfang/Ende um n Zeichen
2263 BOOL
SwCrsrShell::ExtendSelection( BOOL bEnd
, xub_StrLen nCount
)
2265 if( !pCurCrsr
->HasMark() || IsTableMode() )
2266 return FALSE
; // keine Selektion
2268 SwPosition
* pPos
= bEnd
? pCurCrsr
->End() : pCurCrsr
->Start();
2269 SwTxtNode
* pTxtNd
= pPos
->nNode
.GetNode().GetTxtNode();
2270 ASSERT( pTxtNd
, "kein TextNode, wie soll erweitert werden?" );
2272 xub_StrLen nPos
= pPos
->nContent
.GetIndex();
2275 if( ( nPos
+ nCount
) <= pTxtNd
->GetTxt().Len() )
2276 nPos
= nPos
+ nCount
;
2278 return FALSE
; // nicht mehr moeglich
2280 else if( nPos
>= nCount
)
2281 nPos
= nPos
- nCount
;
2283 return FALSE
; // nicht mehr moeglich
2285 SwCallLink
aLk( *this ); // Crsr-Moves ueberwachen,
2287 pPos
->nContent
= nPos
;
2293 // setze nur den sichtbaren Cursor an die angegebene Dokument-Pos.
2294 // returnt FALSE: wenn der SPoint vom Layout korrigiert wurde.
2296 BOOL
SwCrsrShell::SetVisCrsr( const Point
&rPt
)
2298 SET_CURR_SHELL( this );
2300 SwPosition
aPos( *pCurCrsr
->GetPoint() );
2301 SwCrsrMoveState
aTmpState( MV_SETONLYTEXT
);
2302 aTmpState
.bSetInReadOnly
= IsReadOnlyAvailable();
2303 aTmpState
.bRealHeight
= TRUE
;
2305 BOOL bRet
= GetLayout()->GetCrsrOfst( &aPos
, aPt
/*, &aTmpState*/ );
2307 SetInFrontOfLabel( FALSE
); // #i27615#
2309 // nur in TextNodes anzeigen !!
2310 SwTxtNode
* pTxtNd
= aPos
.nNode
.GetNode().GetTxtNode();
2314 const SwSectionNode
* pSectNd
= pTxtNd
->FindSectionNode();
2315 if( pSectNd
&& (pSectNd
->GetSection().IsHiddenFlag() ||
2316 ( !IsReadOnlyAvailable() &&
2317 pSectNd
->GetSection().IsProtectFlag())) )
2320 SwCntntFrm
*pFrm
= pTxtNd
->GetFrm( &aPt
, &aPos
);
2321 if ( Imp()->IsIdleAction() )
2322 pFrm
->PrepareCrsr();
2323 SwRect
aTmp( aCharRect
);
2325 pFrm
->GetCharRect( aCharRect
, aPos
, &aTmpState
);
2326 // ALIGNRECT( aCharRect );
2328 if( aTmp
== aCharRect
&& // BUG 10137: bleibt der Cursor auf der
2329 pVisCrsr
->IsVisible() ) // Position nicht hidden & showen
2332 pVisCrsr
->Hide(); // sichtbaren Cursor immer verstecken
2333 if( IsScrollMDI( this, aCharRect
))
2335 MakeVisible( aCharRect
);
2339 // Bug 29584: bei Rahmenselektion ist der Cursor versteckt, aber den
2340 // D&D-Cursor will man trotzdem haben
2343 if( aTmpState
.bRealHeight
)
2344 aCrsrHeight
= aTmpState
.aRealHeight
;
2347 aCrsrHeight
.X() = 0;
2348 aCrsrHeight
.Y() = aCharRect
.Height();
2351 pVisCrsr
->SetDragCrsr( TRUE
);
2352 pVisCrsr
->Show(); // wieder anzeigen
2357 BOOL
SwCrsrShell::IsOverReadOnlyPos( const Point
& rPt
) const
2360 SwPaM
aPam( *pCurCrsr
->GetPoint() );
2361 GetLayout()->GetCrsrOfst( aPam
.GetPoint(), aPt
);
2362 // --> FME 2004-06-29 #114856# Formular view
2363 return aPam
.HasReadonlySel( GetViewOptions()->IsFormView() );
2368 // returne die Anzahl der Cursor im Ring (Flag besagt ob man nur
2369 // aufgepspannte haben will - sprich etwas selektiert ist (Basic))
2370 USHORT
SwCrsrShell::GetCrsrCnt( BOOL bAll
) const
2372 Ring
* pTmp
= GetCrsr()->GetNext();
2373 USHORT n
= (bAll
|| ( pCurCrsr
->HasMark() &&
2374 *pCurCrsr
->GetPoint() != *pCurCrsr
->GetMark())) ? 1 : 0;
2375 while( pTmp
!= pCurCrsr
)
2377 if( bAll
|| ( ((SwPaM
*)pTmp
)->HasMark() &&
2378 *((SwPaM
*)pTmp
)->GetPoint() != *((SwPaM
*)pTmp
)->GetMark()))
2380 pTmp
= pTmp
->GetNext();
2386 BOOL
SwCrsrShell::IsStartOfDoc() const
2388 if( pCurCrsr
->GetPoint()->nContent
.GetIndex() )
2391 // Hinter EndOfIcons kommt die Content-Section (EndNd+StNd+CntntNd)
2392 SwNodeIndex
aIdx( GetDoc()->GetNodes().GetEndOfExtras(), 2 );
2393 if( !aIdx
.GetNode().IsCntntNode() )
2394 GetDoc()->GetNodes().GoNext( &aIdx
);
2395 return aIdx
== pCurCrsr
->GetPoint()->nNode
;
2399 BOOL
SwCrsrShell::IsEndOfDoc() const
2401 SwNodeIndex
aIdx( GetDoc()->GetNodes().GetEndOfContent(), -1 );
2402 SwCntntNode
* pCNd
= aIdx
.GetNode().GetCntntNode();
2404 pCNd
= GetDoc()->GetNodes().GoPrevious( &aIdx
);
2406 return aIdx
== pCurCrsr
->GetPoint()->nNode
&&
2407 pCNd
->Len() == pCurCrsr
->GetPoint()->nContent
.GetIndex();
2411 // loesche alle erzeugten Crsr, setze den Tabellen-Crsr und den letzten
2412 // Cursor auf seinen TextNode (oder StartNode?).
2413 // Beim naechsten ::GetCrsr werden sie wieder alle erzeugt
2414 // Wird fuers Drag&Drop / ClipBorad-Paste in Tabellen benoetigt.
2415 BOOL
SwCrsrShell::ParkTblCrsr()
2420 pTblCrsr
->ParkCrsr();
2422 while( pCurCrsr
->GetNext() != pCurCrsr
)
2423 delete pCurCrsr
->GetNext();
2425 // vom Cursor !immer! SPoint und Mark umsetzen
2426 pCurCrsr
->SetMark();
2427 *pCurCrsr
->GetMark() = *pCurCrsr
->GetPoint() = *pTblCrsr
->GetPoint();
2428 pCurCrsr
->DeleteMark();
2433 /***********************************************************************
2434 #* Class : SwCrsrShell
2435 #* Methode : ParkCrsr
2436 #* Beschreibung: Vernichtet Selektionen und zus. Crsr aller Shell der
2437 #* verbleibende Crsr der Shell wird geparkt.
2438 #* Datum : MA 05. Nov. 92
2439 #* Update : JP 19.09.97
2440 #***********************************************************************/
2442 void SwCrsrShell::_ParkPams( SwPaM
* pDelRg
, SwShellCrsr
** ppDelRing
)
2444 const SwPosition
*pStt
= pDelRg
->Start(),
2445 *pEnd
= pDelRg
->GetPoint() == pStt
? pDelRg
->GetMark() : pDelRg
->GetPoint();
2447 SwPaM
*pTmpDel
= 0, *pTmp
= *ppDelRing
;
2449 // durchsuche den gesamten Ring
2452 const SwPosition
*pTmpStt
= pTmp
->Start(),
2453 *pTmpEnd
= pTmp
->GetPoint() == pTmpStt
?
2454 pTmp
->GetMark() : pTmp
->GetPoint();
2456 * liegt ein SPoint oder GetMark innerhalb vom Crsr-Bereich
2457 * muss der alte Bereich aufgehoben werden.
2458 * Beim Vergleich ist darauf zu achten, das End() nicht mehr zum
2461 if( *pStt
<= *pTmpStt
)
2463 if( *pEnd
> *pTmpStt
||
2464 ( *pEnd
== *pTmpStt
&& *pEnd
== *pTmpEnd
))
2468 if( *pStt
< *pTmpEnd
)
2472 if( pTmpDel
) // ist der Pam im Bereich ?? loesche ihn
2474 BOOL bDelete
= TRUE
;
2475 if( *ppDelRing
== pTmpDel
)
2477 if( *ppDelRing
== pCurCrsr
)
2479 if( TRUE
== ( bDelete
= GoNextCrsr() ))
2482 pTmp
= (SwPaM
*)pTmp
->GetNext();
2486 bDelete
= FALSE
; // StackCrsr nie loeschen !!
2490 delete pTmpDel
; // hebe alten Bereich auf
2493 pTmpDel
->GetPoint()->nContent
.Assign( 0, 0 );
2494 pTmpDel
->GetPoint()->nNode
= 0;
2496 pTmpDel
->DeleteMark();
2500 else if( !pTmp
->HasMark() ) // sorge auf jedenfall dafuer, das
2501 { // nicht benutzte Indizies beachtet werden!
2502 pTmp
->SetMark(); // SPoint liegt nicht im Bereich,
2503 pTmp
->DeleteMark(); // aber vielleicht GetMark, also setzen
2506 pTmp
= (SwPaM
*)pTmp
->GetNext();
2507 } while( !bGoNext
|| *ppDelRing
!= pTmp
);
2510 void SwCrsrShell::ParkCrsr( const SwNodeIndex
&rIdx
)
2512 SwNode
*pNode
= &rIdx
.GetNode();
2514 // erzeuge einen neuen Pam
2515 SwPaM
* pNew
= new SwPaM( *GetCrsr()->GetPoint() );
2516 if( pNode
->GetStartNode() )
2518 if( ( pNode
= pNode
->StartOfSectionNode())->IsTableNode() )
2520 // der angegebene Node steht in einer Tabelle, also Parke
2521 // den Crsr auf dem Tabellen-Node (ausserhalb der Tabelle)
2522 pNew
->GetPoint()->nNode
= *pNode
->StartOfSectionNode();
2524 else // also auf dem StartNode selbst.
2525 // Dann immer ueber seinen EndNode den StartNode erfragen !!!
2526 // (StartOfSection vom StartNode ist der Parent !)
2527 pNew
->GetPoint()->nNode
= *pNode
->EndOfSectionNode()->StartOfSectionNode();
2530 pNew
->GetPoint()->nNode
= *pNode
->StartOfSectionNode();
2532 pNew
->GetPoint()->nNode
= *pNode
->EndOfSectionNode();
2534 //Alle Shells wollen etwas davon haben.
2535 ViewShell
*pTmp
= this;
2537 if( pTmp
->IsA( TYPE( SwCrsrShell
)))
2539 SwCrsrShell
* pSh
= (SwCrsrShell
*)pTmp
;
2541 pSh
->_ParkPams( pNew
, &pSh
->pCrsrStk
);
2543 pSh
->_ParkPams( pNew
, &pSh
->pCurCrsr
);
2546 // setze den Tabellen Cursor immer auf 0, den aktuellen
2547 // immer auf den Anfang der Tabelle
2548 SwPaM
* pTCrsr
= pSh
->GetTblCrs();
2549 SwNode
* pTblNd
= pTCrsr
->GetPoint()->nNode
.GetNode().FindTableNode();
2552 pTCrsr
->GetPoint()->nContent
.Assign( 0, 0 );
2553 pTCrsr
->GetPoint()->nNode
= 0;
2555 pTCrsr
->DeleteMark();
2556 pSh
->pCurCrsr
->GetPoint()->nNode
= *pTblNd
;
2560 } while ( this != (pTmp
= (ViewShell
*)pTmp
->GetNext() ));
2564 //=========================================================================
2567 * der Copy-Constructor
2568 * Cursor-Position kopieren, in den Ring eingetragen.
2569 * Alle Ansichten eines Dokumentes stehen im Ring der Shells.
2572 SwCrsrShell::SwCrsrShell( SwCrsrShell
& rShell
, Window
*pInitWin
)
2573 : ViewShell( rShell
, pInitWin
),
2574 SwModify( 0 ), pCrsrStk( 0 ), pBlockCrsr( 0 ), pTblCrsr( 0 ),
2575 pBoxIdx( 0 ), pBoxPtr( 0 ), nCrsrMove( 0 ), nBasicActionCnt( 0 ),
2576 eMvState( MV_NONE
),
2577 // --> OD 2008-04-02 #refactorlists#
2579 nMarkedListLevel( 0 )
2582 SET_CURR_SHELL( this );
2583 // Nur die Position vom aktuellen Cursor aus der Copy-Shell uebernehmen
2584 pCurCrsr
= new SwShellCrsr( *this, *(rShell
.pCurCrsr
->GetPoint()) );
2585 pCurCrsr
->GetCntntNode()->Add( this );
2587 bAllProtect
= bVisPortChgd
= bChgCallFlag
= bInCMvVisportChgd
=
2588 bGCAttr
= bIgnoreReadonly
= bSelTblCells
= bBasicHideCrsr
=
2589 bOverwriteCrsr
= FALSE
;
2590 bCallChgLnk
= bHasFocus
= bSVCrsrVis
= bAutoUpdateCells
= TRUE
;
2591 bSetCrsrInReadOnly
= TRUE
;
2592 pVisCrsr
= new SwVisCrsr( this );
2594 // OD 11.02.2003 #100556#
2595 mbMacroExecAllowed
= rShell
.IsMacroExecAllowed();
2600 * der normale Constructor
2603 SwCrsrShell::SwCrsrShell( SwDoc
& rDoc
, Window
*pInitWin
,
2604 const SwViewOption
*pInitOpt
)
2605 : ViewShell( rDoc
, pInitWin
, pInitOpt
),
2606 SwModify( 0 ), pCrsrStk( 0 ), pBlockCrsr( 0 ), pTblCrsr( 0 ),
2607 pBoxIdx( 0 ), pBoxPtr( 0 ), nCrsrMove( 0 ), nBasicActionCnt( 0 ),
2608 eMvState( MV_NONE
), // state for crsr-travelling - GetCrsrOfst
2609 // --> OD 2008-04-02 #refactorlists#
2611 nMarkedListLevel( 0 )
2614 SET_CURR_SHELL( this );
2616 * Erzeugen des initialen Cursors, wird auf die erste
2617 * Inhaltsposition gesetzt
2619 SwNodes
& rNds
= rDoc
.GetNodes();
2621 SwNodeIndex
aNodeIdx( *rNds
.GetEndOfContent().StartOfSectionNode() );
2622 SwCntntNode
* pCNd
= rNds
.GoNext( &aNodeIdx
); // gehe zum 1. ContentNode
2624 pCurCrsr
= new SwShellCrsr( *this, SwPosition( aNodeIdx
, SwIndex( pCNd
, 0 )));
2626 // melde die Shell beim akt. Node als abhaengig an, dadurch koennen alle
2627 // Attribut-Aenderungen ueber den Link weiter gemeldet werden.
2630 bAllProtect
= bVisPortChgd
= bChgCallFlag
= bInCMvVisportChgd
=
2631 bGCAttr
= bIgnoreReadonly
= bSelTblCells
= bBasicHideCrsr
=
2632 bOverwriteCrsr
= FALSE
;
2633 bCallChgLnk
= bHasFocus
= bSVCrsrVis
= bAutoUpdateCells
= TRUE
;
2634 bSetCrsrInReadOnly
= TRUE
;
2636 pVisCrsr
= new SwVisCrsr( this );
2638 // OD 11.02.2003 #100556#
2639 mbMacroExecAllowed
= true;
2644 SwCrsrShell::~SwCrsrShell()
2646 // wenn es nicht die letzte View so sollte zu mindest das
2647 // Feld noch geupdatet werden.
2648 if( GetNext() != this )
2649 CheckTblBoxCntnt( pCurCrsr
->GetPoint() );
2658 * Freigabe der Cursor
2660 while(pCurCrsr
->GetNext() != pCurCrsr
)
2661 delete pCurCrsr
->GetNext();
2667 while( pCrsrStk
->GetNext() != pCrsrStk
)
2668 delete pCrsrStk
->GetNext();
2672 // JP 27.07.98: Bug 54025 - ggfs. den HTML-Parser, der als Client in
2673 // der CursorShell haengt keine Chance geben, sich an den
2674 // TextNode zu haengen.
2675 if( GetRegisteredIn() )
2676 pRegisteredIn
->Remove( this );
2679 SwShellCrsr
* SwCrsrShell::getShellCrsr( bool bBlock
)
2683 if( pBlockCrsr
&& bBlock
)
2684 return &pBlockCrsr
->getShellCrsr();
2688 //Sollte fuer das Clipboard der WaitPtr geschaltet werden?
2689 //Warten bei TableMode, Mehrfachselektion und mehr als x Selektieren Absaetzen.
2691 BOOL
SwCrsrShell::ShouldWait() const
2693 if ( IsTableMode() || GetCrsrCnt() > 1 )
2696 if( HasDrawView() && GetDrawView()->GetMarkedObjectList().GetMarkCount() )
2699 SwPaM
* pPam
= GetCrsr();
2700 return pPam
->Start()->nNode
.GetIndex() + 10 <
2701 pPam
->End()->nNode
.GetIndex();
2705 USHORT
SwCrsrShell::UpdateTblSelBoxes()
2707 if( pTblCrsr
&& ( pTblCrsr
->IsChgd() || !pTblCrsr
->GetBoxesCount() ))
2708 GetLayout()->MakeTblCrsrs( *pTblCrsr
);
2709 return pTblCrsr
? pTblCrsr
->GetBoxesCount() : 0;
2712 // zeige das akt. selektierte "Object" an
2713 void SwCrsrShell::MakeSelVisible()
2715 ASSERT( bHasFocus
, "kein Focus aber Cursor sichtbar machen?" );
2716 if( aCrsrHeight
.Y() < aCharRect
.Height() && aCharRect
.Height() > VisArea().Height() )
2718 SwRect
aTmp( aCharRect
);
2719 long nDiff
= aCharRect
.Height() - VisArea().Height();
2720 if( nDiff
< aCrsrHeight
.X() )
2721 aTmp
.Top( nDiff
+ aCharRect
.Top() );
2724 aTmp
.Top( aCrsrHeight
.X() + aCharRect
.Top() );
2725 aTmp
.Height( aCrsrHeight
.Y() );
2727 if( !aTmp
.HasArea() )
2729 aTmp
.SSize().Height() += 1;
2730 aTmp
.SSize().Width() += 1;
2732 MakeVisible( aTmp
);
2736 if( aCharRect
.HasArea() )
2737 MakeVisible( aCharRect
);
2740 SwRect
aTmp( aCharRect
);
2741 aTmp
.SSize().Height() += 1; aTmp
.SSize().Width() += 1;
2742 MakeVisible( aTmp
);
2748 // suche eine gueltige ContentPosition (nicht geschuetzt/nicht versteckt)
2749 BOOL
SwCrsrShell::FindValidCntntNode( BOOL bOnlyText
)
2751 if( pTblCrsr
) // was soll ich jetzt machen ??
2753 ASSERT( !this, "TabellenSelection nicht aufgehoben!" );
2757 //JP 28.10.97: Bug 45129 - im UI-ReadOnly ist alles erlaubt
2758 if( !bAllProtect
&& GetDoc()->GetDocShell() &&
2759 GetDoc()->GetDocShell()->IsReadOnlyUI() )
2763 if( pCurCrsr
->HasMark() )
2766 // als erstes mal auf Rahmen abpruefen
2767 SwNodeIndex
& rNdIdx
= pCurCrsr
->GetPoint()->nNode
;
2768 ULONG nNdIdx
= rNdIdx
.GetIndex(); // sichern
2769 SwNodes
& rNds
= pDoc
->GetNodes();
2770 SwCntntNode
* pCNd
= rNdIdx
.GetNode().GetCntntNode();
2771 const SwCntntFrm
* pFrm
;
2773 if( pCNd
&& 0 != (pFrm
= pCNd
->GetFrm(0,pCurCrsr
->GetPoint(),FALSE
)) &&
2774 !IsReadOnlyAvailable() && pFrm
->IsProtected() &&
2775 nNdIdx
< rNds
.GetEndOfExtras().GetIndex() )
2777 // geschuetzter Rahmen ueberspringen
2778 SwPaM
aPam( *pCurCrsr
->GetPoint() );
2780 aPam
.GetMark()->nNode
= rNds
.GetEndOfContent();
2781 aPam
.GetPoint()->nNode
= *pCNd
->EndOfSectionNode();
2783 BOOL bFirst
= FALSE
;
2784 if( 0 == (pCNd
= ::GetNode( aPam
, bFirst
, fnMoveForward
, FALSE
)))
2786 aPam
.GetMark()->nNode
= *rNds
.GetEndOfPostIts().StartOfSectionNode();
2787 pCNd
= ::GetNode( aPam
, bFirst
, fnMoveBackward
, FALSE
);
2790 if( !pCNd
) // sollte nie passieren !!!
2792 rNdIdx
= nNdIdx
; // alten Node zurueck
2795 *pCurCrsr
->GetPoint() = *aPam
.GetPoint();
2797 else if( bOnlyText
&& pCNd
&& pCNd
->IsNoTxtNode() )
2799 // dann auf den Anfang vom Doc stellen
2800 rNdIdx
= pDoc
->GetNodes().GetEndOfExtras();
2801 pCurCrsr
->GetPoint()->nContent
.Assign( pDoc
->GetNodes().GoNext(
2803 nNdIdx
= rNdIdx
.GetIndex();
2808 // #i9059# cursor may not stand in protected cells
2809 // (unless cursor in protected areas is OK.)
2810 const SwTableNode
* pTableNode
= rNdIdx
.GetNode().FindTableNode();
2811 if( !IsReadOnlyAvailable() &&
2812 pTableNode
!= NULL
&& rNdIdx
.GetNode().IsProtect() )
2814 // we're in a table, and we're in a protected area, so we're
2815 // probably in a protected cell.
2817 // move forward into non-protected area.
2818 SwPaM
aPam( rNdIdx
.GetNode(), 0 );
2819 while( aPam
.GetNode()->IsProtect() &&
2820 aPam
.Move( fnMoveForward
, fnGoCntnt
) )
2821 ; // nothing to do in the loop; the aPam.Move does the moving!
2823 // didn't work? then go backwards!
2824 if( aPam
.GetNode()->IsProtect() )
2826 SwPaM
aTmpPaM( rNdIdx
.GetNode(), 0 );
2828 while( aPam
.GetNode()->IsProtect() &&
2829 aPam
.Move( fnMoveBackward
, fnGoCntnt
) )
2830 ; // nothing to do in the loop; the aPam.Move does the moving!
2833 // if we're successful, set the new position
2834 if( ! aPam
.GetNode()->IsProtect() )
2836 *pCurCrsr
->GetPoint() = *aPam
.GetPoint();
2840 // in einem geschuetzten Bereich
2841 const SwSectionNode
* pSectNd
= rNdIdx
.GetNode().FindSectionNode();
2842 if( pSectNd
&& ( pSectNd
->GetSection().IsHiddenFlag() ||
2843 ( !IsReadOnlyAvailable() &&
2844 pSectNd
->GetSection().IsProtectFlag() )) )
2846 typedef SwCntntNode
* (SwNodes:: *FNGoSection
)( SwNodeIndex
*, int, int ) const;
2847 FNGoSection funcGoSection
= &SwNodes::GoNextSection
;
2851 for( int nLoopCnt
= 0; !bOk
&& nLoopCnt
< 2; ++nLoopCnt
)
2856 while( 0 != ( pCNd
= (rNds
.*funcGoSection
)( &rNdIdx
,
2857 TRUE
, !IsReadOnlyAvailable() )) )
2859 // in eine Tabelle verschoben -> pruefe ob die
2860 // vielleicht geschuetzt ist
2861 if( pCNd
->FindTableNode() )
2863 SwCallLink
aTmp( *this );
2864 SwCrsrSaveState
aSaveState( *pCurCrsr
);
2865 aTmp
.nNdTyp
= 0; // im DTOR nichts machen!
2866 if( !pCurCrsr
->IsInProtectTable( TRUE
, TRUE
) )
2868 const SwSectionNode
* pSNd
= pCNd
->FindSectionNode();
2869 if( !pSNd
|| !pSNd
->GetSection().IsHiddenFlag()
2870 || (!IsReadOnlyAvailable() &&
2871 pSNd
->GetSection().IsProtectFlag() ))
2874 break; // eine nicht geschuetzte Zelle gef.
2876 continue; // dann weiter suchen
2882 break; // eine nicht geschuetzte Zelle gef.
2886 if( bOk
&& rNdIdx
.GetIndex() < rNds
.GetEndOfExtras().GetIndex() )
2888 // Teste mal auf Fly - kann auch noch geschuetzt sein!!
2889 if( 0 == (pFrm
= pCNd
->GetFrm(0,0,FALSE
)) ||
2890 ( !IsReadOnlyAvailable() && pFrm
->IsProtected() ) ||
2891 ( bOnlyText
&& pCNd
->IsNoTxtNode() ) )
2893 // dann weiter suchen!
2903 funcGoSection
= &SwNodes::GoPrevSection
;
2910 pCNd
= rNdIdx
.GetNode().GetCntntNode();
2911 // USHORT nCntnt = Min( pCNd->Len(), pCurCrsr->GetPoint()->nContent.GetIndex() );
2912 xub_StrLen nCntnt
= rNdIdx
.GetIndex() < nNdIdx
? pCNd
->Len() : 0;
2913 pCurCrsr
->GetPoint()->nContent
.Assign( pCNd
, nCntnt
);
2917 pCNd
= rNdIdx
.GetNode().GetCntntNode();
2919 // falls Cursor im versteckten Bereich ist, auf jedenfall schon mal
2921 if( !pCNd
|| !pCNd
->GetFrm(0,0,FALSE
) )
2923 SwCrsrMoveState
aTmpState( MV_NONE
);
2924 aTmpState
.bSetInReadOnly
= IsReadOnlyAvailable();
2925 GetLayout()->GetCrsrOfst( pCurCrsr
->GetPoint(), pCurCrsr
->GetPtPos(),
2933 void SwCrsrShell::NewCoreSelection()
2938 BOOL
SwCrsrShell::IsCrsrReadonly() const
2940 if ( GetViewOptions()->IsReadonly() ||
2941 // --> FME 2004-06-29 #114856# Formular view
2942 GetViewOptions()->IsFormView() )
2945 SwFrm
*pFrm
= GetCurrFrm( FALSE
);
2946 const SwFlyFrm
* pFly
;
2947 const SwSection
* pSection
;
2949 if( pFrm
&& pFrm
->IsInFly() &&
2950 (pFly
= pFrm
->FindFlyFrm())->GetFmt()->GetEditInReadonly().GetValue() &&
2952 !pFly
->Lower()->IsNoTxtFrm() &&
2953 !GetDrawView()->GetMarkedObjectList().GetMarkCount() )
2957 // --> FME 2004-06-22 #114856# edit in readonly sections
2958 else if ( pFrm
&& pFrm
->IsInSct() &&
2959 0 != ( pSection
= pFrm
->FindSctFrm()->GetSection() ) &&
2960 pSection
->IsEditInReadonlyFlag() )
2972 // darf der Cursor in ReadOnlyBereiche?
2973 void SwCrsrShell::SetReadOnlyAvailable( BOOL bFlag
)
2975 // im GlobalDoc darf NIE umgeschaltet werden
2976 if( (!GetDoc()->GetDocShell() ||
2977 !GetDoc()->GetDocShell()->IsA( SwGlobalDocShell::StaticType() )) &&
2978 bFlag
!= bSetCrsrInReadOnly
)
2980 // wenn das Flag ausgeschaltet wird, dann muessen erstmal alle
2981 // Selektionen aufgehoben werden. Denn sonst wird sich darauf
2982 // verlassen, das nichts geschuetztes selektiert ist!
2987 bSetCrsrInReadOnly
= bFlag
;
2992 BOOL
SwCrsrShell::HasReadonlySel() const
2995 if( IsReadOnlyAvailable() ||
2996 // --> FME 2004-06-29 #114856# Formular view
2997 GetViewOptions()->IsFormView() )
3001 bRet
= pTblCrsr
->HasReadOnlyBoxSel() ||
3002 pTblCrsr
->HasReadonlySel(
3003 // --> FME 2004-06-29 #114856# Formular view
3004 GetViewOptions()->IsFormView() );
3008 const SwPaM
* pCrsr
= pCurCrsr
;
3011 if( pCrsr
->HasReadonlySel(
3012 // --> FME 2004-06-29 #114856# Formular view
3013 GetViewOptions()->IsFormView() ) )
3016 } while( !bRet
&& pCurCrsr
!= ( pCrsr
= (SwPaM
*)pCrsr
->GetNext() ));
3022 BOOL
SwCrsrShell::IsSelFullPara() const
3026 if( pCurCrsr
->GetPoint()->nNode
.GetIndex() ==
3027 pCurCrsr
->GetMark()->nNode
.GetIndex() && pCurCrsr
== pCurCrsr
->GetNext() )
3029 xub_StrLen nStt
= pCurCrsr
->GetPoint()->nContent
.GetIndex(),
3030 nEnd
= pCurCrsr
->GetMark()->nContent
.GetIndex();
3033 xub_StrLen nTmp
= nStt
;
3037 const SwCntntNode
* pCNd
= pCurCrsr
->GetCntntNode();
3038 bRet
= pCNd
&& !nStt
&& nEnd
== pCNd
->Len();
3043 short SwCrsrShell::GetTextDirection( const Point
* pPt
) const
3045 SwPosition
aPos( *pCurCrsr
->GetPoint() );
3046 Point
aPt( pPt
? *pPt
: pCurCrsr
->GetPtPos() );
3049 SwCrsrMoveState
aTmpState( MV_NONE
);
3050 aTmpState
.bSetInReadOnly
= IsReadOnlyAvailable();
3052 GetLayout()->GetCrsrOfst( &aPos
, aPt
, &aTmpState
);
3055 return pDoc
->GetTextDirection( aPos
, &aPt
);
3058 BOOL
SwCrsrShell::IsInVerticalText( const Point
* pPt
) const
3060 const short nDir
= GetTextDirection( pPt
);
3061 return FRMDIR_VERT_TOP_RIGHT
== nDir
|| FRMDIR_VERT_TOP_LEFT
== nDir
;
3064 BOOL
SwCrsrShell::IsInRightToLeftText( const Point
* pPt
) const
3066 const short nDir
= GetTextDirection( pPt
);
3067 // GetTextDirection uses FRMDIR_VERT_TOP_LEFT to indicate RTL in
3068 // vertical environment
3069 return FRMDIR_VERT_TOP_LEFT
== nDir
|| FRMDIR_HORI_RIGHT_TOP
== nDir
;
3073 // If the current cursor position is inside a hidden range, the hidden range
3076 bool SwCrsrShell::SelectHiddenRange()
3079 if ( !GetViewOptions()->IsShowHiddenChar() && !pCurCrsr
->HasMark() )
3081 SwPosition
& rPt
= *(SwPosition
*)pCurCrsr
->GetPoint();
3082 const SwTxtNode
* pNode
= rPt
.nNode
.GetNode().GetTxtNode();
3085 const xub_StrLen nPos
= rPt
.nContent
.GetIndex();
3087 // check if nPos is in hidden range
3088 xub_StrLen nHiddenStart
;
3089 xub_StrLen nHiddenEnd
;
3090 SwScriptInfo::GetBoundsOfHiddenRange( *pNode
, nPos
, nHiddenStart
, nHiddenEnd
);
3091 if ( STRING_LEN
!= nHiddenStart
)
3094 pCurCrsr
->SetMark();
3095 pCurCrsr
->GetMark()->nContent
= nHiddenEnd
;
3106 // die Suchfunktionen
3107 ULONG
SwCrsrShell::Find( const SearchOptions
& rSearchOpt
, BOOL bSearchInNotes
,
3108 SwDocPositions eStart
, SwDocPositions eEnde
,
3110 FindRanges eRng
, int bReplace
)
3114 delete pTblCrsr
, pTblCrsr
= 0;
3115 SwCallLink
aLk( *this ); // Crsr-Moves ueberwachen, evt. Link callen
3116 ULONG nRet
= pCurCrsr
->Find( rSearchOpt
, bSearchInNotes
, eStart
, eEnde
, bCancel
, eRng
, bReplace
);
3117 if( nRet
|| bCancel
)
3122 ULONG
SwCrsrShell::Find( const SwTxtFmtColl
& rFmtColl
,
3123 SwDocPositions eStart
, SwDocPositions eEnde
,
3125 FindRanges eRng
, const SwTxtFmtColl
* pReplFmt
)
3129 delete pTblCrsr
, pTblCrsr
= 0;
3130 SwCallLink
aLk( *this ); // Crsr-Moves ueberwachen, evt. Link callen
3131 ULONG nRet
= pCurCrsr
->Find( rFmtColl
, eStart
, eEnde
, bCancel
, eRng
, pReplFmt
);
3137 ULONG
SwCrsrShell::Find( const SfxItemSet
& rSet
, BOOL bNoCollections
,
3138 SwDocPositions eStart
, SwDocPositions eEnde
,
3140 FindRanges eRng
, const SearchOptions
* pSearchOpt
,
3141 const SfxItemSet
* rReplSet
)
3145 delete pTblCrsr
, pTblCrsr
= 0;
3146 SwCallLink
aLk( *this ); // Crsr-Moves ueberwachen, evt. Link callen
3147 ULONG nRet
= pCurCrsr
->Find( rSet
, bNoCollections
, eStart
, eEnde
, bCancel
,
3148 eRng
, pSearchOpt
, rReplSet
);
3154 void SwCrsrShell::SetSelection( const SwPaM
& rCrsr
)
3157 SwPaM
* pCrsr
= GetCrsr();
3158 *pCrsr
->GetPoint() = *rCrsr
.GetPoint();
3162 *pCrsr
->GetMark() = *rCrsr
.GetMark();
3164 if((SwPaM
*)rCrsr
.GetNext() != &rCrsr
)
3166 const SwPaM
*_pStartCrsr
= (SwPaM
*)rCrsr
.GetNext();
3169 SwPaM
* pCurrentCrsr
= CreateCrsr();
3170 *pCurrentCrsr
->GetPoint() = *_pStartCrsr
->GetPoint();
3171 if(_pStartCrsr
->HasMark())
3173 pCurrentCrsr
->SetMark();
3174 *pCurrentCrsr
->GetMark() = *_pStartCrsr
->GetMark();
3176 } while( (_pStartCrsr
=(SwPaM
*)_pStartCrsr
->GetNext()) != &rCrsr
);
3181 void lcl_RemoveMark( SwPaM
* pPam
)
3183 ASSERT( pPam
->HasMark(), "Don't remove pPoint!" )
3184 pPam
->GetMark()->nContent
.Assign( 0, 0 );
3185 pPam
->GetMark()->nNode
= 0;
3189 const SwStartNode
* lcl_NodeContext( const SwNode
& rNode
)
3191 const SwStartNode
*pRet
= rNode
.StartOfSectionNode();
3192 while( pRet
->IsSectionNode() || pRet
->IsTableNode() ||
3193 pRet
->GetStartNodeType() == SwTableBoxStartNode
)
3195 pRet
= pRet
->StartOfSectionNode();
3201 Checks if a position is valid. To be valid the position's node must
3202 be a content node and the content must not be unregistered.
3204 @param aPos the position to check.
3206 bool lcl_PosOk(const SwPosition
& aPos
)
3208 return NULL
!= aPos
.nNode
.GetNode().GetCntntNode() &&
3209 SwIndexReg::pEmptyIndexArray
!= aPos
.nContent
.GetIdxReg();
3213 Checks if a PaM is valid. For a PaM to be valid its point must be
3214 valid. Additionaly if the PaM has a mark this has to be valid, too.
3216 @param aPam the PaM to check
3218 static bool lcl_CrsrOk(SwPaM
& aPam
)
3220 return lcl_PosOk(*aPam
.GetPoint()) && (! aPam
.HasMark()
3221 || lcl_PosOk(*aPam
.GetMark()));
3224 void SwCrsrShell::ClearUpCrsrs()
3226 // start of the ring
3227 SwPaM
* pStartCrsr
= GetCrsr();
3228 // start loop with second entry of the ring
3229 SwPaM
* pCrsr
= (SwPaM
*) pStartCrsr
->GetNext();
3231 bool bChanged
= false;
3234 For all entries in the ring except the start entry delete the
3235 entry if it is invalid.
3237 while (pCrsr
!= pStartCrsr
)
3239 pTmpCrsr
= (SwPaM
*) pCrsr
->GetNext();
3241 if ( ! lcl_CrsrOk(*pCrsr
))
3251 if( pStartCrsr
->HasMark() && !lcl_PosOk( *pStartCrsr
->GetMark() ) )
3253 lcl_RemoveMark( pStartCrsr
);
3256 if( !lcl_PosOk( *pStartCrsr
->GetPoint() ) )
3258 SwNodes
& aNodes
= GetDoc()->GetNodes();
3259 const SwNode
* pStart
= lcl_NodeContext( pStartCrsr
->GetPoint()->nNode
.GetNode() );
3260 SwNodeIndex
aIdx( pStartCrsr
->GetPoint()->nNode
);
3261 SwNode
* pNode
= aNodes
.GoPrevious(&aIdx
);
3262 if( pNode
== NULL
|| lcl_NodeContext( *pNode
) != pStart
)
3263 aNodes
.GoNext( &aIdx
);
3264 if( pNode
== NULL
|| lcl_NodeContext( *pNode
) != pStart
)
3267 If the start entry of the ring is invalid replace it with a
3268 cursor pointing to the beginning of the first content node in
3271 aIdx
= (*(aNodes
.GetEndOfContent().StartOfSectionNode()));
3272 pNode
= aNodes
.GoNext( &aIdx
);
3274 bool bFound
= (pNode
!= NULL
);
3276 ASSERT(bFound
, "no content node found");
3280 SwPaM
aTmpPam(*pNode
);
3281 *pStartCrsr
= aTmpPam
;
3288 If at least one of the cursors in the ring have been deleted or
3289 replaced, remove the table cursor.
3291 if (pTblCrsr
!= NULL
&& bChanged
)
3296 String
SwCrsrShell::GetCrsrDescr() const
3300 if (IsMultiSelection())
3301 aResult
+= String(SW_RES(STR_MULTISEL
));
3303 aResult
= GetDoc()->GetPaMDescr(*GetCrsr());
3308 SwRect
SwCrsrShell::GetRectOfCurrentChar()
3310 SwCntntFrm
* pFrm
= pCurCrsr
->GetCntntNode()->GetFrm( 0, pCurCrsr
->GetPoint(), FALSE
);
3312 SwCrsrMoveState
aTmpState( MV_NONE
);
3313 aTmpState
.bRealHeight
= TRUE
;
3314 pFrm
->GetCharRect( aRet
, *pCurCrsr
->GetPoint(), &aTmpState
);
3315 //const SwTwips nRealHeight = aTmpState.aRealHeight.Y();
3316 if (aTmpState
.aRealHeight
.X() != 0)
3317 aRet
.Top(aRet
.Top() + aTmpState
.aRealHeight
.X());
3323 void lcl_FillRecognizerData( uno::Sequence
< rtl::OUString
>& rSmartTagTypes
,
3324 uno::Sequence
< uno::Reference
< container::XStringKeyMap
> >& rStringKeyMaps
,
3325 const SwWrongList
& rSmartTagList
, xub_StrLen nCurrent
)
3327 // Insert smart tag information
3328 std::vector
< rtl::OUString
> aSmartTagTypes
;
3329 std::vector
< uno::Reference
< container::XStringKeyMap
> > aStringKeyMaps
;
3331 for ( USHORT i
= 0; i
< rSmartTagList
.Count(); ++i
)
3333 const xub_StrLen nSTPos
= rSmartTagList
.Pos( i
);
3334 const xub_StrLen nSTLen
= rSmartTagList
.Len( i
);
3336 if ( nSTPos
<= nCurrent
&& nCurrent
< nSTPos
+ nSTLen
)
3338 const SwWrongArea
* pArea
= rSmartTagList
.GetElement( i
);
3341 aSmartTagTypes
.push_back( pArea
->maType
);
3342 aStringKeyMaps
.push_back( pArea
->mxPropertyBag
);
3347 if ( aSmartTagTypes
.size() )
3349 rSmartTagTypes
.realloc( aSmartTagTypes
.size() );
3350 rStringKeyMaps
.realloc( aSmartTagTypes
.size() );
3352 std::vector
< rtl::OUString
>::const_iterator aTypesIter
= aSmartTagTypes
.begin();
3354 for ( aTypesIter
= aSmartTagTypes
.begin(); aTypesIter
!= aSmartTagTypes
.end(); ++aTypesIter
)
3355 rSmartTagTypes
[i
++] = *aTypesIter
;
3357 std::vector
< uno::Reference
< container::XStringKeyMap
> >::const_iterator aMapsIter
= aStringKeyMaps
.begin();
3359 for ( aMapsIter
= aStringKeyMaps
.begin(); aMapsIter
!= aStringKeyMaps
.end(); ++aMapsIter
)
3360 rStringKeyMaps
[i
++] = *aMapsIter
;
3364 void lcl_FillTextRange( uno::Reference
<text::XTextRange
>& rRange
,
3365 SwTxtNode
& rNode
, xub_StrLen nBegin
, xub_StrLen nLen
)
3367 // create SwPosition for nStartIndex
3368 SwIndex
aIndex( &rNode
, nBegin
);
3369 SwPosition
aStartPos( rNode
, aIndex
);
3371 // create SwPosition for nEndIndex
3372 SwPosition
aEndPos( aStartPos
);
3373 aEndPos
.nContent
= nBegin
+ nLen
;
3375 uno::Reference
<text::XTextRange
> xRange
=
3376 SwXTextRange::CreateTextRangeFromPosition( rNode
.GetDoc(), aStartPos
, &aEndPos
);
3381 void SwCrsrShell::GetSmartTagTerm( uno::Sequence
< rtl::OUString
>& rSmartTagTypes
,
3382 uno::Sequence
< uno::Reference
< container::XStringKeyMap
> >& rStringKeyMaps
,
3383 uno::Reference
< text::XTextRange
>& rRange
) const
3385 if ( !SwSmartTagMgr::Get().IsSmartTagsEnabled() )
3388 SwPaM
* pCrsr
= GetCrsr();
3389 SwPosition
aPos( *pCrsr
->GetPoint() );
3390 SwTxtNode
*pNode
= aPos
.nNode
.GetNode().GetTxtNode();
3391 if ( pNode
&& !pNode
->IsInProtectSect() )
3393 const SwWrongList
*pSmartTagList
= pNode
->GetSmartTags();
3394 if ( pSmartTagList
)
3396 xub_StrLen nCurrent
= aPos
.nContent
.GetIndex();
3397 xub_StrLen nBegin
= nCurrent
;
3398 xub_StrLen nLen
= 1;
3400 if( pSmartTagList
->InWrongWord( nBegin
, nLen
) && !pNode
->IsSymbol(nBegin
) )
3402 const USHORT nIndex
= pSmartTagList
->GetWrongPos( nBegin
);
3403 const SwWrongList
* pSubList
= pSmartTagList
->SubList( nIndex
);
3406 pSmartTagList
= pSubList
;
3410 lcl_FillRecognizerData( rSmartTagTypes
, rStringKeyMaps
, *pSmartTagList
, nCurrent
);
3411 lcl_FillTextRange( rRange
, *pNode
, nBegin
, nLen
);
3417 // see also SwEditShell::GetCorrection( const Point* pPt, SwRect& rSelectRect )
3418 void SwCrsrShell::GetSmartTagTerm( const Point
& rPt
, SwRect
& rSelectRect
,
3419 uno::Sequence
< rtl::OUString
>& rSmartTagTypes
,
3420 uno::Sequence
< uno::Reference
< container::XStringKeyMap
> >& rStringKeyMaps
,
3421 uno::Reference
<text::XTextRange
>& rRange
)
3423 if ( !SwSmartTagMgr::Get().IsSmartTagsEnabled() )
3426 SwPaM
* pCrsr
= GetCrsr();
3427 SwPosition
aPos( *pCrsr
->GetPoint() );
3429 SwCrsrMoveState
eTmpState( MV_SETONLYTEXT
);
3430 SwSpecialPos aSpecialPos
;
3431 eTmpState
.pSpecialPos
= &aSpecialPos
;
3433 const SwWrongList
*pSmartTagList
;
3435 if( GetLayout()->GetCrsrOfst( &aPos
, aPt
, &eTmpState
) &&
3436 0 != (pNode
= aPos
.nNode
.GetNode().GetTxtNode()) &&
3437 0 != (pSmartTagList
= pNode
->GetSmartTags()) &&
3438 !pNode
->IsInProtectSect() )
3440 xub_StrLen nCurrent
= aPos
.nContent
.GetIndex();
3441 xub_StrLen nBegin
= nCurrent
;
3442 xub_StrLen nLen
= 1;
3444 if( pSmartTagList
->InWrongWord( nBegin
, nLen
) && !pNode
->IsSymbol(nBegin
) )
3446 const USHORT nIndex
= pSmartTagList
->GetWrongPos( nBegin
);
3447 const SwWrongList
* pSubList
= pSmartTagList
->SubList( nIndex
);
3450 pSmartTagList
= pSubList
;
3451 nCurrent
= eTmpState
.pSpecialPos
->nCharOfst
;
3454 lcl_FillRecognizerData( rSmartTagTypes
, rStringKeyMaps
, *pSmartTagList
, nCurrent
);
3455 lcl_FillTextRange( rRange
, *pNode
, nBegin
, nLen
);
3457 // get smarttag word
3458 String
aText( pNode
->GetTxt().Copy( nBegin
, nLen
) );
3460 //save the start and end positons of the line and the starting point
3463 xub_StrLen nLineStart
= GetCrsr()->GetPoint()->nContent
.GetIndex();
3465 xub_StrLen nLineEnd
= GetCrsr()->GetPoint()->nContent
.GetIndex();
3468 // make sure the selection build later from the
3469 // data below does not include footnotes and other
3470 // "in word" character to the left and right in order
3471 // to preserve those. Therefore count those "in words"
3472 // in order to modify the selection accordingly.
3473 const sal_Unicode
* pChar
= aText
.GetBuffer();
3474 xub_StrLen nLeft
= 0;
3475 while (pChar
&& *pChar
++ == CH_TXTATR_INWORD
)
3477 pChar
= aText
.Len() ? aText
.GetBuffer() + aText
.Len() - 1 : 0;
3478 xub_StrLen nRight
= 0;
3479 while (pChar
&& *pChar
-- == CH_TXTATR_INWORD
)
3482 aPos
.nContent
= nBegin
+ nLeft
;
3484 *pCrsr
->GetPoint() = aPos
;
3486 ExtendSelection( sal_True
, nLen
- nLeft
- nRight
);
3487 //no determine the rectangle in the current line
3488 xub_StrLen nWordStart
= (nBegin
+ nLeft
) < nLineStart
? nLineStart
: nBegin
+ nLeft
;
3489 //take one less than the line end - otherwise the next line would be calculated
3490 xub_StrLen nWordEnd
= (nBegin
+ nLen
- nLeft
- nRight
) > nLineEnd
? nLineEnd
- 1: (nBegin
+ nLen
- nLeft
- nRight
);
3492 pCrsr
->DeleteMark();
3493 SwIndex
& rContent
= GetCrsr()->GetPoint()->nContent
;
3494 rContent
= nWordStart
;
3496 SwCrsrMoveState aState
;
3497 aState
.bRealWidth
= TRUE
;
3498 SwCntntNode
* pCntntNode
= pCrsr
->GetCntntNode();
3499 SwCntntFrm
*pCntntFrame
= pCntntNode
->GetFrm( &rPt
, pCrsr
->GetPoint(), FALSE
);
3501 pCntntFrame
->GetCharRect( aStartRect
, *pCrsr
->GetPoint(), &aState
);
3502 rContent
= nWordEnd
;
3504 pCntntFrame
->GetCharRect( aEndRect
, *pCrsr
->GetPoint(),&aState
);
3505 rSelectRect
= aStartRect
.Union( aEndRect
);