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: swcrsr.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"
35 #include <hintids.hxx>
36 #include <svx/protitem.hxx>
38 #include <com/sun/star/i18n/WordType.hdl>
39 #include <com/sun/star/i18n/CharType.hdl>
41 #include <unotools/charclass.hxx>
42 #include <svtools/ctloptions.hxx>
43 #include <swmodule.hxx>
44 #include <fmtcntnt.hxx>
45 #include <swtblfmt.hxx>
47 #include <unocrsr.hxx>
51 #include <section.hxx>
52 #include <swtable.hxx>
54 #include <rootfrm.hxx>
56 #include <scriptinfo.hxx>
57 #include <crstate.hxx>
60 #include <breakit.hxx>
61 #include <crsskip.hxx>
62 #include <vcl/msgbox.hxx>
63 #include <mdiexp.hxx> // ...Percent()
65 #include <statstr.hrc> // ResId fuer Statusleiste
67 #include <redline.hxx> // SwRedline
70 using namespace ::com::sun::star::i18n
;
73 static const USHORT coSrchRplcThreshold
= 60000;
81 _PercentHdl( ULONG nStt
, ULONG nEnd
, SwDocShell
* pSh
)
85 if( 0 != ( bBack
= (nStt
> nEnd
)) )
87 ULONG n
= nStt
; nStt
= nEnd
; nEnd
= n
;
89 ::StartProgress( STR_STATSTR_SEARCH
, nStt
, nEnd
, 0 );
92 _PercentHdl( const SwPaM
& rPam
)
93 : pDSh( (SwDocShell
*)rPam
.GetDoc()->GetDocShell() )
96 if( rPam
.GetPoint()->nNode
== rPam
.GetMark()->nNode
)
99 nStt
= rPam
.GetMark()->nContent
.GetIndex();
100 nEnd
= rPam
.GetPoint()->nContent
.GetIndex();
105 nStt
= rPam
.GetMark()->nNode
.GetIndex();
106 nEnd
= rPam
.GetPoint()->nNode
.GetIndex();
109 if( 0 != ( bBack
= (nStt
> nEnd
)) )
111 ULONG n
= nStt
; nStt
= nEnd
; nEnd
= n
;
113 ::StartProgress( STR_STATSTR_SEARCH
, nStt
, nEnd
, pDSh
);
116 ~_PercentHdl() { ::EndProgress( pDSh
); }
118 void NextPos( ULONG nPos
) const
119 { ::SetProgressState( bBack
? nActPos
- nPos
: nPos
, pDSh
); }
121 void NextPos( SwPosition
& rPos
) const
125 nPos
= rPos
.nNode
.GetIndex();
127 nPos
= rPos
.nContent
.GetIndex();
128 ::SetProgressState( bBack
? nActPos
- nPos
: nPos
, pDSh
);
132 SwCursor::SwCursor( const SwPosition
&rPos
, SwPaM
* pRing
, bool bColumnSel
)
133 : SwPaM( rPos
, pRing
), pSavePos( 0 ), mnRowSpanOffset( 0 ), nCursorBidiLevel( 0 ),
134 mbColumnSelection( bColumnSel
)
138 // @@@ semantic: no copy ctor.
139 SwCursor::SwCursor( SwCursor
& rCpy
)
140 : SwPaM( rCpy
), pSavePos( 0 ), mnRowSpanOffset( rCpy
.mnRowSpanOffset
),
141 nCursorBidiLevel( rCpy
.nCursorBidiLevel
), mbColumnSelection( rCpy
.mbColumnSelection
)
145 SwCursor::~SwCursor()
149 _SwCursor_SavePos
* pNxt
= pSavePos
->pNext
;
155 SwCursor
* SwCursor::Create( SwPaM
* pRing
) const
157 return new SwCursor( *GetPoint(), pRing
, false );
160 bool SwCursor::IsReadOnlyAvailable() const
165 BOOL
SwCursor::IsSkipOverHiddenSections() const
170 BOOL
SwCursor::IsSkipOverProtectSections() const
172 return !IsReadOnlyAvailable();
176 // Sicher die aktuelle Position, damit ggfs. auf diese zurueck
177 // gefallen werden kann. Die SavePos Objekte werden als Stack verwaltet,
178 // damit das auch alles bei verschachtelten Aufrufen funktioniert.
179 // Das CreateNewSavePos ist virtual, damit abgeleitete Klassen vom Cursor
180 // gegebenenfalls eigene SaveObjecte anlegen und in den virtuellen
181 // Check-Routinen verwenden koennen.
183 void SwCursor::SaveState()
185 _SwCursor_SavePos
* pNew
= CreateNewSavePos();
186 pNew
->pNext
= pSavePos
;
190 void SwCursor::RestoreState()
192 if( pSavePos
) // Robust
194 _SwCursor_SavePos
* pDel
= pSavePos
;
195 pSavePos
= pSavePos
->pNext
;
200 _SwCursor_SavePos
* SwCursor::CreateNewSavePos() const
202 return new _SwCursor_SavePos( *this );
205 // stelle fest, ob sich der Point ausserhalb des Content-Bereichs
206 // vom Nodes-Array befindet
207 BOOL
SwCursor::IsNoCntnt() const
209 return GetPoint()->nNode
.GetIndex() <
210 GetDoc()->GetNodes().GetEndOfExtras().GetIndex();
213 bool SwCursor::IsSelOvrCheck(int)
218 // extracted from IsSelOvr()
219 bool SwTableCursor::IsSelOvrCheck(int eFlags
)
221 SwNodes
& rNds
= GetDoc()->GetNodes();
222 // check sections of nodes array
223 if( (nsSwCursorSelOverFlags::SELOVER_CHECKNODESSECTION
& eFlags
)
226 SwNodeIndex
aOldPos( rNds
, GetSavePos()->nNode
);
227 if( !CheckNodesRange( aOldPos
, GetPoint()->nNode
, TRUE
))
229 GetPoint()->nNode
= aOldPos
;
230 GetPoint()->nContent
.Assign( GetCntntNode(), GetSavePos()->nCntnt
);
234 return SwCursor::IsSelOvrCheck(eFlags
);
237 BOOL
SwCursor::IsSelOvr( int eFlags
)
239 SwDoc
* pDoc
= GetDoc();
240 SwNodes
& rNds
= pDoc
->GetNodes();
242 BOOL bSkipOverHiddenSections
= IsSkipOverHiddenSections();
243 BOOL bSkipOverProtectSections
= IsSkipOverProtectSections();
245 if ( IsSelOvrCheck( eFlags
) )
250 // neu: Bereiche ueberpruefen
252 if( pSavePos
->nNode
!= GetPoint()->nNode
.GetIndex() &&
253 //JP 28.10.97: Bug 45129 - im UI-ReadOnly ist alles erlaubt
254 ( !pDoc
->GetDocShell() || !pDoc
->GetDocShell()->IsReadOnlyUI() ))
256 // teste doch mal die neuen Sections:
257 SwNodeIndex
& rPtIdx
= GetPoint()->nNode
;
258 const SwSectionNode
* pSectNd
= rPtIdx
.GetNode().FindSectionNode();
260 ((bSkipOverHiddenSections
&& pSectNd
->GetSection().IsHiddenFlag() ) ||
261 (bSkipOverProtectSections
&& pSectNd
->GetSection().IsProtectFlag() )))
263 if( 0 == ( nsSwCursorSelOverFlags::SELOVER_CHANGEPOS
& eFlags
) )
265 // dann wars das schon
270 // dann setze den Cursor auf die neue Position:
271 SwNodeIndex
aIdx( rPtIdx
);
272 xub_StrLen nCntntPos
= pSavePos
->nCntnt
;
273 int bGoNxt
= pSavePos
->nNode
< rPtIdx
.GetIndex();
274 SwCntntNode
* pCNd
= bGoNxt
275 ? rNds
.GoNextSection( &rPtIdx
, bSkipOverHiddenSections
, bSkipOverProtectSections
)
276 : rNds
.GoPrevSection( &rPtIdx
, bSkipOverHiddenSections
, bSkipOverProtectSections
);
277 if( !pCNd
&& ( nsSwCursorSelOverFlags::SELOVER_ENABLEREVDIREKTION
& eFlags
))
280 pCNd
= bGoNxt
? rNds
.GoNextSection( &rPtIdx
, bSkipOverHiddenSections
, bSkipOverProtectSections
)
281 : rNds
.GoPrevSection( &rPtIdx
, bSkipOverHiddenSections
, bSkipOverProtectSections
);
284 int bIsValidPos
= 0 != pCNd
;
285 BOOL bValidNodesRange
= bIsValidPos
&&
286 ::CheckNodesRange( rPtIdx
, aIdx
, TRUE
);
287 if( !bValidNodesRange
)
289 rPtIdx
= pSavePos
->nNode
;
290 if( 0 == ( pCNd
= rPtIdx
.GetNode().GetCntntNode() ) )
295 if( 0 == ( pCNd
= rPtIdx
.GetNode().GetCntntNode() ) )
297 // dann auf den Anfang vom Doc
298 rPtIdx
= rNds
.GetEndOfExtras();
299 pCNd
= rNds
.GoNext( &rPtIdx
);
304 // ContentIndex noch anmelden:
305 xub_StrLen nTmpPos
= bIsValidPos
? (bGoNxt
? 0 : pCNd
->Len()) : nCntntPos
;
306 GetPoint()->nContent
.Assign( pCNd
, nTmpPos
);
307 if( !bIsValidPos
|| !bValidNodesRange
||
308 // sollten wir in einer Tabelle gelandet sein?
309 IsInProtectTable( TRUE
) )
313 // oder sollte eine geschuetzte Section innerhalb der Selektion liegen?
314 if( HasMark() && bSkipOverProtectSections
)
316 ULONG nSttIdx
= GetMark()->nNode
.GetIndex(),
317 nEndIdx
= GetPoint()->nNode
.GetIndex();
318 if( nEndIdx
<= nSttIdx
)
320 ULONG nTmp
= nSttIdx
;
325 const SwSectionFmts
& rFmts
= pDoc
->GetSections();
326 for( USHORT n
= 0; n
< rFmts
.Count(); ++n
)
328 const SwSectionFmt
* pFmt
= rFmts
[n
];
329 const SvxProtectItem
& rProtect
= pFmt
->GetProtect();
330 if( rProtect
.IsCntntProtected() )
332 const SwFmtCntnt
& rCntnt
= pFmt
->GetCntnt(FALSE
);
333 ASSERT( rCntnt
.GetCntntIdx(), "wo ist der SectionNode?" );
334 ULONG nIdx
= rCntnt
.GetCntntIdx()->GetIndex();
335 if( nSttIdx
<= nIdx
&& nEndIdx
>= nIdx
)
337 // ist es keine gelinkte Section, dann kann sie auch
338 // nicht mitselektiert werden
339 const SwSection
& rSect
= *pFmt
->GetSection();
340 if( CONTENT_SECTION
== rSect
.GetType() )
352 // neu: Bereiche ueberpruefen
354 const SwNode
* pNd
= &GetPoint()->nNode
.GetNode();
355 if( pNd
->IsCntntNode() && !dynamic_cast<SwUnoCrsr
*>(this) )
357 const SwCntntFrm
* pFrm
= ((SwCntntNode
*)pNd
)->GetFrm();
358 if( pFrm
&& pFrm
->IsValid() && 0 == pFrm
->Frm().Height() &&
359 0 != ( nsSwCursorSelOverFlags::SELOVER_CHANGEPOS
& eFlags
) )
361 // skip to the next / prev valid paragraph with a layout
362 SwNodeIndex
& rPtIdx
= GetPoint()->nNode
;
363 int bGoNxt
= pSavePos
->nNode
< rPtIdx
.GetIndex();
364 while( 0 != ( pFrm
= ( bGoNxt
? pFrm
->GetNextCntntFrm()
365 : pFrm
->GetPrevCntntFrm() )) &&
366 0 == pFrm
->Frm().Height() )
369 // --> LIJIAN/FME 2007-11-27 #i72394# skip to prev /next valid paragraph
370 // with a layout in case the first search did not succeed:
374 pFrm
= ((SwCntntNode
*)pNd
)->GetFrm();
375 while ( pFrm
&& 0 == pFrm
->Frm().Height() )
377 pFrm
= bGoNxt
? pFrm
->GetNextCntntFrm()
378 : pFrm
->GetPrevCntntFrm();
384 if( pFrm
&& 0 != (pCNd
= (SwCntntNode
*)pFrm
->GetNode()) )
386 // set this cntntNode as new position
390 // ContentIndex noch anmelden:
391 xub_StrLen nTmpPos
= bGoNxt
? 0 : pCNd
->Len();
392 GetPoint()->nContent
.Assign( pCNd
, nTmpPos
);
394 // sollten wir in einer Tabelle gelandet sein?
395 if( IsInProtectTable( TRUE
) )
404 return TRUE
; // ohne Frames geht gar nichts!
408 // darf der Cursor in geschuetzen "Nodes" stehen?
409 if( 0 == ( nsSwCursorSelOverFlags::SELOVER_CHANGEPOS
& eFlags
) && !IsAtValidPos() )
419 //JP 19.08.98: teste mal auf ungueltige Selektion - sprich ueber
421 if( !::CheckNodesRange( GetMark()->nNode
, GetPoint()->nNode
, TRUE
))
425 return TRUE
; // ohne Frames geht gar nichts!
428 const SwTableNode
* pPtNd
= pNd
->FindTableNode();
430 if( (pNd
= &GetMark()->nNode
.GetNode())->IsCntntNode() &&
431 !((SwCntntNode
*)pNd
)->GetFrm() && !dynamic_cast<SwUnoCrsr
*>(this) )
435 return TRUE
; // ohne Frames geht gar nichts!
438 const SwTableNode
* pMrkNd
= pNd
->FindTableNode();
440 // beide in keinem oder beide im gleichen TableNode
441 if( ( !pMrkNd
&& !pPtNd
) || pPtNd
== pMrkNd
)
444 // in unterschiedlichen Tabellen oder nur Mark in der Tabelle
445 if( ( pPtNd
&& pMrkNd
) || pMrkNd
)
446 { // dann lasse das nicht zu, alte Pos zurueck
448 // Crsr bleibt an der alten Position
452 // ACHTUNG: dieses kann nicht im TableMode geschehen !!
453 if( pPtNd
) // nur Point in Tabelle, dann gehe hinter/vor diese
455 if( nsSwCursorSelOverFlags::SELOVER_CHANGEPOS
& eFlags
)
457 BOOL bSelTop
= GetPoint()->nNode
.GetIndex() <
458 (( nsSwCursorSelOverFlags::SELOVER_TOGGLE
& eFlags
) ? pSavePos
->nNode
459 : GetMark()->nNode
.GetIndex());
462 // in Schleife fuer Tabelle hinter Tabelle
463 ULONG nSEIdx
= pPtNd
->EndOfSectionIndex();
464 ULONG nSttEndTbl
= nSEIdx
+ 1; // dflt. Sel. nach unten
466 if( bSelTop
) // Sel. nach oben
467 nSttEndTbl
= rNds
[ nSEIdx
]->StartOfSectionIndex() - 1;
469 GetPoint()->nNode
= nSttEndTbl
;
470 const SwNode
* pMyNd
= GetNode();
472 if( pMyNd
->IsSectionNode() || ( pMyNd
->IsEndNode() &&
473 pMyNd
->StartOfSectionNode()->IsSectionNode() ) )
475 // die lassen wir zu:
477 ? rNds
.GoPrevSection( &GetPoint()->nNode
,TRUE
,FALSE
)
478 : rNds
.GoNextSection( &GetPoint()->nNode
,TRUE
,FALSE
);
480 /* #i12312# Handle failure of Go{Prev|Next}Section */
484 if( 0 != ( pPtNd
= pMyNd
->FindTableNode() ))
488 if( pMyNd
->IsCntntNode() && // ist es ein ContentNode ??
489 ::CheckNodesRange( GetMark()->nNode
,
490 GetPoint()->nNode
, TRUE
))
493 const SwTableNode
* pOuterTableNd
= pMyNd
->FindTableNode();
495 pMyNd
= pOuterTableNd
;
498 SwCntntNode
* pCNd
= (SwCntntNode
*)pMyNd
;
499 xub_StrLen nTmpPos
= bSelTop
? pCNd
->Len() : 0;
500 GetPoint()->nContent
.Assign( pCNd
, nTmpPos
);
505 ? ( !pMyNd
->IsEndNode() || 0 == ( pPtNd
= pMyNd
->FindTableNode() ))
506 : 0 == ( pPtNd
= pMyNd
->GetTableNode() ))
511 // dann verbleibe auf der alten Position
513 return TRUE
; // Crsr bleibt an der alten Position
515 return FALSE
; // was bleibt noch ??
519 #define IDX (*pCellStt)
525 BOOL
SwCursor::IsInProtectTable( BOOL bMove
, BOOL bChgCrsr
)
527 SwCntntNode
* pCNd
= GetCntntNode();
531 // No table, no protected cell:
532 const SwTableNode
* pTableNode
= pCNd
->FindTableNode();
536 // Current position == last save position?
537 if ( pSavePos
->nNode
== GetPoint()->nNode
.GetIndex() )
540 // Check for convered cell:
541 bool bInCoveredCell
= false;
542 const SwStartNode
* pTmpSttNode
= pCNd
->FindTableBoxStartNode();
543 ASSERT( pTmpSttNode
, "In table, therefore I expect to get a SwTableBoxStartNode" )
544 const SwTableBox
* pBox
= pTmpSttNode
? pTableNode
->GetTable().GetTblBox( pTmpSttNode
->GetIndex() ) : 0; //Robust #151355
545 if ( pBox
&& pBox
->getRowSpan() < 1 ) // Robust #151270
546 bInCoveredCell
= true;
548 // Positions of covered cells are not acceptable:
549 if ( !bInCoveredCell
)
551 // Position not protected?
552 if ( !pCNd
->IsProtect() )
555 // Cursor in protected cells allowed?
556 if ( IsReadOnlyAvailable() )
560 // If we reach this point, we are in a protected or covered table cell!
565 // restore the last save position
567 return TRUE
; // Crsr bleibt an der alten Position
570 // wir stehen in einer geschuetzten TabellenZelle
571 // von Oben nach Unten Traveln ?
572 if( pSavePos
->nNode
< GetPoint()->nNode
.GetIndex() )
574 // suche die naechste "gueltige" Box
576 // folgt nach dem EndNode der Zelle ein weiterer StartNode, dann
577 // gibt es auch eine naechste Zelle
579 SwNodeIndex
* pCellStt
= new SwNodeIndex( *GetNode()->
580 FindTableBoxStartNode()->EndOfSectionNode(), 1 );
582 SwNodeIndex
aCellStt( *GetNode()->FindTableBoxStartNode()->EndOfSectionNode(), 1 );
587 if( !IDX
.GetNode().IsStartNode() )
590 if( 0 == ( pCNd
= IDX
.GetNode().GetCntntNode() ))
591 pCNd
= IDX
.GetNodes().GoNext( &IDX
);
592 if( 0 == ( bProt
= pCNd
->IsProtect() ))
594 IDX
.Assign( *pCNd
->FindTableBoxStartNode()->EndOfSectionNode(), 1 );
598 if( !bProt
) // eine freie Zelle gefunden
600 GetPoint()->nNode
= IDX
;
604 SwCntntNode
* pTmpCNd
= GetCntntNode();
607 GetPoint()->nContent
.Assign( pTmpCNd
, 0 );
610 return IsSelOvr( nsSwCursorSelOverFlags::SELOVER_TOGGLE
|
611 nsSwCursorSelOverFlags::SELOVER_CHANGEPOS
);
613 // am Ende der Tabelle, also setze hinter diese
614 IDX
++; // auf den naechsten Node
616 if( ( pNd
= &IDX
.GetNode())->IsEndNode() || HasMark())
618 // Tabelle allein in einem FlyFrame oder SSelection,
619 // dann verbleibe auf der alten Position
625 return TRUE
; // Crsr bleibt an der alten Position
627 else if( pNd
->IsTableNode() && IDX
++ )
630 bProt
= FALSE
; // Index steht jetzt auf einem ContentNode
634 // suche die vorherige "gueltige" Box
636 // liegt vor dem StartNode der Zelle ein weiterer EndNode, dann
637 // gibt es auch eine vorherige Zelle
639 SwNodeIndex
* pCellStt
= new SwNodeIndex(
640 *GetNode()->FindTableBoxStartNode(), -1 );
642 SwNodeIndex
aCellStt( *GetNode()->FindTableBoxStartNode(), -1 );
648 if( !( pNd
= &IDX
.GetNode())->IsEndNode() )
650 IDX
.Assign( *pNd
->StartOfSectionNode(), +1 );
651 if( 0 == ( pCNd
= IDX
.GetNode().GetCntntNode() ))
652 pCNd
= pNd
->GetNodes().GoNext( &IDX
);
653 if( 0 == ( bProt
= pCNd
->IsProtect() ))
655 IDX
.Assign( *pNd
->FindTableBoxStartNode(), -1 );
659 if( !bProt
) // eine freie Zelle gefunden
661 GetPoint()->nNode
= IDX
;
665 SwCntntNode
* pTmpCNd
= GetCntntNode();
668 GetPoint()->nContent
.Assign( pTmpCNd
, 0 );
671 return IsSelOvr( nsSwCursorSelOverFlags::SELOVER_TOGGLE
|
672 nsSwCursorSelOverFlags::SELOVER_CHANGEPOS
);
674 // am Start der Tabelle, also setze vor diese
675 IDX
--; // auf den naechsten Node
676 if( ( pNd
= &IDX
.GetNode())->IsStartNode() || HasMark() )
678 // Tabelle allein in einem FlyFrame oder Selektion,
679 // dann verbleibe auf der alten Position
685 return TRUE
; // Crsr bleibt an der alten Position
687 else if( pNd
->StartOfSectionNode()->IsTableNode() && IDX
-- )
690 bProt
= FALSE
; // Index steht jetzt auf einem ContentNode
695 // TRUE: an die Position kann der Cursor gesetzt werden
696 BOOL
SwCursor::IsAtValidPos( BOOL bPoint
) const
698 const SwDoc
* pDoc
= GetDoc();
699 const SwPosition
* pPos
= bPoint
? GetPoint() : GetMark();
700 const SwNode
* pNd
= &pPos
->nNode
.GetNode();
702 if( pNd
->IsCntntNode() && !((SwCntntNode
*)pNd
)->GetFrm() &&
703 !dynamic_cast<const SwUnoCrsr
*>(this) )
708 //JP 28.10.97: Bug 45129 - im UI-ReadOnly ist alles erlaubt
709 if( !pDoc
->GetDocShell() || !pDoc
->GetDocShell()->IsReadOnlyUI() )
712 BOOL bCrsrInReadOnly
= IsReadOnlyAvailable();
713 if( !bCrsrInReadOnly
&& pNd
->IsProtect() )
716 const SwSectionNode
* pSectNd
= pNd
->FindSectionNode();
717 if( pSectNd
&& (pSectNd
->GetSection().IsHiddenFlag() ||
718 ( !bCrsrInReadOnly
&& pSectNd
->GetSection().IsProtectFlag() )))
724 void SwCursor::SaveTblBoxCntnt( const SwPosition
* ) {}
726 // setze den SRange fuer das Suchen im Dokument
727 SwMoveFnCollection
* SwCursor::MakeFindRange( SwDocPositions nStart
,
728 SwDocPositions nEnd
, SwPaM
* pRange
) const
731 FillFindPos( nStart
, *pRange
->GetMark() );
732 FillFindPos( nEnd
, *pRange
->GetPoint() );
734 // bestimme die Richtung, in der zu suchen ist
735 // ( GetPoint > GetMark -> vorwaerts, sonst rueckwaerts )
736 return ( DOCPOS_START
== nStart
|| DOCPOS_OTHERSTART
== nStart
||
737 (DOCPOS_CURR
== nStart
&&
738 (DOCPOS_END
== nEnd
|| DOCPOS_OTHEREND
== nEnd
) ))
739 ? fnMoveForward
: fnMoveBackward
;
743 ULONG
lcl_FindSelection( SwFindParas
& rParas
, SwCursor
* pCurCrsr
,
744 SwMoveFn fnMove
, SwCursor
*& pFndRing
,
745 SwPaM
& aRegion
, FindRanges eFndRngs
,
746 BOOL bInReadOnly
, BOOL
& bCancel
)
748 SwDoc
* pDoc
= pCurCrsr
->GetDoc();
749 BOOL bDoesUndo
= pDoc
->DoesUndo();
752 int bSrchBkwrd
= fnMove
== fnMoveBackward
, bEnde
= FALSE
;
753 SwPaM
*pTmpCrsr
= pCurCrsr
, *pSaveCrsr
= pCurCrsr
;
755 // only create progress-bar for ShellCrsr
756 bool bIsUnoCrsr
= 0 != dynamic_cast<SwUnoCrsr
*>(pCurCrsr
);
757 _PercentHdl
* pPHdl
= 0;
759 if( FND_IN_SEL
& eFndRngs
)
761 while( pCurCrsr
!= ( pTmpCrsr
= (SwPaM
*)pTmpCrsr
->GetNext() ))
763 if( nCrsrCnt
&& !bIsUnoCrsr
)
764 pPHdl
= new _PercentHdl( 0, nCrsrCnt
, pDoc
->GetDocShell() );
767 pSaveCrsr
= (SwPaM
*)pSaveCrsr
->GetPrev();
771 // egal in welche Richtung, SPoint ist immer groesser als Mark,
772 // wenn der Suchbereich gueltig ist !!
773 SwPosition
*pSttPos
= aRegion
.GetMark(),
774 *pEndPos
= aRegion
.GetPoint();
775 *pSttPos
= *pTmpCrsr
->Start();
776 *pEndPos
= *pTmpCrsr
->End();
780 if( !nCrsrCnt
&& !pPHdl
&& !bIsUnoCrsr
)
781 pPHdl
= new _PercentHdl( aRegion
);
783 // solange gefunden und nicht auf gleicher Position haengen bleibt
784 while( *pSttPos
<= *pEndPos
&&
785 0 != ( nFndRet
= rParas
.Find( pCurCrsr
, fnMove
,
786 &aRegion
, bInReadOnly
)) &&
788 *pFndRing
->GetPoint() != *pCurCrsr
->GetPoint() ||
789 *pFndRing
->GetMark() != *pCurCrsr
->GetMark() ))
791 if( !( FIND_NO_RING
& nFndRet
))
793 // Bug 24084: Ring richtig herum aufbauen -> gleiche Mimik
794 // wie beim CreateCrsr !!!!
796 SwCursor
* pNew
= pCurCrsr
->Create( pFndRing
);
801 *pNew
->GetMark() = *pCurCrsr
->GetMark();
806 if( !( eFndRngs
& FND_IN_SELALL
) )
812 if( coSrchRplcThreshold
== nFound
&& pDoc
->DoesUndo()
813 && rParas
.IsReplaceMode())
815 short nRet
= pCurCrsr
->MaxReplaceArived();
816 if( RET_YES
== nRet
)
818 pDoc
->DelAllUndoObj();
819 pDoc
->DoUndo( FALSE
);
824 if(RET_CANCEL
== nRet
)
834 // bewege pEndPos vor den gefundenen Bereich
835 *pEndPos
= *pCurCrsr
->Start();
837 // bewege pSttPos hinter den gefundenen Bereich
838 *pSttPos
= *pCurCrsr
->End();
840 if( *pSttPos
== *pEndPos
) // im Bereich, aber am Ende
843 if( !nCrsrCnt
&& pPHdl
)
845 pPHdl
->NextPos( *aRegion
.GetMark() );
849 if( bEnde
|| !( eFndRngs
& ( FND_IN_SELALL
| FND_IN_SEL
)) )
852 pTmpCrsr
= ((SwPaM
*)pTmpCrsr
->GetNext());
853 if( nCrsrCnt
&& pPHdl
)
855 pPHdl
->NextPos( ++pPHdl
->nActPos
);
858 } while( pTmpCrsr
!= pSaveCrsr
);
860 if( nFound
&& !pFndRing
) // falls kein Ring aufgebaut werden soll
861 pFndRing
= pCurCrsr
->Create();
864 pDoc
->DoUndo( bDoesUndo
);
869 int lcl_MakeSelFwrd( const SwNode
& rSttNd
, const SwNode
& rEndNd
,
870 SwPaM
& rPam
, int bFirst
)
872 if( rSttNd
.GetIndex() + 1 == rEndNd
.GetIndex() )
875 SwNodes
& rNds
= rPam
.GetDoc()->GetNodes();
880 rPam
.GetPoint()->nNode
= rSttNd
;
881 pCNd
= rNds
.GoNext( &rPam
.GetPoint()->nNode
);
884 pCNd
->MakeStartIndex( &rPam
.GetPoint()->nContent
);
886 else if( rSttNd
.GetIndex() > rPam
.GetPoint()->nNode
.GetIndex() ||
887 rPam
.GetPoint()->nNode
.GetIndex() >= rEndNd
.GetIndex() )
888 return FALSE
; // steht nicht in dieser Section
891 rPam
.GetPoint()->nNode
= rEndNd
;
892 pCNd
= rNds
.GoPrevious( &rPam
.GetPoint()->nNode
);
895 pCNd
->MakeEndIndex( &rPam
.GetPoint()->nContent
);
897 return *rPam
.GetMark() < *rPam
.GetPoint();
901 int lcl_MakeSelBkwrd( const SwNode
& rSttNd
, const SwNode
& rEndNd
,
902 SwPaM
& rPam
, int bFirst
)
904 if( rEndNd
.GetIndex() + 1 == rSttNd
.GetIndex() )
907 SwNodes
& rNds
= rPam
.GetDoc()->GetNodes();
912 rPam
.GetPoint()->nNode
= rSttNd
;
913 pCNd
= rNds
.GoPrevious( &rPam
.GetPoint()->nNode
);
916 pCNd
->MakeEndIndex( &rPam
.GetPoint()->nContent
);
918 else if( rEndNd
.GetIndex() > rPam
.GetPoint()->nNode
.GetIndex() ||
919 rPam
.GetPoint()->nNode
.GetIndex() >= rSttNd
.GetIndex() )
920 return FALSE
; // steht nicht in dieser Section
923 rPam
.GetPoint()->nNode
= rEndNd
;
924 pCNd
= rNds
.GoNext( &rPam
.GetPoint()->nNode
);
927 pCNd
->MakeStartIndex( &rPam
.GetPoint()->nContent
);
929 return *rPam
.GetPoint() < *rPam
.GetMark();
933 // diese Methode "sucht" fuer alle Anwendungsfaelle, denn in SwFindParas
934 // steht immer die richtigen Parameter und die entsprechende Find-Methode
936 ULONG
SwCursor::FindAll( SwFindParas
& rParas
,
937 SwDocPositions nStart
, SwDocPositions nEnde
,
938 FindRanges eFndRngs
, BOOL
& bCancel
)
941 SwCrsrSaveState
aSaveState( *this );
943 // Region erzeugen, ohne das diese in den Ring aufgenommen wird !
944 SwPaM
aRegion( *GetPoint() );
945 SwMoveFn fnMove
= MakeFindRange( nStart
, nEnde
, &aRegion
);
948 int bMvBkwrd
= fnMove
== fnMoveBackward
;
949 BOOL bInReadOnly
= IsReadOnlyAvailable();
951 SwCursor
* pFndRing
= 0;
952 SwNodes
& rNds
= GetDoc()->GetNodes();
954 // suche in Bereichen ?
955 if( FND_IN_SEL
& eFndRngs
)
957 // String nicht im Bereich gefunden, dann erhalte alle Bereiche,
958 // der Cursor beleibt unveraendert
959 if( 0 == ( nFound
= lcl_FindSelection( rParas
, this, fnMove
,
960 pFndRing
, aRegion
, eFndRngs
,
961 bInReadOnly
, bCancel
) ))
964 // der String wurde ein- bis mehrmals gefunden. Das steht alles
965 // im neuen Crsr-Ring. Darum hebe erstmal den alten Ring auf
966 while( GetNext() != this )
969 *GetPoint() = *pFndRing
->GetPoint();
971 *GetMark() = *pFndRing
->GetMark();
972 pFndRing
->MoveRingTo( this );
975 else if( FND_IN_OTHER
& eFndRngs
)
977 // Cursor als Kopie vom akt. und in den Ring aufnehmen
978 // Verkettung zeigt immer auf den zuerst erzeugten, also vorwaerts
979 SwCursor
* pSav
= Create( this ); // sicher den aktuellen Crsr
981 // wenn schon ausserhalb vom Bodytext, suche von der Position,
982 // ansonsten beginne mit der 1. GrundSection
984 ? lcl_MakeSelBkwrd( rNds
.GetEndOfExtras(),
985 *rNds
.GetEndOfPostIts().StartOfSectionNode(),
986 *this, rNds
.GetEndOfExtras().GetIndex() >=
987 GetPoint()->nNode
.GetIndex() )
988 : lcl_MakeSelFwrd( *rNds
.GetEndOfPostIts().StartOfSectionNode(),
989 rNds
.GetEndOfExtras(), *this,
990 rNds
.GetEndOfExtras().GetIndex() >=
991 GetPoint()->nNode
.GetIndex() ))
993 nFound
= lcl_FindSelection( rParas
, this, fnMove
, pFndRing
,
994 aRegion
, eFndRngs
, bInReadOnly
, bCancel
);
999 // den alten wieder zurueck
1000 *GetPoint() = *pSav
->GetPoint();
1001 if( pSav
->HasMark() )
1004 *GetMark() = *pSav
->GetMark();
1012 if( !( FND_IN_SELALL
& eFndRngs
))
1014 // es sollte nur einer gesucht werden, also fuege in dazu
1015 // egal in welche Richtung, SPoint ist immer groesser als Mark,
1016 // wenn der Suchbereich gueltig ist !!
1017 *GetPoint() = *pFndRing
->GetPoint();
1019 *GetMark() = *pFndRing
->GetMark();
1023 // es wurde ein- bis mehrmals gefunden. Das steht alles
1024 // im neuen Crsr-Ring. Darum hebe erstmal den alten Ring auf
1025 while( GetNext() != this )
1028 *GetPoint() = *pFndRing
->GetPoint();
1030 *GetMark() = *pFndRing
->GetMark();
1031 pFndRing
->MoveRingTo( this );
1035 else if( FND_IN_SELALL
& eFndRngs
)
1037 SwCursor
* pSav
= Create( this ); // sicher den aktuellen Crsr
1039 const SwNode
* pSttNd
= ( FND_IN_BODYONLY
& eFndRngs
)
1040 ? rNds
.GetEndOfContent().StartOfSectionNode()
1041 : rNds
.GetEndOfPostIts().StartOfSectionNode();
1044 ? lcl_MakeSelBkwrd( rNds
.GetEndOfContent(), *pSttNd
,*this, FALSE
)
1045 : lcl_MakeSelFwrd( *pSttNd
, rNds
.GetEndOfContent(), *this, FALSE
))
1047 nFound
= lcl_FindSelection( rParas
, this, fnMove
, pFndRing
,
1048 aRegion
, eFndRngs
, bInReadOnly
, bCancel
);
1053 // den alten wieder zurueck
1054 *GetPoint() = *pSav
->GetPoint();
1055 if( pSav
->HasMark() )
1058 *GetMark() = *pSav
->GetMark();
1064 // es wurde ein- bis mehrmals gefunden. Das steht alles
1065 // im neuen Crsr-Ring. Darum hebe erstmal den alten Ring auf
1068 while( GetNext() != this )
1071 *GetPoint() = *pFndRing
->GetPoint();
1073 *GetMark() = *pFndRing
->GetMark();
1074 pFndRing
->MoveRingTo( this );
1079 // ist ein GetMark gesetzt, dann wird bei gefundenem Object
1080 // der GetMark beibehalten !! Dadurch kann ein Bereich mit der Suche
1081 // aufgespannt werden.
1082 SwPosition
aMarkPos( *GetMark() );
1083 int bMarkPos
= HasMark() && !eFndRngs
;
1085 if( 0 != (nFound
= rParas
.Find( this, fnMove
,
1086 &aRegion
, bInReadOnly
) ? 1 : 0)
1088 *GetMark() = aMarkPos
;
1091 if( nFound
&& SwCursor::IsSelOvr( nsSwCursorSelOverFlags::SELOVER_TOGGLE
) )
1097 void SwCursor::FillFindPos( SwDocPositions ePos
, SwPosition
& rPos
) const
1099 BOOL bIsStart
= TRUE
;
1100 SwCntntNode
* pCNd
= 0;
1101 SwNodes
& rNds
= GetDoc()->GetNodes();
1106 rPos
.nNode
= *rNds
.GetEndOfContent().StartOfSectionNode();
1107 pCNd
= rNds
.GoNext( &rPos
.nNode
);
1111 rPos
.nNode
= rNds
.GetEndOfContent();
1112 pCNd
= rNds
.GoPrevious( &rPos
.nNode
);
1116 case DOCPOS_OTHERSTART
:
1117 rPos
.nNode
= *rNds
[ ULONG(0) ];
1118 pCNd
= rNds
.GoNext( &rPos
.nNode
);
1121 case DOCPOS_OTHEREND
:
1122 rPos
.nNode
= *rNds
.GetEndOfContent().StartOfSectionNode();
1123 pCNd
= rNds
.GoPrevious( &rPos
.nNode
);
1127 // case DOCPOS_CURR:
1134 xub_StrLen nCPos
= 0;
1136 nCPos
= pCNd
->Len();
1137 rPos
.nContent
.Assign( pCNd
, nCPos
);
1141 short SwCursor::MaxReplaceArived()
1147 BOOL
SwCursor::IsStartWord() const
1149 return IsStartWordWT( WordType::ANYWORD_IGNOREWHITESPACES
);
1152 BOOL
SwCursor::IsEndWord() const
1154 return IsEndWordWT( WordType::ANYWORD_IGNOREWHITESPACES
);
1157 BOOL
SwCursor::IsInWord() const
1159 return IsInWordWT( WordType::ANYWORD_IGNOREWHITESPACES
);
1162 BOOL
SwCursor::GoStartWord()
1164 return GoStartWordWT( WordType::ANYWORD_IGNOREWHITESPACES
);
1167 BOOL
SwCursor::GoEndWord()
1169 return GoEndWordWT( WordType::ANYWORD_IGNOREWHITESPACES
);
1172 BOOL
SwCursor::GoNextWord()
1174 return GoNextWordWT( WordType::ANYWORD_IGNOREWHITESPACES
);
1177 BOOL
SwCursor::GoPrevWord()
1179 return GoPrevWordWT( WordType::ANYWORD_IGNOREWHITESPACES
);
1182 BOOL
SwCursor::SelectWord( const Point
* pPt
)
1184 return SelectWordWT( WordType::ANYWORD_IGNOREWHITESPACES
, pPt
);
1187 BOOL
SwCursor::IsStartWordWT( sal_Int16 nWordType
) const
1190 const SwTxtNode
* pTxtNd
= GetNode()->GetTxtNode();
1191 if( pTxtNd
&& pBreakIt
->GetBreakIter().is() )
1193 xub_StrLen nPtPos
= GetPoint()->nContent
.GetIndex();
1194 bRet
= pBreakIt
->GetBreakIter()->isBeginWord(
1195 pTxtNd
->GetTxt(), nPtPos
,
1196 pBreakIt
->GetLocale( pTxtNd
->GetLang( nPtPos
)),
1202 BOOL
SwCursor::IsEndWordWT( sal_Int16 nWordType
) const
1205 const SwTxtNode
* pTxtNd
= GetNode()->GetTxtNode();
1206 if( pTxtNd
&& pBreakIt
->GetBreakIter().is() )
1208 xub_StrLen nPtPos
= GetPoint()->nContent
.GetIndex();
1209 bRet
= pBreakIt
->GetBreakIter()->isEndWord(
1210 pTxtNd
->GetTxt(), nPtPos
,
1211 pBreakIt
->GetLocale( pTxtNd
->GetLang( nPtPos
) ),
1218 BOOL
SwCursor::IsInWordWT( sal_Int16 nWordType
) const
1221 const SwTxtNode
* pTxtNd
= GetNode()->GetTxtNode();
1222 if( pTxtNd
&& pBreakIt
->GetBreakIter().is() )
1224 xub_StrLen nPtPos
= GetPoint()->nContent
.GetIndex();
1225 Boundary aBoundary
= pBreakIt
->GetBreakIter()->getWordBoundary(
1226 pTxtNd
->GetTxt(), nPtPos
,
1227 pBreakIt
->GetLocale( pTxtNd
->GetLang( nPtPos
) ),
1231 bRet
= aBoundary
.startPos
!= aBoundary
.endPos
&&
1232 aBoundary
.startPos
<= nPtPos
&&
1233 nPtPos
<= aBoundary
.endPos
;
1236 const CharClass
& rCC
= GetAppCharClass();
1237 bRet
= rCC
.isLetterNumeric( pTxtNd
->GetTxt(), static_cast<xub_StrLen
>(aBoundary
.startPos
) );
1243 BOOL
SwCursor::IsStartEndSentence( bool bEnd
) const
1246 GetCntntNode() && GetPoint()->nContent
== GetCntntNode()->Len() :
1247 GetPoint()->nContent
.GetIndex() == 0;
1251 SwCursor
aCrsr(*GetPoint(), 0, false);
1252 SwPosition aOrigPos
= *aCrsr
.GetPoint();
1253 aCrsr
.GoSentence( bEnd
? SwCursor::END_SENT
: SwCursor::START_SENT
);
1254 bRet
= aOrigPos
== *aCrsr
.GetPoint();
1260 BOOL
SwCursor::GoStartWordWT( sal_Int16 nWordType
)
1263 const SwTxtNode
* pTxtNd
= GetNode()->GetTxtNode();
1264 if( pTxtNd
&& pBreakIt
->GetBreakIter().is() )
1266 SwCrsrSaveState
aSave( *this );
1267 xub_StrLen nPtPos
= GetPoint()->nContent
.GetIndex();
1268 nPtPos
= (xub_StrLen
)pBreakIt
->GetBreakIter()->getWordBoundary(
1269 pTxtNd
->GetTxt(), nPtPos
,
1270 pBreakIt
->GetLocale( pTxtNd
->GetLang( nPtPos
) ),
1274 if( nPtPos
< pTxtNd
->GetTxt().Len() )
1276 GetPoint()->nContent
= nPtPos
;
1284 BOOL
SwCursor::GoEndWordWT( sal_Int16 nWordType
)
1287 const SwTxtNode
* pTxtNd
= GetNode()->GetTxtNode();
1288 if( pTxtNd
&& pBreakIt
->GetBreakIter().is() )
1290 SwCrsrSaveState
aSave( *this );
1291 xub_StrLen nPtPos
= GetPoint()->nContent
.GetIndex();
1292 nPtPos
= (xub_StrLen
)pBreakIt
->GetBreakIter()->getWordBoundary(
1293 pTxtNd
->GetTxt(), nPtPos
,
1294 pBreakIt
->GetLocale( pTxtNd
->GetLang( nPtPos
) ),
1298 if( nPtPos
<= pTxtNd
->GetTxt().Len() &&
1299 GetPoint()->nContent
.GetIndex() != nPtPos
)
1301 GetPoint()->nContent
= nPtPos
;
1309 BOOL
SwCursor::GoNextWordWT( sal_Int16 nWordType
)
1312 const SwTxtNode
* pTxtNd
= GetNode()->GetTxtNode();
1313 if( pTxtNd
&& pBreakIt
->GetBreakIter().is() )
1315 SwCrsrSaveState
aSave( *this );
1316 xub_StrLen nPtPos
= GetPoint()->nContent
.GetIndex();
1318 nPtPos
= (xub_StrLen
)pBreakIt
->GetBreakIter()->nextWord(
1319 pTxtNd
->GetTxt(), nPtPos
,
1320 pBreakIt
->GetLocale( pTxtNd
->GetLang( nPtPos
, 1 ) ),
1321 nWordType
).startPos
;
1323 if( nPtPos
< pTxtNd
->GetTxt().Len() )
1325 GetPoint()->nContent
= nPtPos
;
1333 BOOL
SwCursor::GoPrevWordWT( sal_Int16 nWordType
)
1336 const SwTxtNode
* pTxtNd
= GetNode()->GetTxtNode();
1337 if( pTxtNd
&& pBreakIt
->GetBreakIter().is() )
1339 SwCrsrSaveState
aSave( *this );
1340 xub_StrLen nPtPos
= GetPoint()->nContent
.GetIndex();
1341 const xub_StrLen nPtStart
= nPtPos
;
1345 nPtPos
= (xub_StrLen
)pBreakIt
->GetBreakIter()->previousWord(
1346 pTxtNd
->GetTxt(), nPtStart
,
1347 pBreakIt
->GetLocale( pTxtNd
->GetLang( nPtPos
, 1 ) ),
1348 nWordType
).startPos
;
1350 if( nPtPos
< pTxtNd
->GetTxt().Len() )
1352 GetPoint()->nContent
= nPtPos
;
1360 BOOL
SwCursor::SelectWordWT( sal_Int16 nWordType
, const Point
* pPt
)
1362 SwCrsrSaveState
aSave( *this );
1365 BOOL bForward
= TRUE
;
1368 if( pPt
&& 0 != (pLayout
= GetDoc()->GetRootFrm()) )
1370 // set the cursor to the layout position
1372 pLayout
->GetCrsrOfst( GetPoint(), aPt
);
1375 const SwTxtNode
* pTxtNd
= GetNode()->GetTxtNode();
1376 if( pTxtNd
&& pBreakIt
->GetBreakIter().is() )
1378 xub_StrLen nPtPos
= GetPoint()->nContent
.GetIndex();
1379 Boundary
aBndry( pBreakIt
->GetBreakIter()->getWordBoundary(
1380 pTxtNd
->GetTxt(), nPtPos
,
1381 pBreakIt
->GetLocale( pTxtNd
->GetLang( nPtPos
) ),
1385 if( aBndry
.startPos
!= aBndry
.endPos
)
1387 GetPoint()->nContent
= (xub_StrLen
)aBndry
.endPos
;
1391 GetMark()->nContent
= (xub_StrLen
)aBndry
.startPos
;
1406 //-----------------------------------------------------------------------------
1407 BOOL
SwCursor::GoSentence( SentenceMoveType eMoveType
)
1410 const SwTxtNode
* pTxtNd
= GetNode()->GetTxtNode();
1411 if( pTxtNd
&& pBreakIt
->GetBreakIter().is() )
1413 //mask deleted redlines
1414 String
sNodeText(pTxtNd
->GetTxt());
1415 const SwDoc
& rDoc
= *pTxtNd
->GetDoc();
1416 const bool nShowChg
= IDocumentRedlineAccess::IsShowChanges( rDoc
.GetRedlineMode() );
1419 USHORT nAct
= rDoc
.GetRedlinePos( *pTxtNd
, USHRT_MAX
);
1420 for ( ; nAct
< rDoc
.GetRedlineTbl().Count(); nAct
++ )
1422 const SwRedline
* pRed
= rDoc
.GetRedlineTbl()[ nAct
];
1423 if ( pRed
->Start()->nNode
> pTxtNd
->GetIndex() )
1426 if( nsRedlineType_t::REDLINE_DELETE
== pRed
->GetType() )
1428 xub_StrLen nStart
, nEnd
;
1429 pRed
->CalcStartEnd( pTxtNd
->GetIndex(), nStart
, nEnd
);
1431 while ( nStart
< nEnd
&& nStart
< sNodeText
.Len() )
1432 sNodeText
.SetChar( nStart
++, CH_TXTATR_INWORD
);
1436 SwCrsrSaveState
aSave( *this );
1437 xub_StrLen nPtPos
= GetPoint()->nContent
.GetIndex();
1438 switch ( eMoveType
)
1441 nPtPos
= (xub_StrLen
)pBreakIt
->GetBreakIter()->endOfSentence(
1443 nPtPos
, pBreakIt
->GetLocale(
1444 pTxtNd
->GetLang( nPtPos
) ));
1448 nPtPos
= (xub_StrLen
)pBreakIt
->GetBreakIter()->endOfSentence(
1450 nPtPos
, pBreakIt
->GetLocale(
1451 pTxtNd
->GetLang( nPtPos
) ));
1452 while (nPtPos
!= (USHORT
) -1 && ++nPtPos
< sNodeText
.Len()
1453 && sNodeText
.GetChar(nPtPos
)== ' ' /*isWhiteSpace( aTxt.GetChar(nPtPos)*/ )
1458 nPtPos
= (xub_StrLen
)pBreakIt
->GetBreakIter()->beginOfSentence(
1460 nPtPos
, pBreakIt
->GetLocale(
1461 pTxtNd
->GetLang( nPtPos
) ));
1464 nPtPos
= (xub_StrLen
)pBreakIt
->GetBreakIter()->beginOfSentence(
1466 nPtPos
, pBreakIt
->GetLocale(
1467 pTxtNd
->GetLang( nPtPos
) ));
1469 return FALSE
; // the previous sentence is not in this paragraph
1471 nPtPos
= (xub_StrLen
)pBreakIt
->GetBreakIter()->beginOfSentence(
1473 nPtPos
- 1, pBreakIt
->GetLocale(
1474 pTxtNd
->GetLang( nPtPos
) ));
1478 // it is allowed to place the PaM just behind the last
1479 // character in the text thus <= ...Len
1480 if( nPtPos
<= pTxtNd
->GetTxt().Len() )
1482 GetPoint()->nContent
= nPtPos
;
1490 BOOL
SwTableCursor::LeftRight( BOOL bLeft
, USHORT nCnt
, USHORT
/*nMode*/,
1491 BOOL
/*bVisualAllowed*/, BOOL
/*bSkipHidden*/, BOOL
/*bInsertCrsr*/ )
1493 return bLeft
? GoPrevCell( nCnt
)
1494 : GoNextCell( nCnt
);
1498 // calculate cursor bidi level: extracted from LeftRight()
1500 SwCursor::DoSetBidiLevelLeftRight(
1501 BOOL
& io_rbLeft
, BOOL bVisualAllowed
, BOOL bInsertCrsr
)
1503 // calculate cursor bidi level
1504 const SwCntntFrm
* pSttFrm
= NULL
;
1505 SwNode
& rNode
= GetPoint()->nNode
.GetNode();
1507 if( rNode
.IsTxtNode() )
1509 const SwTxtNode
& rTNd
= *rNode
.GetTxtNode();
1510 SwIndex
& rIdx
= GetPoint()->nContent
;
1511 xub_StrLen nPos
= rIdx
.GetIndex();
1513 const SvtCTLOptions
& rCTLOptions
= SW_MOD()->GetCTLOptions();
1514 if ( bVisualAllowed
&& rCTLOptions
.IsCTLFontEnabled() &&
1515 SvtCTLOptions::MOVEMENT_VISUAL
==
1516 rCTLOptions
.GetCTLCursorMovement() )
1518 // for visual cursor travelling (used in bidi layout)
1519 // we first have to convert the logic to a visual position
1521 pSttFrm
= rTNd
.GetFrm( &aPt
, GetPoint() );
1524 BYTE nCrsrLevel
= GetCrsrBidiLevel();
1525 sal_Bool bForward
= ! io_rbLeft
;
1526 ((SwTxtFrm
*)pSttFrm
)->PrepareVisualMove( nPos
, nCrsrLevel
,
1527 bForward
, bInsertCrsr
);
1529 SetCrsrBidiLevel( nCrsrLevel
);
1530 io_rbLeft
= ! bForward
;
1535 const SwScriptInfo
* pSI
= SwScriptInfo::GetScriptInfo( rTNd
);
1538 const xub_StrLen nMoveOverPos
= io_rbLeft
?
1539 ( nPos
? nPos
- 1 : 0 ) :
1541 SetCrsrBidiLevel( pSI
->DirType( nMoveOverPos
) );
1548 BOOL
SwCursor::LeftRight( BOOL bLeft
, USHORT nCnt
, USHORT nMode
,
1549 BOOL bVisualAllowed
,BOOL bSkipHidden
, BOOL bInsertCrsr
)
1551 // calculate cursor bidi level
1552 SwNode
& rNode
= GetPoint()->nNode
.GetNode();
1553 const SwCntntFrm
* pSttFrm
= // may side-effect bLeft!
1554 DoSetBidiLevelLeftRight(bLeft
, bVisualAllowed
, bInsertCrsr
);
1556 // kann der Cursor n-mal weiterverschoben werden ?
1557 SwCrsrSaveState
aSave( *this );
1558 SwMoveFn fnMove
= bLeft
? fnMoveBackward
: fnMoveForward
;
1562 fnGo
= CRSR_SKIP_CELLS
== nMode
? fnGoCntntCellsSkipHidden
: fnGoCntntSkipHidden
;
1564 fnGo
= CRSR_SKIP_CELLS
== nMode
? fnGoCntntCells
: fnGoCntnt
;
1566 // ASSERT( not in covered cell )
1570 SwNodeIndex
aOldNodeIdx( GetPoint()->nNode
);
1572 bool bSuccess
= Move( fnMove
, fnGo
);
1576 // If we were located inside a covered cell but our position has been
1577 // corrected, we check if the last move has moved the cursor to a different
1578 // table cell. In this case we set the cursor to the stored covered position
1579 // and redo the move:
1580 if ( mnRowSpanOffset
)
1582 const SwNode
* pOldTabBoxSttNode
= aOldNodeIdx
.GetNode().FindTableBoxStartNode();
1583 const SwTableNode
* pOldTabSttNode
= pOldTabBoxSttNode
? pOldTabBoxSttNode
->FindTableNode() : 0;
1584 const SwNode
* pNewTabBoxSttNode
= GetPoint()->nNode
.GetNode().FindTableBoxStartNode();
1585 const SwTableNode
* pNewTabSttNode
= pNewTabBoxSttNode
? pNewTabBoxSttNode
->FindTableNode() : 0;
1587 const bool bCellChanged
= pOldTabSttNode
&& pNewTabSttNode
&&
1588 pOldTabSttNode
== pNewTabSttNode
&&
1589 pOldTabBoxSttNode
&& pNewTabBoxSttNode
&&
1590 pOldTabBoxSttNode
!= pNewTabBoxSttNode
;
1594 // Set cursor to start/end of covered cell:
1595 SwTableBox
* pTableBox
= pOldTabBoxSttNode
->GetTblBox();
1596 const long nRowSpan
= pTableBox
->getRowSpan();
1599 pTableBox
= & pTableBox
->FindEndOfRowSpan( pOldTabSttNode
->GetTable(), (USHORT
)(pTableBox
->getRowSpan() + mnRowSpanOffset
) );
1600 SwNodeIndex
& rPtIdx
= GetPoint()->nNode
;
1601 SwNodeIndex
aNewIdx( *pTableBox
->GetSttNd() );
1604 GetDoc()->GetNodes().GoNextSection( &rPtIdx
, FALSE
, FALSE
);
1605 SwCntntNode
* pCntntNode
= GetCntntNode();
1608 const xub_StrLen nTmpPos
= bLeft
? pCntntNode
->Len() : 0;
1609 GetPoint()->nContent
.Assign( pCntntNode
, nTmpPos
);
1612 bSuccess
= Move( fnMove
, fnGo
);
1618 mnRowSpanOffset
= 0;
1622 // Check if I'm inside a covered cell. Correct cursor if necessary and
1623 // store covered cell:
1624 const SwNode
* pTableBoxStartNode
= GetPoint()->nNode
.GetNode().FindTableBoxStartNode();
1625 if ( pTableBoxStartNode
)
1627 const SwTableBox
* pTableBox
= pTableBoxStartNode
->GetTblBox();
1628 if ( pTableBox
->getRowSpan() < 1 )
1630 // Store the row span offset:
1631 mnRowSpanOffset
= pTableBox
->getRowSpan();
1633 // Move cursor to non-covered cell:
1634 const SwTableNode
* pTblNd
= pTableBoxStartNode
->FindTableNode();
1635 pTableBox
= & pTableBox
->FindStartOfRowSpan( pTblNd
->GetTable(), USHRT_MAX
);
1636 SwNodeIndex
& rPtIdx
= GetPoint()->nNode
;
1637 SwNodeIndex
aNewIdx( *pTableBox
->GetSttNd() );
1640 GetDoc()->GetNodes().GoNextSection( &rPtIdx
, FALSE
, FALSE
);
1641 SwCntntNode
* pCntntNode
= GetCntntNode();
1644 const xub_StrLen nTmpPos
= bLeft
? pCntntNode
->Len() : 0;
1645 GetPoint()->nContent
.Assign( pCntntNode
, nTmpPos
);
1653 // here come some special rules for visual cursor travelling
1656 SwNode
& rTmpNode
= GetPoint()->nNode
.GetNode();
1657 if ( &rTmpNode
!= &rNode
&& rTmpNode
.IsTxtNode() )
1660 const SwCntntFrm
* pEndFrm
= ((SwTxtNode
&)rTmpNode
).GetFrm( &aPt
, GetPoint() );
1663 if ( ! pEndFrm
->IsRightToLeft() != ! pSttFrm
->IsRightToLeft() )
1666 pEndFrm
->RightMargin( this );
1668 pEndFrm
->LeftMargin( this );
1674 return 0 == nCnt
&& !IsInProtectTable( TRUE
) &&
1675 !IsSelOvr( nsSwCursorSelOverFlags::SELOVER_TOGGLE
|
1676 nsSwCursorSelOverFlags::SELOVER_CHANGEPOS
);
1679 // calculate cursor bidi level: extracted from UpDown()
1680 void SwCursor::DoSetBidiLevelUpDown()
1682 SwNode
& rNode
= GetPoint()->nNode
.GetNode();
1683 if ( rNode
.IsTxtNode() )
1685 const SwScriptInfo
* pSI
=
1686 SwScriptInfo::GetScriptInfo( (SwTxtNode
&)rNode
);
1689 SwIndex
& rIdx
= GetPoint()->nContent
;
1690 xub_StrLen nPos
= rIdx
.GetIndex();
1692 if( nPos
&& nPos
< ((SwTxtNode
&)rNode
).GetTxt().Len() )
1694 const BYTE nCurrLevel
= pSI
->DirType( nPos
);
1695 const BYTE nPrevLevel
= pSI
->DirType( nPos
- 1 );
1697 if ( nCurrLevel
% 2 != nPrevLevel
% 2 )
1699 // set cursor level to the lower of the two levels
1700 SetCrsrBidiLevel( Min( nCurrLevel
, nPrevLevel
) );
1703 SetCrsrBidiLevel( nCurrLevel
);
1709 BOOL
SwCursor::UpDown( BOOL bUp
, USHORT nCnt
,
1710 Point
* pPt
, long nUpDownX
)
1712 SwTableCursor
* pTblCrsr
= dynamic_cast<SwTableCursor
*>(this);
1713 sal_Bool bAdjustTableCrsr
= sal_False
;
1715 // vom Tabellen Crsr Point/Mark in der gleichen Box ??
1716 // dann stelle den Point an den Anfang der Box
1717 if( pTblCrsr
&& GetNode( TRUE
)->StartOfSectionNode() ==
1718 GetNode( FALSE
)->StartOfSectionNode() )
1720 if ( End() != GetPoint() )
1722 bAdjustTableCrsr
= sal_True
;
1729 SwCntntFrm
* pFrm
= GetCntntNode()->GetFrm( &aPt
, GetPoint() );
1733 SwCrsrSaveState
aSave( *this );
1738 pFrm
->GetCharRect( aTmpRect
, *GetPoint() );
1739 aPt
= aTmpRect
.Pos();
1741 nUpDownX
= pFrm
->IsVertical() ?
1742 aPt
.Y() - pFrm
->Frm().Top() :
1743 aPt
.X() - pFrm
->Frm().Left();
1746 // Bei Fussnoten ist auch die Bewegung in eine andere Fussnote erlaubt.
1747 // aber keine Selection!!
1748 const BOOL bChkRange
= pFrm
->IsInFtn() && !HasMark()
1750 const SwPosition
aOldPos( *GetPoint() );
1751 BOOL bInReadOnly
= IsReadOnlyAvailable();
1753 if ( bAdjustTableCrsr
&& !bUp
)
1755 // Special case: We have a table cursor but the start box
1756 // has more than one paragraph. If we want to go down, we have to
1757 // set the point to the last frame in the table box. This is
1758 // only necessary if we do not already have a table selection
1759 const SwStartNode
* pTblNd
= GetNode( TRUE
)->FindTableBoxStartNode();
1760 ASSERT( pTblNd
, "pTblCrsr without SwTableNode?" )
1762 if ( pTblNd
) // safety first
1764 const SwNode
* pEndNd
= pTblNd
->EndOfSectionNode();
1765 GetPoint()->nNode
= *pEndNd
;
1766 pTblCrsr
->Move( fnMoveBackward
, fnGoNode
);
1767 pFrm
= GetCntntNode()->GetFrm( &aPt
, GetPoint() );
1772 (bUp
? pFrm
->UnitUp( this, nUpDownX
, bInReadOnly
)
1773 : pFrm
->UnitDown( this, nUpDownX
, bInReadOnly
) ) &&
1774 CheckNodesRange( aOldPos
.nNode
, GetPoint()->nNode
, bChkRange
))
1776 pFrm
= GetCntntNode()->GetFrm( &aPt
, GetPoint() );
1780 if( !nCnt
&& !IsSelOvr( nsSwCursorSelOverFlags::SELOVER_TOGGLE
|
1781 nsSwCursorSelOverFlags::SELOVER_CHANGEPOS
) ) // die gesamte Anzahl durchlaufen ?
1785 // dann versuche den Cursor auf die Position zu setzen,
1786 // auf halber Heohe vom Char-Rectangle
1787 pFrm
= GetCntntNode()->GetFrm( &aPt
, GetPoint() );
1788 SwCrsrMoveState
eTmpState( MV_UPDOWN
);
1789 eTmpState
.bSetInReadOnly
= bInReadOnly
;
1791 pFrm
->GetCharRect( aTmpRect
, *GetPoint(), &eTmpState
);
1792 if ( pFrm
->IsVertical() )
1794 aPt
.X() = aTmpRect
.Center().X();
1796 aPt
.Y() = pFrm
->Frm().Top() + nUpDownX
;
1800 aPt
.Y() = aTmpRect
.Center().Y();
1802 aPt
.X() = pFrm
->Frm().Left() + nUpDownX
;
1804 pFrm
->GetCrsrOfst( GetPoint(), aPt
, &eTmpState
);
1809 *GetPoint() = aOldPos
;
1811 DoSetBidiLevelUpDown(); // calculate cursor bidi level
1817 BOOL
SwCursor::LeftRightMargin( BOOL bLeft
, BOOL bAPI
)
1820 SwCntntFrm
* pFrm
= GetCntntNode()->GetFrm( &aPt
, GetPoint() );
1822 // calculate cursor bidi level
1824 SetCrsrBidiLevel( pFrm
->IsRightToLeft() ? 1 : 0 );
1826 return pFrm
&& (bLeft
? pFrm
->LeftMargin( this ) :
1827 pFrm
->RightMargin( this, bAPI
) );
1830 BOOL
SwCursor::IsAtLeftRightMargin( BOOL bLeft
, BOOL bAPI
) const
1834 SwCntntFrm
* pFrm
= GetCntntNode()->GetFrm( &aPt
, GetPoint() );
1837 SwPaM
aPam( *GetPoint() );
1838 if( !bLeft
&& aPam
.GetPoint()->nContent
.GetIndex() )
1839 aPam
.GetPoint()->nContent
--;
1840 bRet
= (bLeft
? pFrm
->LeftMargin( &aPam
)
1841 : pFrm
->RightMargin( &aPam
, bAPI
))
1842 && *aPam
.GetPoint() == *GetPoint();
1847 BOOL
SwCursor::SttEndDoc( BOOL bStt
)
1849 SwCrsrSaveState
aSave( *this );
1851 // Springe beim Selektieren nie ueber Section-Grenzen !!
1852 // kann der Cursor weiterverschoben werden ?
1853 SwMoveFn fnMove
= bStt
? fnMoveBackward
: fnMoveForward
;
1854 BOOL bRet
= (!HasMark() || !IsNoCntnt() ) &&
1855 Move( fnMove
, fnGoDoc
) &&
1856 !IsInProtectTable( TRUE
) &&
1857 !IsSelOvr( nsSwCursorSelOverFlags::SELOVER_TOGGLE
|
1858 nsSwCursorSelOverFlags::SELOVER_CHANGEPOS
|
1859 nsSwCursorSelOverFlags::SELOVER_ENABLEREVDIREKTION
);
1864 BOOL
SwCursor::GoPrevNextCell( BOOL bNext
, USHORT nCnt
)
1866 const SwTableNode
* pTblNd
= GetPoint()->nNode
.GetNode().FindTableNode();
1870 // liegt vor dem StartNode der Cell ein weiterer EndNode, dann
1871 // gibt es auch eine vorherige Celle
1872 SwCrsrSaveState
aSave( *this );
1873 SwNodeIndex
& rPtIdx
= GetPoint()->nNode
;
1877 const SwNode
* pTableBoxStartNode
= rPtIdx
.GetNode().FindTableBoxStartNode();
1878 const SwTableBox
* pTableBox
= pTableBoxStartNode
->GetTblBox();
1880 // Check if we have to move the cursor to a covered cell before
1882 if ( mnRowSpanOffset
)
1884 if ( pTableBox
->getRowSpan() > 1 )
1886 pTableBox
= & pTableBox
->FindEndOfRowSpan( pTblNd
->GetTable(), (USHORT
)(pTableBox
->getRowSpan() + mnRowSpanOffset
) );
1887 SwNodeIndex
aNewIdx( *pTableBox
->GetSttNd() );
1889 pTableBoxStartNode
= rPtIdx
.GetNode().FindTableBoxStartNode();
1891 mnRowSpanOffset
= 0;
1894 const SwNode
* pTmpNode
= bNext
?
1895 pTableBoxStartNode
->EndOfSectionNode() :
1898 SwNodeIndex
aCellIdx( *pTmpNode
, bNext
? 1 : -1 );
1899 if( (bNext
&& !aCellIdx
.GetNode().IsStartNode()) ||
1900 (!bNext
&& !aCellIdx
.GetNode().IsEndNode()) )
1903 rPtIdx
= bNext
? aCellIdx
: SwNodeIndex(*aCellIdx
.GetNode().StartOfSectionNode());
1905 pTableBoxStartNode
= rPtIdx
.GetNode().FindTableBoxStartNode();
1906 pTableBox
= pTableBoxStartNode
->GetTblBox();
1907 if ( pTableBox
->getRowSpan() < 1 )
1909 mnRowSpanOffset
= pTableBox
->getRowSpan();
1910 // move cursor to non-covered cell:
1911 pTableBox
= & pTableBox
->FindStartOfRowSpan( pTblNd
->GetTable(), USHRT_MAX
);
1912 SwNodeIndex
aNewIdx( *pTableBox
->GetSttNd() );
1918 if( !rPtIdx
.GetNode().IsCntntNode() )
1919 GetDoc()->GetNodes().GoNextSection( &rPtIdx
, TRUE
, FALSE
);
1920 GetPoint()->nContent
.Assign( GetCntntNode(), 0 );
1922 return !IsInProtectTable( TRUE
);
1925 BOOL
SwTableCursor::GotoTable( const String
& /*rName*/ )
1927 return FALSE
; // invalid action
1930 BOOL
SwCursor::GotoTable( const String
& rName
)
1935 SwTable
* pTmpTbl
= SwTable::FindTable( GetDoc()->FindTblFmtByName( rName
) );
1938 // eine Tabelle im normalen NodesArr
1939 SwCrsrSaveState
aSave( *this );
1940 GetPoint()->nNode
= *pTmpTbl
->GetTabSortBoxes()[ 0 ]->
1941 GetSttNd()->FindTableNode();
1942 Move( fnMoveForward
, fnGoCntnt
);
1949 BOOL
SwCursor::GotoTblBox( const String
& rName
)
1952 const SwTableNode
* pTblNd
= GetPoint()->nNode
.GetNode().FindTableNode();
1955 // erfrage die Box, mit dem Nanen
1956 const SwTableBox
* pTblBox
= pTblNd
->GetTable().GetTblBox( rName
);
1957 if( pTblBox
&& pTblBox
->GetSttNd() &&
1958 ( !pTblBox
->GetFrmFmt()->GetProtect().IsCntntProtected() ||
1959 IsReadOnlyAvailable() ) )
1961 SwCrsrSaveState
aSave( *this );
1962 GetPoint()->nNode
= *pTblBox
->GetSttNd();
1963 Move( fnMoveForward
, fnGoCntnt
);
1970 BOOL
SwCursor::MovePara(SwWhichPara fnWhichPara
, SwPosPara fnPosPara
)
1972 //JP 28.8.2001: for optimization test something before
1973 const SwNode
* pNd
= &GetPoint()->nNode
.GetNode();
1974 bool bShortCut
= false;
1975 if ( fnWhichPara
== fnParaCurr
)
1977 // --> FME 2005-02-21 #i41048#
1978 // If fnWhichPara == fnParaCurr, (*fnWhichPara)( *this, fnPosPara )
1979 // can already move the cursor to a different text node. In this case
1980 // we better check if IsSelOvr().
1981 const SwCntntNode
* pCntntNd
= pNd
->GetCntntNode();
1984 const xub_StrLen nSttEnd
= fnPosPara
== fnMoveForward
? 0 : pCntntNd
->Len();
1985 if ( GetPoint()->nContent
.GetIndex() != nSttEnd
)
1992 if ( pNd
->IsTxtNode() &&
1993 pNd
->GetNodes()[ pNd
->GetIndex() +
1994 (fnWhichPara
== fnParaNext
? 1 : -1 ) ]->IsTxtNode() )
1999 return (*fnWhichPara
)( *this, fnPosPara
);
2001 // else we must use the SaveStructure, because the next/prev is not
2002 // a same node type.
2003 SwCrsrSaveState
aSave( *this );
2004 return (*fnWhichPara
)( *this, fnPosPara
) &&
2005 !IsInProtectTable( TRUE
) &&
2006 !IsSelOvr( nsSwCursorSelOverFlags::SELOVER_TOGGLE
|
2007 nsSwCursorSelOverFlags::SELOVER_CHANGEPOS
);
2011 BOOL
SwCursor::MoveSection( SwWhichSection fnWhichSect
,
2012 SwPosSection fnPosSect
)
2014 SwCrsrSaveState
aSave( *this );
2015 return (*fnWhichSect
)( *this, fnPosSect
) &&
2016 !IsInProtectTable( TRUE
) &&
2017 !IsSelOvr( nsSwCursorSelOverFlags::SELOVER_TOGGLE
|
2018 nsSwCursorSelOverFlags::SELOVER_CHANGEPOS
);
2022 BOOL MoveTable( SwWhichTable, SwPosTable );
2023 BOOL MoveColumn( SwWhichColumn, SwPosColumn );
2024 BOOL MoveRegion( SwWhichRegion, SwPosRegion );
2027 void SwCursor::RestoreSavePos() // Point auf die SavePos setzen
2031 GetPoint()->nNode
= pSavePos
->nNode
;
2032 GetPoint()->nContent
.Assign( GetCntntNode(), pSavePos
->nCntnt
);
2039 SwTableCursor::SwTableCursor( const SwPosition
&rPos
, SwPaM
* pRing
)
2040 : SwCursor( rPos
, pRing
, false )
2044 nTblPtNd
= 0, nTblMkNd
= 0;
2045 nTblPtCnt
= 0, nTblMkCnt
= 0;
2048 SwTableCursor::~SwTableCursor() {}
2051 BOOL
lcl_SeekEntry( const SwSelBoxes
& rTmp
, const SwStartNode
* pSrch
, USHORT
& rFndPos
)
2053 ULONG nIdx
= pSrch
->GetIndex();
2055 USHORT nO
= rTmp
.Count(), nM
, nU
= 0;
2061 nM
= nU
+ ( nO
- nU
) / 2;
2062 if( rTmp
[ nM
]->GetSttNd() == pSrch
)
2067 else if( rTmp
[ nM
]->GetSttIdx() < nIdx
)
2079 SwCursor
* SwTableCursor::MakeBoxSels( SwCursor
* pAktCrsr
)
2085 // wieder in den Inhalt schieben
2087 Move( fnMoveForward
);
2089 Move( fnMoveForward
);
2095 // temp Kopie anlegen, damit alle Boxen, fuer die schon Cursor
2096 // existieren, entfernt werden koennen.
2098 aTmp
.Insert( &aSelBoxes
);
2100 //Jetzt die Alten und die neuen abgleichen.
2101 SwNodes
& rNds
= pAktCrsr
->GetDoc()->GetNodes();
2103 const SwStartNode
* pSttNd
;
2104 SwPaM
* pCur
= pAktCrsr
;
2107 pSttNd
= pCur
->GetPoint()->nNode
.GetNode().FindTableBoxStartNode();
2108 if( !pCur
->HasMark() || !pSttNd
||
2109 pSttNd
!= pCur
->GetMark()->nNode
.GetNode().FindTableBoxStartNode() )
2112 else if( lcl_SeekEntry( aTmp
, pSttNd
, nPos
))
2114 SwNodeIndex
aIdx( *pSttNd
, 1 );
2115 const SwNode
* pNd
= &aIdx
.GetNode();
2116 if( !pNd
->IsCntntNode() )
2117 pNd
= rNds
.GoNextSection( &aIdx
, TRUE
, FALSE
);
2119 SwPosition
* pPos
= pCur
->GetMark();
2120 if( pNd
!= &pPos
->nNode
.GetNode() )
2122 pPos
->nContent
.Assign( (SwCntntNode
*)pNd
, 0 );
2124 aIdx
.Assign( *pSttNd
->EndOfSectionNode(), - 1 );
2125 if( !( pNd
= &aIdx
.GetNode())->IsCntntNode() )
2126 pNd
= rNds
.GoPrevSection( &aIdx
, TRUE
, FALSE
);
2128 pPos
= pCur
->GetPoint();
2129 if( pNd
!= &pPos
->nNode
.GetNode() )
2131 pPos
->nContent
.Assign( (SwCntntNode
*)pNd
, ((SwCntntNode
*)pNd
)->Len() );
2133 aTmp
.Remove( nPos
);
2138 pCur
= (SwPaM
*)pCur
->GetNext();
2141 SwPaM
* pDel
= (SwPaM
*)pCur
->GetPrev();
2143 JP 20.07.98: der alte Code geht mit dem UNO-TableCrsr nicht
2144 if( pDel == pAktCrsr )
2146 if( pAktCrsr->GetNext() == pAktCrsr )
2148 pAktCrsr->DeleteMark();
2149 break; // es gibt nichts mehr zu loeschen!
2151 pAktCrsr = (SwCursor*)pDel->GetPrev();
2156 if( pDel
== pAktCrsr
)
2157 pAktCrsr
->DeleteMark();
2161 } while ( pAktCrsr
!= pCur
);
2163 for( nPos
= 0; nPos
< aTmp
.Count(); ++nPos
)
2165 pSttNd
= aTmp
[ nPos
]->GetSttNd();
2167 SwNodeIndex
aIdx( *pSttNd
, 1 );
2168 if( &aIdx
.GetNodes() != &rNds
)
2170 const SwNode
* pNd
= &aIdx
.GetNode();
2171 if( !pNd
->IsCntntNode() )
2172 pNd
= rNds
.GoNextSection( &aIdx
, TRUE
, FALSE
);
2175 if( pAktCrsr
->GetNext() == pAktCrsr
&& !pAktCrsr
->HasMark() )
2178 pNew
->GetPoint()->nNode
= *pNd
;
2179 pNew
->GetPoint()->nContent
.Assign( (SwCntntNode
*)pNd
, 0 );
2183 pNew
= pAktCrsr
->Create( pAktCrsr
);
2184 pNew
->GetPoint()->nNode
= *pNd
;
2185 pNew
->GetPoint()->nContent
.Assign( (SwCntntNode
*)pNd
, 0 );
2189 SwPosition
* pPos
= pNew
->GetPoint();
2190 pPos
->nNode
.Assign( *pSttNd
->EndOfSectionNode(), - 1 );
2191 if( !( pNd
= &pPos
->nNode
.GetNode())->IsCntntNode() )
2192 pNd
= rNds
.GoPrevSection( &pPos
->nNode
, TRUE
, FALSE
);
2194 pPos
->nContent
.Assign( (SwCntntNode
*)pNd
, ((SwCntntNode
*)pNd
)->Len() );
2201 void SwTableCursor::InsertBox( const SwTableBox
& rTblBox
)
2203 SwTableBox
* pBox
= (SwTableBox
*)&rTblBox
;
2204 aSelBoxes
.Insert( pBox
);
2208 bool SwTableCursor::NewTableSelection()
2211 const SwNode
*pStart
= GetCntntNode()->FindTableBoxStartNode();
2212 const SwNode
*pEnd
= GetCntntNode(FALSE
)->FindTableBoxStartNode();
2213 if( pStart
&& pEnd
)
2215 const SwTableNode
*pTableNode
= pStart
->FindTableNode();
2216 if( pTableNode
== pEnd
->FindTableNode() &&
2217 pTableNode
->GetTable().IsNewModel() )
2221 aNew
.Insert( &aSelBoxes
);
2222 pTableNode
->GetTable().CreateSelection( pStart
, pEnd
, aNew
,
2223 SwTable::SEARCH_NONE
, false );
2224 ActualizeSelection( aNew
);
2230 void SwTableCursor::ActualizeSelection( const SwSelBoxes
&rNew
)
2232 USHORT nOld
= 0, nNew
= 0;
2233 while ( nOld
< aSelBoxes
.Count() && nNew
< rNew
.Count() )
2235 const SwTableBox
* pPOld
= *( aSelBoxes
.GetData() + nOld
);
2236 const SwTableBox
* pPNew
= *( rNew
.GetData() + nNew
);
2237 if( pPOld
== pPNew
)
2238 { // this box will stay
2242 else if( pPOld
->GetSttIdx() < pPNew
->GetSttIdx() )
2243 DeleteBox( nOld
); // this box has to go
2246 InsertBox( *pPNew
); // this is a new one
2252 while( nOld
< aSelBoxes
.Count() )
2253 DeleteBox( nOld
); // some more to delete
2255 for( ; nNew
< rNew
.Count(); ++nNew
) // some more to insert
2256 InsertBox( **( rNew
.GetData() + nNew
) );
2259 BOOL
SwTableCursor::IsCrsrMovedUpdt()
2261 if( !IsCrsrMoved() )
2264 nTblMkNd
= GetMark()->nNode
.GetIndex();
2265 nTblPtNd
= GetPoint()->nNode
.GetIndex();
2266 nTblMkCnt
= GetMark()->nContent
.GetIndex();
2267 nTblPtCnt
= GetPoint()->nContent
.GetIndex();
2272 // Parke den Tabellen-Cursor auf dem StartNode der Boxen.
2273 void SwTableCursor::ParkCrsr()
2275 // Index aus dem TextNode abmelden
2276 SwNode
* pNd
= &GetPoint()->nNode
.GetNode();
2277 if( !pNd
->IsStartNode() )
2278 pNd
= pNd
->StartOfSectionNode();
2279 GetPoint()->nNode
= *pNd
;
2280 GetPoint()->nContent
.Assign( 0, 0 );
2282 pNd
= &GetMark()->nNode
.GetNode();
2283 if( !pNd
->IsStartNode() )
2284 pNd
= pNd
->StartOfSectionNode();
2285 GetMark()->nNode
= *pNd
;
2286 GetMark()->nContent
.Assign( 0, 0 );
2293 BOOL
SwTableCursor::HasReadOnlyBoxSel() const
2296 for( USHORT n
= aSelBoxes
.Count(); n
; )
2297 if( aSelBoxes
[ --n
]->GetFrmFmt()->GetProtect().IsCntntProtected() )