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