LibreOffice Module sw (master) 1
crsrsh.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 <config_wasm_strip.h>
21
22#include <com/sun/star/text/XTextRange.hpp>
23
24#include <hintids.hxx>
25#include <svx/srchdlg.hxx>
26#include <sfx2/viewsh.hxx>
27#include <SwSmartTagMgr.hxx>
28#include <doc.hxx>
29#include <rootfrm.hxx>
30#include <pagefrm.hxx>
31#include <cntfrm.hxx>
32#include <viewimp.hxx>
33#include <pam.hxx>
34#include <swselectionlist.hxx>
35#include "BlockCursor.hxx"
36#include <ndtxt.hxx>
37#include <flyfrm.hxx>
38#include <dview.hxx>
39#include <viewopt.hxx>
40#include <crsrsh.hxx>
41#include <tabfrm.hxx>
42#include <txtfrm.hxx>
43#include <sectfrm.hxx>
44#include <swtable.hxx>
45#include "callnk.hxx"
46#include <viscrs.hxx>
47#include <section.hxx>
48#include <docsh.hxx>
49#include <scriptinfo.hxx>
50#include <globdoc.hxx>
51#include <pamtyp.hxx>
52#include <mdiexp.hxx>
53#include <fmteiro.hxx>
54#include <wrong.hxx>
55#include <unotextrange.hxx>
56#include <vcl/svapp.hxx>
57#include <vcl/settings.hxx>
58#include <GrammarContact.hxx>
61#include <strings.hrc>
63#include <LibreOfficeKit/LibreOfficeKitEnums.h>
64#include <comphelper/lok.hxx>
66#include <sfx2/lokhelper.hxx>
67#include <editeng/editview.hxx>
68#include <editeng/frmdir.hxx>
69#include <sal/log.hxx>
70#include <PostItMgr.hxx>
72#include <vcl/uitest/logger.hxx>
74#include <tabcol.hxx>
75#include <wrtsh.hxx>
76#include <undobj.hxx>
77#include <view.hxx>
78#include <hints.hxx>
79#include <tools/json_writer.hxx>
80
81using namespace com::sun::star;
82using namespace util;
83
88static void CheckRange( SwCursor* pCurrentCursor )
89{
90 auto [pStt, pEnd] = pCurrentCursor->StartEnd(); // SwPosition*
91
92 SwPaM *pTmpDel = nullptr,
93 *pTmp = pCurrentCursor->GetNext();
94
95 // Search the complete ring
96 while( pTmp != pCurrentCursor )
97 {
98 auto [pTmpStt, pTmpEnd] = pTmp->StartEnd(); // SwPosition*
99 if( *pStt <= *pTmpStt )
100 {
101 if( *pEnd > *pTmpStt ||
102 ( *pEnd == *pTmpStt && *pEnd == *pTmpEnd ))
103 pTmpDel = pTmp;
104 }
105 else
106 if( *pStt < *pTmpEnd )
107 pTmpDel = pTmp;
108
109 // If Point or Mark is within the Cursor range, we need to remove the old
110 // range. Take note that Point does not belong to the range anymore.
111 pTmp = pTmp->GetNext();
112 delete pTmpDel; // Remove old range
113 pTmpDel = nullptr;
114 }
115}
116
117// SwCursorShell
118
124{
125 // don't create new Cursor with active table Selection
126 assert(!IsTableMode());
127
128 // ensure that m_pCurrentCursor is valid; if it's invalid it would be
129 // copied to pNew and then pNew would be deleted in UpdateCursor() below
131
132 // New cursor as copy of current one. Add to the ring.
133 // Links point to previously created one, ie forward.
135
136 // Hide PaM logically, to avoid undoing the inverting from
137 // copied PaM (#i75172#)
139
141
143 return pNew;
144}
145
152{
153 // don't delete Cursor with active table Selection
154 assert(!IsTableMode());
155
156 // Is there a next one? Don't do anything if not.
158 return;
159
160 SwCallLink aLk( *this ); // watch Cursor-Moves
161 SwCursor* pNextCursor = static_cast<SwCursor*>(m_pCurrentCursor->GetNext());
162 delete m_pCurrentCursor;
163 m_pCurrentCursor = dynamic_cast<SwShellCursor*>(pNextCursor);
164 UpdateCursor();
165}
166
173{
174 if (HasSelection())
175 {
176 (void) CreateCursor(); // n.b. returns old cursor
177 }
178 return *GetCursor();
179}
180
186{
187 return *GetCursor();
188}
189
194SwCursor* SwCursorShell::GetCursor( bool bMakeTableCursor ) const
195{
196 if( m_pTableCursor )
197 {
198 if( bMakeTableCursor && m_pTableCursor->IsCursorMovedUpdate() )
199 {
200 //don't re-create 'parked' cursors
203 {
205 if( pCNd && pCNd->getLayoutFrame( GetLayout() ) )
206 {
208 if( pCNd && pCNd->getLayoutFrame( GetLayout() ) )
209 {
211 GetLayout()->MakeTableCursors( *pTC );
212 }
213 }
214 }
215 }
216
217 if( m_pTableCursor->IsChgd() )
218 {
219 const_cast<SwCursorShell*>(this)->m_pCurrentCursor =
221 }
222 }
223 return m_pCurrentCursor;
224}
225
227{
228 if( !ActionPend() )
229 {
230 // save for update of the ribbon bar
231 const SwNode& rNd = m_pCurrentCursor->GetPoint()->GetNode();
232 m_nCurrentNode = rNd.GetIndex();
235 if( rNd.IsTextNode() )
237 else
238 m_nLeftFramePos = 0;
239 }
240 SwViewShell::StartAction(); // to the SwViewShell
241}
242
243void SwCursorShell::EndAction( const bool bIdleEnd )
244{
246 bool bVis = m_bSVCursorVis;
247
248 // Idle-formatting?
249 if( bIdleEnd && Imp()->HasPaintRegion() )
250 {
252 }
253
254 // Update all invalid numberings before the last action
255 if( 1 == mnStartAction )
257
258 // #i76923#: Don't show the cursor in the SwViewShell::EndAction() - call.
259 // Only the UpdateCursor shows the cursor.
260 bool bSavSVCursorVis = m_bSVCursorVis;
261 m_bSVCursorVis = false;
262
263 SwViewShell::EndAction( bIdleEnd ); // have SwViewShell go first
264
265 m_bSVCursorVis = bSavSVCursorVis;
266
267 if( ActionPend() )
268 {
269 if( bVis ) // display SV-Cursor again
271
272 return;
273 }
274
275 sal_uInt16 eFlags = SwCursorShell::CHKRANGE;
276 if ( !bIdleEnd )
277 eFlags |= SwCursorShell::SCROLLWIN;
278
279 UpdateCursor( eFlags, bIdleEnd ); // Show Cursor changes
280
281 {
282 SwCallLink aLk( *this ); // Watch cursor moves,
283 aLk.m_nNode = m_nCurrentNode; // possibly call the link
287
288 if( !m_nCursorMove ||
290 // display Cursor & Selections again
292 }
293 // call ChgCall if there is still one
295 {
296 m_aChgLnk.Call(nullptr);
297 m_bChgCallFlag = false; // reset flag
298 }
299}
300
302{
303#ifdef DBG_UTIL
304 OSL_ENSURE( m_nCursorMove < USHRT_MAX, "Too many nested CursorMoves." );
305#endif
307 StartAction();
308}
309
310void SwCursorShell::EndCursorMove( const bool bIdleEnd )
311{
312#ifdef DBG_UTIL
313 OSL_ENSURE( m_nCursorMove, "EndCursorMove() without SttCursorMove()." );
314#endif
315 EndAction( bIdleEnd );
317#ifdef DBG_UTIL
318 if( !m_nCursorMove )
319 m_bInCMvVisportChgd = false;
320#endif
321}
322
323bool SwCursorShell::LeftRight( bool bLeft, sal_uInt16 nCnt, SwCursorSkipMode nMode,
324 bool bVisualAllowed )
325{
326 if( IsTableMode() )
327 return bLeft ? GoPrevCell() : GoNextCell();
328
329 SwCallLink aLk( *this ); // watch Cursor-Moves; call Link if needed
330 bool bRet = false;
331
332 // #i27615# Handle cursor in front of label.
333 const SwTextNode* pTextNd = nullptr;
334
335 if( m_pBlockCursor )
337
338 // 1. CASE: Cursor is in front of label. A move to the right
339 // will simply reset the bInFrontOfLabel flag:
340 SwShellCursor* pShellCursor = getShellCursor( true );
341 if ( !bLeft && pShellCursor->IsInFrontOfLabel() )
342 {
343 SetInFrontOfLabel( false );
344 bRet = true;
345 }
346 // 2. CASE: Cursor is at beginning of numbered paragraph. A move
347 // to the left will simply set the bInFrontOfLabel flag:
348 else if (bLeft
349 && pShellCursor->GetPoint()->GetNode().IsTextNode()
350 && static_cast<SwTextFrame const*>(
351 pShellCursor->GetPoint()->GetNode().GetTextNode()->getLayoutFrame(GetLayout())
352 )->MapModelToViewPos(*pShellCursor->GetPoint()) == TextFrameIndex(0)
353 && !pShellCursor->IsInFrontOfLabel()
354 && !pShellCursor->HasMark()
355 && nullptr != (pTextNd = sw::GetParaPropsNode(*GetLayout(), pShellCursor->GetPoint()->GetNode()))
356 && pTextNd->HasVisibleNumberingOrBullet())
357 {
358 SetInFrontOfLabel( true );
359 bRet = true;
360 }
361 // 3. CASE: Regular cursor move. Reset the bInFrontOfLabel flag:
362 else
363 {
364 const bool bSkipHidden = !GetViewOptions()->IsShowHiddenChar();
365 // #i107447#
366 // To avoid loop the reset of <bInFrontOfLabel> flag is no longer
367 // reflected in the return value <bRet>.
368 const bool bResetOfInFrontOfLabel = SetInFrontOfLabel( false );
369 bRet = pShellCursor->LeftRight( bLeft, nCnt, nMode, bVisualAllowed,
370 bSkipHidden, !IsOverwriteCursor(),
371 GetLayout(),
372 GetViewOptions()->IsFieldName());
373 if ( !bRet && bLeft && bResetOfInFrontOfLabel )
374 {
375 // undo reset of <bInFrontOfLabel> flag
376 SetInFrontOfLabel( true );
377 }
378 }
379
380 if( bRet )
381 {
382 UpdateCursor();
383 }
384
385 return bRet;
386}
387
388void SwCursorShell::MarkListLevel( const OUString& sListId,
389 const int nListLevel )
390{
391 if (sListId == m_sMarkedListId && nListLevel == m_nMarkedListLevel)
392 return;
393
394 // Writer redraws the "marked" list with the field shading, if there
395 // is no field shading then the marked list would be redrawn for no
396 // visually identifiable reason, so skip the mark if field shadings
397 // are disabled.
398 const bool bVisuallyMarked(GetViewOptions()->IsFieldShadings());
399 if (bVisuallyMarked)
400 {
401 if ( !m_sMarkedListId.isEmpty() )
402 mxDoc->MarkListLevel( m_sMarkedListId, m_nMarkedListLevel, false );
404 if ( !sListId.isEmpty() )
405 mxDoc->MarkListLevel( sListId, nListLevel, true );
406 }
407
408 m_sMarkedListId = sListId;
409 m_nMarkedListLevel = nListLevel;
410}
411
413{
414 SwTextNode const*const pTextNd = sw::GetParaPropsNode(*GetLayout(),
415 GetCursor_()->GetPoint()->GetNode());
416
417 if ( !pTextNd )
418 return;
419
420 if (!pTextNd->IsNumbered(GetLayout()))
421 {
423 MarkListLevel( OUString(), 0 );
424 }
426 {
427 if ( pTextNd->IsInList() )
428 {
429 assert(pTextNd->GetActualListLevel() >= 0 &&
430 pTextNd->GetActualListLevel() < MAXLEVEL);
431 MarkListLevel( pTextNd->GetListId(),
432 pTextNd->GetActualListLevel() );
433 }
434 }
435 else
436 {
437 MarkListLevel( OUString(), 0 );
438 }
439}
440
441void SwCursorShell::FirePageChangeEvent(sal_uInt16 nOldPage, sal_uInt16 nNewPage)
442{
443#ifdef ACCESSIBLE_LAYOUT
444 if( Imp()->IsAccessible() )
445 Imp()->FirePageChangeEvent( nOldPage, nNewPage );
446#else
447 (void)nOldPage;
448 (void)nNewPage;
449#endif
450}
451
452void SwCursorShell::FireColumnChangeEvent(sal_uInt16 nOldColumn, sal_uInt16 nNewColumn)
453{
454#ifdef ACCESSIBLE_LAYOUT
455 if( Imp()->IsAccessible() )
456 Imp()->FireColumnChangeEvent( nOldColumn, nNewColumn);
457#else
458 (void)nOldColumn;
459 (void)nNewColumn;
460#endif
461}
462
463void SwCursorShell::FireSectionChangeEvent(sal_uInt16 nOldSection, sal_uInt16 nNewSection)
464{
465#ifdef ACCESSIBLE_LAYOUT
466 if( Imp()->IsAccessible() )
467 Imp()->FireSectionChangeEvent( nOldSection, nNewSection );
468#else
469 (void)nOldSection;
470 (void)nNewSection;
471#endif
472}
473
475{
476 SwFrame* pCurrFrame = GetCurrFrame(false);
477
478 if (pCurrFrame == nullptr)
479 {
480 return false;
481 }
482
483 SwFrame* pCurrCol=pCurrFrame->FindColFrame();
484
485 while(pCurrCol== nullptr && pCurrFrame!=nullptr )
486 {
487 SwLayoutFrame* pParent = pCurrFrame->GetUpper();
488 if(pParent!=nullptr)
489 {
490 pCurrCol=static_cast<SwFrame*>(pParent)->FindColFrame();
491 pCurrFrame = pParent;
492 }
493 else
494 {
495 break;
496 }
497 }
498
499 if(m_oldColFrame == pCurrCol)
500 return false;
501 else
502 {
503 m_oldColFrame = pCurrCol;
504 return true;
505 }
506}
507
508bool SwCursorShell::UpDown( bool bUp, sal_uInt16 nCnt )
509{
510 CurrShell aCurr( this );
511 SwCallLink aLk( *this ); // watch Cursor-Moves; call Link if needed
512
513 bool bTableMode = IsTableMode();
514 SwShellCursor* pTmpCursor = getShellCursor( true );
515
516 bool bRet = pTmpCursor->UpDown( bUp, nCnt );
517 // #i40019# UpDown should always reset the bInFrontOfLabel flag:
518 bRet |= SetInFrontOfLabel(false);
519
520 if( m_pBlockCursor )
522
523 if( bRet )
524 {
525 m_eMvState = CursorMoveState::UpDown; // status for Cursor travelling - GetModelPositionForViewPoint
526 if( !ActionPend() )
527 {
529 if( !bTableMode )
530 eUpdateMode = static_cast<CursorFlag>(eUpdateMode
532 UpdateCursor( o3tl::narrowing<sal_uInt16>(eUpdateMode) );
533 }
534 }
535 return bRet;
536}
537
538bool SwCursorShell::LRMargin( bool bLeft, bool bAPI)
539{
540 SwCallLink aLk( *this ); // watch Cursor-Moves; call Link if needed
541 CurrShell aCurr( this );
542 m_eMvState = CursorMoveState::LeftMargin; // status for Cursor travelling - GetModelPositionForViewPoint
543
544 const bool bTableMode = IsTableMode();
545 SwShellCursor* pTmpCursor = getShellCursor( true );
546
547 if( m_pBlockCursor )
549
550 const bool bWasAtLM = GetCursor_()->IsAtLeftRightMargin(*GetLayout(), true, bAPI);
551
552 bool bRet = pTmpCursor->LeftRightMargin(*GetLayout(), bLeft, bAPI);
553
554 if ( bLeft && !bTableMode && bRet && bWasAtLM && !GetCursor_()->HasMark() )
555 {
556 const SwTextNode * pTextNd = GetCursor_()->GetPointNode().GetTextNode();
557 assert(sw::GetParaPropsNode(*GetLayout(), GetCursor_()->GetPoint()->GetNode()) == pTextNd);
558 if ( pTextNd && pTextNd->HasVisibleNumberingOrBullet() )
559 SetInFrontOfLabel( true );
560 }
561 else if ( !bLeft )
562 {
563 bRet = SetInFrontOfLabel( false ) || bRet;
564 }
565
566 if( bRet )
567 {
568 UpdateCursor();
569 }
570 return bRet;
571}
572
573bool SwCursorShell::IsAtLRMargin( bool bLeft, bool bAPI ) const
574{
575 const SwShellCursor* pTmpCursor = getShellCursor( true );
576 return pTmpCursor->IsAtLeftRightMargin(*GetLayout(), bLeft, bAPI);
577}
578
580{
581 SwCallLink aLk( *this ); // watch Cursor-Moves; call Link if needed
582
584 bool bRet = pTmpCursor->SttEndDoc( bStt );
585 if( bRet )
586 {
587 if( bStt )
588 pTmpCursor->GetPtPos().setY( 0 ); // set to 0 explicitly (table header)
589 if( m_pBlockCursor )
590 {
593 }
594
596 }
597 return bRet;
598}
599
601{
602 if (m_pTableCursor)
603 { // find the table that has the selected boxes
604 return m_pTableCursor->GetSelectedBoxes()[0]->GetSttNd()->FindTableNode();
605 }
607}
608
609// fun cases to consider:
610// * outermost table
611// - into para => SA/ESA
612// - into prev/next table => continue...
613// - no prev/next => done
614// * inner table
615// - into containing cell => SA/ESA
616// - into prev/next of containing cell
617// + into para
618// + into table nested in prev/next cell
619// - out of table -> as above
620// => iterate in one direction until a node is reached that is a parent or a sibling of a parent of the current table
621// - parent reached => SA/ESA depending
622// - not in parent but in *prev/next* sibling of outer cell => TrySelectOuterTable
623// - not in parent but in *prev/next* sibling of outer table => TrySelectOuterTable
624// => select-all cannot select a sequence of table with no para at same level; only 1 table
625// - no parent, no prev/next => TrySelectOuterTable
626
628{
629 SwPosition const point(*getShellCursor(false)->GetPoint());
630 SwPosition const mark(*getShellCursor(false)->GetMark());
631
632 for (auto const fnMove : {&fnMoveBackward, &fnMoveForward})
633 {
634 Push();
635 SwCursor *const pCursor(getShellCursor(false));
636
637 pCursor->Normalize(fnMove == &fnMoveBackward);
638 pCursor->DeleteMark();
639 SwTableNode const*const pTable(pCursor->GetPoint()->GetNode().FindTableNode());
640 assert(pTable);
641 while (MovePara(GoInContent, *fnMove))
642 {
643 SwStartNode const*const pBox(pCursor->GetPoint()->GetNode().FindTableBoxStartNode());
644 if (!pBox)
645 {
647 return true; // moved to paragraph at top-level of text
648 }
649 if (pBox->GetIndex() < pTable->GetIndex()
650 && pTable->EndOfSectionIndex() < pBox->EndOfSectionIndex())
651 {
653 return true; // pBox contains start position (pTable)
654 }
655 }
656
658 // FIXME: Pop doesn't restore original cursor if nested tables
659 *getShellCursor(false)->GetPoint() = point;
660 getShellCursor(false)->SetMark();
661 *getShellCursor(false)->GetMark() = mark;
662 }
663 return false;
664}
665
667{
668 assert(m_pTableCursor);
669 SwTableNode const& rInnerTable(*m_pTableCursor->GetPoint()->GetNode().FindTableNode());
670 SwNodes const& rNodes(rInnerTable.GetNodes());
671 SwTableNode const*const pOuterTable(rInnerTable.GetNodes()[rInnerTable.GetIndex()-1]->FindTableNode());
672 if (!pOuterTable)
673 {
674 return false;
675 }
676
677 // manually select boxes of pOuterTable
678 SwNodeIndex firstCell(*pOuterTable, +1);
679 SwNodeIndex lastCell(*rNodes[pOuterTable->EndOfSectionIndex()-1]->StartOfSectionNode());
680 SwSelBoxes aNew;
681 pOuterTable->GetTable().CreateSelection(&firstCell.GetNode(), &lastCell.GetNode(),
682 aNew, SwTable::SEARCH_NONE, false);
683 // set table cursor to 1st / last content which may be in inner table
684 SwContentNode *const pStart = rNodes.GoNext(&firstCell);
685 assert(pStart); // must at least find the previous point node
686 lastCell = *lastCell.GetNode().EndOfSectionNode();
687 SwContentNode *const pEnd = SwNodes::GoPrevious(&lastCell);
688 assert(pEnd); // must at least find the previous point node
689 delete m_pTableCursor;
690 m_pTableCursor = new SwShellTableCursor(*this, SwPosition(*pStart, 0), Point(),
691 SwPosition(*pEnd, 0), Point());
693 m_pTableCursor->IsCursorMovedUpdate(); // clear this so GetCursor() doesn't recreate our SwSelBoxes
694
695 // this will update m_pCurrentCursor based on m_pTableCursor
697
698 return true;
699}
700
702static SwStartNode const* FindTextStart(SwPosition const& rPos)
703{
704 SwStartNode const* pStartNode(rPos.GetNode().StartOfSectionNode());
705 while (pStartNode && (pStartNode->IsSectionNode() || pStartNode->IsTableNode()))
706 {
707 pStartNode = pStartNode->StartOfSectionNode();
708 }
709 return pStartNode;
710}
711
712static SwStartNode const* FindParentText(SwShellCursor const& rCursor)
713{
714 // find closest section containing both start and end - ignore Sections
715 SwStartNode const* pStartNode(FindTextStart(*rCursor.Start()));
716 SwEndNode const* pEndNode(FindTextStart(*rCursor.End())->EndOfSectionNode());
717 while (pStartNode->EndOfSectionNode()->GetIndex() < pEndNode->GetIndex())
718 {
719 pStartNode = pStartNode->StartOfSectionNode();
720 }
721 while (pStartNode->GetIndex() < pEndNode->StartOfSectionNode()->GetIndex())
722 {
723 pEndNode = pEndNode->StartOfSectionNode()->StartOfSectionNode()->EndOfSectionNode();
724 }
725 assert(pStartNode->EndOfSectionNode() == pEndNode);
726
727 return (pStartNode->IsSectionNode() || pStartNode->IsTableNode())
728 ? FindTextStart(SwPosition(*pStartNode))
729 : pStartNode;
730}
731
733{
734 SwPosition const old(*m_pCurrentCursor->GetPoint());
735 SwStartNode const*const pStartNode(FindParentText(*getShellCursor(false)));
736 assert(pStartNode);
737 SwTableNode const*const pTable(pStartNode->FindTableNode());
738 m_pCurrentCursor->GetPoint()->Assign(*pStartNode);
740 while (m_pCurrentCursor->GetPoint()->GetNode().FindTableNode() != pTable
741 && (!pTable || pTable->GetIndex() < m_pCurrentCursor->GetPoint()->GetNode().FindTableNode()->GetIndex())
742 && MoveOutOfTable());
744 return old != *m_pCurrentCursor->GetPoint();
745}
746
747// select all inside the current XText, with table or hidden para at start/end
749{
750 // find common ancestor node of both ends of cursor
751 SwStartNode const*const pStartNode(FindParentText(*getShellCursor(false)));
752 assert(pStartNode);
753 if (IsTableMode())
754 { // convert m_pTableCursor to m_pCurrentCursor after determining pStartNode
756 }
757 SwNodes& rNodes = GetDoc()->GetNodes();
760 pPos->Assign(bFootnotes ? rNodes.GetEndOfPostIts() : static_cast<SwNode const&>(*pStartNode));
761 rNodes.GoNext( pPos );
762 pPos = m_pCurrentCursor->GetMark();
763 pPos->Assign(bFootnotes ? rNodes.GetEndOfContent() : static_cast<SwNode const&>(*pStartNode->EndOfSectionNode()));
764 SwContentNode* pCNd = SwNodes::GoPrevious( pPos );
765 if (pCNd)
766 pPos->AssignEndIndex(*pCNd);
767}
768
770{
771 for (auto i = rStart.GetIndex() + 1; i < rStart.EndOfSectionIndex(); ++i)
772 {
773 SwNode const& rNode(*rStart.GetNodes()[i]);
774 switch (rNode.GetNodeType())
775 {
777 continue;
780 case SwNodeType::Text:
781 if (rNode.GetTextNode()->IsHidden())
782 {
784 }
786 default:
788 }
789 }
791}
792
793static typename SwCursorShell::StartsWith EndsWith(SwStartNode const& rStart)
794{
795 for (auto i = rStart.EndOfSectionIndex() - 1; rStart.GetIndex() < i; --i)
796 {
797 SwNode const& rNode(*rStart.GetNodes()[i]);
798 switch (rNode.GetNodeType())
799 {
800 case SwNodeType::End:
801 if (rNode.StartOfSectionNode()->IsTableNode())
802 {
804 }
805//TODO buggy SwUndoRedline in testTdf137503? assert(rNode.StartOfSectionNode()->IsSectionNode());
806 break;
807 case SwNodeType::Text:
808 if (rNode.GetTextNode()->IsHidden())
809 {
811 }
813 default:
815 }
816 }
818}
819
820// return the node that is the start of the extended selection (to include table
821// or section start nodes; looks like extending for end nodes is not required)
823{
824 if (m_pTableCursor)
825 {
826 return nullptr;
827 }
828
829 SwNodes& rNodes = GetDoc()->GetNodes();
830 SwShellCursor const*const pShellCursor = getShellCursor(false);
831 SwStartNode const* pStartNode(FindParentText(*pShellCursor));
832
833 SwNodeIndex nNode(*pStartNode);
834 SwContentNode* pStart = rNodes.GoNext(&nNode);
835 if (!pStart)
836 {
837 return nullptr;
838 }
839
840 nNode = *pStartNode->EndOfSectionNode();
841 SwContentNode* pEnd = SwNodes::GoPrevious(&nNode);
842 if (!pEnd)
843 {
844 return nullptr;
845 }
846
847 SwPosition aStart(*pStart, 0);
848 SwPosition aEnd(*pEnd, pEnd->Len());
849 if (!(aStart == *pShellCursor->Start() && aEnd == *pShellCursor->End()))
850 {
851 return nullptr;
852 }
853
854 if (::StartsWith(*pStartNode) == StartsWith::None
855 && ::EndsWith(*pStartNode) == StartsWith::None)
856 {
857 return nullptr; // "ordinary" selection will work
858 }
859
860 // tdf#133990 ensure directly containing section is included in SwUndoDelete
861 while (pStartNode->IsSectionNode()
862 && pStartNode->GetIndex() == pStartNode->StartOfSectionNode()->GetIndex() + 1
863 && pStartNode->EndOfSectionNode()->GetIndex() + 1 == pStartNode->StartOfSectionNode()->EndOfSectionNode()->GetIndex())
864 {
865 pStartNode = pStartNode->StartOfSectionNode();
866 }
867
868 // pStartNode is the node that fully contains the selection - the first
869 // node of the selection is the first node inside pStartNode
870 return pStartNode->GetNodes()[pStartNode->GetIndex() + 1];
871}
872
874{
875 SwShellCursor const*const pShellCursor = getShellCursor(false);
876 SwStartNode const*const pStartNode(FindParentText(*pShellCursor));
877 if (auto const ret = ::StartsWith(*pStartNode); ret != StartsWith::None)
878 {
879 return ret;
880 }
881 if (auto const ret = ::EndsWith(*pStartNode); ret != StartsWith::None)
882 {
883 return ret;
884 }
885 return StartsWith::None;
886}
887
888bool SwCursorShell::MovePage( SwWhichPage fnWhichPage, SwPosPage fnPosPage )
889{
890 bool bRet = false;
891
892 // never jump of section borders at selection
894 {
895 SwCallLink aLk( *this ); // watch Cursor-Moves; call Link if needed
896 CurrShell aCurr( this );
897
898 SwCursorSaveState aSaveState( *m_pCurrentCursor );
900 std::pair<Point, bool> tmp(rPt, false);
902 getLayoutFrame(GetLayout(), m_pCurrentCursor->GetPoint(), &tmp);
903 if( pFrame && GetFrameInPage( pFrame, fnWhichPage, fnPosPage, m_pCurrentCursor ) &&
906 {
907 UpdateCursor();
908 bRet = true;
909 }
910 }
911 return bRet;
912}
913
915{
916 SwContentNode *pCNode = pShellCursor->GetPointContentNode();
917 std::pair<Point, bool> tmp(pShellCursor->GetPtPos(), false);
918 SwContentFrame *const pFrame = pCNode
919 ? pCNode->getLayoutFrame(GetLayout(), pShellCursor->GetPoint(), &tmp)
920 : nullptr;
921 return !pFrame || (pFrame->IsTextFrame() && static_cast<SwTextFrame*>(pFrame)->IsHiddenNow());
922}
923
924// sw_redlinehide: this should work for all cases: GoCurrPara, GoNextPara, GoPrevPara
925static bool IsAtStartOrEndOfFrame(SwCursorShell const*const pShell,
926 SwShellCursor const*const pShellCursor, SwMoveFnCollection const& fnPosPara)
927{
928 SwContentNode *const pCNode = pShellCursor->GetPointContentNode();
929 assert(pCNode); // surely can't have moved otherwise?
930 std::pair<Point, bool> tmp(pShellCursor->GetPtPos(), false);
931 SwContentFrame const*const pFrame = pCNode->getLayoutFrame(
932 pShell->GetLayout(), pShellCursor->GetPoint(), &tmp);
933 if (!pFrame || !pFrame->IsTextFrame())
934 {
935 return false;
936 }
937 SwTextFrame const& rTextFrame(static_cast<SwTextFrame const&>(*pFrame));
938 TextFrameIndex const ix(rTextFrame.MapModelToViewPos(*pShellCursor->GetPoint()));
939 if (&fnParaStart == &fnPosPara)
940 {
941 return ix == TextFrameIndex(0);
942 }
943 else
944 {
945 assert(&fnParaEnd == &fnPosPara);
946 return ix == TextFrameIndex(rTextFrame.GetText().getLength());
947 }
948}
949
950bool SwCursorShell::MovePara(SwWhichPara fnWhichPara, SwMoveFnCollection const & fnPosPara )
951{
952 SwCallLink aLk( *this ); // watch Cursor-Moves; call Link if needed
953 SwShellCursor* pTmpCursor = getShellCursor( true );
954 bool bRet = pTmpCursor->MovePara( fnWhichPara, fnPosPara );
955 if( bRet )
956 {
957 //keep going until we get something visible, i.e. skip
958 //over hidden paragraphs, don't get stuck at the start
959 //which is what SwCursorShell::UpdateCursorPos will reset
960 //the position to if we pass it a position in an
961 //invisible hidden paragraph field
962 while (isInHiddenTextFrame(pTmpCursor)
963 || !IsAtStartOrEndOfFrame(this, pTmpCursor, fnPosPara))
964 {
965 if (!pTmpCursor->MovePara(fnWhichPara, fnPosPara))
966 break;
967 }
968
969 UpdateCursor();
970 }
971 return bRet;
972}
973
975 SwMoveFnCollection const & fnPosSect)
976{
977 SwCallLink aLk( *this ); // watch Cursor-Moves; call Link if needed
978 SwCursor* pTmpCursor = getShellCursor( true );
979 bool bRet = pTmpCursor->MoveSection( fnWhichSect, fnPosSect );
980 if( bRet )
981 UpdateCursor();
982 return bRet;
983
984}
985
986// position cursor
987
988static SwFrame* lcl_IsInHeaderFooter( SwNode& rNd, Point& rPt )
989{
990 SwFrame* pFrame = nullptr;
991 SwContentNode* pCNd = rNd.GetContentNode();
992 if( pCNd )
993 {
994 std::pair<Point, bool> tmp(rPt, false);
995 SwContentFrame *pContentFrame = pCNd->getLayoutFrame(
997 nullptr, &tmp);
998 pFrame = pContentFrame ? pContentFrame->GetUpper() : nullptr;
999 while( pFrame && !pFrame->IsHeaderFrame() && !pFrame->IsFooterFrame() )
1000 pFrame = pFrame->IsFlyFrame() ? static_cast<SwFlyFrame*>(pFrame)->AnchorFrame()
1001 : pFrame->GetUpper();
1002 }
1003 return pFrame;
1004}
1005
1006bool SwCursorShell::IsInHeaderFooter( bool* pbInHeader ) const
1007{
1008 Point aPt;
1010 if( pFrame && pbInHeader )
1011 *pbInHeader = pFrame->IsHeaderFrame();
1012 return nullptr != pFrame;
1013}
1014
1015int SwCursorShell::SetCursor( const Point &rLPt, bool bOnlyText, bool bBlock )
1016{
1017 CurrShell aCurr( this );
1018
1019 SwShellCursor* pCursor = getShellCursor( bBlock );
1020 SwPosition aPos( *pCursor->GetPoint() );
1021 Point aPt( rLPt );
1022 Point & rCurrentCursorPt = pCursor->GetPtPos();
1026
1027 SwTextNode const*const pTextNd = sw::GetParaPropsNode(*GetLayout(), pCursor->GetPoint()->GetNode());
1028
1029 if ( pTextNd && !IsTableMode() &&
1030 // #i37515# No bInFrontOfLabel during selection
1031 !pCursor->HasMark() &&
1032 pTextNd->HasVisibleNumberingOrBullet() )
1033 {
1034 aTmpState.m_bInFrontOfLabel = true; // #i27615#
1035 }
1036 else
1037 {
1038 aTmpState.m_bInFrontOfLabel = false;
1039 }
1040
1041 int bRet = CRSR_POSOLD |
1042 ( GetLayout()->GetModelPositionForViewPoint( &aPos, aPt, &aTmpState )
1043 ? 0 : CRSR_POSCHG );
1044
1045 const bool bOldInFrontOfLabel = IsInFrontOfLabel();
1046 const bool bNewInFrontOfLabel = aTmpState.m_bInFrontOfLabel;
1047
1048 pCursor->SetCursorBidiLevel( aTmpState.m_nCursorBidiLevel );
1049
1050 if( CursorMoveState::RightMargin == aTmpState.m_eState )
1052 // is the new position in header or footer?
1053 SwFrame* pFrame = lcl_IsInHeaderFooter( aPos.GetNode(), aPt );
1054 if( IsTableMode() && !pFrame && aPos.GetNode().StartOfSectionNode() ==
1055 pCursor->GetPoint()->GetNode().StartOfSectionNode() )
1056 // same table column and not in header/footer -> back
1057 return bRet;
1058
1059 if( m_pBlockCursor && bBlock )
1060 {
1061 m_pBlockCursor->setEndPoint( rLPt );
1062 if( !pCursor->HasMark() )
1064 else if( !m_pBlockCursor->getStartPoint() )
1065 m_pBlockCursor->setStartPoint( pCursor->GetMkPos() );
1066 }
1067 if( !pCursor->HasMark() )
1068 {
1069 // is at the same position and if in header/footer -> in the same
1070 if( aPos == *pCursor->GetPoint() &&
1071 bOldInFrontOfLabel == bNewInFrontOfLabel )
1072 {
1073 if( pFrame )
1074 {
1075 if( pFrame->getFrameArea().Contains( rCurrentCursorPt ))
1076 return bRet;
1077 }
1078 else if( aPos.GetNode().IsContentNode() )
1079 {
1080 // in the same frame?
1081 std::pair<Point, bool> tmp(m_aCharRect.Pos(), false);
1082 SwFrame* pOld = static_cast<SwContentNode&>(aPos.GetNode()).getLayoutFrame(
1083 GetLayout(), nullptr, &tmp);
1084 tmp.first = aPt;
1085 SwFrame* pNew = static_cast<SwContentNode&>(aPos.GetNode()).getLayoutFrame(
1086 GetLayout(), nullptr, &tmp);
1087 if( pNew == pOld )
1088 return bRet;
1089 }
1090 }
1091 }
1092 else
1093 {
1094 // SSelection over not allowed sections or if in header/footer -> different
1095 if( !CheckNodesRange( aPos.GetNode(), pCursor->GetMark()->GetNode(), true )
1096 || ( pFrame && !pFrame->getFrameArea().Contains( pCursor->GetMkPos() ) ))
1097 return bRet;
1098
1099 // is at same position but not in header/footer
1100 if( aPos == *pCursor->GetPoint() )
1101 return bRet;
1102 }
1103
1104 SwCallLink aLk( *this ); // watch Cursor-Moves; call Link if needed
1105 SwCursorSaveState aSaveState( *pCursor );
1106
1107 *pCursor->GetPoint() = aPos;
1108 rCurrentCursorPt = aPt;
1109
1110 // #i41424# Only update the marked number levels if necessary
1111 // Force update of marked number levels if necessary.
1112 if ( bNewInFrontOfLabel || bOldInFrontOfLabel )
1113 m_pCurrentCursor->SetInFrontOfLabel_( !bNewInFrontOfLabel );
1114 SetInFrontOfLabel( bNewInFrontOfLabel );
1115
1116 if( !pCursor->IsSelOvr( SwCursorSelOverFlags::ChangePos ) )
1117 {
1119 bRet &= ~CRSR_POSOLD;
1120 }
1121 else if( bOnlyText && !m_pCurrentCursor->HasMark() )
1122 {
1123 if( FindValidContentNode( bOnlyText ) )
1124 {
1125 // position cursor in a valid content
1126 if( aPos == *pCursor->GetPoint() )
1127 bRet = CRSR_POSOLD;
1128 else
1129 {
1130 UpdateCursor();
1131 bRet &= ~CRSR_POSOLD;
1132 }
1133 }
1134 else
1135 {
1136 // there is no valid content -> hide cursor
1137 m_pVisibleCursor->Hide(); // always hide visible cursor
1138 m_eMvState = CursorMoveState::NONE; // status for Cursor travelling
1139 m_bAllProtect = true;
1140 if( GetDoc()->GetDocShell() )
1141 {
1143 CallChgLnk(); // notify UI
1144 }
1145 }
1146 }
1147 return bRet;
1148}
1149
1151{
1152 assert(m_pTableCursor);
1153 delete m_pTableCursor;
1154 m_pTableCursor = nullptr;
1155}
1156
1158{
1159 assert(m_pBlockCursor);
1160 if( m_pBlockCursor && !HasSelection() )
1161 {
1164 *m_pCurrentCursor->GetPoint() = *rPam.GetPoint();
1165 if( rPam.HasMark() )
1166 *m_pCurrentCursor->GetMark() = *rPam.GetMark();
1167 else
1169 }
1170 delete m_pBlockCursor;
1171 m_pBlockCursor = nullptr;
1172}
1173
1175{
1176 if( !m_pBlockCursor )
1177 {
1179 m_pBlockCursor = new SwBlockCursor( *this, aPos );
1181 rBlock.GetPtPos() = m_pCurrentCursor->GetPtPos();
1182 if( m_pCurrentCursor->HasMark() )
1183 {
1184 rBlock.SetMark();
1185 *rBlock.GetMark() = *m_pCurrentCursor->GetMark();
1186 rBlock.GetMkPos() = m_pCurrentCursor->GetMkPos();
1187 }
1188 }
1191}
1192
1194{
1195 // is there any GetMark?
1196 if( m_pTableCursor )
1197 {
1198 std::vector<SwPaM*> vCursors;
1199 for(auto& rCursor : m_pCurrentCursor->GetRingContainer())
1200 if(&rCursor != m_pCurrentCursor)
1201 vCursors.push_back(&rCursor);
1202 for(auto pCursor : vCursors)
1203 delete pCursor;
1205
1207
1210 delete m_pTableCursor;
1211 m_pTableCursor = nullptr;
1212 m_pCurrentCursor->SwSelPaintRects::Show();
1213 }
1214 else
1215 {
1216 if( !m_pCurrentCursor->HasMark() )
1217 return;
1219 if( !m_nCursorMove )
1220 m_pCurrentCursor->SwSelPaintRects::Show();
1221 }
1222}
1223
1224void SwCursorShell::NormalizePam(bool bPointFirst)
1225{
1226 SwCallLink aLk( *this ); // watch Cursor-Moves; call Link if needed
1227 m_pCurrentCursor->Normalize(bPointFirst);
1228}
1229
1231{
1232 SwCallLink aLk( *this ); // watch Cursor-Moves; call Link if needed
1234}
1235
1236//TODO: provide documentation
1246 const Point & rPt,
1247 bool bTstHit )
1248{
1249 CurrShell aCurr( this );
1250
1251 // check if the SPoint is in a table selection
1252 if( m_pTableCursor )
1253 return m_pTableCursor->Contains( rPt );
1254
1255 SwCallLink aLk( *this ); // watch Cursor-Moves; call Link if needed
1256 // search position <rPt> in document
1257 SwPosition aPtPos( *m_pCurrentCursor->GetPoint() );
1258 Point aPt( rPt );
1259
1262 if ( !GetLayout()->GetModelPositionForViewPoint( &aPtPos, aPt, &aTmpState ) && bTstHit )
1263 return false;
1264
1265 // search in all selections for this position
1266 SwShellCursor* pCmp = m_pCurrentCursor; // keep the pointer on cursor
1267 do
1268 {
1269 if (pCmp->HasMark() && *pCmp->Start() <= aPtPos && *pCmp->End() > aPtPos)
1270 return true; // return without update
1271 pCmp = pCmp->GetNext();
1272 } while (m_pCurrentCursor != pCmp);
1273 return false;
1274}
1275
1277{
1278 // Does any exist for deletion?
1280 return;
1281
1283 delete m_pCurrentCursor->GetNext();
1285
1286 if( m_pTableCursor )
1287 {
1288 // delete the ring of cursors
1292 delete m_pTableCursor;
1293 m_pTableCursor = nullptr;
1294 }
1295 else if( m_pBlockCursor )
1296 {
1297 // delete the ring of cursors
1300 *m_pCurrentCursor->GetPoint() = *rBlock.GetPoint();
1301 m_pCurrentCursor->GetPtPos() = rBlock.GetPtPos();
1302 rBlock.DeleteMark();
1304 }
1306}
1307
1309{
1310 int nRet = 0;
1311 const SwPosition *pFirst = nullptr, *pSecond = nullptr;
1312 const SwCursor *pCur = GetCursor(), *pStack = m_pStackCursor;
1313 // cursor on stack is needed if we compare against stack
1314 if( pStack )
1315 {
1316 pFirst = pStack->GetMark();
1317 pSecond = pCur->GetPoint();
1318 }
1319 if( !pFirst || !pSecond )
1320 nRet = INT_MAX;
1321 else if( *pFirst < *pSecond )
1322 nRet = -1;
1323 else if( *pFirst == *pSecond )
1324 nRet = 0;
1325 else
1326 nRet = 1;
1327 return nRet;
1328}
1329
1331{
1333 {
1334 return false;
1335 }
1337 {
1338 return true;
1339 }
1340 if (GetLayout()->HasMergedParas())
1341 {
1342 SwContentFrame const*const pFrame(GetCurrFrame(false));
1343 auto const n(m_pCurrentCursor->GetMark()->GetNodeIndex());
1344 return FrameContainsNode(*pFrame, n);
1345 }
1346 return false;
1347}
1348
1350{
1351 if (GetLayout()->HasMergedParas())
1352 {
1353 SwTextNode const*const pNode(m_pCurrentCursor->GetPoint()->GetNode().GetTextNode());
1354 if (pNode)
1355 {
1356 SwTextFrame const*const pFrame(static_cast<SwTextFrame*>(
1357 pNode->getLayoutFrame(GetLayout())));
1358 if (pFrame)
1359 {
1360 return pFrame->MapModelToViewPos(*m_pCurrentCursor->GetPoint())
1361 == TextFrameIndex(0);
1362 }
1363 }
1364 }
1365 return m_pCurrentCursor->GetPoint()->GetContentIndex() == 0;
1366}
1367
1369{
1370 if (GetLayout()->HasMergedParas())
1371 {
1372 SwTextNode const*const pNode(m_pCurrentCursor->GetPoint()->GetNode().GetTextNode());
1373 if (pNode)
1374 {
1375 SwTextFrame const*const pFrame(static_cast<SwTextFrame*>(
1376 pNode->getLayoutFrame(GetLayout())));
1377 if (pFrame)
1378 {
1379 return pFrame->MapModelToViewPos(*m_pCurrentCursor->GetPoint())
1380 == TextFrameIndex(pFrame->GetText().getLength());
1381 }
1382 }
1383 }
1385}
1386
1388{
1389 if (IsTableMode() || IsBlockMode() || !IsEndPara())
1390 {
1391 return false;
1392 }
1393 SwTableNode const*const pTableNode( IsCursorInTable() );
1394 if (!pTableNode)
1395 {
1396 return false;
1397 }
1398 SwEndNode const*const pEndTableNode(pTableNode->EndOfSectionNode());
1399 SwNodeIndex const lastNode(*pEndTableNode, -2);
1400 SAL_WARN_IF(!lastNode.GetNode().GetTextNode(), "sw.core",
1401 "text node expected");
1402 return (lastNode == m_pCurrentCursor->GetPoint()->GetNode());
1403}
1404
1406{
1408 return aStartNodeType == SwStartNodeType::SwFootnoteStartNode;
1409}
1410
1412{
1413 Point aRet(-1, -1);
1414 if (SwFrame *pFrame = GetCurrFrame())
1415 {
1416 if (SwPageFrame* pCurrentPage = pFrame->FindPageFrame())
1417 {
1418 const Point& rDocPos = GetCursorDocPos();
1419 aRet = rDocPos - pCurrentPage->getFrameArea().TopLeft();
1420 }
1421 }
1422 return aRet;
1423}
1424
1426{
1428}
1429
1431{
1432 if ( bNew != IsInFrontOfLabel() )
1433 {
1436 return true;
1437 }
1438 return false;
1439}
1440
1441namespace {
1442
1443void collectUIInformation(const OUString& aPage)
1444{
1445 EventDescription aDescription;
1446 aDescription.aAction = "GOTO";
1447 aDescription.aParameters = {{"PAGE", aPage}};
1448 aDescription.aID = "writer_edit";
1449 aDescription.aKeyWord = "SwEditWinUIObject";
1450 aDescription.aParent = "MainWindow";
1451 UITestLogger::getInstance().logEvent(aDescription);
1452}
1453
1454}
1455
1456bool SwCursorShell::GotoPage( sal_uInt16 nPage )
1457{
1458 CurrShell aCurr( this );
1459 SwCallLink aLk( *this ); // watch Cursor-Moves; call Link if needed
1460 SwCursorSaveState aSaveState( *m_pCurrentCursor );
1461 bool bRet = GetLayout()->SetCurrPage( m_pCurrentCursor, nPage ) &&
1464 if( bRet )
1466
1467 collectUIInformation(OUString::number(nPage));
1468 return bRet;
1469}
1470
1472{
1473 SwContentFrame* pFrame = GetCurrFrame();
1474 pFrame->GetCharRect( rRect, *pPos );
1475}
1476
1477void SwCursorShell::GetPageNum( sal_uInt16 &rnPhyNum, sal_uInt16 &rnVirtNum,
1478 bool bAtCursorPos, const bool bCalcFrame )
1479{
1480 CurrShell aCurr( this );
1481 // page number: first visible page or the one at the cursor
1482 const SwContentFrame* pCFrame;
1483 const SwPageFrame *pPg = nullptr;
1484
1485 if( !bAtCursorPos || nullptr == (pCFrame = GetCurrFrame( bCalcFrame )) ||
1486 nullptr == (pPg = pCFrame->FindPageFrame()) )
1487 {
1488 pPg = Imp()->GetFirstVisPage(GetOut());
1489 while( pPg && pPg->IsEmptyPage() )
1490 pPg = static_cast<const SwPageFrame *>(pPg->GetNext());
1491 }
1492 // pPg has to exist with a default of 1 for the special case "Writerstart"
1493 rnPhyNum = pPg? pPg->GetPhyPageNum() : 1;
1494 rnVirtNum = pPg? pPg->GetVirtPageNum() : 1;
1495}
1496
1498{
1499 CurrShell aCurr(this);
1500 // page number: first visible page or the one at the cursor
1501 const SwContentFrame* pCFrame = GetCurrFrame(/*bCalcFrame*/true);
1502 const SwPageFrame* pPg = nullptr;
1503
1504 if (pCFrame == nullptr || nullptr == (pPg = pCFrame->FindPageFrame()))
1505 {
1506 pPg = Imp()->GetFirstVisPage(GetOut());
1507 while (pPg && pPg->IsEmptyPage())
1508 pPg = static_cast<const SwPageFrame*>(pPg->GetNext());
1509 }
1510
1511 sal_uInt16 nPageNo = 0;
1512 while (pPg)
1513 {
1514 if (!pPg->IsEmptyPage())
1515 ++nPageNo;
1516 pPg = static_cast<const SwPageFrame*>(pPg->GetPrev());
1517 }
1518 return nPageNo;
1519}
1520
1522{
1523 CurrShell aCurr( this );
1524 // page number: first visible page or the one at the cursor
1525 const SwPageFrame *pPg = Imp()->GetFirstVisPage(GetOut());
1526 if( pPg )
1527 {
1528 const SwTwips nPageTop = pPg->getFrameArea().Top();
1529
1530 if( bNext )
1531 {
1532 // go to next view layout row:
1533 do
1534 {
1535 pPg = static_cast<const SwPageFrame *>(pPg->GetNext());
1536 }
1537 while( pPg && pPg->getFrameArea().Top() == nPageTop );
1538
1539 while( pPg && pPg->IsEmptyPage() )
1540 pPg = static_cast<const SwPageFrame *>(pPg->GetNext());
1541 }
1542 else
1543 {
1544 // go to previous view layout row:
1545 do
1546 {
1547 pPg = static_cast<const SwPageFrame *>(pPg->GetPrev());
1548 }
1549 while( pPg && pPg->getFrameArea().Top() == nPageTop );
1550
1551 while( pPg && pPg->IsEmptyPage() )
1552 pPg = static_cast<const SwPageFrame *>(pPg->GetPrev());
1553 }
1554 }
1555 // pPg has to exist with a default of 1 for the special case "Writerstart"
1556 return pPg ? pPg->GetPhyPageNum() : USHRT_MAX;
1557}
1558
1560{
1561 CurrShell aCurr( this );
1562 // return number of pages
1563 return GetLayout()->GetPageNum();
1564}
1565
1567{
1568 CurrShell aCurr(this);
1569 SwRootFrame* pLayout = GetLayout();
1570 OUStringBuffer aBuf;
1571 for (const SwFrame* pFrame = pLayout->GetLower(); pFrame; pFrame = pFrame->GetNext())
1572 {
1573 aBuf.append(OUString::number(pFrame->getFrameArea().Left())
1574 + ", "
1575 + OUString::number(pFrame->getFrameArea().Top())
1576 + ", "
1577 + OUString::number(pFrame->getFrameArea().Width())
1578 + ", "
1579 + OUString::number(pFrame->getFrameArea().Height())
1580 + "; ");
1581 }
1582 if (!aBuf.isEmpty())
1583 aBuf.setLength( aBuf.getLength() - 2); // remove the last "; "
1584 return aBuf.makeStringAndClear();
1585}
1586
1588{
1589 auto pView = const_cast<SdrView*>(GetDrawView());
1590 if (pView->GetTextEditObject())
1591 {
1592 // Blinking cursor.
1593 EditView& rEditView = pView->GetTextEditOutlinerView()->GetEditView();
1594 rEditView.RegisterOtherShell(pOtherShell);
1595 rEditView.ShowCursor();
1596 rEditView.RegisterOtherShell(nullptr);
1597 // Text selection, if any.
1598 rEditView.DrawSelectionXOR(pOtherShell);
1599
1600 // Shape text lock.
1601 if (OutlinerView* pOutlinerView = pView->GetTextEditOutlinerView())
1602 {
1603 OString sRect = pOutlinerView->GetOutputArea().toString();
1604 SfxLokHelper::notifyOtherView(GetSfxViewShell(), pOtherShell, LOK_CALLBACK_VIEW_LOCK, "rectangle", sRect);
1605 }
1606 }
1607 else
1608 {
1609 // Cursor position.
1610 m_pVisibleCursor->SetPosAndShow(pOtherShell);
1611 // Cursor visibility.
1612 if (GetSfxViewShell() != pOtherShell)
1613 {
1614 OString aPayload = OString::boolean(m_bSVCursorVis);
1615 SfxLokHelper::notifyOtherView(GetSfxViewShell(), pOtherShell, LOK_CALLBACK_VIEW_CURSOR_VISIBLE, "visible", aPayload);
1616 }
1617 // Text selection.
1618 m_pCurrentCursor->Show(pOtherShell);
1619 // Graphic selection.
1620 pView->AdjustMarkHdl(pOtherShell);
1621 }
1622}
1623
1626{
1628 return false;
1629
1630 CurrShell aCurr( this );
1631 SwCallLink aLk( *this ); // watch Cursor-Moves; call Link if needed
1633
1634 // #i24086#: show also all others
1635 if( !ActionPend() )
1636 {
1637 UpdateCursor();
1638 m_pCurrentCursor->Show(nullptr);
1639 }
1640 return true;
1641}
1642
1645{
1647 return false;
1648
1649 CurrShell aCurr( this );
1650 SwCallLink aLk( *this ); // watch Cursor-Moves; call Link if needed
1652
1653 // #i24086#: show also all others
1654 if( !ActionPend() )
1655 {
1656 UpdateCursor();
1657 m_pCurrentCursor->Show(nullptr);
1658 }
1659 return true;
1660}
1661
1663{
1664 SvxSearchDialogWrapper::SetSearchLabel( SearchLabel::Empty );
1665
1667 {
1668 if( !m_pCurrentCursor->HasMark() )
1669 SvxSearchDialogWrapper::SetSearchLabel( SearchLabel::NavElementNotFound );
1670 return;
1671 }
1672
1673 if (bNext)
1674 GoNextCursor();
1675 else
1676 GoPrevCursor();
1677}
1678
1680{
1682 CurrShell aCurr( this );
1683
1684 // always switch off all cursors when painting
1685 SwRect aRect( rRect );
1686
1687 bool bVis = false;
1688 // if a cursor is visible then hide the SV cursor
1689 if( m_pVisibleCursor->IsVisible() && !aRect.Overlaps( m_aCharRect ) )
1690 {
1691 bVis = true;
1693 }
1694
1695 // re-paint area
1696 SwViewShell::Paint(rRenderContext, rRect);
1697
1699 {
1701
1702 if( !ActionPend() )
1703 {
1704 // so that right/bottom borders will not be cropped
1705 pCurrentCursor->Invalidate( VisArea() );
1706 pCurrentCursor->Show(nullptr);
1707 }
1708 else
1709 pCurrentCursor->Invalidate( aRect );
1710
1711 }
1712
1713 if (SwPostItMgr* pPostItMgr = GetPostItMgr())
1714 {
1715 // No point in showing the cursor for Writer text when there is an
1716 // active annotation edit.
1717 if (bVis)
1718 bVis = !pPostItMgr->HasActiveSidebarWin();
1719 }
1720
1721 if( m_bSVCursorVis && bVis ) // also show SV cursor again
1723}
1724
1726{
1727 CurrShell aCurr( this );
1728 bool bVis; // switch off all cursors when scrolling
1729
1730 // if a cursor is visible then hide the SV cursor
1731 bVis = m_pVisibleCursor->IsVisible();
1732 if( bVis )
1734
1735 m_bVisPortChgd = true;
1736 m_aOldRBPos.setX(VisArea().Right());
1737 m_aOldRBPos.setY(VisArea().Bottom());
1738
1739 // For not having problems with the SV cursor, Update() is called for the
1740 // Window in SwViewShell::VisPo...
1741 // During painting no selections should be shown, thus the call is encapsulated. <- TODO: old artefact?
1742 SwViewShell::VisPortChgd( rRect ); // move area
1743
1744 if( m_bSVCursorVis && bVis ) // show SV cursor again
1746
1747 if( m_nCursorMove )
1748 m_bInCMvVisportChgd = true;
1749
1750 m_bVisPortChgd = false;
1751}
1752
1760{
1761 CurrShell aCurr( this );
1762 ++mnStartAction;
1763 SwShellCursor* pShellCursor = getShellCursor( true );
1764 Size aOldSz( GetDocSize() );
1765
1766 if (isInHiddenTextFrame(pShellCursor) && !ExtendedSelectedAll())
1767 {
1770 GetLayout()->GetModelPositionForViewPoint( pShellCursor->GetPoint(), pShellCursor->GetPtPos(),
1771 &aTmpState );
1772 pShellCursor->DeleteMark();
1773 }
1774 auto* pDoc = GetDoc();
1775 if (pDoc)
1776 {
1777 pDoc->getGrammarContact()->updateCursorPosition(*m_pCurrentCursor->GetPoint());
1778 pDoc->getOnlineAccessibilityCheck()->update(*m_pCurrentCursor->GetPoint());
1779 }
1780
1781 --mnStartAction;
1782 if( aOldSz != GetDocSize() )
1783 SizeChgNotify();
1784}
1785
1786// #i65475# - if Point/Mark in hidden sections, move them out
1788{
1789 bool bOk = true;
1790 const SwSectionNode* pSectNd = rPos.GetNode().FindSectionNode();
1791 if( pSectNd && pSectNd->GetSection().IsHiddenFlag() )
1792 {
1793 const SwNode* pFrameNd =
1794 rPos.GetNodes().FindPrvNxtFrameNode( *pSectNd, pSectNd->EndOfSectionNode() );
1795 bOk = pFrameNd != nullptr;
1796 SAL_WARN_IF(!bOk, "sw.core", "found no Node with Frames");
1797 rPos.Assign( *(bOk ? pFrameNd : pSectNd) );
1798 }
1799 return bOk;
1800}
1801
1804{
1805 SwNodeIndex aTmp( rPos.GetNode() );
1806 SwTextNode* pTextNd = aTmp.GetNode().GetTextNode();
1807 while( pTextNd && pTextNd->HasHiddenCharAttribute( true ) )
1808 {
1809 SwContentNode* pContent = aTmp.GetNodes().GoNext( &aTmp );
1810 if ( pContent && pContent->IsTextNode() )
1811 pTextNd = pContent->GetTextNode();
1812 else
1813 pTextNd = nullptr;
1814 }
1815
1816 if ( pTextNd )
1817 rPos.Assign( *pTextNd, 0 );
1818}
1819
1820#if !ENABLE_WASM_STRIP_ACCESSIBILITY
1821namespace {
1822
1823// #i27301# - helper class that notifies the accessibility about invalid text
1824// selections in its destructor
1825class SwNotifyAccAboutInvalidTextSelections
1826{
1827 private:
1828 SwCursorShell& mrCursorSh;
1829
1830 public:
1831 explicit SwNotifyAccAboutInvalidTextSelections( SwCursorShell& _rCursorSh )
1832 : mrCursorSh( _rCursorSh )
1833 {}
1834
1835 ~SwNotifyAccAboutInvalidTextSelections() COVERITY_NOEXCEPT_FALSE
1836 {
1838 }
1839};
1840
1841}
1842#endif
1843
1844void SwCursorShell::UpdateCursor( sal_uInt16 eFlags, bool bIdleEnd )
1845{
1846 CurrShell aCurr( this );
1848
1849 if (ActionPend())
1850 {
1851 if ( eFlags & SwCursorShell::READONLY )
1852 m_bIgnoreReadonly = true;
1853 return; // if not then no update
1854 }
1855
1856#if !ENABLE_WASM_STRIP_ACCESSIBILITY
1857 SwNotifyAccAboutInvalidTextSelections aInvalidateTextSelections( *this );
1858#endif
1859
1860 if ( m_bIgnoreReadonly )
1861 {
1862 m_bIgnoreReadonly = false;
1863 eFlags |= SwCursorShell::READONLY;
1864 }
1865
1866 if( eFlags & SwCursorShell::CHKRANGE ) // check all cursor moves for
1867 CheckRange( m_pCurrentCursor ); // overlapping ranges
1868
1869 if( !bIdleEnd )
1871
1872 // If the current cursor is in a table and point/mark in different boxes,
1873 // then the table mode is active (also if it is already active: m_pTableCursor)
1874 SwPaM* pTstCursor = getShellCursor( true );
1875 if( pTstCursor->HasMark() && !m_pBlockCursor &&
1876 SwDoc::IsInTable( pTstCursor->GetPoint()->GetNode() ) &&
1877 ( m_pTableCursor ||
1878 pTstCursor->GetPointNode().StartOfSectionNode() !=
1879 pTstCursor->GetMarkNode().StartOfSectionNode() ) && !mbSelectAll)
1880 {
1881 SwShellCursor* pITmpCursor = getShellCursor( true );
1882 Point aTmpPt( pITmpCursor->GetPtPos() );
1883 Point aTmpMk( pITmpCursor->GetMkPos() );
1884 SwPosition* pPos = pITmpCursor->GetPoint();
1885
1886 // Bug 65475 (1999) - if Point/Mark in hidden sections, move them out
1887 lcl_CheckHiddenSection( *pPos );
1888 lcl_CheckHiddenSection( *pITmpCursor->GetMark() );
1889
1890 // Move cursor out of hidden paragraphs
1891 if ( !GetViewOptions()->IsShowHiddenChar() )
1892 {
1893 lcl_CheckHiddenPara( *pPos );
1894 lcl_CheckHiddenPara( *pITmpCursor->GetMark() );
1895 }
1896
1897 std::pair<Point, bool> const tmp(aTmpPt, false);
1898 SwContentFrame *pTableFrame = pPos->GetNode().GetContentNode()->
1899 getLayoutFrame( GetLayout(), pPos, &tmp);
1900
1901 OSL_ENSURE( pTableFrame, "Table Cursor not in Content ??" );
1902
1903 // --> Make code robust. The table cursor may point
1904 // to a table in a currently inactive header.
1905 SwTabFrame *pTab = pTableFrame ? pTableFrame->FindTabFrame() : nullptr;
1906
1907 if ( pTab && pTab->GetTable()->GetRowsToRepeat() > 0 )
1908 {
1909 // First check if point is in repeated headline:
1910 bool bInRepeatedHeadline = pTab->IsFollow() && pTab->IsInHeadline( *pTableFrame );
1911
1912 // Second check if mark is in repeated headline:
1913 if ( !bInRepeatedHeadline )
1914 {
1915 std::pair<Point, bool> const tmp1(aTmpMk, false);
1916 SwContentFrame* pMarkTableFrame = pITmpCursor->GetMarkContentNode()->
1917 getLayoutFrame(GetLayout(), pITmpCursor->GetMark(), &tmp1);
1918 OSL_ENSURE( pMarkTableFrame, "Table Cursor not in Content ??" );
1919
1920 if ( pMarkTableFrame )
1921 {
1922 SwTabFrame* pMarkTab = pMarkTableFrame->FindTabFrame();
1923 OSL_ENSURE( pMarkTab, "Table Cursor not in Content ??" );
1924
1925 // Make code robust:
1926 if ( pMarkTab )
1927 {
1928 bInRepeatedHeadline = pMarkTab->IsFollow() && pMarkTab->IsInHeadline( *pMarkTableFrame );
1929 }
1930 }
1931 }
1932
1933 // No table cursor in repeated headlines:
1934 if ( bInRepeatedHeadline )
1935 {
1936 pTableFrame = nullptr;
1937
1938 SwMoveFnCollection const & fnPosSect = *pPos < *pITmpCursor->GetMark()
1940 : fnSectionEnd;
1941
1942 // then only select inside the Box
1943 if( m_pTableCursor )
1944 {
1949 m_pTableCursor->SwSelPaintRects::Hide();
1950 }
1951
1953 GoCurrSection( *m_pCurrentCursor, fnPosSect );
1954 }
1955 }
1956
1957 // we really want a table selection
1958 if( pTab && pTableFrame )
1959 {
1960 if( !m_pTableCursor )
1961 {
1964 *pPos, aTmpPt );
1966 m_pCurrentCursor->SwSelPaintRects::Hide();
1967
1969 if(!m_pTableCursor)
1970 {
1971 SAL_WARN("sw.core", "fdo#74854: "
1972 "this should not happen, but better lose the selection "
1973 "rather than crashing");
1974 return;
1975 }
1976 }
1977
1979 aTmpState.m_bRealHeight = true;
1980 {
1982 if (!pTableFrame->GetCharRect( m_aCharRect, *m_pTableCursor->GetPoint(), &aTmpState))
1983 {
1984 Point aCentrPt( m_aCharRect.Center() );
1986 pTableFrame->GetModelPositionForViewPoint(m_pTableCursor->GetPoint(), aCentrPt, &aTmpState);
1987 bool const bResult =
1989 OSL_ENSURE( bResult, "GetCharRect failed." );
1990 }
1991 }
1992
1993 m_pVisibleCursor->Hide(); // always hide visible Cursor
1994 // scroll Cursor to visible area
1995 if( eFlags & SwCursorShell::SCROLLWIN &&
1996 (HasSelection() || eFlags & SwCursorShell::READONLY ||
1997 !IsCursorReadonly()) )
1998 {
1999 SwFrame* pBoxFrame = pTableFrame;
2000 while( pBoxFrame && !pBoxFrame->IsCellFrame() )
2001 pBoxFrame = pBoxFrame->GetUpper();
2002 if( pBoxFrame && pBoxFrame->getFrameArea().HasArea() )
2003 MakeVisible( pBoxFrame->getFrameArea() );
2004 else
2006 }
2007
2008 // let Layout create the Cursors in the Boxes
2012 m_pTableCursor->Show(nullptr);
2013
2014 // set Cursor-Points to the new Positions
2017
2018 if( m_bSVCursorVis )
2019 {
2020 m_aCursorHeight.setX(0);
2021 m_aCursorHeight.setY(aTmpState.m_aRealHeight.getY() < 0 ?
2023 m_pVisibleCursor->Show(); // show again
2024 }
2025 m_eMvState = CursorMoveState::NONE; // state for cursor travelling - GetModelPositionForViewPoint
2026#if !ENABLE_WASM_STRIP_ACCESSIBILITY
2027 if (Imp()->IsAccessible() && m_bSendAccessibleCursorEvents)
2028 Imp()->InvalidateAccessibleCursorPosition( pTableFrame );
2029#endif
2030 return;
2031 }
2032 }
2033
2034 if( m_pTableCursor )
2035 {
2036 // delete Ring
2038 delete m_pCurrentCursor->GetNext();
2042 delete m_pTableCursor;
2043 m_pTableCursor = nullptr;
2044 }
2045
2046 m_pVisibleCursor->Hide(); // always hide visible Cursor
2047
2048 // are we perhaps in a protected / hidden Section ?
2049 {
2050 SwShellCursor* pShellCursor = getShellCursor( true );
2051 bool bChgState = true;
2052 const SwSectionNode* pSectNd = pShellCursor->GetPointNode().FindSectionNode();
2053 if( pSectNd && ( pSectNd->GetSection().IsHiddenFlag() ||
2054 ( !IsReadOnlyAvailable() &&
2055 pSectNd->GetSection().IsProtectFlag() &&
2056 ( !mxDoc->GetDocShell() ||
2057 !mxDoc->GetDocShell()->IsReadOnly() || m_bAllProtect )) ) )
2058 {
2060 0 == Imp()->GetDrawView()->GetMarkedObjectList().GetMarkCount()))
2061 {
2062 // everything protected/hidden -> special mode
2064 pSectNd->GetSection().IsProtectFlag() )
2065 bChgState = false;
2066 else
2067 {
2068 m_eMvState = CursorMoveState::NONE; // state for cursor travelling
2069 m_bAllProtect = true;
2070 if( GetDoc()->GetDocShell() )
2071 {
2073 CallChgLnk(); // notify UI!
2074 }
2075 return;
2076 }
2077 }
2078 }
2079 if( bChgState )
2080 {
2081 bool bWasAllProtect = m_bAllProtect;
2082 m_bAllProtect = false;
2083 if( bWasAllProtect && GetDoc()->GetDocShell() &&
2084 GetDoc()->GetDocShell()->IsReadOnlyUI() )
2085 {
2086 GetDoc()->GetDocShell()->SetReadOnlyUI( false );
2087 CallChgLnk(); // notify UI!
2088 }
2089 }
2090 }
2091
2093
2094 // The cursor must always point into content; there's some code
2095 // that relies on this. (E.g. in SwEditShell::GetScriptType, which always
2096 // loops _behind_ the last node in the selection, which always works if you
2097 // are in content.) To achieve this, we'll force cursor(s) to point into
2098 // content, if UpdateCursorPos() hasn't already done so.
2100 {
2101 // start will move forwards, end will move backwards
2102 bool bPointIsStart = ( rCmp.Start() == rCmp.GetPoint() );
2103
2104 // move point; forward if it's the start, backwards if it's the end
2105 if( ! rCmp.GetPoint()->GetNode().IsContentNode() )
2106 rCmp.Move( bPointIsStart ? fnMoveForward : fnMoveBackward,
2107 GoInContent );
2108
2109 // move mark (if exists); forward if it's the start, else backwards
2110 if( rCmp.HasMark() )
2111 {
2112 if( ! rCmp.GetMark()->GetNode().IsContentNode() )
2113 {
2114 rCmp.Exchange();
2115 rCmp.Move( !bPointIsStart ? fnMoveForward : fnMoveBackward,
2116 GoInContent );
2117 rCmp.Exchange();
2118 }
2119 }
2120 }
2121
2122 SwRect aOld( m_aCharRect );
2123 bool bFirst = true;
2124 SwContentFrame *pFrame;
2125 int nLoopCnt = 100;
2126 SwShellCursor* pShellCursor = getShellCursor( true );
2127
2128 do {
2129 bool bAgainst;
2130 do {
2131 bAgainst = false;
2132 std::pair<Point, bool> const tmp1(pShellCursor->GetPtPos(), false);
2133 pFrame = pShellCursor->GetPointContentNode()->getLayoutFrame(GetLayout(),
2134 pShellCursor->GetPoint(), &tmp1);
2135 // if the Frame doesn't exist anymore, the complete Layout has to be
2136 // created, because there used to be a Frame here!
2137 if ( !pFrame )
2138 {
2139 do
2140 {
2141 CalcLayout();
2142 std::pair<Point, bool> const tmp(pShellCursor->GetPtPos(), false);
2143 pFrame = pShellCursor->GetPointContentNode()->getLayoutFrame(
2144 GetLayout(), pShellCursor->GetPoint(), &tmp);
2145 } while( !pFrame );
2146 }
2147 else if ( Imp()->IsIdleAction() )
2148 // Guarantee everything's properly formatted
2149 pFrame->PrepareCursor();
2150
2151 // In protected Fly? but ignore in case of frame selection
2152 if( !IsReadOnlyAvailable() && pFrame->IsProtected() &&
2153 ( !Imp()->GetDrawView() ||
2154 !Imp()->GetDrawView()->GetMarkedObjectList().GetMarkCount() ) &&
2155 (!mxDoc->GetDocShell() ||
2156 !mxDoc->GetDocShell()->IsReadOnly() || m_bAllProtect ) )
2157 {
2158 // look for a valid position
2159 bool bChgState = true;
2161 0 == Imp()->GetDrawView()->GetMarkedObjectList().GetMarkCount()))
2162 {
2163 // everything is protected / hidden -> special Mode
2164 if( m_bAllProtect )
2165 bChgState = false;
2166 else
2167 {
2168 m_eMvState = CursorMoveState::NONE; // state for cursor travelling
2169 m_bAllProtect = true;
2170 if( GetDoc()->GetDocShell() )
2171 {
2173 CallChgLnk(); // notify UI!
2174 }
2175 return;
2176 }
2177 }
2178
2179 if( bChgState )
2180 {
2181 bool bWasAllProtect = m_bAllProtect;
2182 m_bAllProtect = false;
2183 if( bWasAllProtect && GetDoc()->GetDocShell() &&
2184 GetDoc()->GetDocShell()->IsReadOnlyUI() )
2185 {
2186 GetDoc()->GetDocShell()->SetReadOnlyUI( false );
2187 CallChgLnk(); // notify UI!
2188 }
2189 m_bAllProtect = false;
2190 bAgainst = true; // look for the right Frame again
2191 }
2192 }
2193 } while( bAgainst );
2194
2195 SwCursorMoveState aTmpState( m_eMvState );
2197 aTmpState.m_bRealHeight = true;
2198 aTmpState.m_bRealWidth = IsOverwriteCursor();
2199 aTmpState.m_nCursorBidiLevel = pShellCursor->GetCursorBidiLevel();
2200
2201 // #i27615#,#i30453#
2202 SwSpecialPos aSpecialPos;
2204 if (pShellCursor->IsInFrontOfLabel())
2205 {
2206 aTmpState.m_pSpecialPos = &aSpecialPos;
2207 }
2208
2209 {
2210 DisableCallbackAction a(*GetLayout()); // tdf#91602 prevent recursive Action
2211 if (!pFrame->GetCharRect(m_aCharRect, *pShellCursor->GetPoint(), &aTmpState))
2212 {
2213 Point& rPt = pShellCursor->GetPtPos();
2214 rPt = m_aCharRect.Center();
2215 pFrame->GetModelPositionForViewPoint( pShellCursor->GetPoint(), rPt, &aTmpState );
2216 }
2217 }
2218 UISizeNotify(); // tdf#96256 update view size
2219
2220 if( !pShellCursor->HasMark() )
2221 m_aCursorHeight = aTmpState.m_aRealHeight;
2222 else
2223 {
2224 m_aCursorHeight.setX(0);
2225 m_aCursorHeight.setY(aTmpState.m_aRealHeight.getY() < 0 ?
2227 }
2228
2229 if( !bFirst && aOld == m_aCharRect )
2230 break;
2231
2232 // if the layout says that we are after the 100th iteration still in
2233 // flow then we should always take the current position for granted.
2234 // (see bug: 29658)
2235 if( !--nLoopCnt )
2236 {
2237 OSL_ENSURE( false, "endless loop? CharRect != OldCharRect ");
2238 break;
2239 }
2240 aOld = m_aCharRect;
2241 bFirst = false;
2242
2243 // update cursor Points to the new Positions
2244 pShellCursor->GetPtPos().setX(m_aCharRect.Left());
2245 pShellCursor->GetPtPos().setY(m_aCharRect.Top());
2246
2247 if( !(eFlags & SwCursorShell::UPDOWN )) // delete old Pos. of Up/Down
2248 {
2250 pFrame->Calc(GetOut());
2251 m_nUpDownX = pFrame->IsVertical() ?
2252 m_aCharRect.Top() - pFrame->getFrameArea().Top() :
2253 m_aCharRect.Left() - pFrame->getFrameArea().Left();
2254 }
2255
2256 // scroll Cursor to visible area
2257 if( m_bHasFocus && eFlags & SwCursorShell::SCROLLWIN &&
2258 (HasSelection() || eFlags & SwCursorShell::READONLY ||
2259 !IsCursorReadonly() || GetViewOptions()->IsSelectionInReadonly()) )
2260 {
2261 // in case of scrolling this EndAction doesn't show the SV cursor
2262 // again, thus save and reset the flag here
2263 bool bSav = m_bSVCursorVis;
2264 m_bSVCursorVis = false;
2266 m_bSVCursorVis = bSav;
2267 }
2268
2269 } while( eFlags & SwCursorShell::SCROLLWIN );
2270
2271 assert(pFrame);
2272
2273 if( m_pBlockCursor )
2275
2276 // We should not restrict cursor update to the active view when using LOK
2277 bool bCheckFocus = m_bHasFocus || comphelper::LibreOfficeKit::isActive();
2278
2279 if( !bIdleEnd && bCheckFocus && !m_bBasicHideCursor )
2280 {
2281 if( m_pTableCursor )
2282 m_pTableCursor->SwSelPaintRects::Show();
2283 else
2284 {
2285 m_pCurrentCursor->SwSelPaintRects::Show();
2286 if( m_pBlockCursor )
2287 {
2289 while( pNxt && pNxt != m_pCurrentCursor )
2290 {
2291 pNxt->SwSelPaintRects::Show();
2292 pNxt = pNxt->GetNext();
2293 }
2294 }
2295 }
2296 }
2297
2298 m_eMvState = CursorMoveState::NONE; // state for cursor travelling - GetModelPositionForViewPoint
2299
2300#if !ENABLE_WASM_STRIP_ACCESSIBILITY
2301 if (Imp()->IsAccessible() && m_bSendAccessibleCursorEvents)
2303#endif
2304
2305 // switch from blinking cursor to read-only-text-selection cursor
2306 const sal_uInt64 nBlinkTime = GetOut()->GetSettings().GetStyleSettings().
2307 GetCursorBlinkTime();
2308
2309 if ( (IsCursorReadonly() && GetViewOptions()->IsSelectionInReadonly()) ==
2310 ( nBlinkTime != STYLE_CURSOR_NOBLINKTIME ) )
2311 {
2312 // non blinking cursor in read only - text selection mode
2313 AllSettings aSettings = GetOut()->GetSettings();
2314 StyleSettings aStyleSettings = aSettings.GetStyleSettings();
2315 const sal_uInt64 nNewBlinkTime = nBlinkTime == STYLE_CURSOR_NOBLINKTIME ?
2318 aStyleSettings.SetCursorBlinkTime( nNewBlinkTime );
2319 aSettings.SetStyleSettings( aStyleSettings );
2320 GetOut()->SetSettings( aSettings );
2321 }
2322
2323 if( m_bSVCursorVis )
2324 m_pVisibleCursor->Show(); // show again
2325
2328
2330}
2331
2333{
2334 SwView* pView = static_cast<SwView*>(GetSfxViewShell());
2335 if (!pView || !pView->GetWrtShellPtr())
2336 return;
2337
2338 SwWrtShell* pShell = &pView->GetWrtShell();
2339
2340 SwFrame* pCurrentFrame = GetCurrFrame();
2342
2343 tools::JsonWriter aJsonWriter;
2344
2345 if (pCurrentFrame && (eType & SelectionType::Table) && pCurrentFrame->IsInTab())
2346 {
2347 const SwRect& rPageRect = pShell->GetAnyCurRect(CurRectType::Page, nullptr);
2348
2349 {
2350 auto columnsNode = aJsonWriter.startNode("columns");
2351 SwTabCols aTabCols;
2352 pShell->GetTabCols(aTabCols);
2353
2354 const int nColumnOffset = aTabCols.GetLeftMin() + rPageRect.Left();
2355
2356 aJsonWriter.put("left", aTabCols.GetLeft());
2357 aJsonWriter.put("right", aTabCols.GetRight());
2358 aJsonWriter.put("tableOffset", static_cast<sal_Int64>(nColumnOffset));
2359
2360 {
2361 auto entriesNode = aJsonWriter.startArray("entries");
2362 for (size_t i = 0; i < aTabCols.Count(); ++i)
2363 {
2364 auto entryNode = aJsonWriter.startStruct();
2365 auto const & rEntry = aTabCols.GetEntry(i);
2366 aJsonWriter.put("position", rEntry.nPos);
2367 aJsonWriter.put("min", rEntry.nMin);
2368 aJsonWriter.put("max", rEntry.nMax);
2369 aJsonWriter.put("hidden", rEntry.bHidden);
2370 }
2371 }
2372 }
2373
2374 {
2375 auto rowsNode = aJsonWriter.startNode("rows");
2376 SwTabCols aTabRows;
2377 pShell->GetTabRows(aTabRows);
2378
2379 const int nRowOffset = aTabRows.GetLeftMin() + rPageRect.Top();
2380
2381 aJsonWriter.put("left", aTabRows.GetLeft());
2382 aJsonWriter.put("right", aTabRows.GetRight());
2383 aJsonWriter.put("tableOffset", static_cast<sal_Int64>(nRowOffset));
2384
2385 {
2386 auto entriesNode = aJsonWriter.startArray("entries");
2387 for (size_t i = 0; i < aTabRows.Count(); ++i)
2388 {
2389 auto entryNode = aJsonWriter.startStruct();
2390 auto const & rEntry = aTabRows.GetEntry(i);
2391 aJsonWriter.put("position", rEntry.nPos);
2392 aJsonWriter.put("min", rEntry.nMin);
2393 aJsonWriter.put("max", rEntry.nMax);
2394 aJsonWriter.put("hidden", rEntry.bHidden);
2395 }
2396 }
2397 }
2398 }
2399
2400 OString pChar = aJsonWriter.finishAndGetAsOString();
2401 GetSfxViewShell()->libreOfficeKitViewCallback(LOK_CALLBACK_TABLE_SELECTED, pChar);
2402}
2403
2405{
2406 assert(m_pBlockCursor);
2408 Point aPt = rBlock.GetPtPos();
2409 std::pair<Point, bool> const tmp(aPt, false);
2411 GetLayout(), rBlock.GetPoint(), &tmp);
2412 Point aMk;
2414 {
2415 aPt = *m_pBlockCursor->getStartPoint();
2416 aMk = *m_pBlockCursor->getEndPoint();
2417 }
2418 else
2419 {
2420 aPt = rBlock.GetPtPos();
2421 if( pFrame )
2422 {
2423 if( pFrame->IsVertical() )
2424 aPt.setY(pFrame->getFrameArea().Top() + GetUpDownX());
2425 else
2426 aPt.setX(pFrame->getFrameArea().Left() + GetUpDownX());
2427 }
2428 aMk = rBlock.GetMkPos();
2429 }
2430 SwRect aRect( aMk, aPt );
2431 aRect.Justify();
2432 SwSelectionList aSelList( pFrame );
2433
2434 if( !GetLayout()->FillSelection( aSelList, aRect ) )
2435 return;
2436
2437 SwCursor* pNxt = static_cast<SwCursor*>(m_pCurrentCursor->GetNext());
2438 while( pNxt != m_pCurrentCursor )
2439 {
2440 delete pNxt;
2441 pNxt = static_cast<SwCursor*>(m_pCurrentCursor->GetNext());
2442 }
2443
2444 std::list<SwPaM*>::iterator pStart = aSelList.getStart();
2445 std::list<SwPaM*>::iterator pPam = aSelList.getEnd();
2446 OSL_ENSURE( pPam != pStart, "FillSelection should deliver at least one PaM" );
2448 --pPam;
2449 // If there is only one text portion inside the rectangle, a simple
2450 // selection is created
2451 if( pPam == pStart )
2452 {
2453 *m_pCurrentCursor->GetPoint() = *(*pPam)->GetPoint();
2454 if( (*pPam)->HasMark() )
2455 *m_pCurrentCursor->GetMark() = *(*pPam)->GetMark();
2456 else
2458 delete *pPam;
2460 }
2461 else
2462 {
2463 // The order of the SwSelectionList has to be preserved but
2464 // the order inside the ring created by CreateCursor() is not like
2465 // expected => First create the selections before the last one
2466 // downto the first selection.
2467 // At least create the cursor for the last selection
2468 --pPam;
2469 *m_pCurrentCursor->GetPoint() = *(*pPam)->GetPoint(); // n-1 (if n == number of selections)
2470 if( (*pPam)->HasMark() )
2471 *m_pCurrentCursor->GetMark() = *(*pPam)->GetMark();
2472 else
2474 delete *pPam;
2476 while( pPam != pStart )
2477 {
2478 --pPam;
2479
2481 pNew->insert( pNew->begin(), m_pCurrentCursor->begin(), m_pCurrentCursor->end());
2482 m_pCurrentCursor->clear();
2484
2485 *m_pCurrentCursor->GetPoint() = *(*pPam)->GetPoint(); // n-2, n-3, .., 2, 1
2486 if( (*pPam)->HasMark() )
2487 {
2489 *m_pCurrentCursor->GetMark() = *(*pPam)->GetMark();
2490 }
2491 else
2494 delete *pPam;
2495 }
2496 {
2498 pNew->insert( pNew->begin(), m_pCurrentCursor->begin(), m_pCurrentCursor->end() );
2499 m_pCurrentCursor->clear();
2501 }
2502 pPam = aSelList.getEnd();
2503 --pPam;
2504 *m_pCurrentCursor->GetPoint() = *(*pPam)->GetPoint(); // n, the last selection
2505 if( (*pPam)->HasMark() )
2506 {
2508 *m_pCurrentCursor->GetMark() = *(*pPam)->GetMark();
2509 }
2510 else
2513 delete *pPam;
2514 }
2515}
2516
2519{
2520 // fdo#60513: if we have a table cursor, copy that; else copy current.
2521 // This seems to work because UpdateCursor() will fix this up on Pop(),
2522 // then MakeBoxSels() will re-create the current m_pCurrentCursor cell ring.
2524 m_pStackCursor = new SwShellCursor( *this, *pCurrent->GetPoint(),
2525 pCurrent->GetPtPos(), m_pStackCursor );
2526
2527 if (pCurrent->HasMark())
2528 {
2530 *m_pStackCursor->GetMark() = *pCurrent->GetMark();
2531 }
2532}
2533
2540bool SwCursorShell::Pop(PopMode const eDelete)
2541{
2542 std::optional<SwCallLink> aLink(std::in_place, *this); // watch Cursor-Moves; call Link if needed
2543 return Pop(eDelete, aLink);
2544}
2545
2546bool SwCursorShell::Pop(PopMode const eDelete,
2547 [[maybe_unused]] std::optional<SwCallLink>& roLink)
2548{
2549 // parameter exists only to be deleted before return
2550 assert(roLink);
2551 comphelper::ScopeGuard aGuard( [&]() { roLink.reset(); } );
2552
2553 // are there any left?
2554 if (nullptr == m_pStackCursor)
2555 return false;
2556
2557 SwShellCursor *pTmp = nullptr, *pOldStack = m_pStackCursor;
2558
2559 // the successor becomes the current one
2561 {
2562 pTmp = m_pStackCursor->GetNext();
2563 }
2564
2565 if (PopMode::DeleteStack == eDelete)
2566 delete m_pStackCursor;
2567
2568 m_pStackCursor = pTmp; // assign new one
2569
2570 if (PopMode::DeleteCurrent == eDelete)
2571 {
2572 ::std::optional<SwCursorSaveState> oSaveState( *m_pCurrentCursor );
2573
2574 // If the visible SSelection was not changed
2575 const Point& rPoint = pOldStack->GetPtPos();
2576 if (rPoint == m_pCurrentCursor->GetPtPos() || rPoint == m_pCurrentCursor->GetMkPos())
2577 {
2578 // move "Selections Rectangles"
2579 m_pCurrentCursor->insert( m_pCurrentCursor->begin(), pOldStack->begin(), pOldStack->end() );
2580 pOldStack->clear();
2581 }
2582
2583 if( pOldStack->HasMark() )
2584 {
2586 *m_pCurrentCursor->GetMark() = *pOldStack->GetMark();
2587 m_pCurrentCursor->GetMkPos() = pOldStack->GetMkPos();
2588 }
2589 else
2590 // no selection so revoke old one and set to old position
2592 *m_pCurrentCursor->GetPoint() = *pOldStack->GetPoint();
2593 m_pCurrentCursor->GetPtPos() = pOldStack->GetPtPos();
2594 delete pOldStack;
2595
2596 if( !m_pCurrentCursor->IsInProtectTable( true ) &&
2599 {
2600 oSaveState.reset(); // prevent UAF
2601 UpdateCursor(); // update current cursor
2602 if (m_pTableCursor)
2603 { // tdf#106929 ensure m_pCurrentCursor ring is recreated from table
2605 }
2606 }
2607 }
2608 return true;
2609}
2610
2616{
2617 // any others left?
2618 if (nullptr == m_pStackCursor)
2619 return;
2620
2621 SwCallLink aLk( *this ); // watch Cursor-Moves; call Link if needed
2622 // rhbz#689053: IsSelOvr must restore the saved stack position, not the
2623 // current one, because current point + stack mark may be invalid PaM
2624 SwCursorSaveState aSaveState(*m_pStackCursor);
2625 // stack cursor & current cursor in same Section?
2626 assert(!m_pStackCursor->HasMark() ||
2628 m_pCurrentCursor->GetPoint()->GetNode(), true));
2631
2632 SwShellCursor * pTmp = nullptr;
2634 {
2635 pTmp = m_pStackCursor->GetNext();
2636 }
2637 delete m_pCurrentCursor;
2639 m_pStackCursor->MoveTo(nullptr); // remove from ring
2640 m_pStackCursor = pTmp;
2641 if( !m_pCurrentCursor->IsInProtectTable( true ) &&
2644 {
2645 UpdateCursor(); // update current cursor
2646 }
2647}
2648
2650{
2652 return;
2653
2654 // if cursor is visible then hide SV cursor
2656 {
2657 CurrShell aCurr( this );
2659 }
2660 // revoke inversion of SSelection
2662 pCurrentCursor->Hide();
2663}
2664
2665void SwCursorShell::ShowCursors( bool bCursorVis )
2666{
2668 return;
2669
2670 CurrShell aCurr( this );
2672 pCurrentCursor->Show(nullptr);
2673
2674 if( m_bSVCursorVis && bCursorVis ) // also show SV cursor again
2676}
2677
2679{
2680 if( m_bBasicHideCursor )
2681 return;
2682
2684
2685 m_bSVCursorVis = true;
2688
2690 {
2691 const OString aPayload = OString::boolean(m_bSVCursorVis);
2692 GetSfxViewShell()->libreOfficeKitViewCallback(LOK_CALLBACK_CURSOR_VISIBLE, aPayload);
2693 SfxLokHelper::notifyOtherViews(GetSfxViewShell(), LOK_CALLBACK_VIEW_CURSOR_VISIBLE, "visible", aPayload);
2694 }
2695
2696 UpdateCursor();
2697}
2698
2700{
2701 if( m_bBasicHideCursor )
2702 return;
2703
2704 m_bSVCursorVis = false;
2705 // possibly reverse selected areas!!
2706 CurrShell aCurr( this );
2710
2712 {
2713 OString aPayload = OString::boolean(m_bSVCursorVis);
2714 GetSfxViewShell()->libreOfficeKitViewCallback(LOK_CALLBACK_CURSOR_VISIBLE, aPayload);
2715 SfxLokHelper::notifyOtherViews(GetSfxViewShell(), LOK_CALLBACK_VIEW_CURSOR_VISIBLE, "visible", aPayload);
2716 }
2717}
2718
2720{
2721 if( !m_bBasicHideCursor )
2722 HideCursors();
2723 m_bHasFocus = false;
2724}
2725
2727{
2729
2730 m_bHasFocus = true;
2731 if( !m_bBasicHideCursor && VisArea().Width() )
2732 {
2733 UpdateCursor( o3tl::narrowing<sal_uInt16>( SwCursorShell::CHKRANGE ) );
2735 }
2736}
2737
2739SwContentFrame *SwCursorShell::GetCurrFrame( const bool bCalcFrame ) const
2740{
2741 CurrShell aCurr( const_cast<SwCursorShell*>(this) );
2742 SwContentFrame *pRet = nullptr;
2744 if ( pNd )
2745 {
2746 if ( bCalcFrame )
2747 {
2748 sal_uInt16* pST = const_cast<sal_uInt16*>(&mnStartAction);
2749 ++(*pST);
2750 const Size aOldSz( GetDocSize() );
2751 std::pair<Point, bool> const tmp(m_pCurrentCursor->GetPtPos(), true);
2752 pRet = pNd->getLayoutFrame(GetLayout(), m_pCurrentCursor->GetPoint(), &tmp);
2753 --(*pST);
2754 if( aOldSz != GetDocSize() )
2755 const_cast<SwCursorShell*>(this)->SizeChgNotify();
2756 }
2757 else
2758 {
2759 std::pair<Point, bool> const tmp(m_pCurrentCursor->GetPtPos(), false);
2760 pRet = pNd->getLayoutFrame(GetLayout(), m_pCurrentCursor->GetPoint(), &tmp);
2761 }
2762 }
2763 return pRet;
2764}
2765
2766//TODO: provide documentation
2773{
2774 if(dynamic_cast<const sw::PostGraphicArrivedHint*>(&rHint) && m_aGrfArrivedLnk.IsSet())
2775 {
2776 m_aGrfArrivedLnk.Call(*this);
2777 return;
2778 }
2779 if (rHint.GetId() != SfxHintId::SwLegacyModify)
2780 return;
2781 auto pLegacy = static_cast<const sw::LegacyModifyHint*>(&rHint);
2782 auto nWhich = pLegacy->GetWhich();
2783 if(!nWhich)
2784 nWhich = RES_OBJECTDYING;
2785 if( m_bCallChgLnk &&
2786 ( !isFormatMessage(nWhich)
2787 || nWhich == RES_FMT_CHG
2788 || nWhich == RES_UPDATE_ATTR
2789 || nWhich == RES_ATTRSET_CHG ))
2790 // messages are not forwarded
2791 // #i6681#: RES_UPDATE_ATTR is implicitly unset in
2792 // SwTextNode::Insert(SwTextHint*, sal_uInt16); we react here and thus do
2793 // not need to send the expensive RES_FMT_CHG in Insert.
2794 CallChgLnk();
2795 if( nWhich == RES_OBJECTDYING )
2796 {
2797 EndListeningAll();
2798 }
2799
2800}
2801
2807{
2808 const SwPaM* pCursor = getShellCursor( true );
2809 return IsTableMode()
2810 || (pCursor->HasMark() &&
2811 (*pCursor->GetPoint() != *pCursor->GetMark()
2812 || IsFlySelectedByCursor(*GetDoc(), *pCursor->Start(), *pCursor->End())));
2813}
2814
2816{
2817 // Do not make any call in StartAction/EndAction but just set the flag.
2818 // This will be handled in EndAction.
2819 if (ActionPend())
2820 m_bChgCallFlag = true; // remember change
2821 else if( m_aChgLnk.IsSet() )
2822 {
2823 if( m_bCallChgLnk )
2824 m_aChgLnk.Call(nullptr);
2825 m_bChgCallFlag = false; // reset flag
2826 }
2827}
2828
2831{
2832 OUString aText;
2833 if (GetLayout()->HasMergedParas())
2834 {
2835 SwContentFrame const*const pFrame(GetCurrFrame(false));
2836 if (pFrame && FrameContainsNode(*pFrame, m_pCurrentCursor->GetMark()->GetNodeIndex()))
2837 {
2838 OUStringBuffer buf;
2839 SwPosition const*const pStart(m_pCurrentCursor->Start());
2840 SwPosition const*const pEnd(m_pCurrentCursor->End());
2841 for (SwNodeOffset i = pStart->GetNodeIndex(); i <= pEnd->GetNodeIndex(); ++i)
2842 {
2843 SwNode const& rNode(*pStart->GetNodes()[i]);
2844 assert(!rNode.IsEndNode());
2845 if (rNode.IsStartNode())
2846 {
2847 i = rNode.EndOfSectionIndex();
2848 }
2849 else if (rNode.IsTextNode())
2850 {
2851 sal_Int32 const nStart(i == pStart->GetNodeIndex()
2852 ? pStart->GetContentIndex()
2853 : 0);
2854 sal_Int32 const nEnd(i == pEnd->GetNodeIndex()
2855 ? pEnd->GetContentIndex()
2856 : rNode.GetTextNode()->Len());
2857 buf.append(rNode.GetTextNode()->GetExpandText(
2858 GetLayout(),
2859 nStart, nEnd - nStart, false, false, false,
2861
2862 }
2863 }
2864 aText = buf.makeStringAndClear();
2865 }
2866 }
2867 else if( m_pCurrentCursor->GetPoint()->GetNodeIndex() ==
2869 {
2871 if( pTextNd )
2872 {
2873 const sal_Int32 nStt = m_pCurrentCursor->Start()->GetContentIndex();
2874 aText = pTextNd->GetExpandText(GetLayout(), nStt,
2875 m_pCurrentCursor->End()->GetContentIndex() - nStt );
2876 }
2877 }
2878 return aText;
2879}
2880
2887{
2888 if( IsTableMode() ) // not possible in table mode
2889 return 0;
2890
2892 : bEnd ? m_pCurrentCursor->End() : m_pCurrentCursor->Start();
2893 SwTextNode* pTextNd = pPos->GetNode().GetTextNode();
2894 if( !pTextNd )
2895 return 0;
2896
2897 const sal_Int32 nPos = pPos->GetContentIndex();
2898 const OUString& rStr = pTextNd->GetText();
2899 sal_Unicode cCh = 0;
2900
2901 if (((nPos+nOffset) >= 0 ) && (nPos+nOffset) < rStr.getLength())
2902 cCh = rStr[nPos + nOffset];
2903
2904 return cCh;
2905}
2906
2912bool SwCursorShell::ExtendSelection( bool bEnd, sal_Int32 nCount )
2913{
2914 if( !m_pCurrentCursor->HasMark() || IsTableMode() )
2915 return false; // no selection
2916
2917 SwPosition* pPos = bEnd ? m_pCurrentCursor->End() : m_pCurrentCursor->Start();
2918 SwTextNode* pTextNd = pPos->GetNode().GetTextNode();
2919 assert(pTextNd);
2920
2921 sal_Int32 nPos = pPos->GetContentIndex();
2922 if( bEnd )
2923 {
2924 if ((nPos + nCount) <= pTextNd->GetText().getLength())
2925 nPos = nPos + nCount;
2926 else
2927 return false; // not possible
2928 }
2929 else if( nPos >= nCount )
2930 nPos = nPos - nCount;
2931 else
2932 return false; // not possible anymore
2933
2934 SwCallLink aLk( *this ); // watch Cursor-Moves; call Link if needed
2935
2936 pPos->SetContent(nPos) ;
2937 UpdateCursor();
2938
2939 return true;
2940}
2941
2947bool SwCursorShell::SetVisibleCursor( const Point &rPt )
2948{
2949 CurrShell aCurr( this );
2950 Point aPt( rPt );
2954 aTmpState.m_bRealHeight = true;
2955
2956 const bool bRet = GetLayout()->GetModelPositionForViewPoint( &aPos, aPt /*, &aTmpState*/ );
2957
2958 SetInFrontOfLabel( false ); // #i27615#
2959
2960 // show only in TextNodes
2961 SwTextNode* pTextNd = aPos.GetNode().GetTextNode();
2962 if( !pTextNd )
2963 return false;
2964
2965 const SwSectionNode* pSectNd = pTextNd->FindSectionNode();
2966 if( pSectNd && (pSectNd->GetSection().IsHiddenFlag() ||
2967 ( !IsReadOnlyAvailable() &&
2968 pSectNd->GetSection().IsProtectFlag())) )
2969 return false;
2970
2971 std::pair<Point, bool> const tmp(aPt, true);
2972 SwContentFrame *pFrame = pTextNd->getLayoutFrame(GetLayout(), &aPos, &tmp);
2973 if ( Imp()->IsIdleAction() )
2974 pFrame->PrepareCursor();
2975 SwRect aTmp( m_aCharRect );
2976
2977 pFrame->GetCharRect( m_aCharRect, aPos, &aTmpState );
2978
2979 // #i10137#
2980 if( aTmp == m_aCharRect && m_pVisibleCursor->IsVisible() )
2981 return true;
2982
2983 m_pVisibleCursor->Hide(); // always hide visible cursor
2984 if( IsScrollMDI( this, m_aCharRect ))
2985 {
2987 m_pCurrentCursor->Show(nullptr);
2988 }
2989
2990 {
2991 if( aTmpState.m_bRealHeight )
2992 m_aCursorHeight = aTmpState.m_aRealHeight;
2993 else
2994 {
2995 m_aCursorHeight.setX(0);
2997 }
2998
3000 m_pVisibleCursor->Show(); // show again
3001 }
3002 return bRet;
3003}
3004
3006{
3007 return m_pVisibleCursor;
3008}
3009
3010bool SwCursorShell::IsOverReadOnlyPos( const Point& rPt ) const
3011{
3012 Point aPt( rPt );
3013 SwPaM aPam( *m_pCurrentCursor->GetPoint() );
3015 // form view
3016 return aPam.HasReadonlySel(GetViewOptions()->IsFormView(), false);
3017}
3018
3023sal_uInt16 SwCursorShell::GetCursorCnt( bool bAll ) const
3024{
3025 SwPaM* pTmp = GetCursor()->GetNext();
3026 sal_uInt16 n = (bAll || ( m_pCurrentCursor->HasMark() &&
3028 while( pTmp != m_pCurrentCursor )
3029 {
3030 if( bAll || ( pTmp->HasMark() &&
3031 *pTmp->GetPoint() != *pTmp->GetMark()))
3032 ++n;
3033 pTmp = pTmp->GetNext();
3034 }
3035 return n;
3036}
3037
3039{
3041 return false;
3042
3043 // after EndOfIcons comes the content selection (EndNd+StNd+ContentNd)
3044 SwNodeIndex aIdx( GetDoc()->GetNodes().GetEndOfExtras(), 2 );
3045 if( !aIdx.GetNode().IsContentNode() )
3046 GetDoc()->GetNodes().GoNext( &aIdx );
3047 return aIdx == m_pCurrentCursor->GetPoint()->GetNode();
3048}
3049
3051{
3052 SwNodeIndex aIdx( GetDoc()->GetNodes().GetEndOfContent(), -1 );
3053 SwContentNode* pCNd = aIdx.GetNode().GetContentNode();
3054 if( !pCNd )
3055 pCNd = SwNodes::GoPrevious( &aIdx );
3056
3057 return aIdx == m_pCurrentCursor->GetPoint()->GetNode() && pCNd &&
3059}
3060
3069{
3070 if( !m_pTableCursor )
3071 return false;
3072
3074
3076 delete m_pCurrentCursor->GetNext();
3077
3078 // *always* move cursor's Point and Mark
3081
3082 return true;
3083}
3084
3085void SwCursorShell::ParkPams( SwPaM* pDelRg, SwShellCursor** ppDelRing )
3086{
3087 auto [pStt, pEnd] = pDelRg->StartEnd(); // SwPosition*
3088
3089 SwPaM *pTmpDel = nullptr, *pTmp = *ppDelRing;
3090
3091 // search over the whole ring
3092 bool bGoNext;
3093 do {
3094
3095 if (!pTmp)
3096 break;
3097
3098 auto [pTmpStt, pTmpEnd] = pTmp->StartEnd(); // SwPosition*
3099 // If a SPoint or GetMark are in a cursor area then cancel the old area.
3100 // During comparison keep in mind that End() is outside the area.
3101 if( *pStt <= *pTmpStt )
3102 {
3103 if( *pEnd > *pTmpStt ||
3104 ( *pEnd == *pTmpStt && *pEnd == *pTmpEnd ))
3105 pTmpDel = pTmp;
3106 }
3107 else
3108 if( *pStt < *pTmpEnd )
3109 pTmpDel = pTmp;
3110
3111 bGoNext = true;
3112 if (pTmpDel) // is the pam in the range -> delete
3113 {
3114 bool bDelete = true;
3115 if( *ppDelRing == pTmpDel )
3116 {
3117 if( *ppDelRing == m_pCurrentCursor )
3118 {
3119 bDelete = GoNextCursor();
3120 if( bDelete )
3121 {
3122 bGoNext = false;
3123 pTmp = pTmp->GetNext();
3124 }
3125 }
3126 else
3127 bDelete = false; // never delete the StackCursor
3128 }
3129
3130 if( bDelete )
3131 {
3132 if (pTmp == pTmpDel)
3133 pTmp = nullptr;
3134 delete pTmpDel; // invalidate old area
3135 }
3136 else
3137 {
3138 pTmpDel->GetPoint()->Assign(SwNodeOffset(0));
3139 pTmpDel->DeleteMark();
3140 }
3141 pTmpDel = nullptr;
3142 }
3143 if( bGoNext && pTmp )
3144 pTmp = pTmp->GetNext();
3145
3146 } while( !bGoNext || *ppDelRing != pTmp );
3147}
3148
3149//TODO: provide documentation
3157{
3158 const SwNode *pNode = &rIdx;
3159
3160 // create a new PaM
3161 SwPaM aNew( *GetCursor()->GetPoint() );
3162 if( pNode->GetStartNode() )
3163 {
3164 pNode = pNode->StartOfSectionNode();
3165 if( pNode->IsTableNode() )
3166 {
3167 // the given node is in a table, thus park cursor to table node
3168 // (outside of the table)
3169 aNew.GetPoint()->Assign( *pNode->StartOfSectionNode() );
3170 }
3171 else
3172 // Also on the start node itself. Then we need to request the start
3173 // node always via its end node! (StartOfSelection of StartNode is
3174 // the parent)
3175 aNew.GetPoint()->Assign( *pNode->EndOfSectionNode()->StartOfSectionNode() );
3176 }
3177 else
3178 aNew.GetPoint()->Assign( *pNode->StartOfSectionNode() );
3179 aNew.SetMark();
3180 aNew.GetPoint()->Assign(*pNode->EndOfSectionNode());
3181
3182 // take care of all shells
3183 for(SwViewShell& rTmp : GetRingContainer())
3184 {
3185 if( auto pSh = dynamic_cast<SwCursorShell *>(&rTmp))
3186 {
3187 if (pSh->m_pStackCursor)
3188 pSh->ParkPams(&aNew, &pSh->m_pStackCursor);
3189
3190 pSh->ParkPams( &aNew, &pSh->m_pCurrentCursor );
3191 if( pSh->m_pTableCursor )
3192 {
3193 // set table cursor always to 0 and the current one always to
3194 // the beginning of the table
3195 SwPaM* pTCursor = pSh->GetTableCrs();
3196 SwNode* pTableNd = pTCursor->GetPoint()->GetNode().FindTableNode();
3197 if ( pTableNd )
3198 {
3199 pTCursor->GetPoint()->Assign(SwNodeOffset(0));
3200 pTCursor->DeleteMark();
3201 pSh->m_pCurrentCursor->GetPoint()->Assign( *pTableNd );
3202 }
3203 }
3204 }
3205 }
3206}
3207
3214 : SwViewShell( rShell, pInitWin )
3215 , sw::BroadcastingModify()
3216 , m_pStackCursor( nullptr )
3217 , m_pBlockCursor( nullptr )
3218 , m_pTableCursor( nullptr )
3219 , m_pBoxIdx( nullptr )
3220 , m_pBoxPtr( nullptr )
3221 , m_nUpDownX(0)
3222 , m_nLeftFramePos(0)
3223 , m_nCurrentNode(0)
3224 , m_nCurrentContent(0)
3225 , m_nCurrentNdTyp(SwNodeType::NONE)
3226 , m_nCursorMove( 0 )
3227 , m_eMvState( CursorMoveState::NONE )
3228 , m_eEnhancedTableSel(SwTable::SEARCH_NONE)
3229 , m_nMarkedListLevel( 0 )
3230 , m_oldColFrame(nullptr)
3231{
3232 CurrShell aCurr( this );
3233 // only keep the position of the current cursor of the copy shell
3234 m_pCurrentCursor = new SwShellCursor( *this, *(rShell.m_pCurrentCursor->GetPoint()) );
3235 m_pCurrentCursor->GetPointContentNode()->Add( this );
3236
3239 m_bOverwriteCursor = false;
3242 m_bSVCursorVis = true;
3244 m_pVisibleCursor = new SwVisibleCursor( this );
3246}
3247
3250 const SwViewOption *pInitOpt )
3251 : SwViewShell( rDoc, pInitWin, pInitOpt )
3252 , sw::BroadcastingModify()
3253 , m_pStackCursor( nullptr )
3254 , m_pBlockCursor( nullptr )
3255 , m_pTableCursor( nullptr )
3256 , m_pBoxIdx( nullptr )
3257 , m_pBoxPtr( nullptr )
3258 , m_nUpDownX(0)
3259 , m_nLeftFramePos(0)
3260 , m_nCurrentNode(0)
3261 , m_nCurrentContent(0)
3262 , m_nCurrentNdTyp(SwNodeType::NONE)
3263 , m_nCursorMove( 0 )
3264 , m_eMvState( CursorMoveState::NONE ) // state for crsr-travelling - GetModelPositionForViewPoint
3265 , m_eEnhancedTableSel(SwTable::SEARCH_NONE)
3266 , m_nMarkedListLevel( 0 )
3267 , m_oldColFrame(nullptr)
3268{
3269 CurrShell aCurr( this );
3270 // create initial cursor and set it to first content position
3271 SwNodes& rNds = rDoc.GetNodes();
3272
3273 SwNodeIndex aNodeIdx( *rNds.GetEndOfContent().StartOfSectionNode() );
3274 SwContentNode* pCNd = rNds.GoNext( &aNodeIdx ); // go to the first ContentNode
3275
3276 m_pCurrentCursor = new SwShellCursor( *this, SwPosition( aNodeIdx, pCNd, 0 ) );
3277
3278 // Register shell as dependent at current node. As a result all attribute
3279 // changes can be forwarded via the Link.
3280 pCNd->Add( this );
3281
3284 m_bOverwriteCursor = false;
3287 m_bSVCursorVis = true;
3289
3290 m_pVisibleCursor = new SwVisibleCursor( this );
3291 m_bMacroExecAllowed = true;
3292}
3293
3295{
3296 // if it is not the last view then at least the field should be updated
3297 if( !unique() )
3299 else
3301
3302 delete m_pVisibleCursor;
3303 delete m_pBlockCursor;
3304 delete m_pTableCursor;
3305
3306 // release cursors
3308 delete m_pCurrentCursor->GetNext();
3309 delete m_pCurrentCursor;
3310
3311 // free stack
3312 if (m_pStackCursor)
3313 {
3315 delete m_pStackCursor->GetNext();
3316 delete m_pStackCursor;
3317 }
3318
3319 // #i54025# - do not give a HTML parser that might potentially hang as
3320 // a client at the cursor shell the chance to hang itself on a TextNode
3321 EndListeningAll();
3322}
3323
3325{
3326 if( m_pTableCursor )
3327 return m_pTableCursor;
3328 if( m_pBlockCursor && bBlock )
3329 return &m_pBlockCursor->getShellCursor();
3330 return m_pCurrentCursor;
3331}
3332
3338{
3339 if ( IsTableMode() || GetCursorCnt() > 1 )
3340 return true;
3341
3342 if( HasDrawView() && GetDrawView()->GetMarkedObjectList().GetMarkCount() )
3343 return true;
3344
3345 SwPaM* pPam = GetCursor();
3346 return pPam->Start()->GetNodeIndex() + SwNodeOffset(10) <
3347 pPam->End()->GetNodeIndex();
3348}
3349
3351{
3353 {
3355 }
3357}
3358
3361{
3362 OSL_ENSURE( m_bHasFocus, "no focus but cursor should be made visible?" );
3364 {
3365 SwRect aTmp( m_aCharRect );
3367 if( nDiff < m_aCursorHeight.getX() )
3368 aTmp.Top( nDiff + m_aCharRect.Top() );
3369 else
3370 {
3371 aTmp.Top( m_aCursorHeight.getX() + m_aCharRect.Top() );
3372 aTmp.Height( m_aCursorHeight.getY() );
3373 }
3374 if( !aTmp.HasArea() )
3375 {
3376 aTmp.AddHeight(1 );
3377 aTmp.AddWidth(1 );
3378 }
3379 MakeVisible( aTmp );
3380 }
3381 else
3382 {
3383 if( m_aCharRect.HasArea() )
3385 else
3386 {
3387 SwRect aTmp( m_aCharRect );
3388 aTmp.AddHeight(1 );
3389 aTmp.AddWidth(1 );
3390 MakeVisible( aTmp );
3391 }
3392 }
3393}
3394
3397{
3398 if( m_pTableCursor )
3399 {
3400 assert(!"Did not remove table selection!");
3401 return false;
3402 }
3403
3404 // #i45129# - everything is allowed in UI-readonly
3405 if( !m_bAllProtect && GetDoc()->GetDocShell() &&
3406 GetDoc()->GetDocShell()->IsReadOnlyUI() )
3407 return true;
3408
3409 if( m_pCurrentCursor->HasMark() )
3410 ClearMark();
3411
3412 // first check for frames
3413 SwPosition& rNdPos = *m_pCurrentCursor->GetPoint();
3414 SwNodeOffset nNdIdx = rNdPos.GetNodeIndex(); // keep backup
3415 SwNodes& rNds = mxDoc->GetNodes();
3416 SwContentNode* pCNd = rNdPos.GetNode().GetContentNode();
3417 const SwContentFrame * pFrame;
3418
3419 if (pCNd && nullptr != (pFrame = pCNd->getLayoutFrame(GetLayout(), m_pCurrentCursor->GetPoint())) &&
3420 !IsReadOnlyAvailable() && pFrame->IsProtected() &&
3421 nNdIdx < rNds.GetEndOfExtras().GetIndex() )
3422 {
3423 // skip protected frame
3424 SwPaM aPam( *m_pCurrentCursor->GetPoint() );
3425 aPam.SetMark();
3426 aPam.GetMark()->Assign( rNds.GetEndOfContent() );
3427 aPam.GetPoint()->Assign( *pCNd->EndOfSectionNode() );
3428
3429 bool bFirst = false;
3430 if( nullptr == (pCNd = ::GetNode( aPam, bFirst, fnMoveForward )))
3431 {
3432 aPam.GetMark()->Assign( *rNds.GetEndOfPostIts().StartOfSectionNode() );
3433 pCNd = ::GetNode( aPam, bFirst, fnMoveBackward );
3434 }
3435
3436 if( !pCNd ) // should *never* happen
3437 {
3438 rNdPos.Assign(nNdIdx); // back to old node
3439 return false;
3440 }
3441 *m_pCurrentCursor->GetPoint() = *aPam.GetPoint();
3442 }
3443 else if( bOnlyText && pCNd && pCNd->IsNoTextNode() )
3444 {
3445 // set to beginning of document
3446 rNdPos.Assign( mxDoc->GetNodes().GetEndOfExtras() );
3447 mxDoc->GetNodes().GoNext( &rNdPos );
3448 nNdIdx = rNdPos.GetNodeIndex();
3449 }
3450
3451 bool bOk = true;
3452
3453 // #i9059# cursor may not stand in protected cells
3454 // (unless cursor in protected areas is OK.)
3455 const SwTableNode* pTableNode = rNdPos.GetNode().FindTableNode();
3456 if( !IsReadOnlyAvailable() &&
3457 pTableNode != nullptr && rNdPos.GetNode().IsProtect() )
3458 {
3459 // we're in a table, and we're in a protected area, so we're
3460 // probably in a protected cell.
3461
3462 // move forward into non-protected area.
3463 SwPaM aPam( rNdPos.GetNode(), 0 );
3464 while( aPam.GetPointNode().IsProtect() &&
3465 aPam.Move( fnMoveForward, GoInContent ) )
3466 ; // nothing to do in the loop; the aPam.Move does the moving!
3467
3468 // didn't work? then go backwards!
3469 if( aPam.GetPointNode().IsProtect() )
3470 {
3471 SwPaM aTmpPaM( rNdPos.GetNode(), 0 );
3472 aPam = aTmpPaM;
3473 while( aPam.GetPointNode().IsProtect() &&
3475 ; // nothing to do in the loop; the aPam.Move does the moving!
3476 }
3477
3478 // if we're successful, set the new position
3479 if( ! aPam.GetPointNode().IsProtect() )
3480 {
3481 *m_pCurrentCursor->GetPoint() = *aPam.GetPoint();
3482 }
3483 }
3484
3485 // in a protected frame
3486 const SwSectionNode* pSectNd = rNdPos.GetNode().FindSectionNode();
3487 if( pSectNd && ( pSectNd->GetSection().IsHiddenFlag() ||
3488 ( !IsReadOnlyAvailable() &&
3489 pSectNd->GetSection().IsProtectFlag() )) )
3490 {
3491 bOk = false;
3492 bool bGoNextSection = true;
3493 for( int nLoopCnt = 0; !bOk && nLoopCnt < 2; ++nLoopCnt )
3494 {
3495 bool bContinue;
3496 do {
3497 bContinue = false;
3498 for (;;)
3499 {
3500 if (bGoNextSection)
3501 pCNd = rNds.GoNextSection( &rNdPos,
3502 true, !IsReadOnlyAvailable() );
3503 else
3504 pCNd = SwNodes::GoPrevSection( &rNdPos,
3505 true, !IsReadOnlyAvailable() );
3506 if ( pCNd == nullptr) break;
3507 // moved inside a table -> check if it is protected
3508 if( pCNd->FindTableNode() )
3509 {
3510 SwCallLink aTmp( *this );
3511 SwCursorSaveState aSaveState( *m_pCurrentCursor );
3512 aTmp.m_nNodeType = SwNodeType::NONE; // don't do anything in DTOR
3513 if( !m_pCurrentCursor->IsInProtectTable( true ) )
3514 {
3515 const SwSectionNode* pSNd = pCNd->FindSectionNode();
3516 if( !pSNd || !pSNd->GetSection().IsHiddenFlag()
3517 || (!IsReadOnlyAvailable() &&
3518 pSNd->GetSection().IsProtectFlag() ))
3519 {
3520 bOk = true;
3521 break; // found non-protected cell
3522 }
3523 continue; // continue search
3524 }
3525 }
3526 else
3527 {
3528 bOk = true;
3529 break; // found non-protected cell
3530 }
3531 }
3532
3533 if( bOk && rNdPos.GetNodeIndex() < rNds.GetEndOfExtras().GetIndex() )
3534 {
3535 // also check for Fly - might be protected as well
3536 pFrame = pCNd->getLayoutFrame(GetLayout(), nullptr, nullptr);
3537 if (nullptr == pFrame ||
3538 ( !IsReadOnlyAvailable() && pFrame->IsProtected() ) ||
3539 ( bOnlyText && pCNd->IsNoTextNode() ) )
3540 {
3541 // continue search
3542 bOk = false;
3543 bContinue = true;
3544 }
3545 }
3546 } while( bContinue );
3547
3548 if( !bOk )
3549 {
3550 if( !nLoopCnt )
3551 bGoNextSection = false;
3552 rNdPos.Assign( nNdIdx );
3553 }
3554 }
3555 }
3556 if( bOk )
3557 {
3558 pCNd = rNdPos.GetNode().GetContentNode();
3559 const sal_Int32 nContent = rNdPos.GetNodeIndex() < nNdIdx ? pCNd->Len() : 0;
3560 m_pCurrentCursor->GetPoint()->SetContent( nContent );
3561 }
3562 else
3563 {
3564 pCNd = rNdPos.GetNode().GetContentNode();
3565 // if cursor in hidden frame, always move it
3566 if (!pCNd || !pCNd->getLayoutFrame(GetLayout(), nullptr, nullptr))
3567 {
3571 &aTmpState );
3572 }
3573 }
3574 return bOk;
3575}
3576
3578{
3579 if ( GetViewOptions()->IsReadonly() ||
3580 GetViewOptions()->IsFormView() /* Formula view */ )
3581 {
3582 SwFrame *pFrame = GetCurrFrame( false );
3583 const SwFlyFrame* pFly;
3584 const SwSection* pSection;
3585
3586 if( pFrame && pFrame->IsInFly() &&
3587 (pFly = pFrame->FindFlyFrame())->GetFormat()->GetEditInReadonly().GetValue() &&
3588 pFly->Lower() &&
3589 !pFly->Lower()->IsNoTextFrame() &&
3590 !GetDrawView()->GetMarkedObjectList().GetMarkCount() )
3591 {
3592 return false;
3593 }
3594 // edit in readonly sections
3595 else if ( pFrame && pFrame->IsInSct() &&
3596 nullptr != ( pSection = pFrame->FindSctFrame()->GetSection() ) &&
3597 pSection->IsEditInReadonlyFlag() )
3598 {
3599 return false;
3600 }
3601 else if ( !IsMultiSelection() && CursorInsideInputField() )
3602 {
3603 return false;
3604 }
3605
3606 return true;
3607 }
3608 return false;
3609}
3610
3613{
3614 // *never* switch in GlobalDoc
3615 if( (!GetDoc()->GetDocShell() ||
3616 dynamic_cast<const SwGlobalDocShell*>(GetDoc()->GetDocShell()) == nullptr ) &&
3617 bFlag != m_bSetCursorInReadOnly )
3618 {
3619 // If the flag is switched off then all selections need to be
3620 // invalidated. Otherwise we would trust that nothing protected is selected.
3621 if( !bFlag )
3622 {
3623 ClearMark();
3624 }
3625 m_bSetCursorInReadOnly = bFlag;
3626 UpdateCursor();
3627 }
3628}
3629
3630bool SwCursorShell::HasReadonlySel(bool const isReplace) const
3631{
3632 // Treat selections that span over start or end of paragraph of an outline node
3633 // with folded outline content as read-only.
3634 if (GetViewOptions()->IsShowOutlineContentVisibilityButton())
3635 {
3636 SwWrtShell* pWrtSh = GetDoc()->GetDocShell()->GetWrtShell();
3637 if (pWrtSh && pWrtSh->HasFoldedOutlineContentSelected())
3638 return true;
3639 }
3640 bool bRet = false;
3641 // If protected area is to be ignored, then selections are never read-only.
3642 if ((IsReadOnlyAvailable() || GetViewOptions()->IsFormView() ||
3643 GetDoc()->GetDocumentSettingManager().get( DocumentSettingId::PROTECT_FORM )) &&
3645 {
3646 if ( m_pTableCursor != nullptr )
3647 {
3648 // TODO: handling when a table cell (cells) is selected
3650 || m_pTableCursor->HasReadonlySel(GetViewOptions()->IsFormView(), isReplace);
3651 }
3652 else
3653 {
3654 for(const SwPaM& rCursor : m_pCurrentCursor->GetRingContainer())
3655 {
3656 if (rCursor.HasReadonlySel(GetViewOptions()->IsFormView(), isReplace))
3657 {
3658 bRet = true;
3659 break;
3660 }
3661 }
3662 }
3663 }
3664 return bRet;
3665}
3666
3668{
3669 // Treat selections that span over start or end of paragraph of an outline node
3670 // with folded outline content as read-only.
3671 if (GetViewOptions()->IsShowOutlineContentVisibilityButton())
3672 {
3673 SwWrtShell* pWrtSh = GetDoc()->GetDocShell()->GetWrtShell();
3674 if (pWrtSh && pWrtSh->HasFoldedOutlineContentSelected())
3675 return true;
3676 }
3677 bool bRet = false;
3678
3679 if ( m_pTableCursor != nullptr )
3680 {
3683 }
3684 else
3685 {
3686 for(const SwPaM& rCursor : m_pCurrentCursor->GetRingContainer())
3687 {
3688 if (rCursor.HasHiddenSections())
3689 {
3690 bRet = true;
3691 break;
3692 }
3693 }
3694 }
3695
3696 return bRet;
3697}
3698
3700{
3701 bool bRet = false;
3702
3705 {
3706 sal_Int32 nStt = m_pCurrentCursor->GetPoint()->GetContentIndex();
3707 sal_Int32 nEnd = m_pCurrentCursor->GetMark()->GetContentIndex();
3708 if( nStt > nEnd )
3709 std::swap( nStt, nEnd );
3711 bRet = pCNd && !nStt && nEnd == pCNd->Len();
3712 }
3713 return bRet;
3714}
3715
3717{
3719 Point aPt( pPt ? *pPt : m_pCurrentCursor->GetPtPos() );
3720 if( pPt )
3721 {
3724
3725 GetLayout()->GetModelPositionForViewPoint( &aPos, aPt, &aTmpState );
3726 }
3727
3728 return mxDoc->GetTextDirection( aPos, &aPt );
3729}
3730
3731bool SwCursorShell::IsInVerticalText( const Point* pPt ) const
3732{
3733 const SvxFrameDirection nDir = GetTextDirection( pPt );
3734 return SvxFrameDirection::Vertical_RL_TB == nDir || SvxFrameDirection::Vertical_LR_TB == nDir
3735 || nDir == SvxFrameDirection::Vertical_LR_BT;
3736}
3737
3739{
3740 const SvxFrameDirection nDir = GetTextDirection();
3741 // GetTextDirection uses SvxFrameDirection::Vertical_LR_TB to indicate RTL in
3742 // vertical environment
3743 return SvxFrameDirection::Vertical_LR_TB == nDir || SvxFrameDirection::Horizontal_RL_TB == nDir;
3744}
3745
3748bool SwCursorShell::IsInHiddenRange(const bool bSelect)
3749{
3750 bool bRet = false;
3751 if ( !GetViewOptions()->IsShowHiddenChar() && !m_pCurrentCursor->HasMark() )
3752 {
3754 const SwTextNode* pNode = rPt.GetNode().GetTextNode();
3755 if ( pNode )
3756 {
3757 const sal_Int32 nPos = rPt.GetContentIndex();
3758
3759 // check if nPos is in hidden range
3760 sal_Int32 nHiddenStart;
3761 sal_Int32 nHiddenEnd;
3762 SwScriptInfo::GetBoundsOfHiddenRange( *pNode, nPos, nHiddenStart, nHiddenEnd );
3763 if ( COMPLETE_STRING != nHiddenStart )
3764 {
3765 if (bSelect)
3766 {
3767 // make selection:
3769 m_pCurrentCursor->GetMark()->SetContent(nHiddenEnd);
3770 }
3771 bRet = true;
3772 }
3773 }
3774 }
3775
3776 return bRet;
3777}
3778
3780 bool bSearchInNotes,
3781 SwDocPositions eStart, SwDocPositions eEnd,
3782 bool& bCancel,
3783 FindRanges eRng,
3784 bool bReplace )
3785{
3786 if( m_pTableCursor )
3787 GetCursor();
3788 delete m_pTableCursor;
3789 m_pTableCursor = nullptr;
3790 SwCallLink aLk( *this ); // watch Cursor-Moves; call Link if needed
3791 sal_Int32 nRet = m_pCurrentCursor->Find_Text(rSearchOpt, bSearchInNotes, eStart, eEnd,
3792 bCancel, eRng, bReplace, GetLayout());
3793 if( nRet || bCancel )
3794 UpdateCursor();
3795 return nRet;
3796}
3797
3798sal_Int32 SwCursorShell::FindFormat( const SwTextFormatColl& rFormatColl,
3799 SwDocPositions eStart, SwDocPositions eEnd,
3800 bool& bCancel,
3801 FindRanges eRng,
3802 const SwTextFormatColl* pReplFormat )
3803{
3804 if( m_pTableCursor )
3805 GetCursor();
3806 delete m_pTableCursor;
3807 m_pTableCursor = nullptr;
3808 SwCallLink aLk( *this ); // watch Cursor-Moves; call Link if needed
3809 sal_Int32 nRet = m_pCurrentCursor->FindFormat(rFormatColl, eStart, eEnd, bCancel, eRng,
3810 pReplFormat );
3811 if( nRet )
3812 UpdateCursor();
3813 return nRet;
3814}
3815
3817 bool bNoCollections,
3818 SwDocPositions eStart, SwDocPositions eEnd,
3819 bool& bCancel,
3820 FindRanges eRng,
3821 const i18nutil::SearchOptions2* pSearchOpt,
3822 const SfxItemSet* rReplSet )
3823{
3824 if( m_pTableCursor )
3825 GetCursor();
3826 delete m_pTableCursor;
3827 m_pTableCursor = nullptr;
3828 SwCallLink aLk( *this ); // watch Cursor-Moves; call Link if needed
3829 sal_Int32 nRet = m_pCurrentCursor->FindAttrs(rSet, bNoCollections, eStart, eEnd,
3830 bCancel, eRng, pSearchOpt, rReplSet, GetLayout());
3831 if( nRet )
3832 UpdateCursor();
3833 return nRet;
3834}
3835
3837{
3838 StartAction();
3839 SwCursor* pCursor = GetCursor();
3840 *pCursor->GetPoint() = *rCursor.GetPoint();
3841 if(rCursor.GetNext() != &rCursor)
3842 {
3843 const SwPaM *_pStartCursor = rCursor.GetNext();
3844 do
3845 {
3846 SwPaM* pCurrentCursor = CreateCursor();
3847 *pCurrentCursor->GetPoint() = *_pStartCursor->GetPoint();
3848 if(_pStartCursor->HasMark())
3849 {
3850 pCurrentCursor->SetMark();
3851 *pCurrentCursor->GetMark() = *_pStartCursor->GetMark();
3852 }
3853 } while( (_pStartCursor = _pStartCursor->GetNext()) != &rCursor );
3854 }
3855 // CreateCursor() adds a copy of current cursor after current, and then deletes mark of current
3856 // cursor; therefore set current cursor's mark only after creating all other cursors
3857 if (rCursor.HasMark())
3858 {
3859 pCursor->SetMark();
3860 *pCursor->GetMark() = *rCursor.GetMark();
3861 }
3862 EndAction();
3863}
3864
3865static const SwStartNode* lcl_NodeContext( const SwNode& rNode )
3866{
3867 const SwStartNode *pRet = rNode.StartOfSectionNode();
3868 while( pRet->IsSectionNode() || pRet->IsTableNode() ||
3870 {
3871 pRet = pRet->StartOfSectionNode();
3872 }
3873 return pRet;
3874}
3875
3882static bool sw_PosOk(const SwPosition & aPos)
3883{
3884 return nullptr != aPos.GetNode().GetContentNode() &&
3885 aPos.GetContentNode();
3886}
3887
3894static bool lcl_CursorOk(SwPaM & aPam)
3895{
3896 return sw_PosOk(*aPam.GetPoint()) && (! aPam.HasMark()
3897 || sw_PosOk(*aPam.GetMark()));
3898}
3899
3901{
3902 // start of the ring
3903 SwPaM * pStartCursor = GetCursor();
3904 // start loop with second entry of the ring
3905 SwPaM * pCursor = pStartCursor->GetNext();
3906 SwPaM * pTmpCursor;
3907 bool bChanged = false;
3908
3909 // For all entries in the ring except the start entry delete the entry if
3910 // it is invalid.
3911 while (pCursor != pStartCursor)
3912 {
3913 pTmpCursor = pCursor->GetNext();
3914 if ( ! lcl_CursorOk(*pCursor))
3915 {
3916 delete pCursor;
3917 bChanged = true;
3918 }
3919 pCursor = pTmpCursor;
3920 }
3921
3922 if( pStartCursor->HasMark() && !sw_PosOk( *pStartCursor->GetMark() ) )
3923 {
3924 pStartCursor->DeleteMark();
3925 bChanged = true;
3926 }
3927 if (pStartCursor->GetPoint()->GetNode().IsTableNode())
3928 {
3929 // tdf#106959: When cursor points to start of a table, the proper content
3930 // node is the first one inside the table, not the previous one
3931 SwNodes& aNodes = GetDoc()->GetNodes();
3932 SwNodeIndex aIdx(pStartCursor->GetPoint()->GetNode());
3933 if (SwNode* pNode = aNodes.GoNext(&aIdx))
3934 {
3935 SwPaM aTmpPam(*pNode);
3936 *pStartCursor = aTmpPam;
3937 bChanged = true;
3938 }
3939 }
3940 if( !sw_PosOk( *pStartCursor->GetPoint() ) )
3941 {
3942 SwNodes & aNodes = GetDoc()->GetNodes();
3943 const SwNode* pStart = lcl_NodeContext( pStartCursor->GetPoint()->GetNode() );
3944 SwNodeIndex aIdx( pStartCursor->GetPoint()->GetNode() );
3945 SwNode * pNode = SwNodes::GoPrevious(&aIdx);
3946 if( pNode == nullptr || lcl_NodeContext( *pNode ) != pStart )
3947 {
3948 pNode = aNodes.GoNext( &aIdx );
3949 if( pNode == nullptr || lcl_NodeContext( *pNode ) != pStart )
3950 {
3951 // If the start entry of the ring is invalid replace it with a
3952 // cursor pointing to the beginning of the first content node in the
3953 // document.
3954 aIdx = *(aNodes.GetEndOfContent().StartOfSectionNode());
3955 pNode = aNodes.GoNext( &aIdx );
3956 }
3957 }
3958 bool bFound = (pNode != nullptr);
3959
3960 assert(bFound);
3961
3962 if (bFound)
3963 {
3964 SwPaM aTmpPam(*pNode);
3965 *pStartCursor = aTmpPam;
3966 }
3967
3968 bChanged = true;
3969 }
3970
3971 // If at least one of the cursors in the ring have been deleted or replaced,
3972 // remove the table cursor.
3973 if (m_pTableCursor != nullptr && bChanged)
3975}
3976
3978{
3979 OUString aResult;
3980
3981 if (IsMultiSelection())
3982 aResult += SwResId(STR_MULTISEL);
3983 else
3984 aResult = SwDoc::GetPaMDescr(*GetCursor());
3985
3986 return aResult;
3987}
3988
3990{
3991 (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SwCursorShell"));
3992
3993 SwViewShell::dumpAsXml(pWriter);
3994
3995 (void)xmlTextWriterStartElement(pWriter, BAD_CAST("m_pCurrentCursor"));
3996 for (const SwPaM& rPaM : m_pCurrentCursor->GetRingContainer())
3997 rPaM.dumpAsXml(pWriter);
3998 (void)xmlTextWriterEndElement(pWriter);
3999
4000 (void)xmlTextWriterEndElement(pWriter);
4001}
4002
4003static void lcl_FillRecognizerData( std::vector< OUString >& rSmartTagTypes,
4004 uno::Sequence< uno::Reference< container::XStringKeyMap > >& rStringKeyMaps,
4005 const SwWrongList& rSmartTagList, sal_Int32 nCurrent )
4006{
4007 // Insert smart tag information
4008 std::vector< uno::Reference< container::XStringKeyMap > > aStringKeyMaps;
4009
4010 for ( sal_uInt16 i = 0; i < rSmartTagList.Count(); ++i )
4011 {
4012 const sal_Int32 nSTPos = rSmartTagList.Pos( i );
4013 const sal_Int32 nSTLen = rSmartTagList.Len( i );
4014
4015 if ( nSTPos <= nCurrent && nCurrent < nSTPos + nSTLen )
4016 {
4017 const SwWrongArea* pArea = rSmartTagList.GetElement( i );
4018 if ( pArea )
4019 {
4020 rSmartTagTypes.push_back( pArea->maType );
4021 aStringKeyMaps.push_back( pArea->mxPropertyBag );
4022 }
4023 }
4024 }
4025
4026 if ( !rSmartTagTypes.empty() )
4027 {
4028 rStringKeyMaps = comphelper::containerToSequence(aStringKeyMaps);
4029 }
4030}
4031
4032static void lcl_FillTextRange( uno::Reference<text::XTextRange>& rRange,
4033 SwTextNode& rNode, sal_Int32 nBegin, sal_Int32 nLen )
4034{
4035 // create SwPosition for nStartIndex
4036 SwPosition aStartPos( rNode, nBegin );
4037 // create SwPosition for nEndIndex
4038 SwPosition aEndPos( rNode, nBegin + nLen );
4039
4040 const rtl::Reference<SwXTextRange> xRange =
4041 SwXTextRange::CreateXTextRange(rNode.GetDoc(), aStartPos, &aEndPos);
4042
4043 rRange = xRange;
4044}
4045
4046void SwCursorShell::GetSmartTagTerm( std::vector< OUString >& rSmartTagTypes,
4047 uno::Sequence< uno::Reference< container::XStringKeyMap > >& rStringKeyMaps,
4048 uno::Reference< text::XTextRange>& rRange ) const
4049{
4050 if ( !SwSmartTagMgr::Get().IsSmartTagsEnabled() )
4051 return;
4052
4053 SwPaM* pCursor = GetCursor();
4054 SwPosition aPos( *pCursor->GetPoint() );
4055 SwTextNode *pNode = aPos.GetNode().GetTextNode();
4056 if ( !pNode || pNode->IsInProtectSect() )
4057 return;
4058
4059 const SwWrongList *pSmartTagList = pNode->GetSmartTags();
4060 if ( !pSmartTagList )
4061 return;
4062
4063 sal_Int32 nCurrent = aPos.GetContentIndex();
4064 sal_Int32 nBegin = nCurrent;
4065 sal_Int32 nLen = 1;
4066
4067 if (!pSmartTagList->InWrongWord(nBegin, nLen) || pNode->IsSymbolAt(nBegin))
4068 return;
4069
4070 const sal_uInt16 nIndex = pSmartTagList->GetWrongPos( nBegin );
4071 const SwWrongList* pSubList = pSmartTagList->SubList( nIndex );
4072 if ( pSubList )
4073 {
4074 pSmartTagList = pSubList;
4075 nCurrent = 0;
4076 }
4077
4078 lcl_FillRecognizerData( rSmartTagTypes, rStringKeyMaps, *pSmartTagList, nCurrent );
4079 lcl_FillTextRange( rRange, *pNode, nBegin, nLen );
4080}
4081
4082// see also SwEditShell::GetCorrection( const Point* pPt, SwRect& rSelectRect )
4083void SwCursorShell::GetSmartTagRect( const Point& rPt, SwRect& rSelectRect )
4084{
4085 SwPaM* pCursor = GetCursor();
4086 SwPosition aPos( *pCursor->GetPoint() );
4087 Point aPt( rPt );
4089 SwSpecialPos aSpecialPos;
4090 eTmpState.m_pSpecialPos = &aSpecialPos;
4091 SwTextNode *pNode;
4092 const SwWrongList *pSmartTagList;
4093
4094 if( !GetLayout()->GetModelPositionForViewPoint( &aPos, aPt, &eTmpState ) )
4095 return;
4096 pNode = aPos.GetNode().GetTextNode();
4097 if( !pNode )
4098 return;
4099 pSmartTagList = pNode->GetSmartTags();
4100 if( !pSmartTagList )
4101 return;
4102 if( pNode->IsInProtectSect() )
4103 return;
4104
4105 sal_Int32 nBegin = aPos.GetContentIndex();
4106 sal_Int32 nLen = 1;
4107
4108 if (!pSmartTagList->InWrongWord(nBegin, nLen) || pNode->IsSymbolAt(nBegin))
4109 return;
4110
4111 // get smarttag word
4112 OUString aText( pNode->GetText().copy(nBegin, nLen) );
4113
4114 //save the start and end positions of the line and the starting point
4115 Push();
4116 LeftMargin();
4117 const sal_Int32 nLineStart = GetCursor()->GetPoint()->GetContentIndex();
4118 RightMargin();
4119 const sal_Int32 nLineEnd = GetCursor()->GetPoint()->GetContentIndex();
4121
4122 // make sure the selection build later from the data below does not
4123 // include "in word" character to the left and right in order to
4124 // preserve those. Therefore count those "in words" in order to
4125 // modify the selection accordingly.
4126 const sal_Unicode* pChar = aText.getStr();
4127 sal_Int32 nLeft = 0;
4128 while (*pChar++ == CH_TXTATR_INWORD)
4129 ++nLeft;
4130 pChar = aText.getLength() ? aText.getStr() + aText.getLength() - 1 : nullptr;
4131 sal_Int32 nRight = 0;
4132 while (pChar && *pChar-- == CH_TXTATR_INWORD)
4133 ++nRight;
4134
4135 aPos.SetContent( nBegin + nLeft );
4136 pCursor = GetCursor();
4137 *pCursor->GetPoint() = aPos;
4138 pCursor->SetMark();
4139 ExtendSelection( true, nLen - nLeft - nRight );
4140 // do not determine the rectangle in the current line
4141 const sal_Int32 nWordStart = (nBegin + nLeft) < nLineStart ? nLineStart : nBegin + nLeft;
4142 // take one less than the line end - otherwise the next line would
4143 // be calculated
4144 const sal_Int32 nWordEnd = std::min(nBegin + nLen - nLeft - nRight, nLineEnd);
4145 Push();
4146 pCursor->DeleteMark();
4147 SwPosition& rPos = *GetCursor()->GetPoint();
4148 rPos.SetContent( nWordStart );
4149 SwRect aStartRect;
4150 SwCursorMoveState aState;
4151 aState.m_bRealWidth = true;
4152 SwContentNode* pContentNode = pCursor->GetPointContentNode();
4153 std::pair<Point, bool> const tmp(rPt, false);
4154 SwContentFrame *pContentFrame = pContentNode->getLayoutFrame(
4155 GetLayout(), pCursor->GetPoint(), &tmp);
4156
4157 pContentFrame->GetCharRect( aStartRect, *pCursor->GetPoint(), &aState );
4158 rPos.SetContent( nWordEnd - 1 );
4159 SwRect aEndRect;
4160 pContentFrame->GetCharRect( aEndRect, *pCursor->GetPoint(),&aState );
4161 rSelectRect = aStartRect.Union( aEndRect );
4163}
4164
4165/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
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...
const StyleSettings & GetStyleSettings() const
void SetStyleSettings(const StyleSettings &rSet)
static const AllSettings & GetSettings()
helper class to disable creation of an action by a callback event in particular, change event from a ...
Definition: rootfrm.hxx:465
void DrawSelectionXOR(OutlinerViewShell *pOtherShell)
void RegisterOtherShell(OutlinerViewShell *pOtherShell)
void ShowCursor(bool bGotoCursor=true, bool bForceVisCursor=true, bool bActivate=false)
virtual const SwRootFrame * GetCurrentLayout() const =0
virtual void NotifyCursorUpdate(const SwCursorShell &rCursorShell)=0
virtual void SetSettings(const AllSettings &rSettings)
const AllSettings & GetSettings() const
SfxHintId GetId() const
static void notifyOtherView(const SfxViewShell *pThisView, SfxViewShell const *pOtherView, int nType, std::string_view rKey, const OString &rPayload)
static void notifyOtherViews(const SfxViewShell *pThisView, int nType, std::string_view rKey, const OString &rPayload)
void SetReadOnlyUI(bool bReadOnly=true)
virtual void libreOfficeKitViewCallback(int nType, const OString &pPayload) const override
void SetCursorBlinkTime(sal_uInt64 nBlinkTime)
sal_uInt64 GetCursorBlinkTime() const
static void SetSearchLabel(const SearchLabel &rSL)
Access to the block cursor.
Definition: BlockCursor.hxx:40
SwShellCursor & getShellCursor()
Access to the shell cursor.
Definition: BlockCursor.cxx:25
std::optional< Point > const & getStartPoint() const
The document coordinates where the block selection has been started.
Definition: BlockCursor.hxx:72
void clearPoints()
Deletion of the mouse created rectangle.
Definition: BlockCursor.hxx:84
void setEndPoint(const Point &rPt)
Defines the ending vertex of the block selection.
Definition: BlockCursor.hxx:67
std::optional< Point > const & getEndPoint() const
The document coordinates where the block selection ends (at the moment)
Definition: BlockCursor.hxx:77
void setStartPoint(const Point &rPt)
Defines the starting vertex of the block selection.
Definition: BlockCursor.hxx:60
SwContentFrame is the layout for content nodes: a common base class for text (paragraph) and non-text...
Definition: cntfrm.hxx:59
SwContentFrame * getLayoutFrame(const SwRootFrame *, const SwPosition *pPos=nullptr, std::pair< Point, bool > const *pViewPosAndCalcFrame=nullptr) const
Definition: node.cxx:1223
virtual sal_Int32 Len() const
Definition: node.cxx:1256
A helper class to save cursor state (position).
Definition: swcrsr.hxx:233
tools::Long m_nLeftFramePos
Definition: crsrsh.hxx:199
void ExtendedSelectAll(bool bFootnotes=true)
Definition: crsrsh.cxx:748
bool Pop(PopMode, ::std::optional< SwCallLink > &roLink)
SAL_DLLPRIVATE void UpdateCursor(sal_uInt16 eFlags=SwCursorShell::SCROLLWIN|SwCursorShell::CHKRANGE, bool bIdleEnd=false)
Definition: crsrsh.cxx:1844
tools::Long GetUpDownX() const
Definition: crsrsh.hxx:361
SwVisibleCursor * GetVisibleCursor() const
Definition: crsrsh.cxx:3005
static void FireSectionChangeEvent(sal_uInt16 nOldSection, sal_uInt16 nNewSection)
Definition: crsrsh.cxx:463
SAL_DLLPRIVATE void MarkListLevel(const OUString &sListId, const int nLevel)
Mark a certain list level of a certain list.
Definition: crsrsh.cxx:388
bool m_bSetCursorInReadOnly
Definition: crsrsh.hxx:236
bool LeftMargin()
Definition: crsrsh.hxx:369
bool GoPrevCell()
Definition: trvltbl.cxx:101
OUString GetCursorDescr() const
Returns textual description of the current selection.
Definition: crsrsh.cxx:3977
bool m_bMacroExecAllowed
Definition: crsrsh.hxx:243
void Push()
store a copy of the current cursor on the cursor stack
Definition: crsrsh.cxx:2518
SAL_DLLPRIVATE void ParkPams(SwPaM *pDelRg, SwShellCursor **ppDelRing)
Definition: crsrsh.cxx:3085
void ShowCursors(bool bCursorVis)
Definition: crsrsh.cxx:2665
bool IsSelOnePara() const
Definition: crsrsh.cxx:1330
void ShowCursor()
Definition: crsrsh.cxx:2678
bool IsReadOnlyAvailable() const
Definition: crsrsh.hxx:493
void ClearTableBoxContent()
Definition: trvltbl.cxx:906
void StartAction()
Definition: crsrsh.cxx:226
const SwTableNode * IsCursorInTable() const
Check if Point of current cursor is placed within a table.
Definition: crsrsh.cxx:600
bool TrySelectOuterTable()
Definition: crsrsh.cxx:666
bool m_bInCMvVisportChgd
Flag for CursorMoves.
Definition: crsrsh.hxx:228
friend class SwVisibleCursor
Definition: crsrsh.hxx:152
bool IsEndOfTable() const
at the very last SwPosition inside a table
Definition: crsrsh.cxx:1387
sal_uInt16 GetNextPrevPageNum(bool bNext=true)
Definition: crsrsh.cxx:1521
bool IsInVerticalText(const Point *pPt=nullptr) const
Definition: crsrsh.cxx:3731
bool GoPrevCursor()
go to the previous SSelection
Definition: crsrsh.cxx:1644
void HideCursors()
Definition: crsrsh.cxx:2649
bool m_bSendAccessibleCursorEvents
Definition: crsrsh.hxx:241
void SttCursorMove()
Definition: crsrsh.cxx:301
void BlockCursorToCursor()
Definition: crsrsh.cxx:1157
SwShellCursor * GetCursor_()
Definition: crsrsh.hxx:342
bool m_bIgnoreReadonly
Definition: crsrsh.hxx:231
void SwapPam()
Definition: crsrsh.cxx:1230
void ShellGetFocus()
Definition: crsrsh.cxx:2726
static void FirePageChangeEvent(sal_uInt16 nOldPage, sal_uInt16 nNewPage)
Definition: crsrsh.cxx:441
sal_uInt16 GetCursorCnt(bool bAll=true) const
Get the number of elements in the ring of cursors.
Definition: crsrsh.cxx:3023
bool IsMacroExecAllowed() const
Definition: crsrsh.hxx:872
Point & GetCursorDocPos() const
Definition: crsrsh.hxx:924
void ParkCursor(const SwNode &rIdx)
Remove selections and additional cursors of all shells.
Definition: crsrsh.cxx:3156
Point m_aOldRBPos
Right/Bottom of last VisArea.
Definition: crsrsh.hxx:176
virtual SwCursor & CreateNewShellCursor() override
Create and return a new shell cursor.
Definition: crsrsh.cxx:172
StartsWith StartsWith_()
If document body starts with a table or starts/ends with hidden paragraph.
Definition: crsrsh.cxx:873
bool IsInHiddenRange(const bool bSelect)
If the current cursor position is inside a hidden range true is returned.
Definition: crsrsh.cxx:3748
static void FireColumnChangeEvent(sal_uInt16 nOldColumn, sal_uInt16 nNewColumn)
Definition: crsrsh.cxx:452
tools::Long m_nUpDownX
try to move the cursor on up/down always in the same column
Definition: crsrsh.hxx:197
bool m_bChgCallFlag
attribute change inside Start- and EndAction
Definition: crsrsh.hxx:219
void HideCursor()
Definition: crsrsh.cxx:2699
void SetSelection(const SwPaM &rCursor)
Definition: crsrsh.cxx:3836
int SetCursor(const Point &rPt, bool bOnlyText=false, bool bBlock=true)
Definition: crsrsh.cxx:1015
bool HasSelection() const
Does the current cursor create a selection?
Definition: crsrsh.cxx:2806
bool IsMultiSelection() const
Definition: crsrsh.hxx:914
CursorMoveState m_eMvState
Status for Cursor-Travelling - GetModelPositionForViewPoint.
Definition: crsrsh.hxx:211
bool SttEndDoc(bool bStt)
Definition: crsrsh.cxx:579
void ClearUpCursors()
Definition: crsrsh.cxx:3900
Point m_aCursorHeight
height & offset from visible Cursor
Definition: crsrsh.hxx:175
void SetReadOnlyAvailable(bool bFlag)
is the cursor allowed to enter ReadOnly sections?
Definition: crsrsh.cxx:3612
virtual SwCursor & GetCurrentShellCursor() override
Return the current shell cursor.
Definition: crsrsh.cxx:185
void NormalizePam(bool bPointFirst=true)
Ensure point and mark of the current PaM are in a specific order.
Definition: crsrsh.cxx:1224
SwBlockCursor * m_pBlockCursor
interface of cursor for block (=rectangular) selection
Definition: crsrsh.hxx:189
bool MovePara(SwWhichPara, SwMoveFnCollection const &)
Definition: crsrsh.cxx:950
bool MoveStartText()
Definition: crsrsh.cxx:732
bool m_bAllProtect
Flag for areas.
Definition: crsrsh.hxx:226
bool IsCursorReadonly() const
Definition: crsrsh.cxx:3577
bool IsEndPara() const
Definition: crsrsh.cxx:1368
bool RightMargin(bool bAPI=false)
Definition: crsrsh.hxx:370
int CompareCursorStackMkCurrPt() const
Definition: crsrsh.cxx:1308
void GetSmartTagTerm(std::vector< OUString > &rSmartTagTypes, css::uno::Sequence< css::uno::Reference< css::container::XStringKeyMap > > &rStringKeyMaps, css::uno::Reference< css::text::XTextRange > &rRange) const
Definition: crsrsh.cxx:4046
bool m_bSelTableCells
Definition: crsrsh.hxx:233
bool ParkTableCursor()
Invalidate cursors.
Definition: crsrsh.cxx:3068
void GetSmartTagRect(const Point &rPt, SwRect &rSelectRect)
Definition: crsrsh.cxx:4083
bool bColumnChange()
Definition: crsrsh.cxx:474
bool GotoPage(sal_uInt16 nPage)
Definition: crsrsh.cxx:1456
SwCursor * GetCursor(bool bMakeTableCursor=true) const
Return pointer to the current shell cursor.
Definition: crsrsh.cxx:194
OUString GetSelText() const
get selected text of a node at current cursor
Definition: crsrsh.cxx:2830
void TableCursorToCursor()
enter block mode, change normal cursor into block cursor
Definition: crsrsh.cxx:1150
bool m_bGCAttr
Definition: crsrsh.hxx:230
bool ExtendSelection(bool bEnd=true, sal_Int32 nCount=1)
extend current SSelection by n characters
Definition: crsrsh.cxx:2912
bool MoveOutOfTable()
Definition: crsrsh.cxx:627
bool IsSttPara() const
Definition: crsrsh.cxx:1349
void Paint(vcl::RenderContext &rRenderContext, const tools::Rectangle &rRect) override
Definition: crsrsh.cxx:1679
bool m_bCallChgLnk
flag for derived classes
Definition: crsrsh.hxx:223
bool IsOverReadOnlyPos(const Point &rPt) const
Definition: crsrsh.cxx:3010
bool ShouldWait() const
Should WaitPtr be switched on for the clipboard?
Definition: crsrsh.cxx:3337
bool GoNextCursor()
go to the next SSelection
Definition: crsrsh.cxx:1625
void CursorToBlockCursor()
leave block mode, change block cursor into normal cursor
Definition: crsrsh.cxx:1174
int m_nMarkedListLevel
Definition: crsrsh.hxx:215
bool LeftRight(bool, sal_uInt16, SwCursorSkipMode, bool)
Definition: crsrsh.cxx:323
bool CursorInsideInputField() const
Definition: crstrvl.cxx:1092
void Combine()
Combine two cursors.
Definition: crsrsh.cxx:2615
bool CheckTableBoxContent(const SwPosition *pPos=nullptr)
Definition: trvltbl.cxx:804
SwPaM * CreateCursor()
delete the current cursor and make the following into the current
Definition: crsrsh.cxx:123
bool SetVisibleCursor(const Point &rPt)
Move visible cursor to given position in document.
Definition: crsrsh.cxx:2947
void GetPageNum(sal_uInt16 &rnPhyNum, sal_uInt16 &rnVirtNum, bool bAtCursorPos=true, const bool bCalcFrame=true)
Definition: crsrsh.cxx:1477
SAL_DLLPRIVATE bool IsAtLRMargin(bool, bool bAPI=false) const
Definition: crsrsh.cxx:573
bool HasMark() const
Definition: crsrsh.hxx:907
bool IsSelFullPara() const
Definition: crsrsh.cxx:3699
SAL_DLLPRIVATE SvxFrameDirection GetTextDirection(const Point *pPt=nullptr) const
Definition: crsrsh.cxx:3716
bool IsStartOfDoc() const
Definition: crsrsh.cxx:3038
void EndAction(const bool bIdleEnd=false)
Definition: crsrsh.cxx:243
SwCursorShell(SwDoc &rDoc, vcl::Window *pWin, const SwViewOption *pOpt)
default constructor
Definition: crsrsh.cxx:3249
Point GetCursorPagePos() const
Definition: crsrsh.cxx:1411
virtual ~SwCursorShell() override
Definition: crsrsh.cxx:3294
SAL_DLLPRIVATE bool UpDown(bool, sal_uInt16)
Definition: crsrsh.cxx:508
virtual void SwClientNotify(const SwModify &, const SfxHint &) override
forward all attribute/format changes at the current node to the Link
Definition: crsrsh.cxx:2772
sal_Int32 FindFormat(const SwTextFormatColl &rFormatColl, SwDocPositions eStart, SwDocPositions eEnd, bool &bCancel, FindRanges eRng, const SwTextFormatColl *pReplFormat)
Definition: crsrsh.cxx:3798
bool TestCurrPam(const Point &rPt, bool bTstHit=false)
Search in the selected area for a Selection that covers the given point.
Definition: crsrsh.cxx:1245
bool MovePage(SwWhichPage, SwPosPage)
Definition: crsrsh.cxx:888
sal_uInt16 m_nCursorMove
Definition: crsrsh.hxx:210
bool m_bBasicHideCursor
Definition: crsrsh.hxx:235
void ShellLoseFocus()
Definition: crsrsh.cxx:2719
bool Right(sal_uInt16 nCnt, SwCursorSkipMode nMode, bool bAllowVisual=false)
Definition: crsrsh.hxx:365
SwContentFrame * GetCurrFrame(const bool bCalcFrame=true) const
Get current frame in which the cursor is positioned.
Definition: crsrsh.cxx:2739
SwVisibleCursor * m_pVisibleCursor
the visible cursor
Definition: crsrsh.hxx:187
SwShellCursor * m_pStackCursor
stack for the cursor
Definition: crsrsh.hxx:186
SAL_DLLPRIVATE bool LRMargin(bool, bool bAPI=false)
Definition: crsrsh.cxx:538
virtual void VisPortChgd(const SwRect &) override
Definition: crsrsh.cxx:1725
sal_Int32 Find_Text(const i18nutil::SearchOptions2 &rSearchOpt, bool bSearchInNotes, SwDocPositions eStart, SwDocPositions eEnd, bool &bCancel, FindRanges eRng, bool bReplace=false)
Definition: crsrsh.cxx:3779
virtual void MakeSelVisible()
show the current selected "object"
Definition: crsrsh.cxx:3360
SAL_DLLPRIVATE bool isInHiddenTextFrame(SwShellCursor *pShellCursor)
Definition: crsrsh.cxx:914
bool IsInRightToLeftText() const
Definition: crsrsh.cxx:3738
void ClearMark()
Definition: crsrsh.cxx:1193
bool SetInFrontOfLabel(bool bNew)
Definition: crsrsh.cxx:1430
Link< SwCursorShell &, void > m_aGrfArrivedLnk
Link calls to UI if a graphic is arrived.
Definition: crsrsh.hxx:183
SwNodeType m_nCurrentNdTyp
Definition: crsrsh.hxx:202
sal_Int32 FindAttrs(const SfxItemSet &rSet, bool bNoCollections, SwDocPositions eStart, SwDocPositions eEnd, bool &bCancel, FindRanges eRng, const i18nutil::SearchOptions2 *pSearchOpt, const SfxItemSet *rReplSet)
Definition: crsrsh.cxx:3816
bool IsOverwriteCursor() const
Definition: crsrsh.hxx:474
bool m_bSVCursorVis
SV-Cursor visible/invisible.
Definition: crsrsh.hxx:218
bool IsEndOfDoc() const
Definition: crsrsh.cxx:3050
void CallChgLnk()
Definition: crsrsh.cxx:2815
SwShellCursor * getShellCursor(bool bBlock)
Delivers the current shell cursor.
Definition: crsrsh.cxx:3324
void DestroyCursor()
transform TableCursor to normal cursor, nullify Tablemode
Definition: crsrsh.cxx:151
OUString m_sMarkedListId
table rows or columns selected by not cell by cell
Definition: crsrsh.hxx:214
bool MoveSection(SwWhichSection, SwMoveFnCollection const &)
Definition: crsrsh.cxx:974
SwRect m_aCharRect
Char-SRectangle on which the cursor is located.
Definition: crsrsh.hxx:174
SAL_DLLPRIVATE void UpdateMarkedListLevel()
Updates the marked list level according to the cursor.
Definition: crsrsh.cxx:412
SwShellTableCursor * m_pTableCursor
table Cursor; only in tables when the selection lays over 2 columns
Definition: crsrsh.hxx:191
CursorFlag
for calling UpdateCursor
Definition: crsrsh.hxx:161
@ READONLY
make visible in spite of Readonly
Definition: crsrsh.hxx:165
@ CHKRANGE
check overlapping PaMs
Definition: crsrsh.hxx:164
@ SCROLLWIN
scroll window
Definition: crsrsh.hxx:163
@ UPDOWN
keep Up/Down on columns
Definition: crsrsh.hxx:162
void GetCharRectAt(SwRect &rRect, const SwPosition *pPos)
Definition: crsrsh.cxx:1471
void RefreshBlockCursor()
Definition: crsrsh.cxx:2404
virtual void dumpAsXml(xmlTextWriterPtr pWriter) const override
Definition: crsrsh.cxx:3989
void KillPams()
Definition: crsrsh.cxx:1276
SwNodeOffset m_nCurrentNode
Definition: crsrsh.hxx:200
sal_uInt16 GetPageNumSeqNonEmpty()
Definition: crsrsh.cxx:1497
Link< LinkParamNone *, void > m_aChgLnk
link will be called by every attribute/ format changes at cursor position.
Definition: crsrsh.hxx:181
SwFrame * m_oldColFrame
Definition: crsrsh.hxx:245
void GoNextPrevCursorSetSearchLabel(const bool bNext)
Definition: crsrsh.cxx:1662
bool m_bHasFocus
Shell is "active" in a window.
Definition: crsrsh.hxx:217
bool HasReadonlySel(bool isReplace=false) const
Definition: crsrsh.cxx:3630
SwShellCursor * m_pCurrentCursor
current cursor
Definition: crsrsh.hxx:185
bool IsInHeaderFooter(bool *pbInHeader=nullptr) const
Definition: crsrsh.cxx:1006
size_t UpdateTableSelBoxes()
Definition: crsrsh.cxx:3350
bool m_bOverwriteCursor
Definition: crsrsh.hxx:237
bool m_bAutoUpdateCells
Definition: crsrsh.hxx:234
void UpdateCursorPos()
Set the cursor back into content.
Definition: crsrsh.cxx:1759
SwNode const * ExtendedSelectedAll() const
If ExtendedSelectAll() was called and selection didn't change since then.
Definition: crsrsh.cxx:822
bool IsTableMode() const
Definition: crsrsh.hxx:667
SAL_DLLPRIVATE void sendLOKCursorUpdates()
Definition: crsrsh.cxx:2332
bool IsInFrontOfLabel() const
Definition: crsrsh.cxx:1425
bool IsCursorInFootnote() const
Definition: crsrsh.cxx:1405
void EndCursorMove(const bool bIdleEnd=false)
Definition: crsrsh.cxx:310
bool IsBlockMode() const
Definition: crsrsh.hxx:664
sal_Int32 m_nCurrentContent
Definition: crsrsh.hxx:201
bool GoNextCell(bool bAppendLine=true)
set cursor into next/previous cell
Definition: trvltbl.cxx:39
bool HasHiddenSections() const
Definition: crsrsh.cxx:3667
sal_Unicode GetChar(bool bEnd=true, tools::Long nOffset=0)
get the nth character of the current SSelection
Definition: crsrsh.cxx:2886
OUString getPageRectangles()
Implementation of lok::Document::getPartPageRectangles() for Writer.
Definition: crsrsh.cxx:1566
sal_uInt16 GetPageCnt()
Definition: crsrsh.cxx:1559
bool FindValidContentNode(bool bOnlyText)
search a valid content position (not protected/hidden)
Definition: crsrsh.cxx:3396
void NotifyCursor(SfxViewShell *pViewShell) const
See SwView::NotifyCursor().
Definition: crsrsh.cxx:1587
bool m_bVisPortChgd
in VisPortChg-Call
Definition: crsrsh.hxx:220
bool MoveSection(SwWhichSection, SwMoveFnCollection const &)
Definition: swcrsr.cxx:2331
bool IsNoContent() const
determine if point is outside of the node-array's content area
Definition: swcrsr.cxx:181
sal_uInt8 GetCursorBidiLevel() const
Definition: swcrsr.hxx:211
bool LeftRightMargin(SwRootFrame const &rLayout, bool bLeftMargin, bool bAPI)
Definition: swcrsr.cxx:2131
virtual bool IsSelOvr(SwCursorSelOverFlags eFlags=SwCursorSelOverFlags::CheckNodeSection|SwCursorSelOverFlags::Toggle|SwCursorSelOverFlags::ChangePos)
Definition: swcrsr.cxx:222
SwCursor * GetNext()
Definition: swcrsr.hxx:219
sal_Int32 FindAttrs(const SfxItemSet &rSet, bool bNoCollections, SwDocPositions nStart, SwDocPositions nEnd, bool &bCancel, FindRanges, const i18nutil::SearchOptions2 *pSearchOpt, const SfxItemSet *rReplSet=nullptr, SwRootFrame const *const pLayout=nullptr)
search for attributes
Definition: findattr.cxx:1409
sal_Int32 Find_Text(const i18nutil::SearchOptions2 &rSearchOpt, bool bSearchInNotes, SwDocPositions nStart, SwDocPositions nEnd, bool &bCancel, FindRanges, bool bReplace=false, SwRootFrame const *const pLayout=nullptr)
Definition: findtxt.cxx:1004
bool IsInProtectTable(bool bMove=false, bool bChgCursor=true)
Definition: swcrsr.cxx:557
bool MovePara(SwWhichPara, SwMoveFnCollection const &)
Definition: swcrsr.cxx:2292
sal_Int32 FindFormat(const SwTextFormatColl &rFormatColl, SwDocPositions nStart, SwDocPositions nEnd, bool &bCancel, FindRanges, const SwTextFormatColl *pReplFormat, SwRootFrame const *const pLayout=nullptr)
search for Format-Collections
Definition: findcoll.cxx:75
bool SttEndDoc(bool bSttDoc)
Definition: swcrsr.cxx:2169
void SetCursorBidiLevel(sal_uInt8 nNewLevel)
Definition: swcrsr.hxx:212
virtual bool LeftRight(bool bLeft, sal_uInt16 nCnt, SwCursorSkipMode nMode, bool bAllowVisual, bool bSkipHidden, bool bInsertCursor, SwRootFrame const *pLayout, bool isFieldNames)
Definition: swcrsr.cxx:1732
void SetColumnSelection(bool bNew)
Definition: swcrsr.hxx:215
bool IsAtLeftRightMargin(SwRootFrame const &rLayout, bool bLeftMargin, bool bAPI) const
Definition: swcrsr.cxx:2148
SwWrtShell * GetWrtShell()
Access to the SwWrtShell belonging to SwView.
Definition: docsh.hxx:225
Definition: doc.hxx:197
static SwTableNode * IsInTable(const SwNode &)
Definition: ndtbl.cxx:219
void UpdateNumRule()
Definition: docnum.cxx:2628
static OUString GetPaMDescr(const SwPaM &rPaM)
Returns a textual description of a PaM.
Definition: doc.cxx:1771
SwNodes & GetNodes()
Definition: doc.hxx:422
IDocumentLayoutAccess const & getIDocumentLayoutAccess() const
Definition: doc.cxx:419
SwDocShell * GetDocShell()
Definition: doc.hxx:1367
Ends a section of nodes in the document model.
Definition: node.hxx:378
void GetTabCols(SwTabCols &rToFill) const
Info about columns and margins.
Definition: fetab.cxx:798
void GetTabRows(SwTabCols &rToFill) const
Definition: fetab.cxx:815
const SwRect & GetAnyCurRect(CurRectType eType, const Point *pPt=nullptr, const css::uno::Reference< css::embed::XEmbeddedObject > &=css::uno::Reference< css::embed::XEmbeddedObject >()) const
Definition: fews.cxx:90
general base class for all free-flowing frames
Definition: flyfrm.hxx:79
const SwRect & getFrameArea() const
Definition: frame.hxx:179
Base class of the Writer layout elements.
Definition: frame.hxx:315
bool IsCellFrame() const
Definition: frame.hxx:1232
bool IsTextFrame() const
Definition: frame.hxx:1240
sal_uInt16 GetVirtPageNum() const
Definition: trvlfrm.cxx:1817
SwFlyFrame * FindFlyFrame()
Definition: frame.hxx:1117
SwSectionFrame * FindSctFrame()
Definition: frame.hxx:1121
SwTabFrame * FindTabFrame()
Definition: frame.hxx:1105
SwFrame * GetNext()
Definition: frame.hxx:682
bool IsHeaderFrame() const
Definition: frame.hxx:1196
virtual void Calc(vcl::RenderContext *pRenderContext) const
Definition: trvlfrm.cxx:1799
bool IsInTab() const
Definition: frame.hxx:961
bool IsProtected() const
Is the Frame or rather the Section in which it lies protected?
Definition: trvlfrm.cxx:1639
SwFrame * GetLower()
Definition: findfrm.cxx:196
bool IsInFly() const
Definition: frame.hxx:967
virtual bool GetModelPositionForViewPoint(SwPosition *, Point &, SwCursorMoveState *=nullptr, bool bTestBackground=false) const
Definition: unusedf.cxx:47
void PrepareCursor()
Definition: calcmove.cxx:403
bool IsFooterFrame() const
Definition: frame.hxx:1200
SwLayoutFrame * GetUpper()
Definition: frame.hxx:684
bool IsVertical() const
Definition: frame.hxx:979
bool IsNoTextFrame() const
Definition: frame.hxx:1244
bool IsFlyFrame() const
Definition: frame.hxx:1216
SwFrame * GetPrev()
Definition: frame.hxx:683
SwFrame * FindColFrame()
Definition: findfrm.cxx:615
SwPageFrame * FindPageFrame()
Definition: frame.hxx:686
virtual bool GetCharRect(SwRect &, const SwPosition &, SwCursorMoveState *=nullptr, bool bAllowFarAway=true) const
Definition: unusedf.cxx:72
bool IsInSct() const
Definition: frame.hxx:973
A layout frame is a frame that contains other frames (m_pLower), e.g. SwPageFrame or SwTabFrame.
Definition: layfrm.hxx:36
const SwFrame * Lower() const
Definition: layfrm.hxx:101
Marks a node in the document model.
Definition: ndindex.hxx:31
const SwNodes & GetNodes() const
Definition: ndindex.hxx:119
SwNode & GetNode() const
Definition: ndindex.hxx:123
Base class of the Writer document model elements.
Definition: node.hxx:98
SwStartNode * GetStartNode()
Definition: node.hxx:642
SwTextNode * GetTextNode()
Inline methods from Node.hxx.
Definition: ndtxt.hxx:901
SwNodeOffset GetIndex() const
Definition: node.hxx:312
const SwStartNode * FindTableBoxStartNode() const
Definition: node.hxx:218
bool IsProtect() const
Is node in something that is protected (range, frame, table cells ... including anchor in case of fra...
Definition: node.cxx:449
bool IsNoTextNode() const
Definition: node.hxx:699
SwNodes & GetNodes()
Node is in which nodes-array/doc?
Definition: node.hxx:744
bool IsInProtectSect() const
Is node in a protected area?
Definition: node.cxx:439
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:968
const SwStartNode * StartOfSectionNode() const
Definition: node.hxx:153
SwNodeOffset EndOfSectionIndex() const
Definition: node.hxx:728
SwContentNode * GetContentNode()
Definition: node.hxx:666
SwNodeType GetNodeType() const
Definition: node.hxx:166
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
SwNode * FindPrvNxtFrameNode(const SwNode &rFrameNd, const SwNode *pEnd, SwRootFrame const *pLayout=nullptr) const
Search previous / next content node or table node with frames.
Definition: nodes.cxx:2188
static SwContentNode * GoPrevSection(SwNodeIndex *, bool bSkipHidden=true, bool bSkipProtect=true)
Definition: nodes.cxx:2064
PaM is Point and Mark: a selection of the document model.
Definition: pam.hxx:188
const SwPosition * GetMark() const
Definition: pam.hxx:255
void SetInFrontOfLabel_(bool bNew)
Definition: pam.hxx:227
SwNode & GetPointNode() const
Definition: pam.hxx:275
virtual void SetMark()
Unless this is called, the getter method of Mark will return Point.
Definition: pam.cxx:643
void Exchange()
Definition: pam.hxx:242
bool IsInFrontOfLabel() const
Definition: pam.hxx:226
void Normalize(bool bPointFirst=true)
Normalizes PaM, i.e.
Definition: pam.cxx:689
std::pair< const SwPosition *, const SwPosition * > StartEnd() const
Because sometimes the cost of the operator<= can add up.
Definition: pam.hxx:269
bool IsMultiSelection() const
Definition: pam.hxx:322
SwContentNode * GetPointContentNode() const
Definition: pam.hxx:279
bool Move(SwMoveFnCollection const &fnMove=fnMoveForward, SwGoInDoc fnGo=GoInContent)
Movement of cursor.
Definition: pam.cxx:657
const SwPosition * End() const
Definition: pam.hxx:263
SwPaM * GetNext()
Definition: pam.hxx:314
SwContentNode * GetMarkContentNode() const
Definition: pam.hxx:280
void DeleteMark()
Definition: pam.hxx:232
SwNode & GetMarkNode() const
Definition: pam.hxx:276
bool HasReadonlySel(bool bFormView, bool isReplace) const
Is in something protected (readonly) or selection contains something protected.
Definition: pam.cxx:746
const SwPosition * GetPoint() const
Definition: pam.hxx:253
bool HasHiddenSections() const
Is there hidden sections in the selected area.
Definition: pam.cxx:1005
const SwPosition * Start() const
Definition: pam.hxx:258
bool HasMark() const
A PaM marks a selection if Point and Mark are distinct positions.
Definition: pam.hxx:251
A page of the document layout.
Definition: pagefrm.hxx:59
sal_uInt16 GetPhyPageNum() const
Definition: pagefrm.hxx:205
bool IsEmptyPage() const
Definition: pagefrm.hxx:158
Of course Writer needs its own rectangles.
Definition: swrect.hxx:35
void Height(tools::Long nNew)
Definition: swrect.hxx:193
bool HasArea() const
Definition: swrect.hxx:300
SwRect & Union(const SwRect &rRect)
Definition: swrect.cxx:35
void Top(const tools::Long nTop)
Definition: swrect.hxx:206
void Pos(const Point &rNew)
Definition: swrect.hxx:171
bool Contains(const Point &rPOINT) const
Definition: swrect.hxx:356
Point Center() const
Definition: swrect.hxx:338
void AddHeight(const tools::Long nAdd)
Definition: swrect.cxx:124
bool Overlaps(const SwRect &rRect) const
Definition: swrect.hxx:374
void AddWidth(const tools::Long nAdd)
Definition: swrect.cxx:123
void Justify()
Definition: swrect.cxx:94
void Left(const tools::Long nLeft)
Definition: swrect.hxx:197
void Width(tools::Long nNew)
Definition: swrect.hxx:189
The root element of a Writer document layout.
Definition: rootfrm.hxx:85
sal_uInt16 GetPageNum() const
Definition: rootfrm.hxx:321
sal_uInt16 SetCurrPage(SwCursor *, sal_uInt16 nPageNum)
Returns a PaM which sits at the beginning of the requested page.
Definition: trvlfrm.cxx:994
bool MakeTableCursors(SwTableCursor &)
Calculates the cells included from the current selection.
Definition: trvlfrm.cxx:1871
virtual bool GetModelPositionForViewPoint(SwPosition *, Point &, SwCursorMoveState *=nullptr, bool bTestBackground=false) const override
Primary passes the call to the first page.
Definition: trvlfrm.cxx:425
static bool GetBoundsOfHiddenRange(const SwTextNode &rNode, sal_Int32 nPos, sal_Int32 &rnStartPos, sal_Int32 &rnEndPos, std::vector< sal_Int32 > *pList=nullptr)
Hidden text range information - static and non-version.
Definition: porlay.cxx:2052
SwSection * GetSection()
Definition: sectfrm.hxx:97
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
bool IsEditInReadonlyFlag() const
Definition: section.hxx:192
void SetShowContentControlOverlay(const bool bShow)
Definition: viscrs.hxx:123
void swapContent(SwSelPaintRects &rSwap)
Definition: viscrs.cxx:370
void SetShowTextInputFieldOverlay(const bool bShow)
Definition: viscrs.hxx:118
This class is used as parameter for creation of a block cursor selection.
std::list< SwPaM * >::iterator getStart()
Start of the container for the selected text portions.
std::list< SwPaM * >::iterator getEnd()
End of the container for the selected text portions.
Represents the current text cursor of one opened edit window.
Definition: viscrs.hxx:140
bool UpDown(bool bUp, sal_uInt16 nCnt)
Definition: viscrs.cxx:1068
void Show(SfxViewShell const *pViewShell)
Definition: viscrs.cxx:960
void Hide()
Definition: viscrs.cxx:1008
void Invalidate(const SwRect &rRect)
Definition: viscrs.cxx:996
SwShellCursor * GetNext()
Definition: viscrs.hxx:188
const Point & GetPtPos() const
Definition: viscrs.hxx:165
SwShellCursor * GetPrev()
Definition: viscrs.hxx:190
virtual void SetMark() override
Unless this is called, the getter method of Mark will return Point.
Definition: viscrs.cxx:939
const Point & GetMkPos() const
Definition: viscrs.hxx:167
bool Contains(const Point &rPt) const
Definition: viscrs.cxx:1220
static SwSmartTagMgr & Get()
Starts a section of nodes in the document model.
Definition: node.hxx:348
SwStartNodeType GetStartNodeType() const
Definition: node.hxx:364
const SwTabColsEntry & GetEntry(size_t nPos) const
Definition: tabcol.hxx:74
size_t Count() const
Definition: tabcol.hxx:65
tools::Long GetLeft() const
Definition: tabcol.hxx:78
tools::Long GetLeftMin() const
Definition: tabcol.hxx:77
tools::Long GetRight() const
Definition: tabcol.hxx:79
SwTabFrame is one table in the document layout, containing rows (which contain cells).
Definition: tabfrm.hxx:49
const SwTable * GetTable() const
Definition: tabfrm.hxx:162
bool IsInHeadline(const SwFrame &rFrame) const
Definition: tabfrm.cxx:5926
bool HasReadOnlyBoxSel() const
Definition: swcrsr.cxx:2612
void SetChgd()
Definition: swcrsr.hxx:301
bool HasHiddenBoxSel() const
Definition: swcrsr.cxx:2626
bool IsCursorMovedUpdate()
Definition: swcrsr.cxx:2582
SwCursor * MakeBoxSels(SwCursor *pCurrentCursor)
Definition: swcrsr.cxx:2411
void ActualizeSelection(const SwSelBoxes &rBoxes)
Definition: swcrsr.cxx:2547
bool IsChgd() const
Definition: swcrsr.hxx:300
const SwSelBoxes & GetSelectedBoxes() const
Definition: swcrsr.hxx:280
size_t GetSelectedBoxesCount() const
Definition: swcrsr.hxx:279
void ParkCursor()
park table cursor on the boxes' start node
Definition: swcrsr.cxx:2595
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,...
sal_uInt16 GetRowsToRepeat() const
Definition: swtable.hxx:201
@ SEARCH_NONE
Definition: swtable.hxx:146
Represents the style of a paragraph.
Definition: fmtcol.hxx:61
Represents the visualization of a paragraph.
Definition: txtfrm.hxx:168
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:112
OUString GetExpandText(SwRootFrame const *pLayout, const sal_Int32 nIdx=0, const sal_Int32 nLen=-1, const bool bWithNum=false, const bool bAddSpaceAfterListLabelStr=false, const bool bWithSpacesForLevel=false, const ExpandMode eAdditionalMode=ExpandMode::ExpandFootnote|ExpandMode::HideFieldmarkCommands) const
add 4th optional parameter <bAddSpaceAfterListLabelStr> indicating, when <bWithNum = true> that a spa...
Definition: ndtxt.cxx:3503