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