1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 <sal/config.h>
24 #include <config_features.h>
26 #include <com/sun/star/frame/theAutoRecovery.hpp>
27 #include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
28 #include <com/sun/star/document/XEventsSupplier.hpp>
29 #include <com/sun/star/drawing/XMasterPageTarget.hpp>
30 #include <com/sun/star/beans/PropertyValue.hpp>
31 #include <com/sun/star/beans/XPropertySetInfo.hpp>
32 #include <com/sun/star/beans/XPropertySet.hpp>
33 #include <com/sun/star/awt/SystemPointer.hpp>
34 #include <com/sun/star/util/URLTransformer.hpp>
35 #include <com/sun/star/util/XURLTransformer.hpp>
36 #include <com/sun/star/frame/XDispatch.hpp>
37 #include <com/sun/star/frame/XLayoutManager.hpp>
38 #include <com/sun/star/presentation/SlideShow.hpp>
39 #include <com/sun/star/media/XPlayer.hpp>
40 #include <officecfg/Office/Common.hxx>
41 #include <svl/stritem.hxx>
42 #include <svl/urihelper.hxx>
43 #include <basic/sbstar.hxx>
45 #include <toolkit/helper/vclunohelper.hxx>
46 #include <comphelper/diagnose_ex.hxx>
48 #include <sfx2/infobar.hxx>
49 #include <sfx2/dispatch.hxx>
50 #include <sfx2/docfile.hxx>
51 #include <sfx2/app.hxx>
52 #include <sfx2/viewfrm.hxx>
53 #include <svx/svdoole2.hxx>
54 #include <svx/f3dchild.hxx>
55 #include <svx/imapdlg.hxx>
56 #include <svx/fontwork.hxx>
57 #include <svx/SvxColorChildWindow.hxx>
58 #include <svx/bmpmask.hxx>
59 #include <svx/srchdlg.hxx>
60 #include <svx/hyperdlg.hxx>
61 #include <svx/svxids.hrc>
62 #include <AnimationChildWindow.hxx>
63 #include <notifydocumentevent.hxx>
64 #include "slideshowimpl.hxx"
65 #include "slideshowviewimpl.hxx"
66 #include "PaneHider.hxx"
68 #include <bitmaps.hlst>
69 #include <strings.hrc>
70 #include <sdresid.hxx>
72 #include <vcl/canvastools.hxx>
73 #include <vcl/commandevent.hxx>
74 #include <vcl/weldutils.hxx>
76 #include <vcl/settings.hxx>
77 #include <vcl/svapp.hxx>
78 #include <vcl/help.hxx>
79 #include <comphelper/processfactory.hxx>
80 #include <comphelper/propertyvalue.hxx>
81 #include <rtl/ref.hxx>
82 #include <o3tl/safeint.hxx>
83 #include <o3tl/string_view.hxx>
84 #include <avmedia/mediawindow.hxx>
85 #include <svtools/colrdlg.hxx>
86 #include <DrawDocShell.hxx>
87 #include <ViewShellBase.hxx>
88 #include <PresentationViewShell.hxx>
89 #include <RemoteServer.hxx>
90 #include <customshowlist.hxx>
91 #include <unopage.hxx>
95 #include <cusshow.hxx>
96 #include <optsitem.hxx>
100 using ::com::sun::star::animations::XAnimationNode
;
101 using ::com::sun::star::animations::XAnimationListener
;
102 using ::com::sun::star::awt::XWindow
;
103 using namespace ::com::sun::star
;
104 using namespace ::com::sun::star::lang
;
105 using namespace ::com::sun::star::uno
;
106 using namespace ::com::sun::star::drawing
;
107 using namespace ::com::sun::star::container
;
108 using namespace ::com::sun::star::document
;
109 using namespace ::com::sun::star::presentation
;
110 using namespace ::com::sun::star::beans
;
114 /** Slots, which will be disabled in the slide show and are managed by Sfx.
115 Have to be sorted in the order of the SIDs */
116 sal_uInt16
const pAllowed
[] =
118 SID_OPENDOC
, // 5501 ///< that internally jumps work
119 SID_JUMPTOMARK
, // 5598
120 SID_OPENHYPERLINK
, // 6676
121 SID_PRESENTATION_END
// 27218
124 class AnimationSlideController
127 enum Mode
{ ALL
, FROM
, CUSTOM
, PREVIEW
};
130 AnimationSlideController( Reference
< XIndexAccess
> const & xSlides
, Mode eMode
);
132 void setStartSlideNumber( sal_Int32 nSlideNumber
) { mnStartSlideNumber
= nSlideNumber
; }
133 sal_Int32
getStartSlideIndex() const;
135 sal_Int32
getCurrentSlideNumber() const;
136 sal_Int32
getCurrentSlideIndex() const;
138 sal_Int32
getSlideIndexCount() const { return maSlideNumbers
.size(); }
139 sal_Int32
getSlideNumberCount() const { return mnSlideCount
; }
141 sal_Int32
getSlideNumber( sal_Int32 nSlideIndex
) const;
143 void insertSlideNumber( sal_Int32 nSlideNumber
, bool bVisible
= true );
144 void setPreviewNode( const Reference
< XAnimationNode
>& xPreviewNode
);
146 bool jumpToSlideIndex( sal_Int32 nNewSlideIndex
);
147 bool jumpToSlideNumber( sal_Int32 nNewSlideIndex
);
150 bool previousSlide();
152 void displayCurrentSlide( const Reference
< XSlideShow
>& xShow
,
153 const Reference
< XDrawPagesSupplier
>& xDrawPages
,
154 const bool bSkipAllMainSequenceEffects
);
156 sal_Int32
getNextSlideIndex() const;
157 sal_Int32
getPreviousSlideIndex() const;
159 bool isVisibleSlideNumber( sal_Int32 nSlideNumber
) const;
161 Reference
< XDrawPage
> getSlideByNumber( sal_Int32 nSlideNumber
) const;
163 sal_Int32
getNextSlideNumber() const;
165 bool hasSlides() const { return !maSlideNumbers
.empty(); }
168 bool getSlideAPI( sal_Int32 nSlideNumber
, Reference
< XDrawPage
>& xSlide
, Reference
< XAnimationNode
>& xAnimNode
);
169 sal_Int32
findSlideIndex( sal_Int32 nSlideNumber
) const;
171 bool isValidIndex( sal_Int32 nIndex
) const { return (nIndex
>= 0) && (o3tl::make_unsigned(nIndex
) < maSlideNumbers
.size()); }
172 bool isValidSlideNumber( sal_Int32 nSlideNumber
) const { return (nSlideNumber
>= 0) && (nSlideNumber
< mnSlideCount
); }
176 sal_Int32 mnStartSlideNumber
;
177 std::vector
< sal_Int32
> maSlideNumbers
;
178 std::vector
< bool > maSlideVisible
;
179 std::vector
< bool > maSlideVisited
;
180 Reference
< XAnimationNode
> mxPreviewNode
;
181 sal_Int32 mnSlideCount
;
182 sal_Int32 mnCurrentSlideIndex
;
183 sal_Int32 mnHiddenSlideNumber
;
184 Reference
< XIndexAccess
> mxSlides
;
187 Reference
< XDrawPage
> AnimationSlideController::getSlideByNumber( sal_Int32 nSlideNumber
) const
189 Reference
< XDrawPage
> xSlide
;
190 if( mxSlides
.is() && (nSlideNumber
>= 0) && (nSlideNumber
< mxSlides
->getCount()) )
191 mxSlides
->getByIndex( nSlideNumber
) >>= xSlide
;
195 bool AnimationSlideController::isVisibleSlideNumber( sal_Int32 nSlideNumber
) const
197 sal_Int32 nIndex
= findSlideIndex( nSlideNumber
);
200 return maSlideVisible
[ nIndex
];
205 void AnimationSlideController::setPreviewNode( const Reference
< XAnimationNode
>& xPreviewNode
)
207 mxPreviewNode
= xPreviewNode
;
210 AnimationSlideController::AnimationSlideController( Reference
< XIndexAccess
> const & xSlides
, Mode eMode
)
212 , mnStartSlideNumber(-1)
214 , mnCurrentSlideIndex(0)
215 , mnHiddenSlideNumber( -1 )
216 , mxSlides( xSlides
)
219 mnSlideCount
= xSlides
->getCount();
222 sal_Int32
AnimationSlideController::getStartSlideIndex() const
224 if( mnStartSlideNumber
>= 0 )
227 const sal_Int32 nCount
= maSlideNumbers
.size();
229 for( nIndex
= 0; nIndex
< nCount
; nIndex
++ )
231 if( maSlideNumbers
[nIndex
] == mnStartSlideNumber
)
239 sal_Int32
AnimationSlideController::getCurrentSlideNumber() const
241 if( mnHiddenSlideNumber
!= -1 )
242 return mnHiddenSlideNumber
;
243 else if( !maSlideNumbers
.empty() )
244 return maSlideNumbers
[mnCurrentSlideIndex
];
249 sal_Int32
AnimationSlideController::getCurrentSlideIndex() const
251 if( mnHiddenSlideNumber
!= -1 )
254 return mnCurrentSlideIndex
;
257 bool AnimationSlideController::jumpToSlideIndex( sal_Int32 nNewSlideIndex
)
259 if( isValidIndex( nNewSlideIndex
) )
261 mnCurrentSlideIndex
= nNewSlideIndex
;
262 mnHiddenSlideNumber
= -1;
263 maSlideVisited
[mnCurrentSlideIndex
] = true;
272 bool AnimationSlideController::jumpToSlideNumber( sal_Int32 nNewSlideNumber
)
274 sal_Int32 nIndex
= findSlideIndex( nNewSlideNumber
);
275 if( isValidIndex( nIndex
) )
277 return jumpToSlideIndex( nIndex
);
279 else if( (nNewSlideNumber
>= 0) && (nNewSlideNumber
< mnSlideCount
) )
281 // jump to a hidden slide
282 mnHiddenSlideNumber
= nNewSlideNumber
;
291 sal_Int32
AnimationSlideController::getSlideNumber( sal_Int32 nSlideIndex
) const
293 if( isValidIndex( nSlideIndex
) )
294 return maSlideNumbers
[nSlideIndex
];
299 void AnimationSlideController::insertSlideNumber( sal_Int32 nSlideNumber
, bool bVisible
/* = true */ )
301 DBG_ASSERT( isValidSlideNumber( nSlideNumber
), "sd::AnimationSlideController::insertSlideNumber(), illegal index" );
302 if( isValidSlideNumber( nSlideNumber
) )
304 maSlideNumbers
.push_back( nSlideNumber
);
305 maSlideVisible
.push_back( bVisible
);
306 maSlideVisited
.push_back( false );
310 bool AnimationSlideController::getSlideAPI( sal_Int32 nSlideNumber
, Reference
< XDrawPage
>& xSlide
, Reference
< XAnimationNode
>& xAnimNode
)
312 if( isValidSlideNumber( nSlideNumber
) ) try
314 xSlide
.set( mxSlides
->getByIndex(nSlideNumber
), UNO_QUERY_THROW
);
316 if( meMode
== PREVIEW
)
318 xAnimNode
= mxPreviewNode
;
322 Reference
< animations::XAnimationNodeSupplier
> xAnimNodeSupplier( xSlide
, UNO_QUERY_THROW
);
323 xAnimNode
= xAnimNodeSupplier
->getAnimationNode();
330 TOOLS_WARN_EXCEPTION( "sd", "sd::AnimationSlideController::getSlideAPI()" );
336 sal_Int32
AnimationSlideController::findSlideIndex( sal_Int32 nSlideNumber
) const
339 const sal_Int32 nCount
= maSlideNumbers
.size();
341 for( nIndex
= 0; nIndex
< nCount
; nIndex
++ )
343 if( maSlideNumbers
[nIndex
] == nSlideNumber
)
350 sal_Int32
AnimationSlideController::getNextSlideIndex() const
356 sal_Int32 nNewSlideIndex
= mnCurrentSlideIndex
+ 1;
357 if( isValidIndex( nNewSlideIndex
) )
359 // if the current slide is not excluded, make sure the
360 // next slide is also not excluded.
361 // if the current slide is excluded, we want to go
362 // to the next slide, even if this is also excluded.
363 if( maSlideVisible
[mnCurrentSlideIndex
] )
365 while( isValidIndex( nNewSlideIndex
) )
367 if( maSlideVisible
[nNewSlideIndex
] )
374 return isValidIndex( nNewSlideIndex
) ? nNewSlideIndex
: -1;
379 return mnHiddenSlideNumber
== -1 ? mnCurrentSlideIndex
+ 1 : mnCurrentSlideIndex
;
388 sal_Int32
AnimationSlideController::getNextSlideNumber() const
390 sal_Int32 nNextSlideIndex
= getNextSlideIndex();
391 if( isValidIndex( nNextSlideIndex
) )
393 return maSlideNumbers
[nNextSlideIndex
];
401 bool AnimationSlideController::nextSlide()
403 return jumpToSlideIndex( getNextSlideIndex() );
406 sal_Int32
AnimationSlideController::getPreviousSlideIndex() const
408 sal_Int32 nNewSlideIndex
= mnCurrentSlideIndex
- 1;
414 // make sure the previous slide is visible
415 // or was already visited
416 while( isValidIndex( nNewSlideIndex
) )
418 if( maSlideVisible
[nNewSlideIndex
] || maSlideVisited
[nNewSlideIndex
] )
434 return nNewSlideIndex
;
437 bool AnimationSlideController::previousSlide()
439 return jumpToSlideIndex( getPreviousSlideIndex() );
442 void AnimationSlideController::displayCurrentSlide( const Reference
< XSlideShow
>& xShow
,
443 const Reference
< XDrawPagesSupplier
>& xDrawPages
,
444 const bool bSkipAllMainSequenceEffects
)
446 const sal_Int32 nCurrentSlideNumber
= getCurrentSlideNumber();
448 if( !(xShow
.is() && (nCurrentSlideNumber
!= -1 )) )
451 Reference
< XDrawPage
> xSlide
;
452 Reference
< XAnimationNode
> xAnimNode
;
453 ::std::vector
<PropertyValue
> aProperties
;
455 const sal_Int32 nNextSlideNumber
= getNextSlideNumber();
456 if( getSlideAPI( nNextSlideNumber
, xSlide
, xAnimNode
) )
458 Sequence
< Any
> aValue
{ Any(xSlide
), Any(xAnimNode
) };
459 aProperties
.emplace_back( "Prefetch" ,
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
.emplace_back( "SkipAllMainSequenceEffects",
473 PropertyState_DIRECT_VALUE
);
474 aProperties
.emplace_back("SkipSlideTransition",
477 PropertyState_DIRECT_VALUE
);
480 if( getSlideAPI( nCurrentSlideNumber
, xSlide
, xAnimNode
) )
481 xShow
->displaySlide( xSlide
, xDrawPages
, xAnimNode
, comphelper::containerToSequence(aProperties
) );
484 constexpr OUStringLiteral
gsOnClick( u
"OnClick" );
485 constexpr OUStringLiteral
gsBookmark( u
"Bookmark" );
486 constexpr OUStringLiteral
gsVerb( u
"Verb" );
488 SlideshowImpl::SlideshowImpl( const Reference
< XPresentation2
>& xPresentation
, ViewShell
* pViewSh
, ::sd::View
* pView
, SdDrawDocument
* pDoc
, vcl::Window
* pParentWindow
)
489 : mxModel(pDoc
->getUnoModel(),UNO_QUERY_THROW
)
490 , maUpdateTimer("SlideShowImpl maUpdateTimer")
491 , maInputFreezeTimer("SlideShowImpl maInputFreezeTimer")
492 , maDeactivateTimer("SlideShowImpl maDeactivateTimer")
494 , mpViewShell(pViewSh
)
495 , mpDocSh(pDoc
->GetDocSh())
497 , mpParentWindow(pParentWindow
)
498 , mpShowWindow(nullptr)
500 , maPresSize( -1, -1 )
501 , meAnimationMode(ANIMATIONMODE_SHOW
)
502 , mpOldActiveWindow(nullptr)
505 , mbAutoSaveWasOn(false)
506 , mbRehearseTimings(false)
509 , mbInputFreeze(false)
511 , maPresSettings( pDoc
->getPresentationSettings() )
512 , mnUserPaintColor( 0x80ff0000L
)
514 , mdUserPaintStrokeWidth ( 150.0 )
515 , mnEndShowEvent(nullptr)
516 , mnContextMenuEvent(nullptr)
517 , mxPresentation( xPresentation
)
520 mpOldActiveWindow
= mpViewShell
->GetActiveWindow();
522 maUpdateTimer
.SetInvokeHandler(LINK(this, SlideshowImpl
, updateHdl
));
523 // Priority must not be too high or we'll starve input handling etc.
524 maUpdateTimer
.SetPriority(TaskPriority::REPAINT
);
526 maDeactivateTimer
.SetInvokeHandler(LINK(this, SlideshowImpl
, deactivateHdl
));
527 maDeactivateTimer
.SetTimeout( 20 );
529 maInputFreezeTimer
.SetInvokeHandler( LINK( this, SlideshowImpl
, ReadyForNextInputHdl
) );
530 maInputFreezeTimer
.SetTimeout( 20 );
532 // no autosave during show
533 if( officecfg::Office::Common::Save::Document::AutoSave::get() )
534 mbAutoSaveWasOn
= true;
536 Application::AddEventListener( LINK( this, SlideshowImpl
, EventListenerHdl
) );
538 mbUsePen
= maPresSettings
.mbMouseAsPen
;
540 SdOptions
* pOptions
= SD_MOD()->GetSdOptions(DocumentType::Impress
);
543 mnUserPaintColor
= pOptions
->GetPresentationPenColor();
544 mdUserPaintStrokeWidth
= pOptions
->GetPresentationPenWidth();
548 SlideshowImpl::~SlideshowImpl()
550 SdModule
*pModule
= SD_MOD();
551 //rhbz#806663 SlideshowImpl can outlive SdModule
552 SdOptions
* pOptions
= pModule
?
553 pModule
->GetSdOptions(DocumentType::Impress
) : nullptr;
556 pOptions
->SetPresentationPenColor(mnUserPaintColor
);
557 pOptions
->SetPresentationPenWidth(mdUserPaintStrokeWidth
);
560 Application::RemoveEventListener( LINK( this, SlideshowImpl
, EventListenerHdl
) );
562 maDeactivateTimer
.Stop();
566 OSL_FAIL("SlideshowImpl::~SlideshowImpl(), component was not disposed!");
567 std::unique_lock
g(m_aMutex
);
572 void SlideshowImpl::disposing(std::unique_lock
<std::mutex
>&)
574 #ifdef ENABLE_SDREMOTE
575 RemoteServer::presentationStopped();
577 if( mxShow
.is() && mpDoc
)
580 "OnEndPresentation" );
582 if( mbAutoSaveWasOn
)
583 setAutoSaveState( true );
586 Application::RemoveUserEvent( mnEndShowEvent
);
587 if( mnContextMenuEvent
)
588 Application::RemoveUserEvent( mnContextMenuEvent
);
590 maInputFreezeTimer
.Stop();
592 SolarMutexGuard aSolarGuard
;
597 if( mxPresentation
.is() )
598 mxPresentation
->end();
600 maUpdateTimer
.Stop();
604 if( mxListenerProxy
.is() )
605 mxListenerProxy
->removeAsSlideShowListener();
610 mxShow
->removeView( mxView
);
612 Reference
< XComponent
> xComponent( mxShow
, UNO_QUERY
);
613 if( xComponent
.is() )
614 xComponent
->dispose();
621 TOOLS_WARN_EXCEPTION( "sd", "sd::SlideshowImpl::stop()" );
626 mxListenerProxy
.clear();
627 mpSlideController
.reset();
629 // take DrawView from presentation window, but give the old window back
630 if( mpShowWindow
&& mpView
)
631 mpView
->DeleteDeviceFromPaintView( *mpShowWindow
->GetOutDev() );
634 mpView
->SetAnimationPause( false );
638 mpViewShell
->SetActiveWindow(mpOldActiveWindow
);
640 mpShowWindow
->SetViewShell( nullptr );
644 mpView
->InvalidateAllWin();
646 if( maPresSettings
.mbFullScreen
)
648 #if HAVE_FEATURE_SCRIPTING
649 // restore StarBASICErrorHdl
650 StarBASIC::SetGlobalErrorHdl(maStarBASICGlobalErrorHdl
);
651 maStarBASICGlobalErrorHdl
= Link
<StarBASIC
*,bool>();
657 mpShowWindow
->Hide();
660 if( meAnimationMode
== ANIMATIONMODE_SHOW
)
662 mpDocSh
->SetSlotFilter();
663 mpDocSh
->ApplySlotFilter();
665 Help::EnableContextHelp();
666 Help::EnableExtHelp();
672 // show current window again
673 if( mpViewShell
&& dynamic_cast< PresentationViewShell
*>( mpViewShell
) == nullptr)
675 if( meAnimationMode
== ANIMATIONMODE_SHOW
)
677 mpViewShell
->GetViewShellBase().ShowUIControls (true);
680 else if( meAnimationMode
== ANIMATIONMODE_PREVIEW
)
682 mpViewShell
->ShowUIControls(true);
687 mpShowWindow
->Hide();
688 mpShowWindow
.disposeAndClear();
692 if( meAnimationMode
== ANIMATIONMODE_SHOW
)
694 ::sd::Window
* pActWin
= mpViewShell
->GetActiveWindow();
698 Size aVisSizePixel
= pActWin
->GetOutputSizePixel();
699 ::tools::Rectangle aVisAreaWin
= pActWin
->PixelToLogic( ::tools::Rectangle( Point(0,0), aVisSizePixel
) );
700 mpViewShell
->VisAreaChanged(aVisAreaWin
);
702 mpView
->VisAreaChanged(pActWin
->GetOutDev());
703 pActWin
->GrabFocus();
707 // restart the custom show dialog if he started us
708 if( mpViewShell
->IsStartShowWithDialog() && getDispatcher() )
710 mpViewShell
->SetStartShowWithDialog( false );
711 getDispatcher()->Execute( SID_CUSTOMSHOW_DLG
, SfxCallMode::ASYNCHRON
| SfxCallMode::RECORD
);
714 mpViewShell
->GetViewShellBase().UpdateBorder(true);
719 mpShowWindow
.disposeAndClear();
722 setActiveXToolbarsVisible( true );
727 bool SlideshowImpl::startPreview(
728 const Reference
< XDrawPage
>& xDrawPage
,
729 const Reference
< XAnimationNode
>& xAnimationNode
,
730 vcl::Window
* pParent
)
736 const Reference
<lang::XServiceInfo
> xServiceInfo( xDrawPage
, UNO_QUERY
);
737 if (xServiceInfo
.is()) {
738 const Sequence
<OUString
> supportedServices(
739 xServiceInfo
->getSupportedServiceNames() );
740 if (comphelper::findValue(supportedServices
, "com.sun.star.drawing.MasterPage") != -1) {
741 OSL_FAIL("sd::SlideshowImpl::startPreview() "
742 "not allowed on master page!");
747 mxPreviewDrawPage
= xDrawPage
;
748 mxPreviewAnimationNode
= xAnimationNode
;
749 meAnimationMode
= ANIMATIONMODE_PREVIEW
;
751 maPresSettings
.mbAll
= false;
752 maPresSettings
.mbEndless
= false;
753 maPresSettings
.mbCustomShow
= false;
754 maPresSettings
.mbManual
= false;
755 maPresSettings
.mbMouseVisible
= false;
756 maPresSettings
.mbMouseAsPen
= false;
757 maPresSettings
.mbLockedPages
= false;
758 maPresSettings
.mbAlwaysOnTop
= false;
759 maPresSettings
.mbUseNavigation
= false;
760 maPresSettings
.mbFullScreen
= false;
761 maPresSettings
.mbAnimationAllowed
= true;
762 maPresSettings
.mnPauseTimeout
= 0;
763 maPresSettings
.mbShowPauseLogo
= false;
765 Reference
< XDrawPagesSupplier
> xDrawPages( mpDoc
->getUnoModel(), UNO_QUERY_THROW
);
766 Reference
< XIndexAccess
> xSlides( xDrawPages
->getDrawPages(), UNO_QUERY_THROW
);
767 mpSlideController
= std::make_shared
<AnimationSlideController
>( xSlides
, AnimationSlideController::PREVIEW
);
769 sal_Int32 nSlideNumber
= 0;
770 Reference
< XPropertySet
> xSet( mxPreviewDrawPage
, UNO_QUERY_THROW
);
771 xSet
->getPropertyValue( "Number" ) >>= nSlideNumber
;
772 mpSlideController
->insertSlideNumber( nSlideNumber
-1 );
773 mpSlideController
->setPreviewNode( xAnimationNode
);
775 mpShowWindow
= VclPtr
<ShowWindow
>::Create( this, ((pParent
== nullptr) && mpViewShell
) ? mpParentWindow
.get() : pParent
);
778 mpViewShell
->SetActiveWindow( mpShowWindow
);
779 mpShowWindow
->SetViewShell (mpViewShell
);
780 mpViewShell
->ShowUIControls (false);
785 mpView
->AddDeviceToPaintView( *mpShowWindow
->GetOutDev(), nullptr );
786 mpView
->SetAnimationPause( true );
789 // call resize handler
792 maPresSize
= pParent
->GetSizePixel();
794 else if( mpViewShell
)
796 ::tools::Rectangle
aContentRect (mpViewShell
->GetViewShellBase().getClientRectangle());
797 if (AllSettings::GetLayoutRTL())
799 aContentRect
.SetLeft( aContentRect
.Right() );
800 aContentRect
.AdjustRight(aContentRect
.Right() );
802 maPresSize
= aContentRect
.GetSize();
803 mpShowWindow
->SetPosPixel( aContentRect
.TopLeft() );
807 OSL_FAIL("sd::SlideshowImpl::startPreview(), I need either a parent window or a viewshell!");
809 resize( maPresSize
);
811 sal_Int32 nPropertyCount
= 1;
812 if( mxPreviewAnimationNode
.is() )
815 Sequence
< beans::PropertyValue
> aProperties(nPropertyCount
);
816 auto pProperties
= aProperties
.getArray();
817 pProperties
[0].Name
= "AutomaticAdvancement";
818 pProperties
[0].Value
<<= 1.0; // one second timeout
820 if( mxPreviewAnimationNode
.is() )
822 pProperties
[1].Name
= "NoSlideTransitions";
823 pProperties
[1].Value
<<= true;
826 bRet
= startShowImpl( aProperties
);
828 if( mpShowWindow
!= nullptr && meAnimationMode
== ANIMATIONMODE_PREVIEW
)
829 mpShowWindow
->SetPreviewMode();
834 TOOLS_WARN_EXCEPTION( "sd", "sd::SlideshowImpl::startPreview()" );
841 bool SlideshowImpl::startShow( PresentationSettingsEx
const * pPresSettings
)
843 const rtl::Reference
<SlideshowImpl
> xKeepAlive(this);
845 DBG_ASSERT( !mxShow
.is(), "sd::SlideshowImpl::startShow(), called twice!" );
848 DBG_ASSERT( mpParentWindow
!=nullptr, "sd::SlideshowImpl::startShow() called without parent window" );
849 if (mpParentWindow
== nullptr)
852 // Autoplay (pps/ppsx)
853 if (mpViewShell
->GetDoc()->IsStartWithPresentation()){
854 mpViewShell
->GetDoc()->SetExitAfterPresenting(true);
863 maPresSettings
= *pPresSettings
;
864 mbRehearseTimings
= pPresSettings
->mbRehearseTimings
;
867 OUString
aPresSlide( maPresSettings
.maPresPage
);
868 SdPage
* pStartPage
= mpViewShell
->GetActualPage();
869 bool bStartWithActualSlide
= pStartPage
;
871 // times should be measured?
872 if( mbRehearseTimings
)
874 maPresSettings
.mbEndless
= false;
875 maPresSettings
.mbManual
= true;
876 maPresSettings
.mbMouseVisible
= true;
877 maPresSettings
.mbMouseAsPen
= false;
878 maPresSettings
.mnPauseTimeout
= 0;
879 maPresSettings
.mbShowPauseLogo
= false;
880 maPresSettings
.mbUseNavigation
= false;
885 if( pStartPage
->GetPageKind() == PageKind::Notes
)
887 // we are in notes page mode, so get
888 // the corresponding draw page
889 const sal_uInt16 nPgNum
= ( pStartPage
->GetPageNum() - 2 ) >> 1;
890 pStartPage
= mpDoc
->GetSdPage( nPgNum
, PageKind::Standard
);
894 if( bStartWithActualSlide
)
896 if ( aPresSlide
.isEmpty())
898 // no preset slide yet, so pick current on one
899 aPresSlide
= pStartPage
->GetName();
900 // if the starting slide is hidden, we can't set slide controller to ALL mode
901 maPresSettings
.mbAll
= !pStartPage
->IsExcluded();
904 if( meAnimationMode
!= ANIMATIONMODE_SHOW
)
906 if( pStartPage
->GetPageKind() == PageKind::Standard
)
908 maPresSettings
.mbAll
= false;
914 createSlideList( maPresSettings
.mbAll
, aPresSlide
);
916 // remember Slide number from where the show was started
918 mnRestoreSlide
= ( pStartPage
->GetPageNum() - 1 ) / 2;
920 if( mpSlideController
->hasSlides() )
922 // hide child windows
925 mpShowWindow
= VclPtr
<ShowWindow
>::Create( this, mpParentWindow
);
926 mpShowWindow
->SetMouseAutoHide( !maPresSettings
.mbMouseVisible
);
927 mpViewShell
->SetActiveWindow( mpShowWindow
);
928 mpShowWindow
->SetViewShell (mpViewShell
);
929 mpViewShell
->GetViewShellBase().ShowUIControls (false);
930 // Hide the side panes for in-place presentations.
931 if ( ! maPresSettings
.mbFullScreen
)
932 mpPaneHider
.reset(new PaneHider(*mpViewShell
,this));
934 // these Slots are forbidden in other views for this document
937 mpDocSh
->SetSlotFilter( true, pAllowed
);
938 mpDocSh
->ApplySlotFilter();
941 Help::DisableContextHelp();
942 Help::DisableExtHelp();
944 if( maPresSettings
.mbFullScreen
)
946 #if HAVE_FEATURE_SCRIPTING
947 // disable basic ide error handling
948 maStarBASICGlobalErrorHdl
= StarBASIC::GetGlobalErrorHdl();
949 StarBASIC::SetGlobalErrorHdl( Link
<StarBASIC
*,bool>() );
953 // call resize handler
954 maPresSize
= mpParentWindow
->GetSizePixel();
955 if (!maPresSettings
.mbFullScreen
)
957 const ::tools::Rectangle
& aClientRect
= mpViewShell
->GetViewShellBase().getClientRectangle();
958 maPresSize
= aClientRect
.GetSize();
959 mpShowWindow
->SetPosPixel( aClientRect
.TopLeft() );
960 resize( maPresSize
);
964 // Note: In FullScreen Mode the OS (window manager) sends a resize to
965 // the WorkWindow once it actually resized it to full size. The
966 // WorkWindow propagates the resize to the DrawViewShell which calls
967 // resize() at the SlideShow (this). Calling resize here results in a
968 // temporary display of a black window in the window's default size
972 mpView
->AddDeviceToPaintView( *mpShowWindow
->GetOutDev(), nullptr );
973 mpView
->SetAnimationPause( true );
976 SfxBindings
* pBindings
= getBindings();
979 pBindings
->Invalidate( SID_PRESENTATION
);
980 pBindings
->Invalidate( SID_REHEARSE_TIMINGS
);
983 // Defer the sd::ShowWindow's GrabFocus to SlideShow::activate. so that the accessible event can be fired correctly.
984 //mpShowWindow->GrabFocus();
986 std::vector
<beans::PropertyValue
> aProperties
;
987 aProperties
.reserve( 4 );
989 aProperties
.emplace_back( "AdvanceOnClick" ,
990 -1, Any( !maPresSettings
.mbLockedPages
),
991 beans::PropertyState_DIRECT_VALUE
);
993 aProperties
.emplace_back( "ImageAnimationsAllowed" ,
994 -1, Any( maPresSettings
.mbAnimationAllowed
),
995 beans::PropertyState_DIRECT_VALUE
);
997 const bool bZOrderEnabled(
998 SD_MOD()->GetSdOptions( mpDoc
->GetDocumentType() )->IsSlideshowRespectZOrder() );
999 aProperties
.emplace_back( "DisableAnimationZOrder" ,
1000 -1, Any( !bZOrderEnabled
),
1001 beans::PropertyState_DIRECT_VALUE
);
1003 aProperties
.emplace_back( "ForceManualAdvance" ,
1004 -1, Any( maPresSettings
.mbManual
),
1005 beans::PropertyState_DIRECT_VALUE
);
1009 aProperties
.emplace_back( "UserPaintColor" ,
1010 // User paint color is black by default.
1011 -1, Any( mnUserPaintColor
),
1012 beans::PropertyState_DIRECT_VALUE
);
1014 aProperties
.emplace_back( "UserPaintStrokeWidth" ,
1015 // User paint color is black by default.
1016 -1, Any( mdUserPaintStrokeWidth
),
1017 beans::PropertyState_DIRECT_VALUE
);
1020 if (mbRehearseTimings
) {
1021 aProperties
.emplace_back( "RehearseTimings" ,
1022 -1, Any(true), beans::PropertyState_DIRECT_VALUE
);
1025 bRet
= startShowImpl( Sequence
<beans::PropertyValue
>(
1026 aProperties
.data(), aProperties
.size() ) );
1030 setActiveXToolbarsVisible( false );
1032 catch (const Exception
&)
1034 TOOLS_WARN_EXCEPTION( "sd", "sd::SlideshowImpl::startShow()" );
1041 bool SlideshowImpl::startShowImpl( const Sequence
< beans::PropertyValue
>& aProperties
)
1045 mxShow
.set( createSlideShow(), UNO_SET_THROW
);
1047 mxView
= new SlideShowView(
1052 maPresSettings
.mbFullScreen
);
1054 // try add wait symbol to properties:
1055 const Reference
<rendering::XSpriteCanvas
> xSpriteCanvas(
1056 mxView
->getCanvas() );
1057 if (xSpriteCanvas
.is())
1059 BitmapEx
waitSymbolBitmap(BMP_WAIT_ICON
);
1060 const Reference
<rendering::XBitmap
> xBitmap(
1061 vcl::unotools::xBitmapFromBitmapEx( waitSymbolBitmap
) );
1064 mxShow
->setProperty(
1065 beans::PropertyValue( "WaitSymbolBitmap" ,
1068 beans::PropertyState_DIRECT_VALUE
) );
1071 BitmapEx
pointerSymbolBitmap(BMP_POINTER_ICON
);
1072 const Reference
<rendering::XBitmap
> xPointerBitmap(
1073 vcl::unotools::xBitmapFromBitmapEx( pointerSymbolBitmap
) );
1074 if (xPointerBitmap
.is())
1076 mxShow
->setProperty(
1077 beans::PropertyValue( "PointerSymbolBitmap" ,
1079 Any( xPointerBitmap
),
1080 beans::PropertyState_DIRECT_VALUE
) );
1083 if (maPresSettings
.mbUseNavigation
)
1085 BitmapEx
prevSlideBm(BMP_PREV_SLIDE
);
1086 const Reference
<rendering::XBitmap
> xPrevSBitmap(
1087 vcl::unotools::xBitmapFromBitmapEx(prevSlideBm
));
1088 if (xPrevSBitmap
.is())
1090 mxShow
->setProperty(beans::PropertyValue("NavigationSlidePrev", -1,
1092 beans::PropertyState_DIRECT_VALUE
));
1094 BitmapEx
menuSlideBm(BMP_MENU_SLIDE
);
1095 const Reference
<rendering::XBitmap
> xMenuSBitmap(
1096 vcl::unotools::xBitmapFromBitmapEx(menuSlideBm
));
1097 if (xMenuSBitmap
.is())
1099 mxShow
->setProperty(beans::PropertyValue("NavigationSlideMenu", -1,
1101 beans::PropertyState_DIRECT_VALUE
));
1103 BitmapEx
nextSlideBm(BMP_NEXT_SLIDE
);
1104 const Reference
<rendering::XBitmap
> xNextSBitmap(
1105 vcl::unotools::xBitmapFromBitmapEx(nextSlideBm
));
1106 if (xNextSBitmap
.is())
1108 mxShow
->setProperty(beans::PropertyValue("NavigationSlideNext", -1,
1110 beans::PropertyState_DIRECT_VALUE
));
1115 for( const auto& rProp
: aProperties
)
1116 mxShow
->setProperty( rProp
);
1118 mxShow
->addView( mxView
);
1120 mxListenerProxy
.set( new SlideShowListenerProxy( this, mxShow
) );
1121 mxListenerProxy
->addAsSlideShowListener();
1123 NotifyDocumentEvent(
1125 "OnStartPresentation");
1126 displaySlideIndex( mpSlideController
->getStartSlideIndex() );
1132 TOOLS_WARN_EXCEPTION( "sd", "sd::SlideshowImpl::startShowImpl()" );
1137 /** called only by the slideshow view when the first paint event occurs.
1138 This actually starts the slideshow. */
1139 void SlideshowImpl::onFirstPaint()
1144 mpShowWindow->SetBackground( Wallpaper( COL_BLACK ) );
1145 mpShowWindow->Erase();
1146 mpShowWindow->SetBackground();
1150 SolarMutexGuard aSolarGuard
;
1151 maUpdateTimer
.SetTimeout( sal_uLong(100) );
1152 maUpdateTimer
.Start();
1155 void SlideshowImpl::paint()
1157 if( mxView
.is() ) try
1159 awt::PaintEvent aEvt
;
1160 // aEvt.UpdateRect = TODO
1161 mxView
->paint( aEvt
);
1165 TOOLS_WARN_EXCEPTION( "sd", "sd::SlideshowImpl::paint()" );
1169 void SAL_CALL
SlideshowImpl::addSlideShowListener( const Reference
< XSlideShowListener
>& xListener
)
1171 if( mxListenerProxy
.is() )
1172 mxListenerProxy
->addSlideShowListener( xListener
);
1175 void SAL_CALL
SlideshowImpl::removeSlideShowListener( const Reference
< XSlideShowListener
>& xListener
)
1177 if( mxListenerProxy
.is() )
1178 mxListenerProxy
->removeSlideShowListener( xListener
);
1181 void SlideshowImpl::slideEnded(const bool bReverse
)
1184 gotoPreviousSlide(true);
1189 bool SlideshowImpl::swipe(const CommandGestureSwipeData
&rSwipeData
)
1191 if (mbUsePen
|| mnContextMenuEvent
)
1193 double nVelocityX
= rSwipeData
.getVelocityX();
1194 // tdf#108475 make it swipe only if some reasonable movement was involved
1195 if (fabs(nVelocityX
) < 50)
1199 gotoPreviousSlide();
1205 //a swipe is followed by a mouse up, tell the view to ignore that mouse up as we've reacted
1206 //to the swipe instead
1207 mxView
->ignoreNextMouseReleased();
1211 bool SlideshowImpl::longpress(const CommandGestureLongPressData
&rLongPressData
)
1213 if (mnContextMenuEvent
)
1216 maPopupMousePos
= Point(rLongPressData
.getX(), rLongPressData
.getY());
1217 mnContextMenuEvent
= Application::PostUserEvent( LINK( this, SlideshowImpl
, ContextMenuHdl
) );
1222 void SlideshowImpl::removeShapeEvents()
1224 if( !(mxShow
.is() && mxListenerProxy
.is()) )
1229 for( const auto& rEntry
: maShapeEventMap
)
1231 mxListenerProxy
->removeShapeEventListener( rEntry
.first
);
1232 mxShow
->setShapeCursor( rEntry
.first
, awt::SystemPointer::ARROW
);
1235 maShapeEventMap
.clear();
1239 TOOLS_WARN_EXCEPTION( "sd", "sd::SlideshowImpl::removeShapeEvents()" );
1243 void SlideshowImpl::registerShapeEvents(sal_Int32 nSlideNumber
)
1245 if( nSlideNumber
< 0 )
1250 Reference
< XDrawPagesSupplier
> xDrawPages( mxModel
, UNO_QUERY_THROW
);
1251 Reference
< XIndexAccess
> xPages( xDrawPages
->getDrawPages(), UNO_QUERY_THROW
);
1253 Reference
< XShapes
> xDrawPage
;
1254 xPages
->getByIndex(nSlideNumber
) >>= xDrawPage
;
1256 if( xDrawPage
.is() )
1258 Reference
< XMasterPageTarget
> xMasterPageTarget( xDrawPage
, UNO_QUERY
);
1259 if( xMasterPageTarget
.is() )
1261 Reference
< XShapes
> xMasterPage
= xMasterPageTarget
->getMasterPage();
1262 if( xMasterPage
.is() )
1263 registerShapeEvents( xMasterPage
);
1265 registerShapeEvents( xDrawPage
);
1270 TOOLS_WARN_EXCEPTION( "sd", "sd::SlideshowImpl::registerShapeEvents()" );
1274 void SlideshowImpl::registerShapeEvents( Reference
< XShapes
> const & xShapes
)
1278 const sal_Int32 nShapeCount
= xShapes
->getCount();
1280 for( nShape
= 0; nShape
< nShapeCount
; nShape
++ )
1282 Reference
< XShape
> xShape
;
1283 xShapes
->getByIndex( nShape
) >>= xShape
;
1285 if( xShape
.is() && xShape
->getShapeType() == "com.sun.star.drawing.GroupShape" )
1287 Reference
< XShapes
> xSubShapes( xShape
, UNO_QUERY
);
1288 if( xSubShapes
.is() )
1289 registerShapeEvents( xSubShapes
);
1292 Reference
< XPropertySet
> xSet( xShape
, UNO_QUERY
);
1296 Reference
< XPropertySetInfo
> xSetInfo( xSet
->getPropertySetInfo() );
1297 if( !xSetInfo
.is() || !xSetInfo
->hasPropertyByName( gsOnClick
) )
1300 WrappedShapeEventImplPtr pEvent
= std::make_shared
<WrappedShapeEventImpl
>();
1301 xSet
->getPropertyValue( gsOnClick
) >>= pEvent
->meClickAction
;
1303 switch( pEvent
->meClickAction
)
1305 case ClickAction_PREVPAGE
:
1306 case ClickAction_NEXTPAGE
:
1307 case ClickAction_FIRSTPAGE
:
1308 case ClickAction_LASTPAGE
:
1309 case ClickAction_STOPPRESENTATION
:
1311 case ClickAction_BOOKMARK
:
1312 if( xSetInfo
->hasPropertyByName( gsBookmark
) )
1313 xSet
->getPropertyValue( gsBookmark
) >>= pEvent
->maStrBookmark
;
1314 if( getSlideNumberForBookmark( pEvent
->maStrBookmark
) == -1 )
1317 case ClickAction_DOCUMENT
:
1318 case ClickAction_SOUND
:
1319 case ClickAction_PROGRAM
:
1320 case ClickAction_MACRO
:
1321 if( xSetInfo
->hasPropertyByName( gsBookmark
) )
1322 xSet
->getPropertyValue( gsBookmark
) >>= pEvent
->maStrBookmark
;
1324 case ClickAction_VERB
:
1325 if( xSetInfo
->hasPropertyByName( gsVerb
) )
1326 xSet
->getPropertyValue( gsVerb
) >>= pEvent
->mnVerb
;
1329 continue; // skip all others
1332 maShapeEventMap
[ xShape
] = pEvent
;
1334 if( mxListenerProxy
.is() )
1335 mxListenerProxy
->addShapeEventListener( xShape
);
1336 mxShow
->setShapeCursor( xShape
, awt::SystemPointer::REFHAND
);
1341 TOOLS_WARN_EXCEPTION( "sd", "sd::SlideshowImpl::registerShapeEvents()" );
1345 void SlideshowImpl::displayCurrentSlide (const bool bSkipAllMainSequenceEffects
)
1348 removeShapeEvents();
1350 if( mpSlideController
&& mxShow
.is() )
1352 Reference
< XDrawPagesSupplier
> xDrawPages( mpDoc
->getUnoModel(),
1354 mpSlideController
->displayCurrentSlide( mxShow
, xDrawPages
, bSkipAllMainSequenceEffects
);
1355 registerShapeEvents(mpSlideController
->getCurrentSlideNumber());
1359 // send out page change event and notify to update all acc info for current page
1362 sal_Int32 currentPageIndex
= getCurrentSlideIndex();
1363 mpViewShell
->fireSwitchCurrentPage(currentPageIndex
);
1364 mpViewShell
->NotifyAccUpdate();
1368 void SlideshowImpl::endPresentation()
1370 if( maPresSettings
.mbMouseAsPen
)
1372 Reference
< XMultiServiceFactory
> xDocFactory(mpDoc
->getUnoModel(), UNO_QUERY
);
1373 if( xDocFactory
.is() )
1374 mxShow
->registerUserPaintPolygons(xDocFactory
);
1377 if( !mnEndShowEvent
)
1378 mnEndShowEvent
= Application::PostUserEvent( LINK(this, SlideshowImpl
, endPresentationHdl
) );
1381 IMPL_LINK_NOARG(SlideshowImpl
, endPresentationHdl
, void*, void)
1383 mnEndShowEvent
= nullptr;
1387 if( mxPresentation
.is() )
1388 mxPresentation
->end();
1391 void SAL_CALL
SlideshowImpl::pause()
1393 SolarMutexGuard aSolarGuard
;
1403 mxShow
->pause(true);
1405 if( mxListenerProxy
.is() )
1406 mxListenerProxy
->paused();
1411 TOOLS_WARN_EXCEPTION( "sd", "sd::SlideshowImpl::pause()" );
1415 void SAL_CALL
SlideshowImpl::resume()
1417 SolarMutexGuard aSolarGuard
;
1419 if( mbIsPaused
) try
1421 if( mpShowWindow
->GetShowWindowMode() == SHOWWINDOWMODE_BLANK
|| mpShowWindow
->GetShowWindowMode() == SHOWWINDOWMODE_END
)
1423 mpShowWindow
->RestartShow();
1430 mxShow
->pause(false);
1433 if( mxListenerProxy
.is() )
1434 mxListenerProxy
->resumed();
1440 TOOLS_WARN_EXCEPTION( "sd", "sd::SlideshowImpl::resume()" );
1442 #ifdef ENABLE_SDREMOTE
1443 RemoteServer::presentationStarted( this );
1447 sal_Bool SAL_CALL
SlideshowImpl::isPaused()
1449 SolarMutexGuard aSolarGuard
;
1453 void SAL_CALL
SlideshowImpl::blankScreen( sal_Int32 nColor
)
1455 SolarMutexGuard aSolarGuard
;
1457 if( mpShowWindow
&& mpSlideController
)
1459 if( mpShowWindow
->SetBlankMode( mpSlideController
->getCurrentSlideIndex(), Color(ColorTransparency
, nColor
) ) )
1466 // XShapeEventListener
1468 void SlideshowImpl::click( const Reference
< XShape
>& xShape
)
1470 SolarMutexGuard aSolarGuard
;
1472 WrappedShapeEventImplPtr pEvent
= maShapeEventMap
[xShape
];
1476 switch( pEvent
->meClickAction
)
1478 case ClickAction_PREVPAGE
: gotoPreviousSlide(); break;
1479 case ClickAction_NEXTPAGE
: gotoNextSlide(); break;
1480 case ClickAction_FIRSTPAGE
: gotoFirstSlide(); break;
1481 case ClickAction_LASTPAGE
: gotoLastSlide(); break;
1482 case ClickAction_STOPPRESENTATION
: endPresentation(); break;
1483 case ClickAction_BOOKMARK
:
1485 gotoBookmark( pEvent
->maStrBookmark
);
1488 case ClickAction_SOUND
:
1490 #if HAVE_FEATURE_AVMEDIA
1493 mxPlayer
.set(avmedia::MediaWindow::createPlayer(pEvent
->maStrBookmark
, ""/*TODO?*/), uno::UNO_SET_THROW
);
1496 catch( uno::Exception
& )
1498 TOOLS_WARN_EXCEPTION( "sd", "sd::SlideshowImpl::click()" );
1504 case ClickAction_DOCUMENT
:
1506 OUString
aBookmark( pEvent
->maStrBookmark
);
1508 sal_Int32 nPos
= aBookmark
.indexOf( '#' );
1511 OUString
aURL( aBookmark
.copy( 0, nPos
+1 ) );
1512 OUString
aName( aBookmark
.copy( nPos
+1 ) );
1513 aURL
+= getUiNameFromPageApiNameImpl( aName
);
1517 mpDocSh
->OpenBookmark( aBookmark
);
1521 case ClickAction_PROGRAM
:
1524 ::URIHelper::SmartRel2Abs(
1525 INetURLObject(mpDocSh
->GetMedium()->GetBaseURL()),
1526 pEvent
->maStrBookmark
, ::URIHelper::GetMaybeFileHdl(), true,
1527 false, INetURLObject::EncodeMechanism::WasEncoded
,
1528 INetURLObject::DecodeMechanism::Unambiguous
) );
1530 if( INetProtocol::File
== aURL
.GetProtocol() )
1532 SfxStringItem
aUrl( SID_FILE_NAME
, aURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
) );
1533 SfxBoolItem
aBrowsing( SID_BROWSE
, true );
1535 if (SfxViewFrame
* pViewFrm
= SfxViewFrame::Current())
1537 SfxUnoFrameItem
aDocFrame(SID_FILLFRAME
, pViewFrm
->GetFrame().GetFrameInterface());
1538 pViewFrm
->GetDispatcher()->ExecuteList( SID_OPENDOC
,
1539 SfxCallMode::ASYNCHRON
| SfxCallMode::RECORD
,
1540 { &aUrl
, &aBrowsing
}, { &aDocFrame
} );
1546 #if HAVE_FEATURE_SCRIPTING
1547 case presentation::ClickAction_MACRO
:
1549 const OUString
aMacro( pEvent
->maStrBookmark
);
1551 if ( SfxApplication::IsXScriptURL( aMacro
) )
1554 Sequence
< sal_Int16
> aOutArgsIndex
;
1555 Sequence
< Any
> aOutArgs
;
1556 Sequence
< Any
>* pInArgs
= new Sequence
< Any
>(0);
1557 mpDocSh
->CallXScript( aMacro
, *pInArgs
, aRet
, aOutArgsIndex
, aOutArgs
);
1561 // aMacro has the following syntax:
1562 // "Macroname.Modulname.Libname.Documentname" or
1563 // "Macroname.Modulname.Libname.Applicationname"
1564 sal_Int32 nIdx
{ 0 };
1565 const std::u16string_view aMacroName
= o3tl::getToken(aMacro
, 0, '.', nIdx
);
1566 const std::u16string_view aModulName
= o3tl::getToken(aMacro
, 0, '.', nIdx
);
1568 // todo: is the limitation still given that only
1569 // Modulname+Macroname can be used here?
1570 OUString aExecMacro
= OUString::Concat(aModulName
) + "." + aMacroName
;
1571 mpDocSh
->GetBasic()->Call(aExecMacro
);
1577 case ClickAction_VERB
:
1579 // todo, better do it async?
1580 SdrObject
* pObj
= SdrObject::getSdrObjectFromXShape(xShape
);
1581 SdrOle2Obj
* pOleObject
= dynamic_cast< SdrOle2Obj
* >(pObj
);
1582 if (pOleObject
&& mpViewShell
)
1583 mpViewShell
->ActivateObject(pOleObject
, pEvent
->mnVerb
);
1591 sal_Int32
SlideshowImpl::getSlideNumberForBookmark( const OUString
& rStrBookmark
)
1594 OUString aBookmark
= getUiNameFromPageApiNameImpl( rStrBookmark
);
1595 sal_uInt16 nPgNum
= mpDoc
->GetPageByName( aBookmark
, bIsMasterPage
);
1597 if( nPgNum
== SDRPAGE_NOTFOUND
)
1599 // Is the bookmark an object?
1600 SdrObject
* pObj
= mpDoc
->GetObj( aBookmark
);
1604 nPgNum
= pObj
->getSdrPageFromSdrObject()->GetPageNum();
1605 bIsMasterPage
= pObj
->getSdrPageFromSdrObject()->IsMasterPage();
1609 if( (nPgNum
== SDRPAGE_NOTFOUND
) || bIsMasterPage
|| static_cast<SdPage
*>(mpDoc
->GetPage(nPgNum
))->GetPageKind() != PageKind::Standard
)
1612 return ( nPgNum
- 1) >> 1;
1615 void SlideshowImpl::contextMenuShow(const css::awt::Point
& point
)
1617 maPopupMousePos
= { point
.X
, point
.Y
};
1618 mnContextMenuEvent
= Application::PostUserEvent(LINK(this, SlideshowImpl
, ContextMenuHdl
));
1621 void SlideshowImpl::hyperLinkClicked( OUString
const& aHyperLink
)
1623 OUString
aBookmark( aHyperLink
);
1625 sal_Int32 nPos
= aBookmark
.indexOf( '#' );
1628 OUString
aURL( aBookmark
.copy( 0, nPos
+1 ) );
1629 OUString
aName( aBookmark
.copy( nPos
+1 ) );
1630 aURL
+= getUiNameFromPageApiNameImpl( aName
);
1634 mpDocSh
->OpenBookmark( aBookmark
);
1637 void SlideshowImpl::displaySlideNumber( sal_Int32 nSlideNumber
)
1639 if( mpSlideController
)
1641 if( mpSlideController
->jumpToSlideNumber( nSlideNumber
) )
1643 displayCurrentSlide();
1648 /** nSlideIndex == -1 displays current slide again */
1649 void SlideshowImpl::displaySlideIndex( sal_Int32 nSlideIndex
)
1651 if( mpSlideController
)
1653 if( (nSlideIndex
== -1) || mpSlideController
->jumpToSlideIndex( nSlideIndex
) )
1655 displayCurrentSlide();
1660 void SlideshowImpl::jumpToBookmark( const OUString
& sBookmark
)
1662 sal_Int32 nSlideNumber
= getSlideNumberForBookmark( sBookmark
);
1663 if( nSlideNumber
!= -1 )
1664 displaySlideNumber( nSlideNumber
);
1667 sal_Int32
SlideshowImpl::getCurrentSlideNumber() const
1669 return mpSlideController
? mpSlideController
->getCurrentSlideNumber() : -1;
1672 sal_Bool SAL_CALL
SlideshowImpl::isEndless()
1674 SolarMutexGuard aSolarGuard
;
1675 return maPresSettings
.mbEndless
;
1678 void SlideshowImpl::update()
1683 void SlideshowImpl::startUpdateTimer()
1685 SolarMutexGuard aSolarGuard
;
1686 maUpdateTimer
.SetTimeout( 0 );
1687 maUpdateTimer
.Start();
1690 /** this timer is called 20ms after a new slide was displayed.
1691 This is used to unfreeze user input that was disabled after
1692 slide change to skip input that was buffered during slide
1693 transition preparation */
1694 IMPL_LINK_NOARG(SlideshowImpl
, ReadyForNextInputHdl
, Timer
*, void)
1696 mbInputFreeze
= false;
1699 /** if I catch someone someday who calls this method by hand
1700 and not by using the timer, I will personally punish this
1701 person seriously, even if this person is me.
1703 IMPL_LINK_NOARG(SlideshowImpl
, updateHdl
, Timer
*, void)
1708 void SlideshowImpl::updateSlideShow()
1710 // prevent me from deletion when recursing (App::EnableYieldMode does)
1711 const rtl::Reference
<SlideshowImpl
> xKeepAlive(this);
1713 Reference
< XSlideShow
> xShow( mxShow
);
1719 double fUpdate
= 0.0;
1720 if( !xShow
->update(fUpdate
) )
1723 if (mxShow
.is() && (fUpdate
>= 0.0))
1725 if (::basegfx::fTools::equalZero(fUpdate
))
1727 // Make sure idle tasks don't starve when we don't have to wait.
1728 // Don't process any events generated after invoking the function.
1729 Application::Reschedule(/*bHandleAllCurrentEvents=*/true);
1733 // Avoid busy loop when the previous call to update()
1734 // returns a small positive number but not 0 (which is
1735 // handled above). Also, make sure that calls to update()
1736 // have a minimum frequency.
1737 // => Allow up to 60 frames per second. Call at least once
1739 const static sal_Int32
nMaximumFrameCount (60);
1740 const static double nMinimumTimeout (1.0 / nMaximumFrameCount
);
1741 const static double nMaximumTimeout (4.0);
1742 fUpdate
= std::clamp(fUpdate
, nMinimumTimeout
, nMaximumTimeout
);
1744 // Make sure that the maximum frame count has not been set
1745 // too high (only then conversion to milliseconds and long
1746 // integer may lead to zero value.)
1747 OSL_ASSERT(static_cast<sal_uLong
>(fUpdate
* 1000.0) > 0);
1750 // Use our high resolution timers for the asynchronous callback.
1751 maUpdateTimer
.SetTimeout(static_cast<sal_uLong
>(fUpdate
* 1000.0));
1752 maUpdateTimer
.Start();
1757 TOOLS_WARN_EXCEPTION( "sd", "sd::SlideshowImpl::updateSlideShow()" );
1761 bool SlideshowImpl::keyInput(const KeyEvent
& rKEvt
)
1763 if( !mxShow
.is() || mbInputFreeze
)
1770 const int nKeyCode
= rKEvt
.GetKeyCode().GetCode();
1773 case awt::Key::CONTEXTMENU
:
1774 if( !mnContextMenuEvent
)
1777 maPopupMousePos
= mpShowWindow
->GetPointerState().maPos
;
1778 mnContextMenuEvent
= Application::PostUserEvent( LINK( this, SlideshowImpl
, ContextMenuHdl
) );
1785 // in case the user cancels the presentation, switch to current slide
1787 if( mpSlideController
&& (ANIMATIONMODE_SHOW
== meAnimationMode
) )
1789 if( mpSlideController
->getCurrentSlideNumber() != -1 )
1790 mnRestoreSlide
= mpSlideController
->getCurrentSlideNumber();
1797 if(rKEvt
.GetKeyCode().IsMod2())
1811 if( !maCharBuffer
.isEmpty() )
1813 if( mpSlideController
)
1815 if( mpSlideController
->jumpToSlideNumber( maCharBuffer
.toInt32() - 1 ) )
1816 displayCurrentSlide();
1818 maCharBuffer
.clear();
1827 // numeric: add to buffer
1838 maCharBuffer
+= OUStringChar( rKEvt
.GetCharCode() );
1842 if(rKEvt
.GetKeyCode().IsMod2())
1844 gotoPreviousSlide();
1851 gotoPreviousEffect();
1855 setUsePen( !mbUsePen
);
1858 // tdf#149351 Ctrl+A disables pointer as pen mode
1860 if(rKEvt
.GetKeyCode().IsMod1())
1868 setEraseAllInk( true );
1885 blankScreen( ((nKeyCode
== KEY_W
) || (nKeyCode
== KEY_COMMA
)) ? 0x00ffffff : 0x00000000 );
1897 TOOLS_WARN_EXCEPTION( "sd", "sd::SlideshowImpl::keyInput()" );
1903 IMPL_LINK( SlideshowImpl
, EventListenerHdl
, VclSimpleEvent
&, rSimpleEvent
, void )
1905 if( !mxShow
.is() || mbInputFreeze
)
1908 if( !((rSimpleEvent
.GetId() == VclEventId::WindowCommand
) && static_cast<VclWindowEvent
*>(&rSimpleEvent
)->GetData()) )
1911 const CommandEvent
& rEvent
= *static_cast<const CommandEvent
*>(static_cast<VclWindowEvent
*>(&rSimpleEvent
)->GetData());
1913 if( rEvent
.GetCommand() != CommandEventId::Media
)
1916 CommandMediaData
* pMediaData
= rEvent
.GetMediaData();
1917 pMediaData
->SetPassThroughToOS(false);
1918 switch (pMediaData
->GetMediaId())
1920 #if defined( MACOSX )
1921 case MediaCommand::Menu
:
1922 if( !mnContextMenuEvent
)
1925 maPopupMousePos
= mpShowWindow
->GetPointerState().maPos
;
1926 mnContextMenuEvent
= Application::PostUserEvent( LINK( this, SlideshowImpl
, ContextMenuHdl
) );
1929 case MediaCommand::VolumeDown
:
1930 gotoPreviousSlide();
1932 case MediaCommand::VolumeUp
:
1936 case MediaCommand::NextTrack
:
1939 case MediaCommand::Pause
:
1943 case MediaCommand::Play
:
1948 case MediaCommand::PlayPause
:
1954 case MediaCommand::PreviousTrack
:
1955 gotoPreviousSlide();
1957 case MediaCommand::NextTrackHold
:
1961 case MediaCommand::Rewind
:
1964 case MediaCommand::Stop
:
1965 // in case the user cancels the presentation, switch to current slide
1967 if( mpSlideController
&& (ANIMATIONMODE_SHOW
== meAnimationMode
) )
1969 if( mpSlideController
->getCurrentSlideNumber() != -1 )
1970 mnRestoreSlide
= mpSlideController
->getCurrentSlideNumber();
1975 pMediaData
->SetPassThroughToOS(true);
1980 void SlideshowImpl::mouseButtonUp(const MouseEvent
& rMEvt
)
1982 if( rMEvt
.IsRight() && !mnContextMenuEvent
)
1984 maPopupMousePos
= rMEvt
.GetPosPixel();
1985 mnContextMenuEvent
= Application::PostUserEvent( LINK( this, SlideshowImpl
, ContextMenuHdl
) );
1989 IMPL_LINK_NOARG(SlideshowImpl
, ContextMenuHdl
, void*, void)
1991 mnContextMenuEvent
= nullptr;
1993 if (mpSlideController
== nullptr)
1996 mbWasPaused
= mbIsPaused
;
2000 std::unique_ptr
<weld::Builder
> xBuilder(Application::CreateBuilder(nullptr, "modules/simpress/ui/slidecontextmenu.ui"));
2001 std::unique_ptr
<weld::Menu
> xMenu(xBuilder
->weld_menu("menu"));
2002 OUString
sNextImage(BMP_MENU_NEXT
), sPrevImage(BMP_MENU_PREV
);
2003 xMenu
->insert(0, "next", SdResId(RID_SVXSTR_MENU_NEXT
), &sNextImage
, nullptr, nullptr, TRISTATE_INDET
);
2004 xMenu
->insert(1, "prev", SdResId(RID_SVXSTR_MENU_PREV
), &sPrevImage
, nullptr, nullptr, TRISTATE_INDET
);
2006 // Adding button to display if in Pen mode
2007 xMenu
->set_active("pen", mbUsePen
);
2009 const ShowWindowMode eMode
= mpShowWindow
->GetShowWindowMode();
2010 xMenu
->set_visible("next", mpSlideController
->getNextSlideIndex() != -1);
2011 xMenu
->set_visible("prev", (mpSlideController
->getPreviousSlideIndex() != -1 ) || (eMode
== SHOWWINDOWMODE_END
) || (eMode
== SHOWWINDOWMODE_PAUSE
) || (eMode
== SHOWWINDOWMODE_BLANK
));
2012 xMenu
->set_visible("edit", mpViewShell
->GetDoc()->IsStartWithPresentation());
2014 std::unique_ptr
<weld::Menu
> xPageMenu(xBuilder
->weld_menu("gotomenu"));
2015 OUString
sFirstImage(BMP_MENU_FIRST
), sLastImage(BMP_MENU_LAST
);
2016 xPageMenu
->insert(0, "first", SdResId(RID_SVXSTR_MENU_FIRST
), &sFirstImage
, nullptr, nullptr, TRISTATE_INDET
);
2017 xPageMenu
->insert(1, "last", SdResId(RID_SVXSTR_MENU_LAST
), &sLastImage
, nullptr, nullptr, TRISTATE_INDET
);
2019 // populate slide goto list
2020 const sal_Int32 nPageNumberCount
= mpSlideController
->getSlideNumberCount();
2021 if( nPageNumberCount
<= 1 )
2023 xMenu
->set_visible("goto", false);
2027 sal_Int32 nCurrentSlideNumber
= mpSlideController
->getCurrentSlideNumber();
2028 if( (eMode
== SHOWWINDOWMODE_END
) || (eMode
== SHOWWINDOWMODE_PAUSE
) || (eMode
== SHOWWINDOWMODE_BLANK
) )
2029 nCurrentSlideNumber
= -1;
2031 xPageMenu
->set_visible("first", mpSlideController
->getSlideNumber(0) != nCurrentSlideNumber
);
2032 xPageMenu
->set_visible("last", mpSlideController
->getSlideNumber(mpSlideController
->getSlideIndexCount() - 1) != nCurrentSlideNumber
);
2034 sal_Int32 nPageNumber
;
2036 for( nPageNumber
= 0; nPageNumber
< nPageNumberCount
; nPageNumber
++ )
2038 if( mpSlideController
->isVisibleSlideNumber( nPageNumber
) )
2040 SdPage
* pPage
= mpDoc
->GetSdPage(static_cast<sal_uInt16
>(nPageNumber
), PageKind::Standard
);
2043 OUString
sId(OUString::number(CM_SLIDES
+ nPageNumber
));
2044 xPageMenu
->append_check(sId
, pPage
->GetName());
2045 if (nPageNumber
== nCurrentSlideNumber
)
2046 xPageMenu
->set_active(sId
, true);
2052 std::unique_ptr
<weld::Menu
> xBlankMenu(xBuilder
->weld_menu("screenmenu"));
2054 if (mpShowWindow
->GetShowWindowMode() == SHOWWINDOWMODE_BLANK
)
2056 xBlankMenu
->set_active((mpShowWindow
->GetBlankColor() == COL_WHITE
) ? "white" : "black", true);
2059 std::unique_ptr
<weld::Menu
> xWidthMenu(xBuilder
->weld_menu("widthmenu"));
2061 // populate color width list
2062 sal_Int32 nIterator
;
2066 for( nIterator
= 1; nIterator
< 6; nIterator
++)
2089 if (nWidth
== mdUserPaintStrokeWidth
)
2090 xWidthMenu
->set_active(OUString::number(nWidth
), true);
2093 ::tools::Rectangle
aRect(maPopupMousePos
, Size(1,1));
2094 weld::Window
* pParent
= weld::GetPopupParent(*mpShowWindow
, aRect
);
2095 ContextMenuSelectHdl(xMenu
->popup_at_rect(pParent
, aRect
));
2098 mxView
->ignoreNextMouseReleased();
2104 void SlideshowImpl::ContextMenuSelectHdl(std::u16string_view rMenuId
)
2106 if (rMenuId
== u
"prev")
2108 gotoPreviousSlide();
2109 mbWasPaused
= false;
2111 else if(rMenuId
== u
"next")
2114 mbWasPaused
= false;
2116 else if (rMenuId
== u
"first")
2119 mbWasPaused
= false;
2121 else if (rMenuId
== u
"last")
2124 mbWasPaused
= false;
2126 else if (rMenuId
== u
"black" || rMenuId
== u
"white")
2128 const Color
aBlankColor(rMenuId
== u
"white" ? COL_WHITE
: COL_BLACK
);
2131 if( mpShowWindow
->GetShowWindowMode() == SHOWWINDOWMODE_BLANK
)
2133 if( mpShowWindow
->GetBlankColor() == aBlankColor
)
2135 mbWasPaused
= false;
2136 mpShowWindow
->RestartShow();
2140 mpShowWindow
->RestartShow();
2142 if( mpShowWindow
->SetBlankMode( mpSlideController
->getCurrentSlideIndex(), aBlankColor
) )
2148 else if (rMenuId
== u
"color")
2150 //Open a color picker based on SvColorDialog
2151 ::Color
aColor( ColorTransparency
, mnUserPaintColor
);
2152 SvColorDialog aColorDlg
;
2153 aColorDlg
.SetColor( aColor
);
2155 if (aColorDlg
.Execute(mpShowWindow
->GetFrameWeld()))
2157 aColor
= aColorDlg
.GetColor();
2158 setPenColor(sal_Int32(aColor
));
2160 mbWasPaused
= false;
2162 else if (rMenuId
== u
"4")
2165 mbWasPaused
= false;
2167 else if (rMenuId
== u
"100")
2170 mbWasPaused
= false;
2172 else if (rMenuId
== u
"150")
2175 mbWasPaused
= false;
2177 else if (rMenuId
== u
"200")
2180 mbWasPaused
= false;
2182 else if (rMenuId
== u
"400")
2185 mbWasPaused
= false;
2187 else if (rMenuId
== u
"erase")
2189 setEraseAllInk(true);
2190 mbWasPaused
= false;
2192 else if (rMenuId
== u
"pen")
2194 setUsePen(!mbUsePen
);
2195 mbWasPaused
= false;
2197 else if (rMenuId
== u
"edit")
2199 // When in autoplay mode (pps/ppsx), offer editing of the presentation
2200 // Turn autostart off, else Impress will close when exiting the Presentation
2201 mpViewShell
->GetDoc()->SetExitAfterPresenting(false);
2202 if( mpSlideController
&& (ANIMATIONMODE_SHOW
== meAnimationMode
) )
2204 if( mpSlideController
->getCurrentSlideNumber() != -1 )
2206 mnRestoreSlide
= mpSlideController
->getCurrentSlideNumber();
2211 else if (rMenuId
== u
"end")
2213 // in case the user cancels the presentation, switch to current slide
2215 if( mpSlideController
&& (ANIMATIONMODE_SHOW
== meAnimationMode
) )
2217 if( mpSlideController
->getCurrentSlideNumber() != -1 )
2219 mnRestoreSlide
= mpSlideController
->getCurrentSlideNumber();
2224 else if (!rMenuId
.empty())
2226 sal_Int32 nPageNumber
= o3tl::toInt32(rMenuId
) - CM_SLIDES
;
2227 const ShowWindowMode eMode
= mpShowWindow
->GetShowWindowMode();
2228 if( (eMode
== SHOWWINDOWMODE_END
) || (eMode
== SHOWWINDOWMODE_PAUSE
) || (eMode
== SHOWWINDOWMODE_BLANK
) )
2230 mpShowWindow
->RestartShow( nPageNumber
);
2232 else if( nPageNumber
!= mpSlideController
->getCurrentSlideNumber() )
2234 displaySlideNumber( nPageNumber
);
2236 mbWasPaused
= false;
2240 Reference
< XSlideShow
> SlideshowImpl::createSlideShow()
2242 Reference
< XSlideShow
> xShow
;
2246 Reference
< uno::XComponentContext
> xContext
=
2247 ::comphelper::getProcessComponentContext();
2249 xShow
.set( presentation::SlideShow::create(xContext
), UNO_SET_THROW
);
2251 catch( uno::Exception
& )
2253 TOOLS_WARN_EXCEPTION( "sd", "sd::SlideshowImpl::createSlideShow()" );
2259 void SlideshowImpl::createSlideList( bool bAll
, std::u16string_view rPresSlide
)
2261 const sal_uInt16 nSlideCount
= mpDoc
->GetSdPageCount( PageKind::Standard
);
2266 SdCustomShow
* pCustomShow
;
2268 if( mpDoc
->GetCustomShowList() && maPresSettings
.mbCustomShow
)
2269 pCustomShow
= mpDoc
->GetCustomShowList()->GetCurObject();
2271 pCustomShow
= nullptr;
2273 // create animation slide controller
2274 AnimationSlideController::Mode eMode
=
2275 ( pCustomShow
&& !pCustomShow
->PagesVector().empty() ) ? AnimationSlideController::CUSTOM
:
2276 (bAll
? AnimationSlideController::ALL
: AnimationSlideController::FROM
);
2278 Reference
< XDrawPagesSupplier
> xDrawPages( mpDoc
->getUnoModel(), UNO_QUERY_THROW
);
2279 Reference
< XIndexAccess
> xSlides( xDrawPages
->getDrawPages(), UNO_QUERY_THROW
);
2280 mpSlideController
= std::make_shared
<AnimationSlideController
>( xSlides
, eMode
);
2282 if( eMode
!= AnimationSlideController::CUSTOM
)
2284 sal_Int32 nFirstVisibleSlide
= 0;
2286 // normal presentation
2287 if( !rPresSlide
.empty() )
2290 bool bTakeNextAvailable
= false;
2292 for( nSlide
= 0, nFirstVisibleSlide
= -1;
2293 ( nSlide
< nSlideCount
) && ( -1 == nFirstVisibleSlide
); nSlide
++ )
2295 SdPage
* pTestSlide
= mpDoc
->GetSdPage( static_cast<sal_uInt16
>(nSlide
), PageKind::Standard
);
2297 if( pTestSlide
->GetName() == rPresSlide
)
2299 if( pTestSlide
->IsExcluded() )
2300 bTakeNextAvailable
= true;
2302 nFirstVisibleSlide
= nSlide
;
2304 else if( bTakeNextAvailable
&& !pTestSlide
->IsExcluded() )
2305 nFirstVisibleSlide
= nSlide
;
2308 if( -1 == nFirstVisibleSlide
)
2309 nFirstVisibleSlide
= 0;
2312 for( sal_Int32 i
= 0; i
< nSlideCount
; i
++ )
2314 bool bVisible
= ! mpDoc
->GetSdPage( static_cast<sal_uInt16
>(i
), PageKind::Standard
)->IsExcluded();
2315 if( bVisible
|| (eMode
== AnimationSlideController::ALL
) )
2316 mpSlideController
->insertSlideNumber( i
, bVisible
);
2319 mpSlideController
->setStartSlideNumber( nFirstVisibleSlide
);
2323 if( meAnimationMode
!= ANIMATIONMODE_SHOW
&& !rPresSlide
.empty() )
2326 for( nSlide
= 0; nSlide
< nSlideCount
; nSlide
++ )
2327 if( rPresSlide
== mpDoc
->GetSdPage( static_cast<sal_uInt16
>(nSlide
), PageKind::Standard
)->GetName() )
2330 if( nSlide
< nSlideCount
)
2331 mpSlideController
->insertSlideNumber( static_cast<sal_uInt16
>(nSlide
) );
2334 for( const auto& rpPage
: pCustomShow
->PagesVector() )
2336 const sal_uInt16 nSdSlide
= ( rpPage
->GetPageNum() - 1 ) / 2;
2338 if( ! mpDoc
->GetSdPage( nSdSlide
, PageKind::Standard
)->IsExcluded())
2339 mpSlideController
->insertSlideNumber( nSdSlide
);
2344 typedef sal_uInt16 (*FncGetChildWindowId
)();
2346 const FncGetChildWindowId aShowChildren
[] =
2348 &AnimationChildWindow::GetChildWindowId
,
2349 &Svx3DChildWindow::GetChildWindowId
,
2350 &SvxFontWorkChildWindow::GetChildWindowId
,
2351 &SvxColorChildWindow::GetChildWindowId
,
2352 &SvxSearchDialogWrapper::GetChildWindowId
,
2353 &SvxBmpMaskChildWindow::GetChildWindowId
,
2354 &SvxIMapDlgChildWindow::GetChildWindowId
,
2355 &SvxHlinkDlgWrapper::GetChildWindowId
,
2356 &SfxInfoBarContainerChild::GetChildWindowId
2359 void SlideshowImpl::hideChildWindows()
2363 if( ANIMATIONMODE_SHOW
!= meAnimationMode
)
2366 SfxViewFrame
* pViewFrame
= getViewFrame();
2371 for( sal_uLong i
= 0; i
< SAL_N_ELEMENTS( aShowChildren
); i
++ )
2373 const sal_uInt16 nId
= ( *aShowChildren
[ i
] )();
2375 if( pViewFrame
->GetChildWindow( nId
) )
2377 pViewFrame
->SetChildWindow( nId
, false );
2378 mnChildMask
|= ::tools::ULong(1) << i
;
2383 void SlideshowImpl::showChildWindows()
2385 if( ANIMATIONMODE_SHOW
== meAnimationMode
)
2387 SfxViewFrame
* pViewFrame
= getViewFrame();
2390 for( sal_uLong i
= 0; i
< SAL_N_ELEMENTS(aShowChildren
); i
++ )
2392 if( mnChildMask
& ( ::tools::ULong(1) << i
) )
2393 pViewFrame
->SetChildWindow( ( *aShowChildren
[ i
] )(), true );
2399 SfxViewFrame
* SlideshowImpl::getViewFrame() const
2401 return mpViewShell
? mpViewShell
->GetViewFrame() : nullptr;
2404 SfxDispatcher
* SlideshowImpl::getDispatcher() const
2406 return (mpViewShell
&& mpViewShell
->GetViewFrame()) ? mpViewShell
->GetViewFrame()->GetDispatcher() : nullptr;
2409 SfxBindings
* SlideshowImpl::getBindings() const
2411 return (mpViewShell
&& mpViewShell
->GetViewFrame()) ? &mpViewShell
->GetViewFrame()->GetBindings() : nullptr;
2414 void SlideshowImpl::resize( const Size
& rSize
)
2420 mpShowWindow
->SetSizePixel( maPresSize
);
2421 mpShowWindow
->Show();
2424 if( mxView
.is() ) try
2426 awt::WindowEvent aEvt
;
2427 mxView
->windowResized(aEvt
);
2431 TOOLS_WARN_EXCEPTION( "sd", "sd::SlideshowImpl::resize()" );
2435 void SlideshowImpl::setActiveXToolbarsVisible( bool bVisible
)
2437 // in case of ActiveX control the toolbars should not be visible if slide show runs in window mode
2438 // actually it runs always in window mode in case of ActiveX control
2439 if ( !(!maPresSettings
.mbFullScreen
&& mpDocSh
&& mpDocSh
->GetMedium()) )
2442 const SfxBoolItem
* pItem
= SfxItemSet::GetItem
<SfxBoolItem
>(mpDocSh
->GetMedium()->GetItemSet(), SID_VIEWONLY
, false);
2443 if ( !(pItem
&& pItem
->GetValue()) )
2446 // this is a plugin/activex mode, no toolbars should be visible during slide show
2447 // after the end of slide show they should be visible again
2448 SfxViewFrame
* pViewFrame
= getViewFrame();
2454 Reference
< frame::XLayoutManager
> xLayoutManager
;
2455 Reference
< beans::XPropertySet
> xFrameProps( pViewFrame
->GetFrame().GetFrameInterface(), UNO_QUERY_THROW
);
2456 if ( ( xFrameProps
->getPropertyValue( "LayoutManager" )
2457 >>= xLayoutManager
)
2458 && xLayoutManager
.is() )
2460 xLayoutManager
->setVisible( bVisible
);
2463 catch( uno::Exception
& )
2467 void SAL_CALL
SlideshowImpl::activate()
2469 SolarMutexGuard aSolarGuard
;
2471 maDeactivateTimer
.Stop();
2473 if( mbActive
|| !mxShow
.is() )
2478 if( ANIMATIONMODE_SHOW
== meAnimationMode
)
2480 if( mbAutoSaveWasOn
)
2481 setAutoSaveState( false );
2485 SfxViewFrame
* pViewFrame
= getViewFrame();
2486 SfxDispatcher
* pDispatcher
= pViewFrame
? pViewFrame
->GetDispatcher() : nullptr;
2492 // filter all forbidden slots
2493 pDispatcher
->SetSlotFilter( SfxSlotFilterState::ENABLED
, pAllowed
);
2497 getBindings()->InvalidateAll(true);
2499 mpShowWindow
->GrabFocus();
2506 void SAL_CALL
SlideshowImpl::deactivate()
2508 SolarMutexGuard aSolarGuard
;
2510 if( mbActive
&& mxShow
.is() )
2512 maDeactivateTimer
.Start();
2516 IMPL_LINK_NOARG(SlideshowImpl
, deactivateHdl
, Timer
*, void)
2518 if( !(mbActive
&& mxShow
.is()) )
2525 if( ANIMATIONMODE_SHOW
== meAnimationMode
)
2527 if( mbAutoSaveWasOn
)
2528 setAutoSaveState( true );
2537 sal_Bool SAL_CALL
SlideshowImpl::isActive()
2539 SolarMutexGuard aSolarGuard
;
2543 void SlideshowImpl::setAutoSaveState( bool bOn
)
2547 uno::Reference
<uno::XComponentContext
> xContext( ::comphelper::getProcessComponentContext() );
2549 uno::Reference
< util::XURLTransformer
> xParser(util::URLTransformer::create(xContext
));
2551 aURL
.Complete
= "vnd.sun.star.autorecovery:/setAutoSaveState";
2552 xParser
->parseStrict(aURL
);
2554 Sequence
< beans::PropertyValue
> aArgs
{ comphelper::makePropertyValue("AutoSaveState", bOn
) };
2556 uno::Reference
< frame::XDispatch
> xAutoSave
= frame::theAutoRecovery::get(xContext
);
2557 xAutoSave
->dispatch(aURL
, aArgs
);
2561 TOOLS_WARN_EXCEPTION( "sd", "sd::SlideshowImpl::setAutoSaveState()");
2565 Reference
< XDrawPage
> SAL_CALL
SlideshowImpl::getCurrentSlide()
2567 SolarMutexGuard aSolarGuard
;
2569 Reference
< XDrawPage
> xSlide
;
2570 if( mxShow
.is() && mpSlideController
)
2572 sal_Int32 nSlide
= getCurrentSlideNumber();
2573 if( (nSlide
>= 0) && (nSlide
< mpSlideController
->getSlideNumberCount() ) )
2574 xSlide
= mpSlideController
->getSlideByNumber( nSlide
);
2580 sal_Int32 SAL_CALL
SlideshowImpl::getNextSlideIndex()
2582 SolarMutexGuard aSolarGuard
;
2586 return mpSlideController
->getNextSlideIndex();
2594 sal_Int32 SAL_CALL
SlideshowImpl::getCurrentSlideIndex()
2596 return mpSlideController
? mpSlideController
->getCurrentSlideIndex() : -1;
2599 // css::presentation::XSlideShowController:
2601 ::sal_Int32 SAL_CALL
SlideshowImpl::getSlideCount()
2603 return mpSlideController
? mpSlideController
->getSlideIndexCount() : 0;
2606 Reference
< XDrawPage
> SAL_CALL
SlideshowImpl::getSlideByIndex(::sal_Int32 Index
)
2608 if ((mpSlideController
== nullptr) || (Index
< 0)
2609 || (Index
>= mpSlideController
->getSlideIndexCount()))
2610 throw IndexOutOfBoundsException();
2612 return mpSlideController
->getSlideByNumber( mpSlideController
->getSlideNumber( Index
) );
2615 sal_Bool SAL_CALL
SlideshowImpl::getAlwaysOnTop()
2617 SolarMutexGuard aSolarGuard
;
2618 return maPresSettings
.mbAlwaysOnTop
;
2621 void SAL_CALL
SlideshowImpl::setAlwaysOnTop( sal_Bool bAlways
)
2623 SolarMutexGuard aSolarGuard
;
2624 if( maPresSettings
.mbAlwaysOnTop
!= bool(bAlways
) )
2626 maPresSettings
.mbAlwaysOnTop
= bAlways
;
2627 // todo, can this be changed while running?
2631 sal_Bool SAL_CALL
SlideshowImpl::isFullScreen()
2633 SolarMutexGuard aSolarGuard
;
2634 return maPresSettings
.mbFullScreen
;
2637 sal_Bool SAL_CALL
SlideshowImpl::getMouseVisible()
2639 SolarMutexGuard aSolarGuard
;
2640 return maPresSettings
.mbMouseVisible
;
2643 void SAL_CALL
SlideshowImpl::setMouseVisible( sal_Bool bVisible
)
2645 SolarMutexGuard aSolarGuard
;
2646 if( maPresSettings
.mbMouseVisible
!= bool(bVisible
) )
2648 maPresSettings
.mbMouseVisible
= bVisible
;
2650 mpShowWindow
->SetMouseAutoHide( !maPresSettings
.mbMouseVisible
);
2654 sal_Bool SAL_CALL
SlideshowImpl::getUsePen()
2656 SolarMutexGuard aSolarGuard
;
2660 void SAL_CALL
SlideshowImpl::setUsePen( sal_Bool bMouseAsPen
)
2662 SolarMutexGuard aSolarGuard
;
2663 mbUsePen
= bMouseAsPen
;
2672 aValue
<<= mnUserPaintColor
;
2673 beans::PropertyValue aPenProp
;
2674 aPenProp
.Name
= "UserPaintColor";
2675 aPenProp
.Value
= aValue
;
2676 mxShow
->setProperty( aPenProp
);
2681 beans::PropertyValue aPenPropWidth
;
2682 aPenPropWidth
.Name
= "UserPaintStrokeWidth";
2683 aPenPropWidth
.Value
<<= mdUserPaintStrokeWidth
;
2684 mxShow
->setProperty( aPenPropWidth
);
2687 beans::PropertyValue aPenPropSwitchPenMode
;
2688 aPenPropSwitchPenMode
.Name
= "SwitchPenMode";
2689 aPenPropSwitchPenMode
.Value
<<= true;
2690 mxShow
->setProperty( aPenPropSwitchPenMode
);
2695 TOOLS_WARN_EXCEPTION( "sd", "sd::SlideshowImpl::setUsePen()" );
2699 double SAL_CALL
SlideshowImpl::getPenWidth()
2701 SolarMutexGuard aSolarGuard
;
2702 return mdUserPaintStrokeWidth
;
2705 void SAL_CALL
SlideshowImpl::setPenWidth( double dStrokeWidth
)
2707 SolarMutexGuard aSolarGuard
;
2708 mdUserPaintStrokeWidth
= dStrokeWidth
;
2709 setUsePen( true ); // enable pen mode, update color and width
2712 sal_Int32 SAL_CALL
SlideshowImpl::getPenColor()
2714 SolarMutexGuard aSolarGuard
;
2715 return mnUserPaintColor
;
2718 void SAL_CALL
SlideshowImpl::setPenColor( sal_Int32 nColor
)
2720 SolarMutexGuard aSolarGuard
;
2721 mnUserPaintColor
= nColor
;
2722 setUsePen( true ); // enable pen mode, update color
2725 void SAL_CALL
SlideshowImpl::setEraseAllInk(sal_Bool bEraseAllInk
)
2730 SolarMutexGuard aSolarGuard
;
2736 beans::PropertyValue aPenPropEraseAllInk
;
2737 aPenPropEraseAllInk
.Name
= "EraseAllInk";
2738 aPenPropEraseAllInk
.Value
<<= bEraseAllInk
;
2739 mxShow
->setProperty( aPenPropEraseAllInk
);
2743 TOOLS_WARN_EXCEPTION( "sd.slideshow", "sd::SlideshowImpl::setEraseAllInk()" );
2747 // XSlideShowController Methods
2748 sal_Bool SAL_CALL
SlideshowImpl::isRunning( )
2750 SolarMutexGuard aSolarGuard
;
2754 void SAL_CALL
SlideshowImpl::gotoNextEffect( )
2756 SolarMutexGuard aSolarGuard
;
2758 if( !(mxShow
.is() && mpSlideController
&& mpShowWindow
) )
2764 const ShowWindowMode eMode
= mpShowWindow
->GetShowWindowMode();
2765 if( eMode
== SHOWWINDOWMODE_END
)
2769 else if( (eMode
== SHOWWINDOWMODE_PAUSE
) || (eMode
== SHOWWINDOWMODE_BLANK
) )
2771 mpShowWindow
->RestartShow();
2775 mxShow
->nextEffect();
2780 void SAL_CALL
SlideshowImpl::gotoPreviousEffect( )
2782 SolarMutexGuard aSolarGuard
;
2784 if( !(mxShow
.is() && mpSlideController
&& mpShowWindow
) )
2790 const ShowWindowMode eMode
= mpShowWindow
->GetShowWindowMode();
2791 if( (eMode
== SHOWWINDOWMODE_PAUSE
) || (eMode
== SHOWWINDOWMODE_BLANK
) )
2793 mpShowWindow
->RestartShow();
2797 mxShow
->previousEffect();
2802 void SAL_CALL
SlideshowImpl::gotoFirstSlide( )
2804 SolarMutexGuard aSolarGuard
;
2806 if( !(mpShowWindow
&& mpSlideController
) )
2812 if( mpShowWindow
->GetShowWindowMode() == SHOWWINDOWMODE_END
)
2814 if( mpSlideController
->getSlideIndexCount() )
2815 mpShowWindow
->RestartShow( 0);
2819 displaySlideIndex( 0 );
2823 void SAL_CALL
SlideshowImpl::gotoNextSlide( )
2825 SolarMutexGuard aSolarGuard
;
2830 const ShowWindowMode eMode
= mpShowWindow
->GetShowWindowMode();
2831 if( (eMode
== SHOWWINDOWMODE_PAUSE
) || (eMode
== SHOWWINDOWMODE_BLANK
) )
2833 mpShowWindow
->RestartShow();
2837 // if this is a show, ignore user inputs and
2838 // start 20ms timer to reenable inputs to filter
2839 // buffered inputs during slide transition
2840 if( meAnimationMode
== ANIMATIONMODE_SHOW
)
2842 mbInputFreeze
= true;
2843 maInputFreezeTimer
.Start();
2846 if( mpSlideController
)
2848 if( mpSlideController
->nextSlide() )
2850 displayCurrentSlide();
2856 if( meAnimationMode
== ANIMATIONMODE_PREVIEW
)
2860 else if( maPresSettings
.mbEndless
)
2862 if( maPresSettings
.mnPauseTimeout
)
2866 if ( maPresSettings
.mbShowPauseLogo
)
2868 Graphic
aGraphic(SfxApplication::GetApplicationLogo(360));
2869 mpShowWindow
->SetPauseMode( maPresSettings
.mnPauseTimeout
, &aGraphic
);
2872 mpShowWindow
->SetPauseMode( maPresSettings
.mnPauseTimeout
);
2877 displaySlideIndex( 0 );
2884 mpShowWindow
->SetEndMode();
2885 if( !mpViewShell
->GetDoc()->IsStartWithPresentation() )
2894 void SAL_CALL
SlideshowImpl::gotoPreviousSlide( )
2896 gotoPreviousSlide(false);
2899 void SlideshowImpl::gotoPreviousSlide (const bool bSkipAllMainSequenceEffects
)
2901 SolarMutexGuard aSolarGuard
;
2903 if( !(mxShow
.is() && mpSlideController
) )
2911 const ShowWindowMode eMode
= mpShowWindow
->GetShowWindowMode();
2912 if( eMode
== SHOWWINDOWMODE_END
)
2914 mpShowWindow
->RestartShow( mpSlideController
->getCurrentSlideIndex() );
2916 else if( (eMode
== SHOWWINDOWMODE_PAUSE
) || (eMode
== SHOWWINDOWMODE_BLANK
) )
2918 mpShowWindow
->RestartShow();
2922 if( mpSlideController
->previousSlide())
2923 displayCurrentSlide(bSkipAllMainSequenceEffects
);
2924 else if (bSkipAllMainSequenceEffects
)
2926 // We could not go to the previous slide (probably because
2927 // the current slide is already the first one). We still
2928 // have to call displayCurrentSlide because the calling
2929 // slideshow can not determine whether there is a previous
2930 // slide or not and has already prepared for a slide change.
2931 // This slide change has to be completed now, even when
2932 // changing to the same slide.
2933 // Note that in this special case we do NOT pass
2934 // bSkipAllMainSequenceEffects because we display the same
2935 // slide as before and do not want to show all its effects.
2936 displayCurrentSlide();
2942 TOOLS_WARN_EXCEPTION( "sd", "sd::SlideshowImpl::gotoPreviousSlide()" );
2946 void SAL_CALL
SlideshowImpl::gotoLastSlide()
2948 SolarMutexGuard aSolarGuard
;
2950 if( !mpSlideController
)
2956 const sal_Int32 nLastSlideIndex
= mpSlideController
->getSlideIndexCount() - 1;
2957 if( nLastSlideIndex
>= 0 )
2959 if( mpShowWindow
->GetShowWindowMode() == SHOWWINDOWMODE_END
)
2961 mpShowWindow
->RestartShow( nLastSlideIndex
);
2965 displaySlideIndex( nLastSlideIndex
);
2970 void SAL_CALL
SlideshowImpl::gotoBookmark( const OUString
& rBookmark
)
2972 SolarMutexGuard aSolarGuard
;
2977 sal_Int32 nSlideNumber
= getSlideNumberForBookmark( rBookmark
);
2978 if( nSlideNumber
!= -1 )
2979 displaySlideNumber( nSlideNumber
);
2982 void SAL_CALL
SlideshowImpl::gotoSlide( const Reference
< XDrawPage
>& xSlide
)
2984 SolarMutexGuard aSolarGuard
;
2986 if( !(mpSlideController
&& xSlide
.is()) )
2992 const sal_Int32 nSlideCount
= mpSlideController
->getSlideNumberCount();
2993 for( sal_Int32 nSlide
= 0; nSlide
< nSlideCount
; nSlide
++ )
2995 if( mpSlideController
->getSlideByNumber( nSlide
) == xSlide
)
2997 displaySlideNumber( nSlide
);
3002 void SAL_CALL
SlideshowImpl::gotoSlideIndex( sal_Int32 nIndex
)
3004 SolarMutexGuard aSolarGuard
;
3009 displaySlideIndex( nIndex
);
3012 void SAL_CALL
SlideshowImpl::stopSound( )
3014 SolarMutexGuard aSolarGuard
;
3026 TOOLS_WARN_EXCEPTION( "sd", "sd::SlideshowImpl::stopSound()" );
3032 ::sal_Int32 SAL_CALL
SlideshowImpl::getCount( )
3034 return getSlideCount();
3037 css::uno::Any SAL_CALL
SlideshowImpl::getByIndex( ::sal_Int32 Index
)
3039 return Any( getSlideByIndex( Index
) );
3042 css::uno::Type SAL_CALL
SlideshowImpl::getElementType( )
3044 return cppu::UnoType
<XDrawPage
>::get();
3047 sal_Bool SAL_CALL
SlideshowImpl::hasElements( )
3049 return getSlideCount() != 0;
3052 Reference
< XSlideShow
> SAL_CALL
SlideshowImpl::getSlideShow()
3057 PresentationSettingsEx::PresentationSettingsEx( const PresentationSettingsEx
& r
)
3058 : PresentationSettings( r
)
3059 , mbRehearseTimings(r
.mbRehearseTimings
)
3060 , mbPreview(r
.mbPreview
)
3061 , mpParentWindow( nullptr )
3065 PresentationSettingsEx::PresentationSettingsEx( PresentationSettings
const & r
)
3066 : PresentationSettings( r
)
3067 , mbRehearseTimings(false)
3069 , mpParentWindow(nullptr)
3073 void PresentationSettingsEx::SetArguments( const Sequence
< PropertyValue
>& rArguments
)
3075 for( const PropertyValue
& rValue
: rArguments
)
3077 SetPropertyValue( rValue
.Name
, rValue
.Value
);
3081 void PresentationSettingsEx::SetPropertyValue( std::u16string_view rProperty
, const Any
& rValue
)
3083 if ( rProperty
== u
"RehearseTimings" )
3085 if( rValue
>>= mbRehearseTimings
)
3088 else if ( rProperty
== u
"Preview" )
3090 if( rValue
>>= mbPreview
)
3093 else if ( rProperty
== u
"AnimationNode" )
3095 if( rValue
>>= mxAnimationNode
)
3098 else if ( rProperty
== u
"ParentWindow" )
3100 Reference
< XWindow
> xWindow
;
3101 if( rValue
>>= xWindow
)
3103 mpParentWindow
= xWindow
.is() ? VCLUnoHelper::GetWindow( xWindow
)
3108 else if ( rProperty
== u
"AllowAnimations" )
3110 if( rValue
>>= mbAnimationAllowed
)
3113 else if ( rProperty
== u
"FirstPage" )
3116 if( rValue
>>= aPresPage
)
3118 maPresPage
= getUiNameFromPageApiNameImpl(aPresPage
);
3119 mbCustomShow
= false;
3125 if( rValue
>>= mxStartPage
)
3129 else if ( rProperty
== u
"IsAlwaysOnTop" )
3131 if( rValue
>>= mbAlwaysOnTop
)
3134 else if ( rProperty
== u
"IsAutomatic" )
3136 if( rValue
>>= mbManual
)
3139 else if ( rProperty
== u
"IsEndless" )
3141 if( rValue
>>= mbEndless
)
3144 else if ( rProperty
== u
"IsFullScreen" )
3146 if( rValue
>>= mbFullScreen
)
3149 else if ( rProperty
== u
"IsMouseVisible" )
3151 if( rValue
>>= mbMouseVisible
)
3154 else if ( rProperty
== u
"Pause" )
3156 sal_Int32 nPause
= -1;
3157 if( (rValue
>>= nPause
) && (nPause
>= 0) )
3159 mnPauseTimeout
= nPause
;
3163 else if ( rProperty
== u
"UsePen" )
3165 if( rValue
>>= mbMouseAsPen
)
3168 throw IllegalArgumentException();
3171 // XAnimationListener
3173 SlideShowListenerProxy::SlideShowListenerProxy( rtl::Reference
< SlideshowImpl
> xController
, css::uno::Reference
< css::presentation::XSlideShow
> xSlideShow
)
3174 : mxController(std::move( xController
))
3175 , mxSlideShow(std::move( xSlideShow
))
3179 SlideShowListenerProxy::~SlideShowListenerProxy()
3183 void SlideShowListenerProxy::addAsSlideShowListener()
3185 if( mxSlideShow
.is() )
3187 Reference
< XSlideShowListener
> xSlideShowListener( this );
3188 mxSlideShow
->addSlideShowListener( xSlideShowListener
);
3192 void SlideShowListenerProxy::removeAsSlideShowListener()
3194 if( mxSlideShow
.is() )
3196 Reference
< XSlideShowListener
> xSlideShowListener( this );
3197 mxSlideShow
->removeSlideShowListener( xSlideShowListener
);
3201 void SlideShowListenerProxy::addShapeEventListener( const css::uno::Reference
< css::drawing::XShape
>& xShape
)
3203 if( mxSlideShow
.is() )
3205 Reference
< XShapeEventListener
> xListener( this );
3206 mxSlideShow
->addShapeEventListener( xListener
, xShape
);
3210 void SlideShowListenerProxy::removeShapeEventListener( const css::uno::Reference
< css::drawing::XShape
>& xShape
)
3212 if( mxSlideShow
.is() )
3214 Reference
< XShapeEventListener
> xListener( this );
3215 mxSlideShow
->removeShapeEventListener( xListener
, xShape
);
3219 void SlideShowListenerProxy::addSlideShowListener( const css::uno::Reference
< css::presentation::XSlideShowListener
>& xListener
)
3221 std::unique_lock
g(m_aMutex
);
3222 maListeners
.addInterface(g
, xListener
);
3225 void SlideShowListenerProxy::removeSlideShowListener( const css::uno::Reference
< css::presentation::XSlideShowListener
>& xListener
)
3227 std::unique_lock
g(m_aMutex
);
3228 maListeners
.removeInterface(g
, xListener
);
3231 void SAL_CALL
SlideShowListenerProxy::beginEvent( const Reference
< XAnimationNode
>& xNode
)
3233 std::unique_lock
aGuard( m_aMutex
);
3235 if( maListeners
.getLength(aGuard
) >= 0 )
3237 maListeners
.forEach(aGuard
,
3238 [&] (Reference
<XAnimationListener
> const& xListener
) {
3239 return xListener
->beginEvent(xNode
);
3244 void SAL_CALL
SlideShowListenerProxy::endEvent( const Reference
< XAnimationNode
>& xNode
)
3246 std::unique_lock
aGuard( m_aMutex
);
3248 if( maListeners
.getLength(aGuard
) >= 0 )
3250 maListeners
.forEach(aGuard
,
3251 [&] (Reference
<XAnimationListener
> const& xListener
) {
3252 return xListener
->endEvent(xNode
);
3257 void SAL_CALL
SlideShowListenerProxy::repeat( const Reference
< XAnimationNode
>& xNode
, ::sal_Int32 nRepeat
)
3259 std::unique_lock
aGuard( m_aMutex
);
3261 if( maListeners
.getLength(aGuard
) >= 0 )
3263 maListeners
.forEach(aGuard
,
3264 [&] (Reference
<XAnimationListener
> const& xListener
) {
3265 return xListener
->repeat(xNode
, nRepeat
);
3270 // css::presentation::XSlideShowListener:
3272 void SAL_CALL
SlideShowListenerProxy::paused( )
3274 std::unique_lock
aGuard( m_aMutex
);
3276 maListeners
.forEach(aGuard
,
3277 [](uno::Reference
<presentation::XSlideShowListener
> const& xListener
)
3279 xListener
->paused();
3283 void SAL_CALL
SlideShowListenerProxy::resumed( )
3285 std::unique_lock
aGuard( m_aMutex
);
3287 maListeners
.forEach(aGuard
,
3288 [](uno::Reference
<presentation::XSlideShowListener
> const& xListener
)
3290 xListener
->resumed();
3294 void SAL_CALL
SlideShowListenerProxy::slideTransitionStarted( )
3296 std::unique_lock
aGuard( m_aMutex
);
3298 maListeners
.forEach(aGuard
,
3299 [](uno::Reference
<presentation::XSlideShowListener
> const& xListener
)
3301 xListener
->slideTransitionStarted();
3305 void SAL_CALL
SlideShowListenerProxy::slideTransitionEnded( )
3307 std::unique_lock
aGuard( m_aMutex
);
3309 maListeners
.forEach(aGuard
,
3310 [](uno::Reference
<presentation::XSlideShowListener
> const& xListener
)
3312 xListener
->slideTransitionEnded ();
3316 void SAL_CALL
SlideShowListenerProxy::slideAnimationsEnded( )
3318 std::unique_lock
aGuard( m_aMutex
);
3320 maListeners
.forEach(aGuard
,
3321 [](uno::Reference
<presentation::XSlideShowListener
> const& xListener
)
3323 xListener
->slideAnimationsEnded ();
3327 void SlideShowListenerProxy::slideEnded(sal_Bool bReverse
)
3330 std::unique_lock
aGuard( m_aMutex
);
3332 if( maListeners
.getLength(aGuard
) >= 0 )
3334 maListeners
.forEach(aGuard
,
3335 [&] (Reference
<XSlideShowListener
> const& xListener
) {
3336 return xListener
->slideEnded(bReverse
);
3342 SolarMutexGuard aSolarGuard
;
3343 if( mxController
.is() )
3344 mxController
->slideEnded(bReverse
);
3348 void SlideShowListenerProxy::hyperLinkClicked( OUString
const& aHyperLink
)
3351 std::unique_lock
aGuard( m_aMutex
);
3353 if( maListeners
.getLength(aGuard
) >= 0 )
3355 maListeners
.forEach(aGuard
,
3356 [&] (Reference
<XSlideShowListener
> const& xListener
) {
3357 return xListener
->hyperLinkClicked(aHyperLink
);
3363 SolarMutexGuard aSolarGuard
;
3364 if( mxController
.is() )
3365 mxController
->hyperLinkClicked(aHyperLink
);
3371 void SAL_CALL
SlideShowListenerProxy::disposing( const css::lang::EventObject
& aDisposeEvent
)
3373 std::unique_lock
g(m_aMutex
);
3374 maListeners
.disposeAndClear( g
, aDisposeEvent
);
3375 mxController
.clear();
3376 mxSlideShow
.clear();
3379 // XShapeEventListener
3381 void SAL_CALL
SlideShowListenerProxy::click( const Reference
< XShape
>& xShape
, const css::awt::MouseEvent
& /*aOriginalEvent*/ )
3383 SolarMutexGuard aSolarGuard
;
3384 if( mxController
.is() )
3385 mxController
->click(xShape
);
3388 void SAL_CALL
SlideShowListenerProxy::contextMenuShow(const css::awt::Point
& point
)
3390 SolarMutexGuard aSolarGuard
;
3391 if (mxController
.is())
3392 mxController
->contextMenuShow(point
);
3397 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */