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 <pagefrm.hxx>
32 #include <svx/srchdlg.hxx>
35 bool SwCursorShell::CallCursorShellFN( FNCursorShell fnCursor
)
37 if (SwWrtShell
* pWrtSh
= dynamic_cast<SwWrtShell
*>(this))
38 pWrtSh
->addCurrentPosition();
40 SwCallLink
aLk( *this ); // watch Cursor-Moves
41 bool bRet
= (this->*fnCursor
)();
43 UpdateCursor( SwCursorShell::SCROLLWIN
| SwCursorShell::CHKRANGE
|
44 SwCursorShell::READONLY
);
48 bool SwCursorShell::CallCursorFN( FNCursor fnCursor
)
50 if (SwWrtShell
* pWrtSh
= dynamic_cast<SwWrtShell
*>(this))
51 pWrtSh
->addCurrentPosition();
53 SwCallLink
aLk( *this ); // watch Cursor-Moves
54 SwCursor
* pCursor
= getShellCursor( true );
55 bool bRet
= (pCursor
->*fnCursor
)();
57 UpdateCursor( SwCursorShell::SCROLLWIN
| SwCursorShell::CHKRANGE
|
58 SwCursorShell::READONLY
);
62 bool SwCursor::GotoFootnoteText()
64 // jump from content to footnote
66 SwTextNode
* pTextNd
= GetPoint()->GetNode().GetTextNode();
68 SwTextAttr
*const pFootnote( pTextNd
69 ? pTextNd
->GetTextAttrForCharAt(
70 GetPoint()->GetContentIndex(), RES_TXTATR_FTN
)
74 SwCursorSaveState
aSaveState( *this );
75 GetPoint()->Assign( *static_cast<SwTextFootnote
*>(pFootnote
)->GetStartNode() );
77 SwContentNode
* pCNd
= GetDoc().GetNodes().GoNextSection(
79 true, !IsReadOnlyAvailable() );
82 bRet
= !IsSelOvr( SwCursorSelOverFlags::CheckNodeSection
|
83 SwCursorSelOverFlags::Toggle
);
89 bool SwCursorShell::GotoFootnoteText()
91 bool bRet
= CallCursorFN( &SwCursor::GotoFootnoteText
);
94 SwTextNode
* pTextNd
= GetCursor_() ?
95 GetCursor_()->GetPoint()->GetNode().GetTextNode() : nullptr;
98 std::pair
<Point
, bool> const tmp(GetCursor_()->GetSttPos(), true);
99 const SwFrame
*pFrame
= pTextNd
->getLayoutFrame( GetLayout(),
100 GetCursor_()->Start(), &tmp
);
101 const SwFootnoteBossFrame
* pFootnoteBoss
;
102 bool bSkip
= pFrame
&& pFrame
->IsInFootnote();
105 pFootnoteBoss
= pFrame
->FindFootnoteBossFrame();
108 pFrame
= pFootnoteBoss
->FindFootnoteCont();
115 const SwContentFrame
* pCnt
= static_cast<const SwLayoutFrame
*>
116 (pFrame
)->ContainsContent();
119 SwTextFrame
const*const pTF(
120 static_cast<const SwTextFrame
*>(pCnt
));
121 *GetCursor_()->GetPoint() =
122 pTF
->MapViewToModelPos(pTF
->GetOffset());
123 UpdateCursor( SwCursorShell::SCROLLWIN
|
124 SwCursorShell::CHKRANGE
| SwCursorShell::READONLY
);
130 if( pFootnoteBoss
->GetNext() && !pFootnoteBoss
->IsPageFrame() )
131 pFrame
= pFootnoteBoss
->GetNext();
133 pFrame
= pFootnoteBoss
->GetUpper();
140 bool SwCursor::GotoFootnoteAnchor()
142 // jump from footnote to anchor
143 const SwNode
* pSttNd
= GetPointNode().FindFootnoteStartNode();
146 // search in all footnotes in document for this StartIndex
147 const SwFootnoteIdxs
& rFootnoteArr
= pSttNd
->GetDoc().GetFootnoteIdxs();
148 for( size_t n
= 0; n
< rFootnoteArr
.size(); ++n
)
150 const SwTextFootnote
* pTextFootnote
= rFootnoteArr
[ n
];
151 if( nullptr != pTextFootnote
->GetStartNode() &&
152 pSttNd
== &pTextFootnote
->GetStartNode()->GetNode() )
154 SwCursorSaveState
aSaveState( *this );
156 SwTextNode
& rTNd
= const_cast<SwTextNode
&>(pTextFootnote
->GetTextNode());
157 GetPoint()->Assign( rTNd
, pTextFootnote
->GetStart() );
159 return !IsSelOvr( SwCursorSelOverFlags::CheckNodeSection
|
160 SwCursorSelOverFlags::Toggle
);
167 bool SwCursorShell::GotoFootnoteAnchor()
169 if (SwWrtShell
* pWrtSh
= dynamic_cast<SwWrtShell
*>(this))
170 pWrtSh
->addCurrentPosition();
172 // jump from footnote to anchor
173 SwCallLink
aLk( *this ); // watch Cursor-Moves
174 bool bRet
= m_pCurrentCursor
->GotoFootnoteAnchor();
177 // special treatment for table header row
178 m_pCurrentCursor
->GetPtPos() = Point();
179 UpdateCursor( SwCursorShell::SCROLLWIN
| SwCursorShell::CHKRANGE
|
180 SwCursorShell::READONLY
);
185 static bool CmpLE( const SwTextFootnote
& rFootnote
, SwNodeOffset nNd
, sal_Int32 nCnt
)
187 const SwNodeOffset nTNd
= rFootnote
.GetTextNode().GetIndex();
188 return nTNd
< nNd
|| ( nTNd
== nNd
&& rFootnote
.GetStart() <= nCnt
);
191 static bool CmpL( const SwTextFootnote
& rFootnote
, SwNodeOffset nNd
, sal_Int32 nCnt
)
193 const SwNodeOffset nTNd
= rFootnote
.GetTextNode().GetIndex();
194 return nTNd
< nNd
|| ( nTNd
== nNd
&& rFootnote
.GetStart() < nCnt
);
197 bool SwCursor::GotoNextFootnoteAnchor()
199 const SwFootnoteIdxs
& rFootnoteArr
= GetDoc().GetFootnoteIdxs();
200 const SwTextFootnote
* pTextFootnote
= nullptr;
203 if( rFootnoteArr
.empty() )
205 SvxSearchDialogWrapper::SetSearchLabel( SearchLabel::NavElementNotFound
);
209 if( rFootnoteArr
.SeekEntry( GetPoint()->GetNode(), &nPos
))
211 // there is a footnote with this index, so search also for the next one
212 if( nPos
< rFootnoteArr
.size() )
214 SwNodeOffset nNdPos
= GetPoint()->GetNodeIndex();
215 const sal_Int32 nCntPos
= GetPoint()->GetContentIndex();
217 pTextFootnote
= rFootnoteArr
[ nPos
];
219 if( CmpLE( *pTextFootnote
, nNdPos
, nCntPos
) )
221 pTextFootnote
= nullptr;
222 for( ++nPos
; nPos
< rFootnoteArr
.size(); ++nPos
)
224 pTextFootnote
= rFootnoteArr
[ nPos
];
225 if( !CmpLE( *pTextFootnote
, nNdPos
, nCntPos
) )
227 pTextFootnote
= nullptr;
233 pTextFootnote
= nullptr;
236 pTextFootnote
= rFootnoteArr
[ --nPos
];
237 if( CmpLE( *pTextFootnote
, nNdPos
, nCntPos
) )
239 pTextFootnote
= rFootnoteArr
[ ++nPos
];
246 else if( nPos
< rFootnoteArr
.size() )
247 pTextFootnote
= rFootnoteArr
[ nPos
];
249 if (pTextFootnote
== nullptr)
251 pTextFootnote
= rFootnoteArr
[ 0 ];
252 SvxSearchDialogWrapper::SetSearchLabel( SearchLabel::EndWrapped
);
255 SvxSearchDialogWrapper::SetSearchLabel( SearchLabel::Empty
);
257 bool bRet
= nullptr != pTextFootnote
;
260 SwCursorSaveState
aSaveState( *this );
262 SwTextNode
& rTNd
= const_cast<SwTextNode
&>(pTextFootnote
->GetTextNode());
263 GetPoint()->Assign( rTNd
, pTextFootnote
->GetStart() );
269 bool SwCursor::GotoPrevFootnoteAnchor()
271 const SwFootnoteIdxs
& rFootnoteArr
= GetDoc().GetFootnoteIdxs();
272 const SwTextFootnote
* pTextFootnote
= nullptr;
275 if( rFootnoteArr
.empty() )
277 SvxSearchDialogWrapper::SetSearchLabel( SearchLabel::NavElementNotFound
);
281 if( rFootnoteArr
.SeekEntry( GetPoint()->GetNode(), &nPos
) )
283 // there is a footnote with this index, so search also for the next one
284 SwNodeOffset nNdPos
= GetPoint()->GetNodeIndex();
285 const sal_Int32 nCntPos
= GetPoint()->GetContentIndex();
287 pTextFootnote
= rFootnoteArr
[ nPos
];
289 if( CmpL( *pTextFootnote
, nNdPos
, nCntPos
))
291 for( ++nPos
; nPos
< rFootnoteArr
.size(); ++nPos
)
293 pTextFootnote
= rFootnoteArr
[ nPos
];
294 if( !CmpL( *pTextFootnote
, nNdPos
, nCntPos
) )
296 pTextFootnote
= rFootnoteArr
[ nPos
-1 ];
304 pTextFootnote
= nullptr;
307 pTextFootnote
= rFootnoteArr
[ --nPos
];
308 if( CmpL( *pTextFootnote
, nNdPos
, nCntPos
))
310 pTextFootnote
= nullptr;
314 pTextFootnote
= nullptr;
317 pTextFootnote
= rFootnoteArr
[ nPos
-1 ];
319 if( pTextFootnote
== nullptr )
321 pTextFootnote
= rFootnoteArr
[ rFootnoteArr
.size() - 1 ];
322 SvxSearchDialogWrapper::SetSearchLabel( SearchLabel::StartWrapped
);
325 SvxSearchDialogWrapper::SetSearchLabel( SearchLabel::Empty
);
327 bool bRet
= nullptr != pTextFootnote
;
330 SwCursorSaveState
aSaveState( *this );
332 SwTextNode
& rTNd
= const_cast<SwTextNode
&>(pTextFootnote
->GetTextNode());
333 GetPoint()->Assign( rTNd
, pTextFootnote
->GetStart() );
339 bool SwCursorShell::GotoNextFootnoteAnchor()
341 return CallCursorFN( &SwCursor::GotoNextFootnoteAnchor
);
344 bool SwCursorShell::GotoPrevFootnoteAnchor()
346 return CallCursorFN( &SwCursor::GotoPrevFootnoteAnchor
);
349 /// jump from border to anchor
350 void SwCursorShell::GotoFlyAnchor()
352 CurrShell
aCurr( this );
353 const SwFrame
* pFrame
= GetCurrFrame();
355 pFrame
= pFrame
->GetUpper();
356 } while( pFrame
&& !pFrame
->IsFlyFrame() );
358 if( !pFrame
) // no FlyFrame
361 SwCallLink
aLk( *this ); // watch Cursor-Moves
362 SwCursorSaveState
aSaveState( *m_pCurrentCursor
);
364 // jump in BodyFrame closest to FlyFrame
365 SwRect
aTmpRect( m_aCharRect
);
366 if( !pFrame
->getFrameArea().Contains( aTmpRect
))
367 aTmpRect
= pFrame
->getFrameArea();
368 Point
aPt( aTmpRect
.Left(), aTmpRect
.Top() +
369 ( aTmpRect
.Bottom() - aTmpRect
.Top() ) / 2 );
370 aPt
.setX(aPt
.getX() > (pFrame
->getFrameArea().Left() + (pFrame
->getFrameArea().SSize().Width() / 2 ))
371 ? pFrame
->getFrameArea().Right()
372 : pFrame
->getFrameArea().Left());
374 const SwPageFrame
* pPageFrame
= pFrame
->FindPageFrame();
375 const SwContentFrame
* pFndFrame
= pPageFrame
->GetContentPos( aPt
, false, true );
376 pFndFrame
->GetModelPositionForViewPoint( m_pCurrentCursor
->GetPoint(), aPt
);
378 bool bRet
= !m_pCurrentCursor
->IsInProtectTable() && !m_pCurrentCursor
->IsSelOvr();
380 UpdateCursor( SwCursorShell::SCROLLWIN
| SwCursorShell::CHKRANGE
|
381 SwCursorShell::READONLY
);
384 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */