/src/libreoffice/sd/source/ui/slideshow/slideshowimpl.cxx
Line | Count | Source |
1 | | /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ |
2 | | /* |
3 | | * This file is part of the LibreOffice project. |
4 | | * |
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 | | * |
9 | | * This file incorporates work covered by the following license notice: |
10 | | * |
11 | | * Licensed to the Apache Software Foundation (ASF) under one or more |
12 | | * contributor license agreements. See the NOTICE file distributed |
13 | | * with this work for additional information regarding copyright |
14 | | * ownership. The ASF licenses this file to you under the Apache |
15 | | * License, Version 2.0 (the "License"); you may not use this file |
16 | | * except in compliance with the License. You may obtain a copy of |
17 | | * the License at http://www.apache.org/licenses/LICENSE-2.0 . |
18 | | */ |
19 | | |
20 | | #include <sal/config.h> |
21 | | |
22 | | #include <algorithm> |
23 | | |
24 | | #include <config_features.h> |
25 | | |
26 | | #include <com/sun/star/frame/theAutoRecovery.hpp> |
27 | | #include <com/sun/star/lang/IndexOutOfBoundsException.hpp> |
28 | | #include <com/sun/star/document/XEventsSupplier.hpp> |
29 | | #include <com/sun/star/drawing/XMasterPageTarget.hpp> |
30 | | #include <com/sun/star/beans/PropertyValue.hpp> |
31 | | #include <com/sun/star/beans/XPropertySetInfo.hpp> |
32 | | #include <com/sun/star/beans/XPropertySet.hpp> |
33 | | #include <com/sun/star/awt/SystemPointer.hpp> |
34 | | #include <com/sun/star/util/URLTransformer.hpp> |
35 | | #include <com/sun/star/util/XURLTransformer.hpp> |
36 | | #include <com/sun/star/frame/XDispatch.hpp> |
37 | | #include <com/sun/star/frame/XLayoutManager.hpp> |
38 | | #include <com/sun/star/presentation/SlideShow.hpp> |
39 | | #include <com/sun/star/media/XPlayer.hpp> |
40 | | #include <officecfg/Office/Impress.hxx> |
41 | | #include <officecfg/Office/Recovery.hxx> |
42 | | #include <svl/stritem.hxx> |
43 | | #include <svl/urihelper.hxx> |
44 | | #include <basic/sbstar.hxx> |
45 | | |
46 | | #include <toolkit/helper/vclunohelper.hxx> |
47 | | #include <comphelper/diagnose_ex.hxx> |
48 | | #include <comphelper/sequence.hxx> |
49 | | |
50 | | #include <sfx2/infobar.hxx> |
51 | | #include <sfx2/dispatch.hxx> |
52 | | #include <sfx2/docfile.hxx> |
53 | | #include <sfx2/app.hxx> |
54 | | #include <sfx2/viewfrm.hxx> |
55 | | #include <svx/svdoole2.hxx> |
56 | | #include <svx/f3dchild.hxx> |
57 | | #include <svx/imapdlg.hxx> |
58 | | #include <svx/fontwork.hxx> |
59 | | #include <svx/SvxColorChildWindow.hxx> |
60 | | #include <svx/bmpmask.hxx> |
61 | | #include <svx/srchdlg.hxx> |
62 | | #include <svx/hyperdlg.hxx> |
63 | | #include <svx/svxids.hrc> |
64 | | #include <svx/unoapi.hxx> |
65 | | #include <AnimationChildWindow.hxx> |
66 | | #include <notifydocumentevent.hxx> |
67 | | #include "slideshowimpl.hxx" |
68 | | #include "slideshowviewimpl.hxx" |
69 | | #include "PaneHider.hxx" |
70 | | |
71 | | #include <bitmaps.hlst> |
72 | | #include <strings.hrc> |
73 | | #include <sdresid.hxx> |
74 | | #include <utility> |
75 | | #include <vcl/ColorDialog.hxx> |
76 | | #include <vcl/canvastools.hxx> |
77 | | #include <vcl/commandevent.hxx> |
78 | | #include <vcl/weldutils.hxx> |
79 | | |
80 | | #include <vcl/settings.hxx> |
81 | | #include <vcl/svapp.hxx> |
82 | | #include <vcl/help.hxx> |
83 | | #include <comphelper/processfactory.hxx> |
84 | | #include <comphelper/propertyvalue.hxx> |
85 | | #include <rtl/ref.hxx> |
86 | | #include <o3tl/safeint.hxx> |
87 | | #include <o3tl/string_view.hxx> |
88 | | #include <avmedia/mediawindow.hxx> |
89 | | #include <DrawDocShell.hxx> |
90 | | #include <ViewShellBase.hxx> |
91 | | #include <PresentationViewShell.hxx> |
92 | | #include <RemoteServer.hxx> |
93 | | #include <customshowlist.hxx> |
94 | | #include <unopage.hxx> |
95 | | #include <sdpage.hxx> |
96 | | #include <sdmod.hxx> |
97 | | #include <app.hrc> |
98 | | #include <cusshow.hxx> |
99 | | #include <optsitem.hxx> |
100 | | #include <unomodel.hxx> |
101 | | |
102 | 0 | #define CM_SLIDES 21 |
103 | | |
104 | | using ::com::sun::star::animations::XAnimationNode; |
105 | | using ::com::sun::star::animations::XAnimationListener; |
106 | | using ::com::sun::star::awt::XWindow; |
107 | | using namespace ::com::sun::star; |
108 | | using namespace ::com::sun::star::lang; |
109 | | using namespace ::com::sun::star::uno; |
110 | | using namespace ::com::sun::star::drawing; |
111 | | using namespace ::com::sun::star::container; |
112 | | using namespace ::com::sun::star::presentation; |
113 | | using namespace ::com::sun::star::beans; |
114 | | |
115 | | namespace sd |
116 | | { |
117 | | /** Slots, which will be disabled in the slide show and are managed by Sfx. |
118 | | Have to be sorted in the order of the SIDs */ |
119 | | sal_uInt16 const pAllowed[] = |
120 | | { |
121 | | SID_OPENDOC , // 5501 ///< that internally jumps work |
122 | | SID_JUMPTOMARK , // 5598 |
123 | | SID_OPENHYPERLINK , // 6676 |
124 | | SID_PRESENTATION_END // 27218 |
125 | | }; |
126 | | |
127 | | class AnimationSlideController |
128 | | { |
129 | | public: |
130 | | enum Mode { ALL, FROM, CUSTOM, PREVIEW }; |
131 | | |
132 | | public: |
133 | | AnimationSlideController( Reference< XIndexAccess > const & xSlides, Mode eMode ); |
134 | | |
135 | 0 | void setStartSlideNumber( sal_Int32 nSlideNumber ) { mnStartSlideNumber = nSlideNumber; } |
136 | | sal_Int32 getStartSlideIndex() const; |
137 | | |
138 | | sal_Int32 getCurrentSlideNumber() const; |
139 | | sal_Int32 getCurrentSlideIndex() const; |
140 | | |
141 | 0 | sal_Int32 getSlideIndexCount() const { return maSlideNumbers.size(); } |
142 | 0 | sal_Int32 getSlideNumberCount() const { return mnSlideCount; } |
143 | | |
144 | | sal_Int32 getSlideNumber( sal_Int32 nSlideIndex ) const; |
145 | | |
146 | | void insertSlideNumber( sal_Int32 nSlideNumber, bool bVisible = true ); |
147 | | void setPreviewNode( const Reference< XAnimationNode >& xPreviewNode ); |
148 | | |
149 | | bool jumpToSlideIndex( sal_Int32 nNewSlideIndex ); |
150 | | bool jumpToSlideNumber( sal_Int32 nNewSlideIndex ); |
151 | | |
152 | | bool nextSlide(); |
153 | | bool previousSlide(); |
154 | | |
155 | | void displayCurrentSlide( const Reference< XSlideShow >& xShow, |
156 | | const Reference< XDrawPagesSupplier>& xDrawPages, |
157 | | const bool bSkipAllMainSequenceEffects ); |
158 | | |
159 | | sal_Int32 getNextSlideIndex() const; |
160 | | sal_Int32 getPreviousSlideIndex() const; |
161 | | |
162 | | bool isVisibleSlideNumber( sal_Int32 nSlideNumber ) const; |
163 | | |
164 | | Reference< XDrawPage > getSlideByNumber( sal_Int32 nSlideNumber ) const; |
165 | | |
166 | | sal_Int32 getNextSlideNumber() const; |
167 | | |
168 | 0 | bool hasSlides() const { return !maSlideNumbers.empty(); } |
169 | | |
170 | | // for InteractiveSlideShow we need to temporarily change the program |
171 | | // and mode, so allow save/restore that settings |
172 | | void pushForPreview(); |
173 | | void popFromPreview(); |
174 | | private: |
175 | | bool getSlideAPI( sal_Int32 nSlideNumber, Reference< XDrawPage >& xSlide, Reference< XAnimationNode >& xAnimNode ); |
176 | | sal_Int32 findSlideIndex( sal_Int32 nSlideNumber ) const; |
177 | | |
178 | 0 | bool isValidIndex( sal_Int32 nIndex ) const { return (nIndex >= 0) && (o3tl::make_unsigned(nIndex) < maSlideNumbers.size()); } |
179 | 0 | bool isValidSlideNumber( sal_Int32 nSlideNumber ) const { return (nSlideNumber >= 0) && (nSlideNumber < mnSlideCount); } |
180 | | |
181 | | private: |
182 | | Mode meMode; |
183 | | sal_Int32 mnStartSlideNumber; |
184 | | std::vector< sal_Int32 > maSlideNumbers; |
185 | | std::vector< bool > maSlideVisible; |
186 | | std::vector< bool > maSlideVisited; |
187 | | Reference< XAnimationNode > mxPreviewNode; |
188 | | sal_Int32 mnSlideCount; |
189 | | sal_Int32 mnCurrentSlideIndex; |
190 | | sal_Int32 mnHiddenSlideNumber; |
191 | | Reference< XIndexAccess > mxSlides; |
192 | | |
193 | | // IASS data for push/pop |
194 | | std::vector< sal_Int32 > maSlideNumbers2; |
195 | | std::vector< bool > maSlideVisible2; |
196 | | std::vector< bool > maSlideVisited2; |
197 | | Reference< XAnimationNode > mxPreviewNode2; |
198 | | Mode meMode2; |
199 | | }; |
200 | | |
201 | | void AnimationSlideController::pushForPreview() |
202 | 0 | { |
203 | 0 | maSlideNumbers2 = maSlideNumbers; |
204 | 0 | maSlideVisible2 = maSlideVisible; |
205 | 0 | maSlideVisited2 = maSlideVisited; |
206 | 0 | maSlideNumbers.clear(); |
207 | 0 | maSlideVisible.clear(); |
208 | 0 | maSlideVisited.clear(); |
209 | 0 | mxPreviewNode2 = mxPreviewNode; |
210 | 0 | meMode2 = meMode; |
211 | 0 | meMode = AnimationSlideController::PREVIEW; |
212 | 0 | } |
213 | | |
214 | | void AnimationSlideController::popFromPreview() |
215 | 0 | { |
216 | 0 | maSlideNumbers = maSlideNumbers2; |
217 | 0 | maSlideVisible = maSlideVisible2; |
218 | 0 | maSlideVisited = maSlideVisited2; |
219 | 0 | maSlideNumbers2.clear(); |
220 | 0 | maSlideVisible2.clear(); |
221 | 0 | maSlideVisited2.clear(); |
222 | 0 | mxPreviewNode = mxPreviewNode2; |
223 | 0 | meMode = meMode2; |
224 | 0 | } |
225 | | |
226 | | Reference< XDrawPage > AnimationSlideController::getSlideByNumber( sal_Int32 nSlideNumber ) const |
227 | 0 | { |
228 | 0 | Reference< XDrawPage > xSlide; |
229 | 0 | if( mxSlides.is() && (nSlideNumber >= 0) && (nSlideNumber < mxSlides->getCount()) ) |
230 | 0 | mxSlides->getByIndex( nSlideNumber ) >>= xSlide; |
231 | 0 | return xSlide; |
232 | 0 | } |
233 | | |
234 | | bool AnimationSlideController::isVisibleSlideNumber( sal_Int32 nSlideNumber ) const |
235 | 0 | { |
236 | 0 | sal_Int32 nIndex = findSlideIndex( nSlideNumber ); |
237 | |
|
238 | 0 | if( nIndex != -1 ) |
239 | 0 | return maSlideVisible[ nIndex ]; |
240 | 0 | else |
241 | 0 | return false; |
242 | 0 | } |
243 | | |
244 | | void AnimationSlideController::setPreviewNode( const Reference< XAnimationNode >& xPreviewNode ) |
245 | 0 | { |
246 | 0 | mxPreviewNode = xPreviewNode; |
247 | 0 | } |
248 | | |
249 | | AnimationSlideController::AnimationSlideController( Reference< XIndexAccess > const & xSlides, Mode eMode ) |
250 | 0 | : meMode( eMode ) |
251 | 0 | , mnStartSlideNumber(-1) |
252 | 0 | , mnSlideCount( 0 ) |
253 | 0 | , mnCurrentSlideIndex(0) |
254 | 0 | , mnHiddenSlideNumber( -1 ) |
255 | 0 | , mxSlides( xSlides ) |
256 | 0 | , meMode2( eMode ) |
257 | 0 | { |
258 | 0 | if( mxSlides.is() ) |
259 | 0 | mnSlideCount = xSlides->getCount(); |
260 | 0 | } |
261 | | |
262 | | sal_Int32 AnimationSlideController::getStartSlideIndex() const |
263 | 0 | { |
264 | 0 | if( mnStartSlideNumber >= 0 ) |
265 | 0 | { |
266 | 0 | sal_Int32 nIndex; |
267 | 0 | const sal_Int32 nCount = maSlideNumbers.size(); |
268 | |
|
269 | 0 | for( nIndex = 0; nIndex < nCount; nIndex++ ) |
270 | 0 | { |
271 | 0 | if( maSlideNumbers[nIndex] == mnStartSlideNumber ) |
272 | 0 | return nIndex; |
273 | 0 | } |
274 | 0 | } |
275 | | |
276 | 0 | return 0; |
277 | 0 | } |
278 | | |
279 | | sal_Int32 AnimationSlideController::getCurrentSlideNumber() const |
280 | 0 | { |
281 | 0 | if( mnHiddenSlideNumber != -1 ) |
282 | 0 | return mnHiddenSlideNumber; |
283 | 0 | else if( !maSlideNumbers.empty() ) |
284 | 0 | return maSlideNumbers[mnCurrentSlideIndex]; |
285 | 0 | else |
286 | 0 | return 0; |
287 | 0 | } |
288 | | |
289 | | sal_Int32 AnimationSlideController::getCurrentSlideIndex() const |
290 | 0 | { |
291 | 0 | if( mnHiddenSlideNumber != -1 ) |
292 | 0 | return -1; |
293 | 0 | else |
294 | 0 | return mnCurrentSlideIndex; |
295 | 0 | } |
296 | | |
297 | | bool AnimationSlideController::jumpToSlideIndex( sal_Int32 nNewSlideIndex ) |
298 | 0 | { |
299 | 0 | if( isValidIndex( nNewSlideIndex ) ) |
300 | 0 | { |
301 | 0 | mnCurrentSlideIndex = nNewSlideIndex; |
302 | 0 | mnHiddenSlideNumber = -1; |
303 | 0 | maSlideVisited[mnCurrentSlideIndex] = true; |
304 | 0 | return true; |
305 | 0 | } |
306 | 0 | else |
307 | 0 | { |
308 | 0 | return false; |
309 | 0 | } |
310 | 0 | } |
311 | | |
312 | | bool AnimationSlideController::jumpToSlideNumber( sal_Int32 nNewSlideNumber ) |
313 | 0 | { |
314 | 0 | sal_Int32 nIndex = findSlideIndex( nNewSlideNumber ); |
315 | 0 | if( isValidIndex( nIndex ) ) |
316 | 0 | { |
317 | 0 | return jumpToSlideIndex( nIndex ); |
318 | 0 | } |
319 | 0 | else if( (nNewSlideNumber >= 0) && (nNewSlideNumber < mnSlideCount) ) |
320 | 0 | { |
321 | | // jump to a hidden slide |
322 | 0 | mnHiddenSlideNumber = nNewSlideNumber; |
323 | 0 | return true; |
324 | 0 | } |
325 | 0 | else |
326 | 0 | { |
327 | 0 | return false; |
328 | 0 | } |
329 | 0 | } |
330 | | |
331 | | sal_Int32 AnimationSlideController::getSlideNumber( sal_Int32 nSlideIndex ) const |
332 | 0 | { |
333 | 0 | if( isValidIndex( nSlideIndex ) ) |
334 | 0 | return maSlideNumbers[nSlideIndex]; |
335 | 0 | else |
336 | 0 | return -1; |
337 | 0 | } |
338 | | |
339 | | void AnimationSlideController::insertSlideNumber( sal_Int32 nSlideNumber, bool bVisible /* = true */ ) |
340 | 0 | { |
341 | 0 | DBG_ASSERT( isValidSlideNumber( nSlideNumber ), "sd::AnimationSlideController::insertSlideNumber(), illegal index" ); |
342 | 0 | if( isValidSlideNumber( nSlideNumber ) ) |
343 | 0 | { |
344 | 0 | maSlideNumbers.push_back( nSlideNumber ); |
345 | 0 | maSlideVisible.push_back( bVisible ); |
346 | 0 | maSlideVisited.push_back( false ); |
347 | 0 | } |
348 | 0 | } |
349 | | |
350 | | bool AnimationSlideController::getSlideAPI( sal_Int32 nSlideNumber, Reference< XDrawPage >& xSlide, Reference< XAnimationNode >& xAnimNode ) |
351 | 0 | { |
352 | 0 | if( isValidSlideNumber( nSlideNumber ) ) try |
353 | 0 | { |
354 | 0 | xSlide.set( mxSlides->getByIndex(nSlideNumber), UNO_QUERY_THROW ); |
355 | |
|
356 | 0 | if( meMode == PREVIEW ) |
357 | 0 | { |
358 | 0 | xAnimNode = mxPreviewNode; |
359 | 0 | } |
360 | 0 | else |
361 | 0 | { |
362 | 0 | Reference< animations::XAnimationNodeSupplier > xAnimNodeSupplier( xSlide, UNO_QUERY_THROW ); |
363 | 0 | xAnimNode = xAnimNodeSupplier->getAnimationNode(); |
364 | 0 | } |
365 | |
|
366 | 0 | return true; |
367 | 0 | } |
368 | 0 | catch( Exception& ) |
369 | 0 | { |
370 | 0 | TOOLS_WARN_EXCEPTION( "sd", "sd::AnimationSlideController::getSlideAPI()" ); |
371 | 0 | } |
372 | | |
373 | 0 | return false; |
374 | 0 | } |
375 | | |
376 | | sal_Int32 AnimationSlideController::findSlideIndex( sal_Int32 nSlideNumber ) const |
377 | 0 | { |
378 | 0 | sal_Int32 nIndex; |
379 | 0 | const sal_Int32 nCount = maSlideNumbers.size(); |
380 | |
|
381 | 0 | for( nIndex = 0; nIndex < nCount; nIndex++ ) |
382 | 0 | { |
383 | 0 | if( maSlideNumbers[nIndex] == nSlideNumber ) |
384 | 0 | return nIndex; |
385 | 0 | } |
386 | | |
387 | 0 | return -1; |
388 | 0 | } |
389 | | |
390 | | sal_Int32 AnimationSlideController::getNextSlideIndex() const |
391 | 0 | { |
392 | 0 | switch( meMode ) |
393 | 0 | { |
394 | 0 | case ALL: |
395 | 0 | { |
396 | 0 | sal_Int32 nNewSlideIndex = mnCurrentSlideIndex + 1; |
397 | 0 | if( isValidIndex( nNewSlideIndex ) ) |
398 | 0 | { |
399 | | // if the current slide is not excluded, make sure the |
400 | | // next slide is also not excluded. |
401 | | // if the current slide is excluded, we want to go |
402 | | // to the next slide, even if this is also excluded. |
403 | 0 | if( maSlideVisible[mnCurrentSlideIndex] ) |
404 | 0 | { |
405 | 0 | while( isValidIndex( nNewSlideIndex ) ) |
406 | 0 | { |
407 | 0 | if( maSlideVisible[nNewSlideIndex] ) |
408 | 0 | break; |
409 | | |
410 | 0 | nNewSlideIndex++; |
411 | 0 | } |
412 | 0 | } |
413 | 0 | } |
414 | 0 | return isValidIndex( nNewSlideIndex ) ? nNewSlideIndex : -1; |
415 | 0 | } |
416 | | |
417 | 0 | case FROM: |
418 | 0 | case CUSTOM: |
419 | 0 | return mnHiddenSlideNumber == -1 ? mnCurrentSlideIndex + 1 : mnCurrentSlideIndex; |
420 | | |
421 | 0 | default: |
422 | 0 | case PREVIEW: |
423 | 0 | return -1; |
424 | |
|
425 | 0 | } |
426 | 0 | } |
427 | | |
428 | | sal_Int32 AnimationSlideController::getNextSlideNumber() const |
429 | 0 | { |
430 | 0 | sal_Int32 nNextSlideIndex = getNextSlideIndex(); |
431 | 0 | if( isValidIndex( nNextSlideIndex ) ) |
432 | 0 | { |
433 | 0 | return maSlideNumbers[nNextSlideIndex]; |
434 | 0 | } |
435 | 0 | else |
436 | 0 | { |
437 | 0 | return -1; |
438 | 0 | } |
439 | 0 | } |
440 | | |
441 | | bool AnimationSlideController::nextSlide() |
442 | 0 | { |
443 | 0 | return jumpToSlideIndex( getNextSlideIndex() ); |
444 | 0 | } |
445 | | |
446 | | sal_Int32 AnimationSlideController::getPreviousSlideIndex() const |
447 | 0 | { |
448 | 0 | sal_Int32 nNewSlideIndex = mnCurrentSlideIndex - 1; |
449 | |
|
450 | 0 | switch( meMode ) |
451 | 0 | { |
452 | 0 | case ALL: |
453 | 0 | { |
454 | | // make sure the previous slide is visible |
455 | | // or was already visited |
456 | 0 | while( isValidIndex( nNewSlideIndex ) ) |
457 | 0 | { |
458 | 0 | if( maSlideVisible[nNewSlideIndex] || maSlideVisited[nNewSlideIndex] ) |
459 | 0 | break; |
460 | | |
461 | 0 | nNewSlideIndex--; |
462 | 0 | } |
463 | |
|
464 | 0 | break; |
465 | 0 | } |
466 | | |
467 | 0 | case PREVIEW: |
468 | 0 | return -1; |
469 | | |
470 | 0 | default: |
471 | 0 | break; |
472 | 0 | } |
473 | | |
474 | 0 | return nNewSlideIndex; |
475 | 0 | } |
476 | | |
477 | | bool AnimationSlideController::previousSlide() |
478 | 0 | { |
479 | 0 | return jumpToSlideIndex( getPreviousSlideIndex() ); |
480 | 0 | } |
481 | | |
482 | | void AnimationSlideController::displayCurrentSlide( const Reference< XSlideShow >& xShow, |
483 | | const Reference< XDrawPagesSupplier>& xDrawPages, |
484 | | const bool bSkipAllMainSequenceEffects ) |
485 | 0 | { |
486 | 0 | const sal_Int32 nCurrentSlideNumber = getCurrentSlideNumber(); |
487 | |
|
488 | 0 | if( !(xShow.is() && (nCurrentSlideNumber != -1 )) ) |
489 | 0 | return; |
490 | | |
491 | 0 | Reference< XDrawPage > xSlide; |
492 | 0 | Reference< XAnimationNode > xAnimNode; |
493 | 0 | ::std::vector<PropertyValue> aProperties; |
494 | |
|
495 | 0 | const sal_Int32 nNextSlideNumber = getNextSlideNumber(); |
496 | 0 | if( getSlideAPI( nNextSlideNumber, xSlide, xAnimNode ) ) |
497 | 0 | { |
498 | 0 | Sequence< Any > aValue{ Any(xSlide), Any(xAnimNode) }; |
499 | 0 | aProperties.emplace_back( "Prefetch" , |
500 | 0 | -1, |
501 | 0 | Any(aValue), |
502 | 0 | PropertyState_DIRECT_VALUE); |
503 | 0 | } |
504 | 0 | if (bSkipAllMainSequenceEffects) |
505 | 0 | { |
506 | | // Add one property that prevents the slide transition from being |
507 | | // shown (to speed up the transition to the previous slide) and |
508 | | // one to show all main sequence effects so that the user can |
509 | | // continue to undo effects. |
510 | 0 | aProperties.emplace_back( "SkipAllMainSequenceEffects", |
511 | 0 | -1, |
512 | 0 | Any(true), |
513 | 0 | PropertyState_DIRECT_VALUE); |
514 | 0 | aProperties.emplace_back("SkipSlideTransition", |
515 | 0 | -1, |
516 | 0 | Any(true), |
517 | 0 | PropertyState_DIRECT_VALUE); |
518 | 0 | } |
519 | |
|
520 | 0 | if( getSlideAPI( nCurrentSlideNumber, xSlide, xAnimNode ) ) |
521 | 0 | xShow->displaySlide( xSlide, xDrawPages, xAnimNode, comphelper::containerToSequence(aProperties) ); |
522 | 0 | } |
523 | | |
524 | | constexpr OUString gsOnClick( u"OnClick"_ustr ); |
525 | | constexpr OUString gsBookmark( u"Bookmark"_ustr ); |
526 | | constexpr OUString gsVerb( u"Verb"_ustr ); |
527 | | |
528 | | SlideshowImpl::SlideshowImpl( const Reference< XPresentation2 >& xPresentation, ViewShell* pViewSh, ::sd::View* pView, SdDrawDocument* pDoc, vcl::Window* pParentWindow ) |
529 | 0 | : mxShow() |
530 | 0 | , mxView() |
531 | 0 | , mxModel(pDoc->getUnoModel()) |
532 | 0 | , maUpdateTimer("SlideShowImpl maUpdateTimer") |
533 | 0 | , maInputFreezeTimer("SlideShowImpl maInputFreezeTimer") |
534 | 0 | , maDeactivateTimer("SlideShowImpl maDeactivateTimer") |
535 | 0 | , mpView(pView) |
536 | 0 | , mpViewShell(pViewSh) |
537 | 0 | , mpDocSh(pDoc->GetDocSh()) |
538 | 0 | , mpDoc(pDoc) |
539 | 0 | , mpParentWindow(pParentWindow) |
540 | 0 | , mpShowWindow(nullptr) |
541 | 0 | , mpSlideController() |
542 | 0 | , mnRestoreSlide(0) |
543 | 0 | , maPopupMousePos() |
544 | 0 | , maPresSize( -1, -1 ) |
545 | 0 | , meAnimationMode(ANIMATIONMODE_SHOW) |
546 | 0 | , maCharBuffer() |
547 | 0 | , mpOldActiveWindow(nullptr) |
548 | 0 | , maStarBASICGlobalErrorHdl() |
549 | 0 | , mnChildMask( 0 ) |
550 | 0 | , mbDisposed(false) |
551 | 0 | , mbAutoSaveWasOn(false) |
552 | 0 | , mbRehearseTimings(false) |
553 | 0 | , mbIsPaused(false) |
554 | 0 | , mbWasPaused(false) |
555 | 0 | , mbInputFreeze(false) |
556 | 0 | , mbActive(false) |
557 | 0 | , maPresSettings( pDoc->getPresentationSettings() ) |
558 | 0 | , mnUserPaintColor( 0x80ff0000L ) |
559 | 0 | , mbUsePen(false) |
560 | 0 | , mdUserPaintStrokeWidth ( 150.0 ) |
561 | 0 | , maShapeEventMap() |
562 | 0 | , mxPreviewDrawPage() |
563 | 0 | , mxPreviewAnimationNode() |
564 | 0 | , mxPlayer() |
565 | 0 | , mpPaneHider() |
566 | 0 | , mnEndShowEvent(nullptr) |
567 | 0 | , mnContextMenuEvent(nullptr) |
568 | 0 | , mnEventObjectChange(nullptr) |
569 | 0 | , mnEventObjectInserted(nullptr) |
570 | 0 | , mnEventObjectRemoved(nullptr) |
571 | 0 | , mnEventPageOrderChange(nullptr) |
572 | 0 | , mxPresentation( xPresentation ) |
573 | 0 | , mxListenerProxy() |
574 | 0 | , mxShow2() |
575 | 0 | , mxView2() |
576 | | , meAnimationMode2() |
577 | 0 | , mbInterActiveSetup(false) |
578 | 0 | , maPresSettings2() |
579 | 0 | , mxPreviewDrawPage2() |
580 | 0 | , mxPreviewAnimationNode2() |
581 | 0 | , mnSlideIndex(0) |
582 | 0 | { |
583 | 0 | if( mpViewShell ) |
584 | 0 | mpOldActiveWindow = mpViewShell->GetActiveWindow(); |
585 | |
|
586 | 0 | maUpdateTimer.SetInvokeHandler(LINK(this, SlideshowImpl, updateHdl)); |
587 | | // Priority must not be too high or we'll starve input handling etc. |
588 | 0 | maUpdateTimer.SetPriority(TaskPriority::REPAINT); |
589 | |
|
590 | 0 | maDeactivateTimer.SetInvokeHandler(LINK(this, SlideshowImpl, deactivateHdl)); |
591 | 0 | maDeactivateTimer.SetTimeout( 20 ); |
592 | |
|
593 | 0 | maInputFreezeTimer.SetInvokeHandler( LINK( this, SlideshowImpl, ReadyForNextInputHdl ) ); |
594 | 0 | maInputFreezeTimer.SetTimeout( 20 ); |
595 | | |
596 | | // no autosave during show |
597 | 0 | if (officecfg::Office::Recovery::AutoSave::Enabled::get()) |
598 | 0 | mbAutoSaveWasOn = true; |
599 | |
|
600 | 0 | Application::AddEventListener( LINK( this, SlideshowImpl, EventListenerHdl ) ); |
601 | |
|
602 | 0 | mbUsePen = maPresSettings.mbMouseAsPen; |
603 | |
|
604 | 0 | SdOptions* pOptions = SdModule::get()->GetSdOptions(DocumentType::Impress); |
605 | 0 | if( pOptions ) |
606 | 0 | { |
607 | 0 | mnUserPaintColor = pOptions->GetPresentationPenColor(); |
608 | 0 | mdUserPaintStrokeWidth = pOptions->GetPresentationPenWidth(); |
609 | 0 | } |
610 | | |
611 | | // to be able to react on various changes in the DrawModel, this class |
612 | | // is now derived from SfxListener and registers itself at the DrawModel |
613 | 0 | if (nullptr != mpDoc) |
614 | 0 | StartListening(*mpDoc); |
615 | 0 | } Unexecuted instantiation: sd::SlideshowImpl::SlideshowImpl(com::sun::star::uno::Reference<com::sun::star::presentation::XPresentation2> const&, sd::ViewShell*, sd::View*, SdDrawDocument*, vcl::Window*) Unexecuted instantiation: sd::SlideshowImpl::SlideshowImpl(com::sun::star::uno::Reference<com::sun::star::presentation::XPresentation2> const&, sd::ViewShell*, sd::View*, SdDrawDocument*, vcl::Window*) |
616 | | |
617 | | SlideshowImpl::~SlideshowImpl() |
618 | 0 | { |
619 | | // stop listening to DrawModel (see above) |
620 | 0 | if (nullptr != mpDoc) |
621 | 0 | EndListening(*mpDoc); |
622 | |
|
623 | 0 | SdModule* pModule = SdModule::get(); |
624 | | //rhbz#806663 SlideshowImpl can outlive SdModule |
625 | 0 | SdOptions* pOptions = pModule ? |
626 | 0 | pModule->GetSdOptions(DocumentType::Impress) : nullptr; |
627 | 0 | if( pOptions ) |
628 | 0 | { |
629 | 0 | pOptions->SetPresentationPenColor(mnUserPaintColor); |
630 | 0 | pOptions->SetPresentationPenWidth(mdUserPaintStrokeWidth); |
631 | 0 | } |
632 | |
|
633 | 0 | Application::RemoveEventListener( LINK( this, SlideshowImpl, EventListenerHdl ) ); |
634 | |
|
635 | 0 | maDeactivateTimer.Stop(); |
636 | |
|
637 | 0 | if( !mbDisposed ) |
638 | 0 | { |
639 | 0 | OSL_FAIL("SlideshowImpl::~SlideshowImpl(), component was not disposed!"); |
640 | 0 | std::unique_lock g(m_aMutex); |
641 | 0 | disposing(g); |
642 | 0 | } |
643 | 0 | } |
644 | | |
645 | | void SlideshowImpl::disposing(std::unique_lock<std::mutex>&) |
646 | 0 | { |
647 | | #ifdef ENABLE_SDREMOTE |
648 | | RemoteServer::presentationStopped(); |
649 | | #endif |
650 | | // IASS: This is the central methodology to 'steer' the |
651 | | // PresenterConsole - in this case, to shut it down |
652 | 0 | if( mxShow.is() && mpDoc ) |
653 | 0 | NotifyDocumentEvent( |
654 | 0 | *mpDoc, |
655 | 0 | u"OnEndPresentation"_ustr ); |
656 | |
|
657 | 0 | if( mbAutoSaveWasOn ) |
658 | 0 | setAutoSaveState( true ); |
659 | |
|
660 | 0 | if( mnEndShowEvent ) |
661 | 0 | Application::RemoveUserEvent( mnEndShowEvent ); |
662 | 0 | if( mnContextMenuEvent ) |
663 | 0 | Application::RemoveUserEvent( mnContextMenuEvent ); |
664 | 0 | if( mnEventObjectChange ) |
665 | 0 | Application::RemoveUserEvent( mnEventObjectChange ); |
666 | 0 | if( mnEventObjectInserted ) |
667 | 0 | Application::RemoveUserEvent( mnEventObjectInserted ); |
668 | 0 | if( mnEventObjectRemoved ) |
669 | 0 | Application::RemoveUserEvent( mnEventObjectRemoved ); |
670 | 0 | if( mnEventPageOrderChange ) |
671 | 0 | Application::RemoveUserEvent( mnEventPageOrderChange ); |
672 | |
|
673 | 0 | maInputFreezeTimer.Stop(); |
674 | |
|
675 | 0 | SolarMutexGuard aSolarGuard; |
676 | |
|
677 | 0 | if( !mxShow.is() ) |
678 | 0 | return; |
679 | | |
680 | 0 | if( mxPresentation.is() ) |
681 | 0 | mxPresentation->end(); |
682 | |
|
683 | 0 | maUpdateTimer.Stop(); |
684 | |
|
685 | 0 | removeShapeEvents(); |
686 | |
|
687 | 0 | if( mxListenerProxy.is() ) |
688 | 0 | mxListenerProxy->removeAsSlideShowListener(); |
689 | |
|
690 | 0 | try |
691 | 0 | { |
692 | 0 | if( mxView.is() ) |
693 | 0 | mxShow->removeView( mxView ); |
694 | |
|
695 | 0 | Reference< XComponent > xComponent( mxShow, UNO_QUERY ); |
696 | 0 | if( xComponent.is() ) |
697 | 0 | xComponent->dispose(); |
698 | |
|
699 | 0 | if( mxView.is() ) |
700 | 0 | mxView->dispose(); |
701 | 0 | } |
702 | 0 | catch( Exception& ) |
703 | 0 | { |
704 | 0 | TOOLS_WARN_EXCEPTION( "sd", "sd::SlideshowImpl::stop()" ); |
705 | 0 | } |
706 | | |
707 | 0 | mxShow.clear(); |
708 | 0 | mxView.clear(); |
709 | 0 | mxListenerProxy.clear(); |
710 | 0 | mpSlideController.reset(); |
711 | | |
712 | | // take DrawView from presentation window, but give the old window back |
713 | 0 | if( mpShowWindow && mpView ) |
714 | 0 | mpView->DeleteDeviceFromPaintView( *mpShowWindow->GetOutDev() ); |
715 | |
|
716 | 0 | if( mpView ) |
717 | 0 | mpView->SetAnimationPause( false ); |
718 | |
|
719 | 0 | if( mpViewShell ) |
720 | 0 | { |
721 | 0 | mpViewShell->SetActiveWindow(mpOldActiveWindow); |
722 | 0 | if (mpShowWindow) |
723 | 0 | mpShowWindow->SetViewShell( nullptr ); |
724 | 0 | } |
725 | |
|
726 | 0 | if( mpView ) |
727 | 0 | mpView->InvalidateAllWin(); |
728 | |
|
729 | 0 | if( maPresSettings.mbFullScreen ) |
730 | 0 | { |
731 | | #if HAVE_FEATURE_SCRIPTING |
732 | | // restore StarBASICErrorHdl |
733 | | StarBASIC::SetGlobalErrorHdl(maStarBASICGlobalErrorHdl); |
734 | | maStarBASICGlobalErrorHdl = Link<StarBASIC*,bool>(); |
735 | | #endif |
736 | 0 | } |
737 | 0 | else |
738 | 0 | { |
739 | 0 | if( mpShowWindow ) |
740 | 0 | mpShowWindow->Hide(); |
741 | 0 | } |
742 | |
|
743 | 0 | if( meAnimationMode == ANIMATIONMODE_SHOW ) |
744 | 0 | { |
745 | 0 | mpDocSh->SetSlotFilter(); |
746 | 0 | mpDocSh->ApplySlotFilter(); |
747 | |
|
748 | 0 | Help::EnableContextHelp(); |
749 | 0 | Help::EnableExtHelp(); |
750 | |
|
751 | 0 | showChildWindows(); |
752 | 0 | mnChildMask = 0; |
753 | 0 | } |
754 | | |
755 | | // show current window again |
756 | 0 | if( mpViewShell && dynamic_cast< PresentationViewShell *>( mpViewShell ) == nullptr) |
757 | 0 | { |
758 | 0 | if( meAnimationMode == ANIMATIONMODE_SHOW ) |
759 | 0 | { |
760 | 0 | mpViewShell->GetViewShellBase().ShowUIControls (true); |
761 | 0 | mpPaneHider.reset(); |
762 | 0 | } |
763 | 0 | else if( meAnimationMode == ANIMATIONMODE_PREVIEW ) |
764 | 0 | { |
765 | 0 | mpViewShell->ShowUIControls(true); |
766 | 0 | } |
767 | 0 | } |
768 | |
|
769 | 0 | if( mpShowWindow ) |
770 | 0 | mpShowWindow->Hide(); |
771 | 0 | mpShowWindow.disposeAndClear(); |
772 | |
|
773 | 0 | if ( mpViewShell ) |
774 | 0 | { |
775 | 0 | if( meAnimationMode == ANIMATIONMODE_SHOW ) |
776 | 0 | { |
777 | 0 | ::sd::Window* pActWin = mpViewShell->GetActiveWindow(); |
778 | |
|
779 | 0 | if (pActWin) |
780 | 0 | { |
781 | 0 | Size aVisSizePixel = pActWin->GetOutputSizePixel(); |
782 | 0 | ::tools::Rectangle aVisAreaWin = pActWin->PixelToLogic( ::tools::Rectangle( Point(0,0), aVisSizePixel) ); |
783 | 0 | mpViewShell->VisAreaChanged(aVisAreaWin); |
784 | 0 | if (mpView) |
785 | 0 | mpView->VisAreaChanged(pActWin->GetOutDev()); |
786 | 0 | pActWin->GrabFocus(); |
787 | 0 | } |
788 | 0 | } |
789 | | |
790 | | // restart the custom show dialog if he started us |
791 | 0 | if( mpViewShell->IsStartShowWithDialog() && getDispatcher() ) |
792 | 0 | { |
793 | 0 | mpViewShell->SetStartShowWithDialog( false ); |
794 | 0 | getDispatcher()->Execute( SID_CUSTOMSHOW_DLG, SfxCallMode::ASYNCHRON | SfxCallMode::RECORD ); |
795 | 0 | } |
796 | |
|
797 | 0 | mpViewShell->GetViewShellBase().UpdateBorder(true); |
798 | 0 | } |
799 | |
|
800 | 0 | if( mpShowWindow ) |
801 | 0 | { |
802 | 0 | mpShowWindow.disposeAndClear(); |
803 | 0 | } |
804 | |
|
805 | 0 | setActiveXToolbarsVisible( true ); |
806 | |
|
807 | 0 | mbDisposed = true; |
808 | 0 | } |
809 | | |
810 | | bool SlideshowImpl::isInteractiveSetup() const |
811 | 0 | { |
812 | 0 | return mbInterActiveSetup; |
813 | 0 | } |
814 | | |
815 | | void SlideshowImpl::startInteractivePreview( const Reference< XDrawPage >& xDrawPage, const Reference< XAnimationNode >& xAnimationNode ) |
816 | 0 | { |
817 | | // set flag that we are in IASS mode |
818 | 0 | mbInterActiveSetup = true; |
819 | | |
820 | | // save stuff that will be replaced temporarily |
821 | 0 | mxShow2 = mxShow; |
822 | 0 | mxView2 = mxView; |
823 | 0 | mxPreviewDrawPage2 = mxPreviewDrawPage; |
824 | 0 | mxPreviewAnimationNode2 = mxPreviewAnimationNode; |
825 | 0 | meAnimationMode2 = meAnimationMode; |
826 | 0 | maPresSettings2 = maPresSettings; |
827 | | |
828 | | // remember slide shown before preview |
829 | 0 | mnSlideIndex = getCurrentSlideIndex(); |
830 | | |
831 | | // set DrawPage/AnimationNode |
832 | 0 | mxPreviewDrawPage = xDrawPage; |
833 | 0 | mxPreviewAnimationNode = xAnimationNode; |
834 | 0 | meAnimationMode = ANIMATIONMODE_PREVIEW; |
835 | | |
836 | | // set PresSettings for preview |
837 | 0 | maPresSettings.mbAll = false; |
838 | 0 | maPresSettings.mbEndless = false; |
839 | 0 | maPresSettings.mbCustomShow = false; |
840 | 0 | maPresSettings.mbManual = false; |
841 | 0 | maPresSettings.mbMouseVisible = false; |
842 | 0 | maPresSettings.mbMouseAsPen = false; |
843 | 0 | maPresSettings.mbLockedPages = false; |
844 | 0 | maPresSettings.mbAlwaysOnTop = false; |
845 | 0 | maPresSettings.mbFullScreen = false; |
846 | 0 | maPresSettings.mbAnimationAllowed = true; |
847 | 0 | maPresSettings.mnPauseTimeout = 0; |
848 | 0 | maPresSettings.mbShowPauseLogo = false; |
849 | | |
850 | | // create a new temporary AnimationSlideController |
851 | 0 | mpSlideController->pushForPreview(); |
852 | | // Reference< XDrawPagesSupplier > xDrawPages( mpDoc->getUnoModel(), UNO_QUERY_THROW ); |
853 | | // Reference< XIndexAccess > xSlides( xDrawPages->getDrawPages(), UNO_QUERY_THROW ); |
854 | | // mpSlideController = std::make_shared<AnimationSlideController>( xSlides, AnimationSlideController::PREVIEW ); |
855 | 0 | sal_Int32 nSlideNumber = 0; |
856 | 0 | Reference< XPropertySet > xSet( xDrawPage, UNO_QUERY_THROW ); |
857 | 0 | xSet->getPropertyValue( u"Number"_ustr ) >>= nSlideNumber; |
858 | 0 | mpSlideController->insertSlideNumber( nSlideNumber-1 ); |
859 | 0 | mpSlideController->setPreviewNode( xAnimationNode ); |
860 | | |
861 | | // prepare properties |
862 | 0 | sal_Int32 nPropertyCount = 1; |
863 | 0 | if( xAnimationNode.is() ) |
864 | 0 | nPropertyCount++; |
865 | 0 | Sequence< beans::PropertyValue > aProperties(nPropertyCount); |
866 | 0 | auto pProperties = aProperties.getArray(); |
867 | 0 | pProperties[0].Name = "AutomaticAdvancement"; |
868 | 0 | pProperties[0].Value <<= 1.0; // one second timeout |
869 | |
|
870 | 0 | if( xAnimationNode.is() ) |
871 | 0 | { |
872 | 0 | pProperties[1].Name = "NoSlideTransitions"; |
873 | 0 | pProperties[1].Value <<= true; |
874 | 0 | } |
875 | | |
876 | | // start preview |
877 | 0 | startShowImpl( aProperties ); |
878 | 0 | } |
879 | | |
880 | | void SlideshowImpl::endInteractivePreview() |
881 | 0 | { |
882 | 0 | if (!mbInterActiveSetup) |
883 | | // not in use, nothing to do |
884 | 0 | return; |
885 | | |
886 | | // cleanup Show/View |
887 | 0 | try |
888 | 0 | { |
889 | 0 | if( mxView.is() ) |
890 | 0 | mxShow->removeView( mxView ); |
891 | |
|
892 | 0 | Reference< XComponent > xComponent( mxShow, UNO_QUERY ); |
893 | 0 | if( xComponent.is() ) |
894 | 0 | xComponent->dispose(); |
895 | |
|
896 | 0 | if( mxView.is() ) |
897 | 0 | mxView->dispose(); |
898 | 0 | } |
899 | 0 | catch( Exception& ) |
900 | 0 | { |
901 | 0 | TOOLS_WARN_EXCEPTION( "sd", "sd::SlideshowImpl::stop()" ); |
902 | 0 | } |
903 | 0 | mxShow.clear(); |
904 | 0 | mxView.clear(); |
905 | 0 | mxView = mxView2; |
906 | 0 | mxShow = mxShow2; |
907 | | |
908 | | // restore SlideController |
909 | 0 | mpSlideController->popFromPreview(); |
910 | | |
911 | | // restore other settings and cleanup temporary incarnations |
912 | 0 | maPresSettings = maPresSettings2; |
913 | 0 | meAnimationMode = meAnimationMode2; |
914 | 0 | mxPreviewAnimationNode = mxPreviewAnimationNode2; |
915 | 0 | mxPreviewAnimationNode2.clear(); |
916 | 0 | mxPreviewDrawPage = mxPreviewDrawPage2; |
917 | 0 | mxPreviewDrawPage2.clear(); |
918 | | |
919 | | // go back to slide shown before preview |
920 | 0 | gotoSlideIndex(mnSlideIndex); |
921 | | |
922 | | // reset IASS mode flag |
923 | 0 | mbInterActiveSetup = false; |
924 | 0 | } |
925 | | |
926 | | bool SlideshowImpl::startPreview( |
927 | | const Reference< XDrawPage >& xDrawPage, |
928 | | const Reference< XAnimationNode >& xAnimationNode, |
929 | | vcl::Window * pParent ) |
930 | 0 | { |
931 | 0 | bool bRet = false; |
932 | |
|
933 | 0 | try |
934 | 0 | { |
935 | 0 | const Reference<lang::XServiceInfo> xServiceInfo( xDrawPage, UNO_QUERY ); |
936 | 0 | if (xServiceInfo.is()) { |
937 | 0 | const Sequence<OUString> supportedServices( |
938 | 0 | xServiceInfo->getSupportedServiceNames() ); |
939 | 0 | if (comphelper::findValue(supportedServices, "com.sun.star.drawing.MasterPage") != -1) { |
940 | 0 | OSL_FAIL("sd::SlideshowImpl::startPreview() " |
941 | 0 | "not allowed on master page!"); |
942 | 0 | return false; |
943 | 0 | } |
944 | 0 | } |
945 | | |
946 | 0 | mxPreviewDrawPage = xDrawPage; |
947 | 0 | mxPreviewAnimationNode = xAnimationNode; |
948 | 0 | meAnimationMode = ANIMATIONMODE_PREVIEW; |
949 | |
|
950 | 0 | maPresSettings.mbAll = false; |
951 | 0 | maPresSettings.mbEndless = false; |
952 | 0 | maPresSettings.mbCustomShow = false; |
953 | 0 | maPresSettings.mbManual = false; |
954 | 0 | maPresSettings.mbMouseVisible = false; |
955 | 0 | maPresSettings.mbMouseAsPen = false; |
956 | 0 | maPresSettings.mbLockedPages = false; |
957 | 0 | maPresSettings.mbAlwaysOnTop = false; |
958 | 0 | maPresSettings.mbFullScreen = false; |
959 | 0 | maPresSettings.mbAnimationAllowed = true; |
960 | 0 | maPresSettings.mnPauseTimeout = 0; |
961 | 0 | maPresSettings.mbShowPauseLogo = false; |
962 | |
|
963 | 0 | rtl::Reference< SdXImpressDocument > xDrawPages( mpDoc->getUnoModel() ); |
964 | 0 | Reference< XIndexAccess > xSlides( xDrawPages->getDrawPages(), UNO_QUERY_THROW ); |
965 | 0 | mpSlideController = std::make_unique<AnimationSlideController>( xSlides, AnimationSlideController::PREVIEW ); |
966 | |
|
967 | 0 | sal_Int32 nSlideNumber = 0; |
968 | 0 | Reference< XPropertySet > xSet( mxPreviewDrawPage, UNO_QUERY_THROW ); |
969 | 0 | xSet->getPropertyValue( u"Number"_ustr ) >>= nSlideNumber; |
970 | 0 | mpSlideController->insertSlideNumber( nSlideNumber-1 ); |
971 | 0 | mpSlideController->setPreviewNode( xAnimationNode ); |
972 | |
|
973 | 0 | mpShowWindow = VclPtr<ShowWindow>::Create( this, ((pParent == nullptr) && mpViewShell) ? mpParentWindow.get() : pParent ); |
974 | 0 | if( mpViewShell ) |
975 | 0 | { |
976 | 0 | mpViewShell->SetActiveWindow( mpShowWindow ); |
977 | 0 | mpShowWindow->SetViewShell (mpViewShell); |
978 | 0 | mpViewShell->ShowUIControls (false); |
979 | 0 | } |
980 | |
|
981 | 0 | if( mpView ) |
982 | 0 | { |
983 | 0 | mpView->AddDeviceToPaintView( *mpShowWindow->GetOutDev(), nullptr ); |
984 | 0 | mpView->SetAnimationPause( true ); |
985 | 0 | } |
986 | | |
987 | | // call resize handler |
988 | 0 | if( pParent ) |
989 | 0 | { |
990 | 0 | maPresSize = pParent->GetSizePixel(); |
991 | 0 | } |
992 | 0 | else if( mpViewShell ) |
993 | 0 | { |
994 | 0 | ::tools::Rectangle aContentRect (mpViewShell->GetViewShellBase().getClientRectangle()); |
995 | 0 | if (AllSettings::GetLayoutRTL()) |
996 | 0 | { |
997 | 0 | aContentRect.SetLeft( aContentRect.Right() ); |
998 | 0 | aContentRect.AdjustRight(aContentRect.Right() ); |
999 | 0 | } |
1000 | 0 | maPresSize = aContentRect.GetSize(); |
1001 | 0 | mpShowWindow->SetPosPixel( aContentRect.TopLeft() ); |
1002 | 0 | } |
1003 | 0 | else |
1004 | 0 | { |
1005 | 0 | OSL_FAIL("sd::SlideshowImpl::startPreview(), I need either a parent window or a viewshell!"); |
1006 | 0 | } |
1007 | 0 | resize( maPresSize ); |
1008 | |
|
1009 | 0 | sal_Int32 nPropertyCount = 1; |
1010 | 0 | if( mxPreviewAnimationNode.is() ) |
1011 | 0 | nPropertyCount++; |
1012 | |
|
1013 | 0 | Sequence< beans::PropertyValue > aProperties(nPropertyCount); |
1014 | 0 | auto pProperties = aProperties.getArray(); |
1015 | 0 | pProperties[0].Name = "AutomaticAdvancement"; |
1016 | 0 | pProperties[0].Value <<= 1.0; // one second timeout |
1017 | |
|
1018 | 0 | if( mxPreviewAnimationNode.is() ) |
1019 | 0 | { |
1020 | 0 | pProperties[1].Name = "NoSlideTransitions"; |
1021 | 0 | pProperties[1].Value <<= true; |
1022 | 0 | } |
1023 | |
|
1024 | 0 | bRet = startShowImpl( aProperties ); |
1025 | |
|
1026 | 0 | if( mpShowWindow != nullptr && meAnimationMode == ANIMATIONMODE_PREVIEW ) |
1027 | 0 | mpShowWindow->SetPreviewMode(); |
1028 | |
|
1029 | 0 | } |
1030 | 0 | catch( Exception& ) |
1031 | 0 | { |
1032 | 0 | TOOLS_WARN_EXCEPTION( "sd", "sd::SlideshowImpl::startPreview()" ); |
1033 | 0 | bRet = false; |
1034 | 0 | } |
1035 | | |
1036 | 0 | return bRet; |
1037 | 0 | } |
1038 | | |
1039 | | bool SlideshowImpl::startShow( PresentationSettingsEx const * pPresSettings ) |
1040 | 0 | { |
1041 | 0 | const rtl::Reference<SlideshowImpl> xKeepAlive(this); |
1042 | |
|
1043 | 0 | DBG_ASSERT( !mxShow.is(), "sd::SlideshowImpl::startShow(), called twice!" ); |
1044 | 0 | if( mxShow.is() ) |
1045 | 0 | return true; |
1046 | 0 | DBG_ASSERT( mpParentWindow!=nullptr, "sd::SlideshowImpl::startShow() called without parent window" ); |
1047 | 0 | if (mpParentWindow == nullptr) |
1048 | 0 | return false; |
1049 | | |
1050 | | // Autoplay (pps/ppsx) |
1051 | 0 | if (mpViewShell->GetDoc()->GetStartWithPresentation()) |
1052 | 0 | { |
1053 | 0 | mpViewShell->GetDoc()->SetExitAfterPresenting(true); |
1054 | 0 | } |
1055 | |
|
1056 | 0 | bool bRet = false; |
1057 | |
|
1058 | 0 | try |
1059 | 0 | { |
1060 | 0 | if( pPresSettings ) |
1061 | 0 | { |
1062 | 0 | maPresSettings = *pPresSettings; |
1063 | 0 | mbRehearseTimings = pPresSettings->mbRehearseTimings; |
1064 | 0 | } |
1065 | |
|
1066 | 0 | OUString aPresSlide( maPresSettings.maPresPage ); |
1067 | 0 | SdPage* pStartPage = mpViewShell->GetActualPage(); |
1068 | 0 | bool bStartWithActualSlide = pStartPage; |
1069 | | |
1070 | | // times should be measured? |
1071 | 0 | if( mbRehearseTimings ) |
1072 | 0 | { |
1073 | 0 | maPresSettings.mbEndless = false; |
1074 | 0 | maPresSettings.mbManual = true; |
1075 | 0 | maPresSettings.mbMouseVisible = true; |
1076 | 0 | maPresSettings.mbMouseAsPen = false; |
1077 | 0 | maPresSettings.mnPauseTimeout = 0; |
1078 | 0 | maPresSettings.mbShowPauseLogo = false; |
1079 | 0 | } |
1080 | |
|
1081 | 0 | if( pStartPage ) |
1082 | 0 | { |
1083 | 0 | if( pStartPage->GetPageKind() == PageKind::Notes ) |
1084 | 0 | { |
1085 | | // we are in notes page mode, so get |
1086 | | // the corresponding draw page |
1087 | 0 | const sal_uInt16 nNotePgNum = pStartPage->GetPageNum(); |
1088 | 0 | assert(nNotePgNum >= 2); |
1089 | 0 | const sal_uInt16 nPgNum = ( nNotePgNum - 2 ) >> 1; |
1090 | 0 | pStartPage = mpDoc->GetSdPage( nPgNum, PageKind::Standard ); |
1091 | 0 | } |
1092 | 0 | } |
1093 | |
|
1094 | 0 | if( bStartWithActualSlide ) |
1095 | 0 | { |
1096 | 0 | if ( aPresSlide.isEmpty()) |
1097 | 0 | { |
1098 | | // no preset slide yet, so pick current on one |
1099 | 0 | aPresSlide = pStartPage->GetName(); |
1100 | | // if the starting slide is hidden, we can't set slide controller to ALL mode |
1101 | 0 | maPresSettings.mbAll = !pStartPage->IsExcluded(); |
1102 | 0 | } |
1103 | |
|
1104 | 0 | if( meAnimationMode != ANIMATIONMODE_SHOW ) |
1105 | 0 | { |
1106 | 0 | if( pStartPage->GetPageKind() == PageKind::Standard ) |
1107 | 0 | { |
1108 | 0 | maPresSettings.mbAll = false; |
1109 | 0 | } |
1110 | 0 | } |
1111 | 0 | } |
1112 | | |
1113 | | // build page list |
1114 | 0 | createSlideList( maPresSettings.mbAll, aPresSlide ); |
1115 | | |
1116 | | // remember Slide number from where the show was started |
1117 | 0 | if( pStartPage ) |
1118 | 0 | mnRestoreSlide = ( pStartPage->GetPageNum() - 1 ) / 2; |
1119 | |
|
1120 | 0 | if( mpSlideController->hasSlides() ) |
1121 | 0 | { |
1122 | | // hide child windows |
1123 | 0 | hideChildWindows(); |
1124 | |
|
1125 | 0 | mpShowWindow = VclPtr<ShowWindow>::Create( this, mpParentWindow ); |
1126 | 0 | mpShowWindow->SetMouseAutoHide( !maPresSettings.mbMouseVisible ); |
1127 | 0 | mpViewShell->SetActiveWindow( mpShowWindow ); |
1128 | 0 | mpShowWindow->SetViewShell (mpViewShell); |
1129 | 0 | mpViewShell->GetViewShellBase().ShowUIControls (false); |
1130 | | // Hide the side panes for in-place presentations. |
1131 | 0 | if ( ! maPresSettings.mbFullScreen) |
1132 | 0 | mpPaneHider.reset(new PaneHider(*mpViewShell,this)); |
1133 | | |
1134 | | // these Slots are forbidden in other views for this document |
1135 | 0 | if( mpDocSh && pPresSettings && !pPresSettings->mbInteractive) // IASS |
1136 | 0 | { |
1137 | 0 | mpDocSh->SetSlotFilter( true, pAllowed ); |
1138 | 0 | mpDocSh->ApplySlotFilter(); |
1139 | 0 | } |
1140 | |
|
1141 | 0 | Help::DisableContextHelp(); |
1142 | 0 | Help::DisableExtHelp(); |
1143 | |
|
1144 | 0 | if( maPresSettings.mbFullScreen ) |
1145 | 0 | { |
1146 | | #if HAVE_FEATURE_SCRIPTING |
1147 | | // disable basic ide error handling |
1148 | | maStarBASICGlobalErrorHdl = StarBASIC::GetGlobalErrorHdl(); |
1149 | | StarBASIC::SetGlobalErrorHdl( Link<StarBASIC*,bool>() ); |
1150 | | #endif |
1151 | 0 | } |
1152 | | |
1153 | | // call resize handler |
1154 | 0 | maPresSize = mpParentWindow->GetSizePixel(); |
1155 | 0 | if (!maPresSettings.mbFullScreen) |
1156 | 0 | { |
1157 | 0 | const ::tools::Rectangle& aClientRect = mpViewShell->GetViewShellBase().getClientRectangle(); |
1158 | 0 | maPresSize = aClientRect.GetSize(); |
1159 | 0 | mpShowWindow->SetPosPixel( aClientRect.TopLeft() ); |
1160 | 0 | resize( maPresSize ); |
1161 | 0 | } |
1162 | | |
1163 | | // #i41824# |
1164 | | // Note: In FullScreen Mode the OS (window manager) sends a resize to |
1165 | | // the WorkWindow once it actually resized it to full size. The |
1166 | | // WorkWindow propagates the resize to the DrawViewShell which calls |
1167 | | // resize() at the SlideShow (this). Calling resize here results in a |
1168 | | // temporary display of a black window in the window's default size |
1169 | |
|
1170 | 0 | if( mpView ) |
1171 | 0 | { |
1172 | 0 | mpView->AddDeviceToPaintView( *mpShowWindow->GetOutDev(), nullptr ); |
1173 | 0 | mpView->SetAnimationPause( true ); |
1174 | 0 | } |
1175 | |
|
1176 | 0 | SfxBindings* pBindings = getBindings(); |
1177 | 0 | if( pBindings ) |
1178 | 0 | { |
1179 | 0 | pBindings->Invalidate( SID_PRESENTATION ); |
1180 | 0 | pBindings->Invalidate( SID_REHEARSE_TIMINGS ); |
1181 | 0 | } |
1182 | | |
1183 | | // Defer the sd::ShowWindow's GrabFocus to SlideShow::activate. so that the accessible event can be fired correctly. |
1184 | | //mpShowWindow->GrabFocus(); |
1185 | |
|
1186 | 0 | std::vector<beans::PropertyValue> aProperties; |
1187 | 0 | aProperties.reserve( 4 ); |
1188 | |
|
1189 | 0 | aProperties.emplace_back( "AdvanceOnClick" , |
1190 | 0 | -1, Any( !maPresSettings.mbLockedPages ), |
1191 | 0 | beans::PropertyState_DIRECT_VALUE ); |
1192 | |
|
1193 | 0 | aProperties.emplace_back( "ImageAnimationsAllowed" , |
1194 | 0 | -1, Any( maPresSettings.mbAnimationAllowed ), |
1195 | 0 | beans::PropertyState_DIRECT_VALUE ); |
1196 | |
|
1197 | 0 | const bool bZOrderEnabled( |
1198 | 0 | SdModule::get()->GetSdOptions( mpDoc->GetDocumentType() )->IsSlideshowRespectZOrder() ); |
1199 | 0 | aProperties.emplace_back( "DisableAnimationZOrder" , |
1200 | 0 | -1, Any( !bZOrderEnabled ), |
1201 | 0 | beans::PropertyState_DIRECT_VALUE ); |
1202 | |
|
1203 | 0 | aProperties.emplace_back( "ForceManualAdvance" , |
1204 | 0 | -1, Any( maPresSettings.mbManual ), |
1205 | 0 | beans::PropertyState_DIRECT_VALUE ); |
1206 | |
|
1207 | 0 | if( mbUsePen ) |
1208 | 0 | { |
1209 | 0 | aProperties.emplace_back( "UserPaintColor" , |
1210 | | // User paint color is black by default. |
1211 | 0 | -1, Any( mnUserPaintColor ), |
1212 | 0 | beans::PropertyState_DIRECT_VALUE ); |
1213 | |
|
1214 | 0 | aProperties.emplace_back( "UserPaintStrokeWidth" , |
1215 | | // User paint color is black by default. |
1216 | 0 | -1, Any( mdUserPaintStrokeWidth ), |
1217 | 0 | beans::PropertyState_DIRECT_VALUE ); |
1218 | 0 | } |
1219 | |
|
1220 | 0 | if (mbRehearseTimings) { |
1221 | 0 | aProperties.emplace_back( "RehearseTimings" , |
1222 | 0 | -1, Any(true), beans::PropertyState_DIRECT_VALUE ); |
1223 | 0 | } |
1224 | |
|
1225 | 0 | bRet = startShowImpl( Sequence<beans::PropertyValue>( |
1226 | 0 | aProperties.data(), aProperties.size() ) ); |
1227 | |
|
1228 | 0 | } |
1229 | |
|
1230 | 0 | setActiveXToolbarsVisible( false ); |
1231 | 0 | } |
1232 | 0 | catch (const Exception&) |
1233 | 0 | { |
1234 | 0 | TOOLS_WARN_EXCEPTION( "sd", "sd::SlideshowImpl::startShow()" ); |
1235 | 0 | bRet = false; |
1236 | 0 | } |
1237 | | |
1238 | 0 | return bRet; |
1239 | 0 | } |
1240 | | |
1241 | | bool SlideshowImpl::startShowImpl( const Sequence< beans::PropertyValue >& aProperties ) |
1242 | 0 | { |
1243 | 0 | try |
1244 | 0 | { |
1245 | 0 | mxShow.set( createSlideShow(), UNO_SET_THROW ); |
1246 | |
|
1247 | 0 | mxView = new SlideShowView( |
1248 | 0 | *mpShowWindow, |
1249 | 0 | mpDoc, |
1250 | 0 | meAnimationMode, |
1251 | 0 | this, |
1252 | 0 | maPresSettings.mbFullScreen); |
1253 | | |
1254 | | // try add wait symbol to properties: |
1255 | 0 | const Reference<rendering::XSpriteCanvas> xSpriteCanvas( |
1256 | 0 | mxView->getCanvas() ); |
1257 | 0 | if (xSpriteCanvas.is()) |
1258 | 0 | { |
1259 | 0 | Bitmap waitSymbolBitmap(BMP_WAIT_ICON); |
1260 | 0 | const Reference<rendering::XBitmap> xBitmap( |
1261 | 0 | vcl::unotools::xBitmapFromBitmap( waitSymbolBitmap ) ); |
1262 | 0 | if (xBitmap.is()) |
1263 | 0 | { |
1264 | 0 | mxShow->setProperty( |
1265 | 0 | beans::PropertyValue( u"WaitSymbolBitmap"_ustr , |
1266 | 0 | -1, |
1267 | 0 | Any( xBitmap ), |
1268 | 0 | beans::PropertyState_DIRECT_VALUE ) ); |
1269 | 0 | } |
1270 | |
|
1271 | 0 | Bitmap pointerSymbolBitmap(BMP_POINTER_ICON); |
1272 | 0 | const Reference<rendering::XBitmap> xPointerBitmap( |
1273 | 0 | vcl::unotools::xBitmapFromBitmap( pointerSymbolBitmap ) ); |
1274 | 0 | if (xPointerBitmap.is()) |
1275 | 0 | { |
1276 | 0 | mxShow->setProperty( |
1277 | 0 | beans::PropertyValue( u"PointerSymbolBitmap"_ustr , |
1278 | 0 | -1, |
1279 | 0 | Any( xPointerBitmap ), |
1280 | 0 | beans::PropertyState_DIRECT_VALUE ) ); |
1281 | 0 | } |
1282 | 0 | if (officecfg::Office::Impress::Misc::Start::ShowNavigationPanel::get()) |
1283 | 0 | { |
1284 | 0 | NavbarButtonSize btnScale = static_cast<NavbarButtonSize>(officecfg::Office::Impress::Layout::Display::NavigationBtnScale::get()); |
1285 | 0 | OUString prevSlidePath = u""_ustr; |
1286 | 0 | OUString nextSlidePath = u""_ustr; |
1287 | 0 | OUString menuPath = u""_ustr; |
1288 | 0 | switch (btnScale) |
1289 | 0 | { |
1290 | 0 | case NavbarButtonSize::Large: |
1291 | 0 | { |
1292 | 0 | prevSlidePath = BMP_PREV_SLIDE_LARGE; |
1293 | 0 | nextSlidePath = BMP_NEXT_SLIDE_LARGE; |
1294 | 0 | menuPath = BMP_MENU_SLIDE_LARGE; |
1295 | 0 | break; |
1296 | 0 | } |
1297 | 0 | case NavbarButtonSize::XLarge: |
1298 | 0 | { |
1299 | 0 | prevSlidePath = BMP_PREV_SLIDE_EXTRALARGE; |
1300 | 0 | nextSlidePath = BMP_NEXT_SLIDE_EXTRALARGE; |
1301 | 0 | menuPath = BMP_MENU_SLIDE_EXTRALARGE; |
1302 | 0 | break; |
1303 | 0 | } |
1304 | 0 | case NavbarButtonSize::Auto: |
1305 | 0 | case NavbarButtonSize::Small: |
1306 | 0 | default: |
1307 | 0 | { |
1308 | 0 | prevSlidePath = BMP_PREV_SLIDE_SMALL; |
1309 | 0 | nextSlidePath = BMP_NEXT_SLIDE_SMALL; |
1310 | 0 | menuPath = BMP_MENU_SLIDE_SMALL; |
1311 | 0 | break; |
1312 | 0 | } |
1313 | 0 | } |
1314 | 0 | Bitmap prevSlideBm(prevSlidePath); |
1315 | 0 | const Reference<rendering::XBitmap> xPrevSBitmap( |
1316 | 0 | vcl::unotools::xBitmapFromBitmap(prevSlideBm)); |
1317 | 0 | if (xPrevSBitmap.is()) |
1318 | 0 | { |
1319 | 0 | mxShow->setProperty(beans::PropertyValue(u"NavigationSlidePrev"_ustr, -1, |
1320 | 0 | Any(xPrevSBitmap), |
1321 | 0 | beans::PropertyState_DIRECT_VALUE)); |
1322 | 0 | } |
1323 | 0 | Bitmap menuSlideBm(menuPath); |
1324 | 0 | const Reference<rendering::XBitmap> xMenuSBitmap( |
1325 | 0 | vcl::unotools::xBitmapFromBitmap(menuSlideBm)); |
1326 | 0 | if (xMenuSBitmap.is()) |
1327 | 0 | { |
1328 | 0 | mxShow->setProperty(beans::PropertyValue(u"NavigationSlideMenu"_ustr, -1, |
1329 | 0 | Any(xMenuSBitmap), |
1330 | 0 | beans::PropertyState_DIRECT_VALUE)); |
1331 | 0 | } |
1332 | 0 | Bitmap nextSlideBm(nextSlidePath); |
1333 | 0 | const Reference<rendering::XBitmap> xNextSBitmap( |
1334 | 0 | vcl::unotools::xBitmapFromBitmap(nextSlideBm)); |
1335 | 0 | if (xNextSBitmap.is()) |
1336 | 0 | { |
1337 | 0 | mxShow->setProperty(beans::PropertyValue(u"NavigationSlideNext"_ustr, -1, |
1338 | 0 | Any(xNextSBitmap), |
1339 | 0 | beans::PropertyState_DIRECT_VALUE)); |
1340 | 0 | } |
1341 | 0 | } |
1342 | 0 | } |
1343 | | |
1344 | 0 | for( const auto& rProp : aProperties ) |
1345 | 0 | mxShow->setProperty( rProp ); |
1346 | |
|
1347 | 0 | mxShow->addView( mxView ); |
1348 | |
|
1349 | 0 | mxListenerProxy.set( new SlideShowListenerProxy( this, mxShow ) ); |
1350 | 0 | mxListenerProxy->addAsSlideShowListener(); |
1351 | | |
1352 | | // IASS: Do only startup the PresenterConsole if this is not |
1353 | | // the SlideShow Preview mode (else would be double) |
1354 | 0 | if (!mbInterActiveSetup) |
1355 | 0 | { |
1356 | | // IASS: This is the central methodology to 'steer' the |
1357 | | // PresenterConsole - in this case, to start it up and make |
1358 | | // it visible (if activated) |
1359 | 0 | NotifyDocumentEvent( |
1360 | 0 | *mpDoc, |
1361 | 0 | u"OnStartPresentation"_ustr); |
1362 | 0 | } |
1363 | |
|
1364 | 0 | displaySlideIndex( mpSlideController->getStartSlideIndex() ); |
1365 | |
|
1366 | 0 | return true; |
1367 | 0 | } |
1368 | 0 | catch( Exception& ) |
1369 | 0 | { |
1370 | 0 | TOOLS_WARN_EXCEPTION( "sd", "sd::SlideshowImpl::startShowImpl()" ); |
1371 | 0 | return false; |
1372 | 0 | } |
1373 | 0 | } |
1374 | | |
1375 | | /** called only by the slideshow view when the first paint event occurs. |
1376 | | This actually starts the slideshow. */ |
1377 | | void SlideshowImpl::onFirstPaint() |
1378 | 0 | { |
1379 | 0 | if( mpShowWindow ) |
1380 | 0 | { |
1381 | | /* |
1382 | | mpShowWindow->SetBackground( Wallpaper( COL_BLACK ) ); |
1383 | | mpShowWindow->Erase(); |
1384 | | mpShowWindow->SetBackground(); |
1385 | | */ |
1386 | 0 | } |
1387 | |
|
1388 | 0 | SolarMutexGuard aSolarGuard; |
1389 | 0 | maUpdateTimer.SetTimeout( sal_uLong(100) ); |
1390 | 0 | maUpdateTimer.Start(); |
1391 | 0 | } |
1392 | | |
1393 | | void SlideshowImpl::paint() |
1394 | 0 | { |
1395 | 0 | if( mxView.is() ) try |
1396 | 0 | { |
1397 | 0 | awt::PaintEvent aEvt; |
1398 | | // aEvt.UpdateRect = TODO |
1399 | 0 | mxView->paint( aEvt ); |
1400 | 0 | } |
1401 | 0 | catch( Exception& ) |
1402 | 0 | { |
1403 | 0 | TOOLS_WARN_EXCEPTION( "sd", "sd::SlideshowImpl::paint()" ); |
1404 | 0 | } |
1405 | 0 | } |
1406 | | |
1407 | | void SAL_CALL SlideshowImpl::addSlideShowListener( const Reference< XSlideShowListener >& xListener ) |
1408 | 0 | { |
1409 | 0 | if( mxListenerProxy.is() ) |
1410 | 0 | mxListenerProxy->addSlideShowListener( xListener ); |
1411 | 0 | } |
1412 | | |
1413 | | void SAL_CALL SlideshowImpl::removeSlideShowListener( const Reference< XSlideShowListener >& xListener ) |
1414 | 0 | { |
1415 | 0 | if( mxListenerProxy.is() ) |
1416 | 0 | mxListenerProxy->removeSlideShowListener( xListener ); |
1417 | 0 | } |
1418 | | |
1419 | | void SlideshowImpl::slideEnded(const bool bReverse) |
1420 | 0 | { |
1421 | 0 | if (bReverse) |
1422 | 0 | gotoPreviousSlide(true); |
1423 | 0 | else |
1424 | 0 | gotoNextSlide(); |
1425 | 0 | } |
1426 | | |
1427 | | bool SlideshowImpl::swipe(const CommandGestureSwipeData &rSwipeData) |
1428 | 0 | { |
1429 | 0 | if (mbUsePen || mnContextMenuEvent) |
1430 | 0 | return false; |
1431 | 0 | double nVelocityX = rSwipeData.getVelocityX(); |
1432 | | // tdf#108475 make it swipe only if some reasonable movement was involved |
1433 | 0 | if (fabs(nVelocityX) < 50) |
1434 | 0 | return false; |
1435 | 0 | if (nVelocityX > 0) |
1436 | 0 | { |
1437 | 0 | gotoPreviousSlide(); |
1438 | 0 | } |
1439 | 0 | else |
1440 | 0 | { |
1441 | 0 | gotoNextEffect(); |
1442 | 0 | } |
1443 | | //a swipe is followed by a mouse up, tell the view to ignore that mouse up as we've reacted |
1444 | | //to the swipe instead |
1445 | 0 | mxView->ignoreNextMouseReleased(); |
1446 | 0 | return true; |
1447 | 0 | } |
1448 | | |
1449 | | bool SlideshowImpl::longpress(const CommandGestureLongPressData &rLongPressData) |
1450 | 0 | { |
1451 | 0 | if (mnContextMenuEvent) |
1452 | 0 | return false; |
1453 | | |
1454 | 0 | maPopupMousePos = Point(rLongPressData.getX(), rLongPressData.getY()); |
1455 | 0 | mnContextMenuEvent = Application::PostUserEvent( LINK( this, SlideshowImpl, ContextMenuHdl ) ); |
1456 | |
|
1457 | 0 | return true; |
1458 | 0 | } |
1459 | | |
1460 | | void SlideshowImpl::removeShapeEvents() |
1461 | 0 | { |
1462 | 0 | if( !(mxShow.is() && mxListenerProxy.is()) ) |
1463 | 0 | return; |
1464 | | |
1465 | 0 | try |
1466 | 0 | { |
1467 | 0 | for( const auto& rEntry : maShapeEventMap ) |
1468 | 0 | { |
1469 | 0 | mxListenerProxy->removeShapeEventListener( rEntry.first ); |
1470 | 0 | mxShow->setShapeCursor( rEntry.first, awt::SystemPointer::ARROW ); |
1471 | 0 | } |
1472 | |
|
1473 | 0 | maShapeEventMap.clear(); |
1474 | 0 | } |
1475 | 0 | catch( Exception& ) |
1476 | 0 | { |
1477 | 0 | TOOLS_WARN_EXCEPTION( "sd", "sd::SlideshowImpl::removeShapeEvents()" ); |
1478 | 0 | } |
1479 | 0 | } |
1480 | | |
1481 | | void SlideshowImpl::registerShapeEvents(sal_Int32 nSlideNumber) |
1482 | 0 | { |
1483 | 0 | if( nSlideNumber < 0 ) |
1484 | 0 | return; |
1485 | | |
1486 | 0 | try |
1487 | 0 | { |
1488 | 0 | Reference< XIndexAccess > xPages( mxModel->getDrawPages(), UNO_QUERY_THROW ); |
1489 | |
|
1490 | 0 | Reference< XShapes > xDrawPage; |
1491 | 0 | xPages->getByIndex(nSlideNumber) >>= xDrawPage; |
1492 | |
|
1493 | 0 | if( xDrawPage.is() ) |
1494 | 0 | { |
1495 | 0 | Reference< XMasterPageTarget > xMasterPageTarget( xDrawPage, UNO_QUERY ); |
1496 | 0 | if( xMasterPageTarget.is() ) |
1497 | 0 | { |
1498 | 0 | Reference< XShapes > xMasterPage = xMasterPageTarget->getMasterPage(); |
1499 | 0 | if( xMasterPage.is() ) |
1500 | 0 | registerShapeEvents( xMasterPage ); |
1501 | 0 | } |
1502 | 0 | registerShapeEvents( xDrawPage ); |
1503 | 0 | } |
1504 | 0 | } |
1505 | 0 | catch( Exception& ) |
1506 | 0 | { |
1507 | 0 | TOOLS_WARN_EXCEPTION( "sd", "sd::SlideshowImpl::registerShapeEvents()" ); |
1508 | 0 | } |
1509 | 0 | } |
1510 | | |
1511 | | void SlideshowImpl::registerShapeEvents( Reference< XShapes > const & xShapes ) |
1512 | 0 | { |
1513 | 0 | try |
1514 | 0 | { |
1515 | 0 | const sal_Int32 nShapeCount = xShapes->getCount(); |
1516 | 0 | sal_Int32 nShape; |
1517 | 0 | for( nShape = 0; nShape < nShapeCount; nShape++ ) |
1518 | 0 | { |
1519 | 0 | Reference< XShape > xShape; |
1520 | 0 | xShapes->getByIndex( nShape ) >>= xShape; |
1521 | |
|
1522 | 0 | if( xShape.is() && xShape->getShapeType() == "com.sun.star.drawing.GroupShape" ) |
1523 | 0 | { |
1524 | 0 | Reference< XShapes > xSubShapes( xShape, UNO_QUERY ); |
1525 | 0 | if( xSubShapes.is() ) |
1526 | 0 | registerShapeEvents( xSubShapes ); |
1527 | 0 | } |
1528 | |
|
1529 | 0 | Reference< XPropertySet > xSet( xShape, UNO_QUERY ); |
1530 | 0 | if( !xSet.is() ) |
1531 | 0 | continue; |
1532 | | |
1533 | 0 | Reference< XPropertySetInfo > xSetInfo( xSet->getPropertySetInfo() ); |
1534 | 0 | if( !xSetInfo.is() || !xSetInfo->hasPropertyByName( gsOnClick ) ) |
1535 | 0 | continue; |
1536 | | |
1537 | 0 | WrappedShapeEventImpl aEvent; |
1538 | 0 | xSet->getPropertyValue( gsOnClick ) >>= aEvent.meClickAction; |
1539 | |
|
1540 | 0 | switch( aEvent.meClickAction ) |
1541 | 0 | { |
1542 | 0 | case ClickAction_PREVPAGE: |
1543 | 0 | case ClickAction_NEXTPAGE: |
1544 | 0 | case ClickAction_FIRSTPAGE: |
1545 | 0 | case ClickAction_LASTPAGE: |
1546 | 0 | case ClickAction_STOPPRESENTATION: |
1547 | 0 | break; |
1548 | 0 | case ClickAction_BOOKMARK: |
1549 | 0 | if( xSetInfo->hasPropertyByName( gsBookmark ) ) |
1550 | 0 | xSet->getPropertyValue( gsBookmark ) >>= aEvent.maStrBookmark; |
1551 | 0 | if( getSlideNumberForBookmark( aEvent.maStrBookmark ) == -1 ) |
1552 | 0 | continue; |
1553 | 0 | break; |
1554 | 0 | case ClickAction_DOCUMENT: |
1555 | 0 | case ClickAction_SOUND: |
1556 | 0 | case ClickAction_PROGRAM: |
1557 | 0 | case ClickAction_MACRO: |
1558 | 0 | if( xSetInfo->hasPropertyByName( gsBookmark ) ) |
1559 | 0 | xSet->getPropertyValue( gsBookmark ) >>= aEvent.maStrBookmark; |
1560 | 0 | break; |
1561 | 0 | case ClickAction_VERB: |
1562 | 0 | if( xSetInfo->hasPropertyByName( gsVerb ) ) |
1563 | 0 | xSet->getPropertyValue( gsVerb ) >>= aEvent.mnVerb; |
1564 | 0 | break; |
1565 | 0 | default: |
1566 | 0 | continue; // skip all others |
1567 | 0 | } |
1568 | | |
1569 | 0 | maShapeEventMap[ xShape ] = std::move(aEvent); |
1570 | |
|
1571 | 0 | if( mxListenerProxy.is() ) |
1572 | 0 | mxListenerProxy->addShapeEventListener( xShape ); |
1573 | 0 | mxShow->setShapeCursor( xShape, awt::SystemPointer::REFHAND ); |
1574 | 0 | } |
1575 | 0 | } |
1576 | 0 | catch( Exception& ) |
1577 | 0 | { |
1578 | 0 | TOOLS_WARN_EXCEPTION( "sd", "sd::SlideshowImpl::registerShapeEvents()" ); |
1579 | 0 | } |
1580 | 0 | } |
1581 | | |
1582 | | void SlideshowImpl::displayCurrentSlide (const bool bSkipAllMainSequenceEffects) |
1583 | 0 | { |
1584 | 0 | stopSound(); |
1585 | 0 | removeShapeEvents(); |
1586 | |
|
1587 | 0 | if( mpSlideController && mxShow.is() ) |
1588 | 0 | { |
1589 | 0 | rtl::Reference< SdXImpressDocument > xDrawPages( mpDoc->getUnoModel() ); |
1590 | 0 | mpSlideController->displayCurrentSlide( mxShow, xDrawPages, bSkipAllMainSequenceEffects ); |
1591 | 0 | registerShapeEvents(mpSlideController->getCurrentSlideNumber()); |
1592 | 0 | update(); |
1593 | |
|
1594 | 0 | } |
1595 | | // send out page change event and notify to update all acc info for current page |
1596 | 0 | if (mpViewShell) |
1597 | 0 | { |
1598 | 0 | sal_Int32 currentPageIndex = getCurrentSlideIndex(); |
1599 | 0 | mpViewShell->fireSwitchCurrentPage(currentPageIndex); |
1600 | 0 | mpViewShell->NotifyAccUpdate(); |
1601 | 0 | } |
1602 | 0 | } |
1603 | | |
1604 | | void SlideshowImpl::endPresentation() |
1605 | 0 | { |
1606 | 0 | if( maPresSettings.mbMouseAsPen) |
1607 | 0 | { |
1608 | 0 | rtl::Reference< SdXImpressDocument > xDocFactory(mpDoc->getUnoModel() ); |
1609 | 0 | if( xDocFactory.is() ) |
1610 | 0 | mxShow->registerUserPaintPolygons(xDocFactory); |
1611 | 0 | } |
1612 | |
|
1613 | 0 | if( !mnEndShowEvent ) |
1614 | 0 | mnEndShowEvent = Application::PostUserEvent( LINK(this, SlideshowImpl, endPresentationHdl) ); |
1615 | 0 | } |
1616 | | |
1617 | | IMPL_LINK_NOARG(SlideshowImpl, endPresentationHdl, void*, void) |
1618 | 0 | { |
1619 | 0 | mnEndShowEvent = nullptr; |
1620 | |
|
1621 | 0 | stopSound(); |
1622 | |
|
1623 | 0 | if( mxPresentation.is() ) |
1624 | 0 | mxPresentation->end(); |
1625 | 0 | } |
1626 | | |
1627 | | void SAL_CALL SlideshowImpl::pause() |
1628 | 0 | { |
1629 | 0 | SolarMutexGuard aSolarGuard; |
1630 | |
|
1631 | 0 | if( mbIsPaused ) |
1632 | 0 | return; |
1633 | | |
1634 | 0 | try |
1635 | 0 | { |
1636 | 0 | mbIsPaused = true; |
1637 | 0 | if( mxShow.is() ) |
1638 | 0 | { |
1639 | 0 | mxShow->pause(true); |
1640 | |
|
1641 | 0 | if( mxListenerProxy.is() ) |
1642 | 0 | mxListenerProxy->paused(); |
1643 | 0 | } |
1644 | 0 | } |
1645 | 0 | catch( Exception& ) |
1646 | 0 | { |
1647 | 0 | TOOLS_WARN_EXCEPTION( "sd", "sd::SlideshowImpl::pause()" ); |
1648 | 0 | } |
1649 | 0 | } |
1650 | | |
1651 | | void SAL_CALL SlideshowImpl::resume() |
1652 | 0 | { |
1653 | 0 | SolarMutexGuard aSolarGuard; |
1654 | |
|
1655 | 0 | if( mbIsPaused ) try |
1656 | 0 | { |
1657 | 0 | if( mpShowWindow->GetShowWindowMode() == SHOWWINDOWMODE_BLANK || mpShowWindow->GetShowWindowMode() == SHOWWINDOWMODE_END ) |
1658 | 0 | { |
1659 | 0 | mpShowWindow->RestartShow(); |
1660 | 0 | } |
1661 | 0 | else |
1662 | 0 | { |
1663 | 0 | mbIsPaused = false; |
1664 | 0 | if( mxShow.is() ) |
1665 | 0 | { |
1666 | 0 | mxShow->pause(false); |
1667 | 0 | update(); |
1668 | |
|
1669 | 0 | if( mxListenerProxy.is() ) |
1670 | 0 | mxListenerProxy->resumed(); |
1671 | 0 | } |
1672 | 0 | } |
1673 | 0 | } |
1674 | 0 | catch( Exception& ) |
1675 | 0 | { |
1676 | 0 | TOOLS_WARN_EXCEPTION( "sd", "sd::SlideshowImpl::resume()" ); |
1677 | 0 | } |
1678 | | #ifdef ENABLE_SDREMOTE |
1679 | | RemoteServer::presentationStarted( this ); |
1680 | | #endif |
1681 | 0 | } |
1682 | | |
1683 | | sal_Bool SAL_CALL SlideshowImpl::isPaused() |
1684 | 0 | { |
1685 | 0 | SolarMutexGuard aSolarGuard; |
1686 | 0 | return mbIsPaused; |
1687 | 0 | } |
1688 | | |
1689 | | void SAL_CALL SlideshowImpl::blankScreen( sal_Int32 nColor ) |
1690 | 0 | { |
1691 | 0 | SolarMutexGuard aSolarGuard; |
1692 | |
|
1693 | 0 | if( mpShowWindow && mpSlideController ) |
1694 | 0 | { |
1695 | 0 | if( mpShowWindow->SetBlankMode( mpSlideController->getCurrentSlideIndex(), Color(ColorTransparency, nColor) ) ) |
1696 | 0 | { |
1697 | 0 | pause(); |
1698 | 0 | } |
1699 | 0 | } |
1700 | 0 | } |
1701 | | |
1702 | | // XShapeEventListener |
1703 | | |
1704 | | void SlideshowImpl::click( const Reference< XShape >& xShape ) |
1705 | 0 | { |
1706 | 0 | SolarMutexGuard aSolarGuard; |
1707 | |
|
1708 | 0 | auto it = maShapeEventMap.find(xShape); |
1709 | 0 | if (it == maShapeEventMap.end()) |
1710 | 0 | return; |
1711 | 0 | WrappedShapeEventImpl* pEvent = &it->second; |
1712 | |
|
1713 | 0 | switch( pEvent->meClickAction ) |
1714 | 0 | { |
1715 | 0 | case ClickAction_PREVPAGE: gotoPreviousSlide(); break; |
1716 | 0 | case ClickAction_NEXTPAGE: gotoNextSlide(); break; |
1717 | 0 | case ClickAction_FIRSTPAGE: gotoFirstSlide(); break; |
1718 | 0 | case ClickAction_LASTPAGE: gotoLastSlide(); break; |
1719 | 0 | case ClickAction_STOPPRESENTATION: endPresentation(); break; |
1720 | 0 | case ClickAction_BOOKMARK: |
1721 | 0 | { |
1722 | 0 | gotoBookmark( pEvent->maStrBookmark ); |
1723 | 0 | } |
1724 | 0 | break; |
1725 | 0 | case ClickAction_SOUND: |
1726 | 0 | { |
1727 | 0 | #if HAVE_FEATURE_AVMEDIA |
1728 | 0 | try |
1729 | 0 | { |
1730 | 0 | mxPlayer.set(avmedia::MediaWindow::createPlayer(pEvent->maStrBookmark, u""_ustr/*TODO?*/), uno::UNO_SET_THROW ); |
1731 | 0 | mxPlayer->start(); |
1732 | 0 | } |
1733 | 0 | catch( uno::Exception& ) |
1734 | 0 | { |
1735 | 0 | TOOLS_WARN_EXCEPTION( "sd", "sd::SlideshowImpl::click()" ); |
1736 | 0 | } |
1737 | 0 | #endif |
1738 | 0 | } |
1739 | 0 | break; |
1740 | | |
1741 | 0 | case ClickAction_DOCUMENT: |
1742 | 0 | { |
1743 | 0 | OUString aBookmark( pEvent->maStrBookmark ); |
1744 | |
|
1745 | 0 | sal_Int32 nPos = aBookmark.indexOf( '#' ); |
1746 | 0 | if( nPos >= 0 ) |
1747 | 0 | { |
1748 | 0 | OUString aURL( aBookmark.copy( 0, nPos+1 ) ); |
1749 | 0 | OUString aName( aBookmark.copy( nPos+1 ) ); |
1750 | 0 | aURL += getUiNameFromPageApiNameImpl( aName ); |
1751 | 0 | aBookmark = aURL; |
1752 | 0 | } |
1753 | |
|
1754 | 0 | mpDocSh->OpenBookmark( aBookmark ); |
1755 | 0 | } |
1756 | 0 | break; |
1757 | | |
1758 | 0 | case ClickAction_PROGRAM: |
1759 | 0 | { |
1760 | 0 | INetURLObject aURL( |
1761 | 0 | ::URIHelper::SmartRel2Abs( |
1762 | 0 | INetURLObject(mpDocSh->GetMedium()->GetBaseURL()), |
1763 | 0 | pEvent->maStrBookmark, ::URIHelper::GetMaybeFileHdl(), true, |
1764 | 0 | false, INetURLObject::EncodeMechanism::WasEncoded, |
1765 | 0 | INetURLObject::DecodeMechanism::Unambiguous ) ); |
1766 | |
|
1767 | 0 | if( INetProtocol::File == aURL.GetProtocol() ) |
1768 | 0 | { |
1769 | 0 | SfxStringItem aUrl( SID_FILE_NAME, aURL.GetMainURL( INetURLObject::DecodeMechanism::NONE ) ); |
1770 | 0 | SfxBoolItem aBrowsing( SID_BROWSE, true ); |
1771 | |
|
1772 | 0 | if (SfxViewFrame* pViewFrm = SfxViewFrame::Current()) |
1773 | 0 | { |
1774 | 0 | SfxUnoFrameItem aDocFrame(SID_FILLFRAME, pViewFrm->GetFrame().GetFrameInterface()); |
1775 | 0 | pViewFrm->GetDispatcher()->ExecuteList( SID_OPENDOC, |
1776 | 0 | SfxCallMode::ASYNCHRON | SfxCallMode::RECORD, |
1777 | 0 | { &aUrl, &aBrowsing }, { &aDocFrame } ); |
1778 | 0 | } |
1779 | 0 | } |
1780 | 0 | } |
1781 | 0 | break; |
1782 | | |
1783 | | #if HAVE_FEATURE_SCRIPTING |
1784 | | case presentation::ClickAction_MACRO: |
1785 | | { |
1786 | | const OUString aMacro( pEvent->maStrBookmark ); |
1787 | | |
1788 | | if ( SfxApplication::IsXScriptURL( aMacro ) ) |
1789 | | { |
1790 | | Any aRet; |
1791 | | Sequence< sal_Int16 > aOutArgsIndex; |
1792 | | Sequence< Any > aOutArgs; |
1793 | | Sequence< Any >* pInArgs = new Sequence< Any >(0); |
1794 | | mpDocSh->CallXScript( aMacro, *pInArgs, aRet, aOutArgsIndex, aOutArgs); |
1795 | | } |
1796 | | else |
1797 | | { |
1798 | | // aMacro has the following syntax: |
1799 | | // "Macroname.Modulname.Libname.Documentname" or |
1800 | | // "Macroname.Modulname.Libname.Applicationname" |
1801 | | sal_Int32 nIdx{ 0 }; |
1802 | | const std::u16string_view aMacroName = o3tl::getToken(aMacro, 0, '.', nIdx); |
1803 | | const std::u16string_view aModulName = o3tl::getToken(aMacro, 0, '.', nIdx); |
1804 | | |
1805 | | // todo: is the limitation still given that only |
1806 | | // Modulname+Macroname can be used here? |
1807 | | OUString aExecMacro = OUString::Concat(aModulName) + "." + aMacroName; |
1808 | | mpDocSh->GetBasic()->Call(aExecMacro); |
1809 | | } |
1810 | | } |
1811 | | break; |
1812 | | #endif |
1813 | | |
1814 | 0 | case ClickAction_VERB: |
1815 | 0 | { |
1816 | | // todo, better do it async? |
1817 | 0 | SdrObject* pObj = SdrObject::getSdrObjectFromXShape(xShape); |
1818 | 0 | SdrOle2Obj* pOleObject = dynamic_cast< SdrOle2Obj* >(pObj); |
1819 | 0 | if (pOleObject && mpViewShell ) |
1820 | 0 | mpViewShell->ActivateObject(pOleObject, pEvent->mnVerb); |
1821 | 0 | } |
1822 | 0 | break; |
1823 | 0 | default: |
1824 | 0 | break; |
1825 | 0 | } |
1826 | 0 | } |
1827 | | |
1828 | | sal_Int32 SlideshowImpl::getSlideNumberForBookmark( const OUString& rStrBookmark ) |
1829 | 0 | { |
1830 | 0 | bool bIsMasterPage; |
1831 | 0 | OUString aBookmark = getUiNameFromPageApiNameImpl( rStrBookmark ); |
1832 | 0 | sal_uInt16 nPgNum = mpDoc->GetPageByName( aBookmark, bIsMasterPage ); |
1833 | |
|
1834 | 0 | if( nPgNum == SDRPAGE_NOTFOUND ) |
1835 | 0 | { |
1836 | | // Is the bookmark an object? |
1837 | 0 | SdrObject* pObj = mpDoc->GetObj( aBookmark ); |
1838 | |
|
1839 | 0 | if( pObj ) |
1840 | 0 | { |
1841 | 0 | nPgNum = pObj->getSdrPageFromSdrObject()->GetPageNum(); |
1842 | 0 | bIsMasterPage = pObj->getSdrPageFromSdrObject()->IsMasterPage(); |
1843 | 0 | } |
1844 | 0 | } |
1845 | |
|
1846 | 0 | if( (nPgNum == SDRPAGE_NOTFOUND) || bIsMasterPage || static_cast<SdPage*>(mpDoc->GetPage(nPgNum))->GetPageKind() != PageKind::Standard ) |
1847 | 0 | return -1; |
1848 | | |
1849 | 0 | return ( nPgNum - 1) >> 1; |
1850 | 0 | } |
1851 | | |
1852 | | void SlideshowImpl::contextMenuShow(const css::awt::Point& point) |
1853 | 0 | { |
1854 | 0 | maPopupMousePos = { point.X, point.Y }; |
1855 | 0 | mnContextMenuEvent = Application::PostUserEvent(LINK(this, SlideshowImpl, ContextMenuHdl)); |
1856 | 0 | } |
1857 | | |
1858 | | void SlideshowImpl::hyperLinkClicked( OUString const& aHyperLink ) |
1859 | 0 | { |
1860 | 0 | OUString aBookmark( aHyperLink ); |
1861 | |
|
1862 | 0 | sal_Int32 nPos = aBookmark.indexOf( '#' ); |
1863 | 0 | if( nPos >= 0 ) |
1864 | 0 | { |
1865 | 0 | OUString aURL( aBookmark.copy( 0, nPos+1 ) ); |
1866 | 0 | OUString aName( aBookmark.copy( nPos+1 ) ); |
1867 | 0 | aURL += getUiNameFromPageApiNameImpl( aName ); |
1868 | 0 | aBookmark = aURL; |
1869 | 0 | } |
1870 | |
|
1871 | 0 | mpDocSh->OpenBookmark( aBookmark ); |
1872 | 0 | } |
1873 | | |
1874 | | void SlideshowImpl::displaySlideNumber( sal_Int32 nSlideNumber ) |
1875 | 0 | { |
1876 | 0 | if( mpSlideController ) |
1877 | 0 | { |
1878 | 0 | if( mpSlideController->jumpToSlideNumber( nSlideNumber ) ) |
1879 | 0 | { |
1880 | 0 | displayCurrentSlide(); |
1881 | 0 | } |
1882 | 0 | } |
1883 | 0 | } |
1884 | | |
1885 | | /** nSlideIndex == -1 displays current slide again */ |
1886 | | void SlideshowImpl::displaySlideIndex( sal_Int32 nSlideIndex ) |
1887 | 0 | { |
1888 | 0 | if( mpSlideController ) |
1889 | 0 | { |
1890 | 0 | if( (nSlideIndex == -1) || mpSlideController->jumpToSlideIndex( nSlideIndex ) ) |
1891 | 0 | { |
1892 | 0 | displayCurrentSlide(); |
1893 | 0 | } |
1894 | 0 | } |
1895 | 0 | } |
1896 | | |
1897 | | void SlideshowImpl::jumpToBookmark( const OUString& sBookmark ) |
1898 | 0 | { |
1899 | 0 | sal_Int32 nSlideNumber = getSlideNumberForBookmark( sBookmark ); |
1900 | 0 | if( nSlideNumber != -1 ) |
1901 | 0 | displaySlideNumber( nSlideNumber ); |
1902 | 0 | } |
1903 | | |
1904 | | sal_Int32 SlideshowImpl::getCurrentSlideNumber() const |
1905 | 0 | { |
1906 | 0 | return mpSlideController ? mpSlideController->getCurrentSlideNumber() : -1; |
1907 | 0 | } |
1908 | | |
1909 | | sal_Bool SAL_CALL SlideshowImpl::isEndless() |
1910 | 0 | { |
1911 | 0 | SolarMutexGuard aSolarGuard; |
1912 | 0 | return maPresSettings.mbEndless; |
1913 | 0 | } |
1914 | | |
1915 | | void SlideshowImpl::update() |
1916 | 0 | { |
1917 | 0 | startUpdateTimer(); |
1918 | 0 | } |
1919 | | |
1920 | | void SlideshowImpl::startUpdateTimer() |
1921 | 0 | { |
1922 | 0 | SolarMutexGuard aSolarGuard; |
1923 | 0 | maUpdateTimer.SetTimeout( 0 ); |
1924 | 0 | maUpdateTimer.Start(); |
1925 | 0 | } |
1926 | | |
1927 | | /** this timer is called 20ms after a new slide was displayed. |
1928 | | This is used to unfreeze user input that was disabled after |
1929 | | slide change to skip input that was buffered during slide |
1930 | | transition preparation */ |
1931 | | IMPL_LINK_NOARG(SlideshowImpl, ReadyForNextInputHdl, Timer *, void) |
1932 | 0 | { |
1933 | 0 | mbInputFreeze = false; |
1934 | 0 | } |
1935 | | |
1936 | | /** if I catch someone someday who calls this method by hand |
1937 | | and not by using the timer, I will personally punish this |
1938 | | person seriously, even if this person is me. |
1939 | | */ |
1940 | | IMPL_LINK_NOARG(SlideshowImpl, updateHdl, Timer *, void) |
1941 | 0 | { |
1942 | 0 | updateSlideShow(); |
1943 | 0 | } |
1944 | | |
1945 | | void SlideshowImpl::updateSlideShow() |
1946 | 0 | { |
1947 | | // prevent me from deletion when recursing (App::EnableYieldMode does) |
1948 | 0 | const rtl::Reference<SlideshowImpl> xKeepAlive(this); |
1949 | |
|
1950 | 0 | Reference< XSlideShow > xShow( mxShow ); |
1951 | 0 | if ( ! xShow.is()) |
1952 | 0 | return; |
1953 | | |
1954 | 0 | try |
1955 | 0 | { |
1956 | 0 | double fUpdate = 0.0; |
1957 | 0 | if( !xShow->update(fUpdate) ) |
1958 | 0 | fUpdate = -1.0; |
1959 | |
|
1960 | 0 | if (mxShow.is() && (fUpdate >= 0.0)) |
1961 | 0 | { |
1962 | 0 | if (::basegfx::fTools::equalZero(fUpdate)) |
1963 | 0 | { |
1964 | | // Make sure idle tasks don't starve when we don't have to wait. |
1965 | | // Don't process any events generated after invoking the function. |
1966 | 0 | Application::Reschedule(/*bHandleAllCurrentEvents=*/true); |
1967 | 0 | } |
1968 | 0 | else |
1969 | 0 | { |
1970 | | // Avoid busy loop when the previous call to update() |
1971 | | // returns a small positive number but not 0 (which is |
1972 | | // handled above). Also, make sure that calls to update() |
1973 | | // have a minimum frequency. |
1974 | | // => Allow up to 60 frames per second. Call at least once |
1975 | | // every 4 seconds. |
1976 | 0 | const static sal_Int32 nMaximumFrameCount (60); |
1977 | 0 | const static double nMinimumTimeout (1.0 / nMaximumFrameCount); |
1978 | 0 | const static double nMaximumTimeout (4.0); |
1979 | 0 | fUpdate = std::clamp(fUpdate, nMinimumTimeout, nMaximumTimeout); |
1980 | | |
1981 | | // Make sure that the maximum frame count has not been set |
1982 | | // too high (only then conversion to milliseconds and long |
1983 | | // integer may lead to zero value.) |
1984 | 0 | OSL_ASSERT(static_cast<sal_uLong>(fUpdate * 1000.0) > 0); |
1985 | 0 | } |
1986 | | |
1987 | | // Use our high resolution timers for the asynchronous callback. |
1988 | 0 | maUpdateTimer.SetTimeout(static_cast<sal_uLong>(fUpdate * 1000.0)); |
1989 | 0 | maUpdateTimer.Start(); |
1990 | 0 | } |
1991 | 0 | } |
1992 | 0 | catch( Exception& ) |
1993 | 0 | { |
1994 | 0 | TOOLS_WARN_EXCEPTION( "sd", "sd::SlideshowImpl::updateSlideShow()" ); |
1995 | 0 | } |
1996 | 0 | } |
1997 | | |
1998 | | bool SlideshowImpl::keyInput(const KeyEvent& rKEvt) |
1999 | 0 | { |
2000 | 0 | if( !mxShow.is() || mbInputFreeze ) |
2001 | 0 | return false; |
2002 | | |
2003 | 0 | bool bRet = true; |
2004 | |
|
2005 | 0 | try |
2006 | 0 | { |
2007 | 0 | const int nKeyCode = rKEvt.GetKeyCode().GetCode(); |
2008 | 0 | switch( nKeyCode ) |
2009 | 0 | { |
2010 | 0 | case awt::Key::CONTEXTMENU: |
2011 | 0 | if( !mnContextMenuEvent ) |
2012 | 0 | { |
2013 | 0 | if( mpShowWindow ) |
2014 | 0 | maPopupMousePos = mpShowWindow->GetPointerState().maPos; |
2015 | 0 | mnContextMenuEvent = Application::PostUserEvent( LINK( this, SlideshowImpl, ContextMenuHdl ) ); |
2016 | 0 | } |
2017 | 0 | break; |
2018 | | |
2019 | | // cancel show |
2020 | 0 | case KEY_ESCAPE: |
2021 | 0 | case KEY_SUBTRACT: |
2022 | | // in case the user cancels the presentation, switch to current slide |
2023 | | // in edit mode |
2024 | 0 | if( mpSlideController && (ANIMATIONMODE_SHOW == meAnimationMode) ) |
2025 | 0 | { |
2026 | 0 | if( mpSlideController->getCurrentSlideNumber() != -1 ) |
2027 | 0 | mnRestoreSlide = mpSlideController->getCurrentSlideNumber(); |
2028 | 0 | } |
2029 | 0 | endPresentation(); |
2030 | 0 | break; |
2031 | | |
2032 | | // advance show |
2033 | 0 | case KEY_PAGEDOWN: |
2034 | 0 | if(rKEvt.GetKeyCode().IsMod2()) |
2035 | 0 | { |
2036 | 0 | gotoNextSlide(); |
2037 | 0 | break; |
2038 | 0 | } |
2039 | 0 | [[fallthrough]]; |
2040 | 0 | case KEY_SPACE: |
2041 | 0 | case KEY_RIGHT: |
2042 | 0 | case KEY_DOWN: |
2043 | 0 | case KEY_XF86FORWARD: |
2044 | 0 | gotoNextEffect(); |
2045 | 0 | break; |
2046 | | |
2047 | 0 | case KEY_RETURN: |
2048 | 0 | { |
2049 | 0 | if( !maCharBuffer.isEmpty() ) |
2050 | 0 | { |
2051 | 0 | if( mpSlideController ) |
2052 | 0 | { |
2053 | 0 | if( mpSlideController->jumpToSlideNumber( maCharBuffer.toInt32() - 1 ) ) |
2054 | 0 | displayCurrentSlide(); |
2055 | 0 | } |
2056 | 0 | maCharBuffer.clear(); |
2057 | 0 | } |
2058 | 0 | else |
2059 | 0 | { |
2060 | 0 | gotoNextEffect(); |
2061 | 0 | } |
2062 | 0 | } |
2063 | 0 | break; |
2064 | | |
2065 | | // numeric: add to buffer |
2066 | 0 | case KEY_0: |
2067 | 0 | case KEY_1: |
2068 | 0 | case KEY_2: |
2069 | 0 | case KEY_3: |
2070 | 0 | case KEY_4: |
2071 | 0 | case KEY_5: |
2072 | 0 | case KEY_6: |
2073 | 0 | case KEY_7: |
2074 | 0 | case KEY_8: |
2075 | 0 | case KEY_9: |
2076 | 0 | maCharBuffer += OUStringChar( rKEvt.GetCharCode() ); |
2077 | 0 | break; |
2078 | | |
2079 | 0 | case KEY_PAGEUP: |
2080 | 0 | if(rKEvt.GetKeyCode().IsMod2()) |
2081 | 0 | { |
2082 | 0 | gotoPreviousSlide(); |
2083 | 0 | break; |
2084 | 0 | } |
2085 | 0 | [[fallthrough]]; |
2086 | 0 | case KEY_LEFT: |
2087 | 0 | case KEY_UP: |
2088 | 0 | case KEY_BACKSPACE: |
2089 | 0 | case KEY_XF86BACK: |
2090 | 0 | gotoPreviousEffect(); |
2091 | 0 | break; |
2092 | | |
2093 | 0 | case KEY_P: |
2094 | 0 | setUsePen( !mbUsePen ); |
2095 | 0 | break; |
2096 | | |
2097 | | // tdf#149351 Ctrl+A disables pointer as pen mode |
2098 | 0 | case KEY_A: |
2099 | 0 | if(rKEvt.GetKeyCode().IsMod1()) |
2100 | 0 | { |
2101 | 0 | setUsePen( false ); |
2102 | 0 | break; |
2103 | 0 | } |
2104 | 0 | break; |
2105 | | |
2106 | 0 | case KEY_E: |
2107 | 0 | setEraseAllInk( true ); |
2108 | 0 | updateSlideShow(); |
2109 | 0 | break; |
2110 | | |
2111 | 0 | case KEY_HOME: |
2112 | 0 | gotoFirstSlide(); |
2113 | 0 | break; |
2114 | | |
2115 | 0 | case KEY_END: |
2116 | 0 | gotoLastSlide(); |
2117 | 0 | break; |
2118 | | |
2119 | 0 | case KEY_B: |
2120 | 0 | case KEY_W: |
2121 | 0 | case KEY_POINT: |
2122 | 0 | case KEY_COMMA: |
2123 | 0 | { |
2124 | 0 | blankScreen( ((nKeyCode == KEY_W ) || (nKeyCode == KEY_COMMA)) ? 0x00ffffff : 0x00000000 ); |
2125 | 0 | } |
2126 | 0 | break; |
2127 | | |
2128 | 0 | default: |
2129 | 0 | bRet = false; |
2130 | 0 | break; |
2131 | 0 | } |
2132 | 0 | } |
2133 | 0 | catch( Exception& ) |
2134 | 0 | { |
2135 | 0 | bRet = false; |
2136 | 0 | TOOLS_WARN_EXCEPTION( "sd", "sd::SlideshowImpl::keyInput()" ); |
2137 | 0 | } |
2138 | | |
2139 | 0 | return bRet; |
2140 | 0 | } |
2141 | | |
2142 | | IMPL_LINK( SlideshowImpl, EventListenerHdl, VclSimpleEvent&, rSimpleEvent, void ) |
2143 | 0 | { |
2144 | 0 | if( !mxShow.is() || mbInputFreeze ) |
2145 | 0 | return; |
2146 | | |
2147 | 0 | if( !((rSimpleEvent.GetId() == VclEventId::WindowCommand) && static_cast<VclWindowEvent*>(&rSimpleEvent)->GetData()) ) |
2148 | 0 | return; |
2149 | | |
2150 | 0 | const CommandEvent& rEvent = *static_cast<const CommandEvent*>(static_cast<VclWindowEvent*>(&rSimpleEvent)->GetData()); |
2151 | |
|
2152 | 0 | if( rEvent.GetCommand() != CommandEventId::Media ) |
2153 | 0 | return; |
2154 | | |
2155 | 0 | CommandMediaData* pMediaData = rEvent.GetMediaData(); |
2156 | 0 | pMediaData->SetPassThroughToOS(false); |
2157 | 0 | switch (pMediaData->GetMediaId()) |
2158 | 0 | { |
2159 | | #if defined( MACOSX ) |
2160 | | case MediaCommand::Menu: |
2161 | | if( !mnContextMenuEvent ) |
2162 | | { |
2163 | | if( mpShowWindow ) |
2164 | | maPopupMousePos = mpShowWindow->GetPointerState().maPos; |
2165 | | mnContextMenuEvent = Application::PostUserEvent( LINK( this, SlideshowImpl, ContextMenuHdl ) ); |
2166 | | } |
2167 | | break; |
2168 | | case MediaCommand::VolumeDown: |
2169 | | gotoPreviousSlide(); |
2170 | | break; |
2171 | | case MediaCommand::VolumeUp: |
2172 | | gotoNextEffect(); |
2173 | | break; |
2174 | | #endif |
2175 | 0 | case MediaCommand::NextTrack: |
2176 | 0 | gotoNextEffect(); |
2177 | 0 | break; |
2178 | 0 | case MediaCommand::Pause: |
2179 | 0 | if( !mbIsPaused ) |
2180 | 0 | blankScreen(0); |
2181 | 0 | break; |
2182 | 0 | case MediaCommand::Play: |
2183 | 0 | if( mbIsPaused ) |
2184 | 0 | resume(); |
2185 | 0 | break; |
2186 | | |
2187 | 0 | case MediaCommand::PlayPause: |
2188 | 0 | if( mbIsPaused ) |
2189 | 0 | resume(); |
2190 | 0 | else |
2191 | 0 | blankScreen(0); |
2192 | 0 | break; |
2193 | 0 | case MediaCommand::PreviousTrack: |
2194 | 0 | gotoPreviousSlide(); |
2195 | 0 | break; |
2196 | 0 | case MediaCommand::NextTrackHold: |
2197 | 0 | gotoLastSlide(); |
2198 | 0 | break; |
2199 | | |
2200 | 0 | case MediaCommand::Rewind: |
2201 | 0 | gotoFirstSlide(); |
2202 | 0 | break; |
2203 | 0 | case MediaCommand::Stop: |
2204 | | // in case the user cancels the presentation, switch to current slide |
2205 | | // in edit mode |
2206 | 0 | if( mpSlideController && (ANIMATIONMODE_SHOW == meAnimationMode) ) |
2207 | 0 | { |
2208 | 0 | if( mpSlideController->getCurrentSlideNumber() != -1 ) |
2209 | 0 | mnRestoreSlide = mpSlideController->getCurrentSlideNumber(); |
2210 | 0 | } |
2211 | 0 | endPresentation(); |
2212 | 0 | break; |
2213 | 0 | default: |
2214 | 0 | pMediaData->SetPassThroughToOS(true); |
2215 | 0 | break; |
2216 | 0 | } |
2217 | 0 | } |
2218 | | |
2219 | | void SlideshowImpl::mouseButtonUp(const MouseEvent& rMEvt) |
2220 | 0 | { |
2221 | 0 | if( rMEvt.IsRight() && !mnContextMenuEvent ) |
2222 | 0 | { |
2223 | 0 | maPopupMousePos = rMEvt.GetPosPixel(); |
2224 | 0 | mnContextMenuEvent = Application::PostUserEvent( LINK( this, SlideshowImpl, ContextMenuHdl ) ); |
2225 | 0 | } |
2226 | 0 | } |
2227 | | |
2228 | | IMPL_LINK_NOARG(SlideshowImpl, ContextMenuHdl, void*, void) |
2229 | 0 | { |
2230 | 0 | mnContextMenuEvent = nullptr; |
2231 | |
|
2232 | 0 | if (mpSlideController == nullptr) |
2233 | 0 | return; |
2234 | | |
2235 | 0 | mbWasPaused = mbIsPaused; |
2236 | 0 | if( !mbWasPaused ) |
2237 | 0 | pause(); |
2238 | |
|
2239 | 0 | std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(nullptr, u"modules/simpress/ui/slidecontextmenu.ui"_ustr)); |
2240 | 0 | std::unique_ptr<weld::Menu> xMenu(xBuilder->weld_menu(u"menu"_ustr)); |
2241 | 0 | OUString sNextImage(BMP_MENU_NEXT), sPrevImage(BMP_MENU_PREV); |
2242 | 0 | xMenu->insert(0, u"next"_ustr, SdResId(RID_SVXSTR_MENU_NEXT), &sNextImage, nullptr, nullptr, TRISTATE_INDET); |
2243 | 0 | xMenu->insert(1, u"prev"_ustr, SdResId(RID_SVXSTR_MENU_PREV), &sPrevImage, nullptr, nullptr, TRISTATE_INDET); |
2244 | | |
2245 | | // Adding button to display if in Pen mode |
2246 | 0 | xMenu->set_active(u"pen"_ustr, mbUsePen); |
2247 | |
|
2248 | 0 | const ShowWindowMode eMode = mpShowWindow->GetShowWindowMode(); |
2249 | 0 | xMenu->set_visible(u"next"_ustr, mpSlideController->getNextSlideIndex() != -1); |
2250 | 0 | xMenu->set_visible(u"prev"_ustr, (mpSlideController->getPreviousSlideIndex() != -1 ) || (eMode == SHOWWINDOWMODE_END) || (eMode == SHOWWINDOWMODE_PAUSE) || (eMode == SHOWWINDOWMODE_BLANK)); |
2251 | 0 | xMenu->set_visible(u"edit"_ustr, mpViewShell->GetDoc()->GetStartWithPresentation() != 0); |
2252 | |
|
2253 | 0 | std::unique_ptr<weld::Menu> xPageMenu(xBuilder->weld_menu(u"gotomenu"_ustr)); |
2254 | 0 | OUString sFirstImage(BMP_MENU_FIRST), sLastImage(BMP_MENU_LAST); |
2255 | 0 | xPageMenu->insert(0, u"first"_ustr, SdResId(RID_SVXSTR_MENU_FIRST), &sFirstImage, nullptr, nullptr, TRISTATE_INDET); |
2256 | 0 | xPageMenu->insert(1, u"last"_ustr, SdResId(RID_SVXSTR_MENU_LAST), &sLastImage, nullptr, nullptr, TRISTATE_INDET); |
2257 | | |
2258 | | // populate slide goto list |
2259 | 0 | const sal_Int32 nPageNumberCount = mpSlideController->getSlideNumberCount(); |
2260 | 0 | if( nPageNumberCount <= 1 ) |
2261 | 0 | { |
2262 | 0 | xMenu->set_visible(u"goto"_ustr, false); |
2263 | 0 | } |
2264 | 0 | else |
2265 | 0 | { |
2266 | 0 | sal_Int32 nCurrentSlideNumber = mpSlideController->getCurrentSlideNumber(); |
2267 | 0 | if( (eMode == SHOWWINDOWMODE_END) || (eMode == SHOWWINDOWMODE_PAUSE) || (eMode == SHOWWINDOWMODE_BLANK) ) |
2268 | 0 | nCurrentSlideNumber = -1; |
2269 | |
|
2270 | 0 | xPageMenu->set_visible(u"first"_ustr, mpSlideController->getSlideNumber(0) != nCurrentSlideNumber); |
2271 | 0 | xPageMenu->set_visible(u"last"_ustr, mpSlideController->getSlideNumber(mpSlideController->getSlideIndexCount() - 1) != nCurrentSlideNumber); |
2272 | |
|
2273 | 0 | sal_Int32 nPageNumber; |
2274 | |
|
2275 | 0 | for( nPageNumber = 0; nPageNumber < nPageNumberCount; nPageNumber++ ) |
2276 | 0 | { |
2277 | 0 | if( mpSlideController->isVisibleSlideNumber( nPageNumber ) ) |
2278 | 0 | { |
2279 | 0 | SdPage* pPage = mpDoc->GetSdPage(static_cast<sal_uInt16>(nPageNumber), PageKind::Standard); |
2280 | 0 | if (pPage) |
2281 | 0 | { |
2282 | 0 | OUString sId(OUString::number(CM_SLIDES + nPageNumber)); |
2283 | 0 | xPageMenu->append_check(sId, pPage->GetName()); |
2284 | 0 | if (nPageNumber == nCurrentSlideNumber) |
2285 | 0 | xPageMenu->set_active(sId, true); |
2286 | 0 | } |
2287 | 0 | } |
2288 | 0 | } |
2289 | 0 | } |
2290 | |
|
2291 | 0 | std::unique_ptr<weld::Menu> xBlankMenu(xBuilder->weld_menu(u"screenmenu"_ustr)); |
2292 | |
|
2293 | 0 | if (mpShowWindow->GetShowWindowMode() == SHOWWINDOWMODE_BLANK) |
2294 | 0 | { |
2295 | 0 | xBlankMenu->set_active((mpShowWindow->GetBlankColor() == COL_WHITE) ? "white" : "black", true); |
2296 | 0 | } |
2297 | |
|
2298 | 0 | std::unique_ptr<weld::Menu> xWidthMenu(xBuilder->weld_menu(u"widthmenu"_ustr)); |
2299 | | |
2300 | | // populate color width list |
2301 | 0 | sal_Int32 nIterator; |
2302 | 0 | double nWidth; |
2303 | |
|
2304 | 0 | nWidth = 4.0; |
2305 | 0 | for( nIterator = 1; nIterator < 6; nIterator++) |
2306 | 0 | { |
2307 | 0 | switch(nIterator) |
2308 | 0 | { |
2309 | 0 | case 1: |
2310 | 0 | nWidth = 4.0; |
2311 | 0 | break; |
2312 | 0 | case 2: |
2313 | 0 | nWidth = 100.0; |
2314 | 0 | break; |
2315 | 0 | case 3: |
2316 | 0 | nWidth = 150.0; |
2317 | 0 | break; |
2318 | 0 | case 4: |
2319 | 0 | nWidth = 200.0; |
2320 | 0 | break; |
2321 | 0 | case 5: |
2322 | 0 | nWidth = 400.0; |
2323 | 0 | break; |
2324 | 0 | default: |
2325 | 0 | break; |
2326 | 0 | } |
2327 | | |
2328 | 0 | if (nWidth == mdUserPaintStrokeWidth) |
2329 | 0 | xWidthMenu->set_active(OUString::number(nWidth), true); |
2330 | 0 | } |
2331 | | |
2332 | 0 | ::tools::Rectangle aRect(maPopupMousePos, Size(1,1)); |
2333 | 0 | weld::Window* pParent = weld::GetPopupParent(*mpShowWindow, aRect); |
2334 | 0 | ContextMenuSelectHdl(xMenu->popup_at_rect(pParent, aRect)); |
2335 | |
|
2336 | 0 | if( mxView.is() ) |
2337 | 0 | mxView->ignoreNextMouseReleased(); |
2338 | |
|
2339 | 0 | if( !mbWasPaused ) |
2340 | 0 | resume(); |
2341 | 0 | } |
2342 | | |
2343 | | void SlideshowImpl::ContextMenuSelectHdl(std::u16string_view rMenuId) |
2344 | 0 | { |
2345 | 0 | if (rMenuId == u"prev") |
2346 | 0 | { |
2347 | 0 | gotoPreviousSlide(); |
2348 | 0 | mbWasPaused = false; |
2349 | 0 | } |
2350 | 0 | else if(rMenuId == u"next") |
2351 | 0 | { |
2352 | 0 | gotoNextSlide(); |
2353 | 0 | mbWasPaused = false; |
2354 | 0 | } |
2355 | 0 | else if (rMenuId == u"first") |
2356 | 0 | { |
2357 | 0 | gotoFirstSlide(); |
2358 | 0 | mbWasPaused = false; |
2359 | 0 | } |
2360 | 0 | else if (rMenuId == u"last") |
2361 | 0 | { |
2362 | 0 | gotoLastSlide(); |
2363 | 0 | mbWasPaused = false; |
2364 | 0 | } |
2365 | 0 | else if (rMenuId == u"black" || rMenuId == u"white") |
2366 | 0 | { |
2367 | 0 | const Color aBlankColor(rMenuId == u"white" ? COL_WHITE : COL_BLACK); |
2368 | 0 | if( mbWasPaused ) |
2369 | 0 | { |
2370 | 0 | if( mpShowWindow->GetShowWindowMode() == SHOWWINDOWMODE_BLANK ) |
2371 | 0 | { |
2372 | 0 | if( mpShowWindow->GetBlankColor() == aBlankColor ) |
2373 | 0 | { |
2374 | 0 | mbWasPaused = false; |
2375 | 0 | mpShowWindow->RestartShow(); |
2376 | 0 | return; |
2377 | 0 | } |
2378 | 0 | } |
2379 | 0 | mpShowWindow->RestartShow(); |
2380 | 0 | } |
2381 | 0 | if( mpShowWindow->SetBlankMode( mpSlideController->getCurrentSlideIndex(), aBlankColor ) ) |
2382 | 0 | { |
2383 | 0 | pause(); |
2384 | 0 | mbWasPaused = true; |
2385 | 0 | } |
2386 | 0 | } |
2387 | 0 | else if (rMenuId == u"color") |
2388 | 0 | { |
2389 | | //Open a color picker based on SvColorDialog |
2390 | 0 | ::Color aColor( ColorTransparency, mnUserPaintColor ); |
2391 | 0 | ColorDialog aColorDlg(mpShowWindow->GetFrameWeld()); |
2392 | 0 | aColorDlg.SetColor( aColor ); |
2393 | |
|
2394 | 0 | if (aColorDlg.Execute()) |
2395 | 0 | { |
2396 | 0 | aColor = aColorDlg.GetColor(); |
2397 | 0 | setPenColor(sal_Int32(aColor)); |
2398 | 0 | } |
2399 | 0 | mbWasPaused = false; |
2400 | 0 | } |
2401 | 0 | else if (rMenuId == u"4") |
2402 | 0 | { |
2403 | 0 | setPenWidth(4.0); |
2404 | 0 | mbWasPaused = false; |
2405 | 0 | } |
2406 | 0 | else if (rMenuId == u"100") |
2407 | 0 | { |
2408 | 0 | setPenWidth(100.0); |
2409 | 0 | mbWasPaused = false; |
2410 | 0 | } |
2411 | 0 | else if (rMenuId == u"150") |
2412 | 0 | { |
2413 | 0 | setPenWidth(150.0); |
2414 | 0 | mbWasPaused = false; |
2415 | 0 | } |
2416 | 0 | else if (rMenuId == u"200") |
2417 | 0 | { |
2418 | 0 | setPenWidth(200.0); |
2419 | 0 | mbWasPaused = false; |
2420 | 0 | } |
2421 | 0 | else if (rMenuId == u"400") |
2422 | 0 | { |
2423 | 0 | setPenWidth(400.0); |
2424 | 0 | mbWasPaused = false; |
2425 | 0 | } |
2426 | 0 | else if (rMenuId == u"erase") |
2427 | 0 | { |
2428 | 0 | setEraseAllInk(true); |
2429 | 0 | mbWasPaused = false; |
2430 | 0 | } |
2431 | 0 | else if (rMenuId == u"pen") |
2432 | 0 | { |
2433 | 0 | setUsePen(!mbUsePen); |
2434 | 0 | mbWasPaused = false; |
2435 | 0 | } |
2436 | 0 | else if (rMenuId == u"edit") |
2437 | 0 | { |
2438 | | // When in autoplay mode (pps/ppsx), offer editing of the presentation |
2439 | | // Turn autostart off, else Impress will close when exiting the Presentation |
2440 | 0 | mpViewShell->GetDoc()->SetExitAfterPresenting(false); |
2441 | 0 | if( mpSlideController && (ANIMATIONMODE_SHOW == meAnimationMode) ) |
2442 | 0 | { |
2443 | 0 | if( mpSlideController->getCurrentSlideNumber() != -1 ) |
2444 | 0 | { |
2445 | 0 | mnRestoreSlide = mpSlideController->getCurrentSlideNumber(); |
2446 | 0 | } |
2447 | 0 | } |
2448 | 0 | endPresentation(); |
2449 | 0 | } |
2450 | 0 | else if (rMenuId == u"end") |
2451 | 0 | { |
2452 | | // in case the user cancels the presentation, switch to current slide |
2453 | | // in edit mode |
2454 | 0 | if( mpSlideController && (ANIMATIONMODE_SHOW == meAnimationMode) ) |
2455 | 0 | { |
2456 | 0 | if( mpSlideController->getCurrentSlideNumber() != -1 ) |
2457 | 0 | { |
2458 | 0 | mnRestoreSlide = mpSlideController->getCurrentSlideNumber(); |
2459 | 0 | } |
2460 | 0 | } |
2461 | 0 | endPresentation(); |
2462 | 0 | } |
2463 | 0 | else if (!rMenuId.empty()) |
2464 | 0 | { |
2465 | 0 | sal_Int32 nPageNumber = o3tl::toInt32(rMenuId) - CM_SLIDES; |
2466 | 0 | const ShowWindowMode eMode = mpShowWindow->GetShowWindowMode(); |
2467 | 0 | if( (eMode == SHOWWINDOWMODE_END) || (eMode == SHOWWINDOWMODE_PAUSE) || (eMode == SHOWWINDOWMODE_BLANK) ) |
2468 | 0 | { |
2469 | 0 | mpShowWindow->RestartShow( nPageNumber ); |
2470 | 0 | } |
2471 | 0 | else if( nPageNumber != mpSlideController->getCurrentSlideNumber() ) |
2472 | 0 | { |
2473 | 0 | displaySlideNumber( nPageNumber ); |
2474 | 0 | } |
2475 | 0 | mbWasPaused = false; |
2476 | 0 | } |
2477 | 0 | } |
2478 | | |
2479 | | Reference< XSlideShow > SlideshowImpl::createSlideShow() |
2480 | 0 | { |
2481 | 0 | Reference< XSlideShow > xShow; |
2482 | |
|
2483 | 0 | try |
2484 | 0 | { |
2485 | 0 | const Reference< uno::XComponentContext >& xContext = |
2486 | 0 | ::comphelper::getProcessComponentContext(); |
2487 | |
|
2488 | 0 | xShow.set( presentation::SlideShow::create(xContext), UNO_SET_THROW ); |
2489 | 0 | } |
2490 | 0 | catch( uno::Exception& ) |
2491 | 0 | { |
2492 | 0 | TOOLS_WARN_EXCEPTION( "sd", "sd::SlideshowImpl::createSlideShow()" ); |
2493 | 0 | } |
2494 | | |
2495 | 0 | return xShow; |
2496 | 0 | } |
2497 | | |
2498 | | void SlideshowImpl::createSlideList( bool bAll, std::u16string_view rPresSlide ) |
2499 | 0 | { |
2500 | 0 | const sal_uInt16 nSlideCount = mpDoc->GetSdPageCount( PageKind::Standard ); |
2501 | |
|
2502 | 0 | if( !nSlideCount ) |
2503 | 0 | return; |
2504 | | |
2505 | 0 | SdCustomShow* pCustomShow; |
2506 | |
|
2507 | 0 | if( mpDoc->GetCustomShowList() && maPresSettings.mbCustomShow ) |
2508 | 0 | pCustomShow = mpDoc->GetCustomShowList()->GetCurObject(); |
2509 | 0 | else |
2510 | 0 | pCustomShow = nullptr; |
2511 | | |
2512 | | // create animation slide controller |
2513 | 0 | AnimationSlideController::Mode eMode = |
2514 | 0 | ( pCustomShow && !pCustomShow->PagesVector().empty() ) ? AnimationSlideController::CUSTOM : |
2515 | 0 | (bAll ? AnimationSlideController::ALL : AnimationSlideController::FROM); |
2516 | |
|
2517 | 0 | rtl::Reference< SdXImpressDocument > xDrawPages( mpDoc->getUnoModel() ); |
2518 | 0 | Reference< XIndexAccess > xSlides( xDrawPages->getDrawPages(), UNO_QUERY_THROW ); |
2519 | 0 | mpSlideController = std::make_unique<AnimationSlideController>( xSlides, eMode ); |
2520 | |
|
2521 | 0 | if( eMode != AnimationSlideController::CUSTOM ) |
2522 | 0 | { |
2523 | 0 | sal_Int32 nFirstVisibleSlide = 0; |
2524 | | |
2525 | | // normal presentation |
2526 | 0 | if( !rPresSlide.empty() ) |
2527 | 0 | { |
2528 | 0 | sal_Int32 nSlide; |
2529 | 0 | bool bTakeNextAvailable = false; |
2530 | |
|
2531 | 0 | for( nSlide = 0, nFirstVisibleSlide = -1; |
2532 | 0 | ( nSlide < nSlideCount ) && ( -1 == nFirstVisibleSlide ); nSlide++ ) |
2533 | 0 | { |
2534 | 0 | SdPage* pTestSlide = mpDoc->GetSdPage( static_cast<sal_uInt16>(nSlide), PageKind::Standard ); |
2535 | |
|
2536 | 0 | if( pTestSlide->GetName() == rPresSlide ) |
2537 | 0 | { |
2538 | 0 | if( pTestSlide->IsExcluded() ) |
2539 | 0 | bTakeNextAvailable = true; |
2540 | 0 | else |
2541 | 0 | nFirstVisibleSlide = nSlide; |
2542 | 0 | } |
2543 | 0 | else if( bTakeNextAvailable && !pTestSlide->IsExcluded() ) |
2544 | 0 | nFirstVisibleSlide = nSlide; |
2545 | 0 | } |
2546 | |
|
2547 | 0 | if( -1 == nFirstVisibleSlide ) |
2548 | 0 | nFirstVisibleSlide = 0; |
2549 | 0 | } |
2550 | |
|
2551 | 0 | for( sal_Int32 i = 0; i < nSlideCount; i++ ) |
2552 | 0 | { |
2553 | 0 | bool bVisible = ! mpDoc->GetSdPage( static_cast<sal_uInt16>(i), PageKind::Standard )->IsExcluded(); |
2554 | 0 | if( bVisible || (eMode == AnimationSlideController::ALL) ) |
2555 | 0 | mpSlideController->insertSlideNumber( i, bVisible ); |
2556 | 0 | } |
2557 | |
|
2558 | 0 | mpSlideController->setStartSlideNumber( nFirstVisibleSlide ); |
2559 | 0 | } |
2560 | 0 | else |
2561 | 0 | { |
2562 | 0 | if( meAnimationMode != ANIMATIONMODE_SHOW && !rPresSlide.empty() ) |
2563 | 0 | { |
2564 | 0 | sal_Int32 nSlide; |
2565 | 0 | for( nSlide = 0; nSlide < nSlideCount; nSlide++ ) |
2566 | 0 | if( rPresSlide == mpDoc->GetSdPage( static_cast<sal_uInt16>(nSlide), PageKind::Standard )->GetName() ) |
2567 | 0 | break; |
2568 | |
|
2569 | 0 | if( nSlide < nSlideCount ) |
2570 | 0 | mpSlideController->insertSlideNumber( static_cast<sal_uInt16>(nSlide) ); |
2571 | 0 | } |
2572 | |
|
2573 | 0 | for( const auto& rpPage : pCustomShow->PagesVector() ) |
2574 | 0 | { |
2575 | 0 | const sal_uInt16 nSdSlide = ( rpPage->GetPageNum() - 1 ) / 2; |
2576 | |
|
2577 | 0 | if( ! mpDoc->GetSdPage( nSdSlide, PageKind::Standard )->IsExcluded()) |
2578 | 0 | mpSlideController->insertSlideNumber( nSdSlide ); |
2579 | 0 | } |
2580 | 0 | } |
2581 | 0 | } |
2582 | | |
2583 | | typedef sal_uInt16 (*FncGetChildWindowId)(); |
2584 | | |
2585 | | const FncGetChildWindowId aShowChildren[] = |
2586 | | { |
2587 | | &AnimationChildWindow::GetChildWindowId, |
2588 | | &Svx3DChildWindow::GetChildWindowId, |
2589 | | &SvxFontWorkChildWindow::GetChildWindowId, |
2590 | | &SvxColorChildWindow::GetChildWindowId, |
2591 | | &SvxSearchDialogWrapper::GetChildWindowId, |
2592 | | &SvxBmpMaskChildWindow::GetChildWindowId, |
2593 | | &SvxIMapDlgChildWindow::GetChildWindowId, |
2594 | | &SvxHlinkDlgWrapper::GetChildWindowId, |
2595 | | &SfxInfoBarContainerChild::GetChildWindowId |
2596 | | }; |
2597 | | |
2598 | | void SlideshowImpl::hideChildWindows() |
2599 | 0 | { |
2600 | 0 | mnChildMask = 0; |
2601 | |
|
2602 | 0 | if( ANIMATIONMODE_SHOW != meAnimationMode ) |
2603 | 0 | return; |
2604 | | |
2605 | 0 | SfxViewFrame* pViewFrame = getViewFrame(); |
2606 | |
|
2607 | 0 | if( !pViewFrame ) |
2608 | 0 | return; |
2609 | | |
2610 | 0 | for( sal_uLong i = 0; i < SAL_N_ELEMENTS( aShowChildren ); i++ ) |
2611 | 0 | { |
2612 | 0 | const sal_uInt16 nId = ( *aShowChildren[ i ] )(); |
2613 | |
|
2614 | 0 | if( pViewFrame->GetChildWindow( nId ) ) |
2615 | 0 | { |
2616 | 0 | pViewFrame->SetChildWindow( nId, false ); |
2617 | 0 | mnChildMask |= ::tools::ULong(1) << i; |
2618 | 0 | } |
2619 | 0 | } |
2620 | 0 | } |
2621 | | |
2622 | | void SlideshowImpl::showChildWindows() |
2623 | 0 | { |
2624 | 0 | if( ANIMATIONMODE_SHOW == meAnimationMode ) |
2625 | 0 | { |
2626 | 0 | SfxViewFrame* pViewFrame = getViewFrame(); |
2627 | 0 | if( pViewFrame ) |
2628 | 0 | { |
2629 | 0 | for( sal_uLong i = 0; i < SAL_N_ELEMENTS(aShowChildren); i++ ) |
2630 | 0 | { |
2631 | 0 | if( mnChildMask & ( ::tools::ULong(1) << i ) ) |
2632 | 0 | pViewFrame->SetChildWindow( ( *aShowChildren[ i ] )(), true ); |
2633 | 0 | } |
2634 | 0 | } |
2635 | 0 | } |
2636 | 0 | } |
2637 | | |
2638 | | SfxViewFrame* SlideshowImpl::getViewFrame() const |
2639 | 0 | { |
2640 | 0 | return mpViewShell ? mpViewShell->GetViewFrame() : nullptr; |
2641 | 0 | } |
2642 | | |
2643 | | SfxDispatcher* SlideshowImpl::getDispatcher() const |
2644 | 0 | { |
2645 | 0 | return (mpViewShell && mpViewShell->GetViewFrame()) ? mpViewShell->GetViewFrame()->GetDispatcher() : nullptr; |
2646 | 0 | } |
2647 | | |
2648 | | SfxBindings* SlideshowImpl::getBindings() const |
2649 | 0 | { |
2650 | 0 | return (mpViewShell && mpViewShell->GetViewFrame()) ? &mpViewShell->GetViewFrame()->GetBindings() : nullptr; |
2651 | 0 | } |
2652 | | |
2653 | | void SlideshowImpl::resize( const Size& rSize ) |
2654 | 0 | { |
2655 | 0 | maPresSize = rSize; |
2656 | |
|
2657 | 0 | if(mpShowWindow) |
2658 | 0 | { |
2659 | 0 | mpShowWindow->SetSizePixel( maPresSize ); |
2660 | 0 | mpShowWindow->Show(); |
2661 | 0 | } |
2662 | |
|
2663 | 0 | if( mxView.is() ) try |
2664 | 0 | { |
2665 | 0 | awt::WindowEvent aEvt; |
2666 | 0 | mxView->windowResized(aEvt); |
2667 | 0 | } |
2668 | 0 | catch( Exception& ) |
2669 | 0 | { |
2670 | 0 | TOOLS_WARN_EXCEPTION( "sd", "sd::SlideshowImpl::resize()" ); |
2671 | 0 | } |
2672 | 0 | } |
2673 | | |
2674 | | void SlideshowImpl::setActiveXToolbarsVisible( bool bVisible ) |
2675 | 0 | { |
2676 | | // in case of ActiveX control the toolbars should not be visible if slide show runs in window mode |
2677 | | // actually it runs always in window mode in case of ActiveX control |
2678 | 0 | if ( !(!maPresSettings.mbFullScreen && mpDocSh && mpDocSh->GetMedium()) ) |
2679 | 0 | return; |
2680 | | |
2681 | 0 | const SfxBoolItem* pItem = mpDocSh->GetMedium()->GetItemSet().GetItem(SID_VIEWONLY, false); |
2682 | 0 | if ( !(pItem && pItem->GetValue()) ) |
2683 | 0 | return; |
2684 | | |
2685 | | // this is a plugin/activex mode, no toolbars should be visible during slide show |
2686 | | // after the end of slide show they should be visible again |
2687 | 0 | SfxViewFrame* pViewFrame = getViewFrame(); |
2688 | 0 | if( !pViewFrame ) |
2689 | 0 | return; |
2690 | | |
2691 | 0 | try |
2692 | 0 | { |
2693 | 0 | Reference< frame::XLayoutManager > xLayoutManager; |
2694 | 0 | Reference< beans::XPropertySet > xFrameProps( pViewFrame->GetFrame().GetFrameInterface(), UNO_QUERY_THROW ); |
2695 | 0 | if ( ( xFrameProps->getPropertyValue( u"LayoutManager"_ustr ) |
2696 | 0 | >>= xLayoutManager ) |
2697 | 0 | && xLayoutManager.is() ) |
2698 | 0 | { |
2699 | 0 | xLayoutManager->setVisible( bVisible ); |
2700 | 0 | } |
2701 | 0 | } |
2702 | 0 | catch( uno::Exception& ) |
2703 | 0 | {} |
2704 | 0 | } |
2705 | | |
2706 | | void SAL_CALL SlideshowImpl::activate() |
2707 | 0 | { |
2708 | 0 | SolarMutexGuard aSolarGuard; |
2709 | |
|
2710 | 0 | maDeactivateTimer.Stop(); |
2711 | |
|
2712 | 0 | if( mbActive || !mxShow.is() ) |
2713 | 0 | return; |
2714 | | |
2715 | 0 | mbActive = true; |
2716 | |
|
2717 | 0 | if( ANIMATIONMODE_SHOW == meAnimationMode ) |
2718 | 0 | { |
2719 | 0 | if( mbAutoSaveWasOn ) |
2720 | 0 | setAutoSaveState( false ); |
2721 | |
|
2722 | 0 | if( mpShowWindow ) |
2723 | 0 | { |
2724 | 0 | SfxViewFrame* pViewFrame = getViewFrame(); |
2725 | 0 | SfxDispatcher* pDispatcher = pViewFrame ? pViewFrame->GetDispatcher() : nullptr; |
2726 | |
|
2727 | 0 | hideChildWindows(); |
2728 | |
|
2729 | 0 | if( pDispatcher ) |
2730 | 0 | { |
2731 | | // filter all forbidden slots |
2732 | 0 | pDispatcher->SetSlotFilter( SfxSlotFilterState::ENABLED, pAllowed ); |
2733 | 0 | } |
2734 | |
|
2735 | 0 | if( getBindings() ) |
2736 | 0 | getBindings()->InvalidateAll(true); |
2737 | |
|
2738 | 0 | mpShowWindow->GrabFocus(); |
2739 | 0 | } |
2740 | 0 | } |
2741 | |
|
2742 | 0 | resume(); |
2743 | 0 | } |
2744 | | |
2745 | | void SAL_CALL SlideshowImpl::deactivate() |
2746 | 0 | { |
2747 | 0 | SolarMutexGuard aSolarGuard; |
2748 | |
|
2749 | 0 | if( mbActive && mxShow.is() ) |
2750 | 0 | { |
2751 | 0 | maDeactivateTimer.Start(); |
2752 | 0 | } |
2753 | 0 | } |
2754 | | |
2755 | | IMPL_LINK_NOARG(SlideshowImpl, deactivateHdl, Timer *, void) |
2756 | 0 | { |
2757 | 0 | if( !(mbActive && mxShow.is()) ) |
2758 | 0 | return; |
2759 | | |
2760 | 0 | mbActive = false; |
2761 | |
|
2762 | 0 | pause(); |
2763 | |
|
2764 | 0 | if( ANIMATIONMODE_SHOW == meAnimationMode ) |
2765 | 0 | { |
2766 | 0 | if( mbAutoSaveWasOn ) |
2767 | 0 | setAutoSaveState( true ); |
2768 | |
|
2769 | 0 | if( mpShowWindow ) |
2770 | 0 | { |
2771 | 0 | showChildWindows(); |
2772 | 0 | } |
2773 | 0 | } |
2774 | 0 | } |
2775 | | |
2776 | | sal_Bool SAL_CALL SlideshowImpl::isActive() |
2777 | 0 | { |
2778 | 0 | SolarMutexGuard aSolarGuard; |
2779 | 0 | return mbActive; |
2780 | 0 | } |
2781 | | |
2782 | | void SlideshowImpl::setAutoSaveState( bool bOn) |
2783 | 0 | { |
2784 | 0 | try |
2785 | 0 | { |
2786 | 0 | const uno::Reference<uno::XComponentContext>& xContext( ::comphelper::getProcessComponentContext() ); |
2787 | |
|
2788 | 0 | uno::Reference< util::XURLTransformer > xParser(util::URLTransformer::create(xContext)); |
2789 | 0 | util::URL aURL; |
2790 | 0 | aURL.Complete = "vnd.sun.star.autorecovery:/setAutoSaveState"; |
2791 | 0 | xParser->parseStrict(aURL); |
2792 | |
|
2793 | 0 | Sequence< beans::PropertyValue > aArgs{ comphelper::makePropertyValue(u"AutoSaveState"_ustr, bOn) }; |
2794 | |
|
2795 | 0 | uno::Reference< frame::XDispatch > xAutoSave = frame::theAutoRecovery::get(xContext); |
2796 | 0 | xAutoSave->dispatch(aURL, aArgs); |
2797 | 0 | } |
2798 | 0 | catch( Exception& ) |
2799 | 0 | { |
2800 | 0 | TOOLS_WARN_EXCEPTION( "sd", "sd::SlideshowImpl::setAutoSaveState()"); |
2801 | 0 | } |
2802 | 0 | } |
2803 | | |
2804 | | Reference< XDrawPage > SAL_CALL SlideshowImpl::getCurrentSlide() |
2805 | 0 | { |
2806 | 0 | SolarMutexGuard aSolarGuard; |
2807 | |
|
2808 | 0 | Reference< XDrawPage > xSlide; |
2809 | 0 | if( mxShow.is() && mpSlideController ) |
2810 | 0 | { |
2811 | 0 | sal_Int32 nSlide = getCurrentSlideNumber(); |
2812 | 0 | if( (nSlide >= 0) && (nSlide < mpSlideController->getSlideNumberCount() ) ) |
2813 | 0 | xSlide = mpSlideController->getSlideByNumber( nSlide ); |
2814 | 0 | } |
2815 | |
|
2816 | 0 | return xSlide; |
2817 | 0 | } |
2818 | | |
2819 | | sal_Int32 SAL_CALL SlideshowImpl::getNextSlideIndex() |
2820 | 0 | { |
2821 | 0 | SolarMutexGuard aSolarGuard; |
2822 | |
|
2823 | 0 | if( mxShow.is() ) |
2824 | 0 | { |
2825 | 0 | return mpSlideController->getNextSlideIndex(); |
2826 | 0 | } |
2827 | 0 | else |
2828 | 0 | { |
2829 | 0 | return -1; |
2830 | 0 | } |
2831 | 0 | } |
2832 | | |
2833 | | sal_Int32 SAL_CALL SlideshowImpl::getCurrentSlideIndex() |
2834 | 0 | { |
2835 | 0 | return mpSlideController ? mpSlideController->getCurrentSlideIndex() : -1; |
2836 | 0 | } |
2837 | | |
2838 | | // css::presentation::XSlideShowController: |
2839 | | |
2840 | | ::sal_Int32 SAL_CALL SlideshowImpl::getSlideCount() |
2841 | 0 | { |
2842 | 0 | return mpSlideController ? mpSlideController->getSlideIndexCount() : 0; |
2843 | 0 | } |
2844 | | |
2845 | | Reference< XDrawPage > SAL_CALL SlideshowImpl::getSlideByIndex(::sal_Int32 Index) |
2846 | 0 | { |
2847 | 0 | if ((mpSlideController == nullptr) || (Index < 0) |
2848 | 0 | || (Index >= mpSlideController->getSlideIndexCount())) |
2849 | 0 | throw IndexOutOfBoundsException(); |
2850 | | |
2851 | 0 | return mpSlideController->getSlideByNumber( mpSlideController->getSlideNumber( Index ) ); |
2852 | 0 | } |
2853 | | |
2854 | | sal_Bool SAL_CALL SlideshowImpl::getAlwaysOnTop() |
2855 | 0 | { |
2856 | 0 | SolarMutexGuard aSolarGuard; |
2857 | 0 | return maPresSettings.mbAlwaysOnTop; |
2858 | 0 | } |
2859 | | |
2860 | | void SAL_CALL SlideshowImpl::setAlwaysOnTop( sal_Bool bAlways ) |
2861 | 0 | { |
2862 | 0 | SolarMutexGuard aSolarGuard; |
2863 | 0 | if( maPresSettings.mbAlwaysOnTop != bool(bAlways) ) |
2864 | 0 | { |
2865 | 0 | maPresSettings.mbAlwaysOnTop = bAlways; |
2866 | | // todo, can this be changed while running? |
2867 | 0 | } |
2868 | 0 | } |
2869 | | |
2870 | | sal_Bool SAL_CALL SlideshowImpl::isFullScreen() |
2871 | 0 | { |
2872 | 0 | SolarMutexGuard aSolarGuard; |
2873 | 0 | return maPresSettings.mbFullScreen; |
2874 | 0 | } |
2875 | | |
2876 | | sal_Bool SAL_CALL SlideshowImpl::getMouseVisible() |
2877 | 0 | { |
2878 | 0 | SolarMutexGuard aSolarGuard; |
2879 | 0 | return maPresSettings.mbMouseVisible; |
2880 | 0 | } |
2881 | | |
2882 | | void SAL_CALL SlideshowImpl::setMouseVisible( sal_Bool bVisible ) |
2883 | 0 | { |
2884 | 0 | SolarMutexGuard aSolarGuard; |
2885 | 0 | if( maPresSettings.mbMouseVisible != bool(bVisible) ) |
2886 | 0 | { |
2887 | 0 | maPresSettings.mbMouseVisible = bVisible; |
2888 | 0 | if( mpShowWindow ) |
2889 | 0 | mpShowWindow->SetMouseAutoHide( !maPresSettings.mbMouseVisible ); |
2890 | 0 | } |
2891 | 0 | } |
2892 | | |
2893 | | sal_Bool SAL_CALL SlideshowImpl::getUsePen() |
2894 | 0 | { |
2895 | 0 | SolarMutexGuard aSolarGuard; |
2896 | 0 | return mbUsePen; |
2897 | 0 | } |
2898 | | |
2899 | | void SAL_CALL SlideshowImpl::setUsePen( sal_Bool bMouseAsPen ) |
2900 | 0 | { |
2901 | 0 | SolarMutexGuard aSolarGuard; |
2902 | 0 | mbUsePen = bMouseAsPen; |
2903 | 0 | if( !mxShow.is() ) |
2904 | 0 | return; |
2905 | | |
2906 | 0 | try |
2907 | 0 | { |
2908 | | // For Pencolor; |
2909 | 0 | beans::PropertyValue aPenProp; |
2910 | 0 | aPenProp.Name = "UserPaintColor"; |
2911 | 0 | if( mbUsePen ) |
2912 | 0 | aPenProp.Value <<= mnUserPaintColor; |
2913 | 0 | mxShow->setProperty( aPenProp ); |
2914 | | |
2915 | | //for StrokeWidth : |
2916 | 0 | if( mbUsePen ) |
2917 | 0 | { |
2918 | 0 | beans::PropertyValue aPenPropWidth; |
2919 | 0 | aPenPropWidth.Name = "UserPaintStrokeWidth"; |
2920 | 0 | aPenPropWidth.Value <<= mdUserPaintStrokeWidth; |
2921 | 0 | mxShow->setProperty( aPenPropWidth ); |
2922 | | |
2923 | | // for Pen Mode |
2924 | 0 | beans::PropertyValue aPenPropSwitchPenMode; |
2925 | 0 | aPenPropSwitchPenMode.Name = "SwitchPenMode"; |
2926 | 0 | aPenPropSwitchPenMode.Value <<= true; |
2927 | 0 | mxShow->setProperty( aPenPropSwitchPenMode ); |
2928 | 0 | } |
2929 | 0 | } |
2930 | 0 | catch( Exception& ) |
2931 | 0 | { |
2932 | 0 | TOOLS_WARN_EXCEPTION( "sd", "sd::SlideshowImpl::setUsePen()" ); |
2933 | 0 | } |
2934 | 0 | } |
2935 | | |
2936 | | double SAL_CALL SlideshowImpl::getPenWidth() |
2937 | 0 | { |
2938 | 0 | SolarMutexGuard aSolarGuard; |
2939 | 0 | return mdUserPaintStrokeWidth; |
2940 | 0 | } |
2941 | | |
2942 | | void SAL_CALL SlideshowImpl::setPenWidth( double dStrokeWidth ) |
2943 | 0 | { |
2944 | 0 | SolarMutexGuard aSolarGuard; |
2945 | 0 | mdUserPaintStrokeWidth = dStrokeWidth; |
2946 | 0 | setUsePen( true ); // enable pen mode, update color and width |
2947 | 0 | } |
2948 | | |
2949 | | sal_Int32 SAL_CALL SlideshowImpl::getPenColor() |
2950 | 0 | { |
2951 | 0 | SolarMutexGuard aSolarGuard; |
2952 | 0 | return mnUserPaintColor; |
2953 | 0 | } |
2954 | | |
2955 | | void SAL_CALL SlideshowImpl::setPenColor( sal_Int32 nColor ) |
2956 | 0 | { |
2957 | 0 | SolarMutexGuard aSolarGuard; |
2958 | 0 | mnUserPaintColor = nColor; |
2959 | 0 | setUsePen( true ); // enable pen mode, update color |
2960 | 0 | } |
2961 | | |
2962 | | void SAL_CALL SlideshowImpl::setEraseAllInk(sal_Bool bEraseAllInk) |
2963 | 0 | { |
2964 | 0 | if( !bEraseAllInk ) |
2965 | 0 | return; |
2966 | | |
2967 | 0 | SolarMutexGuard aSolarGuard; |
2968 | 0 | if( !mxShow.is() ) |
2969 | 0 | return; |
2970 | | |
2971 | 0 | try |
2972 | 0 | { |
2973 | 0 | beans::PropertyValue aPenPropEraseAllInk; |
2974 | 0 | aPenPropEraseAllInk.Name = "EraseAllInk"; |
2975 | 0 | aPenPropEraseAllInk.Value <<= bEraseAllInk; |
2976 | 0 | mxShow->setProperty( aPenPropEraseAllInk ); |
2977 | 0 | } |
2978 | 0 | catch( Exception& ) |
2979 | 0 | { |
2980 | 0 | TOOLS_WARN_EXCEPTION( "sd.slideshow", "sd::SlideshowImpl::setEraseAllInk()" ); |
2981 | 0 | } |
2982 | 0 | } |
2983 | | |
2984 | | // XSlideShowController Methods |
2985 | | sal_Bool SAL_CALL SlideshowImpl::isRunning( ) |
2986 | 0 | { |
2987 | 0 | SolarMutexGuard aSolarGuard; |
2988 | 0 | return mxShow.is(); |
2989 | 0 | } |
2990 | | |
2991 | | void SAL_CALL SlideshowImpl::gotoNextEffect( ) |
2992 | 0 | { |
2993 | 0 | SolarMutexGuard aSolarGuard; |
2994 | |
|
2995 | 0 | if( !(mxShow.is() && mpSlideController && mpShowWindow) ) |
2996 | 0 | return; |
2997 | | |
2998 | 0 | if( mbIsPaused && mpShowWindow->GetShowWindowMode() != SHOWWINDOWMODE_END ) |
2999 | 0 | resume(); |
3000 | |
|
3001 | 0 | const ShowWindowMode eMode = mpShowWindow->GetShowWindowMode(); |
3002 | 0 | if( eMode == SHOWWINDOWMODE_END ) |
3003 | 0 | { |
3004 | 0 | endPresentation(); |
3005 | 0 | } |
3006 | 0 | else if( (eMode == SHOWWINDOWMODE_PAUSE) || (eMode == SHOWWINDOWMODE_BLANK) ) |
3007 | 0 | { |
3008 | 0 | mpShowWindow->RestartShow(); |
3009 | 0 | } |
3010 | 0 | else |
3011 | 0 | { |
3012 | 0 | mxShow->nextEffect(); |
3013 | 0 | update(); |
3014 | 0 | } |
3015 | 0 | } |
3016 | | |
3017 | | void SAL_CALL SlideshowImpl::gotoPreviousEffect( ) |
3018 | 0 | { |
3019 | 0 | SolarMutexGuard aSolarGuard; |
3020 | |
|
3021 | 0 | if( !(mxShow.is() && mpSlideController && mpShowWindow) ) |
3022 | 0 | return; |
3023 | | |
3024 | 0 | const ShowWindowMode eMode = mpShowWindow->GetShowWindowMode(); |
3025 | 0 | if( (eMode == SHOWWINDOWMODE_PAUSE) || (eMode == SHOWWINDOWMODE_BLANK) || mbIsPaused ) |
3026 | 0 | { |
3027 | 0 | resume(); |
3028 | 0 | } |
3029 | 0 | else |
3030 | 0 | { |
3031 | 0 | mxShow->previousEffect(); |
3032 | 0 | update(); |
3033 | 0 | } |
3034 | 0 | } |
3035 | | |
3036 | | void SAL_CALL SlideshowImpl::gotoFirstSlide( ) |
3037 | 0 | { |
3038 | 0 | SolarMutexGuard aSolarGuard; |
3039 | |
|
3040 | 0 | if( !(mpShowWindow && mpSlideController) ) |
3041 | 0 | return; |
3042 | | |
3043 | 0 | if( mbIsPaused ) |
3044 | 0 | resume(); |
3045 | |
|
3046 | 0 | if( mpShowWindow->GetShowWindowMode() == SHOWWINDOWMODE_END ) |
3047 | 0 | { |
3048 | 0 | if( mpSlideController->getSlideIndexCount() ) |
3049 | 0 | mpShowWindow->RestartShow( 0); |
3050 | 0 | } |
3051 | 0 | else |
3052 | 0 | { |
3053 | 0 | displaySlideIndex( 0 ); |
3054 | 0 | } |
3055 | 0 | } |
3056 | | |
3057 | | void SAL_CALL SlideshowImpl::gotoNextSlide( ) |
3058 | 0 | { |
3059 | 0 | SolarMutexGuard aSolarGuard; |
3060 | |
|
3061 | 0 | if( mbIsPaused ) |
3062 | 0 | resume(); |
3063 | |
|
3064 | 0 | const ShowWindowMode eMode = mpShowWindow->GetShowWindowMode(); |
3065 | 0 | if( (eMode == SHOWWINDOWMODE_PAUSE) || (eMode == SHOWWINDOWMODE_BLANK) ) |
3066 | 0 | { |
3067 | 0 | mpShowWindow->RestartShow(); |
3068 | 0 | } |
3069 | 0 | else |
3070 | 0 | { |
3071 | | // if this is a show, ignore user inputs and |
3072 | | // start 20ms timer to reenable inputs to filter |
3073 | | // buffered inputs during slide transition |
3074 | 0 | if( meAnimationMode == ANIMATIONMODE_SHOW ) |
3075 | 0 | { |
3076 | 0 | mbInputFreeze = true; |
3077 | 0 | maInputFreezeTimer.Start(); |
3078 | 0 | } |
3079 | |
|
3080 | 0 | if( mpSlideController ) |
3081 | 0 | { |
3082 | 0 | if( mpSlideController->nextSlide() ) |
3083 | 0 | { |
3084 | 0 | displayCurrentSlide(); |
3085 | 0 | } |
3086 | 0 | else |
3087 | 0 | { |
3088 | 0 | stopSound(); |
3089 | |
|
3090 | 0 | if( meAnimationMode == ANIMATIONMODE_PREVIEW ) |
3091 | 0 | { |
3092 | 0 | endPresentation(); |
3093 | 0 | } |
3094 | 0 | else if( maPresSettings.mbEndless ) |
3095 | 0 | { |
3096 | 0 | if( maPresSettings.mnPauseTimeout ) |
3097 | 0 | { |
3098 | 0 | if( mpShowWindow ) |
3099 | 0 | { |
3100 | 0 | if ( maPresSettings.mbShowPauseLogo ) |
3101 | 0 | { |
3102 | 0 | Graphic aGraphic(SfxApplication::GetApplicationLogo(360)); |
3103 | 0 | mpShowWindow->SetPauseMode( maPresSettings.mnPauseTimeout, &aGraphic ); |
3104 | 0 | } |
3105 | 0 | else |
3106 | 0 | mpShowWindow->SetPauseMode( maPresSettings.mnPauseTimeout ); |
3107 | 0 | } |
3108 | 0 | } |
3109 | 0 | else |
3110 | 0 | { |
3111 | 0 | displaySlideIndex( 0 ); |
3112 | 0 | } |
3113 | 0 | } |
3114 | 0 | else |
3115 | 0 | { |
3116 | 0 | if( mpShowWindow ) |
3117 | 0 | { |
3118 | 0 | mpShowWindow->SetEndMode(); |
3119 | 0 | if (!mpViewShell->GetDoc()->GetStartWithPresentation()) |
3120 | 0 | pause(); |
3121 | 0 | } |
3122 | 0 | } |
3123 | 0 | } |
3124 | 0 | } |
3125 | 0 | } |
3126 | 0 | } |
3127 | | |
3128 | | void SAL_CALL SlideshowImpl::gotoPreviousSlide( ) |
3129 | 0 | { |
3130 | 0 | gotoPreviousSlide(false); |
3131 | 0 | } |
3132 | | |
3133 | | void SlideshowImpl::gotoPreviousSlide (const bool bSkipAllMainSequenceEffects) |
3134 | 0 | { |
3135 | 0 | SolarMutexGuard aSolarGuard; |
3136 | |
|
3137 | 0 | if( !(mxShow.is() && mpSlideController) ) |
3138 | 0 | return; |
3139 | | |
3140 | 0 | try |
3141 | 0 | { |
3142 | 0 | if( mbIsPaused ) |
3143 | 0 | resume(); |
3144 | |
|
3145 | 0 | const ShowWindowMode eMode = mpShowWindow->GetShowWindowMode(); |
3146 | 0 | if( eMode == SHOWWINDOWMODE_END ) |
3147 | 0 | { |
3148 | 0 | mpShowWindow->RestartShow( mpSlideController->getCurrentSlideIndex() ); |
3149 | 0 | } |
3150 | 0 | else if( (eMode == SHOWWINDOWMODE_PAUSE) || (eMode == SHOWWINDOWMODE_BLANK) ) |
3151 | 0 | { |
3152 | 0 | mpShowWindow->RestartShow(); |
3153 | 0 | } |
3154 | 0 | else |
3155 | 0 | { |
3156 | 0 | if( mpSlideController->previousSlide()) |
3157 | 0 | displayCurrentSlide(bSkipAllMainSequenceEffects); |
3158 | 0 | else if (bSkipAllMainSequenceEffects) |
3159 | 0 | { |
3160 | | // We could not go to the previous slide (probably because |
3161 | | // the current slide is already the first one). We still |
3162 | | // have to call displayCurrentSlide because the calling |
3163 | | // slideshow can not determine whether there is a previous |
3164 | | // slide or not and has already prepared for a slide change. |
3165 | | // This slide change has to be completed now, even when |
3166 | | // changing to the same slide. |
3167 | | // Note that in this special case we do NOT pass |
3168 | | // bSkipAllMainSequenceEffects because we display the same |
3169 | | // slide as before and do not want to show all its effects. |
3170 | 0 | displayCurrentSlide(); |
3171 | 0 | } |
3172 | 0 | } |
3173 | 0 | } |
3174 | 0 | catch( Exception& ) |
3175 | 0 | { |
3176 | 0 | TOOLS_WARN_EXCEPTION( "sd", "sd::SlideshowImpl::gotoPreviousSlide()" ); |
3177 | 0 | } |
3178 | 0 | } |
3179 | | |
3180 | | void SAL_CALL SlideshowImpl::gotoLastSlide() |
3181 | 0 | { |
3182 | 0 | SolarMutexGuard aSolarGuard; |
3183 | |
|
3184 | 0 | if( !mpSlideController ) |
3185 | 0 | return; |
3186 | | |
3187 | 0 | if( mbIsPaused ) |
3188 | 0 | resume(); |
3189 | |
|
3190 | 0 | const sal_Int32 nLastSlideIndex = mpSlideController->getSlideIndexCount() - 1; |
3191 | 0 | if( nLastSlideIndex >= 0 ) |
3192 | 0 | { |
3193 | 0 | if( mpShowWindow->GetShowWindowMode() == SHOWWINDOWMODE_END ) |
3194 | 0 | { |
3195 | 0 | mpShowWindow->RestartShow( nLastSlideIndex ); |
3196 | 0 | } |
3197 | 0 | else |
3198 | 0 | { |
3199 | 0 | displaySlideIndex( nLastSlideIndex ); |
3200 | 0 | } |
3201 | 0 | } |
3202 | 0 | } |
3203 | | |
3204 | | void SAL_CALL SlideshowImpl::gotoBookmark( const OUString& rBookmark ) |
3205 | 0 | { |
3206 | 0 | SolarMutexGuard aSolarGuard; |
3207 | |
|
3208 | 0 | if( mbIsPaused ) |
3209 | 0 | resume(); |
3210 | |
|
3211 | 0 | sal_Int32 nSlideNumber = getSlideNumberForBookmark( rBookmark ); |
3212 | 0 | if( nSlideNumber != -1 ) |
3213 | 0 | displaySlideNumber( nSlideNumber ); |
3214 | 0 | } |
3215 | | |
3216 | | void SAL_CALL SlideshowImpl::gotoSlide( const Reference< XDrawPage >& xSlide ) |
3217 | 0 | { |
3218 | 0 | SolarMutexGuard aSolarGuard; |
3219 | |
|
3220 | 0 | if( !(mpSlideController && xSlide.is()) ) |
3221 | 0 | return; |
3222 | | |
3223 | 0 | if( mbIsPaused ) |
3224 | 0 | resume(); |
3225 | |
|
3226 | 0 | const sal_Int32 nSlideCount = mpSlideController->getSlideNumberCount(); |
3227 | 0 | for( sal_Int32 nSlide = 0; nSlide < nSlideCount; nSlide++ ) |
3228 | 0 | { |
3229 | 0 | if( mpSlideController->getSlideByNumber( nSlide ) == xSlide ) |
3230 | 0 | { |
3231 | 0 | displaySlideNumber( nSlide ); |
3232 | 0 | } |
3233 | 0 | } |
3234 | 0 | } |
3235 | | |
3236 | | void SAL_CALL SlideshowImpl::gotoSlideIndex( sal_Int32 nIndex ) |
3237 | 0 | { |
3238 | 0 | SolarMutexGuard aSolarGuard; |
3239 | |
|
3240 | 0 | if( mbIsPaused ) |
3241 | 0 | resume(); |
3242 | |
|
3243 | 0 | displaySlideIndex( nIndex ); |
3244 | 0 | } |
3245 | | |
3246 | | void SAL_CALL SlideshowImpl::stopSound( ) |
3247 | 0 | { |
3248 | 0 | SolarMutexGuard aSolarGuard; |
3249 | |
|
3250 | 0 | try |
3251 | 0 | { |
3252 | 0 | if( mxPlayer.is() ) |
3253 | 0 | { |
3254 | 0 | mxPlayer->stop(); |
3255 | 0 | mxPlayer.clear(); |
3256 | 0 | } |
3257 | 0 | } |
3258 | 0 | catch( Exception& ) |
3259 | 0 | { |
3260 | 0 | TOOLS_WARN_EXCEPTION( "sd", "sd::SlideshowImpl::stopSound()" ); |
3261 | 0 | } |
3262 | 0 | } |
3263 | | |
3264 | | // XIndexAccess |
3265 | | |
3266 | | ::sal_Int32 SAL_CALL SlideshowImpl::getCount( ) |
3267 | 0 | { |
3268 | 0 | return getSlideCount(); |
3269 | 0 | } |
3270 | | |
3271 | | css::uno::Any SAL_CALL SlideshowImpl::getByIndex( ::sal_Int32 Index ) |
3272 | 0 | { |
3273 | 0 | return Any( getSlideByIndex( Index ) ); |
3274 | 0 | } |
3275 | | |
3276 | | css::uno::Type SAL_CALL SlideshowImpl::getElementType( ) |
3277 | 0 | { |
3278 | 0 | return cppu::UnoType<XDrawPage>::get(); |
3279 | 0 | } |
3280 | | |
3281 | | sal_Bool SAL_CALL SlideshowImpl::hasElements( ) |
3282 | 0 | { |
3283 | 0 | return getSlideCount() != 0; |
3284 | 0 | } |
3285 | | |
3286 | | namespace |
3287 | | { |
3288 | | class AsyncUpdateSlideshow_Impl |
3289 | | { |
3290 | | public: |
3291 | | struct AsyncUpdateSlideshowData |
3292 | | { |
3293 | | SlideshowImpl* pSlideshowImpl; |
3294 | | uno::Reference< css::drawing::XDrawPage > XCurrentSlide; |
3295 | | SdrHintKind eHintKind; |
3296 | | }; |
3297 | | |
3298 | | static ImplSVEvent* AsyncUpdateSlideshow( |
3299 | | SlideshowImpl* pSlideshowImpl, |
3300 | | const uno::Reference< css::drawing::XDrawPage >& rXCurrentSlide, |
3301 | | SdrHintKind eHintKind) |
3302 | 0 | { |
3303 | 0 | AsyncUpdateSlideshowData* pNew(new AsyncUpdateSlideshowData); |
3304 | 0 | pNew->pSlideshowImpl = pSlideshowImpl; |
3305 | 0 | pNew->XCurrentSlide = rXCurrentSlide; |
3306 | 0 | pNew->eHintKind = eHintKind; |
3307 | 0 | return Application::PostUserEvent(LINK(nullptr, AsyncUpdateSlideshow_Impl, Update), pNew); |
3308 | | // coverity[leaked_storage] - pDisruptor takes care of its own destruction at idle time |
3309 | 0 | } |
3310 | | |
3311 | | DECL_STATIC_LINK(AsyncUpdateSlideshow_Impl, Update, void*, void); |
3312 | | }; |
3313 | | |
3314 | | IMPL_STATIC_LINK(AsyncUpdateSlideshow_Impl, Update, void*, pData, void) |
3315 | 0 | { |
3316 | 0 | AsyncUpdateSlideshowData* pSlideData(static_cast<AsyncUpdateSlideshowData*>(pData)); |
3317 | 0 | pSlideData->pSlideshowImpl->AsyncNotifyEvent(pSlideData->XCurrentSlide, pSlideData->eHintKind); |
3318 | 0 | delete pSlideData; |
3319 | 0 | } |
3320 | | } |
3321 | | |
3322 | | void SlideshowImpl::AsyncNotifyEvent( |
3323 | | const uno::Reference< css::drawing::XDrawPage >& rXCurrentSlide, |
3324 | | const SdrHintKind eHintKind) |
3325 | 0 | { |
3326 | 0 | switch (eHintKind) |
3327 | 0 | { |
3328 | 0 | case SdrHintKind::ObjectInserted: |
3329 | 0 | { |
3330 | 0 | mnEventObjectInserted = nullptr; |
3331 | | |
3332 | | // refresh single slide |
3333 | 0 | gotoSlide(rXCurrentSlide); |
3334 | 0 | break; |
3335 | 0 | } |
3336 | 0 | case SdrHintKind::ObjectRemoved: |
3337 | 0 | { |
3338 | 0 | mnEventObjectRemoved = nullptr; |
3339 | | |
3340 | | // refresh single slide |
3341 | 0 | gotoSlide(rXCurrentSlide); |
3342 | 0 | break; |
3343 | 0 | } |
3344 | 0 | case SdrHintKind::ObjectChange: |
3345 | 0 | { |
3346 | 0 | mnEventObjectChange = nullptr; |
3347 | | |
3348 | | // refresh single slide |
3349 | 0 | gotoSlide(rXCurrentSlide); |
3350 | 0 | break; |
3351 | 0 | } |
3352 | 0 | case SdrHintKind::PageOrderChange: |
3353 | 0 | { |
3354 | 0 | mnEventPageOrderChange = nullptr; |
3355 | | |
3356 | | // order of pages (object pages or master pages) changed (Insert/Remove/ChangePos) |
3357 | | // rXCurrentSlide is the current slide before the change. |
3358 | 0 | rtl::Reference< SdXImpressDocument > xDrawPages( mpDoc->getUnoModel() ); |
3359 | 0 | Reference< XIndexAccess > xSlides( xDrawPages->getDrawPages(), UNO_QUERY_THROW ); |
3360 | 0 | const sal_Int32 nNewSlideCount(xSlides.is() ? xSlides->getCount() : 0); |
3361 | |
|
3362 | 0 | if (nNewSlideCount != mpSlideController->getSlideNumberCount()) |
3363 | 0 | { |
3364 | | // need to reinitialize AnimationSlideController |
3365 | 0 | OUString aPresSlide( maPresSettings.maPresPage ); |
3366 | 0 | createSlideList( maPresSettings.mbAll, aPresSlide ); |
3367 | 0 | } |
3368 | | |
3369 | | // Check if current slide before change is still valid (maybe removed) |
3370 | 0 | const sal_Int32 nSlideCount(mpSlideController->getSlideNumberCount()); |
3371 | 0 | bool bSlideStillValid(false); |
3372 | |
|
3373 | 0 | for (sal_Int32 nSlide(0); !bSlideStillValid && nSlide < nSlideCount; nSlide++) |
3374 | 0 | { |
3375 | 0 | if (rXCurrentSlide == mpSlideController->getSlideByNumber(nSlide)) |
3376 | 0 | { |
3377 | 0 | bSlideStillValid = true; |
3378 | 0 | } |
3379 | 0 | } |
3380 | |
|
3381 | 0 | if(bSlideStillValid) |
3382 | 0 | { |
3383 | | // stay on that slide |
3384 | 0 | gotoSlide(rXCurrentSlide); |
3385 | 0 | } |
3386 | 0 | else |
3387 | 0 | { |
3388 | | // not possible to stay on that slide, go to 1st slide (kinda restart) |
3389 | 0 | gotoFirstSlide(); |
3390 | 0 | } |
3391 | 0 | break; |
3392 | 0 | } |
3393 | 0 | default: |
3394 | 0 | break; |
3395 | 0 | } |
3396 | 0 | } |
3397 | | |
3398 | | bool SlideshowImpl::isCurrentSlideInvolved(const SdrHint& rHint) |
3399 | 0 | { |
3400 | | // get current slide |
3401 | 0 | uno::Reference< css::drawing::XDrawPage > XCurrentSlide(getCurrentSlide()); |
3402 | 0 | if (!XCurrentSlide.is()) |
3403 | 0 | return false; |
3404 | | |
3405 | 0 | SdrPage* pCurrentSlide(GetSdrPageFromXDrawPage(XCurrentSlide)); |
3406 | 0 | if (nullptr == pCurrentSlide) |
3407 | 0 | return false; |
3408 | | |
3409 | 0 | const SdrPage* pHintPage(rHint.GetPage()); |
3410 | 0 | if (nullptr == pHintPage) |
3411 | 0 | return false; |
3412 | | |
3413 | 0 | if (pHintPage->IsMasterPage()) |
3414 | 0 | { |
3415 | 0 | if (pCurrentSlide->TRG_HasMasterPage()) |
3416 | 0 | { |
3417 | | // current slide uses MasterPage on which the change happened |
3418 | 0 | return pHintPage == &pCurrentSlide->TRG_GetMasterPage(); |
3419 | 0 | } |
3420 | 0 | } |
3421 | | |
3422 | | // object on current slide was changed |
3423 | 0 | return pHintPage == pCurrentSlide; |
3424 | 0 | } |
3425 | | |
3426 | | void SlideshowImpl::sendHintSlideChanged(const SdrPage* pChangedPage) const |
3427 | 0 | { |
3428 | 0 | if (nullptr == pChangedPage) |
3429 | 0 | return; |
3430 | | |
3431 | 0 | if (!mxShow.is()) |
3432 | 0 | return; |
3433 | | |
3434 | 0 | mxShow->setProperty( |
3435 | 0 | beans::PropertyValue( u"HintSlideChanged"_ustr , |
3436 | 0 | -1, |
3437 | 0 | Any( GetXDrawPageForSdrPage(const_cast<SdrPage*>(pChangedPage)) ), |
3438 | 0 | beans::PropertyState_DIRECT_VALUE ) ); |
3439 | 0 | } |
3440 | | |
3441 | | void SlideshowImpl::Notify(SfxBroadcaster& /*rBC*/, const SfxHint& rHint) |
3442 | 0 | { |
3443 | 0 | if (SfxHintId::ThisIsAnSdrHint != rHint.GetId()) |
3444 | | // nothing to do for non-SdrHints |
3445 | 0 | return; |
3446 | | |
3447 | 0 | if (nullptr == mpDoc) |
3448 | | // better do nothing when no DrawModel (should not happen) |
3449 | 0 | return; |
3450 | | |
3451 | | // tdf#158664 I am surprised, but the 'this' instance keeps incarnated |
3452 | | // when the slideshow was running once, so need to check for |
3453 | | // SlideShow instance/running to be safe. |
3454 | | // NOTE: isRunning() checks mxShow.is(), that is what we want |
3455 | 0 | if (!isRunning()) |
3456 | | // no SlideShow instance or not running, nothing to do |
3457 | 0 | return; |
3458 | | |
3459 | 0 | const SdrHint& rSdrHint(static_cast<const SdrHint&>(rHint)); |
3460 | 0 | const SdrHintKind eHintKind(rSdrHint.GetKind()); |
3461 | |
|
3462 | 0 | switch (eHintKind) |
3463 | 0 | { |
3464 | 0 | case SdrHintKind::ObjectInserted: |
3465 | 0 | { |
3466 | 0 | if (nullptr != mnEventObjectInserted) |
3467 | | // avoid multiple events |
3468 | 0 | return; |
3469 | | |
3470 | | // tdf#160669 IASS: inform about ALL changed slides due to prefetch |
3471 | 0 | sendHintSlideChanged(rSdrHint.GetPage()); |
3472 | |
|
3473 | 0 | if (!isCurrentSlideInvolved(rSdrHint)) |
3474 | | // nothing to do when current slide is not involved |
3475 | 0 | return; |
3476 | | |
3477 | | // Refresh current slide |
3478 | 0 | uno::Reference< css::drawing::XDrawPage > XCurrentSlide(getCurrentSlide()); |
3479 | 0 | mnEventObjectInserted = AsyncUpdateSlideshow_Impl::AsyncUpdateSlideshow(this, XCurrentSlide, eHintKind); |
3480 | 0 | break; |
3481 | 0 | } |
3482 | 0 | case SdrHintKind::ObjectRemoved: |
3483 | 0 | { |
3484 | 0 | if (nullptr != mnEventObjectRemoved) |
3485 | | // avoid multiple events |
3486 | 0 | return; |
3487 | | |
3488 | | // tdf#160669 IASS: inform about ALL changed slides due to prefetch |
3489 | 0 | sendHintSlideChanged(rSdrHint.GetPage()); |
3490 | |
|
3491 | 0 | if (!isCurrentSlideInvolved(rSdrHint)) |
3492 | | // nothing to do when current slide is not involved |
3493 | 0 | return; |
3494 | | |
3495 | | // Refresh current slide |
3496 | 0 | uno::Reference< css::drawing::XDrawPage > XCurrentSlide(getCurrentSlide()); |
3497 | 0 | mnEventObjectRemoved = AsyncUpdateSlideshow_Impl::AsyncUpdateSlideshow(this, XCurrentSlide, eHintKind); |
3498 | 0 | break; |
3499 | 0 | } |
3500 | 0 | case SdrHintKind::ObjectChange: |
3501 | 0 | { |
3502 | 0 | if (nullptr != mnEventObjectChange) |
3503 | | // avoid multiple events |
3504 | 0 | return; |
3505 | | |
3506 | | // tdf#160669 IASS: inform about ALL changed slides due to prefetch |
3507 | 0 | sendHintSlideChanged(rSdrHint.GetPage()); |
3508 | |
|
3509 | 0 | if (!isCurrentSlideInvolved(rSdrHint)) |
3510 | | // nothing to do when current slide is not involved |
3511 | 0 | return; |
3512 | | |
3513 | | // Refresh current slide. Need to do that asynchronous, else e.g. |
3514 | | // text edit changes EditEngine/Outliner are not progressed far |
3515 | | // enough (ObjectChanged broadcast which we are in here seems |
3516 | | // too early for some cases) |
3517 | 0 | uno::Reference< css::drawing::XDrawPage > XCurrentSlide(getCurrentSlide()); |
3518 | 0 | mnEventObjectChange = AsyncUpdateSlideshow_Impl::AsyncUpdateSlideshow(this, XCurrentSlide, eHintKind); |
3519 | 0 | break; |
3520 | 0 | } |
3521 | 0 | case SdrHintKind::PageOrderChange: |
3522 | 0 | { |
3523 | | // Unfortunately we get multiple events, e.g. when drag/drop position change in |
3524 | | // slide sorter on left side of EditView. This includes some with page number +1, |
3525 | | // then again -1 (it's a position change). Problem is that in-between already |
3526 | | // a re-schedule seems to happen, so indeed AsyncNotifyEvent will change to +1/-1 |
3527 | | // already. Since we get even more, at least try to take the last one. I found no |
3528 | | // good solution yet for this. |
3529 | 0 | if (nullptr != mnEventPageOrderChange) |
3530 | 0 | Application::RemoveUserEvent( mnEventPageOrderChange ); |
3531 | | |
3532 | | // tdf#160669 IASS: inform about ALL changed slides due to prefetch |
3533 | 0 | sendHintSlideChanged(rSdrHint.GetPage()); |
3534 | | |
3535 | | // order of pages (object pages or master pages) changed (Insert/Remove/ChangePos) |
3536 | 0 | uno::Reference< css::drawing::XDrawPage > XCurrentSlide(getCurrentSlide()); |
3537 | 0 | mnEventPageOrderChange = AsyncUpdateSlideshow_Impl::AsyncUpdateSlideshow(this, XCurrentSlide, eHintKind); |
3538 | 0 | break; |
3539 | 0 | } |
3540 | 0 | case SdrHintKind::ModelCleared: |
3541 | 0 | { |
3542 | | // immediately end presentation |
3543 | 0 | endPresentation(); |
3544 | 0 | break; |
3545 | 0 | } |
3546 | 0 | default: |
3547 | 0 | break; |
3548 | 0 | } |
3549 | 0 | } |
3550 | | |
3551 | | Reference< XSlideShow > SAL_CALL SlideshowImpl::getSlideShow() |
3552 | 0 | { |
3553 | 0 | return mxShow; |
3554 | 0 | } |
3555 | | |
3556 | | PresentationSettingsEx::PresentationSettingsEx( const PresentationSettingsEx& r ) |
3557 | 0 | : PresentationSettings( r ) |
3558 | 0 | , mbRehearseTimings(r.mbRehearseTimings) |
3559 | 0 | , mbPreview(r.mbPreview) |
3560 | 0 | , mpParentWindow( nullptr ) |
3561 | 0 | { |
3562 | 0 | } |
3563 | | |
3564 | | PresentationSettingsEx::PresentationSettingsEx( PresentationSettings const & r ) |
3565 | 0 | : PresentationSettings( r ) |
3566 | 0 | , mbRehearseTimings(false) |
3567 | 0 | , mbPreview(false) |
3568 | 0 | , mpParentWindow(nullptr) |
3569 | 0 | { |
3570 | 0 | } |
3571 | | |
3572 | | void PresentationSettingsEx::SetArguments( const Sequence< PropertyValue >& rArguments ) |
3573 | 0 | { |
3574 | 0 | for( const PropertyValue& rValue : rArguments ) |
3575 | 0 | { |
3576 | 0 | SetPropertyValue( rValue.Name, rValue.Value ); |
3577 | 0 | } |
3578 | 0 | } |
3579 | | |
3580 | | void PresentationSettingsEx::SetPropertyValue( std::u16string_view rProperty, const Any& rValue ) |
3581 | 0 | { |
3582 | 0 | if ( rProperty == u"RehearseTimings" ) |
3583 | 0 | { |
3584 | 0 | if( rValue >>= mbRehearseTimings ) |
3585 | 0 | return; |
3586 | 0 | } |
3587 | 0 | else if ( rProperty == u"Preview" ) |
3588 | 0 | { |
3589 | 0 | if( rValue >>= mbPreview ) |
3590 | 0 | return; |
3591 | 0 | } |
3592 | 0 | else if ( rProperty == u"AnimationNode" ) |
3593 | 0 | { |
3594 | 0 | if( rValue >>= mxAnimationNode ) |
3595 | 0 | return; |
3596 | 0 | } |
3597 | 0 | else if ( rProperty == u"ParentWindow" ) |
3598 | 0 | { |
3599 | 0 | Reference< XWindow > xWindow; |
3600 | 0 | if( rValue >>= xWindow ) |
3601 | 0 | { |
3602 | 0 | mpParentWindow = xWindow.is() ? VCLUnoHelper::GetWindow( xWindow ) |
3603 | 0 | : nullptr; |
3604 | 0 | return; |
3605 | 0 | } |
3606 | 0 | } |
3607 | 0 | else if ( rProperty == u"AllowAnimations" ) |
3608 | 0 | { |
3609 | 0 | if( rValue >>= mbAnimationAllowed ) |
3610 | 0 | return; |
3611 | 0 | } |
3612 | 0 | else if ( rProperty == u"FirstPage" ) |
3613 | 0 | { |
3614 | 0 | OUString aPresPage; |
3615 | 0 | if( rValue >>= aPresPage ) |
3616 | 0 | { |
3617 | 0 | maPresPage = getUiNameFromPageApiNameImpl(aPresPage); |
3618 | 0 | mbCustomShow = false; |
3619 | 0 | mbAll = false; |
3620 | 0 | return; |
3621 | 0 | } |
3622 | 0 | else |
3623 | 0 | { |
3624 | 0 | if( rValue >>= mxStartPage ) |
3625 | 0 | return; |
3626 | 0 | } |
3627 | 0 | } |
3628 | 0 | else if ( rProperty == u"IsAlwaysOnTop" ) |
3629 | 0 | { |
3630 | 0 | if( rValue >>= mbAlwaysOnTop ) |
3631 | 0 | return; |
3632 | 0 | } |
3633 | 0 | else if ( rProperty == u"IsAutomatic" ) |
3634 | 0 | { |
3635 | 0 | if( rValue >>= mbManual ) |
3636 | 0 | return; |
3637 | 0 | } |
3638 | 0 | else if ( rProperty == u"IsEndless" ) |
3639 | 0 | { |
3640 | 0 | if( rValue >>= mbEndless ) |
3641 | 0 | return; |
3642 | 0 | } |
3643 | 0 | else if ( rProperty == u"IsFullScreen" ) |
3644 | 0 | { |
3645 | 0 | if( rValue >>= mbFullScreen ) |
3646 | 0 | return; |
3647 | 0 | } |
3648 | 0 | else if ( rProperty == u"IsMouseVisible" ) |
3649 | 0 | { |
3650 | 0 | if( rValue >>= mbMouseVisible ) |
3651 | 0 | return; |
3652 | 0 | } |
3653 | 0 | else if ( rProperty == u"Pause" ) |
3654 | 0 | { |
3655 | 0 | sal_Int32 nPause = -1; |
3656 | 0 | if( (rValue >>= nPause) && (nPause >= 0) ) |
3657 | 0 | { |
3658 | 0 | mnPauseTimeout = nPause; |
3659 | 0 | return; |
3660 | 0 | } |
3661 | 0 | } |
3662 | 0 | else if ( rProperty == u"UsePen" ) |
3663 | 0 | { |
3664 | 0 | if( rValue >>= mbMouseAsPen ) |
3665 | 0 | return; |
3666 | 0 | } |
3667 | 0 | throw IllegalArgumentException(); |
3668 | 0 | } |
3669 | | |
3670 | | // XAnimationListener |
3671 | | |
3672 | | SlideShowListenerProxy::SlideShowListenerProxy( rtl::Reference< SlideshowImpl > xController, css::uno::Reference< css::presentation::XSlideShow > xSlideShow ) |
3673 | 0 | : mxController(std::move( xController )) |
3674 | 0 | , mxSlideShow(std::move( xSlideShow )) |
3675 | 0 | { |
3676 | 0 | } |
3677 | | |
3678 | | SlideShowListenerProxy::~SlideShowListenerProxy() |
3679 | 0 | { |
3680 | 0 | } |
3681 | | |
3682 | | void SlideShowListenerProxy::addAsSlideShowListener() |
3683 | 0 | { |
3684 | 0 | if( mxSlideShow.is() ) |
3685 | 0 | { |
3686 | 0 | Reference< XSlideShowListener > xSlideShowListener( this ); |
3687 | 0 | mxSlideShow->addSlideShowListener( xSlideShowListener ); |
3688 | 0 | } |
3689 | 0 | } |
3690 | | |
3691 | | void SlideShowListenerProxy::removeAsSlideShowListener() |
3692 | 0 | { |
3693 | 0 | if( mxSlideShow.is() ) |
3694 | 0 | { |
3695 | 0 | Reference< XSlideShowListener > xSlideShowListener( this ); |
3696 | 0 | mxSlideShow->removeSlideShowListener( xSlideShowListener ); |
3697 | 0 | } |
3698 | 0 | } |
3699 | | |
3700 | | void SlideShowListenerProxy::addShapeEventListener( const css::uno::Reference< css::drawing::XShape >& xShape ) |
3701 | 0 | { |
3702 | 0 | if( mxSlideShow.is() ) |
3703 | 0 | { |
3704 | 0 | Reference< XShapeEventListener > xListener( this ); |
3705 | 0 | mxSlideShow->addShapeEventListener( xListener, xShape ); |
3706 | 0 | } |
3707 | 0 | } |
3708 | | |
3709 | | void SlideShowListenerProxy::removeShapeEventListener( const css::uno::Reference< css::drawing::XShape >& xShape ) |
3710 | 0 | { |
3711 | 0 | if( mxSlideShow.is() ) |
3712 | 0 | { |
3713 | 0 | Reference< XShapeEventListener > xListener( this ); |
3714 | 0 | mxSlideShow->removeShapeEventListener( xListener, xShape ); |
3715 | 0 | } |
3716 | 0 | } |
3717 | | |
3718 | | void SlideShowListenerProxy::addSlideShowListener( const css::uno::Reference< css::presentation::XSlideShowListener >& xListener ) |
3719 | 0 | { |
3720 | 0 | std::unique_lock g(m_aMutex); |
3721 | 0 | maListeners.addInterface(g, xListener); |
3722 | 0 | } |
3723 | | |
3724 | | void SlideShowListenerProxy::removeSlideShowListener( const css::uno::Reference< css::presentation::XSlideShowListener >& xListener ) |
3725 | 0 | { |
3726 | 0 | std::unique_lock g(m_aMutex); |
3727 | 0 | maListeners.removeInterface(g, xListener); |
3728 | 0 | } |
3729 | | |
3730 | | void SAL_CALL SlideShowListenerProxy::beginEvent( const Reference< XAnimationNode >& xNode ) |
3731 | 0 | { |
3732 | 0 | std::unique_lock aGuard( m_aMutex ); |
3733 | |
|
3734 | 0 | if( maListeners.getLength(aGuard) >= 0 ) |
3735 | 0 | { |
3736 | 0 | maListeners.forEach(aGuard, |
3737 | 0 | [&] (Reference<XAnimationListener> const& xListener) { |
3738 | 0 | return xListener->beginEvent(xNode); |
3739 | 0 | } ); |
3740 | 0 | } |
3741 | 0 | } |
3742 | | |
3743 | | void SAL_CALL SlideShowListenerProxy::endEvent( const Reference< XAnimationNode >& xNode ) |
3744 | 0 | { |
3745 | 0 | std::unique_lock aGuard( m_aMutex ); |
3746 | |
|
3747 | 0 | if( maListeners.getLength(aGuard) >= 0 ) |
3748 | 0 | { |
3749 | 0 | maListeners.forEach(aGuard, |
3750 | 0 | [&] (Reference<XAnimationListener> const& xListener) { |
3751 | 0 | return xListener->endEvent(xNode); |
3752 | 0 | } ); |
3753 | 0 | } |
3754 | 0 | } |
3755 | | |
3756 | | void SAL_CALL SlideShowListenerProxy::repeat( const Reference< XAnimationNode >& xNode, ::sal_Int32 nRepeat ) |
3757 | 0 | { |
3758 | 0 | std::unique_lock aGuard( m_aMutex ); |
3759 | |
|
3760 | 0 | if( maListeners.getLength(aGuard) >= 0 ) |
3761 | 0 | { |
3762 | 0 | maListeners.forEach(aGuard, |
3763 | 0 | [&] (Reference<XAnimationListener> const& xListener) { |
3764 | 0 | return xListener->repeat(xNode, nRepeat); |
3765 | 0 | } ); |
3766 | 0 | } |
3767 | 0 | } |
3768 | | |
3769 | | // css::presentation::XSlideShowListener: |
3770 | | |
3771 | | void SAL_CALL SlideShowListenerProxy::paused( ) |
3772 | 0 | { |
3773 | 0 | std::unique_lock aGuard( m_aMutex ); |
3774 | |
|
3775 | 0 | maListeners.forEach(aGuard, |
3776 | 0 | [](uno::Reference<presentation::XSlideShowListener> const& xListener) |
3777 | 0 | { |
3778 | 0 | xListener->paused(); |
3779 | 0 | }); |
3780 | 0 | } |
3781 | | |
3782 | | void SAL_CALL SlideShowListenerProxy::resumed( ) |
3783 | 0 | { |
3784 | 0 | std::unique_lock aGuard( m_aMutex ); |
3785 | |
|
3786 | 0 | maListeners.forEach(aGuard, |
3787 | 0 | [](uno::Reference<presentation::XSlideShowListener> const& xListener) |
3788 | 0 | { |
3789 | 0 | xListener->resumed(); |
3790 | 0 | }); |
3791 | 0 | } |
3792 | | |
3793 | | void SAL_CALL SlideShowListenerProxy::slideTransitionStarted( ) |
3794 | 0 | { |
3795 | 0 | std::unique_lock aGuard( m_aMutex ); |
3796 | |
|
3797 | 0 | maListeners.forEach(aGuard, |
3798 | 0 | [](uno::Reference<presentation::XSlideShowListener> const& xListener) |
3799 | 0 | { |
3800 | 0 | xListener->slideTransitionStarted(); |
3801 | 0 | }); |
3802 | 0 | } |
3803 | | |
3804 | | void SAL_CALL SlideShowListenerProxy::slideTransitionEnded( ) |
3805 | 0 | { |
3806 | 0 | std::unique_lock aGuard( m_aMutex ); |
3807 | |
|
3808 | 0 | maListeners.forEach(aGuard, |
3809 | 0 | [](uno::Reference<presentation::XSlideShowListener> const& xListener) |
3810 | 0 | { |
3811 | 0 | xListener->slideTransitionEnded (); |
3812 | 0 | }); |
3813 | 0 | } |
3814 | | |
3815 | | void SAL_CALL SlideShowListenerProxy::slideAnimationsEnded( ) |
3816 | 0 | { |
3817 | 0 | std::unique_lock aGuard( m_aMutex ); |
3818 | |
|
3819 | 0 | maListeners.forEach(aGuard, |
3820 | 0 | [](uno::Reference<presentation::XSlideShowListener> const& xListener) |
3821 | 0 | { |
3822 | 0 | xListener->slideAnimationsEnded (); |
3823 | 0 | }); |
3824 | 0 | } |
3825 | | |
3826 | | void SlideShowListenerProxy::slideEnded(sal_Bool bReverse) |
3827 | 0 | { |
3828 | 0 | { |
3829 | 0 | std::unique_lock aGuard( m_aMutex ); |
3830 | |
|
3831 | 0 | if( maListeners.getLength(aGuard) >= 0 ) |
3832 | 0 | { |
3833 | 0 | maListeners.forEach(aGuard, |
3834 | 0 | [&] (Reference<XSlideShowListener> const& xListener) { |
3835 | 0 | return xListener->slideEnded(bReverse); |
3836 | 0 | } ); |
3837 | 0 | } |
3838 | 0 | } |
3839 | |
|
3840 | 0 | { |
3841 | 0 | SolarMutexGuard aSolarGuard; |
3842 | 0 | if( mxController.is() ) |
3843 | 0 | mxController->slideEnded(bReverse); |
3844 | 0 | } |
3845 | 0 | } |
3846 | | |
3847 | | void SlideShowListenerProxy::hyperLinkClicked( OUString const& aHyperLink ) |
3848 | 0 | { |
3849 | 0 | { |
3850 | 0 | std::unique_lock aGuard( m_aMutex ); |
3851 | |
|
3852 | 0 | if( maListeners.getLength(aGuard) >= 0 ) |
3853 | 0 | { |
3854 | 0 | maListeners.forEach(aGuard, |
3855 | 0 | [&] (Reference<XSlideShowListener> const& xListener) { |
3856 | 0 | return xListener->hyperLinkClicked(aHyperLink); |
3857 | 0 | } ); |
3858 | 0 | } |
3859 | 0 | } |
3860 | |
|
3861 | 0 | { |
3862 | 0 | SolarMutexGuard aSolarGuard; |
3863 | 0 | if( mxController.is() ) |
3864 | 0 | mxController->hyperLinkClicked(aHyperLink); |
3865 | 0 | } |
3866 | 0 | } |
3867 | | |
3868 | | // XEventListener |
3869 | | |
3870 | | void SAL_CALL SlideShowListenerProxy::disposing( const css::lang::EventObject& aDisposeEvent ) |
3871 | 0 | { |
3872 | 0 | std::unique_lock g(m_aMutex); |
3873 | 0 | maListeners.disposeAndClear( g, aDisposeEvent ); |
3874 | 0 | mxController.clear(); |
3875 | 0 | mxSlideShow.clear(); |
3876 | 0 | } |
3877 | | |
3878 | | // XShapeEventListener |
3879 | | |
3880 | | void SAL_CALL SlideShowListenerProxy::click( const Reference< XShape >& xShape, const css::awt::MouseEvent& /*aOriginalEvent*/ ) |
3881 | 0 | { |
3882 | 0 | SolarMutexGuard aSolarGuard; |
3883 | 0 | if( mxController.is() ) |
3884 | 0 | mxController->click(xShape ); |
3885 | 0 | } |
3886 | | |
3887 | | void SAL_CALL SlideShowListenerProxy::contextMenuShow(const css::awt::Point& point) |
3888 | 0 | { |
3889 | 0 | SolarMutexGuard aSolarGuard; |
3890 | 0 | if (mxController.is()) |
3891 | 0 | mxController->contextMenuShow(point); |
3892 | 0 | } |
3893 | | |
3894 | | } // namespace ::sd |
3895 | | |
3896 | | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |