xref: /trunk/main/sd/source/ui/slidesorter/controller/SlsFocusManager.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 #include "precompiled_sd.hxx"
29 #include "controller/SlsFocusManager.hxx"
30 
31 #include "SlideSorter.hxx"
32 #include "PaneDockingWindow.hxx"
33 #include "controller/SlideSorterController.hxx"
34 #include "controller/SlsCurrentSlideManager.hxx"
35 #include "controller/SlsVisibleAreaManager.hxx"
36 #include "model/SlideSorterModel.hxx"
37 #include "model/SlsPageDescriptor.hxx"
38 #include "view/SlideSorterView.hxx"
39 #include "view/SlsLayouter.hxx"
40 #include <vcl/toolbox.hxx>
41 
42 #include "Window.hxx"
43 #include "sdpage.hxx"
44 
45 #define UNIFY_FOCUS_AND_CURRENT_PAGE
46 
47 namespace sd { namespace slidesorter { namespace controller {
48 
49 FocusManager::FocusManager (SlideSorter& rSlideSorter)
50     : mrSlideSorter(rSlideSorter),
51       mnPageIndex(0),
52       mbPageIsFocused(false),
53       mbIsVerticalWrapActive(false)
54 {
55     if (mrSlideSorter.GetModel().GetPageCount() > 0)
56         mnPageIndex = 0;
57 }
58 
59 
60 
61 
62 FocusManager::~FocusManager (void)
63 {
64 }
65 
66 
67 
68 
69 void FocusManager::MoveFocus (FocusMoveDirection eDirection)
70 {
71     if (mnPageIndex >= 0 && mbPageIsFocused)
72     {
73         HideFocusIndicator (GetFocusedPageDescriptor());
74 
75         const sal_Int32 nColumnCount (mrSlideSorter.GetView().GetLayouter().GetColumnCount());
76         const sal_Int32 nPageCount (mrSlideSorter.GetModel().GetPageCount());
77         switch (eDirection)
78         {
79             case FMD_NONE:
80                 // Nothing to be done.
81                 break;
82 
83             case FMD_LEFT:
84                 if (mnPageIndex > 0)
85                     mnPageIndex -= 1;
86                 else if (mbIsVerticalWrapActive)
87                     mnPageIndex = nPageCount-1;
88                 break;
89 
90             case FMD_RIGHT:
91                 if (mnPageIndex < nPageCount-1)
92                     mnPageIndex += 1;
93                 else if (mbIsVerticalWrapActive)
94                     mnPageIndex = 0;
95                 break;
96 
97             case FMD_UP:
98             {
99                 const sal_Int32 nCandidate (mnPageIndex - nColumnCount);
100                 if (nCandidate < 0)
101                 {
102                     if (mbIsVerticalWrapActive)
103                     {
104                         // Wrap arround to the bottom row or the one above
105                         // and go to the correct column.
106                         const sal_Int32 nLastIndex (nPageCount-1);
107                         const sal_Int32 nLastColumn (nLastIndex % nColumnCount);
108                         const sal_Int32 nCurrentColumn (mnPageIndex%nColumnCount);
109                         if (nLastColumn >= nCurrentColumn)
110                         {
111                             // The last row contains the current column.
112                             mnPageIndex = nLastIndex - (nLastColumn-nCurrentColumn);
113                         }
114                         else
115                         {
116                             // Only the second to last row contains the current column.
117                             mnPageIndex = nLastIndex - nLastColumn
118                                 - nColumnCount
119                                 + nCurrentColumn;
120                         }
121                     }
122                 }
123                 else
124                 {
125                     // Move the focus the previous row.
126                     mnPageIndex = nCandidate;
127                 }
128             }
129             break;
130 
131             case FMD_DOWN:
132             {
133                 const sal_Int32 nCandidate (mnPageIndex + nColumnCount);
134                 if (nCandidate >= nPageCount)
135                 {
136                     if (mbIsVerticalWrapActive)
137                     {
138                         // Wrap arround to the correct column.
139                         mnPageIndex = mnPageIndex % nColumnCount;
140                     }
141                     else
142                     {
143                         // Do not move the focus.
144                     }
145                 }
146                 else
147                 {
148                     // Move the focus to the next row.
149                     mnPageIndex = nCandidate;
150                 }
151             }
152             break;
153         }
154 
155         if (mnPageIndex < 0)
156         {
157             OSL_ASSERT(mnPageIndex>=0);
158             mnPageIndex = 0;
159         }
160         else if (mnPageIndex >= nPageCount)
161         {
162             OSL_ASSERT(mnPageIndex<nPageCount);
163             mnPageIndex = nPageCount - 1;
164         }
165 
166         if (mbPageIsFocused)
167         {
168             ShowFocusIndicator(GetFocusedPageDescriptor(), true);
169         }
170     }
171 }
172 
173 
174 
175 
176 void FocusManager::ShowFocus (const bool bScrollToFocus)
177 {
178     mbPageIsFocused = true;
179     ShowFocusIndicator(GetFocusedPageDescriptor(), bScrollToFocus);
180 }
181 
182 
183 
184 
185 void FocusManager::HideFocus (void)
186 {
187     mbPageIsFocused = false;
188     HideFocusIndicator(GetFocusedPageDescriptor());
189 }
190 
191 
192 
193 
194 bool FocusManager::ToggleFocus (void)
195 {
196     if (mnPageIndex >= 0)
197     {
198         if (mbPageIsFocused)
199             HideFocus ();
200         else
201             ShowFocus ();
202     }
203     return mbPageIsFocused;
204 }
205 
206 
207 
208 
209 bool FocusManager::HasFocus (void) const
210 {
211     return mrSlideSorter.GetContentWindow()->HasFocus();
212 }
213 
214 
215 
216 
217 model::SharedPageDescriptor FocusManager::GetFocusedPageDescriptor (void) const
218 {
219     return mrSlideSorter.GetModel().GetPageDescriptor(mnPageIndex);
220 }
221 
222 
223 
224 
225 sal_Int32 FocusManager::GetFocusedPageIndex (void) const
226 {
227     return mnPageIndex;
228 }
229 
230 
231 
232 /*
233 void FocusManager::FocusPage (sal_Int32 nPageIndex)
234 {
235     if (nPageIndex != mnPageIndex)
236     {
237         // Hide the focus while switching it to the specified page.
238         FocusHider aHider (*this);
239         mnPageIndex = nPageIndex;
240     }
241 
242     if (HasFocus() && !IsFocusShowing())
243         ShowFocus();
244 }
245 */
246 
247 
248 
249 void FocusManager::SetFocusedPage (const model::SharedPageDescriptor& rpDescriptor)
250 {
251     if (rpDescriptor.get() != NULL)
252     {
253         FocusHider aFocusHider (*this);
254         mnPageIndex = (rpDescriptor->GetPage()->GetPageNum()-1)/2;
255     }
256 }
257 
258 
259 
260 
261 void FocusManager::SetFocusedPage (sal_Int32 nPageIndex)
262 {
263     FocusHider aFocusHider (*this);
264     mnPageIndex = nPageIndex;
265 }
266 
267 
268 
269 
270 void FocusManager::SetFocusedPageToCurrentPage (void)
271 {
272     SetFocusedPage(mrSlideSorter.GetController().GetCurrentSlideManager()->GetCurrentSlide());
273 }
274 
275 
276 
277 
278 bool FocusManager::IsFocusShowing (void) const
279 {
280     return HasFocus() && mbPageIsFocused;
281 }
282 
283 
284 
285 
286 void FocusManager::HideFocusIndicator (const model::SharedPageDescriptor& rpDescriptor)
287 {
288     if (rpDescriptor.get() != NULL)
289     {
290         mrSlideSorter.GetView().SetState(rpDescriptor, model::PageDescriptor::ST_Focused, false);
291     }
292 }
293 
294 
295 
296 
297 void FocusManager::ShowFocusIndicator (
298     const model::SharedPageDescriptor& rpDescriptor,
299     const bool bScrollToFocus)
300 {
301     if (rpDescriptor.get() != NULL)
302     {
303         mrSlideSorter.GetView().SetState(rpDescriptor, model::PageDescriptor::ST_Focused, true);
304 
305         if (bScrollToFocus)
306         {
307             // Scroll the focused page object into the visible area and repaint
308             // it, so that the focus indicator becomes visible.
309             mrSlideSorter.GetController().GetVisibleAreaManager().RequestVisible(rpDescriptor,true);
310         }
311         mrSlideSorter.GetView().RequestRepaint(rpDescriptor);
312 
313         NotifyFocusChangeListeners();
314     }
315 }
316 
317 
318 
319 
320 void FocusManager::AddFocusChangeListener (const Link& rListener)
321 {
322     if (::std::find (maFocusChangeListeners.begin(), maFocusChangeListeners.end(), rListener)
323         == maFocusChangeListeners.end())
324     {
325         maFocusChangeListeners.push_back (rListener);
326     }
327 }
328 
329 
330 
331 
332 void FocusManager::RemoveFocusChangeListener (const Link& rListener)
333 {
334     maFocusChangeListeners.erase (
335         ::std::find (maFocusChangeListeners.begin(), maFocusChangeListeners.end(), rListener));
336 }
337 
338 
339 
340 
341 void FocusManager::SetFocusToToolBox (void)
342 {
343     HideFocus();
344 
345     if (mrSlideSorter.GetViewShell() != NULL)
346     {
347         ::Window* pParentWindow = mrSlideSorter.GetViewShell()->GetParentWindow();
348         DockingWindow* pDockingWindow = NULL;
349         while (pParentWindow!=NULL && pDockingWindow==NULL)
350         {
351             pDockingWindow = dynamic_cast<DockingWindow*>(pParentWindow);
352             pParentWindow = pParentWindow->GetParent();
353         }
354         if (pDockingWindow)
355         {
356             PaneDockingWindow* pPaneDockingWindow = dynamic_cast<PaneDockingWindow*>(pDockingWindow);
357             if (pPaneDockingWindow != NULL)
358                 pPaneDockingWindow->GetToolBox().GrabFocus();
359         }
360     }
361 }
362 
363 
364 
365 
366 void FocusManager::NotifyFocusChangeListeners (void) const
367 {
368     // Create a copy of the listener list to be safe when that is modified.
369     ::std::vector<Link> aListeners (maFocusChangeListeners);
370 
371     // Tell the slection change listeners that the selection has changed.
372     ::std::vector<Link>::iterator iListener (aListeners.begin());
373     ::std::vector<Link>::iterator iEnd (aListeners.end());
374     for (; iListener!=iEnd; ++iListener)
375     {
376         iListener->Call(NULL);
377     }
378 }
379 
380 
381 
382 
383 FocusManager::FocusHider::FocusHider (FocusManager& rManager)
384 : mbFocusVisible(rManager.IsFocusShowing())
385 , mrManager(rManager)
386 {
387     mrManager.HideFocus();
388 }
389 
390 
391 
392 
393 FocusManager::FocusHider::~FocusHider (void)
394 {
395     if (mbFocusVisible)
396         mrManager.ShowFocus();
397 }
398 
399 } } } // end of namespace ::sd::slidesorter::controller
400 
401