xref: /trunk/main/sd/source/ui/slidesorter/controller/SlsCurrentSlideManager.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 
30 #include "SlideSorter.hxx"
31 #include "model/SlideSorterModel.hxx"
32 #include "model/SlsPageDescriptor.hxx"
33 #include "controller/SlsPageSelector.hxx"
34 #include "controller/SlideSorterController.hxx"
35 #include "controller/SlsCurrentSlideManager.hxx"
36 #include "controller/SlsFocusManager.hxx"
37 #include "view/SlideSorterView.hxx"
38 #include "ViewShellBase.hxx"
39 #include "ViewShell.hxx"
40 #include "DrawViewShell.hxx"
41 #include "sdpage.hxx"
42 #include "FrameView.hxx"
43 #include <com/sun/star/beans/XPropertySet.hpp>
44 
45 using namespace ::com::sun::star;
46 using namespace ::com::sun::star::uno;
47 
48 using namespace ::sd::slidesorter::model;
49 
50 
51 namespace sd { namespace slidesorter { namespace controller {
52 
53 
54 CurrentSlideManager::CurrentSlideManager (SlideSorter& rSlideSorter)
55     : mrSlideSorter(rSlideSorter),
56       mnCurrentSlideIndex(-1),
57       mpCurrentSlide(),
58       maSwitchPageDelayTimer()
59 {
60     maSwitchPageDelayTimer.SetTimeout(100);
61     maSwitchPageDelayTimer.SetTimeoutHdl(LINK(this,CurrentSlideManager,SwitchPageCallback));
62 }
63 
64 
65 
66 
67 CurrentSlideManager::~CurrentSlideManager (void)
68 {
69 }
70 
71 
72 
73 
74 void CurrentSlideManager::NotifyCurrentSlideChange (const SdPage* pPage)
75 {
76     if (pPage != NULL)
77         NotifyCurrentSlideChange(
78             mrSlideSorter.GetModel().GetIndex(
79                 Reference<drawing::XDrawPage>(
80                     const_cast<SdPage*>(pPage)->getUnoPage(),
81                     UNO_QUERY)));
82     else
83         NotifyCurrentSlideChange(-1);
84 }
85 
86 
87 
88 
89 void CurrentSlideManager::NotifyCurrentSlideChange (const sal_Int32 nSlideIndex)
90 {
91     if (mnCurrentSlideIndex != nSlideIndex)
92     {
93         ReleaseCurrentSlide();
94         AcquireCurrentSlide(nSlideIndex);
95 
96         // Update the selection.
97         mrSlideSorter.GetController().GetPageSelector().DeselectAllPages();
98         if (mpCurrentSlide)
99         {
100             mrSlideSorter.GetController().GetPageSelector().SelectPage(mpCurrentSlide);
101             mrSlideSorter.GetController().GetFocusManager().SetFocusedPage(mpCurrentSlide);
102         }
103     }
104 }
105 
106 
107 
108 
109 void CurrentSlideManager::ReleaseCurrentSlide (void)
110 {
111     if (mpCurrentSlide.get() != NULL)
112         mrSlideSorter.GetView().SetState(mpCurrentSlide, PageDescriptor::ST_Current, false);
113 
114     mpCurrentSlide.reset();
115     mnCurrentSlideIndex = -1;
116 }
117 
118 
119 
120 
121 bool CurrentSlideManager::IsCurrentSlideIsValid (void)
122 {
123     return mnCurrentSlideIndex >= 0 && mnCurrentSlideIndex<mrSlideSorter.GetModel().GetPageCount();
124 }
125 
126 
127 
128 
129 void CurrentSlideManager::AcquireCurrentSlide (const sal_Int32 nSlideIndex)
130 {
131     mnCurrentSlideIndex = nSlideIndex;
132 
133     if (IsCurrentSlideIsValid())
134     {
135         // Get a descriptor for the XDrawPage reference.  Note that the
136         // given XDrawPage may or may not be member of the slide sorter
137         // document.
138         mpCurrentSlide = mrSlideSorter.GetModel().GetPageDescriptor(mnCurrentSlideIndex);
139         if (mpCurrentSlide.get() != NULL)
140             mrSlideSorter.GetView().SetState(mpCurrentSlide, PageDescriptor::ST_Current, true);
141     }
142 }
143 
144 
145 
146 
147 void CurrentSlideManager::SwitchCurrentSlide (
148     const sal_Int32 nSlideIndex,
149     const bool bUpdateSelection)
150 {
151     SwitchCurrentSlide(mrSlideSorter.GetModel().GetPageDescriptor(nSlideIndex), bUpdateSelection);
152 }
153 
154 
155 
156 
157 void CurrentSlideManager::SwitchCurrentSlide (
158     const SharedPageDescriptor& rpDescriptor,
159     const bool bUpdateSelection)
160 {
161     if (rpDescriptor.get() != NULL && mpCurrentSlide!=rpDescriptor)
162     {
163         ReleaseCurrentSlide();
164         AcquireCurrentSlide((rpDescriptor->GetPage()->GetPageNum()-1)/2);
165 
166         ViewShell* pViewShell = mrSlideSorter.GetViewShell();
167         if (pViewShell != NULL && pViewShell->IsMainViewShell())
168         {
169             // The slide sorter is the main view.
170             FrameView* pFrameView = pViewShell->GetFrameView();
171             if (pFrameView != NULL)
172                 pFrameView->SetSelectedPage(sal::static_int_cast<sal_uInt16>(mnCurrentSlideIndex));
173             mrSlideSorter.GetController().GetPageSelector().SetCoreSelection();
174         }
175 
176         // We do not tell the XController/ViewShellBase about the new
177         // slide right away.  This is done asynchronously after a short
178         // delay to allow for more slide switches in the slide sorter.
179         // This goes under the assumption that slide switching inside
180         // the slide sorter is fast (no expensive redraw of the new page
181         // (unless the preview of the new slide is not yet preset)) and
182         // that slide switching in the edit view is slow (all shapes of
183         // the new slide have to be repainted.)
184         maSwitchPageDelayTimer.Start();
185 
186         // We have to store the (index of the) new current slide at
187         // the tab control because there are other asynchronous
188         // notifications of the slide switching that otherwise
189         // overwrite the correct value.
190         SetCurrentSlideAtTabControl(mpCurrentSlide);
191 
192         if (bUpdateSelection)
193         {
194             mrSlideSorter.GetController().GetPageSelector().DeselectAllPages();
195             mrSlideSorter.GetController().GetPageSelector().SelectPage(rpDescriptor);
196         }
197         mrSlideSorter.GetController().GetFocusManager().SetFocusedPage(rpDescriptor);
198     }
199 }
200 
201 
202 
203 
204 void CurrentSlideManager::SetCurrentSlideAtViewShellBase (const SharedPageDescriptor& rpDescriptor)
205 {
206     OSL_ASSERT(rpDescriptor.get() != NULL);
207 
208     ViewShellBase* pBase = mrSlideSorter.GetViewShellBase();
209     if (pBase != NULL)
210     {
211         DrawViewShell* pDrawViewShell = dynamic_cast<DrawViewShell*>(
212             pBase->GetMainViewShell().get());
213         if (pDrawViewShell != NULL)
214         {
215             sal_uInt16 nPageNumber = (rpDescriptor->GetPage()->GetPageNum()-1)/2;
216             pDrawViewShell->SwitchPage(nPageNumber);
217             pDrawViewShell->GetPageTabControl()->SetCurPageId(nPageNumber+1);
218         }
219     }
220 }
221 
222 
223 
224 
225 void CurrentSlideManager::SetCurrentSlideAtTabControl (const SharedPageDescriptor& rpDescriptor)
226 {
227     OSL_ASSERT(rpDescriptor.get() != NULL);
228 
229     ViewShellBase* pBase = mrSlideSorter.GetViewShellBase();
230     if (pBase != NULL)
231     {
232         ::boost::shared_ptr<DrawViewShell> pDrawViewShell (
233             ::boost::dynamic_pointer_cast<DrawViewShell>(pBase->GetMainViewShell()));
234         if (pDrawViewShell)
235         {
236             sal_uInt16 nPageNumber = (rpDescriptor->GetPage()->GetPageNum()-1)/2;
237             pDrawViewShell->GetPageTabControl()->SetCurPageId(nPageNumber+1);
238         }
239     }
240 }
241 
242 
243 
244 
245 void CurrentSlideManager::SetCurrentSlideAtXController (const SharedPageDescriptor& rpDescriptor)
246 {
247     OSL_ASSERT(rpDescriptor.get() != NULL);
248 
249     try
250     {
251         Reference<beans::XPropertySet> xSet (mrSlideSorter.GetXController(), UNO_QUERY);
252         if (xSet.is())
253         {
254             Any aPage;
255             aPage <<= rpDescriptor->GetPage()->getUnoPage();
256             xSet->setPropertyValue (
257                 String::CreateFromAscii("CurrentPage"),
258                 aPage);
259         }
260     }
261     catch (Exception aException)
262     {
263         // We have not been able to set the current page at the main view.
264         // This is sad but still leaves us in a valid state.  Therefore,
265         // this exception is silently ignored.
266     }
267 }
268 
269 
270 
271 
272 SharedPageDescriptor CurrentSlideManager::GetCurrentSlide (void)
273 {
274     return mpCurrentSlide;
275 }
276 
277 
278 
279 
280 void CurrentSlideManager::PrepareModelChange (void)
281 {
282     mpCurrentSlide.reset();
283 }
284 
285 
286 
287 
288 void CurrentSlideManager::HandleModelChange (void)
289 {
290     if (mnCurrentSlideIndex >= 0)
291     {
292         mpCurrentSlide = mrSlideSorter.GetModel().GetPageDescriptor(mnCurrentSlideIndex);
293         if (mpCurrentSlide.get() != NULL)
294             mrSlideSorter.GetView().SetState(mpCurrentSlide, PageDescriptor::ST_Current, true);
295     }
296 }
297 
298 
299 
300 
301 IMPL_LINK(CurrentSlideManager, SwitchPageCallback, void*, EMPTYARG)
302 {
303     if (mpCurrentSlide)
304     {
305         // Set current page.  At the moment we have to do this in two
306         // different ways.  The UNO way is the preferable one but, alas,
307         // it does not work always correctly (after some kinds of model
308         // changes).  Therefore, we call DrawViewShell::SwitchPage(),
309         // too.
310         ViewShell* pViewShell = mrSlideSorter.GetViewShell();
311         if (pViewShell==NULL || ! pViewShell->IsMainViewShell())
312             SetCurrentSlideAtViewShellBase(mpCurrentSlide);
313         SetCurrentSlideAtXController(mpCurrentSlide);
314     }
315 
316     return 1;
317 }
318 
319 } } } // end of namespace ::sd::slidesorter::controller
320