Version 6.1.0.2, tag libreoffice-6.1.0.2
[LibreOffice.git] / sd / source / ui / slideshow / slideshowimpl.cxx
blob0ab2165262e3a51efa0892b03cdb0b258be792de
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <config_features.h>
22 #include <com/sun/star/frame/theAutoRecovery.hpp>
23 #include <com/sun/star/lang/XInitialization.hpp>
24 #include <com/sun/star/document/XEventsSupplier.hpp>
25 #include <com/sun/star/drawing/XMasterPageTarget.hpp>
26 #include <com/sun/star/container/XNameReplace.hpp>
27 #include <com/sun/star/beans/PropertyValue.hpp>
28 #include <com/sun/star/beans/XPropertySetInfo.hpp>
29 #include <com/sun/star/beans/XPropertySet.hpp>
30 #include <com/sun/star/awt/SystemPointer.hpp>
31 #include <com/sun/star/util/URLTransformer.hpp>
32 #include <com/sun/star/util/XURLTransformer.hpp>
33 #include <com/sun/star/frame/XDispatch.hpp>
34 #include <com/sun/star/frame/XLayoutManager.hpp>
35 #include <com/sun/star/presentation/SlideShow.hpp>
36 #include <svl/aeitem.hxx>
37 #include <svl/urihelper.hxx>
39 #include <toolkit/helper/vclunohelper.hxx>
41 #include <sfx2/infobar.hxx>
42 #include <sfx2/request.hxx>
43 #include <sfx2/docfile.hxx>
44 #include <sfx2/app.hxx>
45 #include <svx/unoapi.hxx>
46 #include <svx/svdoole2.hxx>
47 #include <sfx2/templdlg.hxx>
48 #include <svx/f3dchild.hxx>
49 #include <svx/imapdlg.hxx>
50 #include <svx/fontwork.hxx>
51 #include <svx/SvxColorChildWindow.hxx>
52 #include <svx/bmpmask.hxx>
53 #include <svx/srchdlg.hxx>
54 #include <svx/hyperdlg.hxx>
55 #include <AnimationChildWindow.hxx>
56 #include <notifydocumentevent.hxx>
57 #include "slideshowimpl.hxx"
58 #include "slideshowviewimpl.hxx"
59 #include <pgjump.hxx>
60 #include "PaneHider.hxx"
62 #include <bitmaps.hlst>
63 #include <vcl/canvastools.hxx>
64 #include <vcl/commandinfoprovider.hxx>
65 #include <vcl/settings.hxx>
67 #include <comphelper/anytostring.hxx>
68 #include <cppuhelper/exc_hlp.hxx>
69 #include <rtl/ref.hxx>
70 #include <canvas/elapsedtime.hxx>
71 #include <avmedia/mediawindow.hxx>
72 #include <svtools/colrdlg.hxx>
73 #include <RemoteServer.hxx>
74 #include <customshowlist.hxx>
75 #include <unopage.hxx>
77 #define CM_SLIDES 21
79 using ::com::sun::star::animations::XAnimationNode;
80 using ::com::sun::star::animations::XAnimationListener;
81 using ::com::sun::star::awt::XWindow;
82 using namespace ::com::sun::star;
83 using namespace ::com::sun::star::lang;
84 using namespace ::com::sun::star::uno;
85 using namespace ::com::sun::star::drawing;
86 using namespace ::com::sun::star::container;
87 using namespace ::com::sun::star::document;
88 using namespace ::com::sun::star::presentation;
89 using namespace ::com::sun::star::beans;
91 namespace sd
93 /** Slots, which will be disabled in the slide show and are managed by Sfx.
94 Have to be sorted in the order of the SIDs */
95 static sal_uInt16 const pAllowed[] =
97 SID_OPENDOC , // 5501 ///< that internally jumps work
98 SID_JUMPTOMARK , // 5598
99 SID_OPENHYPERLINK , // 6676
100 SID_PRESENTATION_END // 27218
103 class AnimationSlideController
105 public:
106 enum Mode { ALL, FROM, CUSTOM, PREVIEW };
108 public:
109 AnimationSlideController( Reference< XIndexAccess > const & xSlides, Mode eMode );
111 void setStartSlideNumber( sal_Int32 nSlideNumber ) { mnStartSlideNumber = nSlideNumber; }
112 sal_Int32 getStartSlideIndex() const;
114 sal_Int32 getCurrentSlideNumber() const;
115 sal_Int32 getCurrentSlideIndex() const;
117 sal_Int32 getSlideIndexCount() const { return maSlideNumbers.size(); }
118 sal_Int32 getSlideNumberCount() const { return mnSlideCount; }
120 sal_Int32 getSlideNumber( sal_Int32 nSlideIndex ) const;
122 void insertSlideNumber( sal_Int32 nSlideNumber, bool bVisible = true );
123 void setPreviewNode( const Reference< XAnimationNode >& xPreviewNode );
125 bool jumpToSlideIndex( sal_Int32 nNewSlideIndex );
126 bool jumpToSlideNumber( sal_Int32 nNewSlideIndex );
128 bool nextSlide();
129 bool previousSlide();
131 void displayCurrentSlide( const Reference< XSlideShow >& xShow,
132 const Reference< XDrawPagesSupplier>& xDrawPages,
133 const bool bSkipAllMainSequenceEffects );
135 sal_Int32 getNextSlideIndex() const;
136 sal_Int32 getPreviousSlideIndex() const;
138 bool isVisibleSlideNumber( sal_Int32 nSlideNumber ) const;
140 Reference< XDrawPage > getSlideByNumber( sal_Int32 nSlideNumber ) const;
142 sal_Int32 getNextSlideNumber() const;
144 bool hasSlides() const { return !maSlideNumbers.empty(); }
146 private:
147 bool getSlideAPI( sal_Int32 nSlideNumber, Reference< XDrawPage >& xSlide, Reference< XAnimationNode >& xAnimNode );
148 sal_Int32 findSlideIndex( sal_Int32 nSlideNumber ) const;
150 bool isValidIndex( sal_Int32 nIndex ) const { return (nIndex >= 0) && (nIndex < static_cast<sal_Int32>(maSlideNumbers.size())); }
151 bool isValidSlideNumber( sal_Int32 nSlideNumber ) const { return (nSlideNumber >= 0) && (nSlideNumber < mnSlideCount); }
153 private:
154 Mode meMode;
155 sal_Int32 mnStartSlideNumber;
156 std::vector< sal_Int32 > maSlideNumbers;
157 std::vector< bool > maSlideVisible;
158 std::vector< bool > maSlideVisited;
159 Reference< XAnimationNode > mxPreviewNode;
160 sal_Int32 mnSlideCount;
161 sal_Int32 mnCurrentSlideIndex;
162 sal_Int32 mnHiddenSlideNumber;
163 Reference< XIndexAccess > mxSlides;
166 Reference< XDrawPage > AnimationSlideController::getSlideByNumber( sal_Int32 nSlideNumber ) const
168 Reference< XDrawPage > xSlide;
169 if( mxSlides.is() && (nSlideNumber >= 0) && (nSlideNumber < mxSlides->getCount()) )
170 mxSlides->getByIndex( nSlideNumber ) >>= xSlide;
171 return xSlide;
174 bool AnimationSlideController::isVisibleSlideNumber( sal_Int32 nSlideNumber ) const
176 sal_Int32 nIndex = findSlideIndex( nSlideNumber );
178 if( nIndex != -1 )
179 return maSlideVisible[ nIndex ];
180 else
181 return false;
184 void AnimationSlideController::setPreviewNode( const Reference< XAnimationNode >& xPreviewNode )
186 mxPreviewNode = xPreviewNode;
189 AnimationSlideController::AnimationSlideController( Reference< XIndexAccess > const & xSlides, Mode eMode )
190 : meMode( eMode )
191 , mnStartSlideNumber(-1)
192 , mnSlideCount( 0 )
193 , mnCurrentSlideIndex(0)
194 , mnHiddenSlideNumber( -1 )
195 , mxSlides( xSlides )
197 if( mxSlides.is() )
198 mnSlideCount = xSlides->getCount();
201 sal_Int32 AnimationSlideController::getStartSlideIndex() const
203 if( mnStartSlideNumber >= 0 )
205 sal_Int32 nIndex;
206 const sal_Int32 nCount = maSlideNumbers.size();
208 for( nIndex = 0; nIndex < nCount; nIndex++ )
210 if( maSlideNumbers[nIndex] == mnStartSlideNumber )
211 return nIndex;
215 return 0;
218 sal_Int32 AnimationSlideController::getCurrentSlideNumber() const
220 if( mnHiddenSlideNumber != -1 )
221 return mnHiddenSlideNumber;
222 else if( !maSlideNumbers.empty() )
223 return maSlideNumbers[mnCurrentSlideIndex];
224 else
225 return 0;
228 sal_Int32 AnimationSlideController::getCurrentSlideIndex() const
230 if( mnHiddenSlideNumber != -1 )
231 return -1;
232 else
233 return mnCurrentSlideIndex;
236 bool AnimationSlideController::jumpToSlideIndex( sal_Int32 nNewSlideIndex )
238 if( isValidIndex( nNewSlideIndex ) )
240 mnCurrentSlideIndex = nNewSlideIndex;
241 mnHiddenSlideNumber = -1;
242 maSlideVisited[mnCurrentSlideIndex] = true;
243 return true;
245 else
247 return false;
251 bool AnimationSlideController::jumpToSlideNumber( sal_Int32 nNewSlideNumber )
253 sal_Int32 nIndex = findSlideIndex( nNewSlideNumber );
254 if( isValidIndex( nIndex ) )
256 return jumpToSlideIndex( nIndex );
258 else if( (nNewSlideNumber >= 0) && (nNewSlideNumber < mnSlideCount) )
260 // jump to a hidden slide
261 mnHiddenSlideNumber = nNewSlideNumber;
262 return true;
264 else
266 return false;
270 sal_Int32 AnimationSlideController::getSlideNumber( sal_Int32 nSlideIndex ) const
272 if( isValidIndex( nSlideIndex ) )
273 return maSlideNumbers[nSlideIndex];
274 else
275 return -1;
278 void AnimationSlideController::insertSlideNumber( sal_Int32 nSlideNumber, bool bVisible /* = true */ )
280 DBG_ASSERT( isValidSlideNumber( nSlideNumber ), "sd::AnimationSlideController::insertSlideNumber(), illegal index" );
281 if( isValidSlideNumber( nSlideNumber ) )
283 maSlideNumbers.push_back( nSlideNumber );
284 maSlideVisible.push_back( bVisible );
285 maSlideVisited.push_back( false );
289 bool AnimationSlideController::getSlideAPI( sal_Int32 nSlideNumber, Reference< XDrawPage >& xSlide, Reference< XAnimationNode >& xAnimNode )
291 if( isValidSlideNumber( nSlideNumber ) ) try
293 xSlide.set( mxSlides->getByIndex(nSlideNumber), UNO_QUERY_THROW );
295 if( meMode == PREVIEW )
297 xAnimNode = mxPreviewNode;
299 else
301 Reference< animations::XAnimationNodeSupplier > xAnimNodeSupplier( xSlide, UNO_QUERY_THROW );
302 xAnimNode = xAnimNodeSupplier->getAnimationNode();
305 return true;
307 catch( Exception& )
309 SAL_WARN( "sd", "sd::AnimationSlideController::getSlideAPI(), "
310 "exception caught: "
311 << comphelper::anyToString( cppu::getCaughtException() ) );
314 return false;
317 sal_Int32 AnimationSlideController::findSlideIndex( sal_Int32 nSlideNumber ) const
319 sal_Int32 nIndex;
320 const sal_Int32 nCount = maSlideNumbers.size();
322 for( nIndex = 0; nIndex < nCount; nIndex++ )
324 if( maSlideNumbers[nIndex] == nSlideNumber )
325 return nIndex;
328 return -1;
331 sal_Int32 AnimationSlideController::getNextSlideIndex() const
333 switch( meMode )
335 case ALL:
337 sal_Int32 nNewSlideIndex = mnCurrentSlideIndex + 1;
338 if( isValidIndex( nNewSlideIndex ) )
340 // if the current slide is not excluded, make sure the
341 // next slide is also not excluded.
342 // if the current slide is excluded, we want to go
343 // to the next slide, even if this is also excluded.
344 if( maSlideVisible[mnCurrentSlideIndex] )
346 while( isValidIndex( nNewSlideIndex ) )
348 if( maSlideVisible[nNewSlideIndex] )
349 break;
351 nNewSlideIndex++;
355 return isValidIndex( nNewSlideIndex ) ? nNewSlideIndex : -1;
358 case FROM:
359 case CUSTOM:
360 return mnHiddenSlideNumber == -1 ? mnCurrentSlideIndex + 1 : mnCurrentSlideIndex;
362 default:
363 case PREVIEW:
364 return -1;
369 sal_Int32 AnimationSlideController::getNextSlideNumber() const
371 sal_Int32 nNextSlideIndex = getNextSlideIndex();
372 if( isValidIndex( nNextSlideIndex ) )
374 return maSlideNumbers[nNextSlideIndex];
376 else
378 return -1;
382 bool AnimationSlideController::nextSlide()
384 return jumpToSlideIndex( getNextSlideIndex() );
387 sal_Int32 AnimationSlideController::getPreviousSlideIndex() const
389 sal_Int32 nNewSlideIndex = mnCurrentSlideIndex - 1;
391 switch( meMode )
393 case ALL:
395 // make sure the previous slide is visible
396 // or was already visited
397 while( isValidIndex( nNewSlideIndex ) )
399 if( maSlideVisible[nNewSlideIndex] || maSlideVisited[nNewSlideIndex] )
400 break;
402 nNewSlideIndex--;
405 break;
408 case PREVIEW:
409 return -1;
411 default:
412 break;
415 return nNewSlideIndex;
418 bool AnimationSlideController::previousSlide()
420 return jumpToSlideIndex( getPreviousSlideIndex() );
423 void AnimationSlideController::displayCurrentSlide( const Reference< XSlideShow >& xShow,
424 const Reference< XDrawPagesSupplier>& xDrawPages,
425 const bool bSkipAllMainSequenceEffects )
427 const sal_Int32 nCurrentSlideNumber = getCurrentSlideNumber();
429 if( xShow.is() && (nCurrentSlideNumber != -1 ) )
431 Reference< XDrawPage > xSlide;
432 Reference< XAnimationNode > xAnimNode;
433 ::std::vector<PropertyValue> aProperties;
435 const sal_Int32 nNextSlideNumber = getNextSlideNumber();
436 if( getSlideAPI( nNextSlideNumber, xSlide, xAnimNode ) )
438 Sequence< Any > aValue(2);
439 aValue[0] <<= xSlide;
440 aValue[1] <<= xAnimNode;
441 aProperties.emplace_back( "Prefetch" ,
443 Any(aValue),
444 PropertyState_DIRECT_VALUE);
446 if (bSkipAllMainSequenceEffects)
448 // Add one property that prevents the slide transition from being
449 // shown (to speed up the transition to the previous slide) and
450 // one to show all main sequence effects so that the user can
451 // continue to undo effects.
452 aProperties.emplace_back( "SkipAllMainSequenceEffects",
454 Any(true),
455 PropertyState_DIRECT_VALUE);
456 aProperties.emplace_back("SkipSlideTransition",
458 Any(true),
459 PropertyState_DIRECT_VALUE);
462 if( getSlideAPI( nCurrentSlideNumber, xSlide, xAnimNode ) )
463 xShow->displaySlide( xSlide, xDrawPages, xAnimNode, comphelper::containerToSequence(aProperties) );
467 SlideshowImpl::SlideshowImpl( const Reference< XPresentation2 >& xPresentation, ViewShell* pViewSh, ::sd::View* pView, SdDrawDocument* pDoc, vcl::Window* pParentWindow )
468 : SlideshowImplBase( m_aMutex )
469 , mxModel(pDoc->getUnoModel(),UNO_QUERY_THROW)
470 , mpView(pView)
471 , mpViewShell(pViewSh)
472 , mpDocSh(pDoc->GetDocSh())
473 , mpDoc(pDoc)
474 , mpParentWindow(pParentWindow)
475 , mpShowWindow(nullptr)
476 , mpTimeButton(nullptr)
477 , mnRestoreSlide(0)
478 , maPresSize( -1, -1 )
479 , meAnimationMode(ANIMATIONMODE_SHOW)
480 , mpOldActiveWindow(nullptr)
481 , mnChildMask( 0 )
482 , mbDisposed(false)
483 , mbAutoSaveWasOn(false)
484 , mbRehearseTimings(false)
485 , mbIsPaused(false)
486 , mbWasPaused(false)
487 , mbInputFreeze(false)
488 , mbActive(false)
489 , maPresSettings( pDoc->getPresentationSettings() )
490 , mnUserPaintColor( 0x80ff0000L )
491 , mbUsePen(false)
492 , mdUserPaintStrokeWidth ( 150.0 )
493 , msOnClick( "OnClick" )
494 , msBookmark( "Bookmark" )
495 , msVerb( "Verb" )
496 , mnEndShowEvent(nullptr)
497 , mnContextMenuEvent(nullptr)
498 , mxPresentation( xPresentation )
500 if( mpViewShell )
501 mpOldActiveWindow = mpViewShell->GetActiveWindow();
503 maUpdateTimer.SetInvokeHandler(LINK(this, SlideshowImpl, updateHdl));
504 // Priority must not be too high or we'll starve input handling etc.
505 maUpdateTimer.SetPriority(TaskPriority::REPAINT);
507 maDeactivateTimer.SetInvokeHandler(LINK(this, SlideshowImpl, deactivateHdl));
508 maDeactivateTimer.SetTimeout( 20 );
510 maInputFreezeTimer.SetInvokeHandler( LINK( this, SlideshowImpl, ReadyForNextInputHdl ) );
511 maInputFreezeTimer.SetTimeout( 20 );
513 SvtSaveOptions aOptions;
515 // no autosave during show
516 if( aOptions.IsAutoSave() )
517 mbAutoSaveWasOn = true;
519 Application::AddEventListener( LINK( this, SlideshowImpl, EventListenerHdl ) );
521 mbUsePen = maPresSettings.mbMouseAsPen;
523 SdOptions* pOptions = SD_MOD()->GetSdOptions(DocumentType::Impress);
524 if( pOptions )
526 mnUserPaintColor = pOptions->GetPresentationPenColor();
527 mdUserPaintStrokeWidth = pOptions->GetPresentationPenWidth();
531 SlideshowImpl::~SlideshowImpl()
533 SdModule *pModule = SD_MOD();
534 //rhbz#806663 SlideshowImpl can outlive SdModule
535 SdOptions* pOptions = pModule ?
536 pModule->GetSdOptions(DocumentType::Impress) : nullptr;
537 if( pOptions )
539 pOptions->SetPresentationPenColor(mnUserPaintColor);
540 pOptions->SetPresentationPenWidth(mdUserPaintStrokeWidth);
543 Application::RemoveEventListener( LINK( this, SlideshowImpl, EventListenerHdl ) );
545 maDeactivateTimer.Stop();
547 if( !mbDisposed )
549 OSL_FAIL("SlideshowImpl::~SlideshowImpl(), component was not disposed!");
550 disposing();
554 void SAL_CALL SlideshowImpl::disposing()
556 #ifdef ENABLE_SDREMOTE
557 RemoteServer::presentationStopped();
558 #endif
559 if( mxShow.is() && mpDoc )
560 NotifyDocumentEvent(
561 *mpDoc,
562 "OnEndPresentation" );
564 if( mbAutoSaveWasOn )
565 setAutoSaveState( true );
567 if( mnEndShowEvent )
568 Application::RemoveUserEvent( mnEndShowEvent );
569 if( mnContextMenuEvent )
570 Application::RemoveUserEvent( mnContextMenuEvent );
572 maInputFreezeTimer.Stop();
574 SolarMutexGuard aSolarGuard;
576 if( !mxShow.is() )
577 return;
579 if( mxPresentation.is() )
580 mxPresentation->end();
582 maUpdateTimer.Stop();
584 removeShapeEvents();
586 if( mxListenerProxy.is() )
587 mxListenerProxy->removeAsSlideShowListener();
591 if( mxView.is() )
592 mxShow->removeView( mxView.get() );
594 Reference< XComponent > xComponent( mxShow, UNO_QUERY );
595 if( xComponent.is() )
596 xComponent->dispose();
598 if( mxView.is() )
599 mxView->dispose();
601 catch( Exception& )
603 SAL_WARN( "sd", "sd::SlideshowImpl::stop(), exception caught: "
604 << comphelper::anyToString( cppu::getCaughtException() ) );
607 mxShow.clear();
608 mxView.clear();
609 mxListenerProxy.clear();
610 mpSlideController.reset();
612 // take DrawView from presentation window, but give the old window back
613 if( mpShowWindow && mpView )
614 mpView->DeleteWindowFromPaintView( mpShowWindow );
616 if( mpView )
617 mpView->SetAnimationPause( false );
619 if( mpViewShell )
621 mpViewShell->SetActiveWindow(mpOldActiveWindow);
622 if (mpShowWindow)
623 mpShowWindow->SetViewShell( nullptr );
626 if( mpView )
627 mpView->InvalidateAllWin();
629 if( maPresSettings.mbFullScreen )
631 #if HAVE_FEATURE_SCRIPTING
632 // restore StarBASICErrorHdl
633 StarBASIC::SetGlobalErrorHdl(maStarBASICGlobalErrorHdl);
634 maStarBASICGlobalErrorHdl = Link<StarBASIC*,bool>();
635 #endif
637 else
639 if( mpShowWindow )
640 mpShowWindow->Hide();
643 if( meAnimationMode == ANIMATIONMODE_SHOW )
645 mpDocSh->SetSlotFilter();
646 mpDocSh->ApplySlotFilter();
648 Help::EnableContextHelp();
649 Help::EnableExtHelp();
651 showChildWindows();
652 mnChildMask = 0;
655 // show current window again
656 if( mpViewShell && dynamic_cast< PresentationViewShell *>( mpViewShell ) == nullptr)
658 if( meAnimationMode == ANIMATIONMODE_SHOW )
660 mpViewShell->GetViewShellBase().ShowUIControls (true);
661 mpPaneHider.reset();
663 else if( meAnimationMode == ANIMATIONMODE_PREVIEW )
665 mpViewShell->ShowUIControls(true);
669 if( mpTimeButton )
670 mpTimeButton->Hide();
671 mpTimeButton.disposeAndClear();
673 if( mpShowWindow )
674 mpShowWindow->Hide();
675 mpShowWindow.disposeAndClear();
677 if ( mpViewShell )
679 if( meAnimationMode == ANIMATIONMODE_SHOW )
681 ::sd::Window* pActWin = mpViewShell->GetActiveWindow();
683 if (pActWin)
685 Size aVisSizePixel = pActWin->GetOutputSizePixel();
686 ::tools::Rectangle aVisAreaWin = pActWin->PixelToLogic( ::tools::Rectangle( Point(0,0), aVisSizePixel) );
687 mpViewShell->VisAreaChanged(aVisAreaWin);
688 if (mpView)
689 mpView->VisAreaChanged(pActWin);
690 pActWin->GrabFocus();
694 // restart the custom show dialog if he started us
695 if( mpViewShell->IsStartShowWithDialog() && getDispatcher() )
697 mpViewShell->SetStartShowWithDialog( false );
698 getDispatcher()->Execute( SID_CUSTOMSHOW_DLG, SfxCallMode::ASYNCHRON | SfxCallMode::RECORD );
701 mpViewShell->GetViewShellBase().UpdateBorder(true);
704 if( mpShowWindow )
706 mpShowWindow.disposeAndClear();
709 setActiveXToolbarsVisible( true );
711 mbDisposed = true;
714 bool SlideshowImpl::startPreview(
715 const Reference< XDrawPage >& xDrawPage,
716 const Reference< XAnimationNode >& xAnimationNode,
717 vcl::Window * pParent )
719 bool bRet = false;
723 const Reference<lang::XServiceInfo> xServiceInfo( xDrawPage, UNO_QUERY );
724 if (xServiceInfo.is()) {
725 const Sequence<OUString> supportedServices(
726 xServiceInfo->getSupportedServiceNames() );
727 for ( sal_Int32 pos = supportedServices.getLength(); pos--; ) {
728 if ( supportedServices[pos] == "com.sun.star.drawing.MasterPage" ) {
729 OSL_FAIL("sd::SlideshowImpl::startPreview() "
730 "not allowed on master page!");
731 return false;
736 mxPreviewDrawPage = xDrawPage;
737 mxPreviewAnimationNode = xAnimationNode;
738 meAnimationMode = ANIMATIONMODE_PREVIEW;
740 maPresSettings.mbAll = false;
741 maPresSettings.mbEndless = false;
742 maPresSettings.mbCustomShow = false;
743 maPresSettings.mbManual = false;
744 maPresSettings.mbMouseVisible = false;
745 maPresSettings.mbMouseAsPen = false;
746 maPresSettings.mbLockedPages = false;
747 maPresSettings.mbAlwaysOnTop = false;
748 maPresSettings.mbFullScreen = false;
749 maPresSettings.mbAnimationAllowed = true;
750 maPresSettings.mnPauseTimeout = 0;
751 maPresSettings.mbShowPauseLogo = false;
753 Reference< XDrawPagesSupplier > xDrawPages( mpDoc->getUnoModel(), UNO_QUERY_THROW );
754 Reference< XIndexAccess > xSlides( xDrawPages->getDrawPages(), UNO_QUERY_THROW );
755 mpSlideController.reset( new AnimationSlideController( xSlides, AnimationSlideController::PREVIEW ) );
757 sal_Int32 nSlideNumber = 0;
758 Reference< XPropertySet > xSet( mxPreviewDrawPage, UNO_QUERY_THROW );
759 xSet->getPropertyValue( "Number" ) >>= nSlideNumber;
760 mpSlideController->insertSlideNumber( nSlideNumber-1 );
761 mpSlideController->setPreviewNode( xAnimationNode );
763 mpShowWindow = VclPtr<ShowWindow>::Create( this, ((pParent == nullptr) && mpViewShell) ? mpParentWindow.get() : pParent );
764 if( mpViewShell )
766 mpViewShell->SetActiveWindow( mpShowWindow );
767 mpShowWindow->SetViewShell (mpViewShell);
768 mpViewShell->ShowUIControls (false);
771 if( mpView )
773 mpView->AddWindowToPaintView( mpShowWindow, nullptr );
774 mpView->SetAnimationPause( true );
777 // call resize handler
778 if( pParent )
780 maPresSize = pParent->GetSizePixel();
782 else if( mpViewShell )
784 ::tools::Rectangle aContentRect (mpViewShell->GetViewShellBase().getClientRectangle());
785 if (AllSettings::GetLayoutRTL())
787 aContentRect.SetLeft( aContentRect.Right() );
788 aContentRect.AdjustRight(aContentRect.Right() );
790 maPresSize = aContentRect.GetSize();
791 mpShowWindow->SetPosPixel( aContentRect.TopLeft() );
793 else
795 OSL_FAIL("sd::SlideshowImpl::startPreview(), I need either a parent window or a viewshell!");
797 resize( maPresSize );
799 sal_Int32 nPropertyCount = 1;
800 if( mxPreviewAnimationNode.is() )
801 nPropertyCount++;
803 Sequence< beans::PropertyValue > aProperties(nPropertyCount);
804 aProperties[0].Name = "AutomaticAdvancement";
805 aProperties[0].Value <<= 1.0; // one second timeout
807 if( mxPreviewAnimationNode.is() )
809 aProperties[1].Name = "NoSlideTransitions";
810 aProperties[1].Value <<= true;
813 bRet = startShowImpl( aProperties );
815 if( mpShowWindow != nullptr && meAnimationMode == ANIMATIONMODE_PREVIEW )
816 mpShowWindow->SetPreviewMode();
819 catch( Exception& )
821 SAL_WARN( "sd", "sd::SlideshowImpl::startPreview(), exception caught: "
822 << comphelper::anyToString( cppu::getCaughtException() ) );
823 bRet = false;
826 return bRet;
829 bool SlideshowImpl::startShow( PresentationSettingsEx const * pPresSettings )
831 const rtl::Reference<SlideshowImpl> this_(this);
833 DBG_ASSERT( !mxShow.is(), "sd::SlideshowImpl::startShow(), called twice!" );
834 if( mxShow.is() )
835 return true;
836 DBG_ASSERT( mpParentWindow!=nullptr, "sd::SlideshowImpl::startShow() called without parent window" );
837 if (mpParentWindow == nullptr)
838 return false;
840 // Autoplay (pps/ppsx)
841 if (mpViewShell->GetDoc()->IsStartWithPresentation()){
842 mpViewShell->GetDoc()->SetExitAfterPresenting(true);
845 bool bRet = false;
849 if( pPresSettings )
851 maPresSettings = *pPresSettings;
852 mbRehearseTimings = pPresSettings->mbRehearseTimings;
855 OUString aPresSlide( maPresSettings.maPresPage );
856 SdPage* pStartPage = mpViewShell->GetActualPage();
857 bool bStartWithActualSlide = pStartPage;
859 // times should be measured?
860 if( mbRehearseTimings )
862 maPresSettings.mbEndless = false;
863 maPresSettings.mbManual = true;
864 maPresSettings.mbMouseVisible = true;
865 maPresSettings.mbMouseAsPen = false;
866 maPresSettings.mnPauseTimeout = 0;
867 maPresSettings.mbShowPauseLogo = false;
870 if( pStartPage )
872 if( pStartPage->GetPageKind() == PageKind::Notes )
874 // we are in notes page mode, so get
875 // the corresponding draw page
876 const sal_uInt16 nPgNum = ( pStartPage->GetPageNum() - 2 ) >> 1;
877 pStartPage = mpDoc->GetSdPage( nPgNum, PageKind::Standard );
881 if( bStartWithActualSlide )
883 if ( aPresSlide.isEmpty())
885 // no preset slide yet, so pick current on one
886 aPresSlide = pStartPage->GetName();
887 // if the starting slide is hidden, we can't set slide controller to ALL mode
888 maPresSettings.mbAll = !pStartPage->IsExcluded();
891 if( meAnimationMode != ANIMATIONMODE_SHOW )
893 if( pStartPage->GetPageKind() == PageKind::Standard )
895 maPresSettings.mbAll = false;
900 // build page list
901 createSlideList( maPresSettings.mbAll, aPresSlide );
903 // remember Slide number from where the show was started
904 if( pStartPage )
905 mnRestoreSlide = ( pStartPage->GetPageNum() - 1 ) / 2;
907 if( mpSlideController->hasSlides() )
909 // hide child windows
910 hideChildWindows();
912 mpShowWindow = VclPtr<ShowWindow>::Create( this, mpParentWindow );
913 mpShowWindow->SetMouseAutoHide( !maPresSettings.mbMouseVisible );
914 mpViewShell->SetActiveWindow( mpShowWindow );
915 mpShowWindow->SetViewShell (mpViewShell);
916 mpViewShell->GetViewShellBase().ShowUIControls (false);
917 // Hide the side panes for in-place presentations.
918 if ( ! maPresSettings.mbFullScreen)
919 mpPaneHider.reset(new PaneHider(*mpViewShell,this));
921 // these Slots are forbidden in other views for this document
922 if( mpDocSh )
924 mpDocSh->SetSlotFilter( true, pAllowed );
925 mpDocSh->ApplySlotFilter();
928 Help::DisableContextHelp();
929 Help::DisableExtHelp();
931 if( maPresSettings.mbFullScreen )
933 #if HAVE_FEATURE_SCRIPTING
934 // disable basic ide error handling
935 maStarBASICGlobalErrorHdl = StarBASIC::GetGlobalErrorHdl();
936 StarBASIC::SetGlobalErrorHdl( Link<StarBASIC*,bool>() );
937 #endif
940 // call resize handler
941 maPresSize = mpParentWindow->GetSizePixel();
942 if (!maPresSettings.mbFullScreen)
944 const ::tools::Rectangle& aClientRect = mpViewShell->GetViewShellBase().getClientRectangle();
945 maPresSize = aClientRect.GetSize();
946 mpShowWindow->SetPosPixel( aClientRect.TopLeft() );
947 resize( maPresSize );
950 // #i41824#
951 // Note: In FullScreen Mode the OS (window manager) sends a resize to
952 // the WorkWindow once it actually resized it to full size. The
953 // WorkWindow propagates the resize to the DrawViewShell which calls
954 // resize() at the SlideShow (this). Calling resize here results in a
955 // temporary display of a black window in the window's default size
957 if( mpView )
959 mpView->AddWindowToPaintView( mpShowWindow, nullptr );
960 mpView->SetAnimationPause( true );
963 SfxBindings* pBindings = getBindings();
964 if( pBindings )
966 pBindings->Invalidate( SID_PRESENTATION );
967 pBindings->Invalidate( SID_REHEARSE_TIMINGS );
970 // Defer the sd::ShowWindow's GrabFocus to SlideShow::activate. so that the accessible event can be fired correctly.
971 //mpShowWindow->GrabFocus();
973 std::vector<beans::PropertyValue> aProperties;
974 aProperties.reserve( 4 );
976 aProperties.emplace_back( "AdvanceOnClick" ,
977 -1, Any( !maPresSettings.mbLockedPages ),
978 beans::PropertyState_DIRECT_VALUE );
980 aProperties.emplace_back( "ImageAnimationsAllowed" ,
981 -1, Any( maPresSettings.mbAnimationAllowed ),
982 beans::PropertyState_DIRECT_VALUE );
984 const bool bZOrderEnabled(
985 SD_MOD()->GetSdOptions( mpDoc->GetDocumentType() )->IsSlideshowRespectZOrder() );
986 aProperties.emplace_back( "DisableAnimationZOrder" ,
987 -1, Any( !bZOrderEnabled ),
988 beans::PropertyState_DIRECT_VALUE );
990 aProperties.emplace_back( "ForceManualAdvance" ,
991 -1, Any( maPresSettings.mbManual ),
992 beans::PropertyState_DIRECT_VALUE );
994 if( mbUsePen )
996 aProperties.emplace_back( "UserPaintColor" ,
997 // User paint color is black by default.
998 -1, Any( mnUserPaintColor ),
999 beans::PropertyState_DIRECT_VALUE );
1001 aProperties.emplace_back( "UserPaintStrokeWidth" ,
1002 // User paint color is black by default.
1003 -1, Any( mdUserPaintStrokeWidth ),
1004 beans::PropertyState_DIRECT_VALUE );
1007 if (mbRehearseTimings) {
1008 aProperties.emplace_back( "RehearseTimings" ,
1009 -1, Any(true), beans::PropertyState_DIRECT_VALUE );
1012 bRet = startShowImpl( Sequence<beans::PropertyValue>(
1013 &aProperties[0], aProperties.size() ) );
1017 setActiveXToolbarsVisible( false );
1019 catch (const Exception&)
1021 SAL_WARN( "sd", "sd::SlideshowImpl::startShow(), exception caught: "
1022 << comphelper::anyToString( cppu::getCaughtException() ) );
1023 bRet = false;
1026 return bRet;
1029 bool SlideshowImpl::startShowImpl( const Sequence< beans::PropertyValue >& aProperties )
1033 mxShow.set( createSlideShow(), UNO_QUERY_THROW );
1035 mxView = new SlideShowView(
1036 *mpShowWindow,
1037 mpDoc,
1038 meAnimationMode,
1039 this,
1040 maPresSettings.mbFullScreen);
1042 // try add wait symbol to properties:
1043 const Reference<rendering::XSpriteCanvas> xSpriteCanvas(
1044 mxView->getCanvas() );
1045 if (xSpriteCanvas.is())
1047 BitmapEx waitSymbolBitmap(BMP_WAIT_ICON);
1048 const Reference<rendering::XBitmap> xBitmap(
1049 vcl::unotools::xBitmapFromBitmapEx( waitSymbolBitmap ) );
1050 if (xBitmap.is())
1052 mxShow->setProperty(
1053 beans::PropertyValue( "WaitSymbolBitmap" ,
1055 makeAny( xBitmap ),
1056 beans::PropertyState_DIRECT_VALUE ) );
1059 BitmapEx pointerSymbolBitmap(BMP_POINTER_ICON);
1060 const Reference<rendering::XBitmap> xPointerBitmap(
1061 vcl::unotools::xBitmapFromBitmapEx( pointerSymbolBitmap ) );
1062 if (xPointerBitmap.is())
1064 mxShow->setProperty(
1065 beans::PropertyValue( "PointerSymbolBitmap" ,
1067 makeAny( xPointerBitmap ),
1068 beans::PropertyState_DIRECT_VALUE ) );
1072 const sal_Int32 nCount = aProperties.getLength();
1073 sal_Int32 nIndex;
1074 for( nIndex = 0; nIndex < nCount; nIndex++ )
1075 mxShow->setProperty( aProperties[nIndex] );
1077 mxShow->addView( mxView.get() );
1079 mxListenerProxy.set( new SlideShowListenerProxy( this, mxShow ) );
1080 mxListenerProxy->addAsSlideShowListener();
1082 NotifyDocumentEvent(
1083 *mpDoc,
1084 "OnStartPresentation");
1085 displaySlideIndex( mpSlideController->getStartSlideIndex() );
1087 return true;
1089 catch( Exception& )
1091 SAL_WARN( "sd", "sd::SlideshowImpl::startShowImpl(), exception caught: "
1092 << comphelper::anyToString( cppu::getCaughtException() ) );
1093 return false;
1097 /** called only by the slideshow view when the first paint event occurs.
1098 This actually starts the slideshow. */
1099 void SlideshowImpl::onFirstPaint()
1101 if( mpShowWindow )
1104 mpShowWindow->SetBackground( Wallpaper( COL_BLACK ) );
1105 mpShowWindow->Erase();
1106 mpShowWindow->SetBackground();
1110 SolarMutexGuard aSolarGuard;
1111 maUpdateTimer.SetTimeout( sal_uLong(100) );
1112 maUpdateTimer.Start();
1115 void SlideshowImpl::paint()
1117 if( mxView.is() ) try
1119 awt::PaintEvent aEvt;
1120 // aEvt.UpdateRect = TODO
1121 mxView->paint( aEvt );
1123 catch( Exception& )
1125 SAL_WARN( "sd", "sd::SlideshowImpl::paint(), exception caught: "
1126 << comphelper::anyToString( cppu::getCaughtException() ) );
1130 void SAL_CALL SlideshowImpl::addSlideShowListener( const Reference< XSlideShowListener >& xListener )
1132 if( mxListenerProxy.is() )
1133 mxListenerProxy->addSlideShowListener( xListener );
1136 void SAL_CALL SlideshowImpl::removeSlideShowListener( const Reference< XSlideShowListener >& xListener )
1138 if( mxListenerProxy.is() )
1139 mxListenerProxy->removeSlideShowListener( xListener );
1142 void SlideshowImpl::slideEnded(const bool bReverse)
1144 if (bReverse)
1145 gotoPreviousSlide(true);
1146 else
1147 gotoNextSlide();
1150 bool SlideshowImpl::swipe(const CommandSwipeData &rSwipeData)
1152 if (mbUsePen || mnContextMenuEvent)
1153 return false;
1154 double nVelocityX = rSwipeData.getVelocityX();
1155 // tdf#108475 make it swipe only if some reasonable movement was involved
1156 if (fabs(nVelocityX) < 50)
1157 return false;
1158 if (nVelocityX > 0)
1160 gotoPreviousSlide();
1162 else
1164 gotoNextEffect();
1166 //a swipe is followed by a mouse up, tell the view to ignore that mouse up as we've reacted
1167 //to the swipe instead
1168 mxView->ignoreNextMouseReleased();
1169 return true;
1172 bool SlideshowImpl::longpress(const CommandLongPressData &rLongPressData)
1174 if (mnContextMenuEvent)
1175 return false;
1177 maPopupMousePos = Point(rLongPressData.getX(), rLongPressData.getY());
1178 mnContextMenuEvent = Application::PostUserEvent( LINK( this, SlideshowImpl, ContextMenuHdl ) );
1180 return true;
1183 void SlideshowImpl::removeShapeEvents()
1185 if( mxShow.is() && mxListenerProxy.is() ) try
1187 WrappedShapeEventImplMap::iterator aIter;
1188 const WrappedShapeEventImplMap::iterator aEnd( maShapeEventMap.end() );
1190 for( aIter = maShapeEventMap.begin(); aIter != aEnd; ++aIter )
1192 mxListenerProxy->removeShapeEventListener( (*aIter).first );
1193 mxShow->setShapeCursor( (*aIter).first, awt::SystemPointer::ARROW );
1196 maShapeEventMap.clear();
1198 catch( Exception& )
1200 SAL_WARN( "sd", "sd::SlideshowImpl::removeShapeEvents(), exception caught: "
1201 << comphelper::anyToString( cppu::getCaughtException() ) );
1205 void SlideshowImpl::registerShapeEvents(sal_Int32 nSlideNumber)
1207 if( nSlideNumber >= 0 ) try
1209 Reference< XDrawPagesSupplier > xDrawPages( mxModel, UNO_QUERY_THROW );
1210 Reference< XIndexAccess > xPages( xDrawPages->getDrawPages(), UNO_QUERY_THROW );
1212 Reference< XShapes > xDrawPage;
1213 xPages->getByIndex(nSlideNumber) >>= xDrawPage;
1215 if( xDrawPage.is() )
1217 Reference< XMasterPageTarget > xMasterPageTarget( xDrawPage, UNO_QUERY );
1218 if( xMasterPageTarget.is() )
1220 Reference< XShapes > xMasterPage( xMasterPageTarget->getMasterPage(), UNO_QUERY );
1221 if( xMasterPage.is() )
1222 registerShapeEvents( xMasterPage );
1224 registerShapeEvents( xDrawPage );
1227 catch( Exception& )
1229 SAL_WARN( "sd", "sd::SlideshowImpl::registerShapeEvents(), exception caught: "
1230 << comphelper::anyToString( cppu::getCaughtException() ) );
1234 void SlideshowImpl::registerShapeEvents( Reference< XShapes > const & xShapes )
1238 const sal_Int32 nShapeCount = xShapes->getCount();
1239 sal_Int32 nShape;
1240 for( nShape = 0; nShape < nShapeCount; nShape++ )
1242 Reference< XShape > xShape;
1243 xShapes->getByIndex( nShape ) >>= xShape;
1245 if( xShape.is() && xShape->getShapeType() == "com.sun.star.drawing.GroupShape" )
1247 Reference< XShapes > xSubShapes( xShape, UNO_QUERY );
1248 if( xSubShapes.is() )
1249 registerShapeEvents( xSubShapes );
1252 Reference< XPropertySet > xSet( xShape, UNO_QUERY );
1253 if( !xSet.is() )
1254 continue;
1256 Reference< XPropertySetInfo > xSetInfo( xSet->getPropertySetInfo() );
1257 if( !xSetInfo.is() || !xSetInfo->hasPropertyByName( msOnClick ) )
1258 continue;
1260 WrappedShapeEventImplPtr pEvent( new WrappedShapeEventImpl );
1261 xSet->getPropertyValue( msOnClick ) >>= pEvent->meClickAction;
1263 switch( pEvent->meClickAction )
1265 case ClickAction_PREVPAGE:
1266 case ClickAction_NEXTPAGE:
1267 case ClickAction_FIRSTPAGE:
1268 case ClickAction_LASTPAGE:
1269 case ClickAction_STOPPRESENTATION:
1270 break;
1271 case ClickAction_BOOKMARK:
1272 if( xSetInfo->hasPropertyByName( msBookmark ) )
1273 xSet->getPropertyValue( msBookmark ) >>= pEvent->maStrBookmark;
1274 if( getSlideNumberForBookmark( pEvent->maStrBookmark ) == -1 )
1275 continue;
1276 break;
1277 case ClickAction_DOCUMENT:
1278 case ClickAction_SOUND:
1279 case ClickAction_PROGRAM:
1280 case ClickAction_MACRO:
1281 if( xSetInfo->hasPropertyByName( msBookmark ) )
1282 xSet->getPropertyValue( msBookmark ) >>= pEvent->maStrBookmark;
1283 break;
1284 case ClickAction_VERB:
1285 if( xSetInfo->hasPropertyByName( msVerb ) )
1286 xSet->getPropertyValue( msVerb ) >>= pEvent->mnVerb;
1287 break;
1288 default:
1289 continue; // skip all others
1292 maShapeEventMap[ xShape ] = pEvent;
1294 if( mxListenerProxy.is() )
1295 mxListenerProxy->addShapeEventListener( xShape );
1296 mxShow->setShapeCursor( xShape, awt::SystemPointer::REFHAND );
1299 catch( Exception& )
1301 SAL_WARN( "sd", "sd::SlideshowImpl::registerShapeEvents(), exception caught: "
1302 << comphelper::anyToString( cppu::getCaughtException() ) );
1306 void SlideshowImpl::displayCurrentSlide (const bool bSkipAllMainSequenceEffects)
1308 stopSound();
1309 removeShapeEvents();
1311 if( mpSlideController.get() && mxShow.is() )
1313 Reference< XDrawPagesSupplier > xDrawPages( mpDoc->getUnoModel(),
1314 UNO_QUERY_THROW );
1315 mpSlideController->displayCurrentSlide( mxShow, xDrawPages, bSkipAllMainSequenceEffects );
1316 registerShapeEvents(mpSlideController->getCurrentSlideNumber());
1317 update();
1320 // send out page change event and notify to update all acc info for current page
1321 if (mpViewShell)
1323 sal_Int32 currentPageIndex = getCurrentSlideIndex();
1324 mpViewShell->fireSwitchCurrentPage(currentPageIndex);
1325 mpViewShell->NotifyAccUpdate();
1329 void SlideshowImpl::endPresentation()
1331 if( maPresSettings.mbMouseAsPen)
1333 Reference< XMultiServiceFactory > xDocFactory(mpDoc->getUnoModel(), UNO_QUERY );
1334 if( xDocFactory.is() )
1335 mxShow->registerUserPaintPolygons(xDocFactory);
1338 if( !mnEndShowEvent )
1339 mnEndShowEvent = Application::PostUserEvent( LINK(this, SlideshowImpl, endPresentationHdl) );
1342 IMPL_LINK_NOARG(SlideshowImpl, endPresentationHdl, void*, void)
1344 mnEndShowEvent = nullptr;
1346 if( mxPresentation.is() )
1347 mxPresentation->end();
1350 void SAL_CALL SlideshowImpl::pause()
1352 SolarMutexGuard aSolarGuard;
1354 if( !mbIsPaused ) try
1356 mbIsPaused = true;
1357 if( mxShow.is() )
1359 mxShow->pause(true);
1361 if( mxListenerProxy.is() )
1362 mxListenerProxy->paused();
1365 catch( Exception& )
1367 SAL_WARN( "sd", "sd::SlideshowImpl::pause(), exception caught: "
1368 << comphelper::anyToString( cppu::getCaughtException() ) );
1372 void SAL_CALL SlideshowImpl::resume()
1374 SolarMutexGuard aSolarGuard;
1376 if( mbIsPaused ) try
1378 if( mpShowWindow->GetShowWindowMode() == SHOWWINDOWMODE_BLANK )
1380 mpShowWindow->RestartShow();
1382 else
1384 mbIsPaused = false;
1385 if( mxShow.is() )
1387 mxShow->pause(false);
1388 update();
1390 if( mxListenerProxy.is() )
1391 mxListenerProxy->resumed();
1395 catch( Exception& )
1397 SAL_WARN( "sd", "sd::SlideshowImpl::resume(), exception caught: "
1398 << comphelper::anyToString( cppu::getCaughtException() ) );
1400 #ifdef ENABLE_SDREMOTE
1401 RemoteServer::presentationStarted( this );
1402 #endif
1405 sal_Bool SAL_CALL SlideshowImpl::isPaused()
1407 SolarMutexGuard aSolarGuard;
1408 return mbIsPaused;
1411 void SAL_CALL SlideshowImpl::blankScreen( sal_Int32 nColor )
1413 SolarMutexGuard aSolarGuard;
1415 if( mpShowWindow && mpSlideController )
1417 if( mpShowWindow->SetBlankMode( mpSlideController->getCurrentSlideIndex(), Color(nColor) ) )
1419 pause();
1424 // XShapeEventListener
1426 void SlideshowImpl::click( const Reference< XShape >& xShape )
1428 SolarMutexGuard aSolarGuard;
1430 WrappedShapeEventImplPtr pEvent = maShapeEventMap[xShape];
1431 if( !pEvent.get() )
1432 return;
1434 switch( pEvent->meClickAction )
1436 case ClickAction_PREVPAGE: gotoPreviousSlide(); break;
1437 case ClickAction_NEXTPAGE: gotoNextSlide(); break;
1438 case ClickAction_FIRSTPAGE: gotoFirstSlide(); break;
1439 case ClickAction_LASTPAGE: gotoLastSlide(); break;
1440 case ClickAction_STOPPRESENTATION: endPresentation(); break;
1441 case ClickAction_BOOKMARK:
1443 gotoBookmark( pEvent->maStrBookmark );
1445 break;
1446 case ClickAction_SOUND:
1448 #if HAVE_FEATURE_AVMEDIA
1451 mxPlayer.set(avmedia::MediaWindow::createPlayer(pEvent->maStrBookmark, ""/*TODO?*/), uno::UNO_QUERY_THROW );
1452 mxPlayer->start();
1454 catch( uno::Exception& )
1456 OSL_FAIL("sd::SlideshowImpl::click(), exception caught!" );
1458 #endif
1460 break;
1462 case ClickAction_DOCUMENT:
1464 OUString aBookmark( pEvent->maStrBookmark );
1466 sal_Int32 nPos = aBookmark.indexOf( '#' );
1467 if( nPos >= 0 )
1469 OUString aURL( aBookmark.copy( 0, nPos+1 ) );
1470 OUString aName( aBookmark.copy( nPos+1 ) );
1471 aURL += getUiNameFromPageApiNameImpl( aName );
1472 aBookmark = aURL;
1475 mpDocSh->OpenBookmark( aBookmark );
1477 break;
1479 case ClickAction_PROGRAM:
1481 INetURLObject aURL(
1482 ::URIHelper::SmartRel2Abs(
1483 INetURLObject(mpDocSh->GetMedium()->GetBaseURL()),
1484 pEvent->maStrBookmark, ::URIHelper::GetMaybeFileHdl(), true,
1485 false, INetURLObject::EncodeMechanism::WasEncoded,
1486 INetURLObject::DecodeMechanism::Unambiguous ) );
1488 if( INetProtocol::File == aURL.GetProtocol() )
1490 SfxStringItem aUrl( SID_FILE_NAME, aURL.GetMainURL( INetURLObject::DecodeMechanism::NONE ) );
1491 SfxBoolItem aBrowsing( SID_BROWSE, true );
1493 SfxViewFrame* pViewFrm = SfxViewFrame::Current();
1494 if (pViewFrm)
1496 pViewFrm->GetDispatcher()->ExecuteList( SID_OPENDOC,
1497 SfxCallMode::ASYNCHRON | SfxCallMode::RECORD,
1498 { &aUrl, &aBrowsing });
1502 break;
1504 case presentation::ClickAction_MACRO:
1506 const OUString aMacro( pEvent->maStrBookmark );
1508 if ( SfxApplication::IsXScriptURL( aMacro ) )
1510 Any aRet;
1511 Sequence< sal_Int16 > aOutArgsIndex;
1512 Sequence< Any > aOutArgs;
1513 Sequence< Any >* pInArgs = new Sequence< Any >(0);
1514 mpDocSh->CallXScript( aMacro, *pInArgs, aRet, aOutArgsIndex, aOutArgs);
1516 else
1518 // aMacro has the following syntax:
1519 // "Macroname.Modulname.Libname.Documentname" or
1520 // "Macroname.Modulname.Libname.Applicationname"
1521 OUString aMacroName = aMacro.getToken(0, '.');
1522 OUString aModulName = aMacro.getToken(1, '.');
1524 // todo: is the limitation still given that only
1525 // Modulname+Macroname can be used here?
1526 OUString aExecMacro = aModulName + "." + aMacroName;
1527 mpDocSh->GetBasic()->Call(aExecMacro);
1530 break;
1532 case ClickAction_VERB:
1534 // todo, better do it async?
1535 SdrObject* pObj = GetSdrObjectFromXShape( xShape );
1536 SdrOle2Obj* pOleObject = dynamic_cast< SdrOle2Obj* >(pObj);
1537 if (pOleObject && mpViewShell )
1538 mpViewShell->ActivateObject(pOleObject, pEvent->mnVerb);
1540 break;
1541 default:
1542 break;
1546 sal_Int32 SlideshowImpl::getSlideNumberForBookmark( const OUString& rStrBookmark )
1548 bool bIsMasterPage;
1549 OUString aBookmark = getUiNameFromPageApiNameImpl( rStrBookmark );
1550 sal_uInt16 nPgNum = mpDoc->GetPageByName( aBookmark, bIsMasterPage );
1552 if( nPgNum == SDRPAGE_NOTFOUND )
1554 // Is the bookmark an object?
1555 SdrObject* pObj = mpDoc->GetObj( aBookmark );
1557 if( pObj )
1559 nPgNum = pObj->GetPage()->GetPageNum();
1560 bIsMasterPage = pObj->GetPage()->IsMasterPage();
1564 if( (nPgNum == SDRPAGE_NOTFOUND) || bIsMasterPage || static_cast<SdPage*>(mpDoc->GetPage(nPgNum))->GetPageKind() != PageKind::Standard )
1565 return -1;
1567 return ( nPgNum - 1) >> 1;
1570 void SlideshowImpl::hyperLinkClicked( OUString const& aHyperLink )
1572 OUString aBookmark( aHyperLink );
1574 sal_Int32 nPos = aBookmark.indexOf( '#' );
1575 if( nPos >= 0 )
1577 OUString aURL( aBookmark.copy( 0, nPos+1 ) );
1578 OUString aName( aBookmark.copy( nPos+1 ) );
1579 aURL += getUiNameFromPageApiNameImpl( aName );
1580 aBookmark = aURL;
1583 mpDocSh->OpenBookmark( aBookmark );
1586 void SlideshowImpl::displaySlideNumber( sal_Int32 nSlideNumber )
1588 if( mpSlideController.get() )
1590 if( mpSlideController->jumpToSlideNumber( nSlideNumber ) )
1592 displayCurrentSlide();
1597 /** nSlideIndex == -1 displays current slide again */
1598 void SlideshowImpl::displaySlideIndex( sal_Int32 nSlideIndex )
1600 if( mpSlideController.get() )
1602 if( (nSlideIndex == -1) || mpSlideController->jumpToSlideIndex( nSlideIndex ) )
1604 displayCurrentSlide();
1609 void SlideshowImpl::jumpToBookmark( const OUString& sBookmark )
1611 sal_Int32 nSlideNumber = getSlideNumberForBookmark( sBookmark );
1612 if( nSlideNumber != -1 )
1613 displaySlideNumber( nSlideNumber );
1616 sal_Int32 SlideshowImpl::getCurrentSlideNumber()
1618 return mpSlideController.get() ? mpSlideController->getCurrentSlideNumber() : -1;
1621 sal_Bool SAL_CALL SlideshowImpl::isEndless()
1623 SolarMutexGuard aSolarGuard;
1624 return maPresSettings.mbEndless;
1627 void SlideshowImpl::update()
1629 startUpdateTimer();
1632 void SlideshowImpl::startUpdateTimer()
1634 SolarMutexGuard aSolarGuard;
1635 maUpdateTimer.SetTimeout( 0 );
1636 maUpdateTimer.Start();
1639 /** this timer is called 20ms after a new slide was displayed.
1640 This is used to unfreeze user input that was disabled after
1641 slide change to skip input that was buffered during slide
1642 transition preparation */
1643 IMPL_LINK_NOARG(SlideshowImpl, ReadyForNextInputHdl, Timer *, void)
1645 mbInputFreeze = false;
1648 /** if I catch someone someday who calls this method by hand
1649 and not by using the timer, I will personally punish this
1650 person seriously, even if this person is me.
1652 IMPL_LINK_NOARG(SlideshowImpl, updateHdl, Timer *, void)
1654 updateSlideShow();
1657 void SlideshowImpl::updateSlideShow()
1659 // prevent me from deletion when recursing (App::EnableYieldMode does)
1660 const rtl::Reference<SlideshowImpl> this_(this);
1662 Reference< XSlideShow > xShow( mxShow );
1663 if ( ! xShow.is())
1664 return;
1668 double fUpdate = 0.0;
1669 if( !xShow->update(fUpdate) )
1670 fUpdate = -1.0;
1672 if (mxShow.is() && (fUpdate >= 0.0))
1674 if (!::basegfx::fTools::equalZero(fUpdate))
1676 // Avoid busy loop when the previous call to update()
1677 // returns a small positive number but not 0 (which is
1678 // handled above). Also, make sure that calls to update()
1679 // have a minimum frequency.
1680 // => Allow up to 60 frames per second. Call at least once
1681 // every 4 seconds.
1682 const static sal_Int32 nMaximumFrameCount (60);
1683 const static double nMinimumTimeout (1.0 / nMaximumFrameCount);
1684 const static double nMaximumTimeout (4.0);
1685 fUpdate = ::basegfx::clamp(fUpdate, nMinimumTimeout, nMaximumTimeout);
1687 // Make sure that the maximum frame count has not been set
1688 // too high (only then conversion to milliseconds and long
1689 // integer may lead to zero value.)
1690 OSL_ASSERT(static_cast<sal_uLong>(fUpdate * 1000.0) > 0);
1693 // Use our high resolution timers for the asynchronous callback.
1694 maUpdateTimer.SetTimeout(static_cast<sal_uLong>(fUpdate * 1000.0));
1695 maUpdateTimer.Start();
1698 catch( Exception& )
1700 SAL_WARN( "sd", "sd::SlideshowImpl::updateSlideShow(), exception caught: "
1701 << comphelper::anyToString( cppu::getCaughtException() ) );
1705 bool SlideshowImpl::keyInput(const KeyEvent& rKEvt)
1707 if( !mxShow.is() || mbInputFreeze )
1708 return false;
1710 bool bRet = true;
1714 const int nKeyCode = rKEvt.GetKeyCode().GetCode();
1715 switch( nKeyCode )
1717 case awt::Key::CONTEXTMENU:
1718 if( !mnContextMenuEvent )
1720 if( mpShowWindow )
1721 maPopupMousePos = mpShowWindow->GetPointerState().maPos;
1722 mnContextMenuEvent = Application::PostUserEvent( LINK( this, SlideshowImpl, ContextMenuHdl ) );
1724 break;
1726 // cancel show
1727 case KEY_ESCAPE:
1728 case KEY_SUBTRACT:
1729 // in case the user cancels the presentation, switch to current slide
1730 // in edit mode
1731 if( mpSlideController.get() && (ANIMATIONMODE_SHOW == meAnimationMode) )
1733 if( mpSlideController->getCurrentSlideNumber() != -1 )
1734 mnRestoreSlide = mpSlideController->getCurrentSlideNumber();
1736 endPresentation();
1737 break;
1739 // advance show
1740 case KEY_PAGEDOWN:
1741 if(rKEvt.GetKeyCode().IsMod2())
1743 gotoNextSlide();
1744 break;
1746 SAL_FALLTHROUGH;
1747 case KEY_SPACE:
1748 case KEY_RIGHT:
1749 case KEY_DOWN:
1750 case KEY_N:
1751 gotoNextEffect();
1752 break;
1754 case KEY_RETURN:
1756 if( !maCharBuffer.isEmpty() )
1758 if( mpSlideController.get() )
1760 if( mpSlideController->jumpToSlideNumber( maCharBuffer.toInt32() - 1 ) )
1761 displayCurrentSlide();
1763 maCharBuffer.clear();
1765 else
1767 gotoNextEffect();
1770 break;
1772 // numeric: add to buffer
1773 case KEY_0:
1774 case KEY_1:
1775 case KEY_2:
1776 case KEY_3:
1777 case KEY_4:
1778 case KEY_5:
1779 case KEY_6:
1780 case KEY_7:
1781 case KEY_8:
1782 case KEY_9:
1783 maCharBuffer += OUStringLiteral1( rKEvt.GetCharCode() );
1784 break;
1786 case KEY_PAGEUP:
1787 if(rKEvt.GetKeyCode().IsMod2())
1789 gotoPreviousSlide();
1790 break;
1792 SAL_FALLTHROUGH;
1793 case KEY_LEFT:
1794 case KEY_UP:
1795 case KEY_P:
1796 case KEY_BACKSPACE:
1797 gotoPreviousEffect();
1798 break;
1800 case KEY_HOME:
1801 gotoFirstSlide();
1802 break;
1804 case KEY_END:
1805 gotoLastSlide();
1806 break;
1808 case KEY_B:
1809 case KEY_W:
1810 case KEY_POINT:
1811 case KEY_COMMA:
1813 blankScreen( ((nKeyCode == KEY_W ) || (nKeyCode == KEY_COMMA)) ? 0x00ffffff : 0x00000000 );
1815 break;
1817 default:
1818 bRet = false;
1819 break;
1822 catch( Exception& )
1824 bRet = false;
1825 SAL_WARN( "sd", "sd::SlideshowImpl::keyInput(), exception caught: "
1826 << comphelper::anyToString( cppu::getCaughtException() ) );
1829 return bRet;
1832 IMPL_LINK( SlideshowImpl, EventListenerHdl, VclSimpleEvent&, rSimpleEvent, void )
1834 if( !mxShow.is() || mbInputFreeze )
1835 return;
1837 if( (rSimpleEvent.GetId() == VclEventId::WindowCommand) && static_cast<VclWindowEvent*>(&rSimpleEvent)->GetData() )
1839 const CommandEvent& rEvent = *static_cast<const CommandEvent*>(static_cast<VclWindowEvent*>(&rSimpleEvent)->GetData());
1841 if( rEvent.GetCommand() == CommandEventId::Media )
1843 CommandMediaData* pMediaData = rEvent.GetMediaData();
1844 pMediaData->SetPassThroughToOS(false);
1845 switch (pMediaData->GetMediaId())
1847 #if defined( MACOSX )
1848 case MediaCommand::Menu:
1849 if( !mnContextMenuEvent )
1851 if( mpShowWindow )
1852 maPopupMousePos = mpShowWindow->GetPointerState().maPos;
1853 mnContextMenuEvent = Application::PostUserEvent( LINK( this, SlideshowImpl, ContextMenuHdl ) );
1855 break;
1856 case MediaCommand::VolumeDown:
1857 gotoPreviousSlide();
1858 break;
1859 case MediaCommand::VolumeUp:
1860 gotoNextEffect();
1861 break;
1862 #endif
1863 case MediaCommand::NextTrack:
1864 gotoNextEffect();
1865 break;
1866 case MediaCommand::Pause:
1867 if( !mbIsPaused )
1868 blankScreen(0);
1869 break;
1870 case MediaCommand::Play:
1871 if( mbIsPaused )
1872 resume();
1873 break;
1875 case MediaCommand::PlayPause:
1876 if( mbIsPaused )
1877 resume();
1878 else
1879 blankScreen(0);
1880 break;
1881 case MediaCommand::PreviousTrack:
1882 gotoPreviousSlide();
1883 break;
1884 case MediaCommand::NextTrackHold:
1885 gotoLastSlide();
1886 break;
1888 case MediaCommand::Rewind:
1889 gotoFirstSlide();
1890 break;
1891 case MediaCommand::Stop:
1892 // in case the user cancels the presentation, switch to current slide
1893 // in edit mode
1894 if( mpSlideController.get() && (ANIMATIONMODE_SHOW == meAnimationMode) )
1896 if( mpSlideController->getCurrentSlideNumber() != -1 )
1897 mnRestoreSlide = mpSlideController->getCurrentSlideNumber();
1899 endPresentation();
1900 break;
1901 default:
1902 pMediaData->SetPassThroughToOS(true);
1903 break;
1909 void SlideshowImpl::mouseButtonUp(const MouseEvent& rMEvt)
1911 if( rMEvt.IsRight() && !mnContextMenuEvent )
1913 maPopupMousePos = rMEvt.GetPosPixel();
1914 mnContextMenuEvent = Application::PostUserEvent( LINK( this, SlideshowImpl, ContextMenuHdl ) );
1918 IMPL_LINK_NOARG(SlideshowImpl, ContextMenuHdl, void*, void)
1920 mnContextMenuEvent = nullptr;
1922 if( mpSlideController.get() == nullptr )
1923 return;
1925 mbWasPaused = mbIsPaused;
1926 if( !mbWasPaused )
1927 pause();
1929 VclBuilder aBuilder(nullptr, VclBuilderContainer::getUIRootDir(), "modules/simpress/ui/slidecontextmenu.ui", "");
1930 VclPtr<PopupMenu> pMenu(aBuilder.get_menu("menu"));
1932 // Adding button to display if in Pen mode
1933 pMenu->CheckItem("pen", mbUsePen);
1935 const ShowWindowMode eMode = mpShowWindow->GetShowWindowMode();
1936 pMenu->EnableItem(pMenu->GetItemId("next"), mpSlideController->getNextSlideIndex() != -1);
1937 pMenu->EnableItem(pMenu->GetItemId("prev"), (mpSlideController->getPreviousSlideIndex() != -1 ) || (eMode == SHOWWINDOWMODE_END) || (eMode == SHOWWINDOWMODE_PAUSE) || (eMode == SHOWWINDOWMODE_BLANK));
1938 pMenu->EnableItem(pMenu->GetItemId("edit"), mpViewShell->GetDoc()->IsStartWithPresentation());
1940 PopupMenu* pPageMenu = pMenu->GetPopupMenu(pMenu->GetItemId("goto"));
1942 SfxViewFrame* pViewFrame = getViewFrame();
1943 if( pViewFrame )
1945 Reference< css::frame::XFrame > xFrame( pViewFrame->GetFrame().GetFrameInterface() );
1946 if( xFrame.is() )
1948 pMenu->SetItemImage(pMenu->GetItemId("next"), vcl::CommandInfoProvider::GetImageForCommand(".uno:NextRecord", xFrame));
1949 pMenu->SetItemImage(pMenu->GetItemId("prev"), vcl::CommandInfoProvider::GetImageForCommand(".uno:PrevRecord", xFrame));
1951 if( pPageMenu )
1953 pPageMenu->SetItemImage(pPageMenu->GetItemId("first"), vcl::CommandInfoProvider::GetImageForCommand(".uno:FirstRecord", xFrame));
1954 pPageMenu->SetItemImage(pPageMenu->GetItemId("last"), vcl::CommandInfoProvider::GetImageForCommand(".uno:LastRecord", xFrame));
1959 // populate slide goto list
1960 if( pPageMenu )
1962 const sal_Int32 nPageNumberCount = mpSlideController->getSlideNumberCount();
1963 if( nPageNumberCount <= 1 )
1965 pMenu->EnableItem(pMenu->GetItemId("goto"), false);
1967 else
1969 sal_Int32 nCurrentSlideNumber = mpSlideController->getCurrentSlideNumber();
1970 if( (eMode == SHOWWINDOWMODE_END) || (eMode == SHOWWINDOWMODE_PAUSE) || (eMode == SHOWWINDOWMODE_BLANK) )
1971 nCurrentSlideNumber = -1;
1973 pPageMenu->EnableItem(pPageMenu->GetItemId("first"), mpSlideController->getSlideNumber(0) != nCurrentSlideNumber);
1974 pPageMenu->EnableItem(pPageMenu->GetItemId("last"), mpSlideController->getSlideNumber(mpSlideController->getSlideIndexCount() - 1) != nCurrentSlideNumber);
1976 sal_Int32 nPageNumber;
1978 for( nPageNumber = 0; nPageNumber < nPageNumberCount; nPageNumber++ )
1980 if( mpSlideController->isVisibleSlideNumber( nPageNumber ) )
1982 SdPage* pPage = mpDoc->GetSdPage(static_cast<sal_uInt16>(nPageNumber), PageKind::Standard);
1983 if (pPage)
1985 pPageMenu->InsertItem( static_cast<sal_uInt16>(CM_SLIDES + nPageNumber), pPage->GetName() );
1986 if( nPageNumber == nCurrentSlideNumber )
1987 pPageMenu->CheckItem( static_cast<sal_uInt16>(CM_SLIDES + nPageNumber) );
1994 if( mpShowWindow->GetShowWindowMode() == SHOWWINDOWMODE_BLANK )
1996 PopupMenu* pBlankMenu = pMenu->GetPopupMenu(pMenu->GetItemId("screen"));
1997 if( pBlankMenu )
1999 pBlankMenu->CheckItem((mpShowWindow->GetBlankColor() == COL_WHITE) ? "white" : "black");
2003 PopupMenu* pWidthMenu = pMenu->GetPopupMenu(pMenu->GetItemId("width"));
2005 // populate color width list
2006 if( pWidthMenu )
2008 sal_Int32 nIterator;
2009 double nWidth;
2011 nWidth = 4.0;
2012 for( nIterator = 1; nIterator < 6; nIterator++)
2014 switch(nIterator)
2016 case 1:
2017 nWidth = 4.0;
2018 break;
2019 case 2:
2020 nWidth = 100.0;
2021 break;
2022 case 3:
2023 nWidth = 150.0;
2024 break;
2025 case 4:
2026 nWidth = 200.0;
2027 break;
2028 case 5:
2029 nWidth = 400.0;
2030 break;
2031 default:
2032 break;
2035 if (nWidth == mdUserPaintStrokeWidth)
2036 pWidthMenu->CheckItem(pWidthMenu->GetItemId(OString::number(nWidth)));
2040 pMenu->SetSelectHdl( LINK( this, SlideshowImpl, ContextMenuSelectHdl ) );
2041 pMenu->Execute( mpShowWindow, maPopupMousePos );
2043 if( mxView.is() )
2044 mxView->ignoreNextMouseReleased();
2046 if( !mbWasPaused )
2047 resume();
2050 IMPL_LINK( SlideshowImpl, ContextMenuSelectHdl, Menu *, pMenu, bool )
2052 if (!pMenu)
2053 return false;
2055 OString sMenuId = pMenu->GetCurItemIdent();
2057 if (sMenuId == "prev")
2059 gotoPreviousSlide();
2060 mbWasPaused = false;
2062 else if(sMenuId == "next")
2064 gotoNextSlide();
2065 mbWasPaused = false;
2067 else if (sMenuId == "first")
2069 gotoFirstSlide();
2070 mbWasPaused = false;
2072 else if (sMenuId == "last")
2074 gotoLastSlide();
2075 mbWasPaused = false;
2077 else if (sMenuId == "black" || sMenuId == "white")
2079 const Color aBlankColor(sMenuId == "white" ? COL_WHITE : COL_BLACK);
2080 if( mbWasPaused )
2082 if( mpShowWindow->GetShowWindowMode() == SHOWWINDOWMODE_BLANK )
2084 if( mpShowWindow->GetBlankColor() == aBlankColor )
2086 mbWasPaused = false;
2087 mpShowWindow->RestartShow();
2088 return false;
2091 mpShowWindow->RestartShow();
2093 if( mpShowWindow->SetBlankMode( mpSlideController->getCurrentSlideIndex(), aBlankColor ) )
2095 pause();
2096 mbWasPaused = true;
2099 else if (sMenuId == "color")
2101 //Open a color picker based on SvColorDialog
2102 ::Color aColor( mnUserPaintColor );
2103 SvColorDialog aColorDlg;
2104 aColorDlg.SetColor( aColor );
2106 if (aColorDlg.Execute(mpShowWindow->GetFrameWeld()))
2108 aColor = aColorDlg.GetColor();
2109 setPenColor(sal_Int32(aColor));
2111 mbWasPaused = false;
2113 else if (sMenuId == "4")
2115 setPenWidth(4.0);
2116 mbWasPaused = false;
2118 else if (sMenuId == "100")
2120 setPenWidth(100.0);
2121 mbWasPaused = false;
2123 else if (sMenuId == "150")
2125 setPenWidth(150.0);
2126 mbWasPaused = false;
2128 else if (sMenuId == "200")
2130 setPenWidth(200.0);
2131 mbWasPaused = false;
2133 else if (sMenuId == "400")
2135 setPenWidth(400.0);
2136 mbWasPaused = false;
2138 else if (sMenuId == "erase")
2140 setEraseAllInk(true);
2141 mbWasPaused = false;
2143 else if (sMenuId == "pen")
2145 setUsePen(!mbUsePen);
2146 mbWasPaused = false;
2148 else if (sMenuId == "edit")
2150 // When in autoplay mode (pps/ppsx), offer editing of the presentation
2151 // Turn autostart off, else Impress will close when exiting the Presentation
2152 mpViewShell->GetDoc()->SetExitAfterPresenting(false);
2153 if( mpSlideController.get() && (ANIMATIONMODE_SHOW == meAnimationMode) )
2155 if( mpSlideController->getCurrentSlideNumber() != -1 )
2157 mnRestoreSlide = mpSlideController->getCurrentSlideNumber();
2160 endPresentation();
2162 else if (sMenuId == "end")
2164 // in case the user cancels the presentation, switch to current slide
2165 // in edit mode
2166 if( mpSlideController.get() && (ANIMATIONMODE_SHOW == meAnimationMode) )
2168 if( mpSlideController->getCurrentSlideNumber() != -1 )
2170 mnRestoreSlide = mpSlideController->getCurrentSlideNumber();
2173 endPresentation();
2175 else
2177 sal_Int32 nPageNumber = pMenu->GetCurItemId() - CM_SLIDES;
2178 const ShowWindowMode eMode = mpShowWindow->GetShowWindowMode();
2179 if( (eMode == SHOWWINDOWMODE_END) || (eMode == SHOWWINDOWMODE_PAUSE) || (eMode == SHOWWINDOWMODE_BLANK) )
2181 mpShowWindow->RestartShow( nPageNumber );
2183 else if( nPageNumber != mpSlideController->getCurrentSlideNumber() )
2185 displaySlideNumber( nPageNumber );
2187 mbWasPaused = false;
2190 return false;
2193 Reference< XSlideShow > SlideshowImpl::createSlideShow()
2195 Reference< XSlideShow > xShow;
2199 Reference< uno::XComponentContext > xContext =
2200 ::comphelper::getProcessComponentContext();
2202 xShow.set( presentation::SlideShow::create(xContext), UNO_QUERY_THROW );
2204 catch( uno::Exception& )
2206 SAL_WARN( "sd", "sd::SlideshowImpl::createSlideShow(), exception caught: "
2207 << comphelper::anyToString( cppu::getCaughtException() ) );
2210 return xShow;
2213 void SlideshowImpl::createSlideList( bool bAll, const OUString& rPresSlide )
2215 const sal_uInt16 nSlideCount = mpDoc->GetSdPageCount( PageKind::Standard );
2217 if( nSlideCount )
2219 SdCustomShow* pCustomShow;
2221 if( mpDoc->GetCustomShowList() && maPresSettings.mbCustomShow )
2222 pCustomShow = mpDoc->GetCustomShowList()->GetCurObject();
2223 else
2224 pCustomShow = nullptr;
2226 // create animation slide controller
2227 AnimationSlideController::Mode eMode =
2228 ( pCustomShow && pCustomShow->PagesVector().size() ) ? AnimationSlideController::CUSTOM :
2229 (bAll ? AnimationSlideController::ALL : AnimationSlideController::FROM);
2231 Reference< XDrawPagesSupplier > xDrawPages( mpDoc->getUnoModel(), UNO_QUERY_THROW );
2232 Reference< XIndexAccess > xSlides( xDrawPages->getDrawPages(), UNO_QUERY_THROW );
2233 mpSlideController.reset( new AnimationSlideController( xSlides, eMode ) );
2235 if( eMode != AnimationSlideController::CUSTOM )
2237 sal_Int32 nFirstVisibleSlide = 0;
2239 // normal presentation
2240 if( !rPresSlide.isEmpty() )
2242 sal_Int32 nSlide;
2243 bool bTakeNextAvailable = false;
2245 for( nSlide = 0, nFirstVisibleSlide = -1;
2246 ( nSlide < nSlideCount ) && ( -1 == nFirstVisibleSlide ); nSlide++ )
2248 SdPage* pTestSlide = mpDoc->GetSdPage( static_cast<sal_uInt16>(nSlide), PageKind::Standard );
2250 if( pTestSlide->GetName() == rPresSlide )
2252 if( pTestSlide->IsExcluded() )
2253 bTakeNextAvailable = true;
2254 else
2255 nFirstVisibleSlide = nSlide;
2257 else if( bTakeNextAvailable && !pTestSlide->IsExcluded() )
2258 nFirstVisibleSlide = nSlide;
2261 if( -1 == nFirstVisibleSlide )
2262 nFirstVisibleSlide = 0;
2265 for( sal_Int32 i = 0; i < nSlideCount; i++ )
2267 bool bVisible = ! mpDoc->GetSdPage( static_cast<sal_uInt16>(i), PageKind::Standard )->IsExcluded();
2268 if( bVisible || (eMode == AnimationSlideController::ALL) )
2269 mpSlideController->insertSlideNumber( i, bVisible );
2272 mpSlideController->setStartSlideNumber( nFirstVisibleSlide );
2274 else
2276 if( meAnimationMode != ANIMATIONMODE_SHOW && !rPresSlide.isEmpty() )
2278 sal_Int32 nSlide;
2279 for( nSlide = 0; nSlide < nSlideCount; nSlide++ )
2280 if( rPresSlide == mpDoc->GetSdPage( static_cast<sal_uInt16>(nSlide), PageKind::Standard )->GetName() )
2281 break;
2283 if( nSlide < nSlideCount )
2284 mpSlideController->insertSlideNumber( static_cast<sal_uInt16>(nSlide) );
2287 sal_Int32 nSlideIndex = 0;
2288 for( SdCustomShow::PageVec::iterator it = pCustomShow->PagesVector().begin();
2289 it != pCustomShow->PagesVector().end(); ++it, nSlideIndex++ )
2291 const sal_uInt16 nSdSlide = ( (*it)->GetPageNum() - 1 ) / 2;
2293 if( ! mpDoc->GetSdPage( nSdSlide, PageKind::Standard )->IsExcluded())
2294 mpSlideController->insertSlideNumber( nSdSlide );
2300 typedef sal_uInt16 (*FncGetChildWindowId)();
2302 static const FncGetChildWindowId aShowChildren[] =
2304 &AnimationChildWindow::GetChildWindowId,
2305 &Svx3DChildWindow::GetChildWindowId,
2306 &SvxFontWorkChildWindow::GetChildWindowId,
2307 &SvxColorChildWindow::GetChildWindowId,
2308 &SvxSearchDialogWrapper::GetChildWindowId,
2309 &SvxBmpMaskChildWindow::GetChildWindowId,
2310 &SvxIMapDlgChildWindow::GetChildWindowId,
2311 &SvxHlinkDlgWrapper::GetChildWindowId,
2312 &SfxInfoBarContainerChild::GetChildWindowId
2315 void SlideshowImpl::hideChildWindows()
2317 mnChildMask = 0;
2319 if( ANIMATIONMODE_SHOW == meAnimationMode )
2321 SfxViewFrame* pViewFrame = getViewFrame();
2323 if( pViewFrame )
2325 for( sal_uLong i = 0; i < SAL_N_ELEMENTS( aShowChildren ); i++ )
2327 const sal_uInt16 nId = ( *aShowChildren[ i ] )();
2329 if( pViewFrame->GetChildWindow( nId ) )
2331 pViewFrame->SetChildWindow( nId, false );
2332 mnChildMask |= 1 << i;
2339 void SlideshowImpl::showChildWindows()
2341 if( ANIMATIONMODE_SHOW == meAnimationMode )
2343 SfxViewFrame* pViewFrame = getViewFrame();
2344 if( pViewFrame )
2346 for( sal_uLong i = 0; i < SAL_N_ELEMENTS(aShowChildren); i++ )
2348 if( mnChildMask & ( 1 << i ) )
2349 pViewFrame->SetChildWindow( ( *aShowChildren[ i ] )(), true );
2355 SfxViewFrame* SlideshowImpl::getViewFrame() const
2357 return mpViewShell ? mpViewShell->GetViewFrame() : nullptr;
2360 SfxDispatcher* SlideshowImpl::getDispatcher() const
2362 return (mpViewShell && mpViewShell->GetViewFrame()) ? mpViewShell->GetViewFrame()->GetDispatcher() : nullptr;
2365 SfxBindings* SlideshowImpl::getBindings() const
2367 return (mpViewShell && mpViewShell->GetViewFrame()) ? &mpViewShell->GetViewFrame()->GetBindings() : nullptr;
2370 void SlideshowImpl::resize( const Size& rSize )
2372 maPresSize = rSize;
2374 if(mpShowWindow)
2376 mpShowWindow->SetSizePixel( maPresSize );
2377 mpShowWindow->Show();
2380 if( mxView.is() ) try
2382 awt::WindowEvent aEvt;
2383 mxView->windowResized(aEvt);
2385 catch( Exception& )
2387 SAL_WARN( "sd", "sd::SlideshowImpl::resize(), exception caught: "
2388 << comphelper::anyToString( cppu::getCaughtException() ) );
2392 void SlideshowImpl::setActiveXToolbarsVisible( bool bVisible )
2394 // in case of ActiveX control the toolbars should not be visible if slide show runs in window mode
2395 // actually it runs always in window mode in case of ActiveX control
2396 if ( !maPresSettings.mbFullScreen && mpDocSh && mpDocSh->GetMedium() )
2398 const SfxBoolItem* pItem = SfxItemSet::GetItem<SfxBoolItem>(mpDocSh->GetMedium()->GetItemSet(), SID_VIEWONLY, false);
2399 if ( pItem && pItem->GetValue() )
2401 // this is a plugin/activex mode, no toolbars should be visible during slide show
2402 // after the end of slide show they should be visible again
2403 SfxViewFrame* pViewFrame = getViewFrame();
2404 if( pViewFrame )
2408 Reference< frame::XLayoutManager > xLayoutManager;
2409 Reference< beans::XPropertySet > xFrameProps( pViewFrame->GetFrame().GetFrameInterface(), UNO_QUERY_THROW );
2410 if ( ( xFrameProps->getPropertyValue( "LayoutManager" )
2411 >>= xLayoutManager )
2412 && xLayoutManager.is() )
2414 xLayoutManager->setVisible( bVisible );
2417 catch( uno::Exception& )
2424 void SAL_CALL SlideshowImpl::activate()
2426 SolarMutexGuard aSolarGuard;
2428 maDeactivateTimer.Stop();
2430 if( !mbActive && mxShow.is() )
2432 mbActive = true;
2434 if( ANIMATIONMODE_SHOW == meAnimationMode )
2436 if( mbAutoSaveWasOn )
2437 setAutoSaveState( false );
2439 if( mpShowWindow )
2441 SfxViewFrame* pViewFrame = getViewFrame();
2442 SfxDispatcher* pDispatcher = pViewFrame ? pViewFrame->GetDispatcher() : nullptr;
2444 hideChildWindows();
2446 if( pDispatcher )
2448 // filter all forbidden slots
2449 pDispatcher->SetSlotFilter( SfxSlotFilterState::ENABLED, pAllowed );
2452 if( getBindings() )
2453 getBindings()->InvalidateAll(true);
2455 mpShowWindow->GrabFocus();
2459 resume();
2463 void SAL_CALL SlideshowImpl::deactivate()
2465 SolarMutexGuard aSolarGuard;
2467 if( mbActive && mxShow.is() )
2469 maDeactivateTimer.Start();
2473 IMPL_LINK_NOARG(SlideshowImpl, deactivateHdl, Timer *, void)
2475 if( mbActive && mxShow.is() )
2477 mbActive = false;
2479 pause();
2481 if( ANIMATIONMODE_SHOW == meAnimationMode )
2483 if( mbAutoSaveWasOn )
2484 setAutoSaveState( true );
2486 if( mpShowWindow )
2488 showChildWindows();
2494 sal_Bool SAL_CALL SlideshowImpl::isActive()
2496 SolarMutexGuard aSolarGuard;
2497 return mbActive;
2500 void SlideshowImpl::setAutoSaveState( bool bOn)
2504 uno::Reference<uno::XComponentContext> xContext( ::comphelper::getProcessComponentContext() );
2506 uno::Reference< util::XURLTransformer > xParser(util::URLTransformer::create(xContext));
2507 util::URL aURL;
2508 aURL.Complete = "vnd.sun.star.autorecovery:/setAutoSaveState";
2509 xParser->parseStrict(aURL);
2511 Sequence< beans::PropertyValue > aArgs(1);
2512 aArgs[0].Name = "AutoSaveState";
2513 aArgs[0].Value <<= bOn;
2515 uno::Reference< frame::XDispatch > xAutoSave = frame::theAutoRecovery::get(xContext);
2516 xAutoSave->dispatch(aURL, aArgs);
2518 catch( Exception& )
2520 OSL_FAIL("sd::SlideshowImpl::setAutoSaveState(), exception caught!");
2524 Reference< XDrawPage > SAL_CALL SlideshowImpl::getCurrentSlide()
2526 SolarMutexGuard aSolarGuard;
2528 Reference< XDrawPage > xSlide;
2529 if( mxShow.is() && mpSlideController.get() )
2531 sal_Int32 nSlide = getCurrentSlideNumber();
2532 if( (nSlide >= 0) && (nSlide < mpSlideController->getSlideNumberCount() ) )
2533 xSlide = mpSlideController->getSlideByNumber( nSlide );
2536 return xSlide;
2539 sal_Int32 SAL_CALL SlideshowImpl::getNextSlideIndex()
2541 SolarMutexGuard aSolarGuard;
2543 if( mxShow.is() )
2545 return mpSlideController->getNextSlideIndex();
2547 else
2549 return -1;
2553 sal_Int32 SAL_CALL SlideshowImpl::getCurrentSlideIndex()
2555 return mpSlideController.get() ? mpSlideController->getCurrentSlideIndex() : -1;
2558 // css::presentation::XSlideShowController:
2560 ::sal_Int32 SAL_CALL SlideshowImpl::getSlideCount()
2562 return mpSlideController.get() ? mpSlideController->getSlideIndexCount() : 0;
2565 Reference< XDrawPage > SAL_CALL SlideshowImpl::getSlideByIndex(::sal_Int32 Index)
2567 if( (mpSlideController.get() == nullptr ) || (Index < 0) || (Index >= mpSlideController->getSlideIndexCount() ) )
2568 throw IndexOutOfBoundsException();
2570 return mpSlideController->getSlideByNumber( mpSlideController->getSlideNumber( Index ) );
2573 sal_Bool SAL_CALL SlideshowImpl::getAlwaysOnTop()
2575 SolarMutexGuard aSolarGuard;
2576 return maPresSettings.mbAlwaysOnTop;
2579 void SAL_CALL SlideshowImpl::setAlwaysOnTop( sal_Bool bAlways )
2581 SolarMutexGuard aSolarGuard;
2582 if( maPresSettings.mbAlwaysOnTop != bool(bAlways) )
2584 maPresSettings.mbAlwaysOnTop = bAlways;
2585 // todo, can this be changed while running?
2589 sal_Bool SAL_CALL SlideshowImpl::isFullScreen()
2591 SolarMutexGuard aSolarGuard;
2592 return maPresSettings.mbFullScreen;
2595 sal_Bool SAL_CALL SlideshowImpl::getMouseVisible()
2597 SolarMutexGuard aSolarGuard;
2598 return maPresSettings.mbMouseVisible;
2601 void SAL_CALL SlideshowImpl::setMouseVisible( sal_Bool bVisible )
2603 SolarMutexGuard aSolarGuard;
2604 if( maPresSettings.mbMouseVisible != bool(bVisible) )
2606 maPresSettings.mbMouseVisible = bVisible;
2607 if( mpShowWindow )
2608 mpShowWindow->SetMouseAutoHide( !maPresSettings.mbMouseVisible );
2612 sal_Bool SAL_CALL SlideshowImpl::getUsePen()
2614 SolarMutexGuard aSolarGuard;
2615 return mbUsePen;
2618 void SAL_CALL SlideshowImpl::setUsePen( sal_Bool bMouseAsPen )
2620 SolarMutexGuard aSolarGuard;
2621 mbUsePen = bMouseAsPen;
2622 if( mxShow.is() ) try
2624 // For Pencolor;
2625 Any aValue;
2626 if( mbUsePen )
2627 aValue <<= mnUserPaintColor;
2628 beans::PropertyValue aPenProp;
2629 aPenProp.Name = "UserPaintColor";
2630 aPenProp.Value = aValue;
2631 mxShow->setProperty( aPenProp );
2633 //for StrokeWidth :
2634 if( mbUsePen )
2636 beans::PropertyValue aPenPropWidth;
2637 aPenPropWidth.Name = "UserPaintStrokeWidth";
2638 aPenPropWidth.Value <<= mdUserPaintStrokeWidth;
2639 mxShow->setProperty( aPenPropWidth );
2641 // for Pen Mode
2642 beans::PropertyValue aPenPropSwitchPenMode;
2643 aPenPropSwitchPenMode.Name = "SwitchPenMode";
2644 aPenPropSwitchPenMode.Value <<= true;
2645 mxShow->setProperty( aPenPropSwitchPenMode );
2648 catch( Exception& )
2650 SAL_WARN( "sd", "sd::SlideshowImpl::setUsePen(), exception caught: "
2651 << comphelper::anyToString( cppu::getCaughtException() ) );
2655 double SAL_CALL SlideshowImpl::getPenWidth()
2657 SolarMutexGuard aSolarGuard;
2658 return mdUserPaintStrokeWidth;
2661 void SAL_CALL SlideshowImpl::setPenWidth( double dStrokeWidth )
2663 SolarMutexGuard aSolarGuard;
2664 mdUserPaintStrokeWidth = dStrokeWidth;
2665 setUsePen( true ); // enable pen mode, update color and width
2668 sal_Int32 SAL_CALL SlideshowImpl::getPenColor()
2670 SolarMutexGuard aSolarGuard;
2671 return mnUserPaintColor;
2674 void SAL_CALL SlideshowImpl::setPenColor( sal_Int32 nColor )
2676 SolarMutexGuard aSolarGuard;
2677 mnUserPaintColor = nColor;
2678 setUsePen( true ); // enable pen mode, update color
2681 void SlideshowImpl::setEraseAllInk(bool bEraseAllInk)
2683 if( bEraseAllInk )
2685 SolarMutexGuard aSolarGuard;
2686 if( mxShow.is() ) try
2688 beans::PropertyValue aPenPropEraseAllInk;
2689 aPenPropEraseAllInk.Name = "EraseAllInk";
2690 aPenPropEraseAllInk.Value <<= bEraseAllInk;
2691 mxShow->setProperty( aPenPropEraseAllInk );
2693 catch( Exception& )
2695 SAL_WARN( "sd.slideshow", "sd::SlideshowImpl::setEraseAllInk(), "
2696 "exception caught: " << comphelper::anyToString( cppu::getCaughtException() ));
2701 // XSlideShowController Methods
2702 sal_Bool SAL_CALL SlideshowImpl::isRunning( )
2704 SolarMutexGuard aSolarGuard;
2705 return mxShow.is();
2708 void SAL_CALL SlideshowImpl::gotoNextEffect( )
2710 SolarMutexGuard aSolarGuard;
2712 if( mxShow.is() && mpSlideController.get() && mpShowWindow )
2714 if( mbIsPaused )
2715 resume();
2717 const ShowWindowMode eMode = mpShowWindow->GetShowWindowMode();
2718 if( eMode == SHOWWINDOWMODE_END )
2720 endPresentation();
2722 else if( (eMode == SHOWWINDOWMODE_PAUSE) || (eMode == SHOWWINDOWMODE_BLANK) )
2724 mpShowWindow->RestartShow();
2726 else
2728 mxShow->nextEffect();
2729 update();
2734 void SAL_CALL SlideshowImpl::gotoPreviousEffect( )
2736 SolarMutexGuard aSolarGuard;
2738 if( mxShow.is() && mpSlideController.get() && mpShowWindow )
2740 if( mbIsPaused )
2741 resume();
2743 const ShowWindowMode eMode = mpShowWindow->GetShowWindowMode();
2744 if( (eMode == SHOWWINDOWMODE_PAUSE) || (eMode == SHOWWINDOWMODE_BLANK) )
2746 mpShowWindow->RestartShow();
2748 else
2750 mxShow->previousEffect();
2751 update();
2756 void SAL_CALL SlideshowImpl::gotoFirstSlide( )
2758 SolarMutexGuard aSolarGuard;
2760 if( mpShowWindow && mpSlideController.get() )
2762 if( mbIsPaused )
2763 resume();
2765 if( mpShowWindow->GetShowWindowMode() == SHOWWINDOWMODE_END )
2767 if( mpSlideController->getSlideIndexCount() )
2768 mpShowWindow->RestartShow( 0);
2770 else
2772 displaySlideIndex( 0 );
2777 void SAL_CALL SlideshowImpl::gotoNextSlide( )
2779 SolarMutexGuard aSolarGuard;
2781 if( mbIsPaused )
2782 resume();
2784 const ShowWindowMode eMode = mpShowWindow->GetShowWindowMode();
2785 if( (eMode == SHOWWINDOWMODE_PAUSE) || (eMode == SHOWWINDOWMODE_BLANK) )
2787 mpShowWindow->RestartShow();
2789 else
2791 // if this is a show, ignore user inputs and
2792 // start 20ms timer to reenable inputs to filter
2793 // buffered inputs during slide transition
2794 if( meAnimationMode == ANIMATIONMODE_SHOW )
2796 mbInputFreeze = true;
2797 maInputFreezeTimer.Start();
2800 if( mpSlideController.get() )
2802 if( mpSlideController->nextSlide() )
2804 displayCurrentSlide();
2806 else
2808 stopSound();
2810 if( meAnimationMode == ANIMATIONMODE_PREVIEW )
2812 endPresentation();
2814 else if( maPresSettings.mbEndless )
2816 if( maPresSettings.mnPauseTimeout )
2818 if( mpShowWindow )
2820 if ( maPresSettings.mbShowPauseLogo )
2822 Graphic aGraphic(SfxApplication::GetApplicationLogo(360));
2823 mpShowWindow->SetPauseMode( maPresSettings.mnPauseTimeout, &aGraphic );
2825 else
2826 mpShowWindow->SetPauseMode( maPresSettings.mnPauseTimeout );
2829 else
2831 displaySlideIndex( 0 );
2834 else
2836 if( mpShowWindow )
2838 mpShowWindow->SetEndMode();
2839 if( !mpViewShell->GetDoc()->IsStartWithPresentation() )
2840 pause();
2848 void SAL_CALL SlideshowImpl::gotoPreviousSlide( )
2850 gotoPreviousSlide(false);
2853 void SlideshowImpl::gotoPreviousSlide (const bool bSkipAllMainSequenceEffects)
2855 SolarMutexGuard aSolarGuard;
2857 if( mxShow.is() && mpSlideController.get() ) try
2859 if( mbIsPaused )
2860 resume();
2862 const ShowWindowMode eMode = mpShowWindow->GetShowWindowMode();
2863 if( eMode == SHOWWINDOWMODE_END )
2865 mpShowWindow->RestartShow( mpSlideController->getCurrentSlideIndex() );
2867 else if( (eMode == SHOWWINDOWMODE_PAUSE) || (eMode == SHOWWINDOWMODE_BLANK) )
2869 mpShowWindow->RestartShow();
2871 else
2873 if( mpSlideController->previousSlide())
2874 displayCurrentSlide(bSkipAllMainSequenceEffects);
2875 else if (bSkipAllMainSequenceEffects)
2877 // We could not go to the previous slide (probably because
2878 // the current slide is already the first one). We still
2879 // have to call displayCurrentSlide because the calling
2880 // slideshow can not determine whether there is a previous
2881 // slide or not and has already prepared for a slide change.
2882 // This slide change has to be completed now, even when
2883 // changing to the same slide.
2884 // Note that in this special case we do NOT pass
2885 // bSkipAllMainSequenceEffects because we display the same
2886 // slide as before and do not want to show all its effects.
2887 displayCurrentSlide();
2891 catch( Exception& )
2893 SAL_WARN( "sd", "sd::SlideshowImpl::gotoPreviousSlide(), exception caught: "
2894 << comphelper::anyToString( cppu::getCaughtException() ) );
2898 void SAL_CALL SlideshowImpl::gotoLastSlide()
2900 SolarMutexGuard aSolarGuard;
2902 if( mpSlideController.get() )
2904 if( mbIsPaused )
2905 resume();
2907 const sal_Int32 nLastSlideIndex = mpSlideController->getSlideIndexCount() - 1;
2908 if( nLastSlideIndex >= 0 )
2910 if( mpShowWindow->GetShowWindowMode() == SHOWWINDOWMODE_END )
2912 mpShowWindow->RestartShow( nLastSlideIndex );
2914 else
2916 displaySlideIndex( nLastSlideIndex );
2922 void SAL_CALL SlideshowImpl::gotoBookmark( const OUString& rBookmark )
2924 SolarMutexGuard aSolarGuard;
2926 if( mbIsPaused )
2927 resume();
2929 sal_Int32 nSlideNumber = getSlideNumberForBookmark( rBookmark );
2930 if( nSlideNumber != -1 )
2931 displaySlideNumber( nSlideNumber );
2934 void SAL_CALL SlideshowImpl::gotoSlide( const Reference< XDrawPage >& xSlide )
2936 SolarMutexGuard aSolarGuard;
2938 if( mpSlideController.get() && xSlide.is() )
2940 if( mbIsPaused )
2941 resume();
2943 const sal_Int32 nSlideCount = mpSlideController->getSlideNumberCount();
2944 for( sal_Int32 nSlide = 0; nSlide < nSlideCount; nSlide++ )
2946 if( mpSlideController->getSlideByNumber( nSlide ) == xSlide )
2948 displaySlideNumber( nSlide );
2954 void SAL_CALL SlideshowImpl::gotoSlideIndex( sal_Int32 nIndex )
2956 SolarMutexGuard aSolarGuard;
2958 if( mbIsPaused )
2959 resume();
2961 displaySlideIndex( nIndex );
2964 void SAL_CALL SlideshowImpl::stopSound( )
2966 SolarMutexGuard aSolarGuard;
2970 if( mxPlayer.is() )
2972 mxPlayer->stop();
2973 mxPlayer.clear();
2976 catch( Exception& )
2978 SAL_WARN( "sd", "sd::SlideshowImpl::stopSound(), exception caught: "
2979 << comphelper::anyToString( cppu::getCaughtException() ) );
2983 // XIndexAccess
2985 ::sal_Int32 SAL_CALL SlideshowImpl::getCount( )
2987 return getSlideCount();
2990 css::uno::Any SAL_CALL SlideshowImpl::getByIndex( ::sal_Int32 Index )
2992 return Any( getSlideByIndex( Index ) );
2995 css::uno::Type SAL_CALL SlideshowImpl::getElementType( )
2997 return cppu::UnoType<XDrawPage>::get();
3000 sal_Bool SAL_CALL SlideshowImpl::hasElements( )
3002 return getSlideCount() != 0;
3005 Reference< XSlideShow > SAL_CALL SlideshowImpl::getSlideShow()
3007 return mxShow;
3010 PresentationSettingsEx::PresentationSettingsEx( const PresentationSettingsEx& r )
3011 : PresentationSettings( r )
3012 , mbRehearseTimings(r.mbRehearseTimings)
3013 , mbPreview(r.mbPreview)
3014 , mpParentWindow( nullptr )
3018 PresentationSettingsEx::PresentationSettingsEx( PresentationSettings const & r )
3019 : PresentationSettings( r )
3020 , mbRehearseTimings(false)
3021 , mbPreview(false)
3022 , mpParentWindow(nullptr)
3026 void PresentationSettingsEx::SetArguments( const Sequence< PropertyValue >& rArguments )
3028 sal_Int32 nArguments = rArguments.getLength();
3029 const PropertyValue* pValue = rArguments.getConstArray();
3031 while( nArguments-- )
3033 SetPropertyValue( pValue->Name, pValue->Value );
3034 pValue++;
3038 void PresentationSettingsEx::SetPropertyValue( const OUString& rProperty, const Any& rValue )
3040 if ( rProperty == "RehearseTimings" )
3042 if( rValue >>= mbRehearseTimings )
3043 return;
3045 else if ( rProperty == "Preview" )
3047 if( rValue >>= mbPreview )
3048 return;
3050 else if ( rProperty == "AnimationNode" )
3052 if( rValue >>= mxAnimationNode )
3053 return;
3055 else if ( rProperty == "ParentWindow" )
3057 Reference< XWindow > xWindow;
3058 if( rValue >>= xWindow )
3060 mpParentWindow = xWindow.is() ? VCLUnoHelper::GetWindow( xWindow )
3061 : VclPtr<vcl::Window>();
3062 return;
3065 else if ( rProperty == "AllowAnimations" )
3067 if( rValue >>= mbAnimationAllowed )
3068 return;
3070 else if ( rProperty == "FirstPage" )
3072 OUString aPresPage;
3073 if( rValue >>= aPresPage )
3075 maPresPage = getUiNameFromPageApiNameImpl(aPresPage);
3076 mbCustomShow = false;
3077 mbAll = false;
3078 return;
3080 else
3082 if( rValue >>= mxStartPage )
3083 return;
3086 else if ( rProperty == "IsAlwaysOnTop" )
3088 if( rValue >>= mbAlwaysOnTop )
3089 return;
3091 else if ( rProperty == "IsAutomatic" )
3093 if( rValue >>= mbManual )
3094 return;
3096 else if ( rProperty == "IsEndless" )
3098 if( rValue >>= mbEndless )
3099 return;
3101 else if ( rProperty == "IsFullScreen" )
3103 if( rValue >>= mbFullScreen )
3104 return;
3106 else if ( rProperty == "IsMouseVisible" )
3108 if( rValue >>= mbMouseVisible )
3109 return;
3111 else if ( rProperty == "Pause" )
3113 sal_Int32 nPause = -1;
3114 if( (rValue >>= nPause) && (nPause >= 0) )
3116 mnPauseTimeout = nPause;
3117 return;
3120 else if ( rProperty == "UsePen" )
3122 if( rValue >>= mbMouseAsPen )
3123 return;
3125 throw IllegalArgumentException();
3128 // XAnimationListener
3130 SlideShowListenerProxy::SlideShowListenerProxy( const rtl::Reference< SlideshowImpl >& xController, const css::uno::Reference< css::presentation::XSlideShow >& xSlideShow )
3131 : maListeners( m_aMutex )
3132 , mxController( xController )
3133 , mxSlideShow( xSlideShow )
3137 SlideShowListenerProxy::~SlideShowListenerProxy()
3141 void SlideShowListenerProxy::addAsSlideShowListener()
3143 if( mxSlideShow.is() )
3145 Reference< XSlideShowListener > xSlideShowListener( this );
3146 mxSlideShow->addSlideShowListener( xSlideShowListener );
3150 void SlideShowListenerProxy::removeAsSlideShowListener()
3152 if( mxSlideShow.is() )
3154 Reference< XSlideShowListener > xSlideShowListener( this );
3155 mxSlideShow->removeSlideShowListener( xSlideShowListener );
3159 void SlideShowListenerProxy::addShapeEventListener( const css::uno::Reference< css::drawing::XShape >& xShape )
3161 if( mxSlideShow.is() )
3163 Reference< XShapeEventListener > xListener( this );
3164 mxSlideShow->addShapeEventListener( xListener, xShape );
3168 void SlideShowListenerProxy::removeShapeEventListener( const css::uno::Reference< css::drawing::XShape >& xShape )
3170 if( mxSlideShow.is() )
3172 Reference< XShapeEventListener > xListener( this );
3173 mxSlideShow->removeShapeEventListener( xListener, xShape );
3177 void SlideShowListenerProxy::addSlideShowListener( const css::uno::Reference< css::presentation::XSlideShowListener >& xListener )
3179 maListeners.addInterface(xListener);
3182 void SlideShowListenerProxy::removeSlideShowListener( const css::uno::Reference< css::presentation::XSlideShowListener >& xListener )
3184 maListeners.removeInterface(xListener);
3187 void SAL_CALL SlideShowListenerProxy::beginEvent( const Reference< XAnimationNode >& xNode )
3189 ::osl::MutexGuard aGuard( m_aMutex );
3191 if( maListeners.getLength() >= 0 )
3193 maListeners.forEach<XSlideShowListener>(
3194 [&] (Reference<XAnimationListener> const& xListener) {
3195 return xListener->beginEvent(xNode);
3196 } );
3200 void SAL_CALL SlideShowListenerProxy::endEvent( const Reference< XAnimationNode >& xNode )
3202 ::osl::MutexGuard aGuard( m_aMutex );
3204 if( maListeners.getLength() >= 0 )
3206 maListeners.forEach<XSlideShowListener>(
3207 [&] (Reference<XAnimationListener> const& xListener) {
3208 return xListener->endEvent(xNode);
3209 } );
3213 void SAL_CALL SlideShowListenerProxy::repeat( const Reference< XAnimationNode >& xNode, ::sal_Int32 nRepeat )
3215 ::osl::MutexGuard aGuard( m_aMutex );
3217 if( maListeners.getLength() >= 0 )
3219 maListeners.forEach<XSlideShowListener>(
3220 [&] (Reference<XAnimationListener> const& xListener) {
3221 return xListener->repeat(xNode, nRepeat);
3222 } );
3226 // css::presentation::XSlideShowListener:
3228 void SAL_CALL SlideShowListenerProxy::paused( )
3230 ::osl::MutexGuard aGuard( m_aMutex );
3232 maListeners.forEach<XSlideShowListener>(
3233 [](uno::Reference<presentation::XSlideShowListener> const& xListener)
3235 xListener->paused();
3239 void SAL_CALL SlideShowListenerProxy::resumed( )
3241 ::osl::MutexGuard aGuard( m_aMutex );
3243 maListeners.forEach<XSlideShowListener>(
3244 [](uno::Reference<presentation::XSlideShowListener> const& xListener)
3246 xListener->resumed();
3250 void SAL_CALL SlideShowListenerProxy::slideTransitionStarted( )
3252 ::osl::MutexGuard aGuard( m_aMutex );
3254 maListeners.forEach<XSlideShowListener>(
3255 [](uno::Reference<presentation::XSlideShowListener> const& xListener)
3257 xListener->slideTransitionStarted();
3261 void SAL_CALL SlideShowListenerProxy::slideTransitionEnded( )
3263 ::osl::MutexGuard aGuard( m_aMutex );
3265 maListeners.forEach<XSlideShowListener>(
3266 [](uno::Reference<presentation::XSlideShowListener> const& xListener)
3268 xListener->slideTransitionEnded ();
3272 void SAL_CALL SlideShowListenerProxy::slideAnimationsEnded( )
3274 ::osl::MutexGuard aGuard( m_aMutex );
3276 maListeners.forEach<XSlideShowListener>(
3277 [](uno::Reference<presentation::XSlideShowListener> const& xListener)
3279 xListener->slideAnimationsEnded ();
3283 void SlideShowListenerProxy::slideEnded(sal_Bool bReverse)
3286 ::osl::MutexGuard aGuard( m_aMutex );
3288 if( maListeners.getLength() >= 0 )
3290 maListeners.forEach<XSlideShowListener>(
3291 [&] (Reference<XSlideShowListener> const& xListener) {
3292 return xListener->slideEnded(bReverse);
3293 } );
3298 SolarMutexGuard aSolarGuard;
3299 if( mxController.is() )
3300 mxController->slideEnded(bReverse);
3304 void SlideShowListenerProxy::hyperLinkClicked( OUString const& aHyperLink )
3307 ::osl::MutexGuard aGuard( m_aMutex );
3309 if( maListeners.getLength() >= 0 )
3311 maListeners.forEach<XSlideShowListener>(
3312 [&] (Reference<XSlideShowListener> const& xListener) {
3313 return xListener->hyperLinkClicked(aHyperLink);
3314 } );
3319 SolarMutexGuard aSolarGuard;
3320 if( mxController.is() )
3321 mxController->hyperLinkClicked(aHyperLink);
3325 // XEventListener
3327 void SAL_CALL SlideShowListenerProxy::disposing( const css::lang::EventObject& aDisposeEvent )
3329 maListeners.disposeAndClear( aDisposeEvent );
3330 mxController.clear();
3331 mxSlideShow.clear();
3334 // XShapeEventListener
3336 void SAL_CALL SlideShowListenerProxy::click( const Reference< XShape >& xShape, const css::awt::MouseEvent& /*aOriginalEvent*/ )
3338 SolarMutexGuard aSolarGuard;
3339 if( mxController.is() )
3340 mxController->click(xShape );
3343 } // namespace ::sd
3345 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */