bump product version to 5.0.4.1
[LibreOffice.git] / sd / source / ui / slideshow / slideshowimpl.cxx
blobbf61d37b827bea8f2d756b6a18dbd76738854765
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/frame/XComponentLoader.hpp>
24 #include <com/sun/star/lang/XInitialization.hpp>
25 #include <com/sun/star/document/XEventsSupplier.hpp>
26 #include <com/sun/star/drawing/XMasterPageTarget.hpp>
27 #include <com/sun/star/container/XNameReplace.hpp>
28 #include <com/sun/star/beans/PropertyValue.hpp>
29 #include <com/sun/star/beans/XPropertySetInfo.hpp>
30 #include <com/sun/star/beans/XPropertySet.hpp>
31 #include <com/sun/star/awt/SystemPointer.hpp>
32 #include <com/sun/star/util/URLTransformer.hpp>
33 #include <com/sun/star/util/XURLTransformer.hpp>
34 #include <com/sun/star/frame/XDispatch.hpp>
35 #include <com/sun/star/frame/XLayoutManager.hpp>
36 #include <com/sun/star/presentation/SlideShow.hpp>
37 #include <svl/aeitem.hxx>
38 #include <svl/urihelper.hxx>
40 #include <toolkit/helper/vclunohelper.hxx>
42 #include <sfx2/infobar.hxx>
43 #include <sfx2/imagemgr.hxx>
44 #include <sfx2/request.hxx>
45 #include <sfx2/docfile.hxx>
46 #include <sfx2/app.hxx>
47 #include <svx/unoapi.hxx>
48 #include <svx/svdoole2.hxx>
49 #include <sfx2/templdlg.hxx>
50 #include <svx/f3dchild.hxx>
51 #include <svx/imapdlg.hxx>
52 #include <svx/fontwork.hxx>
53 #include <svx/SvxColorChildWindow.hxx>
54 #include <svx/bmpmask.hxx>
55 #include <svx/srchdlg.hxx>
56 #include <svx/hyperdlg.hxx>
57 #include "NavigatorChildWindow.hxx"
58 #include "AnimationChildWindow.hxx"
59 #include "notifydocumentevent.hxx"
60 #include <slideshowimpl.hxx>
61 #include <slideshowviewimpl.hxx>
62 #include <pgjump.hxx>
63 #include "PaneHider.hxx"
65 #include "glob.hrc"
66 #include "res_bmp.hrc"
67 #include "sdresid.hxx"
68 #include "vcl/canvastools.hxx"
69 #include <vcl/settings.hxx>
71 #include "comphelper/anytostring.hxx"
72 #include "cppuhelper/exc_hlp.hxx"
73 #include "rtl/ref.hxx"
74 #include "slideshow.hrc"
75 #include "canvas/elapsedtime.hxx"
76 #include "avmedia/mediawindow.hxx"
77 #include "svtools/colrdlg.hxx"
78 #include "RemoteServer.hxx"
79 #include "customshowlist.hxx"
80 #include "unopage.hxx"
82 #include <boost/bind.hpp>
84 using ::cppu::OInterfaceContainerHelper;
85 using ::com::sun::star::animations::XAnimationNode;
86 using ::com::sun::star::animations::XAnimationListener;
87 using ::com::sun::star::awt::XWindow;
88 using namespace ::com::sun::star;
89 using namespace ::com::sun::star::lang;
90 using namespace ::com::sun::star::uno;
91 using namespace ::com::sun::star::drawing;
92 using namespace ::com::sun::star::container;
93 using namespace ::com::sun::star::document;
94 using namespace ::com::sun::star::presentation;
95 using namespace ::com::sun::star::beans;
97 namespace sd
99 /** Slots, which will be disabled in the slide show and are managed by Sfx.
100 Have to be sorted in the order of the SIDs */
101 static sal_uInt16 const pAllowed[] =
103 SID_OPENDOC , // 5501 ///< that internally jumps work
104 SID_JUMPTOMARK , // 5598
105 SID_OPENHYPERLINK , // 6676
106 SID_NAVIGATOR , // 10366
107 SID_PRESENTATION_END , // 27218
108 SID_NAVIGATOR_PAGENAME , // 27287
109 SID_NAVIGATOR_STATE , // 27288
110 SID_NAVIGATOR_INIT , // 27289
111 SID_NAVIGATOR_PEN , // 27291
112 SID_NAVIGATOR_PAGE , // 27292
113 SID_NAVIGATOR_OBJECT // 27293
116 class AnimationSlideController
118 public:
119 enum Mode { ALL, FROM, CUSTOM, PREVIEW };
121 public:
122 AnimationSlideController( Reference< XIndexAccess > xSlides, Mode eMode );
124 void setStartSlideNumber( sal_Int32 nSlideNumber ) { mnStartSlideNumber = nSlideNumber; }
125 sal_Int32 getStartSlideIndex() const;
127 sal_Int32 getCurrentSlideNumber() const;
128 sal_Int32 getCurrentSlideIndex() const;
130 sal_Int32 getSlideIndexCount() const { return maSlideNumbers.size(); }
131 sal_Int32 getSlideNumberCount() const { return mnSlideCount; }
133 sal_Int32 getSlideNumber( sal_Int32 nSlideIndex ) const;
135 void insertSlideNumber( sal_Int32 nSlideNumber, bool bVisible = true );
136 void setPreviewNode( const Reference< XAnimationNode >& xPreviewNode );
138 bool jumpToSlideIndex( sal_Int32 nNewSlideIndex );
139 bool jumpToSlideNumber( sal_Int32 nNewSlideIndex );
141 bool nextSlide();
142 bool previousSlide();
144 void displayCurrentSlide( const Reference< XSlideShow >& xShow,
145 const Reference< XDrawPagesSupplier>& xDrawPages,
146 const bool bSkipAllMainSequenceEffects );
148 sal_Int32 getNextSlideIndex() const;
149 sal_Int32 getPreviousSlideIndex() const;
151 bool isVisibleSlideNumber( sal_Int32 nSlideNumber ) const;
153 Reference< XDrawPage > getSlideByNumber( sal_Int32 nSlideNumber ) const;
155 sal_Int32 getNextSlideNumber() const;
157 bool hasSlides() const { return !maSlideNumbers.empty(); }
159 private:
160 bool getSlideAPI( sal_Int32 nSlideNumber, Reference< XDrawPage >& xSlide, Reference< XAnimationNode >& xAnimNode );
161 sal_Int32 findSlideIndex( sal_Int32 nSlideNumber ) const;
163 bool isValidIndex( sal_Int32 nIndex ) const { return (nIndex >= 0) && (nIndex < (sal_Int32)maSlideNumbers.size()); }
164 bool isValidSlideNumber( sal_Int32 nSlideNumber ) const { return (nSlideNumber >= 0) && (nSlideNumber < mnSlideCount); }
166 private:
167 Mode meMode;
168 sal_Int32 mnStartSlideNumber;
169 std::vector< sal_Int32 > maSlideNumbers;
170 std::vector< bool > maSlideVisible;
171 std::vector< bool > maSlideVisited;
172 Reference< XAnimationNode > mxPreviewNode;
173 sal_Int32 mnSlideCount;
174 sal_Int32 mnCurrentSlideIndex;
175 sal_Int32 mnHiddenSlideNumber;
176 Reference< XIndexAccess > mxSlides;
179 Reference< XDrawPage > AnimationSlideController::getSlideByNumber( sal_Int32 nSlideNumber ) const
181 Reference< XDrawPage > xSlide;
182 if( mxSlides.is() && (nSlideNumber >= 0) && (nSlideNumber < mxSlides->getCount()) )
183 mxSlides->getByIndex( nSlideNumber ) >>= xSlide;
184 return xSlide;
187 bool AnimationSlideController::isVisibleSlideNumber( sal_Int32 nSlideNumber ) const
189 sal_Int32 nIndex = findSlideIndex( nSlideNumber );
191 if( nIndex != -1 )
192 return maSlideVisible[ nIndex ];
193 else
194 return false;
197 void AnimationSlideController::setPreviewNode( const Reference< XAnimationNode >& xPreviewNode )
199 mxPreviewNode = xPreviewNode;
202 AnimationSlideController::AnimationSlideController( Reference< XIndexAccess > xSlides, Mode eMode )
203 : meMode( eMode )
204 , mnStartSlideNumber(-1)
205 , mnSlideCount( 0 )
206 , mnCurrentSlideIndex(0)
207 , mnHiddenSlideNumber( -1 )
208 , mxSlides( xSlides )
210 if( mxSlides.is() )
211 mnSlideCount = xSlides->getCount();
214 sal_Int32 AnimationSlideController::getStartSlideIndex() const
216 if( mnStartSlideNumber >= 0 )
218 sal_Int32 nIndex;
219 const sal_Int32 nCount = maSlideNumbers.size();
221 for( nIndex = 0; nIndex < nCount; nIndex++ )
223 if( maSlideNumbers[nIndex] == mnStartSlideNumber )
224 return nIndex;
228 return 0;
231 sal_Int32 AnimationSlideController::getCurrentSlideNumber() const
233 if( mnHiddenSlideNumber != -1 )
234 return mnHiddenSlideNumber;
235 else if( !maSlideNumbers.empty() )
236 return maSlideNumbers[mnCurrentSlideIndex];
237 else
238 return 0;
241 sal_Int32 AnimationSlideController::getCurrentSlideIndex() const
243 if( mnHiddenSlideNumber != -1 )
244 return -1;
245 else
246 return mnCurrentSlideIndex;
249 bool AnimationSlideController::jumpToSlideIndex( sal_Int32 nNewSlideIndex )
251 if( isValidIndex( nNewSlideIndex ) )
253 mnCurrentSlideIndex = nNewSlideIndex;
254 mnHiddenSlideNumber = -1;
255 maSlideVisited[mnCurrentSlideIndex] = true;
256 return true;
258 else
260 return false;
264 bool AnimationSlideController::jumpToSlideNumber( sal_Int32 nNewSlideNumber )
266 sal_Int32 nIndex = findSlideIndex( nNewSlideNumber );
267 if( isValidIndex( nIndex ) )
269 return jumpToSlideIndex( nIndex );
271 else if( (nNewSlideNumber >= 0) && (nNewSlideNumber < mnSlideCount) )
273 // jump to a hidden slide
274 mnHiddenSlideNumber = nNewSlideNumber;
275 return true;
277 else
279 return false;
283 sal_Int32 AnimationSlideController::getSlideNumber( sal_Int32 nSlideIndex ) const
285 if( isValidIndex( nSlideIndex ) )
286 return maSlideNumbers[nSlideIndex];
287 else
288 return -1;
291 void AnimationSlideController::insertSlideNumber( sal_Int32 nSlideNumber, bool bVisible /* = true */ )
293 DBG_ASSERT( isValidSlideNumber( nSlideNumber ), "sd::AnimationSlideController::insertSlideNumber(), illegal index" );
294 if( isValidSlideNumber( nSlideNumber ) )
296 maSlideNumbers.push_back( nSlideNumber );
297 maSlideVisible.push_back( bVisible );
298 maSlideVisited.push_back( false );
302 bool AnimationSlideController::getSlideAPI( sal_Int32 nSlideNumber, Reference< XDrawPage >& xSlide, Reference< XAnimationNode >& xAnimNode )
304 if( isValidSlideNumber( nSlideNumber ) ) try
306 xSlide = Reference< XDrawPage >( mxSlides->getByIndex(nSlideNumber), UNO_QUERY_THROW );
308 if( meMode == PREVIEW )
310 xAnimNode = mxPreviewNode;
312 else
314 Reference< animations::XAnimationNodeSupplier > xAnimNodeSupplier( xSlide, UNO_QUERY_THROW );
315 xAnimNode = xAnimNodeSupplier->getAnimationNode();
318 return true;
320 catch( Exception& )
322 OSL_FAIL(
323 OString(OString("sd::AnimationSlideController::getSlideAPI(), "
324 "exception caught: ") +
325 OUStringToOString(
326 comphelper::anyToString( cppu::getCaughtException() ),
327 RTL_TEXTENCODING_UTF8 )).getStr() );
331 return false;
334 sal_Int32 AnimationSlideController::findSlideIndex( sal_Int32 nSlideNumber ) const
336 sal_Int32 nIndex;
337 const sal_Int32 nCount = maSlideNumbers.size();
339 for( nIndex = 0; nIndex < nCount; nIndex++ )
341 if( maSlideNumbers[nIndex] == nSlideNumber )
342 return nIndex;
345 return -1;
348 sal_Int32 AnimationSlideController::getNextSlideIndex() const
350 switch( meMode )
352 case ALL:
354 sal_Int32 nNewSlideIndex = mnCurrentSlideIndex + 1;
355 if( isValidIndex( nNewSlideIndex ) )
357 // if the current slide is not excluded, make sure the
358 // next slide is also not excluded.
359 // if the current slide is excluded, we want to go
360 // to the next slide, even if this is also excluded.
361 if( maSlideVisible[mnCurrentSlideIndex] )
363 while( isValidIndex( nNewSlideIndex ) )
365 if( maSlideVisible[nNewSlideIndex] )
366 break;
368 nNewSlideIndex++;
372 return isValidIndex( nNewSlideIndex ) ? nNewSlideIndex : -1;
375 case FROM:
376 case CUSTOM:
377 return mnHiddenSlideNumber == -1 ? mnCurrentSlideIndex + 1 : mnCurrentSlideIndex;
379 default:
380 case PREVIEW:
381 return -1;
386 sal_Int32 AnimationSlideController::getNextSlideNumber() const
388 sal_Int32 nNextSlideIndex = getNextSlideIndex();
389 if( isValidIndex( nNextSlideIndex ) )
391 return maSlideNumbers[nNextSlideIndex];
393 else
395 return -1;
399 bool AnimationSlideController::nextSlide()
401 return jumpToSlideIndex( getNextSlideIndex() );
404 sal_Int32 AnimationSlideController::getPreviousSlideIndex() const
406 sal_Int32 nNewSlideIndex = mnCurrentSlideIndex - 1;
408 switch( meMode )
410 case ALL:
412 // make sure the previous slide is visible
413 // or was already visited
414 while( isValidIndex( nNewSlideIndex ) )
416 if( maSlideVisible[nNewSlideIndex] || maSlideVisited[nNewSlideIndex] )
417 break;
419 nNewSlideIndex--;
422 break;
425 case PREVIEW:
426 return -1;
428 default:
429 break;
432 return nNewSlideIndex;
435 bool AnimationSlideController::previousSlide()
437 return jumpToSlideIndex( getPreviousSlideIndex() );
440 void AnimationSlideController::displayCurrentSlide( const Reference< XSlideShow >& xShow,
441 const Reference< XDrawPagesSupplier>& xDrawPages,
442 const bool bSkipAllMainSequenceEffects )
444 const sal_Int32 nCurrentSlideNumber = getCurrentSlideNumber();
446 if( xShow.is() && (nCurrentSlideNumber != -1 ) )
448 Reference< XDrawPage > xSlide;
449 Reference< XAnimationNode > xAnimNode;
450 ::std::vector<PropertyValue> aProperties;
452 const sal_Int32 nNextSlideNumber = getNextSlideNumber();
453 if( getSlideAPI( nNextSlideNumber, xSlide, xAnimNode ) )
455 Sequence< Any > aValue(2);
456 aValue[0] <<= xSlide;
457 aValue[1] <<= xAnimNode;
458 aProperties.push_back(
459 PropertyValue( "Prefetch" ,
461 Any(aValue),
462 PropertyState_DIRECT_VALUE));
464 if (bSkipAllMainSequenceEffects)
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.push_back(
471 PropertyValue( "SkipAllMainSequenceEffects",
473 Any(sal_True),
474 PropertyState_DIRECT_VALUE));
475 aProperties.push_back(
476 PropertyValue("SkipSlideTransition",
478 Any(sal_True),
479 PropertyState_DIRECT_VALUE));
482 // Convert vector into uno Sequence.
483 Sequence< PropertyValue > aPropertySequence (aProperties.size());
484 for (int nIndex=0,nCount=aProperties.size();nIndex<nCount; ++nIndex)
485 aPropertySequence[nIndex] = aProperties[nIndex];
487 if( getSlideAPI( nCurrentSlideNumber, xSlide, xAnimNode ) )
488 xShow->displaySlide( xSlide, xDrawPages, xAnimNode, aPropertySequence );
492 SlideshowImpl::SlideshowImpl( const Reference< XPresentation2 >& xPresentation, ViewShell* pViewSh, ::sd::View* pView, SdDrawDocument* pDoc, vcl::Window* pParentWindow )
493 : SlideshowImplBase( m_aMutex )
494 , mxModel(pDoc->getUnoModel(),UNO_QUERY_THROW)
495 , mpView(pView)
496 , mpViewShell(pViewSh)
497 , mpDocSh(pDoc->GetDocSh())
498 , mpDoc(pDoc)
499 , mpNewAttr(0)
500 , mpParentWindow(pParentWindow)
501 , mpShowWindow(0)
502 , mpTimeButton(0)
503 , mnRestoreSlide(0)
504 , maPresSize( -1, -1 )
505 , meAnimationMode(ANIMATIONMODE_SHOW)
506 , mpOldActiveWindow(0)
507 , mnChildMask( 0 )
508 , mbGridVisible(false)
509 , mbBordVisible(false)
510 , mbSlideBorderVisible(false)
511 , mbSetOnlineSpelling(false)
512 , mbDisposed(false)
513 , mbAutoSaveWasOn(false)
514 , mbRehearseTimings(false)
515 , mbDesignMode(false)
516 , mbIsPaused(false)
517 , mbWasPaused(false)
518 , mbInputFreeze(false)
519 , mbActive(false)
520 , maPresSettings( pDoc->getPresentationSettings() )
521 , mnUserPaintColor( 0x80ff0000L )
522 , mbUsePen(false)
523 , mdUserPaintStrokeWidth ( 150.0 )
524 #ifdef ENABLE_ERASER_UI
525 , mbSwitchEraserMode(false)
526 , mnEraseInkSize(100)
527 #endif
528 , mnEntryCounter(0)
529 , mnLastSlideNumber(-1)
530 , msOnClick( "OnClick" )
531 , msBookmark( "Bookmark" )
532 , msVerb( "Verb" )
533 , mnEndShowEvent(0)
534 , mnContextMenuEvent(0)
535 , mxPresentation( xPresentation )
537 if( mpViewShell )
538 mpOldActiveWindow = mpViewShell->GetActiveWindow();
540 maUpdateTimer.SetTimeoutHdl(LINK(this, SlideshowImpl, updateHdl));
542 maDeactivateTimer.SetTimeoutHdl(LINK(this, SlideshowImpl, deactivateHdl));
543 maDeactivateTimer.SetTimeout( 20 );
545 maInputFreezeTimer.SetTimeoutHdl( LINK( this, SlideshowImpl, ReadyForNextInputHdl ) );
546 maInputFreezeTimer.SetTimeout( 20 );
548 SvtSaveOptions aOptions;
550 // no autosave during show
551 if( aOptions.IsAutoSave() )
552 mbAutoSaveWasOn = true;
554 Application::AddEventListener( LINK( this, SlideshowImpl, EventListenerHdl ) );
556 mbUsePen = maPresSettings.mbMouseAsPen;
558 SdOptions* pOptions = SD_MOD()->GetSdOptions(DOCUMENT_TYPE_IMPRESS);
559 if( pOptions )
561 mnUserPaintColor = pOptions->GetPresentationPenColor();
562 mdUserPaintStrokeWidth = pOptions->GetPresentationPenWidth();
566 SlideshowImpl::~SlideshowImpl()
568 SdModule *pModule = SD_MOD();
569 //rhbz#806663 SlideshowImpl can outlive SdModule
570 SdOptions* pOptions = pModule ?
571 pModule->GetSdOptions(DOCUMENT_TYPE_IMPRESS) : NULL;
572 if( pOptions )
574 pOptions->SetPresentationPenColor(mnUserPaintColor);
575 pOptions->SetPresentationPenWidth(mdUserPaintStrokeWidth);
578 Application::RemoveEventListener( LINK( this, SlideshowImpl, EventListenerHdl ) );
580 maDeactivateTimer.Stop();
582 if( !mbDisposed )
584 OSL_FAIL("SlideshowImpl::~SlideshowImpl(), component was not disposed!");
585 disposing();
589 void SAL_CALL SlideshowImpl::disposing()
591 #ifdef ENABLE_SDREMOTE
592 RemoteServer::presentationStopped();
593 #endif
594 if( mxShow.is() && mpDoc )
595 NotifyDocumentEvent( mpDoc, "OnEndPresentation" );
597 if( mbAutoSaveWasOn )
598 setAutoSaveState( true );
600 if( mnEndShowEvent )
601 Application::RemoveUserEvent( mnEndShowEvent );
602 if( mnContextMenuEvent )
603 Application::RemoveUserEvent( mnContextMenuEvent );
605 maInputFreezeTimer.Stop();
607 SolarMutexGuard aSolarGuard;
609 if( !mxShow.is() )
610 return;
612 if( mxPresentation.is() )
613 mxPresentation->end();
615 maUpdateTimer.Stop();
617 removeShapeEvents();
619 if( mxListenerProxy.is() )
620 mxListenerProxy->removeAsSlideShowListener();
624 if( mxView.is() )
625 mxShow->removeView( mxView.get() );
627 Reference< XComponent > xComponent( mxShow, UNO_QUERY );
628 if( xComponent.is() )
629 xComponent->dispose();
631 if( mxView.is() )
632 mxView->dispose();
634 catch( Exception& )
636 OSL_FAIL(
637 OString(OString("sd::SlideshowImpl::stop(), "
638 "exception caught: ") +
639 OUStringToOString(
640 comphelper::anyToString( cppu::getCaughtException() ),
641 RTL_TEXTENCODING_UTF8 )).getStr() );
645 mxShow.clear();
646 mxView.clear();
647 mxListenerProxy.clear();
648 mpSlideController.reset();
650 // take DrawView from presentation window, but give the old window back
651 if( mpShowWindow && mpView )
652 mpView->DeleteWindowFromPaintView( mpShowWindow );
654 if( mpView )
655 mpView->SetAnimationPause( false );
657 if( mpViewShell )
659 mpViewShell->SetActiveWindow(mpOldActiveWindow);
660 if (mpShowWindow)
661 mpShowWindow->SetViewShell( NULL );
664 if( mpView )
665 mpView->InvalidateAllWin();
667 if( maPresSettings.mbFullScreen )
669 #if HAVE_FEATURE_SCRIPTING
670 // restore StarBASICErrorHdl
671 StarBASIC::SetGlobalErrorHdl(maStarBASICGlobalErrorHdl);
672 maStarBASICGlobalErrorHdl = Link<StarBASIC*,bool>();
673 #endif
675 else
677 if( mpShowWindow )
678 mpShowWindow->Hide();
681 if( meAnimationMode == ANIMATIONMODE_SHOW )
683 mpDocSh->SetSlotFilter();
684 mpDocSh->ApplySlotFilter();
686 Help::EnableContextHelp();
687 Help::EnableExtHelp();
689 showChildWindows();
690 mnChildMask = 0UL;
693 // show current window again
694 if( mpViewShell && !mpViewShell->ISA(PresentationViewShell))
696 if( meAnimationMode == ANIMATIONMODE_SHOW )
698 mpViewShell->GetViewShellBase().ShowUIControls (true);
699 mpPaneHider.reset();
701 else if( meAnimationMode == ANIMATIONMODE_PREVIEW )
703 mpViewShell->ShowUIControls (true);
707 if( mpTimeButton )
708 mpTimeButton->Hide();
709 mpTimeButton.disposeAndClear();
711 if( mpShowWindow )
712 mpShowWindow->Hide();
713 mpShowWindow.disposeAndClear();
715 if ( mpViewShell )
717 if( meAnimationMode == ANIMATIONMODE_SHOW )
719 ::sd::Window* pActWin = mpViewShell->GetActiveWindow();
721 if (pActWin)
723 Size aVisSizePixel = pActWin->GetOutputSizePixel();
724 Rectangle aVisAreaWin = pActWin->PixelToLogic( Rectangle( Point(0,0), aVisSizePixel) );
725 mpViewShell->VisAreaChanged(aVisAreaWin);
726 if (mpView)
727 mpView->VisAreaChanged(pActWin);
728 pActWin->GrabFocus();
732 // restart the custom show dialog if he started us
733 if( mpViewShell->IsStartShowWithDialog() && getDispatcher() )
735 mpViewShell->SetStartShowWithDialog( false );
736 getDispatcher()->Execute( SID_CUSTOMSHOW_DLG, SfxCallMode::ASYNCHRON | SfxCallMode::RECORD );
739 mpViewShell->GetViewShellBase().UpdateBorder(true);
742 if( mpShowWindow )
744 mpShowWindow.clear();
747 setActiveXToolbarsVisible( true );
749 Application::DisableNoYieldMode();
750 Application::RemovePostYieldListener(LINK(this, SlideshowImpl, PostYieldListener));
752 mbDisposed = true;
755 bool SlideshowImpl::startPreview(
756 const Reference< XDrawPage >& xDrawPage,
757 const Reference< XAnimationNode >& xAnimationNode,
758 vcl::Window* pParent )
760 bool bRet = false;
764 const Reference<lang::XServiceInfo> xServiceInfo( xDrawPage, UNO_QUERY );
765 if (xServiceInfo.is()) {
766 const Sequence<OUString> supportedServices(
767 xServiceInfo->getSupportedServiceNames() );
768 for ( sal_Int32 pos = supportedServices.getLength(); pos--; ) {
769 if ( supportedServices[pos] == "com.sun.star.drawing.MasterPage" ) {
770 OSL_FAIL("sd::SlideshowImpl::startPreview() "
771 "not allowed on master page!");
772 return false;
777 mxPreviewDrawPage = xDrawPage;
778 mxPreviewAnimationNode = xAnimationNode;
779 meAnimationMode = ANIMATIONMODE_PREVIEW;
781 maPresSettings.mbAll = false;
782 maPresSettings.mbEndless = false;
783 maPresSettings.mbCustomShow = false;
784 maPresSettings.mbManual = false;
785 maPresSettings.mbMouseVisible = false;
786 maPresSettings.mbMouseAsPen = false;
787 maPresSettings.mbLockedPages = false;
788 maPresSettings.mbAlwaysOnTop = false;
789 maPresSettings.mbFullScreen = false;
790 maPresSettings.mbAnimationAllowed = true;
791 maPresSettings.mnPauseTimeout = 0;
792 maPresSettings.mbShowPauseLogo = false;
793 maPresSettings.mbStartWithNavigator = false;
795 Reference< XDrawPagesSupplier > xDrawPages( mpDoc->getUnoModel(), UNO_QUERY_THROW );
796 Reference< XIndexAccess > xSlides( xDrawPages->getDrawPages(), UNO_QUERY_THROW );
797 mpSlideController.reset( new AnimationSlideController( xSlides, AnimationSlideController::PREVIEW ) );
799 sal_Int32 nSlideNumber = 0;
800 Reference< XPropertySet > xSet( mxPreviewDrawPage, UNO_QUERY_THROW );
801 xSet->getPropertyValue( "Number" ) >>= nSlideNumber;
802 mpSlideController->insertSlideNumber( nSlideNumber-1 );
803 mpSlideController->setPreviewNode( xAnimationNode );
805 mpShowWindow = VclPtr<ShowWindow>::Create( this, ((pParent == 0) && mpViewShell) ? mpParentWindow.get() : pParent );
806 if( mpViewShell )
808 mpViewShell->SetActiveWindow( mpShowWindow );
809 mpShowWindow->SetViewShell (mpViewShell);
810 mpViewShell->ShowUIControls (false);
813 if( mpView )
815 mpView->AddWindowToPaintView( mpShowWindow, 0 );
816 mpView->SetAnimationPause( true );
819 // call resize handler
820 if( pParent )
822 maPresSize = pParent->GetSizePixel();
824 else if( mpViewShell )
826 Rectangle aContentRect (mpViewShell->GetViewShellBase().getClientRectangle());
827 if (AllSettings::GetLayoutRTL())
829 aContentRect.Left() = aContentRect.Right();
830 aContentRect.Right() += aContentRect.Right();
832 maPresSize = aContentRect.GetSize();
833 mpShowWindow->SetPosPixel( aContentRect.TopLeft() );
835 else
837 OSL_FAIL("sd::SlideshowImpl::startPreview(), I need either a parent window or a viewshell!");
839 resize( maPresSize );
841 sal_Int32 nPropertyCount = 1;
842 if( mxPreviewAnimationNode.is() )
843 nPropertyCount++;
845 Sequence< beans::PropertyValue > aProperties(nPropertyCount);
846 aProperties[0].Name = "AutomaticAdvancement";
847 aProperties[0].Value = uno::makeAny( (double)1.0 ); // one second timeout
849 if( mxPreviewAnimationNode.is() )
851 aProperties[1].Name = "NoSlideTransitions";
852 aProperties[1].Value = uno::makeAny( sal_True );
855 bRet = startShowImpl( aProperties );
857 if( mpShowWindow != nullptr && meAnimationMode == ANIMATIONMODE_PREVIEW )
858 mpShowWindow->SetPreviewMode();
861 catch( Exception& )
863 OSL_FAIL(
864 OString(OString("sd::SlideshowImpl::startPreview(), "
865 "exception caught: ") +
866 OUStringToOString(
867 comphelper::anyToString( cppu::getCaughtException() ),
868 RTL_TEXTENCODING_UTF8 )).getStr() );
869 bRet = false;
872 return bRet;
875 bool SlideshowImpl::startShow( PresentationSettingsEx* pPresSettings )
877 const rtl::Reference<SlideshowImpl> this_(this);
879 DBG_ASSERT( !mxShow.is(), "sd::SlideshowImpl::startShow(), called twice!" );
880 if( mxShow.is() )
881 return true;
882 DBG_ASSERT( mpParentWindow!=nullptr, "sd::SlideshowImpl::startShow() called without parent window" );
883 if (mpParentWindow == nullptr)
884 return false;
886 // Autoplay (pps/ppsx)
887 if (mpViewShell->GetDoc()->IsStartWithPresentation()){
888 mpViewShell->GetDoc()->SetExitAfterPresenting(true);
891 bool bRet = false;
895 if( pPresSettings )
897 maPresSettings = *pPresSettings;
898 mbRehearseTimings = pPresSettings->mbRehearseTimings;
901 OUString aPresSlide( maPresSettings.maPresPage );
902 SdPage* pStartPage = mpViewShell->GetActualPage();
903 bool bStartWithActualSlide = pStartPage;
905 // times should be measured?
906 if( mbRehearseTimings )
908 maPresSettings.mbEndless = false;
909 maPresSettings.mbManual = true;
910 maPresSettings.mbMouseVisible = true;
911 maPresSettings.mbMouseAsPen = false;
912 maPresSettings.mnPauseTimeout = 0;
913 maPresSettings.mbShowPauseLogo = false;
914 maPresSettings.mbStartWithNavigator = false;
917 if( pStartPage )
919 if( pStartPage->GetPageKind() == PK_NOTES )
921 // we are in notes page mode, so get
922 // the corresponding draw page
923 const sal_uInt16 nPgNum = ( pStartPage->GetPageNum() - 2 ) >> 1;
924 pStartPage = mpDoc->GetSdPage( nPgNum, PK_STANDARD );
928 if( bStartWithActualSlide )
930 if ( aPresSlide.isEmpty())
932 // no preset slide yet, so pick current on one
933 aPresSlide = pStartPage->GetName();
934 // if the starting slide is hidden, we can't set slide controller to ALL mode
935 maPresSettings.mbAll = !pStartPage->IsExcluded();
938 if( meAnimationMode != ANIMATIONMODE_SHOW )
940 if( pStartPage->GetPageKind() == PK_STANDARD )
942 maPresSettings.mbAll = false;
947 // build page list
948 createSlideList( maPresSettings.mbAll, aPresSlide );
950 // remember Slide number from where the show was started
951 if( pStartPage )
952 mnRestoreSlide = ( pStartPage->GetPageNum() - 1 ) / 2;
954 if( mpSlideController->hasSlides() )
956 // hide child windows
957 hideChildWindows();
959 mpShowWindow = VclPtr<ShowWindow>::Create( this, mpParentWindow );
960 mpShowWindow->SetMouseAutoHide( !maPresSettings.mbMouseVisible );
961 mpViewShell->SetActiveWindow( mpShowWindow );
962 mpShowWindow->SetViewShell (mpViewShell);
963 mpViewShell->GetViewShellBase().ShowUIControls (false);
964 // Hide the side panes for in-place presentations.
965 if ( ! maPresSettings.mbFullScreen)
966 mpPaneHider.reset(new PaneHider(*mpViewShell,this));
968 if( getViewFrame() )
969 getViewFrame()->SetChildWindow( SID_NAVIGATOR, maPresSettings.mbStartWithNavigator );
971 // these Slots are forbidden in other views for this document
972 if( mpDocSh )
974 mpDocSh->SetSlotFilter( true, sizeof( pAllowed ) / sizeof( sal_uInt16 ), pAllowed );
975 mpDocSh->ApplySlotFilter();
978 Help::DisableContextHelp();
979 Help::DisableExtHelp();
981 if( maPresSettings.mbFullScreen )
983 #if HAVE_FEATURE_SCRIPTING
984 // disable basic ide error handling
985 maStarBASICGlobalErrorHdl = StarBASIC::GetGlobalErrorHdl();
986 StarBASIC::SetGlobalErrorHdl( Link<StarBASIC*,bool>() );
987 #endif
990 // call resize handler
991 maPresSize = mpParentWindow->GetSizePixel();
992 if (!maPresSettings.mbFullScreen)
994 const Rectangle& aClientRect = mpViewShell->GetViewShellBase().getClientRectangle();
995 maPresSize = aClientRect.GetSize();
996 mpShowWindow->SetPosPixel( aClientRect.TopLeft() );
997 resize( maPresSize );
1000 // #i41824#
1001 // Note: In FullScreen Mode the OS (window manager) sends a resize to
1002 // the WorkWindow once it actually resized it to full size. The
1003 // WorkWindow propagates the resize to the DrawViewShell which calls
1004 // resize() at the SlideShow (this). Calling resize here results in a
1005 // temporary display of a black window in the window's default size
1007 if( mpView )
1009 mpView->AddWindowToPaintView( mpShowWindow, 0 );
1010 mpView->SetAnimationPause( true );
1013 SfxBindings* pBindings = getBindings();
1014 if( pBindings )
1016 pBindings->Invalidate( SID_PRESENTATION );
1017 pBindings->Invalidate( SID_REHEARSE_TIMINGS );
1020 // Defer the sd::ShowWindow's GrabFocus to SlideShow::activate. so that the accessible event can be fired correctly.
1021 //mpShowWindow->GrabFocus();
1023 std::vector<beans::PropertyValue> aProperties;
1024 aProperties.reserve( 4 );
1026 aProperties.push_back(
1027 beans::PropertyValue( "AdvanceOnClick" ,
1028 -1, Any( !maPresSettings.mbLockedPages ),
1029 beans::PropertyState_DIRECT_VALUE ) );
1031 aProperties.push_back(
1032 beans::PropertyValue( "ImageAnimationsAllowed" ,
1033 -1, Any( maPresSettings.mbAnimationAllowed ),
1034 beans::PropertyState_DIRECT_VALUE ) );
1036 const bool bZOrderEnabled(
1037 SD_MOD()->GetSdOptions( mpDoc->GetDocumentType() )->IsSlideshowRespectZOrder() );
1038 aProperties.push_back(
1039 beans::PropertyValue( "DisableAnimationZOrder" ,
1040 -1, Any( !bZOrderEnabled ),
1041 beans::PropertyState_DIRECT_VALUE ) );
1043 aProperties.push_back(
1044 beans::PropertyValue( "ForceManualAdvance" ,
1045 -1, Any( maPresSettings.mbManual ),
1046 beans::PropertyState_DIRECT_VALUE ) );
1048 if( mbUsePen )
1050 aProperties.push_back(
1051 beans::PropertyValue( "UserPaintColor" ,
1052 // User paint color is black by default.
1053 -1, Any( mnUserPaintColor ),
1054 beans::PropertyState_DIRECT_VALUE ) );
1056 aProperties.push_back(
1057 beans::PropertyValue( "UserPaintStrokeWidth" ,
1058 // User paint color is black by default.
1059 -1, Any( mdUserPaintStrokeWidth ),
1060 beans::PropertyState_DIRECT_VALUE ) );
1063 if (mbRehearseTimings) {
1064 aProperties.push_back(
1065 beans::PropertyValue( "RehearseTimings" ,
1066 -1, Any(true), beans::PropertyState_DIRECT_VALUE ) );
1069 bRet = startShowImpl( Sequence<beans::PropertyValue>(
1070 &aProperties[0], aProperties.size() ) );
1074 setActiveXToolbarsVisible( false );
1076 catch (const Exception&)
1078 OSL_FAIL(
1079 OString(OString("sd::SlideshowImpl::startShow(), "
1080 "exception caught: ") +
1081 OUStringToOString(
1082 comphelper::anyToString( cppu::getCaughtException() ),
1083 RTL_TEXTENCODING_UTF8 )).getStr() );
1084 bRet = false;
1087 return bRet;
1090 bool SlideshowImpl::startShowImpl( const Sequence< beans::PropertyValue >& aProperties )
1094 mxShow = Reference< XSlideShow >( createSlideShow(), UNO_QUERY_THROW );
1096 mxView = new SlideShowView(
1097 *mpShowWindow,
1098 mpDoc,
1099 meAnimationMode,
1100 this,
1101 maPresSettings.mbFullScreen);
1103 // try add wait symbol to properties:
1104 const Reference<rendering::XSpriteCanvas> xSpriteCanvas(
1105 mxView->getCanvas() );
1106 if (xSpriteCanvas.is())
1108 BitmapEx waitSymbolBitmap( SdResId(BMP_WAIT_ICON) );
1109 const Reference<rendering::XBitmap> xBitmap(
1110 vcl::unotools::xBitmapFromBitmapEx(
1111 xSpriteCanvas->getDevice(), waitSymbolBitmap ) );
1112 if (xBitmap.is())
1114 mxShow->setProperty(
1115 beans::PropertyValue( "WaitSymbolBitmap" ,
1117 makeAny( xBitmap ),
1118 beans::PropertyState_DIRECT_VALUE ) );
1121 BitmapEx pointerSymbolBitmap( SdResId(BMP_POINTER_ICON) );
1122 const Reference<rendering::XBitmap> xPointerBitmap(
1123 vcl::unotools::xBitmapFromBitmapEx(
1124 xSpriteCanvas->getDevice(), pointerSymbolBitmap ) );
1125 if (xPointerBitmap.is())
1127 mxShow->setProperty(
1128 beans::PropertyValue( "PointerSymbolBitmap" ,
1130 makeAny( xPointerBitmap ),
1131 beans::PropertyState_DIRECT_VALUE ) );
1135 const sal_Int32 nCount = aProperties.getLength();
1136 sal_Int32 nIndex;
1137 for( nIndex = 0; nIndex < nCount; nIndex++ )
1138 mxShow->setProperty( aProperties[nIndex] );
1140 mxShow->addView( mxView.get() );
1142 mxListenerProxy.set( new SlideShowListenerProxy( this, mxShow ) );
1143 mxListenerProxy->addAsSlideShowListener();
1145 NotifyDocumentEvent( mpDoc, "OnStartPresentation");
1146 displaySlideIndex( mpSlideController->getStartSlideIndex() );
1148 return true;
1150 catch( Exception& )
1152 OSL_FAIL(
1153 OString(OString("sd::SlideshowImpl::startShowImpl(), "
1154 "exception caught: ") +
1155 OUStringToOString(
1156 comphelper::anyToString( cppu::getCaughtException() ),
1157 RTL_TEXTENCODING_UTF8 )).getStr() );
1158 return false;
1162 /** called only by the slideshow view when the first paint event occurs.
1163 This actually starts the slideshow. */
1164 void SlideshowImpl::onFirstPaint()
1166 if( mpShowWindow )
1169 mpShowWindow->SetBackground( Wallpaper( Color( COL_BLACK ) ) );
1170 mpShowWindow->Erase();
1171 mpShowWindow->SetBackground();
1175 SolarMutexGuard aSolarGuard;
1176 maUpdateTimer.SetTimeout( (sal_uLong)100 );
1177 maUpdateTimer.Start();
1180 void SlideshowImpl::paint( const Rectangle& /* rRect */ )
1182 if( mxView.is() ) try
1184 awt::PaintEvent aEvt;
1185 // aEvt.UpdateRect = TODO
1186 mxView->paint( aEvt );
1188 catch( Exception& )
1190 OSL_FAIL(
1191 OString(OString("sd::SlideshowImpl::paint(), "
1192 "exception caught: ") +
1193 OUStringToOString(
1194 comphelper::anyToString( cppu::getCaughtException() ),
1195 RTL_TEXTENCODING_UTF8 )).getStr() );
1199 void SAL_CALL SlideshowImpl::addSlideShowListener( const Reference< XSlideShowListener >& xListener ) throw (RuntimeException, std::exception)
1201 if( mxListenerProxy.is() )
1202 mxListenerProxy->addSlideShowListener( xListener );
1205 void SAL_CALL SlideshowImpl::removeSlideShowListener( const Reference< XSlideShowListener >& xListener ) throw (RuntimeException, std::exception)
1207 if( mxListenerProxy.is() )
1208 mxListenerProxy->removeSlideShowListener( xListener );
1211 void SlideshowImpl::slideEnded(const bool bReverse)
1213 if (bReverse)
1214 gotoPreviousSlide(true);
1215 else
1216 gotoNextSlide();
1219 bool SlideshowImpl::swipe(const CommandSwipeData &rSwipeData)
1221 if (mbUsePen || mnContextMenuEvent)
1222 return false;
1224 double nVelocityX = rSwipeData.getVelocityX();
1225 if (nVelocityX > 0)
1227 gotoPreviousSlide();
1229 else
1231 gotoNextEffect();
1233 //a swipe is followed by a mouse up, tell the view to ignore that mouse up as we've reacted
1234 //to the swipe instead
1235 mxView->ignoreNextMouseReleased();
1236 return true;
1239 bool SlideshowImpl::longpress(const CommandLongPressData &rLongPressData)
1241 if (mnContextMenuEvent)
1242 return false;
1244 maPopupMousePos = Point(rLongPressData.getX(), rLongPressData.getY());
1245 mnContextMenuEvent = Application::PostUserEvent( LINK( this, SlideshowImpl, ContextMenuHdl ) );
1247 return true;
1250 void SlideshowImpl::removeShapeEvents()
1252 if( mxShow.is() && mxListenerProxy.is() ) try
1254 WrappedShapeEventImplMap::iterator aIter;
1255 const WrappedShapeEventImplMap::iterator aEnd( maShapeEventMap.end() );
1257 for( aIter = maShapeEventMap.begin(); aIter != aEnd; ++aIter )
1259 mxListenerProxy->removeShapeEventListener( (*aIter).first );
1260 mxShow->setShapeCursor( (*aIter).first, awt::SystemPointer::ARROW );
1263 maShapeEventMap.clear();
1265 catch( Exception& )
1267 OSL_FAIL(
1268 OString(OString("sd::SlideshowImpl::removeShapeEvents(), "
1269 "exception caught: ") +
1270 OUStringToOString(
1271 comphelper::anyToString( cppu::getCaughtException() ),
1272 RTL_TEXTENCODING_UTF8 )).getStr() );
1276 void SlideshowImpl::registerShapeEvents(sal_Int32 nSlideNumber)
1278 if( nSlideNumber >= 0 ) try
1280 Reference< XDrawPagesSupplier > xDrawPages( mxModel, UNO_QUERY_THROW );
1281 Reference< XIndexAccess > xPages( xDrawPages->getDrawPages(), UNO_QUERY_THROW );
1283 Reference< XShapes > xDrawPage;
1284 xPages->getByIndex(nSlideNumber) >>= xDrawPage;
1286 if( xDrawPage.is() )
1288 Reference< XMasterPageTarget > xMasterPageTarget( xDrawPage, UNO_QUERY );
1289 if( xMasterPageTarget.is() )
1291 Reference< XShapes > xMasterPage( xMasterPageTarget->getMasterPage(), UNO_QUERY );
1292 if( xMasterPage.is() )
1293 registerShapeEvents( xMasterPage );
1295 registerShapeEvents( xDrawPage );
1298 catch( Exception& )
1300 OSL_FAIL(
1301 OString(OString("sd::SlideshowImpl::registerShapeEvents(), "
1302 "exception caught: ") +
1303 OUStringToOString(
1304 comphelper::anyToString( cppu::getCaughtException() ),
1305 RTL_TEXTENCODING_UTF8 )).getStr() );
1309 void SlideshowImpl::registerShapeEvents( Reference< XShapes >& xShapes ) throw( Exception )
1313 const sal_Int32 nShapeCount = xShapes->getCount();
1314 sal_Int32 nShape;
1315 for( nShape = 0; nShape < nShapeCount; nShape++ )
1317 Reference< XShape > xShape;
1318 xShapes->getByIndex( nShape ) >>= xShape;
1320 if( xShape.is() && xShape->getShapeType() == "com.sun.star.drawing.GroupShape" )
1322 Reference< XShapes > xSubShapes( xShape, UNO_QUERY );
1323 if( xSubShapes.is() )
1324 registerShapeEvents( xSubShapes );
1327 Reference< XPropertySet > xSet( xShape, UNO_QUERY );
1328 if( !xSet.is() )
1329 continue;
1331 Reference< XPropertySetInfo > xSetInfo( xSet->getPropertySetInfo() );
1332 if( !xSetInfo.is() || !xSetInfo->hasPropertyByName( msOnClick ) )
1333 continue;
1335 WrappedShapeEventImplPtr pEvent( new WrappedShapeEventImpl );
1336 xSet->getPropertyValue( msOnClick ) >>= pEvent->meClickAction;
1338 switch( pEvent->meClickAction )
1340 case ClickAction_PREVPAGE:
1341 case ClickAction_NEXTPAGE:
1342 case ClickAction_FIRSTPAGE:
1343 case ClickAction_LASTPAGE:
1344 case ClickAction_STOPPRESENTATION:
1345 break;
1346 case ClickAction_BOOKMARK:
1347 if( xSetInfo->hasPropertyByName( msBookmark ) )
1348 xSet->getPropertyValue( msBookmark ) >>= pEvent->maStrBookmark;
1349 if( getSlideNumberForBookmark( pEvent->maStrBookmark ) == -1 )
1350 continue;
1351 break;
1352 case ClickAction_DOCUMENT:
1353 case ClickAction_SOUND:
1354 case ClickAction_PROGRAM:
1355 case ClickAction_MACRO:
1356 if( xSetInfo->hasPropertyByName( msBookmark ) )
1357 xSet->getPropertyValue( msBookmark ) >>= pEvent->maStrBookmark;
1358 break;
1359 case ClickAction_VERB:
1360 if( xSetInfo->hasPropertyByName( msVerb ) )
1361 xSet->getPropertyValue( msVerb ) >>= pEvent->mnVerb;
1362 break;
1363 default:
1364 continue; // skip all others
1367 maShapeEventMap[ xShape ] = pEvent;
1369 if( mxListenerProxy.is() )
1370 mxListenerProxy->addShapeEventListener( xShape );
1371 mxShow->setShapeCursor( xShape, awt::SystemPointer::REFHAND );
1374 catch( Exception& )
1376 OSL_FAIL(
1377 OString(OString("sd::SlideshowImpl::registerShapeEvents(), "
1378 "exception caught: ") +
1379 OUStringToOString(
1380 comphelper::anyToString( cppu::getCaughtException() ),
1381 RTL_TEXTENCODING_UTF8 )).getStr() );
1385 void SlideshowImpl::displayCurrentSlide (const bool bSkipAllMainSequenceEffects)
1387 stopSound();
1388 removeShapeEvents();
1390 if( mpSlideController.get() && mxShow.is() )
1392 Reference< XDrawPagesSupplier > xDrawPages( mpDoc->getUnoModel(),
1393 UNO_QUERY_THROW );
1394 mpSlideController->displayCurrentSlide( mxShow, xDrawPages, bSkipAllMainSequenceEffects );
1395 registerShapeEvents(mpSlideController->getCurrentSlideNumber());
1396 update();
1398 SfxBindings* pBindings = getBindings();
1399 if( pBindings )
1401 pBindings->Invalidate( SID_NAVIGATOR_STATE );
1402 pBindings->Invalidate( SID_NAVIGATOR_PAGENAME );
1405 // send out page change event and notity to update all acc info for current page
1406 if (mpViewShell)
1408 sal_Int32 currentPageIndex = getCurrentSlideIndex();
1409 mpViewShell->fireSwitchCurrentPage(currentPageIndex);
1410 mpViewShell->NotifyAccUpdate();
1414 void SlideshowImpl::endPresentation()
1416 if( maPresSettings.mbMouseAsPen)
1418 Reference< XMultiServiceFactory > xDocFactory(mpDoc->getUnoModel(), UNO_QUERY );
1419 if( xDocFactory.is() )
1420 mxShow->registerUserPaintPolygons(xDocFactory);
1423 if( !mnEndShowEvent )
1424 mnEndShowEvent = Application::PostUserEvent( LINK(this, SlideshowImpl, endPresentationHdl) );
1427 IMPL_LINK_NOARG(SlideshowImpl, endPresentationHdl)
1429 mnEndShowEvent = 0;
1431 if( mxPresentation.is() )
1432 mxPresentation->end();
1433 return 0;
1436 void SAL_CALL SlideshowImpl::pause() throw (RuntimeException, std::exception)
1438 SolarMutexGuard aSolarGuard;
1440 if( !mbIsPaused ) try
1442 mbIsPaused = true;
1443 if( mxShow.is() )
1445 mxShow->pause(sal_True);
1447 if( mxListenerProxy.is() )
1448 mxListenerProxy->paused();
1451 catch( Exception& )
1453 OSL_FAIL(
1454 OString(OString("sd::SlideshowImpl::pause(), "
1455 "exception caught: ") +
1456 OUStringToOString(
1457 comphelper::anyToString( cppu::getCaughtException() ),
1458 RTL_TEXTENCODING_UTF8 )).getStr() );
1462 void SAL_CALL SlideshowImpl::resume() throw (RuntimeException, std::exception)
1464 SolarMutexGuard aSolarGuard;
1466 if( mbIsPaused ) try
1468 if( mpShowWindow->GetShowWindowMode() == SHOWWINDOWMODE_BLANK )
1470 mpShowWindow->RestartShow();
1472 else
1474 mbIsPaused = false;;
1475 if( mxShow.is() )
1477 mxShow->pause(sal_False);
1478 update();
1480 if( mxListenerProxy.is() )
1481 mxListenerProxy->resumed();
1485 catch( Exception& )
1487 OSL_FAIL(
1488 OString(OString("sd::SlideshowImpl::resume(), "
1489 "exception caught: ") +
1490 OUStringToOString(
1491 comphelper::anyToString( cppu::getCaughtException() ),
1492 RTL_TEXTENCODING_UTF8 )).getStr() );
1494 #ifdef ENABLE_SDREMOTE
1495 RemoteServer::presentationStarted( this );
1496 #endif
1499 sal_Bool SAL_CALL SlideshowImpl::isPaused() throw (RuntimeException, std::exception)
1501 SolarMutexGuard aSolarGuard;
1502 return mbIsPaused;
1505 void SAL_CALL SlideshowImpl::blankScreen( sal_Int32 nColor ) throw (RuntimeException, std::exception)
1507 SolarMutexGuard aSolarGuard;
1509 if( mpShowWindow && mpSlideController )
1511 if( mpShowWindow->SetBlankMode( mpSlideController->getCurrentSlideIndex(), nColor ) )
1513 pause();
1518 // XShapeEventListener
1520 void SlideshowImpl::click( const Reference< XShape >& xShape, const ::com::sun::star::awt::MouseEvent& /* aOriginalEvent */ )
1522 SolarMutexGuard aSolarGuard;
1524 WrappedShapeEventImplPtr pEvent = maShapeEventMap[xShape];
1525 if( !pEvent.get() )
1526 return;
1528 switch( pEvent->meClickAction )
1530 case ClickAction_PREVPAGE: gotoPreviousSlide(); break;
1531 case ClickAction_NEXTPAGE: gotoNextSlide(); break;
1532 case ClickAction_FIRSTPAGE: gotoFirstSlide(); break;
1533 case ClickAction_LASTPAGE: gotoLastSlide(); break;
1534 case ClickAction_STOPPRESENTATION: endPresentation(); break;
1535 case ClickAction_BOOKMARK:
1537 gotoBookmark( pEvent->maStrBookmark );
1539 break;
1540 case ClickAction_SOUND:
1544 mxPlayer.set(avmedia::MediaWindow::createPlayer(pEvent->maStrBookmark, ""/*TODO?*/), uno::UNO_QUERY_THROW );
1545 mxPlayer->start();
1547 catch( uno::Exception& )
1549 OSL_FAIL("sd::SlideshowImpl::click(), exception caught!" );
1552 break;
1554 case ClickAction_DOCUMENT:
1556 OUString aBookmark( pEvent->maStrBookmark );
1558 sal_Int32 nPos = aBookmark.indexOf( '#' );
1559 if( nPos >= 0 )
1561 OUString aURL( aBookmark.copy( 0, nPos+1 ) );
1562 OUString aName( aBookmark.copy( nPos+1 ) );
1563 aURL += getUiNameFromPageApiNameImpl( aName );
1564 aBookmark = aURL;
1567 mpDocSh->OpenBookmark( aBookmark );
1569 break;
1571 case ClickAction_PROGRAM:
1573 INetURLObject aURL(
1574 ::URIHelper::SmartRel2Abs(
1575 INetURLObject(mpDocSh->GetMedium()->GetBaseURL()),
1576 pEvent->maStrBookmark, ::URIHelper::GetMaybeFileHdl(), true,
1577 false, INetURLObject::WAS_ENCODED,
1578 INetURLObject::DECODE_UNAMBIGUOUS ) );
1580 if( INetProtocol::File == aURL.GetProtocol() )
1582 SfxStringItem aUrl( SID_FILE_NAME, aURL.GetMainURL( INetURLObject::NO_DECODE ) );
1583 SfxBoolItem aBrowsing( SID_BROWSE, true );
1585 SfxViewFrame* pViewFrm = SfxViewFrame::Current();
1586 if (pViewFrm)
1587 pViewFrm->GetDispatcher()->Execute( SID_OPENDOC,
1588 SfxCallMode::ASYNCHRON | SfxCallMode::RECORD,
1589 &aUrl,
1590 &aBrowsing,
1591 0L );
1594 break;
1596 case presentation::ClickAction_MACRO:
1598 const OUString aMacro( pEvent->maStrBookmark );
1600 if ( SfxApplication::IsXScriptURL( aMacro ) )
1602 Any aRet;
1603 Sequence< sal_Int16 > aOutArgsIndex;
1604 Sequence< Any > aOutArgs;
1605 Sequence< Any >* pInArgs = new Sequence< Any >(0);
1606 mpDocSh->CallXScript( aMacro, *pInArgs, aRet, aOutArgsIndex, aOutArgs);
1608 else
1610 // aMacro has the following syntax:
1611 // "Macroname.Modulname.Libname.Documentname" or
1612 // "Macroname.Modulname.Libname.Applicationname"
1613 OUString aMacroName = aMacro.getToken(0, '.');
1614 OUString aModulName = aMacro.getToken(1, '.');
1616 // todo: is the limitation still given that only
1617 // Modulname+Macroname can be used here?
1618 OUString aExecMacro = aModulName + "." + aMacroName;
1619 mpDocSh->GetBasic()->Call(aExecMacro);
1622 break;
1624 case ClickAction_VERB:
1626 // todo, better do it async?
1627 SdrObject* pObj = GetSdrObjectFromXShape( xShape );
1628 SdrOle2Obj* pOleObject = PTR_CAST(SdrOle2Obj, pObj);
1629 if (pOleObject && mpViewShell )
1630 mpViewShell->ActivateObject(pOleObject, pEvent->mnVerb);
1632 break;
1633 default:
1634 break;
1638 sal_Int32 SlideshowImpl::getSlideNumberForBookmark( const OUString& rStrBookmark )
1640 bool bIsMasterPage;
1641 OUString aBookmark = getUiNameFromPageApiNameImpl( rStrBookmark );
1642 sal_uInt16 nPgNum = mpDoc->GetPageByName( aBookmark, bIsMasterPage );
1644 if( nPgNum == SDRPAGE_NOTFOUND )
1646 // Is the bookmark an object?
1647 SdrObject* pObj = mpDoc->GetObj( aBookmark );
1649 if( pObj )
1651 nPgNum = pObj->GetPage()->GetPageNum();
1652 bIsMasterPage = pObj->GetPage()->IsMasterPage();
1656 if( (nPgNum == SDRPAGE_NOTFOUND) || bIsMasterPage || static_cast<SdPage*>(mpDoc->GetPage(nPgNum))->GetPageKind() != PK_STANDARD )
1657 return -1;
1659 return ( nPgNum - 1) >> 1;
1662 void SlideshowImpl::hyperLinkClicked( OUString const& aHyperLink ) throw (RuntimeException)
1664 OUString aBookmark( aHyperLink );
1666 sal_Int32 nPos = aBookmark.indexOf( '#' );
1667 if( nPos >= 0 )
1669 OUString aURL( aBookmark.copy( 0, nPos+1 ) );
1670 OUString aName( aBookmark.copy( nPos+1 ) );
1671 aURL += getUiNameFromPageApiNameImpl( aName );
1672 aBookmark = aURL;
1675 mpDocSh->OpenBookmark( aBookmark );
1678 void SlideshowImpl::displaySlideNumber( sal_Int32 nSlideNumber )
1680 if( mpSlideController.get() )
1682 if( mpSlideController->jumpToSlideNumber( nSlideNumber ) )
1684 displayCurrentSlide();
1689 /** nSlideIndex == -1 displays current slide again */
1690 void SlideshowImpl::displaySlideIndex( sal_Int32 nSlideIndex )
1692 if( mpSlideController.get() )
1694 if( (nSlideIndex == -1) || mpSlideController->jumpToSlideIndex( nSlideIndex ) )
1696 displayCurrentSlide();
1701 void SlideshowImpl::jumpToBookmark( const OUString& sBookmark )
1703 sal_Int32 nSlideNumber = getSlideNumberForBookmark( sBookmark );
1704 if( nSlideNumber != -1 )
1705 displaySlideNumber( nSlideNumber );
1708 sal_Int32 SlideshowImpl::getCurrentSlideNumber()
1710 return mpSlideController.get() ? mpSlideController->getCurrentSlideNumber() : -1;
1713 sal_Int32 SlideshowImpl::getFirstSlideNumber()
1715 sal_Int32 nRet = 0;
1716 if( mpSlideController.get() )
1718 sal_Int32 nSlideIndexCount = mpSlideController->getSlideIndexCount() - 1;
1719 if( nSlideIndexCount >= 0 )
1721 nRet = mpSlideController->getSlideNumber( nSlideIndexCount );
1722 while( nSlideIndexCount-- )
1724 sal_Int32 nTemp = mpSlideController->getSlideNumber( nSlideIndexCount );
1725 if( nRet > nTemp )
1726 nRet = nTemp;
1731 return nRet;
1734 sal_Int32 SlideshowImpl::getLastSlideNumber()
1736 sal_Int32 nRet = 0;
1737 if( mpSlideController.get() )
1739 sal_Int32 nSlideIndexCount = mpSlideController->getSlideIndexCount() - 1;
1740 if( nSlideIndexCount >= 0 )
1742 nRet = mpSlideController->getSlideNumber( nSlideIndexCount );
1743 while( nSlideIndexCount-- )
1745 sal_Int32 nTemp = mpSlideController->getSlideNumber( nSlideIndexCount );
1746 if( nRet < nTemp )
1747 nRet = nTemp;
1752 return nRet;
1755 sal_Bool SAL_CALL SlideshowImpl::isEndless() throw( RuntimeException, std::exception )
1757 SolarMutexGuard aSolarGuard;
1758 return maPresSettings.mbEndless;
1761 double SlideshowImpl::update()
1763 startUpdateTimer();
1764 return -1;
1767 void SlideshowImpl::startUpdateTimer()
1769 SolarMutexGuard aSolarGuard;
1770 maUpdateTimer.SetTimeout( 0 );
1771 maUpdateTimer.Start();
1774 /** this timer is called 20ms after a new slide was displayed.
1775 This is used to unfreeze user input that was disabled after
1776 slide change to skip input that was buffered during slide
1777 transition preparation */
1778 IMPL_LINK_NOARG_TYPED(SlideshowImpl, ReadyForNextInputHdl, Timer *, void)
1780 mbInputFreeze = false;
1783 /** if I catch someone someday who calls this method by hand
1784 and not by using the timer, I will personaly punish this
1785 person seriously, even if this person is me.
1787 IMPL_LINK_NOARG_TYPED(SlideshowImpl, updateHdl, Timer *, void)
1789 updateSlideShow();
1792 IMPL_LINK_NOARG(SlideshowImpl, PostYieldListener)
1794 // prevent me from deletion when recursing (App::Reschedule does)
1795 const rtl::Reference<SlideshowImpl> this_(this);
1797 Application::DisableNoYieldMode();
1798 Application::RemovePostYieldListener(LINK(this, SlideshowImpl, PostYieldListener));
1799 Application::Reschedule(true); // fix for fdo#32861 - process
1800 // *all* outstanding events after
1801 // yield is done.
1802 if (mbDisposed)
1803 return 0;
1804 Application::Reschedule(true);
1805 return updateSlideShow();
1808 sal_Int32 SlideshowImpl::updateSlideShow()
1810 // prevent me from deletion when recursing (App::EnableYieldMode does)
1811 const rtl::Reference<SlideshowImpl> this_(this);
1813 Reference< XSlideShow > xShow( mxShow );
1814 if ( ! xShow.is())
1815 return 0;
1819 // TODO(Q3): Evaluate under various systems and setups,
1820 // whether this is really necessary. Under WinXP and Matrox
1821 // G550, the frame rates were much more steadier with this
1822 // tweak, although.
1824 // currently no solution, because this kills sound (at least on Windows)
1826 double fUpdate = 0.0;
1827 if( !xShow->update(fUpdate) )
1828 fUpdate = -1.0;
1830 if (mxShow.is() && (fUpdate >= 0.0))
1832 if (::basegfx::fTools::equalZero(fUpdate))
1834 // Use post yield listener for short update intervalls.
1835 Application::EnableNoYieldMode();
1836 Application::AddPostYieldListener(LINK(this, SlideshowImpl, PostYieldListener));
1838 else
1840 // Avoid busy loop when the previous call to update()
1841 // returns a small positive number but not 0 (which is
1842 // handled above). Also, make sure that calls to update()
1843 // have a minimum frequency.
1844 // => Allow up to 60 frames per second. Call at least once
1845 // every 4 seconds.
1846 const static sal_Int32 mnMaximumFrameCount (60);
1847 const static double mnMinimumTimeout (1.0 / mnMaximumFrameCount);
1848 const static double mnMaximumTimeout (4.0);
1849 fUpdate = ::basegfx::clamp(fUpdate, mnMinimumTimeout, mnMaximumTimeout);
1851 // Make sure that the maximum frame count has not been set
1852 // too high (only then conversion to milliseconds and long
1853 // integer may lead to zero value.)
1854 OSL_ASSERT(static_cast<sal_uLong>(fUpdate * 1000.0) > 0);
1856 Application::DisableNoYieldMode();
1857 Application::RemovePostYieldListener(LINK(this, SlideshowImpl, PostYieldListener));
1859 // Use a timer for the asynchronous callback.
1860 maUpdateTimer.SetTimeout(static_cast<sal_uLong>(fUpdate * 1000.0));
1861 maUpdateTimer.Start();
1865 catch( Exception& )
1867 OSL_FAIL(
1868 OString(OString("sd::SlideshowImpl::updateSlideShow(), exception caught: ")
1869 + OUStringToOString(
1870 comphelper::anyToString( cppu::getCaughtException() ),
1871 RTL_TEXTENCODING_UTF8 )).getStr() );
1873 return 0;
1876 bool SlideshowImpl::keyInput(const KeyEvent& rKEvt)
1878 if( !mxShow.is() || mbInputFreeze )
1879 return false;
1881 bool bRet = true;
1885 const int nKeyCode = rKEvt.GetKeyCode().GetCode();
1886 switch( nKeyCode )
1888 case awt::Key::CONTEXTMENU:
1889 if( !mnContextMenuEvent )
1891 if( mpShowWindow )
1892 maPopupMousePos = mpShowWindow->GetPointerState().maPos;
1893 mnContextMenuEvent = Application::PostUserEvent( LINK( this, SlideshowImpl, ContextMenuHdl ) );
1895 break;
1897 // cancel show
1898 case KEY_ESCAPE:
1899 case KEY_SUBTRACT:
1900 // in case the user cancels the presentation, switch to current slide
1901 // in edit mode
1902 if( mpSlideController.get() && (ANIMATIONMODE_SHOW == meAnimationMode) )
1904 if( mpSlideController->getCurrentSlideNumber() != -1 )
1905 mnRestoreSlide = mpSlideController->getCurrentSlideNumber();
1907 endPresentation();
1908 break;
1910 // advance show
1911 case KEY_PAGEDOWN:
1912 if(rKEvt.GetKeyCode().IsMod2())
1914 gotoNextSlide();
1915 break;
1917 // warning, fall through!
1918 case KEY_SPACE:
1919 case KEY_RIGHT:
1920 case KEY_DOWN:
1921 case KEY_N:
1922 gotoNextEffect();
1923 break;
1925 case KEY_RETURN:
1927 if( !maCharBuffer.isEmpty() )
1929 if( mpSlideController.get() )
1931 if( mpSlideController->jumpToSlideNumber( maCharBuffer.toInt32() - 1 ) )
1932 displayCurrentSlide();
1934 maCharBuffer.clear();
1936 else
1938 gotoNextEffect();
1941 break;
1943 // numeric: add to buffer
1944 case KEY_0:
1945 case KEY_1:
1946 case KEY_2:
1947 case KEY_3:
1948 case KEY_4:
1949 case KEY_5:
1950 case KEY_6:
1951 case KEY_7:
1952 case KEY_8:
1953 case KEY_9:
1954 maCharBuffer += OUString( rKEvt.GetCharCode() );
1955 break;
1957 case KEY_PAGEUP:
1958 if(rKEvt.GetKeyCode().IsMod2())
1960 gotoPreviousSlide();
1961 break;
1963 // warning, fall through!
1964 case KEY_LEFT:
1965 case KEY_UP:
1966 case KEY_P:
1967 case KEY_BACKSPACE:
1968 gotoPreviousEffect();
1969 break;
1971 case KEY_HOME:
1972 gotoFirstSlide();
1973 break;
1975 case KEY_END:
1976 gotoLastSlide();
1977 break;
1979 case KEY_B:
1980 case KEY_W:
1981 case KEY_POINT:
1982 case KEY_COMMA:
1984 blankScreen( ((nKeyCode == KEY_W ) || (nKeyCode == KEY_COMMA)) ? 0x00ffffff : 0x00000000 );
1986 break;
1988 default:
1989 bRet = false;
1990 break;
1993 catch( Exception& )
1995 bRet = false;
1996 OSL_FAIL(
1997 OString(OString("sd::SlideshowImpl::keyInput(), "
1998 "exception caught: ") +
1999 OUStringToOString(
2000 comphelper::anyToString( cppu::getCaughtException() ),
2001 RTL_TEXTENCODING_UTF8 )).getStr() );
2004 return bRet;
2007 IMPL_LINK( SlideshowImpl, EventListenerHdl, VclSimpleEvent*, pEvent )
2009 if( !mxShow.is() || mbInputFreeze )
2010 return 0;
2012 if( pEvent && (pEvent->GetId() == VCLEVENT_WINDOW_COMMAND) && static_cast<VclWindowEvent*>(pEvent)->GetData() )
2014 const CommandEvent& rEvent = *static_cast<const CommandEvent*>(static_cast<VclWindowEvent*>(pEvent)->GetData());
2016 if( rEvent.GetCommand() == CommandEventId::Media )
2018 CommandMediaData* pMediaData = rEvent.GetMediaData();
2019 pMediaData->SetPassThroughToOS(false);
2020 switch (pMediaData->GetMediaId())
2022 #if defined( MACOSX )
2023 case MediaCommand::Menu:
2024 if( !mnContextMenuEvent )
2026 if( mpShowWindow )
2027 maPopupMousePos = mpShowWindow->GetPointerState().maPos;
2028 mnContextMenuEvent = Application::PostUserEvent( LINK( this, SlideshowImpl, ContextMenuHdl ) );
2030 break;
2031 case MediaCommand::VolumeDown:
2032 gotoPreviousSlide();
2033 break;
2034 case MediaCommand::VolumeUp:
2035 gotoNextEffect();
2036 break;
2037 #endif
2038 case MediaCommand::NextTrack:
2039 gotoNextEffect();
2040 break;
2041 case MediaCommand::Pause:
2042 if( !mbIsPaused )
2043 blankScreen(0);
2044 break;
2045 case MediaCommand::Play:
2046 if( mbIsPaused )
2047 resume();
2048 break;
2050 case MediaCommand::PlayPause:
2051 if( mbIsPaused )
2052 resume();
2053 else
2054 blankScreen(0);
2055 break;
2056 case MediaCommand::PreviousTrack:
2057 gotoPreviousSlide();
2058 break;
2059 case MediaCommand::NextTrackHold:
2060 gotoLastSlide();
2061 break;
2063 case MediaCommand::Rewind:
2064 gotoFirstSlide();
2065 break;
2066 case MediaCommand::Stop:
2067 // in case the user cancels the presentation, switch to current slide
2068 // in edit mode
2069 if( mpSlideController.get() && (ANIMATIONMODE_SHOW == meAnimationMode) )
2071 if( mpSlideController->getCurrentSlideNumber() != -1 )
2072 mnRestoreSlide = mpSlideController->getCurrentSlideNumber();
2074 endPresentation();
2075 break;
2076 default:
2077 pMediaData->SetPassThroughToOS(true);
2078 break;
2083 return 0;
2086 void SlideshowImpl::mouseButtonUp(const MouseEvent& rMEvt)
2088 if( rMEvt.IsRight() && !mnContextMenuEvent )
2090 maPopupMousePos = rMEvt.GetPosPixel();
2091 mnContextMenuEvent = Application::PostUserEvent( LINK( this, SlideshowImpl, ContextMenuHdl ) );
2095 IMPL_LINK_NOARG(SlideshowImpl, ContextMenuHdl)
2097 mnContextMenuEvent = 0;
2099 if( mpSlideController.get() == 0 )
2100 return 0;
2102 mbWasPaused = mbIsPaused;
2103 if( !mbWasPaused )
2104 pause();
2106 PopupMenu* pMenu = new PopupMenu( SdResId( RID_SLIDESHOW_CONTEXTMENU ) );
2108 // Adding button to display if in Pen mode
2109 pMenu->CheckItem( CM_PEN_MODE, mbUsePen);
2111 const ShowWindowMode eMode = mpShowWindow->GetShowWindowMode();
2112 pMenu->EnableItem( CM_NEXT_SLIDE, ( mpSlideController->getNextSlideIndex() != -1 ) );
2113 pMenu->EnableItem( CM_PREV_SLIDE, ( mpSlideController->getPreviousSlideIndex() != -1 ) || (eMode == SHOWWINDOWMODE_END) || (eMode == SHOWWINDOWMODE_PAUSE) || (eMode == SHOWWINDOWMODE_BLANK) );
2114 pMenu->EnableItem( CM_EDIT_PRESENTATION, mpViewShell->GetDoc()->IsStartWithPresentation());
2116 PopupMenu* pPageMenu = pMenu->GetPopupMenu( CM_GOTO );
2118 SfxViewFrame* pViewFrame = getViewFrame();
2119 if( pViewFrame )
2121 Reference< ::com::sun::star::frame::XFrame > xFrame( pViewFrame->GetFrame().GetFrameInterface() );
2122 if( xFrame.is() )
2124 pMenu->SetItemImage( CM_NEXT_SLIDE, GetImage( xFrame, "slot:10617" , false ) );
2125 pMenu->SetItemImage( CM_PREV_SLIDE, GetImage( xFrame, "slot:10618" , false ) );
2127 if( pPageMenu )
2129 pPageMenu->SetItemImage( CM_FIRST_SLIDE, GetImage( xFrame, "slot:10616" , false ) );
2130 pPageMenu->SetItemImage( CM_LAST_SLIDE, GetImage( xFrame, "slot:10619" , false ) );
2135 // populate slide goto list
2136 if( pPageMenu )
2138 const sal_Int32 nPageNumberCount = mpSlideController->getSlideNumberCount();
2139 if( nPageNumberCount <= 1 )
2141 pMenu->EnableItem( CM_GOTO, false );
2143 else
2145 sal_Int32 nCurrentSlideNumber = mpSlideController->getCurrentSlideNumber();
2146 if( (eMode == SHOWWINDOWMODE_END) || (eMode == SHOWWINDOWMODE_PAUSE) || (eMode == SHOWWINDOWMODE_BLANK) )
2147 nCurrentSlideNumber = -1;
2149 pPageMenu->EnableItem( CM_FIRST_SLIDE, ( mpSlideController->getSlideNumber(0) != nCurrentSlideNumber ) );
2150 pPageMenu->EnableItem( CM_LAST_SLIDE, ( mpSlideController->getSlideNumber( mpSlideController->getSlideIndexCount() - 1) != nCurrentSlideNumber ) );
2152 sal_Int32 nPageNumber;
2154 for( nPageNumber = 0; nPageNumber < nPageNumberCount; nPageNumber++ )
2156 if( mpSlideController->isVisibleSlideNumber( nPageNumber ) )
2158 SdPage* pPage = mpDoc->GetSdPage((sal_uInt16)nPageNumber, PK_STANDARD);
2159 if (pPage)
2161 pPageMenu->InsertItem( (sal_uInt16)(CM_SLIDES + nPageNumber), pPage->GetName() );
2162 if( nPageNumber == nCurrentSlideNumber )
2163 pPageMenu->CheckItem( (sal_uInt16)(CM_SLIDES + nPageNumber) );
2170 if( mpShowWindow->GetShowWindowMode() == SHOWWINDOWMODE_BLANK )
2172 PopupMenu* pBlankMenu = pMenu->GetPopupMenu( CM_SCREEN );
2173 if( pBlankMenu )
2175 pBlankMenu->CheckItem( ( mpShowWindow->GetBlankColor() == Color( COL_WHITE ) ) ? CM_SCREEN_WHITE : CM_SCREEN_BLACK );
2179 PopupMenu* pWidthMenu = pMenu->GetPopupMenu( CM_WIDTH_PEN);
2181 // populate color width list
2182 if( pWidthMenu )
2184 sal_Int32 nIterator;
2185 double nWidth;
2187 nWidth = 4.0;
2188 for( nIterator = 1; nIterator < 6; nIterator++)
2190 switch(nIterator)
2192 case 1:
2193 nWidth = 4.0;
2194 break;
2195 case 2:
2196 nWidth = 100.0;
2197 break;
2198 case 3:
2199 nWidth = 150.0;
2200 break;
2201 case 4:
2202 nWidth = 200.0;
2203 break;
2204 case 5:
2205 nWidth = 400.0;
2206 break;
2207 default:
2208 break;
2211 pWidthMenu->EnableItem( (sal_uInt16)(CM_WIDTH_PEN + nIterator), true);
2212 if( nWidth == mdUserPaintStrokeWidth)
2213 pWidthMenu->CheckItem( (sal_uInt16)(CM_WIDTH_PEN + nIterator) );
2217 pMenu->SetSelectHdl( LINK( this, SlideshowImpl, ContextMenuSelectHdl ) );
2218 pMenu->Execute( mpShowWindow, maPopupMousePos );
2219 delete pMenu;
2221 if( mxView.is() )
2222 mxView->ignoreNextMouseReleased();
2224 if( !mbWasPaused )
2225 resume();
2226 return 0;
2229 IMPL_LINK( SlideshowImpl, ContextMenuSelectHdl, Menu *, pMenu )
2231 if( pMenu )
2233 sal_uInt16 nMenuId = pMenu->GetCurItemId();
2235 switch( nMenuId )
2237 case CM_PREV_SLIDE:
2238 gotoPreviousSlide();
2239 mbWasPaused = false;
2240 break;
2241 case CM_NEXT_SLIDE:
2242 gotoNextSlide();
2243 mbWasPaused = false;
2244 break;
2245 case CM_FIRST_SLIDE:
2246 gotoFirstSlide();
2247 mbWasPaused = false;
2248 break;
2249 case CM_LAST_SLIDE:
2250 gotoLastSlide();
2251 mbWasPaused = false;
2252 break;
2253 case CM_SCREEN_BLACK:
2254 case CM_SCREEN_WHITE:
2256 const Color aBlankColor( (nMenuId == CM_SCREEN_WHITE) ? COL_WHITE : COL_BLACK );
2257 if( mbWasPaused )
2259 if( mpShowWindow->GetShowWindowMode() == SHOWWINDOWMODE_BLANK )
2261 if( mpShowWindow->GetBlankColor() == aBlankColor )
2263 mbWasPaused = false;
2264 mpShowWindow->RestartShow();
2265 break;
2268 mpShowWindow->RestartShow();
2270 if( mpShowWindow->SetBlankMode( mpSlideController->getCurrentSlideIndex(), aBlankColor ) )
2272 pause();
2273 mbWasPaused = true;
2276 break;
2277 case CM_COLOR_PEN:
2279 //Open a color picker based on SvColorDialog
2280 ::Color aColor( mnUserPaintColor );
2281 SvColorDialog aColorDlg( mpShowWindow);
2282 aColorDlg.SetColor( aColor );
2284 if (aColorDlg.Execute() )
2286 aColor = aColorDlg.GetColor();
2287 setPenColor(aColor.GetColor());
2289 mbWasPaused = false;
2291 break;
2293 case CM_WIDTH_PEN_VERY_THIN:
2295 setPenWidth(4.0);
2296 mbWasPaused = false;
2298 break;
2300 case CM_WIDTH_PEN_THIN:
2302 setPenWidth(100.0);
2303 mbWasPaused = false;
2305 break;
2307 case CM_WIDTH_PEN_NORMAL:
2309 setPenWidth(150.0);
2310 mbWasPaused = false;
2312 break;
2314 case CM_WIDTH_PEN_THICK:
2316 setPenWidth(200.0);
2317 mbWasPaused = false;
2319 break;
2321 case CM_WIDTH_PEN_VERY_THICK:
2323 setPenWidth(400.0);
2324 mbWasPaused = false;
2326 break;
2327 case CM_ERASE_ALLINK:
2329 setEraseAllInk(true);
2330 mbWasPaused = false;
2332 break;
2333 case CM_PEN_MODE:
2335 setUsePen(!mbUsePen);
2336 mbWasPaused = false;
2338 break;
2339 case CM_EDIT_PRESENTATION:
2340 // When in autoplay mode (pps/ppsx), offer editing of the presentation
2341 // Turn autostart off, else Impress will close when exiting the Presentation
2342 mpViewShell->GetDoc()->SetExitAfterPresenting(false);
2343 if( mpSlideController.get() && (ANIMATIONMODE_SHOW == meAnimationMode) )
2345 if( mpSlideController->getCurrentSlideNumber() != -1 )
2347 mnRestoreSlide = mpSlideController->getCurrentSlideNumber();
2350 endPresentation();
2351 break;
2352 case CM_ENDSHOW:
2353 // in case the user cancels the presentation, switch to current slide
2354 // in edit mode
2355 if( mpSlideController.get() && (ANIMATIONMODE_SHOW == meAnimationMode) )
2357 if( mpSlideController->getCurrentSlideNumber() != -1 )
2359 mnRestoreSlide = mpSlideController->getCurrentSlideNumber();
2362 endPresentation();
2363 break;
2364 default:
2365 sal_Int32 nPageNumber = nMenuId - CM_SLIDES;
2366 const ShowWindowMode eMode = mpShowWindow->GetShowWindowMode();
2367 if( (eMode == SHOWWINDOWMODE_END) || (eMode == SHOWWINDOWMODE_PAUSE) || (eMode == SHOWWINDOWMODE_BLANK) )
2369 mpShowWindow->RestartShow( nPageNumber );
2371 else if( nPageNumber != mpSlideController->getCurrentSlideNumber() )
2373 displaySlideNumber( nPageNumber );
2375 mbWasPaused = false;
2376 break;
2380 return 0;
2383 Reference< XSlideShow > SlideshowImpl::createSlideShow()
2385 Reference< XSlideShow > xShow;
2389 Reference< uno::XComponentContext > xContext =
2390 ::comphelper::getProcessComponentContext();
2392 xShow.set( presentation::SlideShow::create(xContext), UNO_QUERY_THROW );
2394 catch( uno::Exception& )
2396 OSL_FAIL(
2397 OString(OString("sd::SlideshowImpl::createSlideShow(), "
2398 "exception caught: ") +
2399 OUStringToOString(
2400 comphelper::anyToString( cppu::getCaughtException() ),
2401 RTL_TEXTENCODING_UTF8 )).getStr() );
2404 return xShow;
2407 void SlideshowImpl::createSlideList( bool bAll, const OUString& rPresSlide )
2409 const long nSlideCount = mpDoc->GetSdPageCount( PK_STANDARD );
2411 if( nSlideCount )
2413 SdCustomShow* pCustomShow;
2415 if( mpDoc->GetCustomShowList() && maPresSettings.mbCustomShow )
2416 pCustomShow = mpDoc->GetCustomShowList()->GetCurObject();
2417 else
2418 pCustomShow = NULL;
2420 // create animation slide controller
2421 AnimationSlideController::Mode eMode =
2422 ( pCustomShow && pCustomShow->PagesVector().size() ) ? AnimationSlideController::CUSTOM :
2423 (bAll ? AnimationSlideController::ALL : AnimationSlideController::FROM);
2425 Reference< XDrawPagesSupplier > xDrawPages( mpDoc->getUnoModel(), UNO_QUERY_THROW );
2426 Reference< XIndexAccess > xSlides( xDrawPages->getDrawPages(), UNO_QUERY_THROW );
2427 mpSlideController.reset( new AnimationSlideController( xSlides, eMode ) );
2429 if( eMode != AnimationSlideController::CUSTOM )
2431 sal_Int32 nFirstVisibleSlide = 0;
2433 // normal presentation
2434 if( !rPresSlide.isEmpty() )
2436 sal_Int32 nSlide;
2437 bool bTakeNextAvailable = false;
2439 for( nSlide = 0, nFirstVisibleSlide = -1;
2440 ( nSlide < nSlideCount ) && ( -1 == nFirstVisibleSlide ); nSlide++ )
2442 SdPage* pTestSlide = mpDoc->GetSdPage( (sal_uInt16)nSlide, PK_STANDARD );
2444 if( pTestSlide->GetName() == rPresSlide )
2446 if( pTestSlide->IsExcluded() )
2447 bTakeNextAvailable = true;
2448 else
2449 nFirstVisibleSlide = nSlide;
2451 else if( bTakeNextAvailable && !pTestSlide->IsExcluded() )
2452 nFirstVisibleSlide = nSlide;
2455 if( -1 == nFirstVisibleSlide )
2456 nFirstVisibleSlide = 0;
2459 for( sal_Int32 i = 0; i < nSlideCount; i++ )
2461 bool bVisible = !( mpDoc->GetSdPage( (sal_uInt16)i, PK_STANDARD ) )->IsExcluded();
2462 if( bVisible || (eMode == AnimationSlideController::ALL) )
2463 mpSlideController->insertSlideNumber( i, bVisible );
2466 mpSlideController->setStartSlideNumber( nFirstVisibleSlide );
2468 else
2470 if( meAnimationMode != ANIMATIONMODE_SHOW && !rPresSlide.isEmpty() )
2472 sal_Int32 nSlide;
2473 for( nSlide = 0; nSlide < nSlideCount; nSlide++ )
2474 if( rPresSlide == mpDoc->GetSdPage( (sal_uInt16) nSlide, PK_STANDARD )->GetName() )
2475 break;
2477 if( nSlide < nSlideCount )
2478 mpSlideController->insertSlideNumber( (sal_uInt16) nSlide );
2481 sal_Int32 nSlideIndex = 0;
2482 for( SdCustomShow::PageVec::iterator it = pCustomShow->PagesVector().begin();
2483 it != pCustomShow->PagesVector().end(); ++it, nSlideIndex++ )
2485 const sal_uInt16 nSdSlide = ( (*it)->GetPageNum() - 1 ) / 2;
2487 if( !( mpDoc->GetSdPage( nSdSlide, PK_STANDARD ) )->IsExcluded())
2488 mpSlideController->insertSlideNumber( nSdSlide );
2494 typedef sal_uInt16 (*FncGetChildWindowId)();
2496 FncGetChildWindowId aShowChildren[] =
2498 &AnimationChildWindow::GetChildWindowId,
2499 &Svx3DChildWindow::GetChildWindowId,
2500 &SvxFontWorkChildWindow::GetChildWindowId,
2501 &SvxColorChildWindow::GetChildWindowId,
2502 &SvxSearchDialogWrapper::GetChildWindowId,
2503 &SvxBmpMaskChildWindow::GetChildWindowId,
2504 &SvxIMapDlgChildWindow::GetChildWindowId,
2505 &SvxHlinkDlgWrapper::GetChildWindowId,
2506 &SfxInfoBarContainerChild::GetChildWindowId
2509 #define NAVIGATOR_CHILD_MASK 0x80000000UL
2511 void SlideshowImpl::hideChildWindows()
2513 mnChildMask = 0UL;
2515 if( ANIMATIONMODE_SHOW == meAnimationMode )
2517 SfxViewFrame* pViewFrame = getViewFrame();
2519 if( pViewFrame )
2521 if( pViewFrame->GetChildWindow( SID_NAVIGATOR ) != NULL )
2522 mnChildMask |= NAVIGATOR_CHILD_MASK;
2524 for( sal_uLong i = 0, nCount = sizeof( aShowChildren ) / sizeof( FncGetChildWindowId ); i < nCount; i++ )
2526 const sal_uInt16 nId = ( *aShowChildren[ i ] )();
2528 if( pViewFrame->GetChildWindow( nId ) )
2530 pViewFrame->SetChildWindow( nId, false );
2531 mnChildMask |= 1 << i;
2538 void SlideshowImpl::showChildWindows()
2540 if( ANIMATIONMODE_SHOW == meAnimationMode )
2542 SfxViewFrame* pViewFrame = getViewFrame();
2543 if( pViewFrame )
2545 pViewFrame->SetChildWindow( SID_NAVIGATOR, ( mnChildMask & NAVIGATOR_CHILD_MASK ) != 0 );
2547 for( sal_uLong i = 0, nCount = sizeof( aShowChildren ) / sizeof( FncGetChildWindowId ); i < nCount; i++ )
2549 if( mnChildMask & ( 1 << i ) )
2550 pViewFrame->SetChildWindow( ( *aShowChildren[ i ] )(), true );
2556 SfxViewFrame* SlideshowImpl::getViewFrame() const
2558 return mpViewShell ? mpViewShell->GetViewFrame() : 0;
2561 SfxDispatcher* SlideshowImpl::getDispatcher() const
2563 return (mpViewShell && mpViewShell->GetViewFrame()) ? mpViewShell->GetViewFrame()->GetDispatcher() : 0;
2566 SfxBindings* SlideshowImpl::getBindings() const
2568 return (mpViewShell && mpViewShell->GetViewFrame()) ? &mpViewShell->GetViewFrame()->GetBindings() : 0;
2571 void SlideshowImpl::resize( const Size& rSize )
2573 maPresSize = rSize;
2575 if(mpShowWindow)
2577 mpShowWindow->SetSizePixel( maPresSize );
2578 mpShowWindow->Show();
2581 if( mxView.is() ) try
2583 awt::WindowEvent aEvt;
2584 mxView->windowResized(aEvt);
2586 catch( Exception& )
2588 OSL_FAIL(
2589 OString(OString("sd::SlideshowImpl::resize(), "
2590 "exception caught: ") +
2591 OUStringToOString(
2592 comphelper::anyToString( cppu::getCaughtException() ),
2593 RTL_TEXTENCODING_UTF8 )).getStr() );
2597 void SlideshowImpl::setActiveXToolbarsVisible( bool bVisible )
2599 // in case of ActiveX control the toolbars should not be visible if slide show runs in window mode
2600 // actually it runs always in window mode in case of ActiveX control
2601 if ( !maPresSettings.mbFullScreen && mpDocSh && mpDocSh->GetMedium() )
2603 SFX_ITEMSET_ARG( mpDocSh->GetMedium()->GetItemSet(), pItem, SfxBoolItem, SID_VIEWONLY, false );
2604 if ( pItem && pItem->GetValue() )
2606 // this is a plugin/activex mode, no toolbars should be visible during slide show
2607 // after the end of slide show they should be visible again
2608 SfxViewFrame* pViewFrame = getViewFrame();
2609 if( pViewFrame )
2613 Reference< frame::XLayoutManager > xLayoutManager;
2614 Reference< beans::XPropertySet > xFrameProps( pViewFrame->GetFrame().GetTopFrame().GetFrameInterface(), UNO_QUERY_THROW );
2615 if ( ( xFrameProps->getPropertyValue( "LayoutManager" )
2616 >>= xLayoutManager )
2617 && xLayoutManager.is() )
2619 xLayoutManager->setVisible( bVisible );
2622 catch( uno::Exception& )
2629 void SAL_CALL SlideshowImpl::activate() throw (RuntimeException, std::exception)
2631 SolarMutexGuard aSolarGuard;
2633 maDeactivateTimer.Stop();
2635 if( !mbActive && mxShow.is() )
2637 mbActive = true;
2639 if( ANIMATIONMODE_SHOW == meAnimationMode )
2641 if( mbAutoSaveWasOn )
2642 setAutoSaveState( false );
2644 if( mpShowWindow )
2646 SfxViewFrame* pViewFrame = getViewFrame();
2647 SfxDispatcher* pDispatcher = pViewFrame ? pViewFrame->GetDispatcher() : 0;
2649 hideChildWindows();
2651 if( pDispatcher )
2653 // filter all forbbiden slots
2654 pDispatcher->SetSlotFilter( SfxSlotFilterState::ENABLED, sizeof(pAllowed) / sizeof(sal_uInt16), pAllowed );
2657 if( getBindings() )
2658 getBindings()->InvalidateAll(true);
2660 mpShowWindow->GrabFocus();
2664 resume();
2668 void SAL_CALL SlideshowImpl::deactivate() throw (RuntimeException, std::exception)
2670 SolarMutexGuard aSolarGuard;
2672 if( mbActive && mxShow.is() )
2674 maDeactivateTimer.Start();
2678 IMPL_LINK_NOARG_TYPED(SlideshowImpl, deactivateHdl, Timer *, void)
2680 if( mbActive && mxShow.is() )
2682 mbActive = false;
2684 pause();
2686 if( ANIMATIONMODE_SHOW == meAnimationMode )
2688 if( mbAutoSaveWasOn )
2689 setAutoSaveState( true );
2691 if( mpShowWindow )
2693 showChildWindows();
2699 sal_Bool SAL_CALL SlideshowImpl::isActive() throw (RuntimeException, std::exception)
2701 SolarMutexGuard aSolarGuard;
2702 return mbActive;
2705 void SlideshowImpl::receiveRequest(SfxRequest& rReq)
2707 const SfxItemSet* pArgs = rReq.GetArgs();
2709 switch ( rReq.GetSlot() )
2711 case SID_NAVIGATOR_PEN:
2712 setUsePen(!mbUsePen);
2713 break;
2715 case SID_NAVIGATOR_PAGE:
2717 PageJump eJump = (PageJump)static_cast<const SfxAllEnumItem&>( pArgs->Get(SID_NAVIGATOR_PAGE)).GetValue();
2718 switch( eJump )
2720 case PAGE_FIRST: gotoFirstSlide(); break;
2721 case PAGE_LAST: gotoLastSlide(); break;
2722 case PAGE_NEXT: gotoNextSlide(); break;
2723 case PAGE_PREVIOUS: gotoPreviousSlide(); break;
2724 case PAGE_NONE: break;
2727 break;
2729 case SID_NAVIGATOR_OBJECT:
2731 const OUString aTarget( static_cast<const SfxStringItem&>(pArgs->Get(SID_NAVIGATOR_OBJECT)).GetValue() );
2733 // is the bookmark a Slide?
2734 bool bIsMasterPage;
2735 sal_uInt16 nPgNum = mpDoc->GetPageByName( aTarget, bIsMasterPage );
2736 SdrObject* pObj = NULL;
2738 if( nPgNum == SDRPAGE_NOTFOUND )
2740 // is the bookmark an object?
2741 pObj = mpDoc->GetObj( aTarget );
2743 if( pObj )
2744 nPgNum = pObj->GetPage()->GetPageNum();
2747 if( nPgNum != SDRPAGE_NOTFOUND )
2749 nPgNum = ( nPgNum - 1 ) >> 1;
2750 displaySlideNumber( nPgNum );
2753 break;
2757 void SlideshowImpl::setAutoSaveState( bool bOn)
2761 uno::Reference<uno::XComponentContext> xContext( ::comphelper::getProcessComponentContext() );
2763 uno::Reference< util::XURLTransformer > xParser(util::URLTransformer::create(xContext));
2764 util::URL aURL;
2765 aURL.Complete = "vnd.sun.star.autorecovery:/setAutoSaveState";
2766 xParser->parseStrict(aURL);
2768 Sequence< beans::PropertyValue > aArgs(1);
2769 aArgs[0].Name = "AutoSaveState";
2770 aArgs[0].Value <<= bOn ? sal_True : sal_False;
2772 uno::Reference< frame::XDispatch > xAutoSave = frame::theAutoRecovery::get(xContext);
2773 xAutoSave->dispatch(aURL, aArgs);
2775 catch( Exception& )
2777 OSL_FAIL("sd::SlideshowImpl::setAutoSaveState(), exception caught!");
2781 Reference< XDrawPage > SAL_CALL SlideshowImpl::getCurrentSlide() throw (RuntimeException, std::exception)
2783 SolarMutexGuard aSolarGuard;
2785 Reference< XDrawPage > xSlide;
2786 if( mxShow.is() && mpSlideController.get() )
2788 sal_Int32 nSlide = getCurrentSlideNumber();
2789 if( (nSlide >= 0) && (nSlide < mpSlideController->getSlideNumberCount() ) )
2790 xSlide = mpSlideController->getSlideByNumber( nSlide );
2793 return xSlide;
2796 sal_Int32 SAL_CALL SlideshowImpl::getNextSlideIndex() throw (RuntimeException, std::exception)
2798 SolarMutexGuard aSolarGuard;
2800 if( mxShow.is() )
2802 return mpSlideController->getNextSlideIndex();
2804 else
2806 return -1;
2810 sal_Int32 SAL_CALL SlideshowImpl::getCurrentSlideIndex() throw (RuntimeException, std::exception)
2812 return mpSlideController.get() ? mpSlideController->getCurrentSlideIndex() : -1;
2815 // ::com::sun::star::presentation::XSlideShowController:
2817 ::sal_Int32 SAL_CALL SlideshowImpl::getSlideCount() throw (RuntimeException, std::exception)
2819 return mpSlideController.get() ? mpSlideController->getSlideIndexCount() : 0;
2822 Reference< XDrawPage > SAL_CALL SlideshowImpl::getSlideByIndex(::sal_Int32 Index) throw (RuntimeException, css::lang::IndexOutOfBoundsException, std::exception)
2824 if( (mpSlideController.get() == 0 ) || (Index < 0) || (Index >= mpSlideController->getSlideIndexCount() ) )
2825 throw IndexOutOfBoundsException();
2827 return mpSlideController->getSlideByNumber( mpSlideController->getSlideNumber( Index ) );
2830 sal_Bool SAL_CALL SlideshowImpl::getAlwaysOnTop() throw (RuntimeException, std::exception)
2832 SolarMutexGuard aSolarGuard;
2833 return maPresSettings.mbAlwaysOnTop;
2836 void SAL_CALL SlideshowImpl::setAlwaysOnTop( sal_Bool bAlways ) throw (RuntimeException, std::exception)
2838 SolarMutexGuard aSolarGuard;
2839 if( maPresSettings.mbAlwaysOnTop != bool(bAlways) )
2841 maPresSettings.mbAlwaysOnTop = bAlways;
2842 // todo, can this be changed while running?
2846 sal_Bool SAL_CALL SlideshowImpl::isFullScreen() throw (RuntimeException, std::exception)
2848 SolarMutexGuard aSolarGuard;
2849 return maPresSettings.mbFullScreen;
2852 sal_Bool SAL_CALL SlideshowImpl::getMouseVisible() throw (RuntimeException, std::exception)
2854 SolarMutexGuard aSolarGuard;
2855 return maPresSettings.mbMouseVisible;
2858 void SAL_CALL SlideshowImpl::setMouseVisible( sal_Bool bVisible ) throw (RuntimeException, std::exception)
2860 SolarMutexGuard aSolarGuard;
2861 if( maPresSettings.mbMouseVisible != bool(bVisible) )
2863 maPresSettings.mbMouseVisible = bVisible;
2864 if( mpShowWindow )
2865 mpShowWindow->SetMouseAutoHide( !maPresSettings.mbMouseVisible );
2869 sal_Bool SAL_CALL SlideshowImpl::getUsePen() throw (RuntimeException, std::exception)
2871 SolarMutexGuard aSolarGuard;
2872 return mbUsePen;
2875 void SAL_CALL SlideshowImpl::setUsePen( sal_Bool bMouseAsPen ) throw (RuntimeException, std::exception)
2877 SolarMutexGuard aSolarGuard;
2878 mbUsePen = bMouseAsPen;
2879 if( mxShow.is() ) try
2881 // For Pencolor;
2882 Any aValue;
2883 if( mbUsePen )
2884 aValue <<= mnUserPaintColor;
2885 beans::PropertyValue aPenProp;
2886 aPenProp.Name = "UserPaintColor";
2887 aPenProp.Value = aValue;
2888 mxShow->setProperty( aPenProp );
2890 //for StrokeWidth :
2891 if( mbUsePen )
2893 beans::PropertyValue aPenPropWidth;
2894 aPenPropWidth.Name = "UserPaintStrokeWidth";
2895 aPenPropWidth.Value <<= mdUserPaintStrokeWidth;
2896 mxShow->setProperty( aPenPropWidth );
2898 // for Pen Mode
2899 beans::PropertyValue aPenPropSwitchPenMode;
2900 aPenPropSwitchPenMode.Name = "SwitchPenMode";
2901 aPenPropSwitchPenMode.Value <<= sal_True;
2902 mxShow->setProperty( aPenPropSwitchPenMode );
2905 catch( Exception& )
2907 OSL_FAIL(
2908 OString(OString("sd::SlideshowImpl::setUsePen(), "
2909 "exception caught: ") +
2910 OUStringToOString(
2911 comphelper::anyToString( cppu::getCaughtException() ),
2912 RTL_TEXTENCODING_UTF8 )).getStr() );
2916 double SAL_CALL SlideshowImpl::getPenWidth() throw (RuntimeException, std::exception)
2918 SolarMutexGuard aSolarGuard;
2919 return mdUserPaintStrokeWidth;
2922 void SAL_CALL SlideshowImpl::setPenWidth( double dStrokeWidth ) throw (RuntimeException, std::exception)
2924 SolarMutexGuard aSolarGuard;
2925 mdUserPaintStrokeWidth = dStrokeWidth;
2926 setUsePen( true ); // enable pen mode, update color and width
2929 sal_Int32 SAL_CALL SlideshowImpl::getPenColor() throw (RuntimeException, std::exception)
2931 SolarMutexGuard aSolarGuard;
2932 return mnUserPaintColor;
2935 void SAL_CALL SlideshowImpl::setPenColor( sal_Int32 nColor ) throw (RuntimeException, std::exception)
2937 SolarMutexGuard aSolarGuard;
2938 mnUserPaintColor = nColor;
2939 setUsePen( true ); // enable pen mode, update color
2942 void SAL_CALL SlideshowImpl::setEraseAllInk(bool bEraseAllInk) throw (RuntimeException)
2944 if( bEraseAllInk )
2946 SolarMutexGuard aSolarGuard;
2947 if( mxShow.is() ) try
2949 beans::PropertyValue aPenPropEraseAllInk;
2950 aPenPropEraseAllInk.Name = "EraseAllInk";
2951 aPenPropEraseAllInk.Value <<= bEraseAllInk;
2952 mxShow->setProperty( aPenPropEraseAllInk );
2954 catch( Exception& )
2956 SAL_WARN( "sd.slideshow", "sd::SlideshowImpl::setEraseAllInk(), "
2957 "exception caught: " << comphelper::anyToString( cppu::getCaughtException() ));
2962 // XSlideShowController Methods
2963 sal_Bool SAL_CALL SlideshowImpl::isRunning( ) throw (RuntimeException, std::exception)
2965 SolarMutexGuard aSolarGuard;
2966 return mxShow.is();
2969 void SAL_CALL SlideshowImpl::gotoNextEffect( ) throw (RuntimeException, std::exception)
2971 SolarMutexGuard aSolarGuard;
2973 if( mxShow.is() && mpSlideController.get() && mpShowWindow )
2975 if( mbIsPaused )
2976 resume();
2978 const ShowWindowMode eMode = mpShowWindow->GetShowWindowMode();
2979 if( eMode == SHOWWINDOWMODE_END )
2981 endPresentation();
2983 else if( (eMode == SHOWWINDOWMODE_PAUSE) || (eMode == SHOWWINDOWMODE_BLANK) )
2985 mpShowWindow->RestartShow();
2987 else
2989 mxShow->nextEffect();
2990 update();
2995 void SAL_CALL SlideshowImpl::gotoPreviousEffect( ) throw (RuntimeException, std::exception)
2997 SolarMutexGuard aSolarGuard;
2999 if( mxShow.is() && mpSlideController.get() && mpShowWindow )
3001 if( mbIsPaused )
3002 resume();
3004 const ShowWindowMode eMode = mpShowWindow->GetShowWindowMode();
3005 if( (eMode == SHOWWINDOWMODE_PAUSE) || (eMode == SHOWWINDOWMODE_BLANK) )
3007 mpShowWindow->RestartShow();
3009 else
3011 mxShow->previousEffect();
3012 update();
3017 void SAL_CALL SlideshowImpl::gotoFirstSlide( ) throw (RuntimeException, std::exception)
3019 SolarMutexGuard aSolarGuard;
3021 if( mpShowWindow && mpSlideController.get() )
3023 if( mbIsPaused )
3024 resume();
3026 if( mpShowWindow->GetShowWindowMode() == SHOWWINDOWMODE_END )
3028 if( mpSlideController->getSlideIndexCount() )
3029 mpShowWindow->RestartShow( 0);
3031 else
3033 displaySlideIndex( 0 );
3038 void SAL_CALL SlideshowImpl::gotoNextSlide( ) throw (RuntimeException, std::exception)
3040 SolarMutexGuard aSolarGuard;
3042 if( mbIsPaused )
3043 resume();
3045 const ShowWindowMode eMode = mpShowWindow->GetShowWindowMode();
3046 if( (eMode == SHOWWINDOWMODE_PAUSE) || (eMode == SHOWWINDOWMODE_BLANK) )
3048 mpShowWindow->RestartShow();
3050 else
3052 // if this is a show, ignore user inputs and
3053 // start 20ms timer to reenable inputs to filter
3054 // buffered inputs during slide transition
3055 if( meAnimationMode == ANIMATIONMODE_SHOW )
3057 mbInputFreeze = true;
3058 maInputFreezeTimer.Start();
3061 if( mpSlideController.get() )
3063 if( mpSlideController->nextSlide() )
3065 displayCurrentSlide();
3067 else
3069 stopSound();
3071 if( meAnimationMode == ANIMATIONMODE_PREVIEW )
3073 endPresentation();
3075 else if( maPresSettings.mbEndless )
3077 if( maPresSettings.mnPauseTimeout )
3079 if( mpShowWindow )
3081 if ( maPresSettings.mbShowPauseLogo )
3083 Graphic aGraphic(SfxApplication::GetApplicationLogo(360));
3084 mpShowWindow->SetPauseMode( 0, maPresSettings.mnPauseTimeout, &aGraphic );
3086 else
3087 mpShowWindow->SetPauseMode( 0, maPresSettings.mnPauseTimeout );
3090 else
3092 displaySlideIndex( 0 );
3095 else
3097 if( mpShowWindow )
3099 mpShowWindow->SetEndMode();
3100 if( !mpViewShell->GetDoc()->IsStartWithPresentation() )
3101 pause();
3109 void SAL_CALL SlideshowImpl::gotoPreviousSlide( ) throw (RuntimeException, std::exception)
3111 gotoPreviousSlide(false);
3114 void SlideshowImpl::gotoPreviousSlide (const bool bSkipAllMainSequenceEffects)
3116 SolarMutexGuard aSolarGuard;
3118 if( mxShow.is() && mpSlideController.get() ) try
3120 if( mbIsPaused )
3121 resume();
3123 const ShowWindowMode eMode = mpShowWindow->GetShowWindowMode();
3124 if( eMode == SHOWWINDOWMODE_END )
3126 mpShowWindow->RestartShow( mpSlideController->getCurrentSlideIndex() );
3128 else if( (eMode == SHOWWINDOWMODE_PAUSE) || (eMode == SHOWWINDOWMODE_BLANK) )
3130 mpShowWindow->RestartShow();
3132 else
3134 if( mpSlideController->previousSlide())
3135 displayCurrentSlide(bSkipAllMainSequenceEffects);
3136 else if (bSkipAllMainSequenceEffects)
3138 // We could not go to the previous slide (probably because
3139 // the current slide is already the first one). We still
3140 // have to call displayCurrentSlide because the calling
3141 // slideshow can not determine whether there is a previous
3142 // slide or not and has already prepared for a slide change.
3143 // This slide change has to be completed now, even when
3144 // changing to the same slide.
3145 // Note that in this special case we do NOT pass
3146 // bSkipAllMainSequenceEffects because we display the same
3147 // slide as before and do not want to show all its effects.
3148 displayCurrentSlide(false);
3152 catch( Exception& )
3154 OSL_FAIL(
3155 OString(OString("sd::SlideshowImpl::gotoPreviousSlide(), "
3156 "exception caught: ") +
3157 OUStringToOString(
3158 comphelper::anyToString( cppu::getCaughtException() ),
3159 RTL_TEXTENCODING_UTF8 )).getStr() );
3163 void SAL_CALL SlideshowImpl::gotoLastSlide() throw (RuntimeException, std::exception)
3165 SolarMutexGuard aSolarGuard;
3167 if( mpSlideController.get() )
3169 if( mbIsPaused )
3170 resume();
3172 const sal_Int32 nLastSlideIndex = mpSlideController->getSlideIndexCount() - 1;
3173 if( nLastSlideIndex >= 0 )
3175 if( mpShowWindow->GetShowWindowMode() == SHOWWINDOWMODE_END )
3177 mpShowWindow->RestartShow( nLastSlideIndex );
3179 else
3181 displaySlideIndex( nLastSlideIndex );
3187 void SAL_CALL SlideshowImpl::gotoBookmark( const OUString& rBookmark ) throw (RuntimeException, std::exception)
3189 SolarMutexGuard aSolarGuard;
3191 if( mbIsPaused )
3192 resume();
3194 sal_Int32 nSlideNumber = getSlideNumberForBookmark( rBookmark );
3195 if( nSlideNumber != -1 )
3196 displaySlideNumber( nSlideNumber );
3199 void SAL_CALL SlideshowImpl::gotoSlide( const Reference< XDrawPage >& xSlide )
3200 throw(IllegalArgumentException, RuntimeException, std::exception)
3202 SolarMutexGuard aSolarGuard;
3204 if( mpSlideController.get() && xSlide.is() )
3206 if( mbIsPaused )
3207 resume();
3209 const sal_Int32 nSlideCount = mpSlideController->getSlideNumberCount();
3210 for( sal_Int32 nSlide = 0; nSlide < nSlideCount; nSlide++ )
3212 if( mpSlideController->getSlideByNumber( nSlide ) == xSlide )
3214 displaySlideNumber( nSlide );
3220 void SAL_CALL SlideshowImpl::gotoSlideIndex( sal_Int32 nIndex ) throw (RuntimeException, std::exception)
3222 SolarMutexGuard aSolarGuard;
3224 if( mbIsPaused )
3225 resume();
3227 displaySlideIndex( nIndex );
3230 void SAL_CALL SlideshowImpl::stopSound( ) throw (RuntimeException, std::exception)
3232 SolarMutexGuard aSolarGuard;
3236 if( mxPlayer.is() )
3238 mxPlayer->stop();
3239 mxPlayer.clear();
3242 catch( Exception& )
3244 OSL_FAIL(
3245 OString(OString("sd::SlideshowImpl::stopSound(), "
3246 "exception caught: ") +
3247 OUStringToOString(
3248 comphelper::anyToString( cppu::getCaughtException() ),
3249 RTL_TEXTENCODING_UTF8 )).getStr() );
3253 // XIndexAccess
3255 ::sal_Int32 SAL_CALL SlideshowImpl::getCount( ) throw (::com::sun::star::uno::RuntimeException, std::exception)
3257 return getSlideCount();
3260 ::com::sun::star::uno::Any SAL_CALL SlideshowImpl::getByIndex( ::sal_Int32 Index ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException, std::exception)
3262 return Any( getSlideByIndex( Index ) );
3265 ::com::sun::star::uno::Type SAL_CALL SlideshowImpl::getElementType( ) throw (::com::sun::star::uno::RuntimeException, std::exception)
3267 return cppu::UnoType<XDrawPage>::get();
3270 sal_Bool SAL_CALL SlideshowImpl::hasElements( ) throw (::com::sun::star::uno::RuntimeException, std::exception)
3272 return getSlideCount() != 0;
3275 Reference< XSlideShow > SAL_CALL SlideshowImpl::getSlideShow() throw (RuntimeException, std::exception)
3277 return mxShow;
3280 PresentationSettingsEx::PresentationSettingsEx( const PresentationSettingsEx& r )
3281 : PresentationSettings( r )
3282 , mbRehearseTimings(r.mbRehearseTimings)
3283 , mbPreview(r.mbPreview)
3284 , mpParentWindow( 0 )
3288 PresentationSettingsEx::PresentationSettingsEx( PresentationSettings& r )
3289 : PresentationSettings( r )
3290 , mbRehearseTimings(false)
3291 , mbPreview(false)
3292 , mpParentWindow(0)
3296 void PresentationSettingsEx::SetArguments( const Sequence< PropertyValue >& rArguments ) throw (IllegalArgumentException)
3298 sal_Int32 nArguments = rArguments.getLength();
3299 const PropertyValue* pValue = rArguments.getConstArray();
3301 while( nArguments-- )
3303 SetPropertyValue( pValue->Name, pValue->Value );
3304 pValue++;
3308 void PresentationSettingsEx::SetPropertyValue( const OUString& rProperty, const Any& rValue ) throw (IllegalArgumentException)
3310 if ( rProperty == "RehearseTimings" )
3312 if( rValue >>= mbRehearseTimings )
3313 return;
3315 else if ( rProperty == "Preview" )
3317 if( rValue >>= mbPreview )
3318 return;
3320 else if ( rProperty == "AnimationNode" )
3322 if( rValue >>= mxAnimationNode )
3323 return;
3325 else if ( rProperty == "ParentWindow" )
3327 Reference< XWindow > xWindow;
3328 if( rValue >>= xWindow )
3330 mpParentWindow = xWindow.is() ? VCLUnoHelper::GetWindow( xWindow )
3331 : VclPtr<vcl::Window>();
3332 return;
3335 else if ( rProperty == "AllowAnimations" )
3337 if( rValue >>= mbAnimationAllowed )
3338 return;
3340 else if ( rProperty == "FirstPage" )
3342 OUString aPresPage;
3343 if( rValue >>= aPresPage )
3345 maPresPage = getUiNameFromPageApiNameImpl(aPresPage);
3346 mbCustomShow = false;
3347 mbAll = false;
3348 return;
3350 else
3352 if( rValue >>= mxStartPage )
3353 return;
3356 else if ( rProperty == "IsAlwaysOnTop" )
3358 if( rValue >>= mbAlwaysOnTop )
3359 return;
3361 else if ( rProperty == "IsAutomatic" )
3363 if( rValue >>= mbManual )
3364 return;
3366 else if ( rProperty == "IsEndless" )
3368 if( rValue >>= mbEndless )
3369 return;
3371 else if ( rProperty == "IsFullScreen" )
3373 if( rValue >>= mbFullScreen )
3374 return;
3376 else if ( rProperty == "IsMouseVisible" )
3378 if( rValue >>= mbMouseVisible )
3379 return;
3381 else if ( rProperty == "Pause" )
3383 sal_Int32 nPause = -1;
3384 if( (rValue >>= nPause) && (nPause >= 0) )
3386 mnPauseTimeout = nPause;
3387 return;
3390 else if ( rProperty == "StartWithNavigator" )
3392 if( rValue >>= mbStartWithNavigator )
3393 return;
3395 else if ( rProperty == "UsePen" )
3397 if( rValue >>= mbMouseAsPen )
3398 return;
3400 throw IllegalArgumentException();
3403 // XAnimationListener
3405 SlideShowListenerProxy::SlideShowListenerProxy( const rtl::Reference< SlideshowImpl >& xController, const css::uno::Reference< css::presentation::XSlideShow >& xSlideShow )
3406 : maListeners( m_aMutex )
3407 , mxController( xController )
3408 , mxSlideShow( xSlideShow )
3412 SlideShowListenerProxy::~SlideShowListenerProxy()
3416 void SlideShowListenerProxy::addAsSlideShowListener()
3418 if( mxSlideShow.is() )
3420 Reference< XSlideShowListener > xSlideShowListener( this );
3421 mxSlideShow->addSlideShowListener( xSlideShowListener );
3425 void SlideShowListenerProxy::removeAsSlideShowListener()
3427 if( mxSlideShow.is() )
3429 Reference< XSlideShowListener > xSlideShowListener( this );
3430 mxSlideShow->removeSlideShowListener( xSlideShowListener );
3434 void SlideShowListenerProxy::addShapeEventListener( const css::uno::Reference< css::drawing::XShape >& xShape )
3436 if( mxSlideShow.is() )
3438 Reference< XShapeEventListener > xListener( this );
3439 mxSlideShow->addShapeEventListener( xListener, xShape );
3443 void SlideShowListenerProxy::removeShapeEventListener( const css::uno::Reference< css::drawing::XShape >& xShape )
3445 if( mxSlideShow.is() )
3447 Reference< XShapeEventListener > xListener( this );
3448 mxSlideShow->removeShapeEventListener( xListener, xShape );
3452 void SlideShowListenerProxy::addSlideShowListener( const css::uno::Reference< css::presentation::XSlideShowListener >& xListener )
3454 maListeners.addInterface(xListener);
3457 void SlideShowListenerProxy::removeSlideShowListener( const css::uno::Reference< css::presentation::XSlideShowListener >& xListener )
3459 maListeners.removeInterface(xListener);
3462 void SAL_CALL SlideShowListenerProxy::beginEvent( const Reference< XAnimationNode >& xNode ) throw (RuntimeException, std::exception)
3464 ::osl::MutexGuard aGuard( m_aMutex );
3466 if( maListeners.getLength() >= 0 )
3467 maListeners.forEach<XSlideShowListener>( boost::bind( &XAnimationListener::beginEvent, _1, boost::cref(xNode) ));
3470 void SAL_CALL SlideShowListenerProxy::endEvent( const Reference< XAnimationNode >& xNode ) throw (RuntimeException, std::exception)
3472 ::osl::MutexGuard aGuard( m_aMutex );
3474 if( maListeners.getLength() >= 0 )
3475 maListeners.forEach<XSlideShowListener>( boost::bind( &XAnimationListener::endEvent, _1, boost::cref(xNode) ));
3478 void SAL_CALL SlideShowListenerProxy::repeat( const Reference< XAnimationNode >& xNode, ::sal_Int32 nRepeat ) throw (RuntimeException, std::exception)
3480 ::osl::MutexGuard aGuard( m_aMutex );
3482 if( maListeners.getLength() >= 0 )
3483 maListeners.forEach<XSlideShowListener>( boost::bind( &XAnimationListener::repeat, _1, boost::cref(xNode), boost::cref(nRepeat) ));
3486 // ::com::sun::star::presentation::XSlideShowListener:
3488 void SAL_CALL SlideShowListenerProxy::paused( ) throw (::com::sun::star::uno::RuntimeException, std::exception)
3490 ::osl::MutexGuard aGuard( m_aMutex );
3492 if( maListeners.getLength() >= 0 )
3493 maListeners.forEach<XSlideShowListener>( boost::mem_fn( &XSlideShowListener::paused ) );
3496 void SAL_CALL SlideShowListenerProxy::resumed( ) throw (::com::sun::star::uno::RuntimeException, std::exception)
3498 ::osl::MutexGuard aGuard( m_aMutex );
3500 if( maListeners.getLength() >= 0 )
3501 maListeners.forEach<XSlideShowListener>( boost::mem_fn( &XSlideShowListener::resumed ) );
3504 void SAL_CALL SlideShowListenerProxy::slideTransitionStarted( ) throw (RuntimeException, std::exception)
3506 ::osl::MutexGuard aGuard( m_aMutex );
3508 if( maListeners.getLength() >= 0 )
3509 maListeners.forEach<XSlideShowListener>( boost::mem_fn( &XSlideShowListener::slideTransitionStarted ) );
3512 void SAL_CALL SlideShowListenerProxy::slideTransitionEnded( ) throw (::com::sun::star::uno::RuntimeException, std::exception)
3514 ::osl::MutexGuard aGuard( m_aMutex );
3516 if( maListeners.getLength() >= 0 )
3517 maListeners.forEach<XSlideShowListener>( boost::mem_fn( &XSlideShowListener::slideTransitionEnded ) );
3520 void SAL_CALL SlideShowListenerProxy::slideAnimationsEnded( ) throw (::com::sun::star::uno::RuntimeException, std::exception)
3522 ::osl::MutexGuard aGuard( m_aMutex );
3524 if( maListeners.getLength() >= 0 )
3525 maListeners.forEach<XSlideShowListener>( boost::mem_fn( &XSlideShowListener::slideAnimationsEnded ) );
3528 void SlideShowListenerProxy::slideEnded(sal_Bool bReverse) throw (RuntimeException, std::exception)
3531 ::osl::MutexGuard aGuard( m_aMutex );
3533 if( maListeners.getLength() >= 0 )
3534 maListeners.forEach<XSlideShowListener>(
3535 boost::bind( &XSlideShowListener::slideEnded, _1, bReverse) );
3539 SolarMutexGuard aSolarGuard;
3540 if( mxController.is() )
3541 mxController->slideEnded(bReverse);
3545 void SlideShowListenerProxy::hyperLinkClicked( OUString const& aHyperLink ) throw (RuntimeException, std::exception)
3548 ::osl::MutexGuard aGuard( m_aMutex );
3550 if( maListeners.getLength() >= 0 )
3551 maListeners.forEach<XSlideShowListener>( boost::bind( &XSlideShowListener::hyperLinkClicked, _1, boost::cref(aHyperLink) ));
3555 SolarMutexGuard aSolarGuard;
3556 if( mxController.is() )
3557 mxController->hyperLinkClicked(aHyperLink);
3561 // XEventListener
3563 void SAL_CALL SlideShowListenerProxy::disposing( const ::com::sun::star::lang::EventObject& aDisposeEvent ) throw (RuntimeException, std::exception)
3565 maListeners.disposeAndClear( aDisposeEvent );
3566 mxController.clear();
3567 mxSlideShow.clear();
3570 // XShapeEventListener
3572 void SAL_CALL SlideShowListenerProxy::click( const Reference< XShape >& xShape, const ::com::sun::star::awt::MouseEvent& aOriginalEvent ) throw (RuntimeException, std::exception)
3574 SolarMutexGuard aSolarGuard;
3575 if( mxController.is() )
3576 mxController->click(xShape, aOriginalEvent );
3579 } // namespace ::sd
3581 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */