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