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 SwCallLink
aLk( *this ); // watch Cursor-Moves
38 bool bRet
= (this->*fnCursor
)();
40 UpdateCursor( SwCursorShell::SCROLLWIN
| SwCursorShell::CHKRANGE
|
41 SwCursorShell::READONLY
);
45 bool SwCursorShell::CallCursorFN( FNCursor fnCursor
)
47 // for footnote anchor<->text recency
48 if (SwWrtShell
* pWrtSh
= dynamic_cast<SwWrtShell
*>(this))
49 pWrtSh
->addCurrentPosition();
51 SwCallLink
aLk( *this ); // watch Cursor-Moves
52 SwCursor
* pCursor
= getShellCursor( true );
53 bool bRet
= (pCursor
->*fnCursor
)();
55 UpdateCursor( SwCursorShell::SCROLLWIN
| SwCursorShell::CHKRANGE
|
56 SwCursorShell::READONLY
);
60 bool SwCursor::GotoFootnoteText()
62 // jump from content to footnote
64 SwTextNode
* pTextNd
= GetPoint()->GetNode().GetTextNode();
66 SwTextAttr
*const pFootnote( pTextNd
67 ? pTextNd
->GetTextAttrForCharAt(
68 GetPoint()->GetContentIndex(), RES_TXTATR_FTN
)
72 SwCursorSaveState
aSaveState( *this );
73 GetPoint()->Assign( *static_cast<SwTextFootnote
*>(pFootnote
)->GetStartNode() );
75 SwContentNode
* pCNd
= SwNodes::GoNextSection(
77 true, !IsReadOnlyAvailable() );
80 bRet
= !IsSelOvr( SwCursorSelOverFlags::CheckNodeSection
|
81 SwCursorSelOverFlags::Toggle
);
87 bool SwCursorShell::GotoFootnoteText()
89 bool bRet
= CallCursorFN( &SwCursor::GotoFootnoteText
);
92 SwTextNode
* pTextNd
= GetCursor_() ?
93 GetCursor_()->GetPoint()->GetNode().GetTextNode() : nullptr;
96 std::pair
<Point
, bool> const tmp(GetCursor_()->GetSttPos(), true);
97 const SwFrame
*pFrame
= pTextNd
->getLayoutFrame( GetLayout(),
98 GetCursor_()->Start(), &tmp
);
99 const SwFootnoteBossFrame
* pFootnoteBoss
;
100 bool bSkip
= pFrame
&& pFrame
->IsInFootnote();
103 pFootnoteBoss
= pFrame
->FindFootnoteBossFrame();
106 pFrame
= pFootnoteBoss
->FindFootnoteCont();
113 const SwContentFrame
* pCnt
= static_cast<const SwLayoutFrame
*>
114 (pFrame
)->ContainsContent();
117 SwTextFrame
const*const pTF(
118 static_cast<const SwTextFrame
*>(pCnt
));
119 *GetCursor_()->GetPoint() =
120 pTF
->MapViewToModelPos(pTF
->GetOffset());
121 UpdateCursor( SwCursorShell::SCROLLWIN
|
122 SwCursorShell::CHKRANGE
| SwCursorShell::READONLY
);
128 if( pFootnoteBoss
->GetNext() && !pFootnoteBoss
->IsPageFrame() )
129 pFrame
= pFootnoteBoss
->GetNext();
131 pFrame
= pFootnoteBoss
->GetUpper();
138 bool SwCursor::GotoFootnoteAnchor()
140 // jump from footnote to anchor
141 const SwNode
* pSttNd
= GetPointNode().FindFootnoteStartNode();
144 // search in all footnotes in document for this StartIndex
145 const SwFootnoteIdxs
& rFootnoteArr
= pSttNd
->GetDoc().GetFootnoteIdxs();
146 for( size_t n
= 0; n
< rFootnoteArr
.size(); ++n
)
148 const SwTextFootnote
* pTextFootnote
= rFootnoteArr
[ n
];
149 if( nullptr != pTextFootnote
->GetStartNode() &&
150 pSttNd
== &pTextFootnote
->GetStartNode()->GetNode() )
152 SwCursorSaveState
aSaveState( *this );
154 SwTextNode
& rTNd
= const_cast<SwTextNode
&>(pTextFootnote
->GetTextNode());
155 GetPoint()->Assign( rTNd
, pTextFootnote
->GetStart() );
157 return !IsSelOvr( SwCursorSelOverFlags::CheckNodeSection
|
158 SwCursorSelOverFlags::Toggle
);
165 bool SwCursorShell::GotoFootnoteAnchor()
167 if (SwWrtShell
* pWrtSh
= dynamic_cast<SwWrtShell
*>(this))
168 pWrtSh
->addCurrentPosition();
170 // jump from footnote to anchor
171 SwCallLink
aLk( *this ); // watch Cursor-Moves
172 bool bRet
= m_pCurrentCursor
->GotoFootnoteAnchor();
175 // special treatment for table header row
176 m_pCurrentCursor
->GetPtPos() = Point();
177 UpdateCursor( SwCursorShell::SCROLLWIN
| SwCursorShell::CHKRANGE
|
178 SwCursorShell::READONLY
);
183 static bool CmpLE( const SwTextFootnote
& rFootnote
, SwNodeOffset nNd
, sal_Int32 nCnt
)
185 const SwNodeOffset nTNd
= rFootnote
.GetTextNode().GetIndex();
186 return nTNd
< nNd
|| ( nTNd
== nNd
&& rFootnote
.GetStart() <= nCnt
);
189 static bool CmpL( const SwTextFootnote
& rFootnote
, SwNodeOffset nNd
, sal_Int32 nCnt
)
191 const SwNodeOffset nTNd
= rFootnote
.GetTextNode().GetIndex();
192 return nTNd
< nNd
|| ( nTNd
== nNd
&& rFootnote
.GetStart() < nCnt
);
195 bool SwCursor::GotoNextFootnoteAnchor()
197 const SwFootnoteIdxs
& rFootnoteArr
= GetDoc().GetFootnoteIdxs();
198 const SwTextFootnote
* pTextFootnote
= nullptr;
201 if( rFootnoteArr
.empty() )
203 SvxSearchDialogWrapper::SetSearchLabel( SearchLabel::NavElementNotFound
);
207 if( rFootnoteArr
.SeekEntry( GetPoint()->GetNode(), &nPos
))
209 // there is a footnote with this index, so search also for the next one
210 if( nPos
< rFootnoteArr
.size() )
212 SwNodeOffset nNdPos
= GetPoint()->GetNodeIndex();
213 const sal_Int32 nCntPos
= GetPoint()->GetContentIndex();
215 pTextFootnote
= rFootnoteArr
[ nPos
];
217 if( CmpLE( *pTextFootnote
, nNdPos
, nCntPos
) )
219 pTextFootnote
= nullptr;
220 for( ++nPos
; nPos
< rFootnoteArr
.size(); ++nPos
)
222 pTextFootnote
= rFootnoteArr
[ nPos
];
223 if( !CmpLE( *pTextFootnote
, nNdPos
, nCntPos
) )
225 pTextFootnote
= nullptr;
231 pTextFootnote
= nullptr;
234 pTextFootnote
= rFootnoteArr
[ --nPos
];
235 if( CmpLE( *pTextFootnote
, nNdPos
, nCntPos
) )
237 pTextFootnote
= rFootnoteArr
[ ++nPos
];
244 else if( nPos
< rFootnoteArr
.size() )
245 pTextFootnote
= rFootnoteArr
[ nPos
];
247 if (pTextFootnote
== nullptr)
249 pTextFootnote
= rFootnoteArr
[ 0 ];
250 SvxSearchDialogWrapper::SetSearchLabel( SearchLabel::EndWrapped
);
253 SvxSearchDialogWrapper::SetSearchLabel( SearchLabel::Empty
);
255 bool bRet
= nullptr != pTextFootnote
;
258 SwCursorSaveState
aSaveState( *this );
260 SwTextNode
& rTNd
= const_cast<SwTextNode
&>(pTextFootnote
->GetTextNode());
261 GetPoint()->Assign( rTNd
, pTextFootnote
->GetStart() );
267 bool SwCursor::GotoPrevFootnoteAnchor()
269 const SwFootnoteIdxs
& rFootnoteArr
= GetDoc().GetFootnoteIdxs();
270 const SwTextFootnote
* pTextFootnote
= nullptr;
273 if( rFootnoteArr
.empty() )
275 SvxSearchDialogWrapper::SetSearchLabel( SearchLabel::NavElementNotFound
);
279 if( rFootnoteArr
.SeekEntry( GetPoint()->GetNode(), &nPos
) )
281 // there is a footnote with this index, so search also for the next one
282 SwNodeOffset nNdPos
= GetPoint()->GetNodeIndex();
283 const sal_Int32 nCntPos
= GetPoint()->GetContentIndex();
285 pTextFootnote
= rFootnoteArr
[ nPos
];
287 if( CmpL( *pTextFootnote
, nNdPos
, nCntPos
))
289 for( ++nPos
; nPos
< rFootnoteArr
.size(); ++nPos
)
291 pTextFootnote
= rFootnoteArr
[ nPos
];
292 if( !CmpL( *pTextFootnote
, nNdPos
, nCntPos
) )
294 pTextFootnote
= rFootnoteArr
[ nPos
-1 ];
302 pTextFootnote
= nullptr;
306 pTextFootnote
= rFootnoteArr
[nPos
];
307 if( CmpL( *pTextFootnote
, nNdPos
, nCntPos
))
309 pTextFootnote
= nullptr;
313 pTextFootnote
= nullptr;
316 pTextFootnote
= rFootnoteArr
[ nPos
-1 ];
318 if( pTextFootnote
== nullptr )
320 pTextFootnote
= rFootnoteArr
[ rFootnoteArr
.size() - 1 ];
321 SvxSearchDialogWrapper::SetSearchLabel( SearchLabel::StartWrapped
);
324 SvxSearchDialogWrapper::SetSearchLabel( SearchLabel::Empty
);
326 bool bRet
= nullptr != pTextFootnote
;
329 SwCursorSaveState
aSaveState( *this );
331 SwTextNode
& rTNd
= const_cast<SwTextNode
&>(pTextFootnote
->GetTextNode());
332 GetPoint()->Assign( rTNd
, pTextFootnote
->GetStart() );
338 bool SwCursorShell::GotoNextFootnoteAnchor()
340 return CallCursorFN( &SwCursor::GotoNextFootnoteAnchor
);
343 bool SwCursorShell::GotoPrevFootnoteAnchor()
345 return CallCursorFN( &SwCursor::GotoPrevFootnoteAnchor
);
348 /// jump from border to anchor
349 void SwCursorShell::GotoFlyAnchor()
351 CurrShell
aCurr( this );
352 const SwFrame
* pFrame
= GetCurrFrame();
354 pFrame
= pFrame
->GetUpper();
355 } while( pFrame
&& !pFrame
->IsFlyFrame() );
357 if( !pFrame
) // no FlyFrame
360 SwCallLink
aLk( *this ); // watch Cursor-Moves
361 SwCursorSaveState
aSaveState( *m_pCurrentCursor
);
363 // jump in BodyFrame closest to FlyFrame
364 SwRect
aTmpRect( m_aCharRect
);
365 if( !pFrame
->getFrameArea().Contains( aTmpRect
))
366 aTmpRect
= pFrame
->getFrameArea();
367 Point
aPt( aTmpRect
.Left(), aTmpRect
.Top() +
368 ( aTmpRect
.Bottom() - aTmpRect
.Top() ) / 2 );
369 aPt
.setX(aPt
.getX() > (pFrame
->getFrameArea().Left() + (pFrame
->getFrameArea().SSize().Width() / 2 ))
370 ? pFrame
->getFrameArea().Right()
371 : pFrame
->getFrameArea().Left());
373 const SwPageFrame
* pPageFrame
= pFrame
->FindPageFrame();
374 const SwContentFrame
* pFndFrame
= pPageFrame
->GetContentPos( aPt
, false, true );
375 pFndFrame
->GetModelPositionForViewPoint( m_pCurrentCursor
->GetPoint(), aPt
);
377 bool bRet
= !m_pCurrentCursor
->IsInProtectTable() && !m_pCurrentCursor
->IsSelOvr();
379 UpdateCursor( SwCursorShell::SCROLLWIN
| SwCursorShell::CHKRANGE
|
380 SwCursorShell::READONLY
);
383 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */