LibreOffice Module sw (master) 1
swcrsr.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20#include <hintids.hxx>
21#include <editeng/protitem.hxx>
22#include <com/sun/star/i18n/WordType.hpp>
23#include <com/sun/star/i18n/XBreakIterator.hpp>
25#include <svl/ctloptions.hxx>
26#include <svl/srchitem.hxx>
27#include <swmodule.hxx>
28#include <fmtcntnt.hxx>
29#include <swtblfmt.hxx>
30#include <swcrsr.hxx>
31#include <unocrsr.hxx>
32#include <bookmark.hxx>
33#include <doc.hxx>
34#include <IDocumentUndoRedo.hxx>
37#include <docary.hxx>
38#include <ndtxt.hxx>
39#include <section.hxx>
40#include <swtable.hxx>
41#include <cntfrm.hxx>
42#include <rootfrm.hxx>
43#include <txtfrm.hxx>
44#include <notxtfrm.hxx>
45#include <scriptinfo.hxx>
46#include <crstate.hxx>
47#include <docsh.hxx>
48#include <viewsh.hxx>
49#include <frmatr.hxx>
50#include <breakit.hxx>
51#include <mdiexp.hxx>
52#include <strings.hrc>
53#include <redline.hxx>
54#include <txatbase.hxx>
56#include <memory>
57#include <comphelper/lok.hxx>
58#include <editsh.hxx>
59
60#include <viewopt.hxx>
61
62using namespace ::com::sun::star::i18n;
63
64const sal_uInt16 coSrchRplcThreshold = 60000;
65
66namespace {
67
68struct PercentHdl
69{
70 SwDocShell* pDSh;
71 sal_uLong nActPos;
72 bool bBack, bNodeIdx;
73
74 PercentHdl( sal_uLong nStt, sal_uLong nEnd, SwDocShell* pSh )
75 : pDSh(pSh), nActPos(nStt), bBack(false), bNodeIdx(false)
76 {
77 bBack = (nStt > nEnd);
78 if( bBack )
79 std::swap( nStt, nEnd );
80 ::StartProgress( STR_STATSTR_SEARCH, nStt, nEnd );
81 }
82
83 explicit PercentHdl( const SwPaM& rPam )
84 : pDSh( rPam.GetDoc().GetDocShell() )
85 {
86 sal_Int32 nStt, nEnd;
87 if( rPam.GetPoint()->GetNode() == rPam.GetMark()->GetNode() )
88 {
89 bNodeIdx = false;
90 nStt = rPam.GetMark()->GetContentIndex();
91 nEnd = rPam.GetPoint()->GetContentIndex();
92 }
93 else
94 {
95 bNodeIdx = true;
96 nStt = sal_Int32(rPam.GetMark()->GetNodeIndex());
97 nEnd = sal_Int32(rPam.GetPoint()->GetNodeIndex());
98 }
99 nActPos = nStt;
100 bBack = (nStt > nEnd );
101 if( bBack )
102 std::swap( nStt, nEnd );
103 ::StartProgress( STR_STATSTR_SEARCH, nStt, nEnd, pDSh );
104 }
105
106 ~PercentHdl() { ::EndProgress( pDSh ); }
107
108 void NextPos( sal_uLong nPos ) const
109 { ::SetProgressState( bBack ? nActPos - nPos : nPos, pDSh ); }
110
111 void NextPos( SwPosition const & rPos ) const
112 {
113 sal_Int32 nPos;
114 if( bNodeIdx )
115 nPos = sal_Int32(rPos.GetNodeIndex());
116 else
117 nPos = rPos.GetContentIndex();
118 ::SetProgressState( bBack ? nActPos - nPos : nPos, pDSh );
119 }
120};
121
122}
123
124SwCursor::SwCursor( const SwPosition &rPos, SwPaM* pRing )
125 : SwPaM( rPos, pRing )
126 , m_nRowSpanOffset(0)
127 , m_nCursorBidiLevel(0)
128 , m_bColumnSelection(false)
129{
130}
131
132// @@@ semantic: no copy ctor.
133SwCursor::SwCursor(SwCursor const& rCpy, SwPaM *const pRing)
134 : SwPaM( rCpy, pRing )
135 , m_nRowSpanOffset(rCpy.m_nRowSpanOffset)
136 , m_nCursorBidiLevel(rCpy.m_nCursorBidiLevel)
137 , m_bColumnSelection(rCpy.m_bColumnSelection)
138{
139}
140
142{
143}
144
146{
147 return new SwCursor( *GetPoint(), pRing );
148}
149
151{
152 return false;
153}
154
156{
157 return true;
158}
159
161{
162 return !IsReadOnlyAvailable();
163}
164
165// CreateNewSavePos is virtual so that derived classes of cursor can implement
166// own SaveObjects if needed and validate them in the virtual check routines.
168{
169 m_vSavePos.emplace_back( *this );
170}
171
173{
174 if (!m_vSavePos.empty()) // Robust
175 {
176 m_vSavePos.pop_back();
177 }
178}
179
182{
183 return GetPoint()->GetNodeIndex() <
185}
186
188{
189 return false;
190}
191
192// extracted from IsSelOvr()
194{
195 SwNodes& rNds = GetDoc().GetNodes();
196 // check sections of nodes array
198 && HasMark() )
199 {
200 SwNodeIndex aOldPos( rNds, GetSavePos()->nNode );
201 if( !CheckNodesRange( aOldPos.GetNode(), GetPoint()->GetNode(), true ))
202 {
203 GetPoint()->Assign( aOldPos );
204 GetPoint()->SetContent( GetSavePos()->nContent );
205 return true;
206 }
207 }
208 return SwCursor::IsSelOvrCheck(eFlags);
209}
210
211namespace
212{
213 const SwTextAttr* InputFieldAtPos(SwPosition const *pPos)
214 {
215 SwTextNode* pTextNd = pPos->GetNode().GetTextNode();
216 if (!pTextNd)
217 return nullptr;
219 }
220}
221
223{
224 SwDoc& rDoc = GetDoc();
225 SwNodes& rNds = rDoc.GetNodes();
226
227 bool bSkipOverHiddenSections = IsSkipOverHiddenSections();
228 bool bSkipOverProtectSections = IsSkipOverProtectSections();
229
230 if ( IsSelOvrCheck( eFlags ) )
231 {
232 return true;
233 }
234
235 if (m_vSavePos.back().nNode != GetPoint()->GetNodeIndex() &&
236 // (1997) in UI-ReadOnly everything is allowed
237 ( !rDoc.GetDocShell() || !rDoc.GetDocShell()->IsReadOnlyUI() ))
238 {
239 // check new sections
240 SwPosition& rPtPos = *GetPoint();
241 const SwSectionNode* pSectNd = rPtPos.GetNode().FindSectionNode();
242 if( pSectNd &&
243 ((bSkipOverHiddenSections && pSectNd->GetSection().IsHiddenFlag() ) ||
244 (bSkipOverProtectSections && pSectNd->GetSection().IsProtectFlag() )))
245 {
246 if( !( SwCursorSelOverFlags::ChangePos & eFlags ) )
247 {
248 // then we're already done
250 return true;
251 }
252
253 // set cursor to new position:
254 SwNodeIndex aIdx( rPtPos.GetNode() );
255 sal_Int32 nContentPos = m_vSavePos.back().nContent;
256 bool bGoNxt = m_vSavePos.back().nNode < rPtPos.GetNodeIndex();
257 SwContentNode* pCNd = bGoNxt
258 ? rNds.GoNextSection( &rPtPos, bSkipOverHiddenSections, bSkipOverProtectSections)
259 : SwNodes::GoPrevSection( &rPtPos, bSkipOverHiddenSections, bSkipOverProtectSections);
260 if( !pCNd && ( SwCursorSelOverFlags::EnableRevDirection & eFlags ))
261 {
262 bGoNxt = !bGoNxt;
263 pCNd = bGoNxt ? rNds.GoNextSection( &rPtPos, bSkipOverHiddenSections, bSkipOverProtectSections)
264 : SwNodes::GoPrevSection( &rPtPos, bSkipOverHiddenSections, bSkipOverProtectSections);
265 }
266
267 bool bIsValidPos = nullptr != pCNd;
268 const bool bValidNodesRange = bIsValidPos &&
269 ::CheckNodesRange( rPtPos.GetNode(), aIdx.GetNode(), true );
270 if( !bValidNodesRange )
271 {
272 rPtPos.Assign( m_vSavePos.back().nNode );
273 pCNd = rPtPos.GetNode().GetContentNode();
274 if( !pCNd )
275 {
276 bIsValidPos = false;
277 nContentPos = 0;
278 rPtPos.Assign( aIdx );
279 pCNd = rPtPos.GetNode().GetContentNode();
280 if( !pCNd )
281 {
282 // then to the beginning of the document
283 rPtPos.Assign( rNds.GetEndOfExtras() );
284 pCNd = rNds.GoNext( &rPtPos );
285 }
286 }
287 }
288
289 // register ContentIndex:
290 const sal_Int32 nTmpPos = bIsValidPos ? (bGoNxt ? 0 : pCNd->Len()) : nContentPos;
291 GetPoint()->SetContent( nTmpPos );
292 if( !bIsValidPos || !bValidNodesRange ||
293 IsInProtectTable( true ) )
294 return true;
295 }
296
297 // is there a protected section in the section?
298 if( HasMark() && bSkipOverProtectSections)
299 {
300 SwNodeOffset nSttIdx = GetMark()->GetNodeIndex(),
301 nEndIdx = GetPoint()->GetNodeIndex();
302 if( nEndIdx <= nSttIdx )
303 std::swap( nSttIdx, nEndIdx );
304
305 const SwSectionFormats& rFormats = rDoc.GetSections();
306 for( SwSectionFormats::size_type n = 0; n < rFormats.size(); ++n )
307 {
308 const SwSectionFormat* pFormat = rFormats[n];
309 const SvxProtectItem& rProtect = pFormat->GetProtect();
310 if( rProtect.IsContentProtected() )
311 {
312 const SwFormatContent& rContent = pFormat->GetContent(false);
313 OSL_ENSURE( rContent.GetContentIdx(), "No SectionNode?" );
314 SwNodeOffset nIdx = rContent.GetContentIdx()->GetIndex();
315 if( nSttIdx <= nIdx && nEndIdx >= nIdx )
316 {
317 // if it is no linked section then we cannot select it
318 const SwSection& rSect = *pFormat->GetSection();
319 if( SectionType::Content == rSect.GetType() )
320 {
322 return true;
323 }
324 }
325 }
326 }
327 }
328 }
329
330 const SwNode* pNd = &GetPoint()->GetNode();
331 if( pNd->IsContentNode() && !dynamic_cast<SwUnoCursor*>(this) )
332 {
333 const SwContentFrame* pFrame = static_cast<const SwContentNode*>(pNd)->getLayoutFrame( rDoc.getIDocumentLayoutAccess().GetCurrentLayout() );
334 if ( (SwCursorSelOverFlags::ChangePos & eFlags) //allowed to change position if it's a bad one
335 && pFrame && pFrame->isFrameAreaDefinitionValid()
336 && !pFrame->getFrameArea().Height() //a bad zero height position
337 && !InputFieldAtPos(GetPoint()) ) //unless it's a (vertical) input field
338 {
339 // skip to the next/prev valid paragraph with a layout
340 SwPosition& rPtPos = *GetPoint();
341 bool bGoNxt = m_vSavePos.back().nNode < rPtPos.GetNodeIndex();
342 for (;;)
343 {
344 pFrame = bGoNxt ? pFrame->FindNextCnt(true) : pFrame->FindPrevCnt();
345 if (!pFrame || 0 != pFrame->getFrameArea().Height() )
346 break;
347 }
348
349 // #i72394# skip to prev/next valid paragraph with a layout in case
350 // the first search did not succeed:
351 if( !pFrame )
352 {
353 bGoNxt = !bGoNxt;
354 pFrame = static_cast<const SwContentNode*>(pNd)->getLayoutFrame( rDoc.getIDocumentLayoutAccess().GetCurrentLayout() );
355 while ( pFrame && 0 == pFrame->getFrameArea().Height() )
356 {
357 pFrame = bGoNxt ? pFrame->FindNextCnt(true) : pFrame->FindPrevCnt();
358 }
359 }
360
361 if (pFrame != nullptr)
362 {
363 if (pFrame->IsTextFrame())
364 {
365 SwTextFrame const*const pTextFrame(static_cast<SwTextFrame const*>(pFrame));
366 *GetPoint() = pTextFrame->MapViewToModelPos(TextFrameIndex(
367 bGoNxt ? 0 : pTextFrame->GetText().getLength()));
368 }
369 else
370 {
371 assert(pFrame->IsNoTextFrame());
372 SwContentNode *const pCNd = const_cast<SwContentNode*>(
373 static_cast<SwNoTextFrame const*>(pFrame)->GetNode());
374 assert(pCNd);
375
376 // set this ContentNode as new position
377 rPtPos.Assign( *pCNd );
378 // assign corresponding ContentIndex
379 const sal_Int32 nTmpPos = bGoNxt ? 0 : pCNd->Len();
380 GetPoint()->SetContent( nTmpPos );
381 }
382
383
384 if (rPtPos.GetNodeIndex() == m_vSavePos.back().nNode
385 && GetPoint()->GetContentIndex() == m_vSavePos.back().nContent)
386 {
387 // new position equals saved one
388 // --> trigger restore of saved pos by setting <pFrame> to NULL - see below
389 pFrame = nullptr;
390 }
391
392 if ( IsInProtectTable( true ) )
393 {
394 // new position in protected table
395 // --> trigger restore of saved pos by setting <pFrame> to NULL - see below
396 pFrame = nullptr;
397 }
398 }
399 }
400
401 if( !pFrame )
402 {
403 DeleteMark();
405 return true; // we need a frame
406 }
407 }
408
409 // is the cursor allowed to be in a protected node?
410 if( !( SwCursorSelOverFlags::ChangePos & eFlags ) && !IsAtValidPos() )
411 {
412 DeleteMark();
414 return true;
415 }
416
417 if( !HasMark() )
418 return false;
419
420 // check for invalid sections
421 if( !::CheckNodesRange( GetMark()->GetNode(), GetPoint()->GetNode(), true ))
422 {
423 DeleteMark();
425 return true; // we need a frame
426 }
427
428 pNd = &GetMark()->GetNode();
429 if( pNd->IsContentNode()
430 && !static_cast<const SwContentNode*>(pNd)->getLayoutFrame( rDoc.getIDocumentLayoutAccess().GetCurrentLayout() )
431 && !dynamic_cast<SwUnoCursor*>(this) )
432 {
433 DeleteMark();
435 return true; // we need a frame
436 }
437
438 // ensure that selection is only inside an InputField or contains the InputField completely
439 {
440 const SwTextAttr* pInputFieldTextAttrAtPoint = InputFieldAtPos(GetPoint());
441 const SwTextAttr* pInputFieldTextAttrAtMark = InputFieldAtPos(GetMark());
442
443 if ( pInputFieldTextAttrAtPoint != pInputFieldTextAttrAtMark )
444 {
445 const SwNodeOffset nRefNodeIdx =
447 ? m_vSavePos.back().nNode
448 : GetMark()->GetNodeIndex();
449 const sal_Int32 nRefContentIdx =
451 ? m_vSavePos.back().nContent
453 const bool bIsForwardSelection =
454 nRefNodeIdx < GetPoint()->GetNodeIndex()
455 || ( nRefNodeIdx == GetPoint()->GetNodeIndex()
456 && nRefContentIdx < GetPoint()->GetContentIndex() );
457
458 if ( pInputFieldTextAttrAtPoint != nullptr )
459 {
460 const sal_Int32 nNewPointPos =
461 bIsForwardSelection ? *(pInputFieldTextAttrAtPoint->End()) : pInputFieldTextAttrAtPoint->GetStart();
462 GetPoint()->SetContent( nNewPointPos );
463 }
464
465 if ( pInputFieldTextAttrAtMark != nullptr )
466 {
467 const sal_Int32 nNewMarkPos =
468 bIsForwardSelection ? pInputFieldTextAttrAtMark->GetStart() : *(pInputFieldTextAttrAtMark->End());
469 GetMark()->SetContent( nNewMarkPos );
470 }
471 }
472 }
473
474 const SwTableNode* pPtNd = GetPoint()->GetNode().FindTableNode();
475 const SwTableNode* pMrkNd = GetMark()->GetNode().FindTableNode();
476 // both in no or in same table node
477 if( ( !pMrkNd && !pPtNd ) || pPtNd == pMrkNd )
478 return false;
479
480 // in different tables or only mark in table
481 if( pMrkNd )
482 {
483 // not allowed, so go back to old position
485 // Cursor stays at old position
486 return true;
487 }
488
489 // Note: this cannot happen in TableMode
490 // Only Point in Table then go behind/in front of table
492 {
493 bool bSelTop = GetPoint()->GetNodeIndex() <
495 ? m_vSavePos.back().nNode : GetMark()->GetNodeIndex());
496
497 do { // loop for table after table
498 SwNodeOffset nSEIdx = pPtNd->EndOfSectionIndex();
499 SwNodeOffset nSttEndTable = nSEIdx + 1;
500
501 if( bSelTop )
502 nSttEndTable = rNds[ nSEIdx ]->StartOfSectionIndex() - 1;
503
504 GetPoint()->Assign( nSttEndTable );
505 const SwNode* pMyNd = &(GetPointNode());
506
507 if( pMyNd->IsSectionNode() || ( pMyNd->IsEndNode() &&
508 pMyNd->StartOfSectionNode()->IsSectionNode() ) )
509 {
510 pMyNd = bSelTop
511 ? SwNodes::GoPrevSection( GetPoint(),true,false )
512 : rNds.GoNextSection( GetPoint(),true,false );
513
514 /* #i12312# Handle failure of Go{Prev|Next}Section */
515 if ( nullptr == pMyNd)
516 break;
517
518 pPtNd = pMyNd->FindTableNode();
519 if( pPtNd )
520 continue;
521 }
522
523 // we permit these
524 if( pMyNd->IsContentNode() &&
526 GetPoint()->GetNode(), true ))
527 {
528 // table in table
529 const SwTableNode* pOuterTableNd = pMyNd->FindTableNode();
530 if ( pOuterTableNd )
531 pMyNd = pOuterTableNd;
532 else
533 {
534 SwContentNode* pCNd = const_cast<SwContentNode*>(static_cast<const SwContentNode*>(pMyNd));
535 GetPoint()->SetContent( bSelTop ? pCNd->Len() : 0 );
536 return false;
537 }
538 }
539 if( bSelTop )
540 {
541 if ( !pMyNd->IsEndNode() )
542 break;
543 pPtNd = pMyNd->FindTableNode();
544 }
545 else
546 pPtNd = pMyNd->GetTableNode();
547 if (!pPtNd)
548 break;
549 } while( true );
550 }
551
552 // stay on old position
554 return true;
555}
556
557bool SwCursor::IsInProtectTable( bool bMove, bool bChgCursor )
558{
560 if( !pCNd )
561 return false;
562
563 // No table, no protected cell:
564 const SwTableNode* pTableNode = pCNd->FindTableNode();
565 if ( !pTableNode )
566 return false;
567
568 // Current position == last save position?
569 if (m_vSavePos.back().nNode == GetPoint()->GetNodeIndex())
570 return false;
571
572 // Check for covered cell:
573 bool bInCoveredCell = false;
574 const SwStartNode* pTmpSttNode = pCNd->FindTableBoxStartNode();
575 OSL_ENSURE( pTmpSttNode, "In table, therefore I expect to get a SwTableBoxStartNode" );
576 const SwTableBox* pBox = pTmpSttNode ? pTableNode->GetTable().GetTableBox( pTmpSttNode->GetIndex() ) : nullptr; //Robust #151355
577 if ( pBox && pBox->getRowSpan() < 1 ) // Robust #151270
578 bInCoveredCell = true;
579
580 // Positions of covered cells are not acceptable:
581 if ( !bInCoveredCell )
582 {
583 // Position not protected?
584 if ( !pCNd->IsProtect() )
585 return false;
586
587 // Cursor in protected cells allowed?
588 if ( IsReadOnlyAvailable() )
589 return false;
590 }
591
592 // If we reach this point, we are in a protected or covered table cell!
593
594 if( !bMove )
595 {
596 if( bChgCursor )
597 // restore the last save position
599
600 return true; // Cursor stays at old position
601 }
602
603 // We are in a protected table cell. Traverse top to bottom?
604 if (m_vSavePos.back().nNode < GetPoint()->GetNodeIndex())
605 {
606 // search next valid box
607 // if there is another StartNode after the EndNode of a cell then
608 // there is another cell
609 SwNodeIndex aCellStt( *GetPointNode().FindTableBoxStartNode()->EndOfSectionNode(), 1 );
610 bool bProt = true;
612 for (;;) {
613 if( !aCellStt.GetNode().IsStartNode() )
614 break;
615 ++aCellStt;
616 pCNd = aCellStt.GetNode().GetContentNode();
617 if( !pCNd )
618 pCNd = aCellStt.GetNodes().GoNext( &aCellStt );
619 bProt = pCNd->IsProtect();
620 if( !bProt )
621 break;
622 aCellStt.Assign( *pCNd->FindTableBoxStartNode()->EndOfSectionNode(), 1 );
623 }
624
625SetNextCursor:
626 if( !bProt ) // found free cell
627 {
628 GetPoint()->Assign( aCellStt );
630 if( pTmpCNd )
631 {
632 GetPoint()->SetContent( 0 );
633 return false;
634 }
637 }
638 // end of table, so go to next node
639 ++aCellStt;
640 SwNode* pNd = &aCellStt.GetNode();
641 if( pNd->IsEndNode() || HasMark())
642 {
643 // if only table in FlyFrame or SSelection then stay on old position
644 if( bChgCursor )
646 return true;
647 }
648 else if( pNd->IsTableNode() )
649 {
650 ++aCellStt;
651 goto GoNextCell;
652 }
653
654 bProt = false; // index is now on a content node
655 goto SetNextCursor;
656 }
657
658 // search for the previous valid box
659 {
660 // if there is another EndNode in front of the StartNode than there
661 // exists a previous cell
662 SwNodeIndex aCellStt( *GetPointNode().FindTableBoxStartNode(), -1 );
663 SwNode* pNd;
664 bool bProt = true;
666 for (;;) {
667 pNd = &aCellStt.GetNode();
668 if( !pNd->IsEndNode() )
669 break;
670 aCellStt.Assign( *pNd->StartOfSectionNode(), +1 );
671 pCNd = aCellStt.GetNode().GetContentNode();
672 if( !pCNd )
673 pCNd = pNd->GetNodes().GoNext( &aCellStt );
674 bProt = pCNd->IsProtect();
675 if( !bProt )
676 break;
677 aCellStt.Assign( *pNd->FindTableBoxStartNode(), -1 );
678 }
679
680SetPrevCursor:
681 if( !bProt ) // found free cell
682 {
683 GetPoint()->Assign( aCellStt );
685 if( pTmpCNd )
686 {
687 GetPoint()->SetContent( 0 );
688 return false;
689 }
692 }
693 // at the beginning of a table, so go to next node
694 --aCellStt;
695 pNd = &aCellStt.GetNode();
696 if( pNd->IsStartNode() || HasMark() )
697 {
698 // if only table in FlyFrame or SSelection then stay on old position
699 if( bChgCursor )
701 return true;
702 }
703 else if( pNd->StartOfSectionNode()->IsTableNode() )
704 {
705 --aCellStt;
706 goto GoPrevCell;
707 }
708
709 bProt = false; // index is now on a content node
710 goto SetPrevCursor;
711 }
712}
713
715bool SwCursor::IsAtValidPos( bool bPoint ) const
716{
717 const SwDoc& rDoc = GetDoc();
718 const SwPosition* pPos = bPoint ? GetPoint() : GetMark();
719 const SwNode* pNd = &pPos->GetNode();
720
721 if( pNd->IsContentNode() && !static_cast<const SwContentNode*>(pNd)->getLayoutFrame( rDoc.getIDocumentLayoutAccess().GetCurrentLayout() ) &&
722 !dynamic_cast<const SwUnoCursor*>(this) )
723 {
724 return false;
725 }
726
727 // #i45129# - in UI-ReadOnly everything is allowed
728 if( !rDoc.GetDocShell() || !rDoc.GetDocShell()->IsReadOnlyUI() )
729 return true;
730
731 const bool bCursorInReadOnly = IsReadOnlyAvailable();
732 if( !bCursorInReadOnly && pNd->IsProtect() )
733 return false;
734
735 const SwSectionNode* pSectNd = pNd->FindSectionNode();
736 return !pSectNd
737 || !(pSectNd->GetSection().IsHiddenFlag() ||
738 ( !bCursorInReadOnly && pSectNd->GetSection().IsProtectFlag() ));
739}
740
742
745 SwDocPositions nEnd, SwPaM* pRange ) const
746{
747 pRange->SetMark();
748 FillFindPos( nStart, *pRange->GetMark() );
749 FillFindPos( nEnd, *pRange->GetPoint() );
750
751 // determine direction of search
752 return ( SwDocPositions::Start == nStart || SwDocPositions::OtherStart == nStart ||
753 (SwDocPositions::Curr == nStart &&
754 (SwDocPositions::End == nEnd || SwDocPositions::OtherEnd == nEnd ) ))
756}
757
758static sal_Int32 lcl_FindSelection( SwFindParas& rParas, SwCursor* pCurrentCursor,
759 SwMoveFnCollection const & fnMove, SwCursor*& pFndRing,
760 SwPaM& aRegion, FindRanges eFndRngs,
761 bool bInReadOnly, bool& bCancel )
762{
763 SwDoc& rDoc = pCurrentCursor->GetDoc();
764 bool const bDoesUndo = rDoc.GetIDocumentUndoRedo().DoesUndo();
765 int nFndRet = 0;
766 sal_Int32 nFound = 0;
767 const bool bSrchBkwrd = &fnMove == &fnMoveBackward;
768 SwPaM *pTmpCursor = pCurrentCursor, *pSaveCursor = pCurrentCursor;
769 std::unique_ptr<SvxSearchItem> xSearchItem;
770
771 // only create progress bar for ShellCursor
772 bool bIsUnoCursor = dynamic_cast<SwUnoCursor*>(pCurrentCursor) != nullptr;
773 std::unique_ptr<PercentHdl> pPHdl;
774 sal_uInt16 nCursorCnt = 0;
775 if( FindRanges::InSel & eFndRngs )
776 {
777 while( pCurrentCursor != ( pTmpCursor = pTmpCursor->GetNext() ))
778 ++nCursorCnt;
779 if( nCursorCnt && !bIsUnoCursor )
780 pPHdl.reset(new PercentHdl( 0, nCursorCnt, rDoc.GetDocShell() ));
781 }
782 else
783 pSaveCursor = pSaveCursor->GetPrev();
784
785 bool bEnd = false;
786 do {
787 aRegion.SetMark();
788 // independent from search direction: SPoint is always bigger than mark
789 // if the search area is valid
790 SwPosition *pSttPos = aRegion.GetMark(),
791 *pEndPos = aRegion.GetPoint();
792 *pSttPos = *pTmpCursor->Start();
793 *pEndPos = *pTmpCursor->End();
794 if( bSrchBkwrd )
795 aRegion.Exchange();
796
797 if( !nCursorCnt && !pPHdl && !bIsUnoCursor )
798 pPHdl.reset(new PercentHdl( aRegion ));
799
800 // as long as found and not at same position
801 while( *pSttPos <= *pEndPos )
802 {
803 nFndRet = rParas.DoFind(*pCurrentCursor, fnMove, aRegion, bInReadOnly, xSearchItem);
804 if( 0 == nFndRet ||
805 ( pFndRing &&
806 *pFndRing->GetPoint() == *pCurrentCursor->GetPoint() &&
807 *pFndRing->GetMark() == *pCurrentCursor->GetMark() ))
808 break;
809 if( !( FIND_NO_RING & nFndRet ))
810 {
811 // #i24084# - create ring similar to the one in CreateCursor
812 SwCursor* pNew = pCurrentCursor->Create( pFndRing );
813 if( !pFndRing )
814 pFndRing = pNew;
815
816 pNew->SetMark();
817 *pNew->GetMark() = *pCurrentCursor->GetMark();
818 }
819
820 ++nFound;
821
822 if( !( eFndRngs & FindRanges::InSelAll) )
823 {
824 bEnd = true;
825 break;
826 }
827
828 if ((coSrchRplcThreshold == nFound)
829 && rDoc.GetIDocumentUndoRedo().DoesUndo()
830 && rParas.IsReplaceMode())
831 {
832 short nRet = pCurrentCursor->MaxReplaceArived();
833 if( RET_YES == nRet )
834 {
835 rDoc.GetIDocumentUndoRedo().DelAllUndoObj();
836 rDoc.GetIDocumentUndoRedo().DoUndo(false);
837 }
838 else
839 {
840 bEnd = true;
841 if(RET_CANCEL == nRet)
842 {
843 bCancel = true;
844 }
845 break;
846 }
847 }
848
849 if( bSrchBkwrd )
850 // move pEndPos in front of the found area
851 *pEndPos = *pCurrentCursor->Start();
852 else
853 // move pSttPos behind the found area
854 *pSttPos = *pCurrentCursor->End();
855
856 if( *pSttPos == *pEndPos )
857 // in area but at the end => done
858 break;
859
860 if( !nCursorCnt && pPHdl )
861 {
862 pPHdl->NextPos( *aRegion.GetMark() );
863 }
864 }
865
866 if( bEnd || !( eFndRngs & ( FindRanges::InSelAll | FindRanges::InSel )) )
867 break;
868
869 pTmpCursor = pTmpCursor->GetNext();
870 if( nCursorCnt && pPHdl )
871 {
872 pPHdl->NextPos( ++pPHdl->nActPos );
873 }
874
875 } while( pTmpCursor != pSaveCursor && pTmpCursor->GetNext() != pTmpCursor);
876
877 if( nFound && !pFndRing ) // if no ring should be created
878 pFndRing = pCurrentCursor->Create();
879
880 rDoc.GetIDocumentUndoRedo().DoUndo(bDoesUndo);
881 return nFound;
882}
883
884static bool lcl_MakeSelFwrd( const SwNode& rSttNd, const SwNode& rEndNd,
885 SwPaM& rPam, bool bFirst )
886{
887 if( rSttNd.GetIndex() + 1 == rEndNd.GetIndex() )
888 return false;
889
890 SwNodes& rNds = rPam.GetDoc().GetNodes();
891 rPam.DeleteMark();
892 SwContentNode* pCNd;
893 if( !bFirst )
894 {
895 rPam.GetPoint()->Assign(rSttNd);
896 pCNd = rNds.GoNext( rPam.GetPoint() );
897 if( !pCNd )
898 return false;
899 rPam.GetPoint()->AssignStartIndex(*pCNd);
900 }
901 else if( rSttNd.GetIndex() > rPam.GetPoint()->GetNodeIndex() ||
902 rPam.GetPoint()->GetNodeIndex() >= rEndNd.GetIndex() )
903 // not in this section
904 return false;
905
906 rPam.SetMark();
907 rPam.GetPoint()->Assign(rEndNd);
908 pCNd = SwNodes::GoPrevious( rPam.GetPoint() );
909 if( !pCNd )
910 return false;
911 rPam.GetPoint()->AssignEndIndex(*pCNd);
912
913 return *rPam.GetMark() < *rPam.GetPoint();
914}
915
916static bool lcl_MakeSelBkwrd( const SwNode& rSttNd, const SwNode& rEndNd,
917 SwPaM& rPam, bool bFirst )
918{
919 if( rEndNd.GetIndex() + 1 == rSttNd.GetIndex() )
920 return false;
921
922 SwNodes& rNds = rPam.GetDoc().GetNodes();
923 rPam.DeleteMark();
924 SwContentNode* pCNd;
925 if( !bFirst )
926 {
927 rPam.GetPoint()->Assign(rSttNd);
928 pCNd = SwNodes::GoPrevious( rPam.GetPoint() );
929 if( !pCNd )
930 return false;
931 rPam.GetPoint()->AssignEndIndex(*pCNd);
932 }
933 else if( rEndNd.GetIndex() > rPam.GetPoint()->GetNodeIndex() ||
934 rPam.GetPoint()->GetNodeIndex() >= rSttNd.GetIndex() )
935 return false; // not in this section
936
937 rPam.SetMark();
938 rPam.GetPoint()->Assign(rEndNd);
939 pCNd = rNds.GoNext( rPam.GetPoint() );
940 if( !pCNd )
941 return false;
942 rPam.GetPoint()->SetContent(0);
943
944 return *rPam.GetPoint() < *rPam.GetMark();
945}
946
947// this method "searches" for all use cases because in SwFindParas is always the
948// correct parameters and respective search method
950 SwDocPositions nStart, SwDocPositions nEnd,
951 FindRanges eFndRngs, bool& bCancel )
952{
953 bCancel = false;
954 SwCursorSaveState aSaveState( *this );
955
956 // create region without adding it to the ring
957 SwPaM aRegion( *GetPoint() );
958 SwMoveFnCollection const & fnMove = MakeFindRange( nStart, nEnd, &aRegion );
959
960 sal_Int32 nFound = 0;
961 const bool bMvBkwrd = &fnMove == &fnMoveBackward;
962 bool bInReadOnly = IsReadOnlyAvailable();
963 std::unique_ptr<SvxSearchItem> xSearchItem;
964
965 SwCursor* pFndRing = nullptr;
966 SwNodes& rNds = GetDoc().GetNodes();
967
968 // search in sections?
969 if( FindRanges::InSel & eFndRngs )
970 {
971 // if string was not found in region then get all sections (cursors
972 // stays unchanged)
973 nFound = lcl_FindSelection( rParas, this, fnMove,
974 pFndRing, aRegion, eFndRngs,
975 bInReadOnly, bCancel );
976 if( 0 == nFound )
977 return nFound;
978
979 // found string at least once; it's all in new Cursor ring thus delete old one
980 while( GetNext() != this )
981 delete GetNext();
982
983 *GetPoint() = *pFndRing->GetPoint();
984 SetMark();
985 *GetMark() = *pFndRing->GetMark();
986 pFndRing->GetRingContainer().merge( GetRingContainer() );
987 delete pFndRing;
988 }
989 else if( FindRanges::InOther & eFndRngs )
990 {
991 // put cursor as copy of current into ring
992 // chaining points always to first created, so forward
993 SwCursor* pSav = Create( this ); // save the current cursor
994
995 // if already outside of body text search from this position or start at
996 // 1. base section
997 if( bMvBkwrd
1000 *this, rNds.GetEndOfExtras().GetIndex() >=
1001 GetPoint()->GetNodeIndex() )
1003 rNds.GetEndOfExtras(), *this,
1004 rNds.GetEndOfExtras().GetIndex() >=
1005 GetPoint()->GetNodeIndex() ))
1006 {
1007 nFound = lcl_FindSelection( rParas, this, fnMove, pFndRing,
1008 aRegion, eFndRngs, bInReadOnly, bCancel );
1009 }
1010
1011 if( !nFound )
1012 {
1013 // put back the old one
1014 *GetPoint() = *pSav->GetPoint();
1015 if( pSav->HasMark() )
1016 {
1017 SetMark();
1018 *GetMark() = *pSav->GetMark();
1019 }
1020 else
1021 DeleteMark();
1022 return 0;
1023 }
1024
1025 if( !( FindRanges::InSelAll & eFndRngs ))
1026 {
1027 // there should only be a single one, thus add it
1028 // independent from search direction: SPoint is always bigger than
1029 // mark if the search area is valid
1030 *GetPoint() = *pFndRing->GetPoint();
1031 SetMark();
1032 *GetMark() = *pFndRing->GetMark();
1033 }
1034 else
1035 {
1036 // found string at least once; it's all in new Cursor ring thus delete old one
1037 while( GetNext() != this )
1038 delete GetNext();
1039
1040 *GetPoint() = *pFndRing->GetPoint();
1041 SetMark();
1042 *GetMark() = *pFndRing->GetMark();
1043 pFndRing->GetRingContainer().merge( GetRingContainer() );
1044 }
1045 delete pFndRing;
1046 }
1047 else if( FindRanges::InSelAll & eFndRngs )
1048 {
1049 SwCursor* pSav = Create( this ); // save the current cursor
1050
1051 const SwNode* pSttNd = ( FindRanges::InBodyOnly & eFndRngs )
1054
1055 if( bMvBkwrd
1056 ? lcl_MakeSelBkwrd( rNds.GetEndOfContent(), *pSttNd, *this, false )
1057 : lcl_MakeSelFwrd( *pSttNd, rNds.GetEndOfContent(), *this, false ))
1058 {
1059 nFound = lcl_FindSelection( rParas, this, fnMove, pFndRing,
1060 aRegion, eFndRngs, bInReadOnly, bCancel );
1061 }
1062
1063 if( !nFound )
1064 {
1065 // put back the old one
1066 *GetPoint() = *pSav->GetPoint();
1067 if( pSav->HasMark() )
1068 {
1069 SetMark();
1070 *GetMark() = *pSav->GetMark();
1071 }
1072 else
1073 DeleteMark();
1074 return 0;
1075 }
1076 while( GetNext() != this )
1077 delete GetNext();
1078
1079 *GetPoint() = *pFndRing->GetPoint();
1080 SetMark();
1081 *GetMark() = *pFndRing->GetMark();
1082 pFndRing->GetRingContainer().merge( GetRingContainer() );
1083 delete pFndRing;
1084 }
1085 else
1086 {
1087 // if a GetMark is set then keep the GetMark of the found object
1088 // This allows spanning an area with this search.
1089 SwPosition aMarkPos( *GetMark() );
1090 const bool bMarkPos = HasMark() && (eFndRngs == FindRanges::InBody);
1091
1092 nFound = rParas.DoFind(*this, fnMove, aRegion, bInReadOnly, xSearchItem) ? 1 : 0;
1093 if (0 != nFound && bMarkPos)
1094 *GetMark() = aMarkPos;
1095 }
1096
1098 nFound = 0;
1099 return nFound;
1100}
1101
1103{
1104 bool bIsStart = true;
1105 SwContentNode* pCNd = nullptr;
1106 SwNodes& rNds = GetDoc().GetNodes();
1107
1108 switch( ePos )
1109 {
1112 pCNd = rNds.GoNext( &rPos );
1113 break;
1115 rPos.Assign(rNds.GetEndOfContent());
1116 pCNd = SwNodes::GoPrevious( &rPos );
1117 bIsStart = false;
1118 break;
1120 rPos.Assign( *rNds[ SwNodeOffset(0) ] );
1121 pCNd = rNds.GoNext( &rPos );
1122 break;
1124 rPos.Assign( *rNds.GetEndOfContent().StartOfSectionNode() );
1125 pCNd = SwNodes::GoPrevious( &rPos );
1126 bIsStart = false;
1127 break;
1128 default:
1129 rPos = *GetPoint();
1130 }
1131
1132 if( pCNd && !bIsStart )
1133 {
1134 rPos.AssignEndIndex( *pCNd );
1135 }
1136}
1137
1139{
1140 return RET_YES;
1141}
1142
1143namespace {
1144
1145struct HideWrapper
1146{
1147 // either the frame's text or the node's text (possibly pre-filtered)
1148 OUString const* m_pText;
1149 // this is actually a TextFrameIndex but all of the i18n code uses sal_Int32
1150 sal_Int32 m_nPtIndex;
1151 // if mapping is needed, use this frame
1152 SwTextFrame * m_pFrame;
1153 // input in the constructor, output (via mapping) in the destructor
1154 SwTextNode *& m_rpTextNode;
1155 sal_Int32 & m_rPtPos;
1156
1157 HideWrapper(SwRootFrame const*const pLayout,
1158 SwTextNode *& rpTextNode, sal_Int32 & rPtPos,
1159 OUString const*const pFilteredNodeText = nullptr)
1160 : m_pText(pFilteredNodeText)
1161 , m_pFrame(nullptr)
1162 , m_rpTextNode(rpTextNode)
1163 , m_rPtPos(rPtPos)
1164 {
1165 if (pLayout && pLayout->HasMergedParas())
1166 {
1167 m_pFrame = static_cast<SwTextFrame*>(rpTextNode->getLayoutFrame(pLayout));
1168 m_pText = &m_pFrame->GetText();
1169 m_nPtIndex = sal_Int32(m_pFrame->MapModelToView(rpTextNode, rPtPos));
1170 }
1171 else
1172 {
1173 if (!m_pText)
1174 {
1175 m_pText = &rpTextNode->GetText();
1176 }
1177 m_nPtIndex = rPtPos;
1178 }
1179 }
1180 ~HideWrapper()
1181 {
1182 AssignBack(m_rpTextNode, m_rPtPos);
1183 }
1184 void AssignBack(SwTextNode *& rpTextNode, sal_Int32 & rPtPos)
1185 {
1186 if (0 <= m_nPtIndex && m_pFrame)
1187 {
1188 std::pair<SwTextNode*, sal_Int32> const pos(
1189 m_pFrame->MapViewToModel(TextFrameIndex(m_nPtIndex)));
1190 rpTextNode = pos.first;
1191 rPtPos = pos.second;
1192 }
1193 else
1194 {
1195 rPtPos = m_nPtIndex;
1196 }
1197 }
1198};
1199
1200} // namespace
1201
1202bool SwCursor::SelectWord( SwViewShell const * pViewShell, const Point* pPt )
1203{
1204 return SelectWordWT( pViewShell, WordType::ANYWORD_IGNOREWHITESPACES, pPt );
1205}
1206
1207bool SwCursor::IsStartWordWT(sal_Int16 nWordType, SwRootFrame const*const pLayout) const
1208{
1209 bool bRet = false;
1210 SwTextNode* pTextNd = GetPointNode().GetTextNode();
1211 if (pTextNd)
1212 {
1213 sal_Int32 nPtPos = GetPoint()->GetContentIndex();
1214
1215 HideWrapper w(pLayout, pTextNd, nPtPos);
1216
1217 bRet = g_pBreakIt->GetBreakIter()->isBeginWord(
1218 *w.m_pText, w.m_nPtIndex,
1219 g_pBreakIt->GetLocale( pTextNd->GetLang( nPtPos )),
1220 nWordType );
1221 }
1222 return bRet;
1223}
1224
1225bool SwCursor::IsEndWordWT(sal_Int16 nWordType, SwRootFrame const*const pLayout) const
1226{
1227 bool bRet = false;
1228 SwTextNode* pTextNd = GetPointNode().GetTextNode();
1229 if (pTextNd)
1230 {
1231 sal_Int32 nPtPos = GetPoint()->GetContentIndex();
1232
1233 HideWrapper w(pLayout, pTextNd, nPtPos);
1234
1235 bRet = g_pBreakIt->GetBreakIter()->isEndWord(
1236 *w.m_pText, w.m_nPtIndex,
1237 g_pBreakIt->GetLocale( pTextNd->GetLang( nPtPos ) ),
1238 nWordType );
1239
1240 }
1241 return bRet;
1242}
1243
1244bool SwCursor::IsInWordWT(sal_Int16 nWordType, SwRootFrame const*const pLayout) const
1245{
1246 bool bRet = false;
1247 SwTextNode* pTextNd = GetPointNode().GetTextNode();
1248 if (pTextNd)
1249 {
1250 sal_Int32 nPtPos = GetPoint()->GetContentIndex();
1251
1252 {
1253 HideWrapper w(pLayout, pTextNd, nPtPos);
1254
1255 Boundary aBoundary = g_pBreakIt->GetBreakIter()->getWordBoundary(
1256 *w.m_pText, w.m_nPtIndex,
1257 g_pBreakIt->GetLocale( pTextNd->GetLang( nPtPos ) ),
1258 nWordType,
1259 true );
1260
1261 bRet = aBoundary.startPos != aBoundary.endPos &&
1262 aBoundary.startPos <= w.m_nPtIndex &&
1263 w.m_nPtIndex <= aBoundary.endPos;
1264 w.m_nPtIndex = aBoundary.startPos; // hack: convert startPos back...
1265 }
1266 if(bRet)
1267 {
1268 const CharClass& rCC = GetAppCharClass();
1269 bRet = rCC.isLetterNumeric(pTextNd->GetText(), nPtPos);
1270 }
1271 }
1272 return bRet;
1273}
1274
1275bool SwCursor::IsStartEndSentence(bool bEnd, SwRootFrame const*const pLayout) const
1276{
1277 bool bRet = bEnd ?
1279 GetPoint()->GetContentIndex() == 0;
1280
1281 if ((pLayout != nullptr && pLayout->HasMergedParas()) || !bRet)
1282 {
1283 SwCursor aCursor(*GetPoint(), nullptr);
1284 SwPosition aOrigPos = *aCursor.GetPoint();
1285 aCursor.GoSentence(bEnd ? SwCursor::END_SENT : SwCursor::START_SENT, pLayout);
1286 bRet = aOrigPos == *aCursor.GetPoint();
1287 }
1288 return bRet;
1289}
1290
1291bool SwCursor::GoStartWordWT(sal_Int16 nWordType, SwRootFrame const*const pLayout)
1292{
1293 bool bRet = false;
1294 SwTextNode* pTextNd = GetPointNode().GetTextNode();
1295 if (pTextNd)
1296 {
1297 SwCursorSaveState aSave( *this );
1298 sal_Int32 nPtPos = GetPoint()->GetContentIndex();
1299
1300 {
1301 HideWrapper w(pLayout, pTextNd, nPtPos);
1302
1303 w.m_nPtIndex = g_pBreakIt->GetBreakIter()->getWordBoundary(
1304 *w.m_pText, w.m_nPtIndex,
1305 g_pBreakIt->GetLocale( pTextNd->GetLang( nPtPos ) ),
1306 nWordType,
1307 false ).startPos;
1308 }
1309
1310 if (nPtPos < pTextNd->GetText().getLength() && nPtPos >= 0)
1311 {
1312 GetPoint()->Assign(*pTextNd, nPtPos);
1313 if( !IsSelOvr() )
1314 bRet = true;
1315 }
1316 }
1317 return bRet;
1318}
1319
1320bool SwCursor::GoEndWordWT(sal_Int16 nWordType, SwRootFrame const*const pLayout)
1321{
1322 bool bRet = false;
1323 SwTextNode* pTextNd = GetPointNode().GetTextNode();
1324 if (pTextNd)
1325 {
1326 SwCursorSaveState aSave( *this );
1327 sal_Int32 nPtPos = GetPoint()->GetContentIndex();
1328
1329 {
1330 HideWrapper w(pLayout, pTextNd, nPtPos);
1331
1332 w.m_nPtIndex = g_pBreakIt->GetBreakIter()->getWordBoundary(
1333 *w.m_pText, w.m_nPtIndex,
1334 g_pBreakIt->GetLocale( pTextNd->GetLang( nPtPos ) ),
1335 nWordType,
1336 true ).endPos;
1337 }
1338
1339 if (nPtPos <= pTextNd->GetText().getLength() && nPtPos >= 0 &&
1340 GetPoint()->GetContentIndex() != nPtPos )
1341 {
1342 GetPoint()->Assign(*pTextNd, nPtPos);
1343 if( !IsSelOvr() )
1344 bRet = true;
1345 }
1346 }
1347 return bRet;
1348}
1349
1350bool SwCursor::GoNextWordWT(sal_Int16 nWordType, SwRootFrame const*const pLayout)
1351{
1352 bool bRet = false;
1353 SwTextNode* pTextNd = GetPointNode().GetTextNode();
1354 if (pTextNd)
1355 {
1356 SwCursorSaveState aSave( *this );
1357 sal_Int32 nPtPos = GetPoint()->GetContentIndex();
1358
1359 {
1360 HideWrapper w(pLayout, pTextNd, nPtPos);
1361
1362 w.m_nPtIndex = g_pBreakIt->GetBreakIter()->nextWord(
1363 *w.m_pText, w.m_nPtIndex,
1364 g_pBreakIt->GetLocale( pTextNd->GetLang(nPtPos, 1) ),
1365 nWordType ).startPos;
1366 }
1367
1368 if (nPtPos <= pTextNd->GetText().getLength() && nPtPos >= 0)
1369 {
1370 GetPoint()->Assign(*pTextNd, nPtPos);
1371 if( !IsSelOvr() )
1372 bRet = true;
1373 }
1374 }
1375 return bRet;
1376}
1377
1378bool SwCursor::GoPrevWordWT(sal_Int16 nWordType, SwRootFrame const*const pLayout)
1379{
1380 bool bRet = false;
1381 SwTextNode* pTextNd = GetPointNode().GetTextNode();
1382 if (pTextNd)
1383 {
1384 SwCursorSaveState aSave( *this );
1385 sal_Int32 nPtPos = GetPoint()->GetContentIndex();
1386
1387 {
1388 HideWrapper w(pLayout, pTextNd, nPtPos);
1389
1390 const sal_Int32 nPtStart = w.m_nPtIndex;
1391 if (w.m_nPtIndex)
1392 {
1393 --w.m_nPtIndex;
1394 w.AssignBack(pTextNd, nPtPos);
1395 }
1396
1397 w.m_nPtIndex = g_pBreakIt->GetBreakIter()->previousWord(
1398 *w.m_pText, nPtStart,
1399 g_pBreakIt->GetLocale( pTextNd->GetLang(nPtPos, 1) ),
1400 nWordType ).startPos;
1401 }
1402
1403 if (nPtPos < pTextNd->GetText().getLength() && nPtPos >= 0)
1404 {
1405 GetPoint()->Assign(*pTextNd, nPtPos);
1406 if( !IsSelOvr() )
1407 bRet = true;
1408 }
1409 }
1410 return bRet;
1411}
1412
1413bool SwCursor::SelectWordWT( SwViewShell const * pViewShell, sal_Int16 nWordType, const Point* pPt )
1414{
1415 SwCursorSaveState aSave( *this );
1416
1417 bool bRet = false;
1418 DeleteMark();
1419 const SwRootFrame* pLayout = pViewShell->GetLayout();
1420 if( pPt && nullptr != pLayout )
1421 {
1422 // set the cursor to the layout position
1423 Point aPt( *pPt );
1424 pLayout->GetModelPositionForViewPoint( GetPoint(), aPt );
1425 }
1426
1427 SwTextNode* pTextNd = GetPointNode().GetTextNode();
1428 if (pTextNd)
1429 {
1430 // Should we select the whole fieldmark?
1431 const IDocumentMarkAccess* pMarksAccess = GetDoc().getIDocumentMarkAccess( );
1432 sw::mark::IFieldmark const*const pMark(pMarksAccess->getInnerFieldmarkFor(*GetPoint()));
1435 {
1436 *GetPoint() = sw::mark::FindFieldSep(*pMark);
1437 GetPoint()->AdjustContent(+1); // Don't select the separator
1438
1439 const SwPosition& rEnd = pMark->GetMarkEnd();
1440
1441 assert(pMark->GetMarkEnd() != *GetPoint());
1442 SetMark();
1443 *GetMark() = rEnd;
1444 GetMark()->AdjustContent(-1); // Don't select the end delimiter
1445
1446 bRet = true;
1447 }
1448 else
1449 {
1450 bool bForward = true;
1451 sal_Int32 nPtPos = GetPoint()->GetContentIndex();
1452
1453 HideWrapper w(pViewShell->GetLayout(), pTextNd, nPtPos);
1454
1455 Boundary aBndry( g_pBreakIt->GetBreakIter()->getWordBoundary(
1456 *w.m_pText, w.m_nPtIndex,
1457 g_pBreakIt->GetLocale( pTextNd->GetLang( nPtPos ) ),
1458 nWordType,
1459 bForward ));
1460
1461 if (comphelper::LibreOfficeKit::isActive() && aBndry.startPos == aBndry.endPos && w.m_nPtIndex > 0)
1462 {
1463 // nPtPos is the end of the paragraph, select the last word then.
1464 --w.m_nPtIndex;
1465 w.AssignBack(pTextNd, nPtPos);
1466
1467 aBndry = g_pBreakIt->GetBreakIter()->getWordBoundary(
1468 *w.m_pText, w.m_nPtIndex,
1469 g_pBreakIt->GetLocale( pTextNd->GetLang( nPtPos ) ),
1470 nWordType,
1471 bForward );
1472
1473 }
1474
1475 SwTextNode * pStartNode(pTextNd);
1476 sal_Int32 nStartIndex;
1477 w.m_nPtIndex = aBndry.startPos;
1478 w.AssignBack(pStartNode, nStartIndex);
1479
1480 SwTextNode * pEndNode(pTextNd);
1481 sal_Int32 nEndIndex;
1482 w.m_nPtIndex = aBndry.endPos;
1483 w.AssignBack(pEndNode, nEndIndex);
1484
1485 if( aBndry.startPos != aBndry.endPos )
1486 {
1487 GetPoint()->Assign(*pEndNode, nEndIndex);
1488 if( !IsSelOvr() )
1489 {
1490 SetMark();
1491 GetMark()->Assign(*pStartNode, nStartIndex);
1492 if (sw::mark::IMark* pAnnotationMark = pMarksAccess->getAnnotationMarkFor(*GetPoint()))
1493 {
1494 // An annotation mark covers the selected word. Check
1495 // if it covers only the word: in that case we select
1496 // the comment anchor as well.
1497 bool bStartMatch = GetMark()->GetNode() == pAnnotationMark->GetMarkStart().GetNode() &&
1498 GetMark()->GetContentIndex() == pAnnotationMark->GetMarkStart().GetContentIndex();
1499 bool bEndMatch = GetPoint()->GetNode() == pAnnotationMark->GetMarkEnd().GetNode() &&
1500 GetPoint()->GetContentIndex() + 1 == pAnnotationMark->GetMarkEnd().GetContentIndex();
1501 if (bStartMatch && bEndMatch)
1502 GetPoint()->AdjustContent(+1);
1503 }
1504 if( !IsSelOvr() )
1505 bRet = true;
1506 }
1507 }
1508 }
1509 }
1510
1511 if( !bRet )
1512 {
1513 DeleteMark();
1515 }
1516 return bRet;
1517}
1518
1519static OUString lcl_MaskDeletedRedlines( const SwTextNode* pTextNd )
1520{
1521 OUString aRes;
1522 if (pTextNd)
1523 {
1524 //mask deleted redlines
1525 OUString sNodeText(pTextNd->GetText());
1526 const SwDoc& rDoc = pTextNd->GetDoc();
1528 if ( bShowChg )
1529 {
1530 SwRedlineTable::size_type nAct = rDoc.getIDocumentRedlineAccess().GetRedlinePos( *pTextNd, RedlineType::Any );
1531 for ( ; nAct < rDoc.getIDocumentRedlineAccess().GetRedlineTable().size(); nAct++ )
1532 {
1533 const SwRangeRedline* pRed = rDoc.getIDocumentRedlineAccess().GetRedlineTable()[ nAct ];
1534 if ( pRed->Start()->GetNode() > *pTextNd )
1535 break;
1536
1537 if( RedlineType::Delete == pRed->GetType() )
1538 {
1539 sal_Int32 nStart, nEnd;
1540 pRed->CalcStartEnd( pTextNd->GetIndex(), nStart, nEnd );
1541
1542 while ( nStart < nEnd && nStart < sNodeText.getLength() )
1543 sNodeText = sNodeText.replaceAt( nStart++, 1, rtl::OUStringChar(CH_TXTATR_INWORD) );
1544 }
1545 }
1546 }
1547 aRes = sNodeText;
1548 }
1549 return aRes;
1550}
1551
1552bool SwCursor::GoSentence(SentenceMoveType eMoveType, SwRootFrame const*const pLayout)
1553{
1554 bool bRet = false;
1555 SwTextNode* pTextNd = GetPointNode().GetTextNode();
1556 if (pTextNd)
1557 {
1558 OUString const sNodeText(lcl_MaskDeletedRedlines(pTextNd));
1559
1560 SwCursorSaveState aSave( *this );
1561 sal_Int32 nPtPos = GetPoint()->GetContentIndex();
1562
1563 {
1564 HideWrapper w(pLayout, pTextNd, nPtPos, &sNodeText);
1565
1566 switch ( eMoveType )
1567 {
1568 case START_SENT: /* when modifying: see also ExpandToSentenceBorders below! */
1569 w.m_nPtIndex = g_pBreakIt->GetBreakIter()->beginOfSentence(
1570 *w.m_pText, w.m_nPtIndex,
1571 g_pBreakIt->GetLocale(pTextNd->GetLang(nPtPos)));
1572 break;
1573 case END_SENT: /* when modifying: see also ExpandToSentenceBorders below! */
1574 w.m_nPtIndex = g_pBreakIt->GetBreakIter()->endOfSentence(
1575 *w.m_pText, w.m_nPtIndex,
1576 g_pBreakIt->GetLocale(pTextNd->GetLang(nPtPos)));
1577 break;
1578 case NEXT_SENT:
1579 {
1580 w.m_nPtIndex = g_pBreakIt->GetBreakIter()->endOfSentence(
1581 *w.m_pText, w.m_nPtIndex,
1582 g_pBreakIt->GetLocale(pTextNd->GetLang(nPtPos)));
1583 if (w.m_nPtIndex >= 0 && w.m_nPtIndex < w.m_pText->getLength())
1584 {
1585 do
1586 {
1587 ++w.m_nPtIndex;
1588 }
1589 while (w.m_nPtIndex < w.m_pText->getLength()
1590 && (*w.m_pText)[w.m_nPtIndex] == ' ');
1591 }
1592 break;
1593 }
1594 case PREV_SENT:
1595 w.m_nPtIndex = g_pBreakIt->GetBreakIter()->beginOfSentence(
1596 *w.m_pText, w.m_nPtIndex,
1597 g_pBreakIt->GetLocale(pTextNd->GetLang(nPtPos)));
1598
1599 if (w.m_nPtIndex == 0)
1600 return false; // the previous sentence is not in this paragraph
1601 if (w.m_nPtIndex > 0)
1602 {
1603 w.m_nPtIndex = g_pBreakIt->GetBreakIter()->beginOfSentence(
1604 *w.m_pText, w.m_nPtIndex - 1,
1605 g_pBreakIt->GetLocale(pTextNd->GetLang(nPtPos)));
1606 }
1607 break;
1608 }
1609 }
1610
1611 // it is allowed to place the PaM just behind the last
1612 // character in the text thus <= ...Len
1613 if (nPtPos <= pTextNd->GetText().getLength() && nPtPos >= 0)
1614 {
1615 GetPoint()->Assign(*pTextNd, nPtPos);
1616 if( !IsSelOvr() )
1617 bRet = true;
1618 }
1619 }
1620 return bRet;
1621}
1622
1624{
1625 SwTextNode* pStartNd = Start()->GetNode().GetTextNode();
1626 SwTextNode* pEndNd = End()->GetNode().GetTextNode();
1627 if (!pStartNd || !pEndNd)
1628 return;
1629
1630 if (!HasMark())
1631 SetMark();
1632
1633 OUString sStartText( lcl_MaskDeletedRedlines( pStartNd ) );
1634 OUString sEndText( pStartNd == pEndNd? sStartText : lcl_MaskDeletedRedlines( pEndNd ) );
1635
1636 SwCursorSaveState aSave( *this );
1637 sal_Int32 nStartPos = Start()->GetContentIndex();
1638 sal_Int32 nEndPos = End()->GetContentIndex();
1639
1640 {
1641 HideWrapper w(pLayout, pStartNd, nStartPos, &sStartText);
1642
1643 w.m_nPtIndex = g_pBreakIt->GetBreakIter()->beginOfSentence(
1644 *w.m_pText, w.m_nPtIndex,
1645 g_pBreakIt->GetLocale( pStartNd->GetLang( nStartPos ) ) );
1646 }
1647 {
1648 HideWrapper w(pLayout, pEndNd, nEndPos, &sEndText);
1649
1650 w.m_nPtIndex = g_pBreakIt->GetBreakIter()->endOfSentence(
1651 *w.m_pText, w.m_nPtIndex,
1652 g_pBreakIt->GetLocale( pEndNd->GetLang( nEndPos ) ) );
1653 }
1654
1655 // it is allowed to place the PaM just behind the last
1656 // character in the text thus <= ...Len
1657 if (nStartPos <= pStartNd->GetText().getLength() && nStartPos >= 0)
1658 {
1659 GetMark()->Assign(*pStartNd, nStartPos);
1660 }
1661 if (nEndPos <= pEndNd->GetText().getLength() && nEndPos >= 0)
1662 {
1663 GetPoint()->Assign(*pEndNd, nEndPos);
1664 }
1665}
1666
1667bool SwTableCursor::LeftRight( bool bLeft, sal_uInt16 nCnt, SwCursorSkipMode /*nMode*/,
1668 bool /*bVisualAllowed*/, bool /*bSkipHidden*/, bool /*bInsertCursor*/,
1669 SwRootFrame const*, bool /*isFieldNames*/)
1670{
1671 return bLeft ? GoPrevCell( nCnt )
1672 : GoNextCell( nCnt );
1673}
1674
1675// calculate cursor bidi level: extracted from LeftRight()
1676const SwContentFrame*
1678 bool & io_rbLeft, bool bVisualAllowed, bool bInsertCursor)
1679{
1680 // calculate cursor bidi level
1681 const SwContentFrame* pSttFrame = nullptr;
1682 SwNode& rNode = GetPoint()->GetNode();
1683
1684 if( rNode.IsTextNode() )
1685 {
1686 const SwTextNode& rTNd = *rNode.GetTextNode();
1687 sal_Int32 nPos = GetPoint()->GetContentIndex();
1688
1689 if ( bVisualAllowed && SvtCTLOptions::IsCTLFontEnabled() &&
1691 {
1692 // for visual cursor travelling (used in bidi layout)
1693 // we first have to convert the logic to a visual position
1694 Point aPt;
1695 std::pair<Point, bool> const tmp(aPt, true);
1696 pSttFrame = rTNd.getLayoutFrame(
1697 GetDoc().getIDocumentLayoutAccess().GetCurrentLayout(),
1698 GetPoint(), &tmp);
1699 if( pSttFrame )
1700 {
1701 sal_uInt8 nCursorLevel = GetCursorBidiLevel();
1702 bool bForward = ! io_rbLeft;
1703 SwTextFrame *const pTF(const_cast<SwTextFrame*>(
1704 static_cast<const SwTextFrame*>(pSttFrame)));
1705 TextFrameIndex nTFIndex(pTF->MapModelToViewPos(*GetPoint()));
1706 pTF->PrepareVisualMove( nTFIndex, nCursorLevel,
1707 bForward, bInsertCursor );
1708 *GetPoint() = pTF->MapViewToModelPos(nTFIndex);
1709 SetCursorBidiLevel( nCursorLevel );
1710 io_rbLeft = ! bForward;
1711 }
1712 }
1713 else
1714 {
1715 SwTextFrame const* pFrame;
1716 const SwScriptInfo* pSI = SwScriptInfo::GetScriptInfo(rTNd, &pFrame);
1717 if ( pSI )
1718 {
1719 const sal_Int32 nMoveOverPos = io_rbLeft ?
1720 ( nPos ? nPos - 1 : 0 ) :
1721 nPos;
1722 TextFrameIndex nIndex(pFrame->MapModelToView(&rTNd, nMoveOverPos));
1724 }
1725 }
1726 }
1727 return pSttFrame;
1728}
1729
1730bool SwCursor::LeftRight( bool bLeft, sal_uInt16 nCnt, SwCursorSkipMode nMode,
1731 bool bVisualAllowed,bool bSkipHidden, bool bInsertCursor,
1732 SwRootFrame const*const pLayout, bool isFieldNames)
1733{
1734 // calculate cursor bidi level
1735 SwNode& rNode = GetPoint()->GetNode();
1736 const SwContentFrame* pSttFrame = // may side-effect bLeft!
1737 DoSetBidiLevelLeftRight(bLeft, bVisualAllowed, bInsertCursor);
1738
1739 // can the cursor be moved n times?
1740 SwCursorSaveState aSave( *this );
1741 SwMoveFnCollection const & fnMove = bLeft ? fnMoveBackward : fnMoveForward;
1742
1743 SwGoInDoc fnGo;
1744 if ( bSkipHidden )
1746 else
1748
1749 SwTextFrame const* pFrame(nullptr);
1750 if (pLayout)
1751 {
1752 pFrame = static_cast<SwTextFrame*>(rNode.GetContentNode()->getLayoutFrame(pLayout));
1753 if (pFrame)
1754 {
1755 while (pFrame->GetPrecede())
1756 {
1757 pFrame = static_cast<SwTextFrame const*>(pFrame->GetPrecede());
1758 }
1759 }
1760 }
1761
1762 while( nCnt )
1763 {
1764 SwNodeIndex aOldNodeIdx( GetPoint()->GetNode() );
1765
1766 TextFrameIndex beforeIndex(-1);
1767 if (pFrame)
1768 {
1769 beforeIndex = pFrame->MapModelToViewPos(*GetPoint());
1770 }
1771
1772 if (!bLeft && pLayout && pLayout->GetFieldmarkMode() == sw::FieldmarkMode::ShowResult)
1773 {
1774 SwTextNode const*const pNode(GetPoint()->GetNode().GetTextNode());
1775 assert(pNode);
1776 if (pNode->Len() != GetPoint()->GetContentIndex()
1777 && pNode->GetText()[GetPoint()->GetContentIndex()] == CH_TXT_ATR_FIELDSTART)
1778 {
1779 IDocumentMarkAccess const& rIDMA(*GetDoc().getIDocumentMarkAccess());
1780 sw::mark::IFieldmark const*const pMark(rIDMA.getFieldmarkAt(*GetPoint()));
1781 assert(pMark);
1782 *GetPoint() = sw::mark::FindFieldSep(*pMark);
1783 }
1784 }
1785
1786 if ( !Move( fnMove, fnGo ) )
1787 {
1788 const SwEditShell* pSh = GetDoc().GetEditShell();
1789 const SwViewOption* pViewOptions = pSh ? pSh->GetViewOptions() : nullptr;
1790 if (pViewOptions && pViewOptions->IsShowOutlineContentVisibilityButton())
1791 {
1792 // Fixes crash that occurs in documents with outline content folded at the end of
1793 // the document. When the cursor is at the end of the visible document and
1794 // right arrow key is pressed Move fails after moving the cursor to the
1795 // end of the document model, which doesn't have a node frame and causes
1796 // weird numbers to be displayed in the statusbar page number count. Left
1797 // arrow, when in this state, causes a crash without RestoredSavePos() added here.
1799 }
1800 break;
1801 }
1802
1803 if (pFrame)
1804 {
1805 SwTextFrame const* pNewFrame(static_cast<SwTextFrame const*>(
1806 GetPoint()->GetNode().GetContentNode()->getLayoutFrame(pLayout)));
1807 if (pNewFrame)
1808 {
1809 while (pNewFrame->GetPrecede())
1810 {
1811 pNewFrame = static_cast<SwTextFrame const*>(pNewFrame->GetPrecede());
1812 }
1813 }
1814 // sw_redlinehide: fully redline-deleted nodes don't have frames...
1815 if (pFrame == pNewFrame || !pNewFrame)
1816 {
1817 if (!pNewFrame || beforeIndex == pFrame->MapModelToViewPos(*GetPoint()))
1818 {
1819 continue; // moving inside delete redline, doesn't count...
1820 }
1821 }
1822 else
1823 {
1824 // assume iteration is stable & returns the same frame
1825 assert(!pFrame->IsAnFollow(pNewFrame) && !pNewFrame->IsAnFollow(pFrame));
1826 pFrame = pNewFrame;
1827 }
1828 }
1829
1830 if (bLeft && pLayout && pLayout->GetFieldmarkMode() == sw::FieldmarkMode::ShowCommand)
1831 {
1832 SwTextNode const*const pNode(GetPoint()->GetNode().GetTextNode());
1833 assert(pNode);
1834 if (pNode->Len() != GetPoint()->GetContentIndex()
1835 && pNode->GetText()[GetPoint()->GetContentIndex()] == CH_TXT_ATR_FIELDEND)
1836 {
1837 IDocumentMarkAccess const& rIDMA(*GetDoc().getIDocumentMarkAccess());
1838 sw::mark::IFieldmark const*const pMark(rIDMA.getFieldmarkAt(*GetPoint()));
1839 assert(pMark);
1840 *GetPoint() = sw::mark::FindFieldSep(*pMark);
1841 }
1842 }
1843
1844 if (isFieldNames)
1845 {
1846 SwTextNode const*const pNode(GetPoint()->GetNode().GetTextNode());
1847 assert(pNode);
1848 SwTextAttr const*const pInputField(pNode->GetTextAttrAt(
1850 if (pInputField)
1851 {
1852 continue; // skip over input fields
1853 }
1854 }
1855
1856 // If we were located inside a covered cell but our position has been
1857 // corrected, we check if the last move has moved the cursor to a
1858 // different table cell. In this case we set the cursor to the stored
1859 // covered position and redo the move:
1860 if (m_nRowSpanOffset)
1861 {
1862 const SwNode* pOldTabBoxSttNode = aOldNodeIdx.GetNode().FindTableBoxStartNode();
1863 const SwTableNode* pOldTabSttNode = pOldTabBoxSttNode ? pOldTabBoxSttNode->FindTableNode() : nullptr;
1864 const SwNode* pNewTabBoxSttNode = GetPoint()->GetNode().FindTableBoxStartNode();
1865 const SwTableNode* pNewTabSttNode = pNewTabBoxSttNode ? pNewTabBoxSttNode->FindTableNode() : nullptr;
1866
1867 const bool bCellChanged = pOldTabSttNode && pNewTabSttNode &&
1868 pOldTabSttNode == pNewTabSttNode &&
1869 pOldTabBoxSttNode && pNewTabBoxSttNode &&
1870 pOldTabBoxSttNode != pNewTabBoxSttNode;
1871
1872 if ( bCellChanged )
1873 {
1874 // Set cursor to start/end of covered cell:
1875 SwTableBox* pTableBox = pOldTabBoxSttNode->GetTableBox();
1876 if ( pTableBox && pTableBox->getRowSpan() > 1 )
1877 {
1878 pTableBox = & pTableBox->FindEndOfRowSpan(
1879 pOldTabSttNode->GetTable(),
1880 o3tl::narrowing<sal_uInt16>(pTableBox->getRowSpan() + m_nRowSpanOffset));
1881 SwPosition& rPtPos = *GetPoint();
1882 SwNodeIndex aNewIdx( *pTableBox->GetSttNd() );
1883 rPtPos.Assign( aNewIdx );
1884
1885 GetDoc().GetNodes().GoNextSection( &rPtPos, false, false );
1886 SwContentNode* pContentNode = GetPointContentNode();
1887 if ( pContentNode )
1888 {
1889 GetPoint()->SetContent( bLeft ? pContentNode->Len() : 0 );
1890
1891 // Redo the move:
1892 if ( !Move( fnMove, fnGo ) )
1893 break;
1894 }
1895 }
1896 m_nRowSpanOffset = 0;
1897 }
1898 }
1899
1900 // Check if I'm inside a covered cell. Correct cursor if necessary and
1901 // store covered cell:
1902 const SwNode* pTableBoxStartNode = GetPoint()->GetNode().FindTableBoxStartNode();
1903 if ( pTableBoxStartNode )
1904 {
1905 const SwTableBox* pTableBox = pTableBoxStartNode->GetTableBox();
1906 if ( pTableBox && pTableBox->getRowSpan() < 1 )
1907 {
1908 // Store the row span offset:
1909 m_nRowSpanOffset = pTableBox->getRowSpan();
1910
1911 // Move cursor to non-covered cell:
1912 const SwTableNode* pTableNd = pTableBoxStartNode->FindTableNode();
1913 pTableBox = & pTableBox->FindStartOfRowSpan( pTableNd->GetTable() );
1914 SwPosition& rPtPos = *GetPoint();
1915 SwNodeIndex aNewIdx( *pTableBox->GetSttNd() );
1916 rPtPos.Assign( aNewIdx );
1917
1918 GetDoc().GetNodes().GoNextSection( &rPtPos, false, false );
1919 SwContentNode* pContentNode = GetPointContentNode();
1920 if ( pContentNode )
1921 {
1922 GetPoint()->SetContent( bLeft ? pContentNode->Len() : 0 );
1923 }
1924 }
1925 }
1926 --nCnt;
1927 }
1928
1929 // here come some special rules for visual cursor travelling
1930 if ( pSttFrame )
1931 {
1932 SwNode& rTmpNode = GetPoint()->GetNode();
1933 if ( &rTmpNode != &rNode && rTmpNode.IsTextNode() )
1934 {
1935 Point aPt;
1936 std::pair<Point, bool> const tmp(aPt, true);
1937 const SwContentFrame* pEndFrame = rTmpNode.GetTextNode()->getLayoutFrame(
1938 GetDoc().getIDocumentLayoutAccess().GetCurrentLayout(),
1939 GetPoint(), &tmp);
1940 if ( pEndFrame )
1941 {
1942 if ( ! pEndFrame->IsRightToLeft() != ! pSttFrame->IsRightToLeft() )
1943 {
1944 if ( ! bLeft )
1945 pEndFrame->RightMargin( this );
1946 else
1947 pEndFrame->LeftMargin( this );
1948 }
1949 }
1950 }
1951 }
1952
1953 return 0 == nCnt && !IsInProtectTable( true ) &&
1956}
1957
1958// calculate cursor bidi level: extracted from UpDown()
1960{
1961 SwNode& rNode = GetPoint()->GetNode();
1962 if ( !rNode.IsTextNode() )
1963 return;
1964
1965 SwTextFrame const* pFrame;
1966 const SwScriptInfo* pSI =
1967 SwScriptInfo::GetScriptInfo( *rNode.GetTextNode(), &pFrame );
1968 if ( !pSI )
1969 return;
1970
1971 const sal_Int32 nPos = GetPoint()->GetContentIndex();
1972
1973 if (!(nPos && nPos < rNode.GetTextNode()->GetText().getLength()))
1974 return;
1975
1976 TextFrameIndex const nIndex(pFrame->MapModelToView(rNode.GetTextNode(), nPos));
1977 const sal_uInt8 nCurrLevel = pSI->DirType( nIndex );
1978 const sal_uInt8 nPrevLevel = pSI->DirType( nIndex - TextFrameIndex(1) );
1979
1980 if ( nCurrLevel % 2 != nPrevLevel % 2 )
1981 {
1982 // set cursor level to the lower of the two levels
1983 SetCursorBidiLevel( std::min( nCurrLevel, nPrevLevel ) );
1984 }
1985 else
1986 SetCursorBidiLevel( nCurrLevel );
1987}
1988
1989bool SwCursor::UpDown( bool bUp, sal_uInt16 nCnt,
1990 Point const * pPt, tools::Long nUpDownX,
1991 SwRootFrame & rLayout)
1992{
1993 SwTableCursor* pTableCursor = dynamic_cast<SwTableCursor*>(this);
1994 bool bAdjustTableCursor = false;
1995
1996 // If the point/mark of the table cursor in the same box then set cursor to
1997 // beginning of the box
1998 if( pTableCursor && GetPointNode().StartOfSectionNode() ==
2000 {
2001 if ( End() != GetPoint() )
2002 Exchange();
2003 bAdjustTableCursor = true;
2004 }
2005
2006 bool bRet = false;
2007 Point aPt;
2008 if( pPt )
2009 aPt = *pPt;
2010 std::pair<Point, bool> const temp(aPt, true);
2011 SwContentFrame* pFrame = GetPointContentNode()->getLayoutFrame(&rLayout, GetPoint(), &temp);
2012
2013 if( pFrame )
2014 {
2015 SwCursorSaveState aSave( *this );
2016
2017 if( !pPt )
2018 {
2019 SwRect aTmpRect;
2020 pFrame->GetCharRect( aTmpRect, *GetPoint() );
2021 aPt = aTmpRect.Pos();
2022
2023 nUpDownX = pFrame->IsVertical() ?
2024 aPt.getY() - pFrame->getFrameArea().Top() :
2025 aPt.getX() - pFrame->getFrameArea().Left();
2026 }
2027
2028 // It is allowed to move footnotes in other footnotes but not sections
2029 const bool bChkRange = !pFrame->IsInFootnote() || HasMark();
2030 const SwPosition aOldPos( *GetPoint() );
2031 const bool bInReadOnly = IsReadOnlyAvailable();
2032
2033 if ( bAdjustTableCursor && !bUp )
2034 {
2035 // Special case: We have a table cursor but the start box has more
2036 // than one paragraph. If we want to go down, we have to set the
2037 // point to the last frame in the table box. This is only necessary
2038 // if we do not already have a table selection
2039 const SwStartNode* pTableNd = GetPointNode().FindTableBoxStartNode();
2040 OSL_ENSURE( pTableNd, "pTableCursor without SwTableNode?" );
2041
2042 if ( pTableNd ) // safety first
2043 {
2044 const SwNode* pEndNd = pTableNd->EndOfSectionNode();
2045 GetPoint()->Assign( *pEndNd );
2046 pTableCursor->Move( fnMoveBackward, GoInNode );
2047 std::pair<Point, bool> const tmp(aPt, true);
2048 pFrame = GetPointContentNode()->getLayoutFrame(&rLayout, GetPoint(), &tmp);
2049 }
2050 }
2051
2052 while( nCnt &&
2053 (bUp ? pFrame->UnitUp( this, nUpDownX, bInReadOnly )
2054 : pFrame->UnitDown( this, nUpDownX, bInReadOnly ) ) &&
2055 CheckNodesRange( aOldPos.GetNode(), GetPoint()->GetNode(), bChkRange ))
2056 {
2057 std::pair<Point, bool> const tmp(aPt, true);
2058 pFrame = GetPointContentNode()->getLayoutFrame(&rLayout, GetPoint(), &tmp);
2059 --nCnt;
2060 }
2061
2062 // iterate over whole number of items?
2063 if( !nCnt && !IsSelOvr( SwCursorSelOverFlags::Toggle |
2065 {
2066 if( !pTableCursor )
2067 {
2068 // try to position the cursor at half of the char-rect's height
2069 DisableCallbackAction a(rLayout);
2070 std::pair<Point, bool> const tmp(aPt, true);
2071 pFrame = GetPointContentNode()->getLayoutFrame(&rLayout, GetPoint(), &tmp);
2073 eTmpState.m_bSetInReadOnly = bInReadOnly;
2074 SwRect aTmpRect;
2075 pFrame->GetCharRect( aTmpRect, *GetPoint(), &eTmpState );
2076 if ( pFrame->IsVertical() )
2077 {
2078 aPt.setX(aTmpRect.Center().getX());
2079 pFrame->Calc(rLayout.GetCurrShell()->GetOut());
2080 aPt.setY(pFrame->getFrameArea().Top() + nUpDownX);
2081 }
2082 else
2083 {
2084 aPt.setY(aTmpRect.Center().getY());
2085 pFrame->Calc(rLayout.GetCurrShell()->GetOut());
2086 aPt.setX(pFrame->getFrameArea().Left() + nUpDownX);
2087 }
2088 pFrame->GetModelPositionForViewPoint( GetPoint(), aPt, &eTmpState );
2089 }
2091 }
2092 else if (!pFrame->IsInFootnote()) // tdf#150457 Jump to the begin/end
2093 // of the first/last line only if the
2094 // cursor is not inside a footnote
2095 {
2096 sal_Int32 nOffset = 0;
2097
2098 // Jump to beginning or end of line when the cursor at first or last line.
2099 if(!bUp)
2100 {
2101 SwTextNode* pTextNd = GetPoint()->GetNode().GetTextNode();
2102 if (pTextNd)
2103 nOffset = pTextNd->GetText().getLength();
2104 }
2105 const SwPosition aPos(*GetPointContentNode(), nOffset);
2106
2107 //if cursor has already been at start or end of file,
2108 //Update cursor to change nUpDownX.
2109 if ( aOldPos.GetContentIndex() == nOffset )
2110 {
2111 if (SwEditShell* pSh = GetDoc().GetEditShell())
2112 pSh->UpdateCursor();
2113 bRet = false;
2114 }
2115 else{
2116 *GetPoint() = aPos; // just give a new position
2117 bRet = true;
2118 }
2119
2120 }
2121 else
2122 *GetPoint() = aOldPos;
2123
2124 DoSetBidiLevelUpDown(); // calculate cursor bidi level
2125 }
2126 return bRet;
2127}
2128
2129bool SwCursor::LeftRightMargin(SwRootFrame const& rLayout, bool bLeft, bool bAPI)
2130{
2131 Point aPt;
2132 std::pair<Point, bool> const tmp(aPt, true);
2133 SwContentFrame const*const pFrame = GetPointContentNode()->getLayoutFrame(
2134 &rLayout, GetPoint(), &tmp);
2135
2136 // calculate cursor bidi level
2137 if ( pFrame )
2138 SetCursorBidiLevel( pFrame->IsRightToLeft() ? 1 : 0 );
2139
2140 SwCursorSaveState aSave( *this );
2141 return pFrame
2142 && (bLeft ? pFrame->LeftMargin( this ) : pFrame->RightMargin( this, bAPI ) )
2144}
2145
2146bool SwCursor::IsAtLeftRightMargin(SwRootFrame const& rLayout, bool bLeft, bool bAPI) const
2147{
2148 bool bRet = false;
2149 Point aPt;
2150 std::pair<Point, bool> const tmp(aPt, true);
2151 SwContentFrame const*const pFrame = GetPointContentNode()->getLayoutFrame(
2152 &rLayout, GetPoint(), &tmp);
2153 if( pFrame )
2154 {
2155 SwPaM aPam( *GetPoint() );
2156 if( !bLeft && aPam.GetPoint()->GetContentIndex() )
2157 aPam.GetPoint()->AdjustContent(-1);
2158 bRet = (bLeft ? pFrame->LeftMargin( &aPam )
2159 : pFrame->RightMargin( &aPam, bAPI ))
2160 && (!pFrame->IsTextFrame()
2161 || static_cast<SwTextFrame const*>(pFrame)->MapModelToViewPos(*aPam.GetPoint())
2162 == static_cast<SwTextFrame const*>(pFrame)->MapModelToViewPos(*GetPoint()));
2163 }
2164 return bRet;
2165}
2166
2167bool SwCursor::SttEndDoc( bool bStt )
2168{
2169 SwCursorSaveState aSave( *this );
2170 // Never jump over section boundaries during selection!
2171 // Can the cursor still moved on?
2172 SwMoveFnCollection const & fnMove = bStt ? fnMoveBackward : fnMoveForward;
2173 bool bRet = (!HasMark() || !IsNoContent() ) &&
2174 Move( fnMove, GoInDoc ) &&
2175 !IsInProtectTable( true ) &&
2179 return bRet;
2180}
2181
2182bool SwCursor::GoPrevNextCell( bool bNext, sal_uInt16 nCnt )
2183{
2184 const SwTableNode* pTableNd = GetPoint()->GetNode().FindTableNode();
2185 if( !pTableNd )
2186 return false;
2187
2188 // If there is another EndNode in front of the cell's StartNode then there
2189 // exists a previous cell
2190 SwCursorSaveState aSave( *this );
2191 SwPosition& rPtPos = *GetPoint();
2192
2193 while( nCnt-- )
2194 {
2195 const SwNode* pTableBoxStartNode = rPtPos.GetNode().FindTableBoxStartNode();
2196 const SwTableBox* pTableBox = pTableBoxStartNode->GetTableBox();
2197
2198 // Check if we have to move the cursor to a covered cell before
2199 // proceeding:
2200 if (m_nRowSpanOffset)
2201 {
2202 if ( pTableBox && pTableBox->getRowSpan() > 1 )
2203 {
2204 pTableBox = & pTableBox->FindEndOfRowSpan( pTableNd->GetTable(),
2205 o3tl::narrowing<sal_uInt16>(pTableBox->getRowSpan() + m_nRowSpanOffset));
2206 rPtPos.Assign( *pTableBox->GetSttNd() );
2207 pTableBoxStartNode = rPtPos.GetNode().FindTableBoxStartNode();
2208 }
2209 m_nRowSpanOffset = 0;
2210 }
2211
2212 const SwNode* pTmpNode = bNext ?
2213 pTableBoxStartNode->EndOfSectionNode() :
2214 pTableBoxStartNode;
2215
2216 SwNodeIndex aCellIdx( *pTmpNode, bNext ? 1 : -1 );
2217 if( (bNext && !aCellIdx.GetNode().IsStartNode()) ||
2218 (!bNext && !aCellIdx.GetNode().IsEndNode()) )
2219 return false;
2220
2221 if (bNext)
2222 rPtPos.Assign( aCellIdx );
2223 else
2224 rPtPos.Assign(*aCellIdx.GetNode().StartOfSectionNode());
2225
2226 pTableBoxStartNode = rPtPos.GetNode().FindTableBoxStartNode();
2227 pTableBox = pTableBoxStartNode->GetTableBox();
2228 if ( pTableBox && pTableBox->getRowSpan() < 1 )
2229 {
2230 m_nRowSpanOffset = pTableBox->getRowSpan();
2231 // move cursor to non-covered cell:
2232 pTableBox = & pTableBox->FindStartOfRowSpan( pTableNd->GetTable() );
2233 rPtPos.Assign( *pTableBox->GetSttNd() );
2234 }
2235 }
2236
2237 rPtPos.Adjust(SwNodeOffset(1));
2238 if( !rPtPos.GetNode().IsContentNode() )
2239 GetDoc().GetNodes().GoNextSection( &rPtPos, true, false );
2240 GetPoint()->SetContent( 0 );
2241
2242 return !IsInProtectTable( true );
2243}
2244
2245bool SwTableCursor::GotoTable( const OUString& )
2246{
2247 return false; // invalid action
2248}
2249
2250bool SwCursor::GotoTable( const OUString& rName )
2251{
2252 bool bRet = false;
2253 if ( !HasMark() )
2254 {
2255 SwTable* pTmpTable = SwTable::FindTable( GetDoc().FindTableFormatByName( rName ) );
2256 if( pTmpTable )
2257 {
2258 // a table in a normal nodes array
2259 SwCursorSaveState aSave( *this );
2260 GetPoint()->Assign( *pTmpTable->GetTabSortBoxes()[ 0 ]->
2261 GetSttNd()->FindTableNode() );
2263 bRet = !IsSelOvr();
2264 }
2265 }
2266 return bRet;
2267}
2268
2269bool SwCursor::GotoTableBox( const OUString& rName )
2270{
2271 bool bRet = false;
2272 const SwTableNode* pTableNd = GetPoint()->GetNode().FindTableNode();
2273 if( pTableNd )
2274 {
2275 // retrieve box by name
2276 const SwTableBox* pTableBox = pTableNd->GetTable().GetTableBox( rName );
2277 if( pTableBox && pTableBox->GetSttNd() &&
2278 ( !pTableBox->GetFrameFormat()->GetProtect().IsContentProtected() ||
2280 {
2281 SwCursorSaveState aSave( *this );
2282 GetPoint()->Assign( *pTableBox->GetSttNd() );
2284 bRet = !IsSelOvr();
2285 }
2286 }
2287 return bRet;
2288}
2289
2290bool SwCursor::MovePara(SwWhichPara fnWhichPara, SwMoveFnCollection const & fnPosPara )
2291{
2292 // for optimization test something before
2293 const SwNode* pNd = &GetPoint()->GetNode();
2294 bool bShortCut = false;
2295 if ( fnWhichPara == GoCurrPara )
2296 {
2297 // #i41048#
2298 // If fnWhichPara == GoCurrPara then (*fnWhichPara)( *this, fnPosPara )
2299 // can already move the cursor to a different text node. In this case
2300 // we better check if IsSelOvr().
2301 const SwContentNode* pContentNd = pNd->GetContentNode();
2302 if ( pContentNd )
2303 {
2304 const sal_Int32 nSttEnd = &fnPosPara == &fnMoveForward ? 0 : pContentNd->Len();
2305 if ( GetPoint()->GetContentIndex() != nSttEnd )
2306 bShortCut = true;
2307 }
2308 }
2309 else
2310 {
2311 if ( pNd->IsTextNode() &&
2312 pNd->GetNodes()[ pNd->GetIndex() +
2313 SwNodeOffset(fnWhichPara == GoNextPara ? 1 : -1 ) ]->IsTextNode() )
2314 bShortCut = true;
2315 }
2316
2317 if ( bShortCut )
2318 return (*fnWhichPara)( *this, fnPosPara );
2319
2320 // else we must use the SaveStructure, because the next/prev is not
2321 // a same node type.
2322 SwCursorSaveState aSave( *this );
2323 return (*fnWhichPara)( *this, fnPosPara ) &&
2324 !IsInProtectTable( true ) &&
2327}
2328
2330 SwMoveFnCollection const & fnPosSect)
2331{
2332 SwCursorSaveState aSave( *this );
2333 return (*fnWhichSect)( *this, fnPosSect ) &&
2334 !IsInProtectTable( true ) &&
2337}
2338
2340{
2341 // This method is not supposed to be used in cases when nodes may be
2342 // deleted; detect such cases, but do not crash (example: fdo#40831).
2343 SwNodeOffset uNodeCount(GetPoint()->GetNodes().Count());
2344 OSL_ENSURE(m_vSavePos.empty() || m_vSavePos.back().nNode < uNodeCount,
2345 "SwCursor::RestoreSavePos: invalid node: "
2346 "probably something was deleted; consider using SwUnoCursor instead");
2347 if (m_vSavePos.empty() || m_vSavePos.back().nNode >= uNodeCount)
2348 return;
2349
2350 GetPoint()->Assign( m_vSavePos.back().nNode );
2351
2352 sal_Int32 nIdx = 0;
2353 if ( GetPointContentNode() )
2354 {
2355 if (m_vSavePos.back().nContent <= GetPointContentNode()->Len())
2356 nIdx = m_vSavePos.back().nContent;
2357 else
2358 {
2359 nIdx = GetPointContentNode()->Len();
2360 OSL_FAIL("SwCursor::RestoreSavePos: invalid content index");
2361 }
2362 }
2363 GetPoint()->SetContent( nIdx );
2364}
2365
2367 : SwCursor( rPos, nullptr )
2368{
2369 m_bParked = false;
2370 m_bChanged = false;
2373 m_nTablePtCnt = 0;
2374 m_nTableMkCnt = 0;
2375}
2376
2378
2379static bool
2380lcl_SeekEntry(const SwSelBoxes& rTmp, SwStartNode const*const pSrch,
2381 size_t & o_rFndPos)
2382{
2383 SwNodeOffset nIdx = pSrch->GetIndex();
2384
2385 size_t nO = rTmp.size();
2386 if( nO > 0 )
2387 {
2388 nO--;
2389 size_t nU = 0;
2390 while( nU <= nO )
2391 {
2392 size_t nM = nU + ( nO - nU ) / 2;
2393 if( rTmp[ nM ]->GetSttNd() == pSrch )
2394 {
2395 o_rFndPos = nM;
2396 return true;
2397 }
2398 else if( rTmp[ nM ]->GetSttIdx() < nIdx )
2399 nU = nM + 1;
2400 else if( nM == 0 )
2401 return false;
2402 else
2403 nO = nM - 1;
2404 }
2405 }
2406 return false;
2407}
2408
2410{
2411 if (m_bChanged)
2412 {
2413 if (m_bParked)
2414 {
2415 // move back into content
2416 Exchange();
2418 Exchange();
2420 m_bParked = false;
2421 }
2422
2423 m_bChanged = false;
2424
2425 // create temporary copies so that all boxes that
2426 // have already cursors can be removed
2428
2429 // compare old and new ones
2430 SwNodes& rNds = pCurrentCursor->GetDoc().GetNodes();
2431 const SwStartNode* pSttNd;
2432 SwCursor* pCur = pCurrentCursor;
2433 do {
2434 size_t nPos;
2435 bool bDel = false;
2436 pSttNd = pCur->GetPoint()->GetNode().FindTableBoxStartNode();
2437 if( !pCur->HasMark() || !pSttNd ||
2438 pSttNd != pCur->GetMark()->GetNode().FindTableBoxStartNode() )
2439 bDel = true;
2440
2441 else if( lcl_SeekEntry( aTmp, pSttNd, nPos ))
2442 {
2443 SwNodeIndex aIdx( *pSttNd, 1 );
2444 const SwNode* pNd = &aIdx.GetNode();
2445 if( !pNd->IsContentNode() )
2446 pNd = rNds.GoNextSection( &aIdx, true, false );
2447
2448 SwPosition* pPos = pCur->GetMark();
2449 if( pNd != &pPos->GetNode() )
2450 pPos->Assign( *pNd );
2451 pPos->SetContent( 0 );
2452
2453 aIdx.Assign( *pSttNd->EndOfSectionNode(), - 1 );
2454 pNd = &aIdx.GetNode();
2455 if( !pNd->IsContentNode() )
2456 pNd = SwNodes::GoPrevSection( &aIdx, true, false );
2457
2458 pPos = pCur->GetPoint();
2459 if (pNd && pNd != &pPos->GetNode())
2460 pPos->Assign( *pNd );
2461 pPos->SetContent( pNd ? static_cast<const SwContentNode*>(pNd)->Len() : 0);
2462
2463 aTmp.erase( aTmp.begin() + nPos );
2464 }
2465 else
2466 bDel = true;
2467
2468 pCur = pCur->GetNext();
2469 if( bDel )
2470 {
2471 SwCursor* pDel = pCur->GetPrev();
2472 if (pDel == dynamic_cast<SwShellCursor*>(pCurrentCursor))
2473 pCurrentCursor = pDel->GetPrev();
2474
2475 if( pDel == pCurrentCursor )
2476 pCurrentCursor->DeleteMark();
2477 else
2478 delete pDel;
2479 }
2480 } while ( pCurrentCursor != pCur );
2481
2482 for (size_t nPos = 0; nPos < aTmp.size(); ++nPos)
2483 {
2484 pSttNd = aTmp[ nPos ]->GetSttNd();
2485
2486 SwNodeIndex aIdx( *pSttNd, 1 );
2487 if( &aIdx.GetNodes() != &rNds )
2488 break;
2489 SwNode* pNd = &aIdx.GetNode();
2490 if( !pNd->IsContentNode() )
2491 pNd = rNds.GoNextSection( &aIdx, true, false );
2492
2493 SwPaM *const pNew = (!pCurrentCursor->IsMultiSelection() && !pCurrentCursor->HasMark())
2494 ? pCurrentCursor
2495 : pCurrentCursor->Create( pCurrentCursor );
2496 pNew->GetPoint()->Assign( *pNd );
2497 pNew->SetMark();
2498
2499 SwPosition* pPos = pNew->GetPoint();
2500 pPos->Assign( *pSttNd->EndOfSectionNode(), - 1 );
2501 pNd = &pPos->GetNode();
2502 if( !pNd->IsContentNode() )
2503 pNd = SwNodes::GoPrevSection( pPos, true, false );
2504 if (pNd)
2505 pPos->AssignEndIndex(*static_cast<SwContentNode*>(pNd));
2506 }
2507 }
2508 return pCurrentCursor;
2509}
2510
2511void SwTableCursor::InsertBox( const SwTableBox& rTableBox )
2512{
2513 SwTableBox* pBox = const_cast<SwTableBox*>(&rTableBox);
2514 m_SelectedBoxes.insert(pBox);
2515 m_bChanged = true;
2516}
2517
2518void SwTableCursor::DeleteBox(size_t const nPos)
2519{
2521 m_bChanged = true;
2522}
2523
2525{
2526 bool bRet = false;
2527 const SwNode *pStart = GetPointNode().FindTableBoxStartNode();
2528 const SwNode *pEnd = GetMarkNode().FindTableBoxStartNode();
2529 if( pStart && pEnd )
2530 {
2531 const SwTableNode *pTableNode = pStart->FindTableNode();
2532 if( pTableNode == pEnd->FindTableNode() &&
2533 pTableNode->GetTable().IsNewModel() )
2534 {
2535 bRet = true;
2537 pTableNode->GetTable().CreateSelection( pStart, pEnd, aNew,
2538 SwTable::SEARCH_NONE, false );
2539 ActualizeSelection( aNew );
2540 }
2541 }
2542 return bRet;
2543}
2544
2546{
2547 size_t nOld = 0, nNew = 0;
2548 while (nOld < m_SelectedBoxes.size() && nNew < rNew.size())
2549 {
2550 SwTableBox const*const pPOld = m_SelectedBoxes[ nOld ];
2551 const SwTableBox* pPNew = rNew[ nNew ];
2552 if( pPOld == pPNew )
2553 { // this box will stay
2554 ++nOld;
2555 ++nNew;
2556 }
2557 else if( pPOld->GetSttIdx() < pPNew->GetSttIdx() )
2558 {
2559 DeleteBox( nOld ); // this box has to go
2560 }
2561 else
2562 {
2563 InsertBox( *pPNew ); // this is a new one
2564 ++nOld;
2565 ++nNew;
2566 }
2567 }
2568
2569 while (nOld < m_SelectedBoxes.size())
2570 {
2571 DeleteBox( nOld ); // some more to delete
2572 }
2573
2574 for ( ; nNew < rNew.size(); ++nNew ) // some more to insert
2575 {
2576 InsertBox( *rNew[ nNew ] );
2577 }
2578}
2579
2581{
2582 if( !IsCursorMoved() )
2583 return false;
2584
2589 return true;
2590}
2591
2594{
2595 // de-register index from text node
2596 SwNode* pNd = &GetPoint()->GetNode();
2597 if( !pNd->IsStartNode() )
2598 pNd = pNd->StartOfSectionNode();
2599 GetPoint()->Assign(*pNd);
2600
2601 pNd = &GetMark()->GetNode();
2602 if( !pNd->IsStartNode() )
2603 pNd = pNd->StartOfSectionNode();
2604 GetMark()->Assign(*pNd);
2605
2606 m_bChanged = true;
2607 m_bParked = true;
2608}
2609
2611{
2612 bool bRet = false;
2613 for (size_t n = m_SelectedBoxes.size(); n; )
2614 {
2615 if (m_SelectedBoxes[--n]->GetFrameFormat()->GetProtect().IsContentProtected())
2616 {
2617 bRet = true;
2618 break;
2619 }
2620 }
2621 return bRet;
2622}
2623
2625{
2626 bool bRet = false;
2627 for (size_t n = m_SelectedBoxes.size(); n; )
2628 {
2629 if (m_SelectedBoxes[--n]->GetFrameFormat()->IsHidden())
2630 {
2631 bRet = true;
2632 break;
2633 }
2634 }
2635 return bRet;
2636}
2637
2638/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
css::chart::ChartAxisLabelPosition ePos
o3tl::strong_int< sal_Int32, struct Tag_TextFrameIndex > TextFrameIndex
Denotes a character index in a text frame at a layout level, after extent mapping from a text node at...
SwBreakIt * g_pBreakIt
Definition: breakit.cxx:34
bool isLetterNumeric(const OUString &rStr, sal_Int32 nPos) const
helper class to disable creation of an action by a callback event in particular, change event from a ...
Definition: rootfrm.hxx:465
virtual const SwRootFrame * GetCurrentLayout() const =0
Provides access to the marks of a document.
virtual sw::mark::IMark * getAnnotationMarkFor(const SwPosition &rPosition) const =0
virtual ::sw::mark::IFieldmark * getFieldmarkAt(const SwPosition &rPos) const =0
get Fieldmark for CH_TXT_ATR_FIELDSTART/CH_TXT_ATR_FIELDEND at rPos
virtual sw::mark::IFieldmark * getInnerFieldmarkFor(const SwPosition &pos) const =0
static SW_DLLPUBLIC MarkType GetType(const ::sw::mark::IMark &rMark)
Returns the MarkType used to create the mark.
Definition: docbm.cxx:502
static bool IsShowChanges(const RedlineFlags eM)
virtual SwRedlineTable::size_type GetRedlinePos(const SwNode &rNode, RedlineType nType) const =0
virtual const SwRedlineTable & GetRedlineTable() const =0
virtual RedlineFlags GetRedlineFlags() const =0
Query the currently set redline mode.
void setX(tools::Long nX)
void setY(tools::Long nY)
constexpr tools::Long getX() const
constexpr tools::Long getY() const
bool IsReadOnlyUI() const
static bool IsCTLFontEnabled()
static CursorMovement GetCTLCursorMovement()
bool IsContentProtected() const
css::uno::Reference< css::i18n::XBreakIterator > const & GetBreakIter() const
Definition: breakit.hxx:63
const css::lang::Locale & GetLocale(const LanguageType aLang)
Definition: breakit.hxx:68
SwContentFrame is the layout for content nodes: a common base class for text (paragraph) and non-text...
Definition: cntfrm.hxx:59
virtual bool UnitUp(SwPaM *, const SwTwips nOffset, bool bSetInReadOnly) const
Definition: trvlfrm.cxx:963
virtual bool UnitDown(SwPaM *, const SwTwips nOffset, bool bSetInReadOnly) const
Definition: trvlfrm.cxx:968
virtual bool LeftMargin(SwPaM *) const =0
virtual bool RightMargin(SwPaM *, bool bAPI=false) const =0
SwContentFrame * getLayoutFrame(const SwRootFrame *, const SwPosition *pPos=nullptr, std::pair< Point, bool > const *pViewPosAndCalcFrame=nullptr) const
Definition: node.cxx:1223
virtual sal_Int32 Len() const
Definition: node.cxx:1256
A helper class to save cursor state (position).
Definition: swcrsr.hxx:233
SwMoveFnCollection const & MakeFindRange(SwDocPositions, SwDocPositions, SwPaM *) const
set range for search in document
Definition: swcrsr.cxx:744
void RestoreState()
Definition: swcrsr.cxx:172
void RestoreSavePos()
Restore cursor state to the one saved by SwCursorSaveState.
Definition: swcrsr.cxx:2339
bool MoveSection(SwWhichSection, SwMoveFnCollection const &)
Definition: swcrsr.cxx:2329
bool SelectWord(SwViewShell const *pViewShell, const Point *pPt)
Definition: swcrsr.cxx:1202
bool IsNoContent() const
determine if point is outside of the node-array's content area
Definition: swcrsr.cxx:181
virtual short MaxReplaceArived()
Definition: swcrsr.cxx:1138
virtual bool IsAtValidPos(bool bPoint=true) const
Return <true> if cursor can be set to this position.
Definition: swcrsr.cxx:715
sal_uInt8 GetCursorBidiLevel() const
Definition: swcrsr.hxx:211
bool LeftRightMargin(SwRootFrame const &rLayout, bool bLeftMargin, bool bAPI)
Definition: swcrsr.cxx:2129
std::vector< SwCursor_SavePos > m_vSavePos
Definition: swcrsr.hxx:74
bool GoPrevNextCell(bool bNext, sal_uInt16 nCnt)
Definition: swcrsr.cxx:2182
bool GoNextWordWT(sal_Int16 nWordType, SwRootFrame const *pLayout=nullptr)
Definition: swcrsr.cxx:1350
virtual bool IsSelOvrCheck(SwCursorSelOverFlags eFlags)
Definition: swcrsr.cxx:187
bool GoPrevWordWT(sal_Int16 nWordType, SwRootFrame const *pLayout=nullptr)
Definition: swcrsr.cxx:1378
bool GoNextCell(sal_uInt16 nCnt=1)
Definition: swcrsr.hxx:174
virtual void DoSetBidiLevelUpDown()
Definition: swcrsr.cxx:1959
virtual bool IsSelOvr(SwCursorSelOverFlags eFlags=SwCursorSelOverFlags::CheckNodeSection|SwCursorSelOverFlags::Toggle|SwCursorSelOverFlags::ChangePos)
Definition: swcrsr.cxx:222
SwCursor * GetNext()
Definition: swcrsr.hxx:219
SwCursor(SwCursor const &rPaM)=delete
bool IsEndWordWT(sal_Int16 nWordType, SwRootFrame const *pLayout=nullptr) const
Definition: swcrsr.cxx:1225
void ExpandToSentenceBorders(SwRootFrame const *pLayout)
Definition: swcrsr.cxx:1623
bool IsInProtectTable(bool bMove=false, bool bChgCursor=true)
Definition: swcrsr.cxx:557
bool IsInWordWT(sal_Int16 nWordType, SwRootFrame const *pLayout=nullptr) const
Definition: swcrsr.cxx:1244
bool MovePara(SwWhichPara, SwMoveFnCollection const &)
Definition: swcrsr.cxx:2290
bool IsStartEndSentence(bool bEnd, SwRootFrame const *pLayout) const
Definition: swcrsr.cxx:1275
bool GotoTableBox(const OUString &rName)
Definition: swcrsr.cxx:2269
void SaveState()
Definition: swcrsr.cxx:167
bool GoPrevCell(sal_uInt16 nCnt=1)
Definition: swcrsr.hxx:175
virtual bool GotoTable(const OUString &rName)
Definition: swcrsr.cxx:2250
bool SttEndDoc(bool bSttDoc)
Definition: swcrsr.cxx:2167
bool SelectWordWT(SwViewShell const *pViewShell, sal_Int16 nWordType, const Point *pPt)
Definition: swcrsr.cxx:1413
void SetCursorBidiLevel(sal_uInt8 nNewLevel)
Definition: swcrsr.hxx:212
virtual ~SwCursor() override
Definition: swcrsr.cxx:141
SentenceMoveType
Definition: swcrsr.hxx:154
@ NEXT_SENT
Definition: swcrsr.hxx:155
@ END_SENT
Definition: swcrsr.hxx:158
@ START_SENT
Definition: swcrsr.hxx:157
@ PREV_SENT
Definition: swcrsr.hxx:156
bool GoEndWordWT(sal_Int16 nWordType, SwRootFrame const *pLayout=nullptr)
Definition: swcrsr.cxx:1320
sal_Int32 m_nRowSpanOffset
Definition: swcrsr.hxx:75
virtual SwCursor * Create(SwPaM *pRing=nullptr) const
Definition: swcrsr.cxx:145
virtual const SwContentFrame * DoSetBidiLevelLeftRight(bool &io_rbLeft, bool bVisualAllowed, bool bInsertCursor)
Definition: swcrsr.cxx:1677
virtual bool IsReadOnlyAvailable() const
Definition: swcrsr.cxx:150
bool GoStartWordWT(sal_Int16 nWordType, SwRootFrame const *pLayout=nullptr)
Definition: swcrsr.cxx:1291
virtual bool LeftRight(bool bLeft, sal_uInt16 nCnt, SwCursorSkipMode nMode, bool bAllowVisual, bool bSkipHidden, bool bInsertCursor, SwRootFrame const *pLayout, bool isFieldNames)
Definition: swcrsr.cxx:1730
sal_Int32 FindAll(SwFindParas &, SwDocPositions, SwDocPositions, FindRanges, bool &bCancel)
Definition: swcrsr.cxx:949
virtual bool IsSkipOverHiddenSections() const
Definition: swcrsr.cxx:155
virtual void SaveTableBoxContent(const SwPosition *pPos)
Definition: swcrsr.cxx:741
virtual bool IsSkipOverProtectSections() const
Definition: swcrsr.cxx:160
bool UpDown(bool bUp, sal_uInt16 nCnt, Point const *pPt, tools::Long nUpDownX, SwRootFrame &rLayout)
Definition: swcrsr.cxx:1989
SwCursor * GetPrev()
Definition: swcrsr.hxx:221
bool IsStartWordWT(sal_Int16 nWordType, SwRootFrame const *pLayout=nullptr) const
Definition: swcrsr.cxx:1207
bool GoSentence(SentenceMoveType eMoveType, SwRootFrame const *pLayout=nullptr)
Definition: swcrsr.cxx:1552
void FillFindPos(SwDocPositions ePos, SwPosition &rPos) const
Definition: swcrsr.cxx:1102
const SwCursor_SavePos * GetSavePos() const
Definition: swcrsr.hxx:315
bool IsAtLeftRightMargin(SwRootFrame const &rLayout, bool bLeftMargin, bool bAPI) const
Definition: swcrsr.cxx:2146
Definition: doc.hxx:197
SwSectionFormats & GetSections()
Definition: doc.hxx:1356
IDocumentUndoRedo & GetIDocumentUndoRedo()
Definition: doc.cxx:158
SwNodes & GetNodes()
Definition: doc.hxx:422
IDocumentRedlineAccess const & getIDocumentRedlineAccess() const
Definition: doc.cxx:349
SwEditShell const * GetEditShell() const
Definition: doccorr.cxx:330
IDocumentLayoutAccess const & getIDocumentLayoutAccess() const
Definition: doc.cxx:419
IDocumentMarkAccess * getIDocumentMarkAccess()
Definition: docbm.cxx:1890
SwDocShell * GetDocShell()
Definition: doc.hxx:1370
Content, content of frame (header, footer, fly).
Definition: fmtcntnt.hxx:32
const SwNodeIndex * GetContentIdx() const
Definition: fmtcntnt.hxx:46
const SvxProtectItem & GetProtect(bool=true) const
Definition: frmatr.hxx:106
const SwFormatContent & GetContent(bool=true) const
Definition: fmtcntnt.hxx:55
const SwRect & getFrameArea() const
Definition: frame.hxx:179
bool isFrameAreaDefinitionValid() const
Definition: frame.hxx:171
bool IsTextFrame() const
Definition: frame.hxx:1240
SwContentFrame * FindPrevCnt()
Definition: findfrm.cxx:201
bool IsInFootnote() const
Definition: frame.hxx:955
virtual void Calc(vcl::RenderContext *pRenderContext) const
Definition: trvlfrm.cxx:1799
bool IsRightToLeft() const
Definition: frame.hxx:993
virtual bool GetModelPositionForViewPoint(SwPosition *, Point &, SwCursorMoveState *=nullptr, bool bTestBackground=false) const
Definition: unusedf.cxx:47
bool IsVertical() const
Definition: frame.hxx:979
bool IsNoTextFrame() const
Definition: frame.hxx:1244
SwContentFrame * FindNextCnt(const bool _bInSameFootnote=false)
Definition: findfrm.cxx:217
virtual bool GetCharRect(SwRect &, const SwPosition &, SwCursorMoveState *=nullptr, bool bAllowFarAway=true) const
Definition: unusedf.cxx:72
Marks a node in the document model.
Definition: ndindex.hxx:31
const SwNodes & GetNodes() const
Definition: ndindex.hxx:119
SwNode & GetNode() const
Definition: ndindex.hxx:123
SwNodeOffset GetIndex() const
Definition: ndindex.hxx:111
SwNodeIndex & Assign(SwNodes const &rNds, SwNodeOffset nIdx)
Definition: ndindex.hxx:114
Base class of the Writer document model elements.
Definition: node.hxx:98
SwTextNode * GetTextNode()
Inline methods from Node.hxx.
Definition: ndtxt.hxx:901
SwNodeOffset GetIndex() const
Definition: node.hxx:312
const SwStartNode * FindTableBoxStartNode() const
Definition: node.hxx:218
bool IsProtect() const
Is node in something that is protected (range, frame, table cells ... including anchor in case of fra...
Definition: node.cxx:449
SwNodes & GetNodes()
Node is in which nodes-array/doc?
Definition: node.hxx:706
SwTableBox * GetTableBox() const
If node is in a table return the respective table box.
Definition: node.cxx:772
bool IsContentNode() const
Definition: node.hxx:188
SwDoc & GetDoc()
Definition: node.hxx:233
bool IsEndNode() const
Definition: node.hxx:189
bool IsStartNode() const
Definition: node.hxx:187
bool IsSectionNode() const
Definition: node.hxx:192
bool IsTableNode() const
Definition: node.hxx:191
bool IsTextNode() const
Definition: node.hxx:190
SwTableNode * FindTableNode()
Search table node, in which it is.
Definition: node.cxx:380
SwSectionNode * FindSectionNode()
Search section node, in which it is.
Definition: ndsect.cxx:968
const SwStartNode * StartOfSectionNode() const
Definition: node.hxx:153
SwNodeOffset EndOfSectionIndex() const
Definition: node.hxx:691
SwContentNode * GetContentNode()
Definition: node.hxx:666
SwTableNode * GetTableNode()
Definition: node.hxx:650
const SwEndNode * EndOfSectionNode() const
Definition: node.hxx:695
SwNode & GetEndOfExtras() const
This is the last EndNode of a special section.
Definition: ndarr.hxx:163
SwNode & GetEndOfContent() const
Regular ContentSection (i.e. the BodyText).
Definition: ndarr.hxx:165
static SwContentNode * GoPrevious(SwNodeIndex *)
Definition: nodes.cxx:1333
SwContentNode * GoNext(SwNodeIndex *) const
Definition: nodes.cxx:1299
SwContentNode * GoNextSection(SwNodeIndex *, bool bSkipHidden=true, bool bSkipProtect=true) const
Go to next content-node that is not protected or hidden (Both set FALSE ==> GoNext/GoPrevious!...
Definition: nodes.cxx:1948
SwNode & GetEndOfPostIts() const
A still empty section.
Definition: ndarr.hxx:154
static SwContentNode * GoPrevSection(SwNodeIndex *, bool bSkipHidden=true, bool bSkipProtect=true)
Definition: nodes.cxx:2064
PaM is Point and Mark: a selection of the document model.
Definition: pam.hxx:188
const SwPosition * GetMark() const
Definition: pam.hxx:255
SwNode & GetPointNode() const
Definition: pam.hxx:275
virtual void SetMark()
Unless this is called, the getter method of Mark will return Point.
Definition: pam.cxx:643
void Exchange()
Definition: pam.hxx:242
bool IsMultiSelection() const
Definition: pam.hxx:322
SwContentNode * GetPointContentNode() const
Definition: pam.hxx:279
bool Move(SwMoveFnCollection const &fnMove=fnMoveForward, SwGoInDoc fnGo=GoInContent)
Movement of cursor.
Definition: pam.cxx:657
const SwPosition * End() const
Definition: pam.hxx:263
SwPaM * GetNext()
Definition: pam.hxx:314
SwDoc & GetDoc() const
Definition: pam.hxx:291
OUString GetText() const
Definition: pam.cxx:1305
void DeleteMark()
Definition: pam.hxx:232
SwNode & GetMarkNode() const
Definition: pam.hxx:276
const SwPosition * GetPoint() const
Definition: pam.hxx:253
const SwPosition * Start() const
Definition: pam.hxx:258
bool HasMark() const
A PaM marks a selection if Point and Mark are distinct positions.
Definition: pam.hxx:251
void CalcStartEnd(SwNodeOffset nNdIdx, sal_Int32 &rStart, sal_Int32 &rEnd) const
Calculates the intersection with text node number nNdIdx.
Definition: docredln.cxx:1470
RedlineType GetType(sal_uInt16 nPos=0) const
Definition: docredln.cxx:1975
Of course Writer needs its own rectangles.
Definition: swrect.hxx:35
void Height(tools::Long nNew)
Definition: swrect.hxx:193
void Top(const tools::Long nTop)
Definition: swrect.hxx:206
void Pos(const Point &rNew)
Definition: swrect.hxx:171
Point Center() const
Definition: swrect.hxx:338
void Left(const tools::Long nLeft)
Definition: swrect.hxx:197
vector_type::size_type size_type
Definition: docary.hxx:223
The root element of a Writer document layout.
Definition: rootfrm.hxx:85
SwViewShell * GetCurrShell() const
Definition: rootfrm.hxx:215
bool HasMergedParas() const
Definition: wsfrm.cxx:4773
sw::FieldmarkMode GetFieldmarkMode() const
Definition: rootfrm.hxx:436
virtual bool GetModelPositionForViewPoint(SwPosition *, Point &, SwCursorMoveState *=nullptr, bool bTestBackground=false) const override
Primary passes the call to the first page.
Definition: trvlfrm.cxx:425
sal_uInt8 DirType(const TextFrameIndex nPos) const
Definition: porlay.cxx:1899
static SwScriptInfo * GetScriptInfo(const SwTextNode &rNode, SwTextFrame const **o_pFrame=nullptr, bool bAllowInvalid=false)
return a frame for the node, ScriptInfo is its member... (many clients need both frame and SI,...
Definition: porlay.cxx:2608
SwSection * GetSection() const
Definition: section.cxx:646
Array of Undo-history.
Definition: docary.hxx:193
A section node represents the start of a section on the UI, i.e.
Definition: node.hxx:575
const SwSection & GetSection() const
Definition: node.hxx:590
bool IsProtectFlag() const
Definition: section.hxx:191
bool IsHiddenFlag() const
Definition: section.hxx:190
SectionType GetType() const
Definition: section.hxx:173
Represents the current text cursor of one opened edit window.
Definition: viscrs.hxx:140
Starts a section of nodes in the document model.
Definition: node.hxx:348
SwTableBox is one table cell in the document model.
Definition: swtable.hxx:443
sal_Int32 getRowSpan() const
Definition: swtable.hxx:540
SwTableBox & FindStartOfRowSpan(const SwTable &, sal_uInt16 nMaxStep=USHRT_MAX)
SwTableBox::FindStartOfRowSpan(..) returns the "master" cell, the cell which overlaps the given cell,...
SwNodeOffset GetSttIdx() const
Definition: swtable.cxx:2242
SwFrameFormat * GetFrameFormat()
Definition: swtable.hxx:481
const SwStartNode * GetSttNd() const
Definition: swtable.hxx:495
SwTableBox & FindEndOfRowSpan(const SwTable &, sal_uInt16 nMaxStep)
SwTableBox::FindEndOfRowSpan(..) returns the last overlapped cell if there is any.
bool HasReadOnlyBoxSel() const
Definition: swcrsr.cxx:2610
bool HasHiddenBoxSel() const
Definition: swcrsr.cxx:2624
bool IsCursorMovedUpdate()
Definition: swcrsr.cxx:2580
void DeleteBox(size_t nPos)
Definition: swcrsr.cxx:2518
bool NewTableSelection()
Definition: swcrsr.cxx:2524
virtual bool LeftRight(bool bLeft, sal_uInt16 nCnt, SwCursorSkipMode nMode, bool bAllowVisual, bool bSkipHidden, bool bInsertCursor, SwRootFrame const *, bool) override
Definition: swcrsr.cxx:1667
SwSelBoxes m_SelectedBoxes
Definition: swcrsr.hxx:261
SwCursor * MakeBoxSels(SwCursor *pCurrentCursor)
Definition: swcrsr.cxx:2409
virtual bool IsSelOvrCheck(SwCursorSelOverFlags eFlags) override
Definition: swcrsr.cxx:193
SwNodeOffset m_nTableMkNd
Definition: swcrsr.hxx:258
bool m_bParked
Definition: swcrsr.hxx:263
SwTableCursor(const SwPosition &rPos)
Definition: swcrsr.cxx:2366
void ActualizeSelection(const SwSelBoxes &rBoxes)
Definition: swcrsr.cxx:2545
bool IsCursorMoved() const
Definition: swcrsr.hxx:292
sal_Int32 m_nTablePtCnt
Definition: swcrsr.hxx:259
bool m_bChanged
Definition: swcrsr.hxx:262
SwNodeOffset m_nTablePtNd
Definition: swcrsr.hxx:257
void InsertBox(const SwTableBox &rTableBox)
Definition: swcrsr.cxx:2511
virtual bool GotoTable(const OUString &rName) override
Definition: swcrsr.cxx:2245
void ParkCursor()
park table cursor on the boxes' start node
Definition: swcrsr.cxx:2593
virtual ~SwTableCursor() override
Definition: swcrsr.cxx:2377
sal_Int32 m_nTableMkCnt
Definition: swcrsr.hxx:260
const SwTable & GetTable() const
Definition: node.hxx:542
SwTable is one table in the document model, containing rows (which contain cells).
Definition: swtable.hxx:113
void CreateSelection(const SwPaM &rPam, SwSelBoxes &rBoxes, const SearchType eSearchType, bool bProtect) const
void SwTable::CreateSelection(..) fills the selection structure with table cells for a given SwPaM,...
const SwTableBox * GetTableBox(const OUString &rName, const bool bPerformValidCheck=false) const
Definition: swtable.cxx:1344
static SwTable * FindTable(SwFrameFormat const *const pFormat)
Definition: swtable.cxx:2308
@ SEARCH_NONE
Definition: swtable.hxx:146
SwTableSortBoxes & GetTabSortBoxes()
Definition: swtable.hxx:267
bool IsNewModel() const
Definition: swtable.hxx:193
A wrapper around SfxPoolItem to store the start position of (usually) a text portion,...
Definition: txatbase.hxx:44
const sal_Int32 * End() const
Definition: txatbase.hxx:156
sal_Int32 GetStart() const
Definition: txatbase.hxx:88
Represents the visualization of a paragraph.
Definition: txtfrm.hxx:168
void PrepareVisualMove(TextFrameIndex &nPos, sal_uInt8 &nCursorLevel, bool &bRight, bool bInsertCursor)
Prepares the cursor position for a visual cursor move (BiDi).
Definition: frmcrsr.cxx:1045
SwPosition MapViewToModelPos(TextFrameIndex nIndex) const
Definition: txtfrm.cxx:1333
std::pair< SwTextNode *, sal_Int32 > MapViewToModel(TextFrameIndex nIndex) const
map position in potentially merged text frame to SwPosition
Definition: txtfrm.cxx:1318
TextFrameIndex MapModelToView(SwTextNode const *pNode, sal_Int32 nIndex) const
Definition: txtfrm.cxx:1339
TextFrameIndex MapModelToViewPos(SwPosition const &rPos) const
Definition: txtfrm.cxx:1354
const OUString & GetText() const
Returns the text portion we want to edit (for inline see underneath)
Definition: txtfrm.cxx:1380
SwTextNode is a paragraph in the document model.
Definition: ndtxt.hxx:112
virtual sal_Int32 Len() const override
Definition: ndtxt.cxx:291
SwTextAttr * GetTextAttrAt(sal_Int32 const nIndex, sal_uInt16 const nWhich, ::sw::GetTextAttrMode const eMode=::sw::GetTextAttrMode::Default) const
get the innermost text attribute covering position nIndex.
Definition: ndtxt.cxx:1804
const OUString & GetText() const
Definition: ndtxt.hxx:244
LanguageType GetLang(const sal_Int32 nBegin, const sal_Int32 nLen=0, sal_uInt16 nScript=0) const
Definition: thints.cxx:3474
std::vector< SwSectionFormat * >::size_type size_type
Definition: docary.hxx:67
size_t size() const
Definition: docary.hxx:88
bool IsShowOutlineContentVisibilityButton() const
Definition: viewopt.cxx:177
vcl::RenderContext * GetOut() const
Definition: viewsh.hxx:365
const SwViewOption * GetViewOptions() const
Definition: viewsh.hxx:452
SwRootFrame * GetLayout() const
Definition: viewsh.cxx:2163
const_iterator begin() const
size_type erase(const Value &x)
size_type size() const
std::pair< const_iterator, bool > insert(Value &&x)
void merge(RingContainer< value_type > aDestRing)
Merges two ring containers.
Definition: ring.hxx:182
ring_container GetRingContainer()
Definition: ring.hxx:240
@ UpDown
Cursor Up/Down.
bool(* SwWhichPara)(SwPaM &, SwMoveFnCollection const &)
Definition: cshtyp.hxx:43
SwDocPositions
Definition: cshtyp.hxx:104
FindRanges
Definition: cshtyp.hxx:91
@ InSel
Find in selections.
@ InBodyOnly
Find only in body - only in combination with FindRanges::InSelAll !!!
@ InSelAll
All (only in non-body and selections).
@ InOther
Find "all" in Footer/Header/Fly...
@ InBody
Find "one" only in body text.
bool(* SwWhichSection)(SwPaM &, SwMoveFnCollection const &)
Definition: cshtyp.hxx:51
constexpr OUStringLiteral IsHidden(u"IsHidden")
static SwContentNode * GetContentNode(SwDoc &rDoc, SwPosition &rPos, bool bNext)
Definition: fltshell.cxx:54
#define CH_TXTATR_INWORD
Definition: hintids.hxx:175
constexpr TypedWhichId< SwFormatField > RES_TXTATR_INPUTFIELD(55)
#define CH_TXT_ATR_FIELDEND
Definition: hintids.hxx:185
#define CH_TXT_ATR_FIELDSTART
Definition: hintids.hxx:183
CharClass & GetAppCharClass()
Definition: init.cxx:721
sal_Int32 nIndex
sal_Int64 n
uno_Any a
sal_uInt16 nPos
void StartProgress(TranslateId pMessResId, tools::Long nStartValue, tools::Long nEndValue, SwDocShell *pDocShell)
Definition: mainwn.cxx:52
void EndProgress(SwDocShell const *pDocShell)
Definition: mainwn.cxx:92
void SetProgressState(tools::Long nPosition, SwDocShell const *pDocShell)
Definition: mainwn.cxx:82
double getLength(const B2DPolygon &rCandidate)
size
SwPosition FindFieldSep(IFieldmark const &rMark)
return position of the CH_TXT_ATR_FIELDSEP for rMark
@ Parent
EXPAND : (Start < nIndex <= End)
long Long
sal_Int32 w
o3tl::strong_int< sal_Int32, struct Tag_SwNodeOffset > SwNodeOffset
Definition: nodeoffset.hxx:16
SwNodeOffset min(const SwNodeOffset &a, const SwNodeOffset &b)
Definition: nodeoffset.hxx:35
bool GoCurrPara(SwPaM &rPam, SwMoveFnCollection const &aPosPara)
Definition: pam.cxx:1248
bool GoInContentSkipHidden(SwPaM &rPam, SwMoveFnCollection const &fnMove)
Definition: pam.cxx:1219
bool GoInContentCells(SwPaM &rPam, SwMoveFnCollection const &fnMove)
Definition: pam.cxx:1211
bool GoInNode(SwPaM &rPam, SwMoveFnCollection const &fnMove)
Definition: pam.cxx:1194
SwContentNode * GetNode(SwPaM &rPam, bool &rbFirst, SwMoveFnCollection const &fnMove, bool const bInReadOnly, SwRootFrame const *const i_pLayout)
This function returns the next node in direction of search.
Definition: pam.cxx:1043
bool GoInDoc(SwPaM &rPam, SwMoveFnCollection const &fnMove)
Definition: pam.cxx:1182
bool GoInContentCellsSkipHidden(SwPaM &rPam, SwMoveFnCollection const &fnMove)
Definition: pam.cxx:1227
bool CheckNodesRange(const SwNode &rStt, const SwNode &rEnd, bool bChkSection)
Check if the given range is inside one of the defined top-level sections.
Definition: pam.cxx:349
bool GoNextPara(SwPaM &rPam, SwMoveFnCollection const &aPosPara)
Definition: pam.cxx:1275
bool GoInContent(SwPaM &rPam, SwMoveFnCollection const &fnMove)
Definition: pam.cxx:1203
auto(*)(SwPaM &rPam, SwMoveFnCollection const &fnMove) -> bool SwGoInDoc
Definition: pam.hxx:172
SwMoveFnCollection const & fnMoveBackward
Definition: paminit.cxx:60
SwMoveFnCollection const & fnMoveForward
SwPam::Move()/Find() default argument.
Definition: paminit.cxx:61
sal_uIntPtr sal_uLong
bool m_bSetInReadOnly
ReadOnly areas may be entered.
Definition: crstate.hxx:148
virtual bool IsReplaceMode() const =0
virtual int DoFind(SwPaM &, SwMoveFnCollection const &, const SwPaM &, bool, std::unique_ptr< SvxSearchItem > &xSearchItem)=0
Marks a position in the document model.
Definition: pam.hxx:38
void Adjust(SwNodeOffset nDelta)
Adjust node position, and resets content position to zero.
Definition: pam.cxx:257
SwNode & GetNode() const
Definition: pam.hxx:81
void Assign(const SwNode &rNd, SwNodeOffset nDelta, sal_Int32 nContentOffset=0)
These all set both nNode and nContent.
Definition: pam.cxx:231
void AssignEndIndex(const SwContentNode &rNd)
Set nNode to rNd, and nContent to the end of rNd.
Definition: pam.cxx:277
void SetContent(sal_Int32 nContentIndex)
Set content index, only valid to call this if the position points to a SwContentNode subclass.
Definition: pam.cxx:267
SwNodeOffset GetNodeIndex() const
Definition: pam.hxx:78
void AssignStartIndex(const SwContentNode &rNd)
Set nNode to rNd, and nContent to the beginning of rNd.
Definition: pam.cxx:272
sal_Int32 GetContentIndex() const
Definition: pam.hxx:85
void AdjustContent(sal_Int32 nDelta)
Adjust content index, only valid to call this if the position points to a SwContentNode subclass.
Definition: pam.cxx:262
static bool lcl_SeekEntry(const SwSelBoxes &rTmp, SwStartNode const *const pSrch, size_t &o_rFndPos)
Definition: swcrsr.cxx:2380
static bool lcl_MakeSelBkwrd(const SwNode &rSttNd, const SwNode &rEndNd, SwPaM &rPam, bool bFirst)
Definition: swcrsr.cxx:916
static OUString lcl_MaskDeletedRedlines(const SwTextNode *pTextNd)
Definition: swcrsr.cxx:1519
static bool lcl_MakeSelFwrd(const SwNode &rSttNd, const SwNode &rEndNd, SwPaM &rPam, bool bFirst)
Definition: swcrsr.cxx:884
const sal_uInt16 coSrchRplcThreshold
Definition: swcrsr.cxx:64
static sal_Int32 lcl_FindSelection(SwFindParas &rParas, SwCursor *pCurrentCursor, SwMoveFnCollection const &fnMove, SwCursor *&pFndRing, SwPaM &aRegion, FindRanges eFndRngs, bool bInReadOnly, bool &bCancel)
Definition: swcrsr.cxx:758
SwCursorSkipMode
Definition: swcrsr.hxx:65
SwCursorSelOverFlags
Definition: swcrsr.hxx:50
const int FIND_NO_RING
Definition: swcrsr.hxx:37
unsigned char sal_uInt8
Count
RET_CANCEL
RET_YES
size_t pos