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