1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
22 #include <hintids.hxx>
23 #include <comphelper/string.hxx>
24 #include <svl/itemiter.hxx>
25 #include <editeng/lrspitem.hxx>
26 #include <editeng/adjustitem.hxx>
27 #include <editeng/formatbreakitem.hxx>
28 #include <svx/svdobj.hxx>
29 #include <osl/diagnose.h>
32 #include <IDocumentUndoRedo.hxx>
33 #include <IDocumentRedlineAccess.hxx>
34 #include <IDocumentFieldsAccess.hxx>
35 #include <IDocumentLayoutAccess.hxx>
36 #include <pagefrm.hxx>
38 #include <rootfrm.hxx>
42 #include <swtable.hxx>
47 #include <txtinet.hxx>
48 #include <fmtinfmt.hxx>
49 #include <txttxmrk.hxx>
59 #include <cellatr.hxx>
61 #include <redline.hxx>
62 #include <fmtcntnt.hxx>
63 #include <fmthdft.hxx>
64 #include <pagedesc.hxx>
66 #include <charfmt.hxx>
71 #include <unotools/intlwrapper.hxx>
72 #include <docufld.hxx>
73 #include <svx/srchdlg.hxx>
74 #include <frameformats.hxx>
77 #include <textcontentcontrol.hxx>
79 using namespace ::com::sun::star
;
81 void SwCursorShell::MoveCursorToNum()
83 SwCallLink
aLk( *this ); // watch Cursor-Moves
84 SwCursorSaveState
aSaveState( *m_pCurrentCursor
);
87 CurrShell
aCurr( this );
88 // try to set cursor onto this position, at half of the char-
89 // SRectangle's height
90 Point
aPt( m_pCurrentCursor
->GetPtPos() );
91 std::pair
<Point
, bool> const tmp(aPt
, true);
92 SwContentFrame
* pFrame
= m_pCurrentCursor
->GetPointContentNode()->getLayoutFrame(
93 GetLayout(), m_pCurrentCursor
->GetPoint(), &tmp
);
94 pFrame
->GetCharRect( m_aCharRect
, *m_pCurrentCursor
->GetPoint() );
95 pFrame
->Calc(GetOut());
96 if( pFrame
->IsVertical() )
98 aPt
.setX(m_aCharRect
.Center().getX());
99 aPt
.setY(pFrame
->getFrameArea().Top() + GetUpDownX());
103 aPt
.setY(m_aCharRect
.Center().getY());
104 aPt
.setX(pFrame
->getFrameArea().Left() + GetUpDownX());
106 pFrame
->GetModelPositionForViewPoint( m_pCurrentCursor
->GetPoint(), aPt
);
107 if ( !m_pCurrentCursor
->IsSelOvr( SwCursorSelOverFlags::Toggle
|
108 SwCursorSelOverFlags::ChangePos
))
110 UpdateCursor(SwCursorShell::UPDOWN
|
111 SwCursorShell::SCROLLWIN
| SwCursorShell::CHKRANGE
|
112 SwCursorShell::READONLY
);
116 /// go to next/previous point on the same level
117 void SwCursorShell::GotoNextNum()
119 if (!SwDoc::GotoNextNum(*m_pCurrentCursor
->GetPoint(), GetLayout()))
124 void SwCursorShell::GotoPrevNum()
126 if (!SwDoc::GotoPrevNum(*m_pCurrentCursor
->GetPoint(), GetLayout()))
131 /// jump from content to header
132 bool SwCursorShell::GotoHeaderText()
134 const SwFrame
* pFrame
= GetCurrFrame()->FindPageFrame();
135 while( pFrame
&& !pFrame
->IsHeaderFrame() )
136 pFrame
= pFrame
->GetLower();
137 // found header, search 1. content frame
138 while( pFrame
&& !pFrame
->IsContentFrame() )
139 pFrame
= pFrame
->GetLower();
144 CurrShell
aCurr( this );
146 SwCallLink
aLk( *this ); // watch Cursor-Moves
147 SwCursor
*pTmpCursor
= getShellCursor( true );
148 SwCursorSaveState
aSaveState( *pTmpCursor
);
149 pFrame
->Calc(GetOut());
150 Point
aPt( pFrame
->getFrameArea().Pos() + pFrame
->getFramePrintArea().Pos() );
151 pFrame
->GetModelPositionForViewPoint( pTmpCursor
->GetPoint(), aPt
);
152 if( !pTmpCursor
->IsSelOvr() )
156 return nullptr != pFrame
;
159 /// jump from content to footer
160 bool SwCursorShell::GotoFooterText()
162 const SwPageFrame
* pFrame
= GetCurrFrame()->FindPageFrame();
166 const SwFrame
* pLower
= pFrame
->GetLastLower();
168 while( pLower
&& !pLower
->IsFooterFrame() )
169 pLower
= pLower
->GetLower();
170 // found footer, search 1. content frame
171 while( pLower
&& !pLower
->IsContentFrame() )
172 pLower
= pLower
->GetLower();
177 SwCursor
*pTmpCursor
= getShellCursor( true );
178 CurrShell
aCurr( this );
179 // get position in footer
180 SwCallLink
aLk( *this ); // watch Cursor-Moves
181 SwCursorSaveState
aSaveState( *pTmpCursor
);
182 pLower
->Calc(GetOut());
183 Point
aPt( pLower
->getFrameArea().Pos() + pLower
->getFramePrintArea().Pos() );
184 pLower
->GetModelPositionForViewPoint( pTmpCursor
->GetPoint(), aPt
);
185 if( !pTmpCursor
->IsSelOvr() )
189 return nullptr != pFrame
;
192 bool SwCursorShell::SetCursorInHdFt(size_t nDescNo
, bool bInHeader
, bool bEven
, bool bFirst
)
194 SwDoc
*pMyDoc
= GetDoc();
195 const SwPageDesc
* pDesc
= nullptr;
197 CurrShell
aCurr( this );
199 if( SIZE_MAX
== nDescNo
)
201 // take the current one
202 const SwContentFrame
*pCurrFrame
= GetCurrFrame();
203 const SwPageFrame
* pPage
= (pCurrFrame
== nullptr) ? nullptr : pCurrFrame
->FindPageFrame();
204 if( pPage
&& pMyDoc
->ContainsPageDesc(
205 pPage
->GetPageDesc(), &nDescNo
) )
206 pDesc
= pPage
->GetPageDesc();
209 if (nDescNo
< pMyDoc
->GetPageDescCnt())
210 pDesc
= &pMyDoc
->GetPageDesc( nDescNo
);
215 // check if the attribute exists
216 const SwFormatContent
* pCnt
= nullptr;
219 const SwFormatHeader
& rHd
220 = bEven
? bFirst
? pDesc
->GetFirstLeft().GetHeader() : pDesc
->GetLeft().GetHeader()
221 : bFirst
? pDesc
->GetFirstMaster().GetHeader() : pDesc
->GetMaster().GetHeader();
222 if( rHd
.GetHeaderFormat() )
223 pCnt
= &rHd
.GetHeaderFormat()->GetContent();
227 const SwFormatFooter
& rFt
228 = bEven
? bFirst
? pDesc
->GetFirstLeft().GetFooter() : pDesc
->GetLeft().GetFooter()
229 : bFirst
? pDesc
->GetFirstMaster().GetFooter() : pDesc
->GetMaster().GetFooter();
230 if( rFt
.GetFooterFormat() )
231 pCnt
= &rFt
.GetFooterFormat()->GetContent();
234 if( !pCnt
|| !pCnt
->GetContentIdx() )
237 SwNodeIndex
aIdx( *pCnt
->GetContentIdx(), 1 );
238 SwContentNode
* pCNd
= aIdx
.GetNode().GetContentNode();
240 pCNd
= pMyDoc
->GetNodes().GoNext( &aIdx
);
242 Point
aPt( m_pCurrentCursor
->GetPtPos() );
244 std::pair
<Point
, bool> const tmp(aPt
, false);
245 if (!pCNd
|| nullptr == pCNd
->getLayoutFrame(GetLayout(), nullptr, &tmp
))
248 // then we can set the cursor in here
249 SwCallLink
aLk( *this ); // watch Cursor-Moves
250 SwCursorSaveState
aSaveState( *m_pCurrentCursor
);
254 SwPosition
& rPos
= *m_pCurrentCursor
->GetPoint();
255 rPos
.Assign( *pCNd
);
257 if (m_pCurrentCursor
->IsSelOvr())
260 UpdateCursor( SwCursorShell::SCROLLWIN
| SwCursorShell::CHKRANGE
|
261 SwCursorShell::READONLY
);
265 /// jump to the next index
266 bool SwCursorShell::GotoNextTOXBase( const OUString
* pName
)
268 const SwSectionFormats
& rFormats
= GetDoc()->GetSections();
269 SwContentNode
* pFnd
= nullptr;
270 for( SwSectionFormats::size_type n
= rFormats
.size(); n
; )
272 const SwSection
* pSect
= rFormats
[ --n
]->GetSection();
273 if (SectionType::ToxContent
== pSect
->GetType())
275 SwSectionNode
const*const pSectNd(
276 pSect
->GetFormat()->GetSectionNode());
278 && m_pCurrentCursor
->GetPoint()->GetNode() < *pSectNd
279 && (!pFnd
|| pFnd
->GetIndex() > pSectNd
->GetIndex())
280 && (!pName
|| *pName
==
281 static_cast<SwTOXBaseSection
const*>(pSect
)->GetTOXName()))
283 SwNodeIndex
aIdx(*pSectNd
, 1);
284 SwContentNode
* pCNd
= aIdx
.GetNode().GetContentNode();
286 pCNd
= GetDoc()->GetNodes().GoNext( &aIdx
);
288 pCNd
->EndOfSectionIndex() <= pSectNd
->EndOfSectionIndex())
290 SwContentFrame
const*const pCFrame(
291 pCNd
->getLayoutFrame(GetLayout()));
293 (IsReadOnlyAvailable() || !pCFrame
->IsProtected()))
303 SwCallLink
aLk( *this ); // watch Cursor-Moves
304 SwCursorSaveState
aSaveState( *m_pCurrentCursor
);
305 m_pCurrentCursor
->GetPoint()->Assign( *pFnd
);
306 bool bRet
= !m_pCurrentCursor
->IsSelOvr();
308 UpdateCursor(SwCursorShell::SCROLLWIN
|SwCursorShell::CHKRANGE
|SwCursorShell::READONLY
);
312 /// jump to previous index
313 bool SwCursorShell::GotoPrevTOXBase( const OUString
* pName
)
315 const SwSectionFormats
& rFormats
= GetDoc()->GetSections();
316 SwContentNode
* pFnd
= nullptr;
317 for( SwSectionFormats::size_type n
= rFormats
.size(); n
; )
319 const SwSection
* pSect
= rFormats
[ --n
]->GetSection();
320 if (SectionType::ToxContent
== pSect
->GetType())
322 SwSectionNode
const*const pSectNd(
323 pSect
->GetFormat()->GetSectionNode());
325 && m_pCurrentCursor
->GetPoint()->GetNode() > *pSectNd
->EndOfSectionNode()
326 && (!pFnd
|| *pFnd
< *pSectNd
)
327 && (!pName
|| *pName
==
328 static_cast<SwTOXBaseSection
const*>(pSect
)->GetTOXName()))
330 SwNodeIndex
aIdx(*pSectNd
, 1);
331 SwContentNode
* pCNd
= aIdx
.GetNode().GetContentNode();
333 pCNd
= GetDoc()->GetNodes().GoNext( &aIdx
);
335 pCNd
->EndOfSectionIndex() <= pSectNd
->EndOfSectionIndex())
337 SwContentFrame
const*const pCFrame(
338 pCNd
->getLayoutFrame(GetLayout()));
340 (IsReadOnlyAvailable() || !pCFrame
->IsProtected()))
352 SwCallLink
aLk( *this ); // watch Cursor-Moves
353 SwCursorSaveState
aSaveState( *m_pCurrentCursor
);
354 m_pCurrentCursor
->GetPoint()->Assign(*pFnd
);
355 bool bRet
= !m_pCurrentCursor
->IsSelOvr();
357 UpdateCursor(SwCursorShell::SCROLLWIN
|SwCursorShell::CHKRANGE
|SwCursorShell::READONLY
);
361 /// jump to index of TOXMark
362 void SwCursorShell::GotoTOXMarkBase()
365 sal_uInt16 nCnt
= SwDoc::GetCurTOXMark(*m_pCurrentCursor
->GetPoint(), aMarks
);
368 // Take the 1. and get the index type. Ask it for the actual index.
369 const SwTOXType
* pType
= aMarks
[0]->GetTOXType();
370 auto pContentFrame
= pType
->FindContentFrame(*GetDoc(), *GetLayout());
373 SwCallLink
aLk(*this); // watch Cursor-Moves
374 SwCursorSaveState
aSaveState(*m_pCurrentCursor
);
375 assert(pContentFrame
->IsTextFrame());
376 *m_pCurrentCursor
->GetPoint() = static_cast<SwTextFrame
const*>(pContentFrame
)->MapViewToModelPos(TextFrameIndex(0));
377 if(!m_pCurrentCursor
->IsInProtectTable() && !m_pCurrentCursor
->IsSelOvr())
378 UpdateCursor(SwCursorShell::SCROLLWIN
|SwCursorShell::CHKRANGE
|SwCursorShell::READONLY
);
381 /// Jump to next/previous table formula
382 /// Optionally it is possible to also jump to broken formulas
383 bool SwCursorShell::GotoNxtPrvTableFormula( bool bNext
, bool bOnlyErrors
)
385 SvxSearchDialogWrapper::SetSearchLabel( SearchLabel::Empty
);
391 SwPosition aOldPos
= *m_pCurrentCursor
->GetPoint();
392 SwPosition
& rPos
= *m_pCurrentCursor
->GetPoint();
395 SwPosition
aFndPos( GetDoc()->GetNodes().GetEndOfContent() );
397 aFndPos
.Assign(SwNodeOffset(0));
398 SetGetExpField
aFndGEF( aFndPos
), aCurGEF( rPos
);
401 const SwNode
* pSttNd
= rPos
.GetNode().FindTableBoxStartNode();
404 const SwTableBox
* pTBox
= pSttNd
->FindTableNode()->GetTable().
405 GetTableBox( pSttNd
->GetIndex() );
407 aCurGEF
= SetGetExpField( *pTBox
);
411 if( rPos
.GetNode() < GetDoc()->GetNodes().GetEndOfExtras() )
413 // also at collection use only the first frame
414 std::pair
<Point
, bool> const tmp(aPt
, false);
415 aCurGEF
.SetBodyPos( *rPos
.GetNode().GetContentNode()->getLayoutFrame( GetLayout(),
419 sal_uInt32 nMaxItems
= GetDoc()->GetAttrPool().GetItemCount2( RES_BOXATR_FORMULA
);
422 sal_uInt8 nMaxDo
= 2;
424 for (const SfxPoolItem
* pItem
: GetDoc()->GetAttrPool().GetItemSurrogates(RES_BOXATR_FORMULA
))
426 const SwTableBox
* pTBox
;
427 auto pFormulaItem
= dynamic_cast<const SwTableBoxFormula
*>(pItem
);
430 pTBox
= pFormulaItem
->GetTableBox();
433 pTBox
->GetSttNd()->GetNodes().IsDocNodes() &&
435 !pFormulaItem
->HasValidBoxes() ) )
437 SwNodeIndex
aIdx( *pTBox
->GetSttNd() );
438 const SwContentNode
* pCNd
= GetDoc()->GetNodes().GoNext( &aIdx
);
439 std::pair
<Point
, bool> const tmp(aPt
, false);
442 const SwContentFrame
* pCFrame
= pCNd
->getLayoutFrame(GetLayout(), nullptr, &tmp
);
443 if (pCFrame
&& (IsReadOnlyAvailable() || !pCFrame
->IsProtected() ))
445 SetGetExpField
aCmp( *pTBox
);
446 aCmp
.SetBodyPos( *pCFrame
);
448 if( bNext
? ( aCurGEF
< aCmp
&& aCmp
< aFndGEF
)
449 : ( aCmp
< aCurGEF
&& aFndGEF
< aCmp
))
462 rPos
.Assign(SwNodeOffset(0), 0);
463 aCurGEF
= SetGetExpField( rPos
);
464 SvxSearchDialogWrapper::SetSearchLabel( SearchLabel::EndWrapped
);
468 aCurGEF
= SetGetExpField( SwPosition( GetDoc()->GetNodes().GetEndOfContent() ) );
469 SvxSearchDialogWrapper::SetSearchLabel( SearchLabel::StartWrapped
);
472 } while( !bFnd
&& --nMaxDo
);
478 SvxSearchDialogWrapper::SetSearchLabel( SearchLabel::NavElementNotFound
);
482 CurrShell
aCurr( this );
483 SwCallLink
aLk( *this ); // watch Cursor-Moves
484 SwCursorSaveState
aSaveState( *m_pCurrentCursor
);
486 aFndGEF
.GetPosOfContent( rPos
);
487 m_pCurrentCursor
->DeleteMark();
489 bFnd
= !m_pCurrentCursor
->IsSelOvr();
491 UpdateCursor( SwCursorShell::SCROLLWIN
| SwCursorShell::CHKRANGE
|
492 SwCursorShell::READONLY
);
497 /// jump to next/previous index marker
498 bool SwCursorShell::GotoNxtPrvTOXMark( bool bNext
)
500 SvxSearchDialogWrapper::SetSearchLabel( SearchLabel::Empty
);
506 SwPosition
& rPos
= *m_pCurrentCursor
->GetPoint();
509 SwPosition
aFndPos( GetDoc()->GetNodes().GetEndOfContent() );
511 aFndPos
.Assign(SwNodeOffset(0));
512 SetGetExpField
aFndGEF( aFndPos
), aCurGEF( rPos
);
514 if( rPos
.GetNodeIndex() < GetDoc()->GetNodes().GetEndOfExtras().GetIndex() )
516 // also at collection use only the first frame
517 std::pair
<Point
, bool> const tmp(aPt
, false);
518 aCurGEF
.SetBodyPos( *rPos
.GetNode().
519 GetContentNode()->getLayoutFrame(GetLayout(), &rPos
, &tmp
));
522 const SwTextNode
* pTextNd
;
523 const SwTextTOXMark
* pTextTOX
;
524 sal_uInt32 nMaxItems
= GetDoc()->GetAttrPool().GetItemCount2( RES_TXTATR_TOXMARK
);
527 SvxSearchDialogWrapper::SetSearchLabel( SearchLabel::NavElementNotFound
);
532 for (const SfxPoolItem
* pItem
: GetDoc()->GetAttrPool().GetItemSurrogates(RES_TXTATR_TOXMARK
))
534 auto pToxMarkItem
= dynamic_cast<const SwTOXMark
*>(pItem
);
537 pTextTOX
= pToxMarkItem
->GetTextTOXMark();
540 pTextNd
= &pTextTOX
->GetTextNode();
541 if( !pTextNd
->GetNodes().IsDocNodes() )
543 std::pair
<Point
, bool> const tmp(aPt
, false);
544 const SwContentFrame
* pCFrame
= pTextNd
->getLayoutFrame(GetLayout(), nullptr, &tmp
);
545 if( pCFrame
&& ( IsReadOnlyAvailable() || !pCFrame
->IsProtected() ))
547 SetGetExpField
aCmp( *pTextNd
, *pTextTOX
);
548 aCmp
.SetBodyPos( *pCFrame
);
550 if( bNext
? ( aCurGEF
< aCmp
&& aCmp
< aFndGEF
)
551 : ( aCmp
< aCurGEF
&& aFndGEF
< aCmp
))
562 rPos
.Assign(SwNodeOffset(0), 0);
563 aCurGEF
= SetGetExpField( rPos
);
564 SvxSearchDialogWrapper::SetSearchLabel( SearchLabel::EndWrapped
);
568 aCurGEF
= SetGetExpField( SwPosition( GetDoc()->GetNodes().GetEndOfContent() ) );
569 SvxSearchDialogWrapper::SetSearchLabel( SearchLabel::StartWrapped
);
574 CurrShell
aCurr( this );
575 SwCallLink
aLk( *this ); // watch Cursor-Moves
576 SwCursorSaveState
aSaveState( *m_pCurrentCursor
);
578 aFndGEF
.GetPosOfContent( rPos
);
580 bFnd
= !m_pCurrentCursor
->IsSelOvr();
582 UpdateCursor( SwCursorShell::SCROLLWIN
| SwCursorShell::CHKRANGE
|
583 SwCursorShell::READONLY
);
587 /// traveling between marks
588 const SwTOXMark
& SwCursorShell::GotoTOXMark( const SwTOXMark
& rStart
,
591 CurrShell
aCurr( this );
592 SwCallLink
aLk( *this ); // watch Cursor-Moves
593 SwCursorSaveState
aSaveState( *m_pCurrentCursor
);
595 const SwTOXMark
& rNewMark
= GetDoc()->GotoTOXMark( rStart
, eDir
,
596 IsReadOnlyAvailable() );
598 SwPosition
& rPos
= *GetCursor()->GetPoint();
599 rPos
.Assign(rNewMark
.GetTextTOXMark()->GetTextNode(),
600 rNewMark
.GetTextTOXMark()->GetStart() );
602 if( !m_pCurrentCursor
->IsSelOvr() )
603 UpdateCursor( SwCursorShell::SCROLLWIN
| SwCursorShell::CHKRANGE
|
604 SwCursorShell::READONLY
);
609 /// jump to next/previous field type
610 static void lcl_MakeFieldLst(
611 SetGetExpFields
& rLst
,
612 const SwFieldType
& rFieldType
,
613 const bool bInReadOnly
,
614 const bool bChkInpFlag
= false )
616 // always search the 1. frame
618 std::vector
<SwFormatField
*> vFields
;
619 rFieldType
.GatherFields(vFields
, false);
620 for(SwFormatField
* pFormatField
: vFields
)
622 SwTextField
* pTextField
= pFormatField
->GetTextField();
623 if ( pTextField
!= nullptr
625 || static_cast<const SwSetExpField
*>(pTextField
->GetFormatField().GetField())->GetInputFlag() ) )
627 const SwTextNode
& rTextNode
= pTextField
->GetTextNode();
628 std::pair
<Point
, bool> const tmp(aPt
, false);
629 const SwContentFrame
* pCFrame
=
630 rTextNode
.getLayoutFrame(
631 rTextNode
.GetDoc().getIDocumentLayoutAccess().GetCurrentLayout(),
633 if ( pCFrame
!= nullptr
634 && ( bInReadOnly
|| !pCFrame
->IsProtected() ) )
636 std::unique_ptr
<SetGetExpField
> pNew(new SetGetExpField( rTextNode
, pTextField
));
637 pNew
->SetBodyPos( *pCFrame
);
638 rLst
.insert( std::move(pNew
) );
644 static SetGetExpFields::const_iterator
645 lcl_FindField(bool & o_rFound
, SetGetExpFields
const& rSrtLst
,
646 SwRootFrame
const *const pLayout
, SwTextNode
*const pTextNode
,
647 SwTextField
const *const pTextField
, SwPosition
const& rPos
,
648 sal_Int32
const nContentOffset
)
650 std::optional
<SetGetExpField
> oSrch
;
651 if (-1 == nContentOffset
)
653 oSrch
.emplace(rPos
.GetNode(), pTextField
, rPos
.GetContentIndex());
657 oSrch
.emplace(rPos
.GetNode(), pTextField
, nContentOffset
);
660 if (rPos
.GetNodeIndex() < pTextNode
->GetNodes().GetEndOfExtras().GetIndex())
662 // also at collection use only the first frame
664 std::pair
<Point
, bool> const tmp(aPt
, false);
665 oSrch
->SetBodyPos(*pTextNode
->getLayoutFrame(pLayout
, &rPos
, &tmp
));
668 SetGetExpFields::const_iterator it
= rSrtLst
.lower_bound(&*oSrch
);
670 o_rFound
= (it
!= rSrtLst
.end()) && (**it
== *oSrch
);
674 bool SwCursorShell::MoveFieldType(
675 const SwFieldType
* pFieldType
,
677 const SwFieldIds nResType
,
678 const bool bAddSetExpressionFieldsToInputFields
)
680 // sorted list of all fields
681 SetGetExpFields aSrtLst
;
685 if( SwFieldIds::Input
!= pFieldType
->Which() && !pFieldType
->HasWriterListeners() )
690 // found Modify object, add all fields to array
691 ::lcl_MakeFieldLst( aSrtLst
, *pFieldType
, IsReadOnlyAvailable() );
693 if( SwFieldIds::Input
== pFieldType
->Which() && bAddSetExpressionFieldsToInputFields
)
695 // there are hidden input fields in the set exp. fields
696 const SwFieldTypes
& rFieldTypes
= *mxDoc
->getIDocumentFieldsAccess().GetFieldTypes();
697 const size_t nSize
= rFieldTypes
.size();
698 for( size_t i
=0; i
< nSize
; ++i
)
700 pFieldType
= rFieldTypes
[ i
].get();
701 if ( SwFieldIds::SetExp
== pFieldType
->Which() )
703 ::lcl_MakeFieldLst( aSrtLst
, *pFieldType
, IsReadOnlyAvailable(), true );
710 const SwFieldTypes
& rFieldTypes
= *mxDoc
->getIDocumentFieldsAccess().GetFieldTypes();
711 const size_t nSize
= rFieldTypes
.size();
712 const bool bAllFieldTypes
= nResType
== SwFieldIds::Unknown
;
713 for( size_t i
=0; i
< nSize
; ++i
)
715 pFieldType
= rFieldTypes
[ i
].get();
716 if (bAllFieldTypes
|| nResType
== pFieldType
->Which())
718 ::lcl_MakeFieldLst( aSrtLst
, *pFieldType
, IsReadOnlyAvailable() );
724 if( aSrtLst
.empty() )
727 SetGetExpFields::const_iterator it
;
728 SwCursor
* pCursor
= getShellCursor( true );
730 // (1998): Always use field for search so that the right one is found as
731 // well some are in frames that are anchored to a paragraph that has a
733 const SwPosition
& rPos
= *pCursor
->GetPoint();
735 SwTextNode
* pTNd
= rPos
.GetNode().GetTextNode();
736 OSL_ENSURE( pTNd
, "No ContentNode" );
738 SwTextField
* pTextField
= pTNd
->GetFieldTextAttrAt(rPos
.GetContentIndex(), ::sw::GetTextAttrMode::Default
);
739 const bool bDelField
= ( pTextField
== nullptr );
740 sal_Int32 nContentOffset
= -1;
744 // create dummy for the search
745 SwFormatField
* pFormatField
= new SwFormatField( SwDateTimeField(
746 static_cast<SwDateTimeFieldType
*>(mxDoc
->getIDocumentFieldsAccess().GetSysFieldType( SwFieldIds::DateTime
) ) ) );
748 pTextField
= new SwTextField( *pFormatField
, rPos
.GetContentIndex(),
749 mxDoc
->IsClipBoard() );
750 pTextField
->ChgTextNode( pTNd
);
754 // the cursor might be anywhere inside the input field,
755 // but we will be searching for the field start
756 if (pTextField
->Which() == RES_TXTATR_INPUTFIELD
757 && rPos
.GetContentIndex() != pTextField
->GetStart())
758 nContentOffset
= pTextField
->GetStart();
761 it
= lcl_FindField(isSrch
, aSrtLst
,
762 GetLayout(), pTNd
, pTextField
, rPos
, nContentOffset
);
766 auto const pFormat(static_cast<SwFormatField
*>(&pTextField
->GetAttr()));
771 if( it
!= aSrtLst
.end() && isSrch
) // found
775 if( ++it
== aSrtLst
.end() )
776 return false; // already at the end
780 if( it
== aSrtLst
.begin() )
781 return false; // no more steps backward possible
789 if( it
== aSrtLst
.end() )
794 if( it
== aSrtLst
.begin() )
795 return false; // no more steps backward possible
800 const SetGetExpField
& rFnd
= **it
;
802 CurrShell
aCurr( this );
803 SwCallLink
aLk( *this ); // watch Cursor-Moves
804 SwCursorSaveState
aSaveState( *pCursor
);
806 rFnd
.GetPosOfContent( *pCursor
->GetPoint() );
807 bool bRet
= !m_pCurrentCursor
->IsSelOvr( SwCursorSelOverFlags::CheckNodeSection
|
808 SwCursorSelOverFlags::Toggle
);
810 UpdateCursor(SwCursorShell::SCROLLWIN
|SwCursorShell::CHKRANGE
|SwCursorShell::READONLY
);
814 bool SwCursorShell::GotoFootnoteAnchor(const SwTextFootnote
& rTextFootnote
)
816 if (SwWrtShell
* pWrtSh
= dynamic_cast<SwWrtShell
*>(this))
817 pWrtSh
->addCurrentPosition();
820 SwCursor
* pCursor
= getShellCursor(true);
822 CurrShell
aCurr(this);
823 SwCallLink
aLk(*this); // watch Cursor-Moves
824 SwCursorSaveState
aSaveState(*pCursor
);
826 pCursor
->GetPoint()->Assign(rTextFootnote
.GetTextNode(),
827 rTextFootnote
.GetStart());
828 bRet
= !pCursor
->IsSelOvr();
830 UpdateCursor(SwCursorShell::SCROLLWIN
|SwCursorShell::CHKRANGE
|SwCursorShell::READONLY
);
834 bool SwCursorShell::GotoFormatContentControl(const SwFormatContentControl
& rContentControl
)
836 std::shared_ptr
<SwContentControl
> pContentControl
= rContentControl
.GetContentControl();
837 const SwTextContentControl
* pTextContentControl
= pContentControl
->GetTextAttr();
838 if (!pTextContentControl
)
841 CurrShell
aCurr(this);
842 SwCallLink
aLink(*this);
844 SwCursor
* pCursor
= getShellCursor(true);
845 SwCursorSaveState
aSaveState(*pCursor
);
847 SwTextNode
* pTextNode
= pContentControl
->GetTextNode();
848 // Don't select the text attribute itself at the start.
849 sal_Int32 nStart
= pTextContentControl
->GetStart() + 1;
850 pCursor
->GetPoint()->Assign(*pTextNode
, nStart
);
853 // select contents for certain controls or conditions
854 if (pContentControl
->GetShowingPlaceHolder() || pContentControl
->GetCheckbox()
855 || pContentControl
->GetSelectedListItem() || pContentControl
->GetSelectedDate())
858 // Don't select the CH_TXTATR_BREAKWORD itself at the end.
859 sal_Int32 nEnd
= *pTextContentControl
->End() - 1;
860 pCursor
->GetMark()->Assign(*pTextNode
, nEnd
);
861 bRet
= !pCursor
->IsSelOvr();
868 UpdateCursor(SwCursorShell::SCROLLWIN
| SwCursorShell::CHKRANGE
869 | SwCursorShell::READONLY
);
876 * Go to the next (or previous) form control, based first on tabIndex and then paragraph position,
877 * where a tabIndex of 1 is first, 0 is last, and -1 is excluded.
879 void SwCursorShell::GotoFormControl(bool bNext
)
881 // (note: this only applies to modern content controls and legacy fieldmarks,
882 // since activeX richText controls aren't exposed to SW keystrokes)
884 struct FormControlSort
886 bool operator()(std::pair
<const SwPosition
&, sal_uInt32
> rLHS
,
887 std::pair
<const SwPosition
&, sal_uInt32
> rRHS
) const
889 assert(rLHS
.second
&& rRHS
.second
&& "tabIndex zero must be changed to SAL_MAX_UINT32");
890 //first compare tabIndexes where 1 has the priority.
891 if (rLHS
.second
< rRHS
.second
)
893 if (rLHS
.second
> rRHS
.second
)
896 // when tabIndexes are equal (and they usually are) then sort by paragraph position
897 return rLHS
.first
< rRHS
.first
;
900 std::map
<std::pair
<SwPosition
, sal_uInt32
>,
901 std::pair
<SwTextContentControl
*, sw::mark::IFieldmark
*>, FormControlSort
> aFormMap
;
903 // add all of the eligible modern Content Controls into a sorted map
904 SwContentControlManager
& rManager
= GetDoc()->GetContentControlManager();
905 for (size_t i
= 0; i
< rManager
.GetCount(); ++i
)
907 SwTextContentControl
* pTCC
= rManager
.UnsortedGet(i
);
908 if (!pTCC
|| !pTCC
->GetTextNode())
910 auto pCC
= pTCC
->GetContentControl().GetContentControl();
912 // -1 indicates the control should not participate in keyboard tab navigation
913 if (pCC
&& pCC
->GetTabIndex() == SAL_MAX_UINT32
)
916 const SwPosition
nPos(*pTCC
->GetTextNode(), pTCC
->GetStart());
918 // since 0 is the lowest priority (1 is the highest), and -1 has already been excluded,
919 // use SAL_MAX_UINT32 as zero's tabIndex so that automatic sorting is correct.
920 sal_uInt32 nTabIndex
= pCC
&& pCC
->GetTabIndex() ? pCC
->GetTabIndex() : SAL_MAX_UINT32
;
922 const std::pair
<SwTextContentControl
*, sw::mark::IFieldmark
*> pFormControl(pTCC
, nullptr);
923 aFormMap
[std::make_pair(nPos
, nTabIndex
)] = pFormControl
;
926 if (aFormMap
.begin() == aFormMap
.end())
928 // only legacy fields exist. Avoid reprocessing everything and use legacy code path.
929 GotoFieldmark(bNext
? GetFieldmarkAfter(/*Loop=*/true) : GetFieldmarkBefore(/*Loop=*/true));
933 // add all of the legacy form field controls into the sorted map
934 IDocumentMarkAccess
* pMarkAccess
= GetDoc()->getIDocumentMarkAccess();
935 for (auto it
= pMarkAccess
->getFieldmarksBegin(); it
!= pMarkAccess
->getFieldmarksEnd(); ++it
)
937 auto pFieldMark
= dynamic_cast<sw::mark::IFieldmark
*>(*it
);
939 std::pair
<SwTextContentControl
*, sw::mark::IFieldmark
*> pFormControl(nullptr, pFieldMark
);
940 // legacy form fields do not have (functional) tabIndexes - use lowest priority for them
941 aFormMap
[std::make_pair((*it
)->GetMarkStart(), SAL_MAX_UINT32
)] = pFormControl
;
944 if (aFormMap
.begin() == aFormMap
.end())
947 // Identify the current location in the document, and the current tab index priority
949 // A content control could contain a Fieldmark, so check for legacy fieldmarks first
950 sw::mark::IFieldmark
* pFieldMark
= GetCurrentFieldmark();
951 SwTextContentControl
* pTCC
= !pFieldMark
? CursorInsideContentControl() : nullptr;
953 auto pCC
= pTCC
? pTCC
->GetContentControl().GetContentControl() : nullptr;
954 const sal_Int32 nCurTabIndex
= pCC
&& pCC
->GetTabIndex() ? pCC
->GetTabIndex() : SAL_MAX_UINT32
;
956 SwPosition
nCurPos(*GetCursor()->GetPoint());
958 nCurPos
= pFieldMark
->GetMarkStart();
959 else if (pTCC
&& pTCC
->GetTextNode())
960 nCurPos
= SwPosition(*pTCC
->GetTextNode(), pTCC
->GetStart());
962 // Find the previous (or next) tab control and navigate to it
963 const std::pair
<SwPosition
, sal_uInt32
> nOldPos(nCurPos
, nCurTabIndex
);
965 // lower_bound acts like find, and returns a pointer to nFindPos if it exists,
966 // otherwise it will point to the previous entry.
967 auto aNewPos
= aFormMap
.lower_bound(nOldPos
);
968 if (bNext
&& aNewPos
!= aFormMap
.end())
970 else if (!bNext
&& aNewPos
!= aFormMap
.end() && aNewPos
->first
== nOldPos
)
972 // Found the current position - need to return previous
973 if (aNewPos
== aFormMap
.begin())
974 aNewPos
= aFormMap
.end(); // prepare to loop around
979 if (aNewPos
== aFormMap
.end())
981 // Loop around to the other side
983 aNewPos
= aFormMap
.begin();
988 // the entry contains a pointer to either a Content Control (first) or Fieldmark (second)
989 if (aNewPos
->second
.first
)
991 auto& rFCC
= static_cast<SwFormatContentControl
&>(aNewPos
->second
.first
->GetAttr());
992 GotoFormatContentControl(rFCC
);
996 assert(aNewPos
->second
.second
);
997 GotoFieldmark(aNewPos
->second
.second
);
1001 bool SwCursorShell::GotoFormatField( const SwFormatField
& rField
)
1003 SwTextField
const*const pTextField(rField
.GetTextField());
1005 || (GetLayout()->IsHideRedlines()
1006 && sw::IsFieldDeletedInModel(
1007 GetDoc()->getIDocumentRedlineAccess(), *pTextField
)))
1010 CurrShell
aCurr( this );
1011 SwCallLink
aLk( *this ); // watch Cursor-Moves
1013 SwCursor
* pCursor
= getShellCursor( true );
1014 SwCursorSaveState
aSaveState( *pCursor
);
1016 SwTextNode
* pTNd
= pTextField
->GetpTextNode();
1017 pCursor
->GetPoint()->Assign(*pTNd
, pTextField
->GetStart() );
1019 bool bRet
= !pCursor
->IsSelOvr();
1021 UpdateCursor(SwCursorShell::SCROLLWIN
|SwCursorShell::CHKRANGE
|SwCursorShell::READONLY
);
1025 SwTextField
* SwCursorShell::GetTextFieldAtPos(
1026 const SwPosition
* pPos
,
1027 ::sw::GetTextAttrMode
const eMode
)
1029 SwTextField
* pTextField
= nullptr;
1031 SwTextNode
* const pNode
= pPos
->GetNode().GetTextNode();
1032 if ( pNode
!= nullptr )
1034 pTextField
= pNode
->GetFieldTextAttrAt(pPos
->GetContentIndex(), eMode
);
1040 SwTextField
* SwCursorShell::GetTextFieldAtCursor(
1041 const SwPaM
* pCursor
,
1042 ::sw::GetTextAttrMode
const eMode
)
1044 SwTextField
* pTextField
= GetTextFieldAtPos(pCursor
->Start(), eMode
);
1046 || pCursor
->Start()->GetNode() != pCursor
->End()->GetNode() )
1049 SwTextField
* pFieldAtCursor
= nullptr;
1050 const sal_Int32 nTextFieldLength
=
1051 pTextField
->End() != nullptr
1052 ? *(pTextField
->End()) - pTextField
->GetStart()
1054 if ( ( pCursor
->End()->GetContentIndex() - pCursor
->Start()->GetContentIndex() ) <= nTextFieldLength
)
1056 pFieldAtCursor
= pTextField
;
1059 return pFieldAtCursor
;
1062 SwField
* SwCursorShell::GetFieldAtCursor(
1063 const SwPaM
*const pCursor
,
1064 const bool bIncludeInputFieldAtStart
)
1066 SwTextField
*const pField(GetTextFieldAtCursor(pCursor
,
1067 bIncludeInputFieldAtStart
? ::sw::GetTextAttrMode::Default
: ::sw::GetTextAttrMode::Expand
));
1069 ? const_cast<SwField
*>(pField
->GetFormatField().GetField())
1073 SwField
* SwCursorShell::GetCurField( const bool bIncludeInputFieldAtStart
) const
1075 SwPaM
* pCursor
= GetCursor();
1076 if ( pCursor
->IsMultiSelection() )
1078 // multi selection not handled.
1082 SwField
* pCurField
= GetFieldAtCursor( pCursor
, bIncludeInputFieldAtStart
);
1083 if ( pCurField
!= nullptr
1084 && SwFieldIds::Table
== pCurField
->GetTyp()->Which() )
1086 // table formula? convert internal name into external
1087 const SwTableNode
* pTableNd
= IsCursorInTable();
1088 static_cast<SwTableField
*>(pCurField
)->PtrToBoxNm( pTableNd
? &pTableNd
->GetTable() : nullptr );
1094 bool SwCursorShell::CursorInsideInputField() const
1096 for(SwPaM
& rCursor
: GetCursor()->GetRingContainer())
1098 if (dynamic_cast<const SwTextInputField
*>(GetTextFieldAtCursor(&rCursor
, ::sw::GetTextAttrMode::Parent
)))
1104 SwTextContentControl
* SwCursorShell::CursorInsideContentControl() const
1106 for (SwPaM
& rCursor
: GetCursor()->GetRingContainer())
1108 const SwPosition
* pStart
= rCursor
.Start();
1109 SwTextNode
* pTextNode
= pStart
->GetNode().GetTextNode();
1115 sal_Int32 nIndex
= pStart
->GetContentIndex();
1116 if (SwTextAttr
* pAttr
= pTextNode
->GetTextAttrAt(nIndex
, RES_TXTATR_CONTENTCONTROL
, ::sw::GetTextAttrMode::Parent
))
1118 return static_txtattr_cast
<SwTextContentControl
*>(pAttr
);
1125 bool SwCursorShell::PosInsideInputField( const SwPosition
& rPos
)
1127 return dynamic_cast<const SwTextInputField
*>(GetTextFieldAtPos(&rPos
, ::sw::GetTextAttrMode::Parent
)) != nullptr;
1130 bool SwCursorShell::DocPtInsideInputField( const Point
& rDocPt
) const
1132 SwPosition
aPos( *(GetCursor()->Start()) );
1133 Point
aDocPt( rDocPt
);
1134 if ( GetLayout()->GetModelPositionForViewPoint( &aPos
, aDocPt
) )
1136 return PosInsideInputField( aPos
);
1141 sal_Int32
SwCursorShell::StartOfInputFieldAtPos( const SwPosition
& rPos
)
1143 const SwTextInputField
* pTextInputField
= dynamic_cast<const SwTextInputField
*>(GetTextFieldAtPos(&rPos
, ::sw::GetTextAttrMode::Default
));
1144 assert(pTextInputField
!= nullptr
1145 && "<SwEditShell::StartOfInputFieldAtPos(..)> - no Input Field at given position");
1146 return pTextInputField
->GetStart();
1149 sal_Int32
SwCursorShell::EndOfInputFieldAtPos( const SwPosition
& rPos
)
1151 const SwTextInputField
* pTextInputField
= dynamic_cast<const SwTextInputField
*>(GetTextFieldAtPos(&rPos
, ::sw::GetTextAttrMode::Default
));
1152 assert(pTextInputField
!= nullptr
1153 && "<SwEditShell::EndOfInputFieldAtPos(..)> - no Input Field at given position");
1154 return *(pTextInputField
->End());
1157 void SwCursorShell::GotoOutline( SwOutlineNodes::size_type nIdx
)
1159 SwCursor
* pCursor
= getShellCursor( true );
1161 CurrShell
aCurr( this );
1162 SwCallLink
aLk( *this ); // watch Cursor-Moves
1163 SwCursorSaveState
aSaveState( *pCursor
);
1165 const SwNodes
& rNds
= GetDoc()->GetNodes();
1166 SwTextNode
* pTextNd
= rNds
.GetOutLineNds()[ nIdx
]->GetTextNode();
1167 pCursor
->GetPoint()->Assign(*pTextNd
);
1169 if( !pCursor
->IsSelOvr() )
1170 UpdateCursor(SwCursorShell::SCROLLWIN
|SwCursorShell::CHKRANGE
|SwCursorShell::READONLY
);
1173 bool SwCursorShell::GotoOutline( const OUString
& rName
)
1175 SwCursor
* pCursor
= getShellCursor( true );
1177 CurrShell
aCurr( this );
1178 SwCallLink
aLk( *this ); // watch Cursor-Moves
1179 SwCursorSaveState
aSaveState( *pCursor
);
1182 if (mxDoc
->GotoOutline(*pCursor
->GetPoint(), rName
, GetLayout())
1183 && !pCursor
->IsSelOvr())
1185 UpdateCursor(SwCursorShell::SCROLLWIN
|SwCursorShell::CHKRANGE
|SwCursorShell::READONLY
);
1191 /// jump to next node with outline num.
1192 bool SwCursorShell::GotoNextOutline()
1194 const SwNodes
& rNds
= GetDoc()->GetNodes();
1196 if ( rNds
.GetOutLineNds().empty() )
1198 SvxSearchDialogWrapper::SetSearchLabel( SearchLabel::NavElementNotFound
);
1202 SwCursor
* pCursor
= getShellCursor( true );
1203 SwNode
* pNd
= &(pCursor
->GetPointNode());
1204 SwOutlineNodes::size_type nPos
;
1205 bool bUseFirst
= !rNds
.GetOutLineNds().Seek_Entry( pNd
, &nPos
);
1206 SwOutlineNodes::size_type
const nStartPos(nPos
);
1214 if (rNds
.GetOutLineNds().size() <= nPos
)
1225 if (nPos
== nStartPos
)
1227 SvxSearchDialogWrapper::SetSearchLabel( SearchLabel::NavElementNotFound
);
1232 pNd
= rNds
.GetOutLineNds()[ nPos
];
1234 while (!sw::IsParaPropsNode(*GetLayout(), *pNd
->GetTextNode()));
1236 if (nPos
< nStartPos
)
1238 SvxSearchDialogWrapper::SetSearchLabel( SearchLabel::EndWrapped
);
1242 SvxSearchDialogWrapper::SetSearchLabel( SearchLabel::Empty
);
1245 CurrShell
aCurr( this );
1246 SwCallLink
aLk( *this ); // watch Cursor-Moves
1247 SwCursorSaveState
aSaveState( *pCursor
);
1248 pCursor
->GetPoint()->Assign(*pNd
);
1250 bool bRet
= !pCursor
->IsSelOvr();
1252 UpdateCursor(SwCursorShell::SCROLLWIN
|SwCursorShell::CHKRANGE
|SwCursorShell::READONLY
);
1256 /// jump to previous node with outline num.
1257 bool SwCursorShell::GotoPrevOutline()
1259 const SwNodes
& rNds
= GetDoc()->GetNodes();
1261 if ( rNds
.GetOutLineNds().empty() )
1263 SvxSearchDialogWrapper::SetSearchLabel( SearchLabel::NavElementNotFound
);
1267 SwCursor
* pCursor
= getShellCursor( true );
1268 SwNode
* pNd
= &(pCursor
->GetPointNode());
1269 SwOutlineNodes::size_type nPos
;
1270 (void)rNds
.GetOutLineNds().Seek_Entry(pNd
, &nPos
);
1271 SwOutlineNodes::size_type
const nStartPos(nPos
);
1277 nPos
= rNds
.GetOutLineNds().size() - 1;
1283 if (nPos
== nStartPos
)
1289 pNd
= rNds
.GetOutLineNds()[ nPos
];
1291 while (!sw::IsParaPropsNode(*GetLayout(), *pNd
->GetTextNode()));
1295 SvxSearchDialogWrapper::SetSearchLabel( SearchLabel::NavElementNotFound
);
1299 if (nStartPos
< nPos
)
1301 SvxSearchDialogWrapper::SetSearchLabel( SearchLabel::StartWrapped
);
1305 SvxSearchDialogWrapper::SetSearchLabel( SearchLabel::Empty
);
1307 CurrShell
aCurr( this );
1308 SwCallLink
aLk( *this ); // watch Cursor-Moves
1309 SwCursorSaveState
aSaveState( *pCursor
);
1310 pCursor
->GetPoint()->Assign(*pNd
);
1312 bool bRet
= !pCursor
->IsSelOvr();
1314 UpdateCursor(SwCursorShell::SCROLLWIN
|SwCursorShell::CHKRANGE
|SwCursorShell::READONLY
);
1318 /// search "outline position" before previous outline node at given level
1319 SwOutlineNodes::size_type
SwCursorShell::GetOutlinePos(sal_uInt8 nLevel
, SwPaM
* pPaM
)
1321 SwPaM
* pCursor
= pPaM
? pPaM
: getShellCursor(true);
1322 const SwNodes
& rNds
= GetDoc()->GetNodes();
1324 SwNode
* pNd
= &(pCursor
->GetPointNode());
1325 SwOutlineNodes::size_type nPos
;
1326 if( rNds
.GetOutLineNds().Seek_Entry( pNd
, &nPos
))
1327 nPos
++; // is at correct position; take next for while
1329 while( nPos
-- ) // check the one in front of the current
1331 pNd
= rNds
.GetOutLineNds()[ nPos
];
1333 if (sw::IsParaPropsNode(*GetLayout(), *pNd
->GetTextNode())
1334 && pNd
->GetTextNode()->GetAttrOutlineLevel()-1 <= nLevel
)
1336 if (pNd
->GetIndex() < rNds
.GetEndOfExtras().GetIndex()
1337 && pCursor
->GetPointNode().GetIndex() > rNds
.GetEndOfExtras().GetIndex())
1339 // node found in extras but cursor position is not in extras
1340 return SwOutlineNodes::npos
;
1345 return SwOutlineNodes::npos
; // no more left
1348 void SwCursorShell::MakeOutlineSel(SwOutlineNodes::size_type nSttPos
, SwOutlineNodes::size_type nEndPos
,
1349 bool bWithChildren
, bool bKillPams
)
1351 const SwNodes
& rNds
= GetDoc()->GetNodes();
1352 const SwOutlineNodes
& rOutlNds
= rNds
.GetOutLineNds();
1353 if( rOutlNds
.empty() )
1356 CurrShell
aCurr( this );
1357 SwCallLink
aLk( *this ); // watch Cursor-Moves
1359 if( nSttPos
> nEndPos
) // parameters switched?
1361 OSL_ENSURE( false, "Start > End for array access" );
1362 std::swap(nSttPos
, nEndPos
);
1365 SwNode
* pSttNd
= rOutlNds
[ nSttPos
];
1366 SwNode
* pEndNd
= rOutlNds
[ nEndPos
];
1370 const int nLevel
= pEndNd
->GetTextNode()->GetAttrOutlineLevel()-1;
1371 for( ++nEndPos
; nEndPos
< rOutlNds
.size(); ++nEndPos
)
1373 pEndNd
= rOutlNds
[ nEndPos
];
1374 const int nNxtLevel
= pEndNd
->GetTextNode()->GetAttrOutlineLevel()-1;
1375 if( nNxtLevel
<= nLevel
)
1376 break; // EndPos is now on the next one
1379 // if without children then set onto next one
1380 else if( ++nEndPos
< rOutlNds
.size() )
1381 pEndNd
= rOutlNds
[ nEndPos
];
1383 if( nEndPos
== rOutlNds
.size() ) // no end found
1384 pEndNd
= &rNds
.GetEndOfContent();
1389 SwCursorSaveState
aSaveState( *m_pCurrentCursor
);
1391 // set end to the end of the previous content node
1392 m_pCurrentCursor
->GetPoint()->Assign(*pSttNd
);
1393 m_pCurrentCursor
->SetMark();
1394 m_pCurrentCursor
->GetPoint()->Assign(*pEndNd
);
1395 m_pCurrentCursor
->Move( fnMoveBackward
, GoInNode
); // end of predecessor
1397 // and everything is already selected
1398 bool bRet
= !m_pCurrentCursor
->IsSelOvr();
1400 UpdateCursor(SwCursorShell::SCROLLWIN
|SwCursorShell::CHKRANGE
|SwCursorShell::READONLY
);
1403 /// jump to reference marker
1404 bool SwCursorShell::GotoRefMark( const OUString
& rRefMark
, sal_uInt16 nSubType
,
1407 CurrShell
aCurr( this );
1408 SwCallLink
aLk( *this ); // watch Cursor-Moves
1409 SwCursorSaveState
aSaveState( *m_pCurrentCursor
);
1411 sal_Int32 nPos
= -1;
1412 SwTextNode
* pTextNd
= SwGetRefFieldType::FindAnchor( GetDoc(), rRefMark
,
1413 nSubType
, nSeqNo
, &nPos
, nullptr, GetLayout());
1414 if( !pTextNd
|| !pTextNd
->GetNodes().IsDocNodes() )
1417 m_pCurrentCursor
->GetPoint()->Assign(*pTextNd
, nPos
);
1419 if( m_pCurrentCursor
->IsSelOvr() )
1422 UpdateCursor(SwCursorShell::SCROLLWIN
|SwCursorShell::CHKRANGE
|SwCursorShell::READONLY
);
1426 bool SwCursorShell::IsPageAtPos( const Point
&rPt
) const
1429 return nullptr != GetLayout()->GetPageAtPos( rPt
);
1433 bool SwCursorShell::GetContentAtPos( const Point
& rPt
,
1434 SwContentAtPos
& rContentAtPos
,
1436 SwRect
* pFieldRect
)
1438 CurrShell
aCurr( this );
1443 rContentAtPos
.eContentAtPos
= IsAttrAtPos::NONE
;
1444 rContentAtPos
.aFnd
.pField
= nullptr;
1449 SwPosition
aPos( *m_pCurrentCursor
->GetPoint() );
1451 SwTextNode
* pTextNd
;
1452 SwCursorMoveState aTmpState
;
1453 aTmpState
.m_bFieldInfo
= true;
1454 aTmpState
.m_bExactOnly
= !( IsAttrAtPos::Outline
& rContentAtPos
.eContentAtPos
);
1455 aTmpState
.m_bContentCheck
= bool(IsAttrAtPos::ContentCheck
& rContentAtPos
.eContentAtPos
);
1456 aTmpState
.m_bSetInReadOnly
= IsReadOnlyAvailable();
1458 SwSpecialPos aSpecialPos
;
1459 aTmpState
.m_pSpecialPos
= ( IsAttrAtPos::SmartTag
& rContentAtPos
.eContentAtPos
) ?
1460 &aSpecialPos
: nullptr;
1462 const bool bCursorFoundExact
= GetLayout()->GetModelPositionForViewPoint( &aPos
, aPt
, &aTmpState
);
1463 pTextNd
= aPos
.GetNode().GetTextNode();
1465 const SwNodes
& rNds
= GetDoc()->GetNodes();
1467 && IsAttrAtPos::Outline
& rContentAtPos
.eContentAtPos
1468 && !rNds
.GetOutLineNds().empty() )
1470 // only for nodes in outline nodes
1471 SwOutlineNodes::size_type nPos
= 0;
1472 bool bFoundOutline
= rNds
.GetOutLineNds().Seek_Entry(pTextNd
, &nPos
);
1473 if (!bFoundOutline
&& nPos
&& (IsAttrAtPos::AllowContaining
& rContentAtPos
.eContentAtPos
))
1475 // nPos points to the first found outline node not before pTextNd, or to end();
1476 // when bFoundOutline is false, and nPos is not 0, it means that there were
1477 // outline nodes before pTextNd, and nPos-1 points to the last of those.
1478 pTextNd
= rNds
.GetOutLineNds()[nPos
- 1]->GetTextNode();
1479 bFoundOutline
= true;
1483 rContentAtPos
.eContentAtPos
= IsAttrAtPos::Outline
;
1484 rContentAtPos
.sStr
= sw::GetExpandTextMerged(GetLayout(), *pTextNd
, true, false, ExpandMode::ExpandFootnote
);
1485 rContentAtPos
.aFnd
.pNode
= pTextNd
;
1489 else if ( IsAttrAtPos::ContentCheck
& rContentAtPos
.eContentAtPos
1490 && bCursorFoundExact
)
1495 && IsAttrAtPos::NumLabel
& rContentAtPos
.eContentAtPos
)
1497 bRet
= aTmpState
.m_bInNumPortion
;
1498 rContentAtPos
.aFnd
.pNode
= sw::GetParaPropsNode(*GetLayout(), aPos
.GetNode());
1500 Size
aSizeLogic(aTmpState
.m_nInNumPortionOffset
, 0);
1501 Size aSizePixel
= GetWin()->LogicToPixel(aSizeLogic
);
1502 rContentAtPos
.nDist
= aSizePixel
.Width();
1504 else if( bCursorFoundExact
&& pTextNd
)
1506 SwContentFrame
*pFrame(nullptr);
1507 if( !aTmpState
.m_bPosCorr
)
1509 SwTextAttr
* pTextAttr
;
1510 if ( IsAttrAtPos::SmartTag
& rContentAtPos
.eContentAtPos
1511 && !aTmpState
.m_bFootnoteNoInfo
)
1513 const SwWrongList
* pSmartTagList
= pTextNd
->GetSmartTags();
1514 sal_Int32 nCurrent
= aPos
.GetContentIndex();
1515 const sal_Int32 nBegin
= nCurrent
;
1518 if (pSmartTagList
&& pSmartTagList
->InWrongWord(nCurrent
, nLen
) && !pTextNd
->IsSymbolAt(nBegin
))
1520 const sal_uInt16 nIndex
= pSmartTagList
->GetWrongPos( nBegin
);
1521 const SwWrongList
* pSubList
= pSmartTagList
->SubList( nIndex
);
1524 nCurrent
= aTmpState
.m_pSpecialPos
->nCharOfst
;
1526 if ( pSubList
->InWrongWord( nCurrent
, nLen
) )
1532 if( bRet
&& bSetCursor
)
1534 SwCursorSaveState
aSaveState( *m_pCurrentCursor
);
1535 SwCallLink
aLk( *this ); // watch Cursor-Moves
1536 m_pCurrentCursor
->DeleteMark();
1537 *m_pCurrentCursor
->GetPoint() = aPos
;
1538 if( m_pCurrentCursor
->IsSelOvr( SwCursorSelOverFlags::CheckNodeSection
| SwCursorSelOverFlags::Toggle
) )
1545 rContentAtPos
.eContentAtPos
= IsAttrAtPos::SmartTag
;
1547 std::pair
<Point
, bool> tmp(aPt
, true);
1550 pFrame
= pTextNd
->getLayoutFrame(GetLayout(), nullptr, &tmp
);
1552 pFrame
->GetCharRect( *pFieldRect
, aPos
, &aTmpState
);
1559 && ( IsAttrAtPos::Field
| IsAttrAtPos::ClickField
) & rContentAtPos
.eContentAtPos
1560 && !aTmpState
.m_bFootnoteNoInfo
)
1562 pTextAttr
= pTextNd
->GetFieldTextAttrAt( aPos
.GetContentIndex() );
1563 const SwField
* pField
= pTextAttr
!= nullptr
1564 ? pTextAttr
->GetFormatField().GetField()
1566 if ( IsAttrAtPos::ClickField
& rContentAtPos
.eContentAtPos
1567 && pField
&& !pField
->HasClickHdl() )
1576 std::pair
<Point
, bool> tmp(aPt
, true);
1577 pFrame
= pTextNd
->getLayoutFrame(GetLayout(), nullptr, &tmp
);
1580 //tdf#116397 now that we looking for the bounds of the field drop the SmartTag
1581 //index within field setting so we don't the bounds of the char within the field
1582 SwSpecialPos
* pSpecialPos
= aTmpState
.m_pSpecialPos
;
1583 aTmpState
.m_pSpecialPos
= nullptr;
1584 pFrame
->GetCharRect( *pFieldRect
, aPos
, &aTmpState
);
1585 aTmpState
.m_pSpecialPos
= pSpecialPos
;
1591 SwCallLink
aLk( *this ); // watch Cursor-Moves
1592 SwCursorSaveState
aSaveState( *m_pCurrentCursor
);
1593 m_pCurrentCursor
->DeleteMark();
1594 *m_pCurrentCursor
->GetPoint() = aPos
;
1595 if( m_pCurrentCursor
->IsSelOvr() )
1597 // allow click fields in protected sections
1598 // only placeholder is not possible
1599 if( IsAttrAtPos::Field
& rContentAtPos
.eContentAtPos
1600 || SwFieldIds::JumpEdit
== pField
->Which() )
1606 else if( SwFieldIds::Table
== pField
->Which() &&
1607 static_cast<const SwTableField
*>(pField
)->IsIntrnlName() )
1609 // create from internal (for CORE) the external
1611 const SwTableNode
* pTableNd
= pTextNd
->FindTableNode();
1612 if( pTableNd
) // is in a table
1613 const_cast<SwTableField
*>(static_cast<const SwTableField
*>(pField
))->PtrToBoxNm( &pTableNd
->GetTable() );
1619 rContentAtPos
.aFnd
.pField
= pField
;
1620 rContentAtPos
.pFndTextAttr
= pTextAttr
;
1621 rContentAtPos
.eContentAtPos
= IsAttrAtPos::Field
;
1626 if( !bRet
&& IsAttrAtPos::FormControl
& rContentAtPos
.eContentAtPos
)
1628 IDocumentMarkAccess
* pMarksAccess
= GetDoc()->getIDocumentMarkAccess( );
1629 sw::mark::IFieldmark
* pFieldBookmark
= pMarksAccess
->getInnerFieldmarkFor(aPos
);
1630 if (bCursorFoundExact
&& pFieldBookmark
)
1632 rContentAtPos
.eContentAtPos
= IsAttrAtPos::FormControl
;
1633 rContentAtPos
.aFnd
.pFieldmark
= pFieldBookmark
;
1638 if (!bRet
&& rContentAtPos
.eContentAtPos
& IsAttrAtPos::ContentControl
)
1640 SwTextAttr
* pAttr
= pTextNd
->GetTextAttrAt(
1641 aPos
.GetContentIndex(), RES_TXTATR_CONTENTCONTROL
, ::sw::GetTextAttrMode::Parent
);
1644 rContentAtPos
.eContentAtPos
= IsAttrAtPos::ContentControl
;
1645 rContentAtPos
.pFndTextAttr
= pAttr
;
1650 if( !bRet
&& IsAttrAtPos::Ftn
& rContentAtPos
.eContentAtPos
)
1652 if( aTmpState
.m_bFootnoteNoInfo
)
1654 // over the footnote's char
1658 *m_pCurrentCursor
->GetPoint() = aPos
;
1659 if( !GotoFootnoteAnchor() )
1663 rContentAtPos
.eContentAtPos
= IsAttrAtPos::Ftn
;
1665 else if ( nullptr != ( pTextAttr
= pTextNd
->GetTextAttrForCharAt(
1666 aPos
.GetContentIndex(), RES_TXTATR_FTN
)) )
1671 if (SwWrtShell
* pWrtSh
= dynamic_cast<SwWrtShell
*>(this))
1672 pWrtSh
->addCurrentPosition();
1674 SwCallLink
aLk( *this ); // watch Cursor-Moves
1675 SwCursorSaveState
aSaveState( *m_pCurrentCursor
);
1676 m_pCurrentCursor
->GetPoint()->Assign( *static_cast<SwTextFootnote
*>(pTextAttr
)->GetStartNode() );
1677 SwContentNode
* pCNd
= GetDoc()->GetNodes().GoNextSection(
1678 m_pCurrentCursor
->GetPoint(),
1679 true, !IsReadOnlyAvailable() );
1683 if( m_pCurrentCursor
->IsSelOvr( SwCursorSelOverFlags::CheckNodeSection
|
1684 SwCursorSelOverFlags::Toggle
))
1695 rContentAtPos
.eContentAtPos
= IsAttrAtPos::Ftn
;
1696 rContentAtPos
.pFndTextAttr
= pTextAttr
;
1697 rContentAtPos
.aFnd
.pAttr
= &pTextAttr
->GetAttr();
1701 std::pair
<Point
, bool> tmp(aPt
, true);
1702 pFrame
= pTextNd
->getLayoutFrame(GetLayout(), nullptr, &tmp
);
1704 pFrame
->GetCharRect( *pFieldRect
, aPos
, &aTmpState
);
1711 && ( IsAttrAtPos::ToxMark
| IsAttrAtPos::RefMark
) & rContentAtPos
.eContentAtPos
1712 && !aTmpState
.m_bFootnoteNoInfo
)
1714 pTextAttr
= nullptr;
1715 if( IsAttrAtPos::ToxMark
& rContentAtPos
.eContentAtPos
)
1717 std::vector
<SwTextAttr
*> const marks(
1718 pTextNd
->GetTextAttrsAt(
1719 aPos
.GetContentIndex(), RES_TXTATR_TOXMARK
));
1721 { // hmm... can only return 1 here
1722 pTextAttr
= *marks
.begin();
1727 IsAttrAtPos::RefMark
& rContentAtPos
.eContentAtPos
)
1729 std::vector
<SwTextAttr
*> const marks(
1730 pTextNd
->GetTextAttrsAt(
1731 aPos
.GetContentIndex(), RES_TXTATR_REFMARK
));
1733 { // hmm... can only return 1 here
1734 pTextAttr
= *marks
.begin();
1743 SwCallLink
aLk( *this ); // watch Cursor-Moves
1744 SwCursorSaveState
aSaveState( *m_pCurrentCursor
);
1745 m_pCurrentCursor
->DeleteMark();
1746 *m_pCurrentCursor
->GetPoint() = aPos
;
1747 if( m_pCurrentCursor
->IsSelOvr( SwCursorSelOverFlags::CheckNodeSection
| SwCursorSelOverFlags::Toggle
) )
1755 const sal_Int32
* pEnd
= pTextAttr
->GetEnd();
1757 rContentAtPos
.sStr
=
1758 pTextNd
->GetExpandText(GetLayout(), pTextAttr
->GetStart(), *pEnd
- pTextAttr
->GetStart());
1759 else if( RES_TXTATR_TOXMARK
== pTextAttr
->Which())
1760 rContentAtPos
.sStr
=
1761 pTextAttr
->GetTOXMark().GetAlternativeText();
1763 rContentAtPos
.eContentAtPos
=
1764 RES_TXTATR_TOXMARK
== pTextAttr
->Which()
1765 ? IsAttrAtPos::ToxMark
1766 : IsAttrAtPos::RefMark
;
1767 rContentAtPos
.pFndTextAttr
= pTextAttr
;
1768 rContentAtPos
.aFnd
.pAttr
= &pTextAttr
->GetAttr();
1770 std::pair
<Point
, bool> tmp(aPt
, true);
1773 pFrame
= pTextNd
->getLayoutFrame(GetLayout(), nullptr, &tmp
);
1775 pFrame
->GetCharRect( *pFieldRect
, aPos
, &aTmpState
);
1782 && IsAttrAtPos::InetAttr
& rContentAtPos
.eContentAtPos
1783 && !aTmpState
.m_bFootnoteNoInfo
)
1785 sal_Int32 index
= aPos
.GetContentIndex();
1786 pTextAttr
= pTextNd
->GetTextAttrAt(index
, RES_TXTATR_INETFMT
);
1788 if(!pTextAttr
&& index
> 0)
1789 pTextAttr
= pTextNd
->GetTextAttrAt(index
- 1, RES_TXTATR_INETFMT
);
1790 // "detect" only INetAttrs with URLs
1791 if( pTextAttr
&& !pTextAttr
->GetINetFormat().GetValue().isEmpty() )
1796 SwCursorSaveState
aSaveState( *m_pCurrentCursor
);
1797 SwCallLink
aLk( *this ); // watch Cursor-Moves
1798 m_pCurrentCursor
->DeleteMark();
1799 *m_pCurrentCursor
->GetPoint() = aPos
;
1800 if( m_pCurrentCursor
->IsSelOvr( SwCursorSelOverFlags::CheckNodeSection
|
1801 SwCursorSelOverFlags::Toggle
) )
1808 const sal_Int32 nSt
= pTextAttr
->GetStart();
1809 const sal_Int32 nEnd
= *pTextAttr
->End();
1811 rContentAtPos
.sStr
= pTextNd
->GetExpandText(GetLayout(), nSt
, nEnd
-nSt
);
1813 rContentAtPos
.aFnd
.pAttr
= &pTextAttr
->GetAttr();
1814 rContentAtPos
.eContentAtPos
= IsAttrAtPos::InetAttr
;
1815 rContentAtPos
.pFndTextAttr
= pTextAttr
;
1819 std::pair
<Point
, bool> tmp(aPt
, true);
1820 pFrame
= pTextNd
->getLayoutFrame(GetLayout(), nullptr, &tmp
);
1823 //get bounding box of range
1825 SwPosition
aStartPos(*pTextNd
, nSt
);
1826 pFrame
->GetCharRect(aStart
, aStartPos
, &aTmpState
);
1828 SwPosition
aEndPos(*pTextNd
, nEnd
);
1829 pFrame
->GetCharRect(aEnd
, aEndPos
, &aTmpState
);
1830 if (aStart
.Top() != aEnd
.Top() || aStart
.Bottom() != aEnd
.Bottom())
1832 aStart
.Left(pFrame
->getFrameArea().Left());
1833 aEnd
.Right(pFrame
->getFrameArea().Right());
1835 *pFieldRect
= aStart
.Union(aEnd
);
1842 if( !bRet
&& IsAttrAtPos::Redline
& rContentAtPos
.eContentAtPos
)
1844 const SwRangeRedline
* pRedl
= GetDoc()->getIDocumentRedlineAccess().GetRedline(aPos
, nullptr);
1848 rContentAtPos
.aFnd
.pRedl
= pRedl
;
1849 rContentAtPos
.eContentAtPos
= IsAttrAtPos::Redline
;
1850 rContentAtPos
.pFndTextAttr
= nullptr;
1855 std::pair
<Point
, bool> tmp(aPt
, true);
1856 pFrame
= pTextNd
->getLayoutFrame(GetLayout(), nullptr, &tmp
);
1859 // not sure if this should be limited to one
1860 // paragraph, or mark the entire redline; let's
1861 // leave it limited to one for now...
1864 pRedl
->CalcStartEnd(pTextNd
->GetIndex(), nStart
, nEnd
);
1865 if (nStart
== COMPLETE_STRING
)
1867 // consistency: found pRedl, so there must be
1868 // something in pTextNd
1869 assert(nEnd
!= COMPLETE_STRING
);
1872 if (nEnd
== COMPLETE_STRING
)
1874 nEnd
= pTextNd
->Len();
1876 //get bounding box of range
1878 pFrame
->GetCharRect(aStart
, SwPosition(*pTextNd
, nStart
), &aTmpState
);
1880 pFrame
->GetCharRect(aEnd
, SwPosition(*pTextNd
, nEnd
), &aTmpState
);
1881 if (aStart
.Top() != aEnd
.Top() || aStart
.Bottom() != aEnd
.Bottom())
1883 aStart
.Left(pFrame
->getFrameArea().Left());
1884 aEnd
.Right(pFrame
->getFrameArea().Right());
1886 *pFieldRect
= aStart
.Union(aEnd
);
1893 if( !bRet
&& ( ( IsAttrAtPos::TableRedline
& rContentAtPos
.eContentAtPos
) ||
1894 ( IsAttrAtPos::TableColRedline
& rContentAtPos
.eContentAtPos
) ) )
1896 const SwTableNode
* pTableNd
;
1897 const SwTableBox
* pBox
;
1898 const SwTableLine
* pTableLine
;
1899 const SwStartNode
* pSttNd
= pTextNd
->FindTableBoxStartNode();
1900 if( pSttNd
&& nullptr != ( pTableNd
= pTextNd
->FindTableNode()) &&
1901 nullptr != ( pBox
= pTableNd
->GetTable().GetTableBox(
1902 pSttNd
->GetIndex() )) &&
1903 nullptr != ( pTableLine
= pBox
->GetUpper() ) &&
1904 ( RedlineType::None
!= pBox
->GetRedlineType() ||
1905 RedlineType::None
!= pTableLine
->GetRedlineType() ) )
1907 const SwRedlineTable
& aRedlineTable
= GetDoc()->getIDocumentRedlineAccess().GetRedlineTable();
1908 if ( RedlineType::None
!= pTableLine
->GetRedlineType() )
1910 SwRedlineTable::size_type nPos
= 0;
1911 nPos
= pTableLine
->UpdateTextChangesOnly(nPos
);
1912 if ( nPos
!= SwRedlineTable::npos
)
1914 rContentAtPos
.aFnd
.pRedl
= aRedlineTable
[nPos
];
1915 rContentAtPos
.eContentAtPos
= IsAttrAtPos::TableRedline
;
1921 SwRedlineTable::size_type n
= 0;
1922 SwNodeIndex
aIdx( *pSttNd
, 1 );
1923 const SwPosition
aBoxStart(aIdx
);
1924 const SwRangeRedline
* pFnd
= aRedlineTable
.FindAtPosition( aBoxStart
, n
, /*next=*/true );
1925 if( pFnd
&& RedlineType::Delete
== pFnd
->GetType() )
1927 rContentAtPos
.aFnd
.pRedl
= aRedlineTable
[n
];
1928 rContentAtPos
.eContentAtPos
= IsAttrAtPos::TableColRedline
;
1936 && ( IsAttrAtPos::TableBoxFml
& rContentAtPos
.eContentAtPos
1938 || IsAttrAtPos::TableBoxValue
& rContentAtPos
.eContentAtPos
1942 const SwTableNode
* pTableNd
;
1943 const SwTableBox
* pBox
;
1944 const SwStartNode
* pSttNd
= pTextNd
->FindTableBoxStartNode();
1945 const SwTableBoxFormula
* pItem
;
1947 const SwTableBoxValue
* pItem2
= nullptr;
1949 if( pSttNd
&& nullptr != ( pTableNd
= pTextNd
->FindTableNode()) &&
1950 nullptr != ( pBox
= pTableNd
->GetTable().GetTableBox(
1951 pSttNd
->GetIndex() )) &&
1953 ( (pItem
= pBox
->GetFrameFormat()->GetItemIfSet( RES_BOXATR_FORMULA
, false )) ||
1954 (pItem2
= pBox
->GetFrameFormat()->GetItemIfSet( RES_BOXATR_VALUE
, false )) )
1956 (pItem
= pBox
->GetFrameFormat()->GetItemIfSet( RES_BOXATR_FORMULA
, false ))
1960 std::pair
<Point
, bool> tmp(aPt
, true);
1961 SwFrame
* pF
= pTextNd
->getLayoutFrame(GetLayout(), nullptr, &tmp
);
1964 // then the CellFrame
1965 pFrame
= static_cast<SwContentFrame
*>(pF
);
1966 while( pF
&& !pF
->IsCellFrame() )
1967 pF
= pF
->GetUpper();
1970 if( aTmpState
.m_bPosCorr
)
1972 if( pF
&& !pF
->getFrameArea().Contains( aPt
))
1978 if( pF
) // only then it is valid
1980 // create from internal (for CORE) the external
1982 rContentAtPos
.eContentAtPos
= IsAttrAtPos::TableBoxFml
;
1985 rContentAtPos
.eContentAtPos
= IsAttrAtPos::TableBoxValue
;
1988 const_cast<SwTableBoxFormula
&>(*pItem
).PtrToBoxNm( &pTableNd
->GetTable() );
1993 SwCallLink
aLk( *this ); // watch Cursor-Moves
1994 SwCursorSaveState
aSaveState( *m_pCurrentCursor
);
1995 *m_pCurrentCursor
->GetPoint() = aPos
;
1996 if( m_pCurrentCursor
->IsSelOvr( SwCursorSelOverFlags::CheckNodeSection
|
1997 SwCursorSelOverFlags::Toggle
) )
2007 *pFieldRect
= pF
->getFramePrintArea();
2008 *pFieldRect
+= pF
->getFrameArea().Pos();
2010 rContentAtPos
.pFndTextAttr
= nullptr;
2011 rContentAtPos
.aFnd
.pAttr
= pItem
;
2018 if( !bRet
&& IsAttrAtPos::CurrAttrs
& rContentAtPos
.eContentAtPos
)
2020 const sal_Int32 n
= aPos
.GetContentIndex();
2021 SfxItemSetFixed
<POOLATTR_BEGIN
, POOLATTR_END
- 1> aSet( GetDoc()->GetAttrPool() );
2022 if( pTextNd
->GetpSwpHints() )
2024 for( size_t i
= 0; i
< pTextNd
->GetSwpHints().Count(); ++i
)
2026 const SwTextAttr
* pHt
= pTextNd
->GetSwpHints().Get(i
);
2027 const sal_Int32 nAttrStart
= pHt
->GetStart();
2028 if( nAttrStart
> n
) // over the section
2031 if( nullptr != pHt
->End() && (
2033 ( pHt
->DontExpand() ? n
< *pHt
->End()
2034 : n
<= *pHt
->End() )) ||
2035 ( n
== nAttrStart
&&
2036 ( nAttrStart
== *pHt
->End() || !n
))) )
2038 aSet
.Put( pHt
->GetAttr() );
2041 if( pTextNd
->HasSwAttrSet() &&
2042 pTextNd
->GetpSwAttrSet()->Count() )
2044 SfxItemSet
aFormatSet( pTextNd
->GetSwAttrSet() );
2045 // remove all from format set that are also in TextSet
2046 aFormatSet
.Differentiate( aSet
);
2047 // now merge all together
2048 aSet
.Put( aFormatSet
);
2052 pTextNd
->SwContentNode::GetAttr( aSet
);
2054 rContentAtPos
.sStr
= "Pos: (";
2055 rContentAtPos
.sStr
+= OUString::number( sal_Int32(aPos
.GetNodeIndex()));
2056 rContentAtPos
.sStr
+= ":";
2057 rContentAtPos
.sStr
+= OUString::number( aPos
.GetContentIndex());
2058 rContentAtPos
.sStr
+= ")";
2059 rContentAtPos
.sStr
+= "\nParagraph Style: ";
2060 rContentAtPos
.sStr
+= pTextNd
->GetFormatColl()->GetName();
2061 if( pTextNd
->GetCondFormatColl() )
2063 rContentAtPos
.sStr
+= "\nConditional Style: " + pTextNd
->GetCondFormatColl()->GetName();
2068 OUStringBuffer sAttrs
;
2069 SfxItemIter
aIter( aSet
);
2070 const SfxPoolItem
* pItem
= aIter
.GetCurItem();
2071 const IntlWrapper
aInt(SvtSysLocale().GetUILanguageTag());
2074 if( !IsInvalidItem( pItem
))
2077 GetDoc()->GetAttrPool().GetPresentation(*pItem
,
2078 MapUnit::MapCM
, aStr
, aInt
);
2079 if (!sAttrs
.isEmpty())
2080 sAttrs
.append(", ");
2081 sAttrs
.append(aStr
);
2083 pItem
= aIter
.NextItem();
2085 if (!sAttrs
.isEmpty())
2087 if( !rContentAtPos
.sStr
.isEmpty() )
2088 rContentAtPos
.sStr
+= "\n";
2089 rContentAtPos
.sStr
+= "Attr: " + sAttrs
;
2093 rContentAtPos
.eContentAtPos
= IsAttrAtPos::CurrAttrs
;
2100 rContentAtPos
.eContentAtPos
= IsAttrAtPos::NONE
;
2101 rContentAtPos
.aFnd
.pField
= nullptr;
2107 const SwPostItField
* SwCursorShell::GetPostItFieldAtCursor() const
2109 if ( IsTableMode() )
2112 const SwPosition
* pCursorPos
= GetCursor_()->GetPoint();
2113 const SwTextNode
* pTextNd
= pCursorPos
->GetNode().GetTextNode();
2117 const SwPostItField
* pPostItField
= nullptr;
2118 SwTextAttr
* pTextAttr
= pTextNd
->GetFieldTextAttrAt( pCursorPos
->GetContentIndex() );
2119 const SwField
* pField
= pTextAttr
!= nullptr ? pTextAttr
->GetFormatField().GetField() : nullptr;
2120 if ( pField
&& pField
->Which()== SwFieldIds::Postit
)
2122 pPostItField
= static_cast<const SwPostItField
*>(pField
);
2125 return pPostItField
;
2128 /// is the node in a protected section?
2129 bool SwContentAtPos::IsInProtectSect() const
2131 const SwTextNode
* pNd
= nullptr;
2134 switch( eContentAtPos
)
2136 case IsAttrAtPos::Field
:
2137 case IsAttrAtPos::ClickField
:
2138 pNd
= static_txtattr_cast
<SwTextField
const*>(pFndTextAttr
)->GetpTextNode();
2141 case IsAttrAtPos::Ftn
:
2142 pNd
= &static_cast<const SwTextFootnote
*>(pFndTextAttr
)->GetTextNode();
2145 case IsAttrAtPos::InetAttr
:
2146 pNd
= static_txtattr_cast
<SwTextINetFormat
const*>(pFndTextAttr
)->GetpTextNode();
2156 if( pNd
->IsInProtectSect() )
2159 const SwContentFrame
* pFrame
= pNd
->getLayoutFrame(pNd
->GetDoc().getIDocumentLayoutAccess().GetCurrentLayout(), nullptr, nullptr);
2160 return pFrame
&& pFrame
->IsProtected() ;
2163 bool SwContentAtPos::IsInRTLText()const
2165 const SwTextNode
* pNd
= nullptr;
2166 if (!pFndTextAttr
|| (eContentAtPos
!= IsAttrAtPos::Ftn
))
2169 const SwTextFootnote
* pTextFootnote
= static_cast<const SwTextFootnote
*>(pFndTextAttr
);
2170 if(!pTextFootnote
->GetStartNode())
2173 SwStartNode
* pSttNd
= pTextFootnote
->GetStartNode()->GetNode().GetStartNode();
2174 SwPaM
aTemp( *pSttNd
);
2175 aTemp
.Move(fnMoveForward
, GoInNode
);
2176 SwContentNode
* pContentNode
= aTemp
.GetPointContentNode();
2177 if(pContentNode
&& pContentNode
->IsTextNode())
2178 pNd
= pContentNode
->GetTextNode();
2183 SwIterator
<SwTextFrame
, SwTextNode
, sw::IteratorMode::UnwrapMulti
> aIter(*pNd
);
2184 SwTextFrame
* pTmpFrame
= aIter
.First();
2187 if ( !pTmpFrame
->IsFollow())
2189 bRet
= pTmpFrame
->IsRightToLeft();
2192 pTmpFrame
= aIter
.Next();
2197 bool SwCursorShell::SelectTextModel( const sal_Int32 nStart
,
2198 const sal_Int32 nEnd
)
2200 CurrShell
aCurr( this );
2203 SwCallLink
aLk( *this );
2204 SwCursorSaveState
aSaveState( *m_pCurrentCursor
);
2206 SwPosition
& rPos
= *m_pCurrentCursor
->GetPoint();
2207 m_pCurrentCursor
->DeleteMark();
2208 rPos
.SetContent(nStart
);
2209 m_pCurrentCursor
->SetMark();
2210 rPos
.SetContent(nEnd
);
2212 if( !m_pCurrentCursor
->IsSelOvr() )
2221 TextFrameIndex
SwCursorShell::GetCursorPointAsViewIndex() const
2223 SwPosition
const*const pPos(GetCursor()->GetPoint());
2224 SwTextNode
const*const pTextNode(pPos
->GetNode().GetTextNode());
2226 SwTextFrame
const*const pFrame(static_cast<SwTextFrame
const*>(pTextNode
->getLayoutFrame(GetLayout())));
2228 return pFrame
->MapModelToViewPos(*pPos
);
2231 bool SwCursorShell::SelectTextView(TextFrameIndex
const nStart
,
2232 TextFrameIndex
const nEnd
)
2234 CurrShell
aCurr( this );
2237 SwCallLink
aLk( *this );
2238 SwCursorSaveState
aSaveState( *m_pCurrentCursor
);
2240 SwPosition
& rPos
= *m_pCurrentCursor
->GetPoint();
2241 m_pCurrentCursor
->DeleteMark();
2242 // indexes must correspond to cursor point!
2243 SwTextFrame
const*const pFrame(static_cast<SwTextFrame
const*>(m_pCurrentCursor
->GetPoint()->GetNode().GetTextNode()->getLayoutFrame(GetLayout())));
2245 rPos
= pFrame
->MapViewToModelPos(nStart
);
2246 m_pCurrentCursor
->SetMark();
2247 rPos
= pFrame
->MapViewToModelPos(nEnd
);
2249 if (!m_pCurrentCursor
->IsSelOvr())
2258 bool SwCursorShell::SelectTextAttr( sal_uInt16 nWhich
,
2260 const SwTextAttr
* pTextAttr
)
2262 CurrShell
aCurr( this );
2269 SwPosition
& rPos
= *m_pCurrentCursor
->GetPoint();
2270 SwTextNode
* pTextNd
= rPos
.GetNode().GetTextNode();
2272 ? pTextNd
->GetTextAttrAt(rPos
.GetContentIndex(),
2274 bExpand
? ::sw::GetTextAttrMode::Expand
: ::sw::GetTextAttrMode::Default
)
2280 const sal_Int32
* pEnd
= pTextAttr
->End();
2281 bool bRet
= SelectTextModel(pTextAttr
->GetStart(), (pEnd
? *pEnd
: pTextAttr
->GetStart() + 1));
2285 bool SwCursorShell::GotoINetAttr( const SwTextINetFormat
& rAttr
)
2287 if( !rAttr
.GetpTextNode() )
2289 SwCursor
* pCursor
= getShellCursor( true );
2291 CurrShell
aCurr( this );
2292 SwCallLink
aLk( *this ); // watch Cursor-Moves
2293 SwCursorSaveState
aSaveState( *pCursor
);
2295 pCursor
->GetPoint()->Assign(*rAttr
.GetpTextNode(), rAttr
.GetStart() );
2296 bool bRet
= !pCursor
->IsSelOvr();
2298 UpdateCursor(SwCursorShell::SCROLLWIN
|SwCursorShell::CHKRANGE
|SwCursorShell::READONLY
);
2302 const SwFormatINetFormat
* SwCursorShell::FindINetAttr( std::u16string_view rName
) const
2304 return mxDoc
->FindINetAttr( rName
);
2307 bool SwCursorShell::GetShadowCursorPos( const Point
& rPt
, SwFillMode eFillMode
,
2308 SwRect
& rRect
, sal_Int16
& rOrient
)
2311 CurrShell
aCurr( this );
2313 if (IsTableMode() || HasSelection()
2314 || !GetDoc()->GetIDocumentUndoRedo().DoesUndo())
2318 SwPosition
aPos( *m_pCurrentCursor
->GetPoint() );
2320 SwFillCursorPos
aFPos( eFillMode
);
2321 SwCursorMoveState
aTmpState( &aFPos
);
2324 if( GetLayout()->GetModelPositionForViewPoint( &aPos
, aPt
, &aTmpState
) &&
2325 !aPos
.GetNode().IsProtect())
2327 // start position in protected section?
2328 rRect
= aFPos
.aCursor
;
2329 rOrient
= aFPos
.eOrient
;
2335 bool SwCursorShell::SetShadowCursorPos( const Point
& rPt
, SwFillMode eFillMode
)
2337 CurrShell
aCurr( this );
2339 if (IsTableMode() || HasSelection()
2340 || !GetDoc()->GetIDocumentUndoRedo().DoesUndo())
2344 SwPosition
aPos( *m_pCurrentCursor
->GetPoint() );
2346 SwFillCursorPos
aFPos( eFillMode
);
2347 SwCursorMoveState
aTmpState( &aFPos
);
2349 if( !GetLayout()->GetModelPositionForViewPoint( &aPos
, aPt
, &aTmpState
) )
2352 SwCallLink
aLk( *this ); // watch Cursor-Moves
2355 SwContentNode
* pCNd
= aPos
.GetNode().GetContentNode();
2356 SwUndoId nUndoId
= SwUndoId::INS_FROM_SHADOWCRSR
;
2357 // If only the paragraph attributes "Adjust" or "LRSpace" are set,
2358 // then the following should not delete those again.
2359 if( 0 == aFPos
.nParaCnt
+ aFPos
.nColumnCnt
&&
2360 ( SwFillMode::Indent
== aFPos
.eMode
||
2361 ( text::HoriOrientation::NONE
!= aFPos
.eOrient
&&
2362 0 == aFPos
.nTabCnt
+ aFPos
.nSpaceCnt
)) &&
2363 pCNd
&& pCNd
->Len() )
2364 nUndoId
= SwUndoId::EMPTY
;
2366 GetDoc()->GetIDocumentUndoRedo().StartUndo( nUndoId
, nullptr );
2368 SwTextFormatColl
* pNextFormat
= nullptr;
2369 SwTextNode
* pTNd
= pCNd
? pCNd
->GetTextNode() : nullptr;
2371 pNextFormat
= &pTNd
->GetTextColl()->GetNextTextFormatColl();
2373 const SwSectionNode
* pSectNd
= pCNd
? pCNd
->FindSectionNode() : nullptr;
2374 if( pSectNd
&& aFPos
.nParaCnt
)
2376 SwNodeIndex
aEnd( aPos
.GetNode(), 1 );
2377 while( aEnd
.GetNode().IsEndNode() &&
2379 pSectNd
->EndOfSectionNode() )
2382 if( aEnd
.GetNode().IsEndNode() &&
2383 pCNd
->Len() == aPos
.GetContentIndex() )
2384 aPos
.Assign( *pSectNd
->EndOfSectionNode() );
2387 for( sal_uInt16 n
= 0; n
< aFPos
.nParaCnt
+ aFPos
.nColumnCnt
; ++n
)
2389 GetDoc()->getIDocumentContentOperations().AppendTextNode( aPos
);
2390 if( !n
&& pNextFormat
)
2392 *m_pCurrentCursor
->GetPoint() = aPos
;
2393 GetDoc()->SetTextFormatColl( *m_pCurrentCursor
, pNextFormat
, false );
2395 if( n
< aFPos
.nColumnCnt
)
2397 *m_pCurrentCursor
->GetPoint() = aPos
;
2398 GetDoc()->getIDocumentContentOperations().InsertPoolItem( *m_pCurrentCursor
,
2399 SvxFormatBreakItem( SvxBreak::ColumnBefore
, RES_BREAK
) );
2403 *m_pCurrentCursor
->GetPoint() = aPos
;
2404 switch( aFPos
.eMode
)
2406 case SwFillMode::Indent
:
2407 if( nullptr != (pCNd
= aPos
.GetNode().GetContentNode() ))
2409 assert(pCNd
->IsTextNode()); // ???
2411 RES_PARATR_ADJUST
, RES_PARATR_ADJUST
,
2412 RES_MARGIN_FIRSTLINE
, RES_MARGIN_TEXTLEFT
> aSet(GetDoc()->GetAttrPool());
2413 SvxFirstLineIndentItem
firstLine(pCNd
->GetAttr(RES_MARGIN_FIRSTLINE
));
2414 SvxTextLeftMarginItem
leftMargin(pCNd
->GetAttr(RES_MARGIN_TEXTLEFT
));
2415 firstLine
.SetTextFirstLineOffset(0);
2416 leftMargin
.SetTextLeft(aFPos
.nTabCnt
);
2417 aSet
.Put(firstLine
);
2418 aSet
.Put(leftMargin
);
2420 const SvxAdjustItem
& rAdj
= pCNd
->GetAttr(RES_PARATR_ADJUST
);
2421 if( SvxAdjust::Left
!= rAdj
.GetAdjust() )
2422 aSet
.Put( SvxAdjustItem( SvxAdjust::Left
, RES_PARATR_ADJUST
) );
2424 GetDoc()->getIDocumentContentOperations().InsertItemSet( *m_pCurrentCursor
, aSet
);
2427 OSL_ENSURE( false, "No ContentNode" );
2431 case SwFillMode::Tab
:
2432 case SwFillMode::TabSpace
:
2433 case SwFillMode::Space
:
2435 OUStringBuffer sInsert
;
2436 if (aFPos
.eMode
== SwFillMode::Space
)
2438 comphelper::string::padToLength(sInsert
, sInsert
.getLength() + aFPos
.nSpaceOnlyCnt
, ' ');
2443 comphelper::string::padToLength(sInsert
, aFPos
.nTabCnt
, '\t');
2444 if (aFPos
.nSpaceCnt
)
2445 comphelper::string::padToLength(sInsert
, sInsert
.getLength() + aFPos
.nSpaceCnt
, ' ');
2447 if (!sInsert
.isEmpty())
2448 GetDoc()->getIDocumentContentOperations().InsertString( *m_pCurrentCursor
, sInsert
.makeStringAndClear());
2450 [[fallthrough
]]; // still need to set orientation
2451 case SwFillMode::Margin
:
2452 if( text::HoriOrientation::NONE
!= aFPos
.eOrient
)
2454 SvxAdjustItem
aAdj( SvxAdjust::Left
, RES_PARATR_ADJUST
);
2455 switch( aFPos
.eOrient
)
2457 case text::HoriOrientation::CENTER
:
2458 aAdj
.SetAdjust( SvxAdjust::Center
);
2460 case text::HoriOrientation::RIGHT
:
2461 aAdj
.SetAdjust( SvxAdjust::Right
);
2466 GetDoc()->getIDocumentContentOperations().InsertPoolItem( *m_pCurrentCursor
, aAdj
);
2471 GetDoc()->GetIDocumentUndoRedo().EndUndo( nUndoId
, nullptr );
2477 const SwRangeRedline
* SwCursorShell::SelNextRedline()
2482 CurrShell
aCurr( this );
2483 SwCallLink
aLk( *this ); // watch Cursor-Moves
2484 SwCursorSaveState
aSaveState( *m_pCurrentCursor
);
2486 // ensure point is at the end so alternating SelNext/SelPrev works
2487 NormalizePam(false);
2488 const SwRangeRedline
* pFnd
= GetDoc()->getIDocumentRedlineAccess().SelNextRedline( *m_pCurrentCursor
);
2490 // at the end of the document, go to the start of the document, and try again
2493 GetDoc()->GetDocShell()->GetWrtShell()->StartOfSection();
2494 pFnd
= GetDoc()->getIDocumentRedlineAccess().SelNextRedline( *m_pCurrentCursor
);
2497 if( pFnd
&& !m_pCurrentCursor
->IsInProtectTable() && !m_pCurrentCursor
->IsSelOvr() )
2498 UpdateCursor( SwCursorShell::SCROLLWIN
|SwCursorShell::CHKRANGE
|SwCursorShell::READONLY
);
2504 const SwRangeRedline
* SwCursorShell::SelPrevRedline()
2509 CurrShell
aCurr( this );
2510 SwCallLink
aLk( *this ); // watch Cursor-Moves
2511 SwCursorSaveState
aSaveState( *m_pCurrentCursor
);
2513 // ensure point is at the start so alternating SelNext/SelPrev works
2515 const SwRangeRedline
* pFnd
= GetDoc()->getIDocumentRedlineAccess().SelPrevRedline( *m_pCurrentCursor
);
2517 // at the start of the document, go to the end of the document, and try again
2520 GetDoc()->GetDocShell()->GetWrtShell()->EndOfSection();
2521 pFnd
= GetDoc()->getIDocumentRedlineAccess().SelPrevRedline( *m_pCurrentCursor
);
2524 if( pFnd
&& !m_pCurrentCursor
->IsInProtectTable() && !m_pCurrentCursor
->IsSelOvr() )
2525 UpdateCursor( SwCursorShell::SCROLLWIN
|SwCursorShell::CHKRANGE
|SwCursorShell::READONLY
);
2531 const SwRangeRedline
* SwCursorShell::GotoRedline_( SwRedlineTable::size_type nArrPos
, bool bSelect
)
2533 const SwRangeRedline
* pFnd
= nullptr;
2534 SwCallLink
aLk( *this ); // watch Cursor-Moves
2535 SwCursorSaveState
aSaveState( *m_pCurrentCursor
);
2537 pFnd
= GetDoc()->getIDocumentRedlineAccess().GetRedlineTable()[ nArrPos
];
2541 *m_pCurrentCursor
->GetPoint() = *pFnd
->Start();
2543 SwPosition
* pPtPos
= m_pCurrentCursor
->GetPoint();
2544 if( !pPtPos
->GetNode().IsContentNode() )
2546 SwContentNode
* pCNd
= GetDoc()->GetNodes().GoNextSection( pPtPos
,
2547 true, IsReadOnlyAvailable() );
2550 if( pPtPos
->GetNode() <= pFnd
->End()->GetNode() )
2551 pPtPos
->SetContent( 0 );
2557 if( pFnd
&& bSelect
)
2559 m_pCurrentCursor
->SetMark();
2560 if( RedlineType::FmtColl
== pFnd
->GetType() )
2562 SwContentNode
* pCNd
= pPtPos
->GetNode().GetContentNode();
2563 m_pCurrentCursor
->GetPoint()->SetContent( pCNd
->Len() );
2564 m_pCurrentCursor
->GetMark()->Assign( *pCNd
, 0 );
2567 *m_pCurrentCursor
->GetPoint() = *pFnd
->End();
2569 pPtPos
= m_pCurrentCursor
->GetPoint();
2570 if( !pPtPos
->GetNode().IsContentNode() )
2572 SwContentNode
* pCNd
= SwNodes::GoPrevSection( pPtPos
,
2573 true, IsReadOnlyAvailable() );
2576 if( pPtPos
->GetNode() >= m_pCurrentCursor
->GetMark()->GetNode() )
2577 pPtPos
->SetContent( pCNd
->Len() );
2586 m_pCurrentCursor
->DeleteMark();
2587 m_pCurrentCursor
->RestoreSavePos();
2589 else if( bSelect
&& *m_pCurrentCursor
->GetMark() == *m_pCurrentCursor
->GetPoint() )
2590 m_pCurrentCursor
->DeleteMark();
2592 if( pFnd
&& !m_pCurrentCursor
->IsInProtectTable() && !m_pCurrentCursor
->IsSelOvr() )
2593 UpdateCursor( SwCursorShell::SCROLLWIN
| SwCursorShell::CHKRANGE
2594 | SwCursorShell::READONLY
);
2599 m_pCurrentCursor
->DeleteMark();
2604 const SwRangeRedline
* SwCursorShell::GotoRedline( SwRedlineTable::size_type nArrPos
, bool bSelect
)
2606 const SwRangeRedline
* pFnd
= nullptr;
2610 CurrShell
aCurr( this );
2612 const SwRedlineTable
& rTable
= GetDoc()->getIDocumentRedlineAccess().GetRedlineTable();
2613 const SwRangeRedline
* pTmp
= rTable
[ nArrPos
];
2614 sal_uInt16 nSeqNo
= pTmp
->GetSeqNo();
2615 if( !nSeqNo
|| !bSelect
)
2617 pFnd
= GotoRedline_( nArrPos
, bSelect
);
2621 bool bCheck
= false;
2623 SwRedlineTable::size_type nArrSavPos
= nArrPos
;
2626 pTmp
= GotoRedline_( nArrPos
, true );
2631 if( pTmp
&& bCheck
)
2633 // Check for overlaps. These can happen when FormatColl-
2634 // Redlines were stretched over a whole paragraph
2635 SwPaM
* pCur
= m_pCurrentCursor
;
2636 SwPaM
* pNextPam
= pCur
->GetNext();
2637 auto [pCStt
, pCEnd
] = pCur
->StartEnd(); // SwPosition*
2638 while( pCur
!= pNextPam
)
2640 auto [pNStt
, pNEnd
] = pNextPam
->StartEnd(); // SwPosition*
2643 switch( ::ComparePosition( *pCStt
, *pCEnd
,
2646 case SwComparePosition::Inside
: // Pos1 is completely in Pos2
2647 if( !pCur
->HasMark() )
2650 *pCur
->GetMark() = *pNStt
;
2657 case SwComparePosition::Outside
: // Pos2 is completely in Pos1
2658 case SwComparePosition::Equal
: // Pos1 has same size as Pos2
2661 case SwComparePosition::OverlapBefore
: // Pos1 overlaps Pos2 at beginning
2662 if( !pCur
->HasMark() )
2666 case SwComparePosition::OverlapBehind
: // Pos1 overlaps Pos2 at end
2667 if( !pCur
->HasMark() )
2670 *pCur
->GetMark() = *pNStt
;
2682 // not needed anymore
2683 SwPaM
* pPrevPam
= pNextPam
->GetPrev();
2685 pNextPam
= pPrevPam
;
2687 pNextPam
= pNextPam
->GetNext();
2691 SwRedlineTable::size_type nFndPos
= 2 == nLoopCnt
2692 ? rTable
.FindNextOfSeqNo( nArrPos
)
2693 : rTable
.FindPrevOfSeqNo( nArrPos
);
2694 if( SwRedlineTable::npos
!= nFndPos
||
2695 ( 0 != ( --nLoopCnt
) && SwRedlineTable::npos
!= (
2696 nFndPos
= rTable
.FindPrevOfSeqNo( nArrSavPos
))) )
2700 // create new cursor
2709 } while( nLoopCnt
);
2713 bool SwCursorShell::SelectNxtPrvHyperlink( bool bNext
)
2715 SwNodes
& rNds
= GetDoc()->GetNodes();
2716 const SwNode
* pBodyEndNd
= &rNds
.GetEndOfContent();
2717 const SwNode
* pBodySttNd
= pBodyEndNd
->StartOfSectionNode();
2718 SwNodeOffset nBodySttNdIdx
= pBodySttNd
->GetIndex();
2721 SetGetExpField
aCmpPos( SwPosition( bNext
? *pBodyEndNd
: *pBodySttNd
) );
2722 SetGetExpField
aCurPos( bNext
? *m_pCurrentCursor
->End() : *m_pCurrentCursor
->Start() );
2723 if( aCurPos
.GetNode() < nBodySttNdIdx
)
2725 const SwContentNode
* pCNd
= aCurPos
.GetNodeFromContent()->GetContentNode();
2726 std::pair
<Point
, bool> tmp(aPt
, true);
2729 SwContentFrame
* pFrame
= pCNd
->getLayoutFrame(GetLayout(), nullptr, &tmp
);
2731 aCurPos
.SetBodyPos( *pFrame
);
2735 // check first all the hyperlink fields
2737 const SwTextNode
* pTextNd
;
2738 const SwCharFormats
* pFormats
= GetDoc()->GetCharFormats();
2739 for( SwCharFormats::size_type n
= pFormats
->size(); 1 < n
; )
2741 SwIterator
<SwTextINetFormat
,SwCharFormat
> aIter(*(*pFormats
)[--n
]);
2743 for( SwTextINetFormat
* pFnd
= aIter
.First(); pFnd
; pFnd
= aIter
.Next() )
2745 pTextNd
= pFnd
->GetpTextNode();
2746 if( pTextNd
&& pTextNd
->GetNodes().IsDocNodes() )
2748 SwTextINetFormat
& rAttr
= *pFnd
;
2749 SetGetExpField
aPos( *pTextNd
, rAttr
);
2750 if (pTextNd
->GetIndex() < nBodySttNdIdx
)
2752 std::pair
<Point
, bool> tmp(aPt
, true);
2753 SwContentFrame
* pFrame
= pTextNd
->getLayoutFrame(GetLayout(), nullptr, &tmp
);
2756 aPos
.SetBodyPos( *pFrame
);
2761 ? ( aPos
< aCmpPos
&& aCurPos
< aPos
)
2762 : ( aCmpPos
< aPos
&& aPos
< aCurPos
))
2764 OUString
sText(pTextNd
->GetExpandText(GetLayout(),
2766 *rAttr
.GetEnd() - rAttr
.GetStart() ) );
2768 sText
= sText
.replaceAll("\x0a", "");
2769 sText
= comphelper::string::strip(sText
, ' ');
2771 if( !sText
.isEmpty() )
2779 // then check all the Flys with a URL or image map
2781 for(sw::SpzFrameFormat
* pSpz
: *GetDoc()->GetSpzFrameFormats())
2783 auto pFormat
= static_cast<SwFlyFrameFormat
*>(pSpz
);
2784 const SwFormatURL
& rURLItem
= pFormat
->GetURL();
2785 if( rURLItem
.GetMap() || !rURLItem
.GetURL().isEmpty() )
2787 SwFlyFrame
* pFly
= pFormat
->GetFrame( &aPt
);
2788 SwPosition
aTmpPos( *pBodySttNd
);
2790 GetBodyTextNode( *GetDoc(), aTmpPos
, *pFly
->GetLower() ) )
2792 SetGetExpField
aPos( *pFormat
, &aTmpPos
);
2795 ? ( aPos
< aCmpPos
&& aCurPos
< aPos
)
2796 : ( aCmpPos
< aPos
&& aPos
< aCurPos
))
2804 const SwTextINetFormat
* pFndAttr
= aCmpPos
.GetINetFormat();
2805 const SwFlyFrameFormat
* pFndFormat
= aCmpPos
.GetFlyFormat();
2806 if( !pFndAttr
&& !pFndFormat
)
2809 CurrShell
aCurr( this );
2810 SwCallLink
aLk( *this );
2813 // found a text attribute ?
2816 SwCursorSaveState
aSaveState( *m_pCurrentCursor
);
2818 aCmpPos
.GetPosOfContent( *m_pCurrentCursor
->GetPoint() );
2819 m_pCurrentCursor
->DeleteMark();
2820 m_pCurrentCursor
->SetMark();
2821 m_pCurrentCursor
->GetPoint()->SetContent( *pFndAttr
->End() );
2823 if( !m_pCurrentCursor
->IsInProtectTable() && !m_pCurrentCursor
->IsSelOvr() )
2825 UpdateCursor( SwCursorShell::SCROLLWIN
|SwCursorShell::CHKRANGE
|
2826 SwCursorShell::READONLY
);
2830 // found a draw object ?
2831 else if( RES_DRAWFRMFMT
== pFndFormat
->Which() )
2833 const SdrObject
* pSObj
= pFndFormat
->FindSdrObject();
2836 static_cast<SwFEShell
*>(this)->SelectObj( pSObj
->GetCurrentBoundRect().Center() );
2841 else // then is it a fly
2843 SwFlyFrame
* pFly
= pFndFormat
->GetFrame(&aPt
);
2846 static_cast<SwFEShell
*>(this)->SelectFlyFrame( *pFly
);
2854 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */