LibreOffice Module sw (master)  1
trvlfnfl.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  * Licensed to the Apache Software Foundation (ASF) under one or more
12  * contributor license agreements. See the NOTICE file distributed
13  * with this work for additional information regarding copyright
14  * ownership. The ASF licenses this file to you under the Apache
15  * License, Version 2.0 (the "License"); you may not use this file
16  * except in compliance with the License. You may obtain a copy of
17  * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 #include <svx/svdmodel.hxx>
21 #include <svx/svdpage.hxx>
22 #include <crsrsh.hxx>
23 #include <doc.hxx>
24 #include <pagefrm.hxx>
25 #include <cntfrm.hxx>
26 #include <ftnfrm.hxx>
27 #include <viewimp.hxx>
28 #include <swcrsr.hxx>
29 #include <dflyobj.hxx>
30 #include <ndtxt.hxx>
31 #include <flyfrm.hxx>
32 #include <txtfrm.hxx>
33 #include <txtftn.hxx>
34 #include <ftnidx.hxx>
35 #include <viscrs.hxx>
36 #include "callnk.hxx"
37 #include <svx/srchdlg.hxx>
38 
39 bool SwCursorShell::CallCursorShellFN( FNCursorShell fnCursor )
40 {
41  SwCallLink aLk( *this ); // watch Cursor-Moves
42  bool bRet = (this->*fnCursor)();
43  if( bRet )
46  return bRet;
47 }
48 
49 bool SwCursorShell::CallCursorFN( FNCursor fnCursor )
50 {
51  SwCallLink aLk( *this ); // watch Cursor-Moves
52  SwCursor* pCursor = getShellCursor( true );
53  bool bRet = (pCursor->*fnCursor)();
54  if( bRet )
57  return bRet;
58 }
59 
61 {
62  // jump from content to footnote
63  bool bRet = false;
64  SwTextNode* pTextNd = GetPoint()->nNode.GetNode().GetTextNode();
65 
66  SwTextAttr *const pFootnote( pTextNd
67  ? pTextNd->GetTextAttrForCharAt(
68  GetPoint()->nContent.GetIndex(), RES_TXTATR_FTN)
69  : nullptr);
70  if (pFootnote)
71  {
72  SwCursorSaveState aSaveState( *this );
73  GetPoint()->nNode = *static_cast<SwTextFootnote*>(pFootnote)->GetStartNode();
74 
76  &GetPoint()->nNode,
77  true, !IsReadOnlyAvailable() );
78  if( pCNd )
79  {
80  GetPoint()->nContent.Assign( pCNd, 0 );
83  }
84  }
85  return bRet;
86 }
87 
89 {
91  if( !bRet )
92  {
93  SwTextNode* pTextNd = GetCursor_() ?
94  GetCursor_()->GetPoint()->nNode.GetNode().GetTextNode() : nullptr;
95  if( pTextNd )
96  {
97  std::pair<Point, bool> const tmp(GetCursor_()->GetSttPos(), true);
98  const SwFrame *pFrame = pTextNd->getLayoutFrame( GetLayout(),
99  GetCursor_()->Start(), &tmp);
100  const SwFootnoteBossFrame* pFootnoteBoss;
101  bool bSkip = pFrame && pFrame->IsInFootnote();
102  while( pFrame && nullptr != ( pFootnoteBoss = pFrame->FindFootnoteBossFrame() ) )
103  {
104  if( nullptr != ( pFrame = pFootnoteBoss->FindFootnoteCont() ) )
105  {
106  if( bSkip )
107  bSkip = false;
108  else
109  {
110  const SwContentFrame* pCnt = static_cast<const SwLayoutFrame*>
111  (pFrame)->ContainsContent();
112  if( pCnt )
113  {
114  SwTextFrame const*const pTF(
115  static_cast<const SwTextFrame*>(pCnt));
116  *GetCursor_()->GetPoint() =
117  pTF->MapViewToModelPos(pTF->GetOfst());
120  bRet = true;
121  break;
122  }
123  }
124  }
125  if( pFootnoteBoss->GetNext() && !pFootnoteBoss->IsPageFrame() )
126  pFrame = pFootnoteBoss->GetNext();
127  else
128  pFrame = pFootnoteBoss->GetUpper();
129  }
130  }
131  }
132  return bRet;
133 }
134 
136 {
137  // jump from footnote to anchor
138  const SwNode* pSttNd = GetNode().FindFootnoteStartNode();
139  if( pSttNd )
140  {
141  // search in all footnotes in document for this StartIndex
142  const SwTextFootnote* pTextFootnote;
143  const SwFootnoteIdxs& rFootnoteArr = pSttNd->GetDoc()->GetFootnoteIdxs();
144  for( size_t n = 0; n < rFootnoteArr.size(); ++n )
145  if( nullptr != ( pTextFootnote = rFootnoteArr[ n ])->GetStartNode() &&
146  pSttNd == &pTextFootnote->GetStartNode()->GetNode() )
147  {
148  SwCursorSaveState aSaveState( *this );
149 
150  SwTextNode& rTNd = const_cast<SwTextNode&>(pTextFootnote->GetTextNode());
151  GetPoint()->nNode = rTNd;
152  GetPoint()->nContent.Assign( &rTNd, pTextFootnote->GetStart() );
153 
156  }
157  }
158  return false;
159 }
160 
162 {
163  // jump from footnote to anchor
164  SwCallLink aLk( *this ); // watch Cursor-Moves
165  bool bRet = m_pCurrentCursor->GotoFootnoteAnchor();
166  if( bRet )
167  {
168  // special treatment for table header row
172  }
173  return bRet;
174 }
175 
176 static bool CmpLE( const SwTextFootnote& rFootnote, sal_uLong nNd, sal_Int32 nCnt )
177 {
178  const sal_uLong nTNd = rFootnote.GetTextNode().GetIndex();
179  return nTNd < nNd || ( nTNd == nNd && rFootnote.GetStart() <= nCnt );
180 }
181 
182 static bool CmpL( const SwTextFootnote& rFootnote, sal_uLong nNd, sal_Int32 nCnt )
183 {
184  const sal_uLong nTNd = rFootnote.GetTextNode().GetIndex();
185  return nTNd < nNd || ( nTNd == nNd && rFootnote.GetStart() < nCnt );
186 }
187 
189 {
190  const SwFootnoteIdxs& rFootnoteArr = GetDoc()->GetFootnoteIdxs();
191  const SwTextFootnote* pTextFootnote = nullptr;
192  size_t nPos = 0;
193 
194  if( rFootnoteArr.empty() )
195  {
196  SvxSearchDialogWrapper::SetSearchLabel( SearchLabel::NavElementNotFound );
197  return false;
198  }
199 
200  if( rFootnoteArr.SeekEntry( GetPoint()->nNode, &nPos ))
201  {
202  // there is a footnote with this index, so search also for the next one
203  if( nPos < rFootnoteArr.size() )
204  {
205  sal_uLong nNdPos = GetPoint()->nNode.GetIndex();
206  const sal_Int32 nCntPos = GetPoint()->nContent.GetIndex();
207 
208  pTextFootnote = rFootnoteArr[ nPos ];
209  // search forwards
210  if( CmpLE( *pTextFootnote, nNdPos, nCntPos ) )
211  {
212  pTextFootnote = nullptr;
213  for( ++nPos; nPos < rFootnoteArr.size(); ++nPos )
214  {
215  pTextFootnote = rFootnoteArr[ nPos ];
216  if( !CmpLE( *pTextFootnote, nNdPos, nCntPos ) )
217  break; // found
218  pTextFootnote = nullptr;
219  }
220  }
221  else if( nPos )
222  {
223  // search backwards
224  pTextFootnote = nullptr;
225  while( nPos )
226  {
227  pTextFootnote = rFootnoteArr[ --nPos ];
228  if( CmpLE( *pTextFootnote, nNdPos, nCntPos ) )
229  {
230  pTextFootnote = rFootnoteArr[ ++nPos ];
231  break; // found
232  }
233  }
234  }
235  }
236  }
237  else if( nPos < rFootnoteArr.size() )
238  pTextFootnote = rFootnoteArr[ nPos ];
239 
240  if (pTextFootnote == nullptr)
241  {
242  pTextFootnote = rFootnoteArr[ 0 ];
243  SvxSearchDialogWrapper::SetSearchLabel( SearchLabel::EndWrapped );
244  }
245  else
246  SvxSearchDialogWrapper::SetSearchLabel( SearchLabel::Empty );
247 
248  bool bRet = nullptr != pTextFootnote;
249  if( bRet )
250  {
251  SwCursorSaveState aSaveState( *this );
252 
253  SwTextNode& rTNd = const_cast<SwTextNode&>(pTextFootnote->GetTextNode());
254  GetPoint()->nNode = rTNd;
255  GetPoint()->nContent.Assign( &rTNd, pTextFootnote->GetStart() );
256  bRet = !IsSelOvr();
257  }
258  return bRet;
259 }
260 
262 {
263  const SwFootnoteIdxs& rFootnoteArr = GetDoc()->GetFootnoteIdxs();
264  const SwTextFootnote* pTextFootnote = nullptr;
265  size_t nPos = 0;
266 
267  if( rFootnoteArr.empty() )
268  {
269  SvxSearchDialogWrapper::SetSearchLabel( SearchLabel::NavElementNotFound );
270  return false;
271  }
272 
273  if( rFootnoteArr.SeekEntry( GetPoint()->nNode, &nPos ) )
274  {
275  // there is a footnote with this index, so search also for the next one
276  sal_uLong nNdPos = GetPoint()->nNode.GetIndex();
277  const sal_Int32 nCntPos = GetPoint()->nContent.GetIndex();
278 
279  pTextFootnote = rFootnoteArr[ nPos ];
280  // search forwards
281  if( CmpL( *pTextFootnote, nNdPos, nCntPos ))
282  {
283  for( ++nPos; nPos < rFootnoteArr.size(); ++nPos )
284  {
285  pTextFootnote = rFootnoteArr[ nPos ];
286  if( !CmpL( *pTextFootnote, nNdPos, nCntPos ) )
287  {
288  pTextFootnote = rFootnoteArr[ nPos-1 ];
289  break;
290  }
291  }
292  }
293  else if( nPos )
294  {
295  // search backwards
296  pTextFootnote = nullptr;
297  while( nPos )
298  {
299  pTextFootnote = rFootnoteArr[ --nPos ];
300  if( CmpL( *pTextFootnote, nNdPos, nCntPos ))
301  break; // found
302  pTextFootnote = nullptr;
303  }
304  }
305  else
306  pTextFootnote = nullptr;
307  }
308  else if( nPos )
309  pTextFootnote = rFootnoteArr[ nPos-1 ];
310 
311  if( pTextFootnote == nullptr )
312  {
313  pTextFootnote = rFootnoteArr[ rFootnoteArr.size() - 1 ];
314  SvxSearchDialogWrapper::SetSearchLabel( SearchLabel::StartWrapped );
315  }
316  else
317  SvxSearchDialogWrapper::SetSearchLabel( SearchLabel::Empty );
318 
319  bool bRet = nullptr != pTextFootnote;
320  if( bRet )
321  {
322  SwCursorSaveState aSaveState( *this );
323 
324  SwTextNode& rTNd = const_cast<SwTextNode&>(pTextFootnote->GetTextNode());
325  GetPoint()->nNode = rTNd;
326  GetPoint()->nContent.Assign( &rTNd, pTextFootnote->GetStart() );
327  bRet = !IsSelOvr();
328  }
329  return bRet;
330 }
331 
333 {
335 }
336 
338 {
340 }
341 
344 {
345  SET_CURR_SHELL( this );
346  const SwFrame* pFrame = GetCurrFrame();
347  do {
348  pFrame = pFrame->GetUpper();
349  } while( pFrame && !pFrame->IsFlyFrame() );
350 
351  if( !pFrame ) // no FlyFrame
352  return;
353 
354  SwCallLink aLk( *this ); // watch Cursor-Moves
355  SwCursorSaveState aSaveState( *m_pCurrentCursor );
356 
357  // jump in BodyFrame closest to FlyFrame
358  SwRect aTmpRect( m_aCharRect );
359  if( !pFrame->getFrameArea().IsInside( aTmpRect ))
360  aTmpRect = pFrame->getFrameArea();
361  Point aPt( aTmpRect.Left(), aTmpRect.Top() +
362  ( aTmpRect.Bottom() - aTmpRect.Top() ) / 2 );
363  aPt.setX(aPt.getX() > (pFrame->getFrameArea().Left() + (pFrame->getFrameArea().SSize().Width() / 2 ))
364  ? pFrame->getFrameArea().Right()
365  : pFrame->getFrameArea().Left());
366 
367  const SwPageFrame* pPageFrame = pFrame->FindPageFrame();
368  const SwContentFrame* pFndFrame = pPageFrame->GetContentPos( aPt, false, true );
369  pFndFrame->GetCursorOfst( m_pCurrentCursor->GetPoint(), aPt );
370 
372  if( bRet )
375 }
376 
377 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
Base class of the Writer layout elements.
Definition: frame.hxx:295
Represents the visualization of a paragraph.
Definition: txtfrm.hxx:149
sal_uLong GetIndex() const
Definition: node.hxx:282
SAL_DLLPRIVATE void UpdateCursor(sal_uInt16 eFlags=SwCursorShell::SCROLLWIN|SwCursorShell::CHKRANGE, bool bIdleEnd=false)
Definition: crsrsh.cxx:1552
SwNode & GetNode(bool bPoint=true) const
Definition: pam.hxx:223
SwShellCursor * m_pCurrentCursor
current cursor
Definition: crsrsh.hxx:179
bool IsInProtectTable(bool bMove=false, bool bChgCursor=true)
Definition: swcrsr.cxx:545
bool GotoNextFootnoteAnchor()
Definition: trvlfnfl.cxx:332
check overlapping PaMs
Definition: crsrsh.hxx:158
SwNodeIndex nNode
Definition: pam.hxx:37
bool IsInFootnote() const
Definition: frame.hxx:925
SwShellCursor * getShellCursor(bool bBlock)
Delivers the current shell cursor.
Definition: crsrsh.cxx:2923
sal_uIntPtr sal_uLong
SwContentFrame * getLayoutFrame(const SwRootFrame *, const SwPosition *pPos=nullptr, std::pair< Point, bool > const *pViewPosAndCalcFrame=nullptr) const
Definition: node.cxx:1150
virtual bool IsSelOvr(SwCursorSelOverFlags eFlags=SwCursorSelOverFlags::CheckNodeSection|SwCursorSelOverFlags::Toggle|SwCursorSelOverFlags::ChangePos)
Definition: swcrsr.cxx:216
TextFrameIndex GetOfst() const
Definition: txtfrm.hxx:426
SwNode & GetNode() const
Definition: ndindex.hxx:118
bool GotoFootnoteAnchor()
jump from footnote to anchor
Definition: trvlfnfl.cxx:161
Of course Writer needs its own rectangles.
Definition: swrect.hxx:34
bool GotoNextFootnoteAnchor()
Definition: trvlfnfl.cxx:188
SwTextAttr * GetTextAttrForCharAt(const sal_Int32 nIndex, const sal_uInt16 nWhich=RES_TXTATR_END) const
get the text attribute at position nIndex which owns the dummy character CH_TXTATR_* at that position...
Definition: ndtxt.cxx:3058
bool IsFlyFrame() const
Definition: frame.hxx:1186
void Top(const long nTop)
Definition: swrect.hxx:202
SwIndex nContent
Definition: pam.hxx:38
const SwRect & getFrameArea() const
Definition: frame.hxx:175
void setX(long nX)
SwFootnoteContFrame * FindFootnoteCont()
Definition: ftnfrm.cxx:964
bool GotoFootnoteText()
jump from content to footnote
Definition: trvlfnfl.cxx:88
sal_uLong GetIndex() const
Definition: ndindex.hxx:151
sal_Int32 GetStart() const
Definition: txatbase.hxx:82
static bool CmpL(const SwTextFootnote &rFootnote, sal_uLong nNd, sal_Int32 nCnt)
Definition: trvlfnfl.cxx:182
void Right(const long nRight)
Definition: swrect.hxx:198
size_type size() const
SwShellCursor * GetCursor_()
Definition: crsrsh.hxx:330
long getX() const
static SwNodePtr GetStartNode(SwOutlineNodes const *pOutlNds, int nOutlineLevel, SwOutlineNodes::size_type *nOutl)
Definition: docglbl.cxx:90
SwTextFootnote * SeekEntry(const SwNodeIndex &rIdx, size_t *pPos=nullptr) const
Definition: ftnidx.cxx:409
A helper class to save cursor state (position).
Definition: swcrsr.hxx:230
const SwPosition * GetPoint() const
Definition: pam.hxx:207
SwIndex & Assign(SwIndexReg *, sal_Int32)
Definition: index.cxx:198
#define RES_TXTATR_FTN
Definition: hintids.hxx:152
SwPageFrame * FindPageFrame()
Definition: frame.hxx:658
SwDoc * GetDoc()
Definition: node.hxx:702
bool GotoFootnoteText()
Definition: trvlfnfl.cxx:60
SwDoc * GetDoc() const
Definition: pam.hxx:243
SwLayoutFrame * GetUpper()
Definition: frame.hxx:656
SwFootnoteBossFrame * FindFootnoteBossFrame(bool bFootnotes=false)
Definition: findfrm.cxx:435
#define SET_CURR_SHELL(shell)
Definition: swtypes.hxx:101
bool empty() const
void SSize(const Size &rNew)
Definition: swrect.hxx:176
bool GotoPrevFootnoteAnchor()
Definition: trvlfnfl.cxx:261
static bool CmpLE(const SwTextFootnote &rFootnote, sal_uLong nNd, sal_Int32 nCnt)
Definition: trvlfnfl.cxx:176
A page of the document layout.
Definition: pagefrm.hxx:40
virtual bool GetCursorOfst(SwPosition *, Point &, SwCursorMoveState *=nullptr, bool bTestBackground=false) const
Definition: unusedf.cxx:46
static void SetSearchLabel(const SearchLabel &rSL)
bool GotoPrevFootnoteAnchor()
Definition: trvlfnfl.cxx:337
virtual bool IsReadOnlyAvailable() const
Definition: swcrsr.cxx:144
void Left(const long nLeft)
Definition: swrect.hxx:193
SwTextNode is a paragraph in the document model.
Definition: ndtxt.hxx:79
void Bottom(const long nBottom)
Definition: swrect.hxx:207
SwContentFrame * GetCurrFrame(const bool bCalcFrame=true) const
Get current frame in which the cursor is positioned.
Definition: crsrsh.cxx:2350
sal_Int32 GetIndex() const
Definition: index.hxx:95
bool IsInside(const Point &rPOINT) const
Definition: swrect.cxx:110
SwNodes & GetNodes()
Definition: doc.hxx:403
bool IsPageFrame() const
Definition: frame.hxx:1154
const Point & GetPtPos() const
Definition: viscrs.hxx:140
scroll window
Definition: crsrsh.hxx:157
SAL_DLLPRIVATE bool CallCursorShellFN(FNCursorShell)
Definition: trvlfnfl.cxx:39
SwNodeIndex * GetStartNode() const
Definition: txtftn.hxx:41
SwFootnoteIdxs & GetFootnoteIdxs()
Definition: doc.hxx:628
SwContentNode * GoNextSection(SwNodeIndex *, bool bSkipHidden=true, bool bSkipProtect=true) const
Go to next content-node that is not protected or hidden (Both set FALSE ==> GoNext/GoPrevious!!!).
Definition: nodes.cxx:1923
make visible in spite of Readonly
Definition: crsrsh.hxx:159
void GotoFlyAnchor()
jump from the frame to the anchor
Definition: trvlfnfl.cxx:343
bool GotoFootnoteAnchor()
Definition: trvlfnfl.cxx:135
SwRect m_aCharRect
Char-SRectangle on which the cursor is located.
Definition: crsrsh.hxx:168
SwRootFrame * GetLayout() const
Definition: viewsh.cxx:2072
sal_Int32 nPos
const SwContentFrame * GetContentPos(Point &rPoint, const bool bDontLeave, const bool bBodyOnly=false, SwCursorMoveState *pCMS=nullptr, const bool bDefaultExpand=true) const
Finds the closest Content for the SPoint Is used for Pages, Flys and Cells if GetCursorOfst failed...
Definition: trvlfrm.cxx:1179
SwPosition MapViewToModelPos(TextFrameIndex nIndex) const
Definition: txtfrm.cxx:1237
SAL_DLLPRIVATE bool CallCursorFN(FNCursor)
Definition: trvlfnfl.cxx:49
const SwTextNode & GetTextNode() const
Definition: txtftn.hxx:69
const SwStartNode * FindFootnoteStartNode() const
Definition: node.hxx:200
SwTextNode * GetTextNode()
Inline methods from Node.hxx.
Definition: ndtxt.hxx:843
SwFrame * GetNext()
Definition: frame.hxx:654
Base class of the Writer document model elements.
Definition: node.hxx:79