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