LibreOffice Module sw (master)  1
navmgr.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 
10 #include <navmgr.hxx>
11 #include <wrtsh.hxx>
12 #include <sfx2/bindings.hxx>
13 #include <sfx2/viewfrm.hxx>
14 #include <vcl/svapp.hxx>
15 #include <cmdid.h>
16 #include <view.hxx>
17 #include <doc.hxx>
18 #include <unocrsr.hxx>
19 
20 #include <com/sun/star/frame/XLayoutManager.hpp>
21 #include <com/sun/star/beans/XPropertySet.hpp>
22 
23 // This method positions the cursor to the position rPos.
24 
26 
27  // EnterStdMode() prevents the cursor to 'block' the current
28  // shell when it should move from the image back to the normal shell
31  // cursor consists of two SwPositions: Point and Mark.
32  // Such a pair is called a PaM. SwPaM is derived from SwRing.
33  // The Ring contains the single regions of a multi-selection.
34  SwPaM* pPaM = m_rMyShell.GetCursor();
35 
36  if(pPaM->HasMark())
37  pPaM->DeleteMark(); // If there was a selection, get rid of it
38  *pPaM->GetPoint() = rPos; // Position Cursor
39 
41 }
42 
43 // Ctor for the SwNavigationMgr class
44 // Sets the shell to the current shell
45 // and the index of the current position to 0
46 
48  : m_nCurrent(0), m_rMyShell(rShell)
49 {
50 }
51 
53 {
55  for (auto & it : m_entries)
56  {
57  EndListening(it->m_aNotifier);
58  }
59  m_entries.clear();
60 }
61 
63 {
64  // our cursors may now spontaneously self-destruct: remove from
65  // m_entries if that happens
66  if (typeid(rHint) == typeid(sw::UnoCursorHint))
67  {
68  auto it = std::find_if(m_entries.begin(), m_entries.end(),
69  [&rBC](const sw::UnoCursorPointer& rItem) { return !rItem || &rBC == &rItem->m_aNotifier; });
70  if (it != m_entries.end())
71  {
72  EndListening(rBC);
73  m_entries.erase(it);
74  }
75  }
76 }
77 
78 // This method is used by the navigation shell - defined in sw/source/uibase/inc/navsh.hxx
79 // and implemented in sw/source/uibase/shells/navsh.cxx
80 // It is called when we want to check if the back button should be enabled or not.
81 // The back button should be enabled only if there are some entries in the navigation history
82 
84  return (m_nCurrent > 0);
85 }
86 
87 // Similar to backEnabled() method.
88 // The forward button should be enabled if we ever clicked back
89 // Due to the implementation of the navigation class, this is when the
90 // current position within the navigation history entries in not the last one
91 // i.e. when the m_nCurrent index is not at the end of the m_entries vector
92 
94  return m_nCurrent+1 < m_entries.size();
95 }
96 
97 // The goBack() method positions the cursor to the previous entry in the navigation history
98 // If there was no history to go forward to, it adds the current position of the cursor
99 // to the history so we could go forward to where we came from
100 
102 
103  // Although the button should be disabled whenever the backEnabled() returns false,
104  // the UI is sometimes not as responsive as we would like it to be :)
105  // this check prevents segmentation faults and in this way the class is not relying on the UI
106 
107  if (!backEnabled()) return;
108 
109  /* Trying to get the current cursor */
110  SwPaM* pPaM = m_rMyShell.GetCursor();
111  if (!pPaM) {
112  return;
113  }
114  // This flag will be used to manually refresh the buttons
115 
116  bool bForwardWasDisabled = !forwardEnabled();
117 
118  // If we're going backwards in our history, but the current location is not
119  // in the history then we need to add *here* to it so that we can "go
120  // forward" to here again.
121 
122  if (bForwardWasDisabled) {
123 
124  // the cursor consists of two SwPositions: Point and Mark.
125  // We are adding the current Point to the navigation history
126  // so we could later navigate forward to it
127 
128  // The addEntry() method returns true iff we should decrement
129  // the index before navigating back
130 
131  if (addEntry(*pPaM->GetPoint()) ) {
132  m_nCurrent--;
133  }
134  }
135  m_nCurrent--;
136  // Position cursor to appropriate navigation history entry
137  GotoSwPosition(*m_entries[m_nCurrent]->GetPoint());
138  // Refresh the buttons
139  if (bForwardWasDisabled)
141  if (!backEnabled())
143 }
144 
145 // The goForward() method positions the cursor to the next entry in the navigation history
146 
148 
149  // Although the button should be disabled whenever the backForward() returns false,
150  // the UI is sometimes not as responsive as we would like it to be :)
151  // this check prevents segmentation faults and in this way the class is not relying on the UI
152 
153  if (!forwardEnabled()) return;
154 
155  // This flag will be used to manually refresh the buttons
156  bool bBackWasDisabled = !backEnabled();
157  // The current index is positioned at the current entry in the navigation history
158  // We have to increment it to go to the next entry
159  m_nCurrent++;
160  GotoSwPosition(*m_entries[m_nCurrent]->GetPoint());
161  // Refresh the buttons
162  if (bBackWasDisabled)
164  if (!forwardEnabled())
166 }
167 
168 // This method adds the SwPosition rPos to the navigation history
169 // rPos is usually the current position of the cursor in the document
170 
172 
173  // For additions other than to the end, check here if the cursor position has changed
174  if (m_nCurrent < m_entries.size() && (rPos == *m_entries[m_nCurrent]->GetPoint()))
175  return false;
176 
177  // Flags that will be used for refreshing the buttons
178  bool bBackWasDisabled = !backEnabled();
179  bool bForwardWasEnabled = forwardEnabled();
180 
181  bool bRet = false; // return value of the function.
182  // Indicates whether the index should be decremented before
183  // jumping back or not
184  // The navigation history has recency with temporal ordering enhancement,
185  // as described on http://zing.ncsl.nist.gov/hfweb/proceedings/greenberg/
186  // If any forward history exists, twist the tail of the
187  // list from the current position to the end
188  if (bForwardWasEnabled) {
189 
190  size_t number_ofm_entries = m_entries.size(); // To avoid calling m_entries.size() multiple times
191  int curr = m_nCurrent; // Index from which we'll twist the tail.
192  int n = (number_ofm_entries - curr) / 2; // Number of entries that will swap places
193  for (int i = 0; i < n; i++) {
194  std::swap(m_entries[curr + i], m_entries[number_ofm_entries -1 - i]);
195  }
196 
197  if (*m_entries.back()->GetPoint() != rPos)
198  {
200  StartListening(pCursor->m_aNotifier);
201  m_entries.push_back(pCursor);
202  }
203  bRet = true;
204  }
205  else {
206  if ( (!m_entries.empty() && *m_entries.back()->GetPoint() != rPos) || m_entries.empty() ) {
208  StartListening(pCursor->m_aNotifier);
209  m_entries.push_back(pCursor);
210  bRet = true;
211  }
212  if (m_entries.size() > 1 && *m_entries.back()->GetPoint() == rPos)
213  bRet = true;
214  if (m_entries.size() == 1 && *m_entries.back()->GetPoint() == rPos)
215  bRet = false;
216  }
217  m_nCurrent = m_entries.size();
218 
219  // Refresh buttons
220  if (bBackWasDisabled)
222  if (bForwardWasEnabled)
224 
225  return bRet;
226 }
227 
228 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
SfxViewFrame * GetViewFrame() const
std::shared_ptr< SwUnoCursor > CreateUnoCursor(const SwPosition &rPos, bool bTableCursor=false)
Definition: doc.cxx:1776
void DeleteMark()
Definition: pam.hxx:177
Marks a position in the document model.
Definition: pam.hxx:35
SwPaM * GetCursor(bool bMakeTableCursor=true) const
Return pointer to the current shell cursor.
Definition: crsrsh.cxx:194
bool forwardEnabled()
Definition: navmgr.cxx:93
#define FN_NAVIGATION_FORWARD
Definition: cmdid.h:614
sal_Int64 n
bool addEntry(const SwPosition &rPos)
Definition: navmgr.cxx:171
void EnterStdMode()
Definition: select.cxx:551
void Invalidate(sal_uInt16 nId)
void EndAllAction()
Definition: edws.cxx:97
Used by the UI to modify the document model.
Definition: wrtsh.hxx:93
void goBack()
Definition: navmgr.cxx:101
const SwView & GetView() const
Definition: wrtsh.hxx:431
Stack_t::size_type m_nCurrent
Definition: navmgr.hxx:34
SwDoc * GetDoc() const
Definition: viewsh.hxx:281
void GotoSwPosition(const SwPosition &rPos)
Definition: navmgr.cxx:25
PaM is Point and Mark: a selection of the document model.
Definition: pam.hxx:136
Stack_t m_entries
Definition: navmgr.hxx:33
void goForward()
Definition: navmgr.cxx:147
int i
bool backEnabled()
Definition: navmgr.cxx:83
const SwPosition * GetPoint() const
Definition: pam.hxx:207
SwNavigationMgr(SwWrtShell &rShell)
Definition: navmgr.cxx:47
SfxBindings & GetBindings()
bool HasMark() const
A PaM marks a selection if Point and Mark are distinct positions.
Definition: pam.hxx:205
void StartListening(SfxBroadcaster &rBroadcaster, DuplicateHandling eDuplicateHanding=DuplicateHandling::Unexpected)
SwWrtShell & m_rMyShell
Definition: navmgr.hxx:35
void EndListening(SfxBroadcaster &rBroadcaster, bool bRemoveAllDuplicates=false)
#define FN_NAVIGATION_BACK
Definition: cmdid.h:613
virtual void Notify(SfxBroadcaster &rBC, const SfxHint &rHint) override
Definition: navmgr.cxx:62
~SwNavigationMgr() override
Definition: navmgr.cxx:52
void StartAllAction()
For all views of this document.
Definition: edws.cxx:86