bump product version to 4.1.6.2
[LibreOffice.git] / sw / source / ui / wrtsh / navmgr.cxx
blobc140ade33f4053ae670ee581d418b673c1e03044
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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/.
8 */
10 #include "navmgr.hxx"
11 #include "wrtsh.hxx"
12 #include <sfx2/bindings.hxx>
13 #include <sfx2/viewfrm.hxx>
14 #include <cmdid.h>
15 #include <view.hxx>
16 #include <doc.hxx>
17 #include <unocrsr.hxx>
19 #include <com/sun/star/frame/XLayoutManager.hpp>
21 /**
22 * If SMART is defined, the navigation history has recency with temporal ordering enhancement,
23 * as described on http://zing.ncsl.nist.gov/hfweb/proceedings/greenberg/
26 #define SMART 1
28 // This method positions the cursor to the position rPos.
30 void SwNavigationMgr::GotoSwPosition(const SwPosition &rPos) {
31 // EnterStdMode() prevents the cursor to 'block' the current
32 // shell when it should move from the image back to the normal shell
33 m_rMyShell.EnterStdMode();
34 m_rMyShell.StartAllAction();
35 // cursor consists of two SwPositions: Point and Mark.
36 // Such a pair is called a PaM. SwPaM is derived from SwRing.
37 // The Ring contains the single regions of a multi-selection.
38 SwPaM* pPaM = m_rMyShell.GetCrsr();
40 if(pPaM->HasMark())
41 pPaM->DeleteMark(); // If there was a selection, get rid of it
42 *pPaM->GetPoint() = rPos; // Position Cursor
44 m_rMyShell.EndAllAction();
47 // Ctor for the SwNavigationMgr class
48 // Sets the shell to the current shell
49 // and the index of the current position to 0
51 SwNavigationMgr::SwNavigationMgr(SwWrtShell & rShell)
52 : m_nCurrent(0), m_rMyShell(rShell)
56 // This method is used by the navigation shell - defined in sw/source/ui/inc/navsh.hxx
57 // and implemented in sw/source/ui/shells/navsh.cxx
58 // It is called when we want to check if the back button should be enabled or not.
59 // The back button should be enabled only if there are some entries in the navigation history
61 bool SwNavigationMgr::backEnabled() {
62 return (m_nCurrent > 0);
65 // Similar to backEnabled() method.
66 // The forward button should be enabled if we ever clicked back
67 // Due to the implementation of the navigation class, this is when the
68 // current position within the navigation history entries in not the last one
69 // i.e. when the m_nCurrent index is not at the end of the m_entries vector
71 bool SwNavigationMgr::forwardEnabled() {
72 return m_nCurrent+1 < m_entries.size();
75 // The goBack() method positions the cursor to the previous entry in the navigation history
76 // If there was no history to go forward to, it adds the current position of the cursor
77 // to the history so we could go forward to where we came from
79 void SwNavigationMgr::goBack() {
81 // Although the button should be disabled whenever the backEnabled() returns false,
82 // the UI is sometimes not as responsive as we would like it to be :)
83 // this check prevents segmentation faults and in this way the class is not relying on the UI
85 if (backEnabled()) {
86 /* Trying to get the current cursor */
87 SwPaM* pPaM = m_rMyShell.GetCrsr();
88 if (!pPaM) {
89 return;
91 // This flag will be used to manually refresh the buttons
93 bool bForwardWasDisabled = !forwardEnabled();
95 // If we're going backwards in our history, but the current location is not
96 // in the history then we need to add *here* to it so that we can "go
97 // forward" to here again.
99 if (bForwardWasDisabled) {
101 // the cursor consists of two SwPositions: Point and Mark.
102 // We are adding the current Point to the navigation history
103 // so we could later navigate forward to it
105 // The addEntry() method returns true iff we should decrement
106 // the index before navigating back
108 if (addEntry(*pPaM->GetPoint()) ) {
109 m_nCurrent--;
112 m_nCurrent--;
113 // Position cursor to appropriate navigation history entry
114 GotoSwPosition(*m_entries[m_nCurrent]->GetPoint());
115 // Refresh the buttons
116 if (bForwardWasDisabled)
117 m_rMyShell.GetView().GetViewFrame()->GetBindings().Invalidate(FN_NAVIGATION_FORWARD);
118 if (!backEnabled())
119 m_rMyShell.GetView().GetViewFrame()->GetBindings().Invalidate(FN_NAVIGATION_BACK);
123 // The goForward() method positions the cursor to the next entry in the navigation history
125 void SwNavigationMgr::goForward() {
127 // Although the button should be disabled whenever the backForward() returns false,
128 // the UI is sometimes not as responsive as we would like it to be :)
129 // this check prevents segmentation faults and in this way the class is not relying on the UI
131 if (forwardEnabled()) {
132 // This flag will be used to manually refresh the buttons
133 bool bBackWasDisabled = !backEnabled();
134 // The current index is positioned at the current entry in the navigation history
135 // We have to increment it to go to the next entry
136 m_nCurrent++;
137 GotoSwPosition(*m_entries[m_nCurrent]->GetPoint());
138 // Refresh the buttons
139 if (bBackWasDisabled)
140 m_rMyShell.GetView().GetViewFrame()->GetBindings().Invalidate(FN_NAVIGATION_BACK);
141 if (!forwardEnabled())
142 m_rMyShell.GetView().GetViewFrame()->GetBindings().Invalidate(FN_NAVIGATION_FORWARD);
146 // This method adds the SwPosition rPos to the navigation history
147 // rPos is usually the current position of the cursor in the document
149 bool SwNavigationMgr::addEntry(const SwPosition& rPos) {
150 // Flags that will be used for refreshing the buttons
151 bool bBackWasDisabled = !backEnabled();
152 bool bForwardWasEnabled = forwardEnabled();
154 bool bRet = false; // return value of the function.
155 // Indicates whether the index should be decremented before
156 // jumping back or not
157 #if SMART
158 // If any forward history exists, twist the tail of the
159 // list from the current position to the end
160 if (bForwardWasEnabled) {
162 size_t number_ofm_entries = m_entries.size(); // To avoid calling m_entries.size() multiple times
163 int curr = m_nCurrent; // Index from which we'll twist the tail.
164 int n = (number_ofm_entries - curr) / 2; // Number of entries that will swap places
165 for (int i = 0; i < n; i++) {
166 ::std::swap(m_entries[curr + i], m_entries[number_ofm_entries -1 - i]);
169 if (*m_entries.back()->GetPoint() != rPos)
171 SwUnoCrsr *const pCursor = m_rMyShell.GetDoc()->CreateUnoCrsr(rPos);
172 m_entries.push_back(::boost::shared_ptr<SwUnoCrsr>(pCursor));
174 bRet = true;
176 else {
177 if ( (!m_entries.empty() && *m_entries.back()->GetPoint() != rPos) || m_entries.empty() ) {
178 SwUnoCrsr *const pCursor = m_rMyShell.GetDoc()->CreateUnoCrsr(rPos);
179 m_entries.push_back(::boost::shared_ptr<SwUnoCrsr>(pCursor));
180 bRet = true;
182 if (m_entries.size() > 1 && *m_entries.back()->GetPoint() == rPos)
183 bRet = true;
184 if (m_entries.size() == 1 && *m_entries.back()->GetPoint() == rPos)
185 bRet = false;
187 #else
188 m_entries.erase(m_entries.begin() + m_nCurrent, m_entries.end());
189 SwUnoCrsr *const pCursor = m_rMyShell.GetDoc()->CreateUnoCrsr(rPos);
190 m_entries.push_back(::boost::shared_ptr<SwUnoCrsr>(pCursor));
191 bRet = true;
192 #endif
193 m_nCurrent = m_entries.size();
195 // Refresh buttons
196 if (bBackWasDisabled)
197 m_rMyShell.GetView().GetViewFrame()->GetBindings().Invalidate(FN_NAVIGATION_BACK);
198 if (bForwardWasEnabled)
199 m_rMyShell.GetView().GetViewFrame()->GetBindings().Invalidate(FN_NAVIGATION_FORWARD);
201 // show the Navigation toolbar
202 css::uno::Reference< css::frame::XFrame > xFrame =
203 m_rMyShell.GetView().GetViewFrame()->GetFrame().GetFrameInterface();
204 if (xFrame.is())
206 css::uno::Reference< css::beans::XPropertySet > xPropSet(xFrame, css::uno::UNO_QUERY);
207 if (xPropSet.is())
209 css::uno::Reference< css::frame::XLayoutManager > xLayoutManager;
210 css::uno::Any aValue = xPropSet->getPropertyValue( OUString( "LayoutManager" ) );
212 aValue >>= xLayoutManager;
213 if (xLayoutManager.is())
215 const OUString sResourceURL( "private:resource/toolbar/navigationobjectbar" );
216 css::uno::Reference< css::ui::XUIElement > xUIElement = xLayoutManager->getElement(sResourceURL);
217 if (!xUIElement.is())
219 xLayoutManager->createElement( sResourceURL );
220 xLayoutManager->showElement( sResourceURL );
226 return bRet;
228 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */