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