sd/source/ui/accessibility/AccessibleDrawDocumentView.cxx | 3 sd/source/ui/animations/CustomAnimationPane.cxx | 3 sd/source/ui/animations/SlideTransitionPane.cxx | 2 sd/source/ui/app/sdmod1.cxx | 2 sd/source/ui/dlg/navigatr.cxx | 2 sd/source/ui/docshell/docshel3.cxx | 2 sd/source/ui/func/funavig.cxx | 2 sd/source/ui/func/fupoor.cxx | 4 sd/source/ui/inc/slideshow.hxx | 9 sd/source/ui/slideshow/slideshow.cxx | 46 + sd/source/ui/slideshow/slideshowimpl.cxx | 436 +++++++++++++- sd/source/ui/slideshow/slideshowimpl.hxx | 35 + sd/source/ui/unoidl/DrawController.cxx | 23 sd/source/ui/view/drawview.cxx | 3 sd/source/ui/view/drviews1.cxx | 4 sd/source/ui/view/drviews2.cxx | 6 sd/source/ui/view/drviews3.cxx | 4 sd/source/ui/view/drviews4.cxx | 2 sd/source/ui/view/drviews7.cxx | 9 sd/source/ui/view/drviewsa.cxx | 9 sd/source/ui/view/drviewse.cxx | 8 sd/source/ui/view/drviewsh.cxx | 5 sd/source/ui/view/sdview2.cxx | 3 sd/source/ui/view/viewshel.cxx | 25 24 files changed, 608 insertions(+), 39 deletions(-)
New commits: commit 91d778ff459b79cb1e6c47574ca9ad0f9689c79e Author: Armin Le Grand (allotropia) <armin.le.grand.ext...@allotropia.de> AuthorDate: Thu Feb 22 23:25:39 2024 +0100 Commit: Thorsten Behrens <thorsten.behr...@allotropia.de> CommitDate: Fri Feb 23 10:47:56 2024 +0100 IASS: Added SdrObject Insert/Remove suppport Change-Id: I7f6aad0ec12de3c3b2677f1ca07e8efd5a881982 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/163797 Tested-by: Jenkins Reviewed-by: Armin Le Grand <armin.le.gr...@me.com> diff --git a/sd/source/ui/slideshow/slideshowimpl.cxx b/sd/source/ui/slideshow/slideshowimpl.cxx index 02702be0d73e..d247da44190c 100644 --- a/sd/source/ui/slideshow/slideshowimpl.cxx +++ b/sd/source/ui/slideshow/slideshowimpl.cxx @@ -563,6 +563,8 @@ SlideshowImpl::SlideshowImpl( const Reference< XPresentation2 >& xPresentation, , mnEndShowEvent(nullptr) , mnContextMenuEvent(nullptr) , mnEventObjectChange(nullptr) +, mnEventObjectInserted(nullptr) +, mnEventObjectRemoved(nullptr) , mnEventPageOrderChange(nullptr) , mxPresentation( xPresentation ) , mxListenerProxy() @@ -656,6 +658,10 @@ void SlideshowImpl::disposing(std::unique_lock<std::mutex>&) Application::RemoveUserEvent( mnContextMenuEvent ); if( mnEventObjectChange ) Application::RemoveUserEvent( mnEventObjectChange ); + if( mnEventObjectInserted ) + Application::RemoveUserEvent( mnEventObjectInserted ); + if( mnEventObjectRemoved ) + Application::RemoveUserEvent( mnEventObjectRemoved ); if( mnEventPageOrderChange ) Application::RemoveUserEvent( mnEventPageOrderChange ); @@ -3277,53 +3283,104 @@ void SlideshowImpl::AsyncNotifyEvent( const uno::Reference< css::drawing::XDrawPage >& rXCurrentSlide, const SdrHintKind eHintKind) { - if (SdrHintKind::ObjectChange == eHintKind) + switch (eHintKind) { - mnEventObjectChange = nullptr; - - // refresh single slide - gotoSlide(rXCurrentSlide); - } - else if (SdrHintKind::PageOrderChange == eHintKind) - { - mnEventPageOrderChange = nullptr; + case SdrHintKind::ObjectInserted: + { + mnEventObjectInserted = nullptr; - // order of pages (object pages or master pages) changed (Insert/Remove/ChangePos) - // rXCurrentSlide is the current slide before the change. - Reference< XDrawPagesSupplier > xDrawPages( mpDoc->getUnoModel(), UNO_QUERY_THROW ); - Reference< XIndexAccess > xSlides( xDrawPages->getDrawPages(), UNO_QUERY_THROW ); - const sal_Int32 nNewSlideCount(xSlides.is() ? xSlides->getCount() : 0); + // refresh single slide + gotoSlide(rXCurrentSlide); + break; + } + case SdrHintKind::ObjectRemoved: + { + mnEventObjectRemoved = nullptr; - if (nNewSlideCount != mpSlideController->getSlideNumberCount()) + // refresh single slide + gotoSlide(rXCurrentSlide); + break; + } + case SdrHintKind::ObjectChange: { - // need to reinitialize AnimationSlideController - OUString aPresSlide( maPresSettings.maPresPage ); - createSlideList( maPresSettings.mbAll, aPresSlide ); + mnEventObjectChange = nullptr; + + // refresh single slide + gotoSlide(rXCurrentSlide); + break; } + case SdrHintKind::PageOrderChange: + { + mnEventPageOrderChange = nullptr; - // Check if current slide before change is still valid (maybe removed) - const sal_Int32 nSlideCount(mpSlideController->getSlideNumberCount()); - bool bSlideStillValid(false); + // order of pages (object pages or master pages) changed (Insert/Remove/ChangePos) + // rXCurrentSlide is the current slide before the change. + Reference< XDrawPagesSupplier > xDrawPages( mpDoc->getUnoModel(), UNO_QUERY_THROW ); + Reference< XIndexAccess > xSlides( xDrawPages->getDrawPages(), UNO_QUERY_THROW ); + const sal_Int32 nNewSlideCount(xSlides.is() ? xSlides->getCount() : 0); - for (sal_Int32 nSlide(0); !bSlideStillValid && nSlide < nSlideCount; nSlide++) - { - if (rXCurrentSlide == mpSlideController->getSlideByNumber(nSlide)) + if (nNewSlideCount != mpSlideController->getSlideNumberCount()) { - bSlideStillValid = true; + // need to reinitialize AnimationSlideController + OUString aPresSlide( maPresSettings.maPresPage ); + createSlideList( maPresSettings.mbAll, aPresSlide ); } - } - if(bSlideStillValid) - { - // stay on that slide - gotoSlide(rXCurrentSlide); + // Check if current slide before change is still valid (maybe removed) + const sal_Int32 nSlideCount(mpSlideController->getSlideNumberCount()); + bool bSlideStillValid(false); + + for (sal_Int32 nSlide(0); !bSlideStillValid && nSlide < nSlideCount; nSlide++) + { + if (rXCurrentSlide == mpSlideController->getSlideByNumber(nSlide)) + { + bSlideStillValid = true; + } + } + + if(bSlideStillValid) + { + // stay on that slide + gotoSlide(rXCurrentSlide); + } + else + { + // not possible to stay on that slide, go to 1st slide (kinda restart) + gotoFirstSlide(); + } + break; } - else + default: + break; + } +} + +bool SlideshowImpl::isCurrentSlideInvolved(const SdrHint& rHint) +{ + // get current slide + uno::Reference< css::drawing::XDrawPage > XCurrentSlide(getCurrentSlide()); + if (!XCurrentSlide.is()) + return false; + + SdrPage* pCurrentSlide(GetSdrPageFromXDrawPage(XCurrentSlide)); + if (nullptr == pCurrentSlide) + return false; + + const SdrPage* pHintPage(rHint.GetPage()); + if (nullptr == pHintPage) + return false; + + if (pHintPage->IsMasterPage()) + { + if (pCurrentSlide->TRG_HasMasterPage()) { - // not possible to stay on that slide, go to 1st slide (kinda restart) - gotoFirstSlide(); + // current slide uses MasterPage on which the change happened + return pHintPage == &pCurrentSlide->TRG_GetMasterPage(); } } + + // object on current slide was changed + return pHintPage == pCurrentSlide; } void SlideshowImpl::Notify(SfxBroadcaster& /*rBC*/, const SfxHint& rHint) @@ -3344,75 +3401,84 @@ void SlideshowImpl::Notify(SfxBroadcaster& /*rBC*/, const SfxHint& rHint) // no SlideShow instance or not running, nothing to do return; - const SdrHintKind eHintKind(static_cast<const SdrHint&>(rHint).GetKind()); + const SdrHint& rSdrHint(static_cast<const SdrHint&>(rHint)); + const SdrHintKind eHintKind(rSdrHint.GetKind()); - if (SdrHintKind::ObjectChange == eHintKind) + switch (eHintKind) { - if (nullptr != mnEventObjectChange) - // avoid multiple events - return; - - // Object changed, object & involved page included in rHint. - uno::Reference< css::drawing::XDrawPage > XCurrentSlide(getCurrentSlide()); - if (!XCurrentSlide.is()) - return; + case SdrHintKind::ObjectInserted: + { + if (nullptr != mnEventObjectChange) + // avoid multiple events + return; - SdrPage* pCurrentSlide(GetSdrPageFromXDrawPage(XCurrentSlide)); - if (nullptr == pCurrentSlide) - return; + if (!isCurrentSlideInvolved(rSdrHint)) + // nothing to do when current slide is not involved + return; - const SdrPage* pHintPage(static_cast<const SdrHint&>(rHint).GetPage()); - if (nullptr == pHintPage) - return; + // Refresh current slide + uno::Reference< css::drawing::XDrawPage > XCurrentSlide(getCurrentSlide()); + mnEventObjectInserted = AsyncUpdateSlideshow_Impl::AsyncUpdateSlideshow(this, XCurrentSlide, eHintKind); + break; + } + case SdrHintKind::ObjectRemoved: + { + if (nullptr != mnEventObjectRemoved) + // avoid multiple events + return; - bool bCurrentSlideIsInvolved(false); + if (!isCurrentSlideInvolved(rSdrHint)) + // nothing to do when current slide is not involved + return; - if (pHintPage->IsMasterPage()) - { - if (pCurrentSlide->TRG_HasMasterPage()) - { - // current slide uses MasterPage on which the change happened - bCurrentSlideIsInvolved = (pHintPage == &pCurrentSlide->TRG_GetMasterPage()); - } + // Refresh current slide + uno::Reference< css::drawing::XDrawPage > XCurrentSlide(getCurrentSlide()); + mnEventObjectRemoved = AsyncUpdateSlideshow_Impl::AsyncUpdateSlideshow(this, XCurrentSlide, eHintKind); + break; } - else + case SdrHintKind::ObjectChange: { - // object on current slide was changed - bCurrentSlideIsInvolved = (pHintPage == pCurrentSlide); - } + if (nullptr != mnEventObjectChange) + // avoid multiple events + return; - if (!bCurrentSlideIsInvolved) - // nothing to do when current slide is not involved - return; + if (!isCurrentSlideInvolved(rSdrHint)) + // nothing to do when current slide is not involved + return; - // Refresh current slide. Need to do that asynchronous, else e.g. - // text edit changes EditEngine/Outliner are not progressed far - // enough (ObjectChanged broadcast which we are in here seems - // to early for some cases) - mnEventObjectChange = AsyncUpdateSlideshow_Impl::AsyncUpdateSlideshow(this, XCurrentSlide, eHintKind); - } - else if (SdrHintKind::PageOrderChange == eHintKind) - { - // Unfortunately we get multiple events, e.g. when drag/drop position change in - // slide sorter on left side of EditView. This includes some with page number +1, - // then again -1 (it's a position change). Problem is that in-between already - // a re-schedule seems to happen, so indeed AsyncNotifyEvent will change to +1/-1 - // already. Since we get even more, at least try to take the last one. I found no - // good solution yet for this. - if (nullptr != mnEventPageOrderChange) - Application::RemoveUserEvent( mnEventPageOrderChange ); + // Refresh current slide. Need to do that asynchronous, else e.g. + // text edit changes EditEngine/Outliner are not progressed far + // enough (ObjectChanged broadcast which we are in here seems + // to early for some cases) + uno::Reference< css::drawing::XDrawPage > XCurrentSlide(getCurrentSlide()); + mnEventObjectChange = AsyncUpdateSlideshow_Impl::AsyncUpdateSlideshow(this, XCurrentSlide, eHintKind); + break; + } + case SdrHintKind::PageOrderChange: + { + // Unfortunately we get multiple events, e.g. when drag/drop position change in + // slide sorter on left side of EditView. This includes some with page number +1, + // then again -1 (it's a position change). Problem is that in-between already + // a re-schedule seems to happen, so indeed AsyncNotifyEvent will change to +1/-1 + // already. Since we get even more, at least try to take the last one. I found no + // good solution yet for this. + if (nullptr != mnEventPageOrderChange) + Application::RemoveUserEvent( mnEventPageOrderChange ); - // order of pages (object pages or master pages) changed (Insert/Remove/ChangePos) - uno::Reference< css::drawing::XDrawPage > XCurrentSlide(getCurrentSlide()); - mnEventPageOrderChange = AsyncUpdateSlideshow_Impl::AsyncUpdateSlideshow(this, XCurrentSlide, eHintKind); - } - else if (SdrHintKind::ModelCleared == eHintKind) - { - // immediately end presentation - endPresentation(); + // order of pages (object pages or master pages) changed (Insert/Remove/ChangePos) + uno::Reference< css::drawing::XDrawPage > XCurrentSlide(getCurrentSlide()); + mnEventPageOrderChange = AsyncUpdateSlideshow_Impl::AsyncUpdateSlideshow(this, XCurrentSlide, eHintKind); + break; + } + case SdrHintKind::ModelCleared: + { + // immediately end presentation + endPresentation(); + break; + } + default: + break; } - - // maybe need to add reactions here to other Hint-Types } Reference< XSlideShow > SAL_CALL SlideshowImpl::getSlideShow() diff --git a/sd/source/ui/slideshow/slideshowimpl.hxx b/sd/source/ui/slideshow/slideshowimpl.hxx index 42697b93e8e0..0718d3b33597 100644 --- a/sd/source/ui/slideshow/slideshowimpl.hxx +++ b/sd/source/ui/slideshow/slideshowimpl.hxx @@ -214,6 +214,9 @@ private: virtual ~SlideshowImpl() override; + // helper to check if given hint is associated with CurrentSlide + bool isCurrentSlideInvolved(const SdrHint& rHint); + // override WeakComponentImplHelperBase::disposing() // This function is called upon disposing the component, // if your component needs special work when it becomes @@ -353,6 +356,8 @@ private: ImplSVEvent * mnEndShowEvent; ImplSVEvent * mnContextMenuEvent; ImplSVEvent * mnEventObjectChange; + ImplSVEvent * mnEventObjectInserted; + ImplSVEvent * mnEventObjectRemoved; ImplSVEvent * mnEventPageOrderChange; css::uno::Reference< css::presentation::XPresentation2 > mxPresentation; commit 13bd59fea725dfa40c4e9fe464fec0e7e4854ab2 Author: Armin Le Grand (allotropia) <armin.le.grand.ext...@allotropia.de> AuthorDate: Wed Feb 21 15:51:23 2024 +0100 Commit: Thorsten Behrens <thorsten.behr...@allotropia.de> CommitDate: Fri Feb 23 10:47:42 2024 +0100 IASS: Allow exit Impress when SlideShow is running Change-Id: Iffccf2c7fe37845f9da44fd911cf974db026af89 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/163697 Tested-by: Jenkins Reviewed-by: Armin Le Grand <armin.le.gr...@me.com> diff --git a/sd/source/ui/unoidl/DrawController.cxx b/sd/source/ui/unoidl/DrawController.cxx index 3dd4c4c65478..7f974cb4ac6a 100644 --- a/sd/source/ui/unoidl/DrawController.cxx +++ b/sd/source/ui/unoidl/DrawController.cxx @@ -182,8 +182,27 @@ sal_Bool SAL_CALL DrawController::suspend( sal_Bool Suspend ) { // do not allow suspend if a slideshow needs this controller! rtl::Reference< SlideShow > xSlideShow( SlideShow::GetSlideShow( *pViewShellBase ) ); - if( xSlideShow.is() && xSlideShow->dependsOn(pViewShellBase) ) - return false; + if (xSlideShow.is()) + { + if (SlideShow::IsInteractiveSlideshow()) + { + // IASS mode: If preview mode, end it + if (xSlideShow->isInteractiveSetup()) + xSlideShow->endInteractivePreview(); + + // end the SlideShow + xSlideShow->end(); + + // use SfxBaseController::suspend( Suspend ) below + // for normal processing and return value + } + else + { + // original reaction - prevent exit + if (xSlideShow->dependsOn(pViewShellBase)) + return false; + } + } } } commit 21a517f630ecc71d2fd0212fa0a50e9b1a8a0e0c Author: Armin Le Grand (allotropia) <armin.le.grand.ext...@allotropia.de> AuthorDate: Tue Feb 20 20:03:51 2024 +0100 Commit: Thorsten Behrens <thorsten.behr...@allotropia.de> CommitDate: Fri Feb 23 10:46:59 2024 +0100 IASS: Avoid more SlideShow shutdowns There are many ways the SlideShow may be stopped, but with IASS mode less are needed. Identified quite some and added needed code. Also added that for setting transitions or adding an effect to an Object when the SlideShow is up (the FullScreen one, makes no sense in-place) the Preview for that is show in the running SlideShow by switching to it, showing, and back. So this is used in this mode as a permanent preview for those changes. Change-Id: I5cc34e230358aecad30fec8aee05acfa937f9270 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/163669 Tested-by: Jenkins Reviewed-by: Armin Le Grand <armin.le.gr...@me.com> diff --git a/sd/source/ui/animations/CustomAnimationPane.cxx b/sd/source/ui/animations/CustomAnimationPane.cxx index 2276fa91b3aa..d4199e14aad7 100644 --- a/sd/source/ui/animations/CustomAnimationPane.cxx +++ b/sd/source/ui/animations/CustomAnimationPane.cxx @@ -1883,7 +1883,8 @@ void CustomAnimationPane::onAdd() updateControls(); - SlideShow::Stop( mrBase ); + if (!SlideShow::IsInteractiveSlideshow()) // IASS + SlideShow::Stop( mrBase ); } void CustomAnimationPane::onRemove() diff --git a/sd/source/ui/animations/SlideTransitionPane.cxx b/sd/source/ui/animations/SlideTransitionPane.cxx index ac3f01762d50..74f459095b4c 100644 --- a/sd/source/ui/animations/SlideTransitionPane.cxx +++ b/sd/source/ui/animations/SlideTransitionPane.cxx @@ -884,7 +884,7 @@ void SlideTransitionPane::applyToSelectedPages(bool bPreview = true) { if (aEffect.mnType) // mnType = 0 denotes no transition playCurrentEffect(); - else if( mxView.is() ) + else if( mxView.is() && !SlideShow::IsInteractiveSlideshow()) // IASS SlideShow::Stop( mrBase ); } diff --git a/sd/source/ui/inc/slideshow.hxx b/sd/source/ui/inc/slideshow.hxx index 81af4a52f4ee..2703d9611e31 100644 --- a/sd/source/ui/inc/slideshow.hxx +++ b/sd/source/ui/inc/slideshow.hxx @@ -106,6 +106,12 @@ public: // helper api + bool startInteractivePreview( + const css::uno::Reference< css::drawing::XDrawPage >& xDrawPage, + const css::uno::Reference< css::animations::XAnimationNode >& xAnimationNode ); + bool isInteractiveSetup() const; + void endInteractivePreview(); + void startPreview( const css::uno::Reference< css::drawing::XDrawPage >& xDrawPage, const css::uno::Reference< css::animations::XAnimationNode >& xAnimationNode ); diff --git a/sd/source/ui/slideshow/slideshow.cxx b/sd/source/ui/slideshow/slideshow.cxx index a7b335e59fc9..010f8697e42a 100644 --- a/sd/source/ui/slideshow/slideshow.cxx +++ b/sd/source/ui/slideshow/slideshow.cxx @@ -194,6 +194,16 @@ bool SlideShow::StartPreview( ViewShellBase const & rBase, if( !xSlideShow.is() ) return false; + // end an already running IASS Preview (when someone is fast) + if (SlideShow::IsInteractiveSlideshow() && xSlideShow->isInteractiveSetup()) + xSlideShow->endInteractivePreview(); + + // check if IASS re-use of running Slideshow can/should be done + // and do it + if (SlideShow::IsInteractiveSlideshow() && xSlideShow->isFullScreen()) // IASS + return xSlideShow->startInteractivePreview( xDrawPage, xAnimationNode ); + + // fallback to usual mode xSlideShow->startPreview( xDrawPage, xAnimationNode ); return true; } @@ -665,6 +675,13 @@ void SAL_CALL SlideShow::end() { SolarMutexGuard aGuard; + if (SlideShow::IsInteractiveSlideshow() && isInteractiveSetup()) + { + // If IASS was active clean that up, but do not end SlideShow + endInteractivePreview(); + return; + } + // The mbIsInStartup flag should have been reset during the start of the // slide show. Reset it here just in case that something has horribly // gone wrong. @@ -930,6 +947,28 @@ void SlideShow::disposing(std::unique_lock<std::mutex>&) mpDoc = nullptr; } +bool SlideShow::startInteractivePreview( const Reference< XDrawPage >& xDrawPage, const Reference< XAnimationNode >& xAnimationNode ) +{ + if (!mxController.is()) + return false; + + mxController->startInteractivePreview(xDrawPage, xAnimationNode); + return mxController->isInteractiveSetup(); +} + +bool SlideShow::isInteractiveSetup() const +{ + if (!mxController.is()) + return false; + + return mxController->isInteractiveSetup(); +} + +void SlideShow::endInteractivePreview() +{ + mxController->endInteractivePreview(); +} + void SlideShow::startPreview( const Reference< XDrawPage >& xDrawPage, const Reference< XAnimationNode >& xAnimationNode ) { Sequence< PropertyValue > aArguments{ diff --git a/sd/source/ui/slideshow/slideshowimpl.cxx b/sd/source/ui/slideshow/slideshowimpl.cxx index 37d6e861e02d..02702be0d73e 100644 --- a/sd/source/ui/slideshow/slideshowimpl.cxx +++ b/sd/source/ui/slideshow/slideshowimpl.cxx @@ -165,6 +165,10 @@ public: bool hasSlides() const { return !maSlideNumbers.empty(); } + // for InteractiveSlideShow we need to temporarily change the program + // and mode, so allow save/restore that settings + void pushForPreview(); + void popFromPreview(); private: bool getSlideAPI( sal_Int32 nSlideNumber, Reference< XDrawPage >& xSlide, Reference< XAnimationNode >& xAnimNode ); sal_Int32 findSlideIndex( sal_Int32 nSlideNumber ) const; @@ -183,8 +187,40 @@ private: sal_Int32 mnCurrentSlideIndex; sal_Int32 mnHiddenSlideNumber; Reference< XIndexAccess > mxSlides; + + // IASS data for push/pop + std::vector< sal_Int32 > maSlideNumbers2; + std::vector< bool > maSlideVisible2; + std::vector< bool > maSlideVisited2; + Reference< XAnimationNode > mxPreviewNode2; + Mode meMode2; }; +void AnimationSlideController::pushForPreview() +{ + maSlideNumbers2 = maSlideNumbers; + maSlideVisible2 = maSlideVisible; + maSlideVisited2 = maSlideVisited; + maSlideNumbers.clear(); + maSlideVisible.clear(); + maSlideVisited.clear(); + mxPreviewNode2 = mxPreviewNode; + meMode2 = meMode; + meMode = AnimationSlideController::PREVIEW; +} + +void AnimationSlideController::popFromPreview() +{ + maSlideNumbers = maSlideNumbers2; + maSlideVisible = maSlideVisible2; + maSlideVisited = maSlideVisited2; + maSlideNumbers2.clear(); + maSlideVisible2.clear(); + maSlideVisited2.clear(); + mxPreviewNode = mxPreviewNode2; + meMode = meMode2; +} + Reference< XDrawPage > AnimationSlideController::getSlideByNumber( sal_Int32 nSlideNumber ) const { Reference< XDrawPage > xSlide; @@ -487,7 +523,9 @@ constexpr OUStringLiteral gsBookmark( u"Bookmark" ); constexpr OUStringLiteral gsVerb( u"Verb" ); SlideshowImpl::SlideshowImpl( const Reference< XPresentation2 >& xPresentation, ViewShell* pViewSh, ::sd::View* pView, SdDrawDocument* pDoc, vcl::Window* pParentWindow ) -: mxModel(pDoc->getUnoModel(),UNO_QUERY_THROW) +: mxShow() +, mxView() +, mxModel(pDoc->getUnoModel(),UNO_QUERY_THROW) , maUpdateTimer("SlideShowImpl maUpdateTimer") , maInputFreezeTimer("SlideShowImpl maInputFreezeTimer") , maDeactivateTimer("SlideShowImpl maDeactivateTimer") @@ -497,10 +535,14 @@ SlideshowImpl::SlideshowImpl( const Reference< XPresentation2 >& xPresentation, , mpDoc(pDoc) , mpParentWindow(pParentWindow) , mpShowWindow(nullptr) +, mpSlideController() , mnRestoreSlide(0) +, maPopupMousePos() , maPresSize( -1, -1 ) , meAnimationMode(ANIMATIONMODE_SHOW) +, maCharBuffer() , mpOldActiveWindow(nullptr) +, maStarBASICGlobalErrorHdl() , mnChildMask( 0 ) , mbDisposed(false) , mbAutoSaveWasOn(false) @@ -513,11 +555,25 @@ SlideshowImpl::SlideshowImpl( const Reference< XPresentation2 >& xPresentation, , mnUserPaintColor( 0x80ff0000L ) , mbUsePen(false) , mdUserPaintStrokeWidth ( 150.0 ) +, maShapeEventMap() +, mxPreviewDrawPage() +, mxPreviewAnimationNode() +, mxPlayer() +, mpPaneHider() , mnEndShowEvent(nullptr) , mnContextMenuEvent(nullptr) , mnEventObjectChange(nullptr) , mnEventPageOrderChange(nullptr) , mxPresentation( xPresentation ) +, mxListenerProxy() +, mxShow2() +, mxView2() +, meAnimationMode2() +, mbInterActiveSetup(false) +, maPresSettings2() +, mxPreviewDrawPage2() +, mxPreviewAnimationNode2() +, mnSlideIndex(0) { if( mpViewShell ) mpOldActiveWindow = mpViewShell->GetActiveWindow(); @@ -740,6 +796,122 @@ void SlideshowImpl::disposing(std::unique_lock<std::mutex>&) mbDisposed = true; } +bool SlideshowImpl::isInteractiveSetup() const +{ + return mbInterActiveSetup; +} + +void SlideshowImpl::startInteractivePreview( const Reference< XDrawPage >& xDrawPage, const Reference< XAnimationNode >& xAnimationNode ) +{ + // set flag that we are in IASS mode + mbInterActiveSetup = true; + + // save stuff that will be replaced temporarily + mxShow2 = mxShow; + mxView2 = mxView; + mxPreviewDrawPage2 = mxPreviewDrawPage; + mxPreviewAnimationNode2 = mxPreviewAnimationNode; + meAnimationMode2 = meAnimationMode; + maPresSettings2 = maPresSettings; + + // remember slide shown before preview + mnSlideIndex = getCurrentSlideIndex(); + + // set DrawPage/AnimationNode + mxPreviewDrawPage = xDrawPage; + mxPreviewAnimationNode = xAnimationNode; + meAnimationMode = ANIMATIONMODE_PREVIEW; + + // set PresSettings for preview + maPresSettings.mbAll = false; + maPresSettings.mbEndless = false; + maPresSettings.mbCustomShow = false; + maPresSettings.mbManual = false; + maPresSettings.mbMouseVisible = false; + maPresSettings.mbMouseAsPen = false; + maPresSettings.mbLockedPages = false; + maPresSettings.mbAlwaysOnTop = false; + maPresSettings.mbFullScreen = false; + maPresSettings.mbAnimationAllowed = true; + maPresSettings.mnPauseTimeout = 0; + maPresSettings.mbShowPauseLogo = false; + + // create a new temporary AnimationSlideController + mpSlideController->pushForPreview(); + // Reference< XDrawPagesSupplier > xDrawPages( mpDoc->getUnoModel(), UNO_QUERY_THROW ); + // Reference< XIndexAccess > xSlides( xDrawPages->getDrawPages(), UNO_QUERY_THROW ); + // mpSlideController = std::make_shared<AnimationSlideController>( xSlides, AnimationSlideController::PREVIEW ); + sal_Int32 nSlideNumber = 0; + Reference< XPropertySet > xSet( xDrawPage, UNO_QUERY_THROW ); + xSet->getPropertyValue( "Number" ) >>= nSlideNumber; + mpSlideController->insertSlideNumber( nSlideNumber-1 ); + mpSlideController->setPreviewNode( xAnimationNode ); + + // prepare properties + sal_Int32 nPropertyCount = 1; + if( xAnimationNode.is() ) + nPropertyCount++; + Sequence< beans::PropertyValue > aProperties(nPropertyCount); + auto pProperties = aProperties.getArray(); + pProperties[0].Name = "AutomaticAdvancement"; + pProperties[0].Value <<= 1.0; // one second timeout + + if( xAnimationNode.is() ) + { + pProperties[1].Name = "NoSlideTransitions"; + pProperties[1].Value <<= true; + } + + // start preview + startShowImpl( aProperties ); +} + +void SlideshowImpl::endInteractivePreview() +{ + if (!mbInterActiveSetup) + // not in use, nothing to do + return; + + // cleanup Show/View + try + { + if( mxView.is() ) + mxShow->removeView( mxView ); + + Reference< XComponent > xComponent( mxShow, UNO_QUERY ); + if( xComponent.is() ) + xComponent->dispose(); + + if( mxView.is() ) + mxView->dispose(); + } + catch( Exception& ) + { + TOOLS_WARN_EXCEPTION( "sd", "sd::SlideshowImpl::stop()" ); + } + mxShow.clear(); + mxView.clear(); + mxView = mxView2; + mxShow = mxShow2; + + // restore SlideController + mpSlideController->popFromPreview(); + + // restore other settings and cleanup temporary incarnations + maPresSettings = maPresSettings2; + meAnimationMode = meAnimationMode2; + mxPreviewAnimationNode = mxPreviewAnimationNode2; + mxPreviewAnimationNode2.clear(); + mxPreviewDrawPage = mxPreviewDrawPage2; + mxPreviewDrawPage2.clear(); + + // go back to slide shown before preview + gotoSlideIndex(mnSlideIndex); + + // reset IASS mode flag + mbInterActiveSetup = false; +} + bool SlideshowImpl::startPreview( const Reference< XDrawPage >& xDrawPage, const Reference< XAnimationNode >& xAnimationNode, diff --git a/sd/source/ui/slideshow/slideshowimpl.hxx b/sd/source/ui/slideshow/slideshowimpl.hxx index 9c0ae75dd5e9..42697b93e8e0 100644 --- a/sd/source/ui/slideshow/slideshowimpl.hxx +++ b/sd/source/ui/slideshow/slideshowimpl.hxx @@ -227,6 +227,14 @@ private: const css::uno::Reference< css::animations::XAnimationNode >& xAnimationNode, vcl::Window* pParent ); + // methods for InterActiveSlideShow that support to + // re-use a running FullScreen presentation for previews IASS + void startInteractivePreview( + const css::uno::Reference< css::drawing::XDrawPage >& xDrawPage, + const css::uno::Reference< css::animations::XAnimationNode >& xAnimationNode); + void endInteractivePreview(); + bool isInteractiveSetup() const; + /** forces an async call to update in the main thread */ void startUpdateTimer(); @@ -317,6 +325,7 @@ private: VclPtr< ::sd::Window> mpOldActiveWindow; Link<StarBASIC*,bool> maStarBASICGlobalErrorHdl; ::tools::ULong mnChildMask; + bool mbDisposed; bool mbAutoSaveWasOn; bool mbRehearseTimings; @@ -348,6 +357,16 @@ private: css::uno::Reference< css::presentation::XPresentation2 > mxPresentation; ::rtl::Reference< SlideShowListenerProxy > mxListenerProxy; + + // local variables to support preview for a running SlideShow IASS + css::uno::Reference< css::presentation::XSlideShow > mxShow2; + rtl::Reference<sd::SlideShowView> mxView2; + AnimationMode meAnimationMode2; + bool mbInterActiveSetup; + PresentationSettings maPresSettings2; + css::uno::Reference< css::drawing::XDrawPage > mxPreviewDrawPage2; + css::uno::Reference< css::animations::XAnimationNode > mxPreviewAnimationNode2; + ::sal_Int32 mnSlideIndex; }; } // namespace ::sd commit 74cefffcfa0fde9ef2a541a46aa47845d1582bf9 Author: Armin Le Grand (allotropia) <armin.le.grand.ext...@allotropia.de> AuthorDate: Fri Feb 16 17:01:39 2024 +0100 Commit: Thorsten Behrens <thorsten.behr...@allotropia.de> CommitDate: Fri Feb 23 10:44:00 2024 +0100 IASS: Preparations for InterActiveSlideShow The idea is a long wanted feature, to allow the EditView to stay active during a running Presentation so that you can do changes which then directly show up in the running presentation. This will need quite some steps. To be on the safe side all of the changes are isolated by a variable to cause no harm. For now this uses ENVVAR ENABLE_INTERACTIVE_SLIDESHOW, but that may change e.g. as config entry or option. Change-Id: Id0ab9a473603225456206fbd933e932248681509 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/163514 Tested-by: Jenkins Reviewed-by: Armin Le Grand <armin.le.gr...@me.com> diff --git a/sd/source/ui/accessibility/AccessibleDrawDocumentView.cxx b/sd/source/ui/accessibility/AccessibleDrawDocumentView.cxx index 82f692bb272a..35f70a079c94 100644 --- a/sd/source/ui/accessibility/AccessibleDrawDocumentView.cxx +++ b/sd/source/ui/accessibility/AccessibleDrawDocumentView.cxx @@ -338,7 +338,8 @@ void SAL_CALL //mpChildrenManager->SetShapeList (uno::Reference<drawing::XShapes> ( // xView->getCurrentPage(), uno::UNO_QUERY)); rtl::Reference< sd::SlideShow > xSlideshow( sd::SlideShow::GetSlideShow( mpSdViewSh->GetViewShellBase() ) ); - if( xSlideshow.is() && xSlideshow->isRunning() && xSlideshow->isFullScreen() ) + if( xSlideshow.is() && (xSlideshow->isRunning() && !sd::SlideShow::IsInteractiveSlideshow()) //IASS + && xSlideshow->isFullScreen() ) { css::uno::Reference< drawing::XDrawPage > xSlide; // MT IA2: Not used... diff --git a/sd/source/ui/app/sdmod1.cxx b/sd/source/ui/app/sdmod1.cxx index eeaa12166bb1..1d19eb6e9204 100644 --- a/sd/source/ui/app/sdmod1.cxx +++ b/sd/source/ui/app/sdmod1.cxx @@ -196,7 +196,7 @@ void SdModule::Execute(SfxRequest& rReq) ::sd::ViewShell* pViewShell = pDocShell ? pDocShell->GetViewShell() : nullptr; if (pViewShell) { - if( sd::SlideShow::IsRunning( pViewShell->GetViewShellBase() ) ) + if( sd::SlideShow::IsRunning( pViewShell->GetViewShellBase() ) && !sd::SlideShow::IsInteractiveSlideshow() ) // IASS { // Prevent documents from opening while the slide // show is running, except when this request comes diff --git a/sd/source/ui/dlg/navigatr.cxx b/sd/source/ui/dlg/navigatr.cxx index ca6bc100cad9..b5183a9fc1fb 100644 --- a/sd/source/ui/dlg/navigatr.cxx +++ b/sd/source/ui/dlg/navigatr.cxx @@ -187,7 +187,7 @@ void SdNavigatorWin::InitTreeLB( const SdDrawDocument* pDoc ) // Disable the shape filter drop down menu when there is a running slide // show. - if (pViewShell!=nullptr && sd::SlideShow::IsRunning( pViewShell->GetViewShellBase() )) + if (pViewShell!=nullptr && sd::SlideShow::IsRunning( pViewShell->GetViewShellBase() ) && !sd::SlideShow::IsInteractiveSlideshow() ) // IASS mxToolbox->set_item_sensitive("shapes", false); else mxToolbox->set_item_sensitive("shapes", true); diff --git a/sd/source/ui/docshell/docshel3.cxx b/sd/source/ui/docshell/docshel3.cxx index be045818a67a..bc60da435d36 100644 --- a/sd/source/ui/docshell/docshel3.cxx +++ b/sd/source/ui/docshell/docshel3.cxx @@ -133,7 +133,7 @@ static void lcl_setLanguage( const SdDrawDocument *pDoc, std::u16string_view rLa */ void DrawDocShell::Execute( SfxRequest& rReq ) { - if(mpViewShell && SlideShow::IsRunning( mpViewShell->GetViewShellBase() )) + if(mpViewShell && SlideShow::IsRunning( mpViewShell->GetViewShellBase() ) && !SlideShow::IsInteractiveSlideshow() ) // IASS { // during a running presentation no slot will be executed return; diff --git a/sd/source/ui/func/funavig.cxx b/sd/source/ui/func/funavig.cxx index bd0cdb7c3336..3e1861645461 100644 --- a/sd/source/ui/func/funavig.cxx +++ b/sd/source/ui/func/funavig.cxx @@ -51,7 +51,7 @@ rtl::Reference<FuPoor> FuNavigation::Create( ViewShell* pViewSh, ::sd::Window* p void FuNavigation::DoExecute( SfxRequest& rReq ) { - bool bSlideShow = SlideShow::IsRunning( mpViewShell->GetViewShellBase() ); + bool bSlideShow = SlideShow::IsRunning( mpViewShell->GetViewShellBase() ) && !SlideShow::IsInteractiveSlideshow(); // IASS switch ( rReq.GetSlot() ) { diff --git a/sd/source/ui/func/fupoor.cxx b/sd/source/ui/func/fupoor.cxx index c75959fbc243..3b0934a9fe1b 100644 --- a/sd/source/ui/func/fupoor.cxx +++ b/sd/source/ui/func/fupoor.cxx @@ -123,7 +123,7 @@ void FuPoor::ForceScroll(const Point& aPixPos) aScrollTimer.Stop(); if ( mpView->IsDragHelpLine() || mpView->IsSetPageOrg() || - SlideShow::IsRunning( mpViewShell->GetViewShellBase() ) ) + (SlideShow::IsRunning( mpViewShell->GetViewShellBase() ) && !SlideShow::IsInteractiveSlideshow()) ) // IASS return; Point aPos = mpWindow->OutputToScreenPixel(aPixPos); @@ -176,7 +176,7 @@ bool FuPoor::KeyInput(const KeyEvent& rKEvt) { sal_uInt16 nCode = rKEvt.GetKeyCode().GetCode(); bool bReturn = false; - bool bSlideShow = SlideShow::IsRunning( mpViewShell->GetViewShellBase() ); + bool bSlideShow = SlideShow::IsRunning( mpViewShell->GetViewShellBase() ) && !SlideShow::IsInteractiveSlideshow(); // IASS switch (nCode) { diff --git a/sd/source/ui/inc/slideshow.hxx b/sd/source/ui/inc/slideshow.hxx index afbfee68469b..81af4a52f4ee 100644 --- a/sd/source/ui/inc/slideshow.hxx +++ b/sd/source/ui/inc/slideshow.hxx @@ -101,6 +101,9 @@ public: /// returns false even if there is a running presentation but in another ViewShell static bool IsRunning( const ViewShell& rViewShell ); + /// returns true if the interactive slideshow mode is activated + static bool IsInteractiveSlideshow(); + // helper api void startPreview( diff --git a/sd/source/ui/slideshow/slideshow.cxx b/sd/source/ui/slideshow/slideshow.cxx index 348bc606b800..a7b335e59fc9 100644 --- a/sd/source/ui/slideshow/slideshow.cxx +++ b/sd/source/ui/slideshow/slideshow.cxx @@ -217,6 +217,13 @@ bool SlideShow::IsRunning( const ViewShell& rViewShell ) return xSlideShow.is() && xSlideShow->isRunning() && (xSlideShow->mxController->getViewShell() == &rViewShell); } +/// returns true if the interactive slideshow mode is activated +bool SlideShow::IsInteractiveSlideshow() +{ + static bool g_bEnable_Interactive_Slideshow(getenv("ENABLE_INTERACTIVE_SLIDESHOW")); + return g_bEnable_Interactive_Slideshow; +} + void SlideShow::CreateController( ViewShell* pViewSh, ::sd::View* pView, vcl::Window* pParentWindow ) { SAL_INFO_IF( !mxController.is(), "sd.slideshow", "sd::SlideShow::CreateController(), clean up old controller first!" ); diff --git a/sd/source/ui/slideshow/slideshowimpl.cxx b/sd/source/ui/slideshow/slideshowimpl.cxx index 8cfd7632fd58..37d6e861e02d 100644 --- a/sd/source/ui/slideshow/slideshowimpl.cxx +++ b/sd/source/ui/slideshow/slideshowimpl.cxx @@ -948,7 +948,7 @@ bool SlideshowImpl::startShow( PresentationSettingsEx const * pPresSettings ) mpPaneHider.reset(new PaneHider(*mpViewShell,this)); // these Slots are forbidden in other views for this document - if( mpDocSh ) + if( mpDocSh && !SlideShow::IsInteractiveSlideshow()) // IASS { mpDocSh->SetSlotFilter( true, pAllowed ); mpDocSh->ApplySlotFilter(); diff --git a/sd/source/ui/view/drawview.cxx b/sd/source/ui/view/drawview.cxx index bd454bec194b..e70de30f2194 100644 --- a/sd/source/ui/view/drawview.cxx +++ b/sd/source/ui/view/drawview.cxx @@ -509,7 +509,8 @@ void DrawView::CompleteRedraw(OutputDevice* pOutDev, const vcl::Region& rReg, sd { if( pShowWindow == pOutDev && mpViewSh ) xSlideshow->paint(); - return; + if (!SlideShow::IsInteractiveSlideshow()) // IASS + return; } } } diff --git a/sd/source/ui/view/drviews1.cxx b/sd/source/ui/view/drviews1.cxx index bff9f67872bd..067d5fc65788 100644 --- a/sd/source/ui/view/drviews1.cxx +++ b/sd/source/ui/view/drviews1.cxx @@ -1332,7 +1332,7 @@ sal_Int8 DrawViewShell::AcceptDrop ( sal_uInt16 /*nPage*/, SdrLayerID nLayer ) { - if( SlideShow::IsRunning( GetViewShellBase() ) ) + if( SlideShow::IsRunning( GetViewShellBase() ) && !SlideShow::IsInteractiveSlideshow() ) // IASS return DND_ACTION_NONE; return mpDrawView->AcceptDrop( rEvt, rTargetHelper, nLayer ); @@ -1352,7 +1352,7 @@ sal_Int8 DrawViewShell::ExecuteDrop ( if( nPage != SDRPAGE_NOTFOUND ) nPage = GetDoc()->GetSdPage( nPage, mePageKind )->GetPageNum(); - if( SlideShow::IsRunning( GetViewShellBase() ) ) + if( SlideShow::IsRunning( GetViewShellBase() ) && !SlideShow::IsInteractiveSlideshow()) // IASS return DND_ACTION_NONE; Broadcast(ViewShellHint(ViewShellHint::HINT_COMPLEX_MODEL_CHANGE_START)); diff --git a/sd/source/ui/view/drviews2.cxx b/sd/source/ui/view/drviews2.cxx index 7dc9e98a167f..b3a7d16da693 100644 --- a/sd/source/ui/view/drviews2.cxx +++ b/sd/source/ui/view/drviews2.cxx @@ -606,7 +606,9 @@ public: void DrawViewShell::FuTemporary(SfxRequest& rReq) { // during a native slide show nothing gets executed! - if(SlideShow::IsRunning( GetViewShellBase() ) && (rReq.GetSlot() != SID_NAVIGATOR)) + if(SlideShow::IsRunning( GetViewShellBase() ) + && !SlideShow::IsInteractiveSlideshow() // IASS + && (rReq.GetSlot() != SID_NAVIGATOR)) return; DBG_ASSERT( mpDrawView, "sd::DrawViewShell::FuTemporary(), no draw view!" ); @@ -3928,7 +3930,7 @@ void DrawViewShell::DuplicateSelectedSlides (SfxRequest& rRequest) void DrawViewShell::ExecutePropPanelAttr (SfxRequest const & rReq) { - if(SlideShow::IsRunning( GetViewShellBase() )) + if(SlideShow::IsRunning( GetViewShellBase() ) && !SlideShow::IsInteractiveSlideshow()) // IASS return; SdDrawDocument* pDoc = GetDoc(); diff --git a/sd/source/ui/view/drviews3.cxx b/sd/source/ui/view/drviews3.cxx index 2a3b778531c1..3eb669633806 100644 --- a/sd/source/ui/view/drviews3.cxx +++ b/sd/source/ui/view/drviews3.cxx @@ -138,7 +138,9 @@ void DrawViewShell::ExecCtrl(SfxRequest& rReq) case SID_SWITCHPAGE: // BASIC { // switch page in running slide show - if(SlideShow::IsRunning(GetViewShellBase()) && rReq.GetArgs()) + if(SlideShow::IsRunning(GetViewShellBase()) + && !SlideShow::IsInteractiveSlideshow() // IASS + && rReq.GetArgs()) { if (const SfxUInt32Item* pWhatPage = rReq.GetArg<SfxUInt32Item>(ID_VAL_WHATPAGE)) SlideShow::GetSlideShow(GetViewShellBase())->jumpToPageNumber(static_cast<sal_Int32>((pWhatPage->GetValue()-1)>>1)); diff --git a/sd/source/ui/view/drviews4.cxx b/sd/source/ui/view/drviews4.cxx index 8919a52d380f..bc389c069a34 100644 --- a/sd/source/ui/view/drviews4.cxx +++ b/sd/source/ui/view/drviews4.cxx @@ -530,7 +530,7 @@ void DrawViewShell::Command(const CommandEvent& rCEvt, ::sd::Window* pWin) if( GetView() &&GetView()->getSmartTags().Command(rCEvt) ) return; - const bool bNativeShow (SlideShow::IsRunning(GetViewShellBase())); + const bool bNativeShow (SlideShow::IsRunning(GetViewShellBase()) && !SlideShow::IsInteractiveSlideshow()); // IASS if( rCEvt.GetCommand() == CommandEventId::PasteSelection && !bNativeShow ) { diff --git a/sd/source/ui/view/drviews7.cxx b/sd/source/ui/view/drviews7.cxx index 04af475681f3..1852cdbc2290 100644 --- a/sd/source/ui/view/drviews7.cxx +++ b/sd/source/ui/view/drviews7.cxx @@ -1297,7 +1297,8 @@ void DrawViewShell::GetMenuState( SfxItemSet &rSet ) } rtl::Reference< sd::SlideShow > xSlideshow( SlideShow::GetSlideShow( GetViewShellBase() ) ); - if( (xSlideshow.is() && xSlideshow->isRunning() && (xSlideshow->getAnimationMode() != ANIMATIONMODE_PREVIEW) ) || GetDocSh()->IsPreview() ) + if( (xSlideshow.is() && xSlideshow->isRunning() && !SlideShow::IsInteractiveSlideshow() // IASS + && (xSlideshow->getAnimationMode() != ANIMATIONMODE_PREVIEW) ) || GetDocSh()->IsPreview() ) { // Own Slots rSet.DisableItem( SID_PRESENTATION ); @@ -1320,7 +1321,7 @@ void DrawViewShell::GetMenuState( SfxItemSet &rSet ) rSet.DisableItem( SID_DELETE_PAGE ); rSet.DisableItem( SID_PAGESETUP ); - if( xSlideshow.is() && xSlideshow->isRunning() ) + if( xSlideshow.is() && xSlideshow->isRunning() && !SlideShow::IsInteractiveSlideshow() ) // IASS { rSet.ClearItem(SID_INSERTFILE); rSet.ClearItem(SID_OBJECT_ROTATE); @@ -1648,7 +1649,7 @@ void DrawViewShell::GetModeSwitchingMenuState (SfxItemSet &rSet) // clause because the current function of the docshell can only be // search and replace or spell checking and in that case switching the // view mode is allowed. - const bool bIsRunning = SlideShow::IsRunning(GetViewShellBase()); + const bool bIsRunning = SlideShow::IsRunning(GetViewShellBase()) && !SlideShow::IsInteractiveSlideshow(); // IASS if (GetViewFrame()->GetFrame().IsInPlace() || bIsRunning) { @@ -1940,7 +1941,7 @@ void DrawViewShell::GetState (SfxItemSet& rSet) void DrawViewShell::Execute (SfxRequest& rReq) { - if(SlideShow::IsRunning(GetViewShellBase())) + if(SlideShow::IsRunning(GetViewShellBase()) && !SlideShow::IsInteractiveSlideshow()) // IASS { // Do not execute anything during a native slide show. return; diff --git a/sd/source/ui/view/drviewsa.cxx b/sd/source/ui/view/drviewsa.cxx index 2868c38d6c90..6bb62eaaea31 100644 --- a/sd/source/ui/view/drviewsa.cxx +++ b/sd/source/ui/view/drviewsa.cxx @@ -357,7 +357,7 @@ void DrawViewShell::Shutdown() { ViewShell::Shutdown(); - if(SlideShow::IsRunning( GetViewShellBase() ) ) + if(SlideShow::IsRunning( GetViewShellBase() ) && !SlideShow::IsInteractiveSlideshow()) // IASS { // Turn off effects. GetDrawView()->SetAnimationMode(SdrAnimationMode::Disable); @@ -537,7 +537,8 @@ void DrawViewShell::GetStatusBarState(SfxItemSet& rSet) or page) with the help of the ZoomItems !!! */ if( SfxItemState::DEFAULT == rSet.GetItemState( SID_ATTR_ZOOM ) ) { - if (GetDocSh()->IsUIActive() || SlideShow::IsRunning(GetViewShellBase()) + if (GetDocSh()->IsUIActive() + || (SlideShow::IsRunning(GetViewShellBase()) && !SlideShow::IsInteractiveSlideshow()) // IASS || !GetActiveWindow()) { rSet.DisableItem( SID_ATTR_ZOOM ); @@ -568,7 +569,9 @@ void DrawViewShell::GetStatusBarState(SfxItemSet& rSet) if( SfxItemState::DEFAULT == rSet.GetItemState( SID_ATTR_ZOOMSLIDER ) ) { rtl::Reference< sd::SlideShow > xSlideshow( SlideShow::GetSlideShow( GetDoc() ) ); - if (GetDocSh()->IsUIActive() || (xSlideshow.is() && xSlideshow->isRunning()) || !GetActiveWindow() ) + if (GetDocSh()->IsUIActive() + || (xSlideshow.is() && xSlideshow->isRunning() && !SlideShow::IsInteractiveSlideshow()) // IASS + || !GetActiveWindow() ) { rSet.DisableItem( SID_ATTR_ZOOMSLIDER ); } diff --git a/sd/source/ui/view/drviewse.cxx b/sd/source/ui/view/drviewse.cxx index 5c74a0f50b10..537bde162641 100644 --- a/sd/source/ui/view/drviewse.cxx +++ b/sd/source/ui/view/drviewse.cxx @@ -142,7 +142,7 @@ void DrawViewShell::FuPermanent(SfxRequest& rReq) { // We do not execute a thing during a native slide show - if (SlideShow::IsRunning(GetViewShellBase())) + if (SlideShow::IsRunning(GetViewShellBase()) && !SlideShow::IsInteractiveSlideshow()) // IASS return; sal_uInt16 nSId = rReq.GetSlot(); @@ -738,9 +738,9 @@ void DrawViewShell::FuSupport(SfxRequest& rReq) GetDocSh()->SetStyleFamily(static_cast<SfxStyleFamily>(rReq.GetArgs()->Get( SID_STYLE_FAMILY ).GetValue())); // We do not execute a thing during a native slide show - if(SlideShow::IsRunning(GetViewShellBase()) && - (rReq.GetSlot() != SID_PRESENTATION_END && - rReq.GetSlot() != SID_SIZE_PAGE)) + if((SlideShow::IsRunning(GetViewShellBase()) + && !SlideShow::IsInteractiveSlideshow()) // IASS + && (rReq.GetSlot() != SID_PRESENTATION_END && rReq.GetSlot() != SID_SIZE_PAGE)) return; CheckLineTo (rReq); diff --git a/sd/source/ui/view/drviewsh.cxx b/sd/source/ui/view/drviewsh.cxx index f323497ac46f..d421a76163a8 100644 --- a/sd/source/ui/view/drviewsh.cxx +++ b/sd/source/ui/view/drviewsh.cxx @@ -47,7 +47,10 @@ void DrawViewShell::GotoBookmark(std::u16string_view rBookmark) void DrawViewShell::MakeVisible(const ::tools::Rectangle& rRect, vcl::Window& rWin) { - if ( (IsMouseButtonDown() && !IsMouseSelecting()) || SlideShow::IsRunning( GetViewShellBase() ) ) + if ( IsMouseButtonDown() && !IsMouseSelecting() ) + return; + + if ( SlideShow::IsRunning( GetViewShellBase() ) && !SlideShow::IsInteractiveSlideshow() ) // IASS return; // tdf#98646 check if Rectangle which contains the bounds of the region to diff --git a/sd/source/ui/view/sdview2.cxx b/sd/source/ui/view/sdview2.cxx index af76e39afd4b..64c2b47ec30c 100644 --- a/sd/source/ui/view/sdview2.cxx +++ b/sd/source/ui/view/sdview2.cxx @@ -577,7 +577,8 @@ sal_Int8 View::AcceptDrop( const AcceptDropEvent& rEvt, DropTargetHelper& rTarge mpDropMarkerObj = nullptr; } - if( bBookmark && bFile && ( nDropAction & DND_ACTION_MOVE ) && mpViewSh && SlideShow::IsRunning(mpViewSh->GetViewShellBase()) ) + if( bBookmark && bFile && ( nDropAction & DND_ACTION_MOVE ) && mpViewSh + && ( SlideShow::IsRunning(mpViewSh->GetViewShellBase()) && !SlideShow::IsInteractiveSlideshow() )) // IASS bBookmark = false; if( bDrawing || bGraphic || bMtf || bBitmap || bBookmark || bFile || bFileList || bXFillExchange || bSBAFormat || bEditEngineODF || bString || bRTF ) diff --git a/sd/source/ui/view/viewshel.cxx b/sd/source/ui/view/viewshel.cxx index 8a7d6f482c82..a93dd362d34e 100644 --- a/sd/source/ui/view/viewshel.cxx +++ b/sd/source/ui/view/viewshel.cxx @@ -316,7 +316,7 @@ void ViewShell::Activate(bool bIsMDIActivate) rBindings.Invalidate( SID_3D_STATE, true ); rtl::Reference< SlideShow > xSlideShow( SlideShow::GetSlideShow( GetViewShellBase() ) ); - if (xSlideShow.is() && xSlideShow->isRunning()) + if (xSlideShow.is() && xSlideShow->isRunning()) //IASS { bool bSuccess = xSlideShow->activate(GetViewShellBase()); assert(bSuccess && "can only return false with a PresentationViewShell"); (void)bSuccess; @@ -368,7 +368,7 @@ void ViewShell::Deactivate(bool bIsMDIActivate) if (bIsMDIActivate) { rtl::Reference< SlideShow > xSlideShow( SlideShow::GetSlideShow( GetViewShellBase() ) ); - if(xSlideShow.is() && xSlideShow->isRunning() ) + if(xSlideShow.is() && xSlideShow->isRunning() ) //IASS xSlideShow->deactivate(); if(HasCurrentFunction()) @@ -404,7 +404,18 @@ bool ViewShell::KeyInput(const KeyEvent& rKEvt, ::sd::Window* pWin) if(!bReturn) { rtl::Reference< SlideShow > xSlideShow( SlideShow::GetSlideShow( GetViewShellBase() ) ); - if(xSlideShow.is() && xSlideShow->isRunning()) + const bool bSlideShowRunning(xSlideShow.is() && xSlideShow->isRunning()); + bool bUseForSlideShow(bSlideShowRunning); + + if(bSlideShowRunning && SlideShow::IsInteractiveSlideshow()) + { + // IASS + OutputDevice* pShOut(xSlideShow->getShowWindow()); + vcl::Window* pShWin(pShOut ? pShOut->GetOwnerWindow() : nullptr); + bUseForSlideShow = pShWin && pShWin->HasFocus(); + } + + if(bUseForSlideShow) //IASS { bReturn = xSlideShow->keyInput(rKEvt); } @@ -809,7 +820,10 @@ bool ViewShell::HandleScrollCommand(const CommandEvent& rCEvt, ::sd::Window* pWi void ViewShell::SetupRulers() { - if(!mbHasRulers || !mpContentWindow || SlideShow::IsRunning(GetViewShellBase())) + if(!mbHasRulers || !mpContentWindow ) + return; + + if( SlideShow::IsRunning(GetViewShellBase()) && !SlideShow::IsInteractiveSlideshow()) // IASS return; ::tools::Long nHRulerOfs = 0; @@ -1026,7 +1040,8 @@ void ViewShell::ArrangeGUIElements() // The size of the window of the center pane is set differently from // that of the windows in the docking windows. - bool bSlideShowActive = (xSlideShow.is() && xSlideShow->isRunning()) && !xSlideShow->isFullScreen() && xSlideShow->getAnimationMode() == ANIMATIONMODE_SHOW; + bool bSlideShowActive = (xSlideShow.is() && xSlideShow->isRunning()) //IASS + && !xSlideShow->isFullScreen() && xSlideShow->getAnimationMode() == ANIMATIONMODE_SHOW; if ( !bSlideShowActive) { OSL_ASSERT (GetViewShell()!=nullptr); commit bd1e303cee5d152c53f52008238c807a6b7349a0 Author: Armin Le Grand (allotropia) <armin.le.grand.ext...@allotropia.de> AuthorDate: Thu Jan 11 14:22:32 2024 +0100 Commit: Thorsten Behrens <thorsten.behr...@allotropia.de> CommitDate: Fri Feb 23 10:43:44 2024 +0100 tdf#158664 Ignore Notifications when SlideShow is inactive The impl SlideshowImpl gets notifications for changes from the ObjectModel, but needs to ignore them when SlideShow is not active/running. For discussion how to do this see comments in task. Change-Id: Ic251af4b82f0f4b48d8d9b0127dd2f6015966935 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/161922 Tested-by: Jenkins Reviewed-by: Armin Le Grand <armin.le.gr...@me.com> diff --git a/sd/source/ui/slideshow/slideshowimpl.cxx b/sd/source/ui/slideshow/slideshowimpl.cxx index 5d5004a90596..8cfd7632fd58 100644 --- a/sd/source/ui/slideshow/slideshowimpl.cxx +++ b/sd/source/ui/slideshow/slideshowimpl.cxx @@ -3164,6 +3164,14 @@ void SlideshowImpl::Notify(SfxBroadcaster& /*rBC*/, const SfxHint& rHint) // better do nothing when no DrawModel (should not happen) return; + // tdf#158664 I am surprised, but the 'this' instance keeps incarnated + // when the slideshow was running once, so need to check for + // SlideShow instance/running to be safe. + // NOTE: isRunning() checks mxShow.is(), that is what we want + if (!isRunning()) + // no SlideShow instance or not running, nothing to do + return; + const SdrHintKind eHintKind(static_cast<const SdrHint&>(rHint).GetKind()); if (SdrHintKind::ObjectChange == eHintKind) commit 14251b828dcaeee47bdd7e7d7349a1a6a4e8e177 Author: Armin Le Grand (allotropia) <armin.le.grand.ext...@allotropia.de> AuthorDate: Fri Nov 24 16:02:17 2023 +0100 Commit: Thorsten Behrens <thorsten.behr...@allotropia.de> CommitDate: Fri Feb 23 10:37:20 2024 +0100 Update SlideShow on DrawModel changes II Change-Id: Idfbbb7744cc7b2182647b45f509399535a2d4df2 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/159930 Tested-by: Jenkins Reviewed-by: Armin Le Grand <armin.le.gr...@me.com> diff --git a/sd/source/ui/slideshow/slideshowimpl.cxx b/sd/source/ui/slideshow/slideshowimpl.cxx index 245aaa7efd9d..5d5004a90596 100644 --- a/sd/source/ui/slideshow/slideshowimpl.cxx +++ b/sd/source/ui/slideshow/slideshowimpl.cxx @@ -515,6 +515,8 @@ SlideshowImpl::SlideshowImpl( const Reference< XPresentation2 >& xPresentation, , mdUserPaintStrokeWidth ( 150.0 ) , mnEndShowEvent(nullptr) , mnContextMenuEvent(nullptr) +, mnEventObjectChange(nullptr) +, mnEventPageOrderChange(nullptr) , mxPresentation( xPresentation ) { if( mpViewShell ) @@ -596,6 +598,10 @@ void SlideshowImpl::disposing(std::unique_lock<std::mutex>&) Application::RemoveUserEvent( mnEndShowEvent ); if( mnContextMenuEvent ) Application::RemoveUserEvent( mnContextMenuEvent ); + if( mnEventObjectChange ) + Application::RemoveUserEvent( mnEventObjectChange ); + if( mnEventPageOrderChange ) + Application::RemoveUserEvent( mnEventPageOrderChange ); maInputFreezeTimer.Stop(); @@ -3068,16 +3074,19 @@ namespace { SlideshowImpl* pSlideshowImpl; uno::Reference< css::drawing::XDrawPage > XCurrentSlide; + SdrHintKind eHintKind; }; - static void AsyncUpdateSlideshow( + static ImplSVEvent* AsyncUpdateSlideshow( SlideshowImpl* pSlideshowImpl, - uno::Reference< css::drawing::XDrawPage >& rXCurrentSlide) + uno::Reference< css::drawing::XDrawPage >& rXCurrentSlide, + SdrHintKind eHintKind) { AsyncUpdateSlideshowData* pNew(new AsyncUpdateSlideshowData); pNew->pSlideshowImpl = pSlideshowImpl; pNew->XCurrentSlide = rXCurrentSlide; - Application::PostUserEvent(LINK(nullptr, AsyncUpdateSlideshow_Impl, Update), pNew); + pNew->eHintKind = eHintKind; + return Application::PostUserEvent(LINK(nullptr, AsyncUpdateSlideshow_Impl, Update), pNew); // coverity[leaked_storage] - pDisruptor takes care of its own destruction at idle time } @@ -3087,11 +3096,64 @@ namespace IMPL_STATIC_LINK(AsyncUpdateSlideshow_Impl, Update, void*, pData, void) { AsyncUpdateSlideshowData* pSlideData(static_cast<AsyncUpdateSlideshowData*>(pData)); - pSlideData->pSlideshowImpl->gotoSlide(pSlideData->XCurrentSlide); + pSlideData->pSlideshowImpl->AsyncNotifyEvent(pSlideData->XCurrentSlide, pSlideData->eHintKind); delete pSlideData; } } +void SlideshowImpl::AsyncNotifyEvent( + const uno::Reference< css::drawing::XDrawPage >& rXCurrentSlide, + const SdrHintKind eHintKind) +{ + if (SdrHintKind::ObjectChange == eHintKind) + { + mnEventObjectChange = nullptr; + + // refresh single slide + gotoSlide(rXCurrentSlide); + } + else if (SdrHintKind::PageOrderChange == eHintKind) + { + mnEventPageOrderChange = nullptr; + + // order of pages (object pages or master pages) changed (Insert/Remove/ChangePos) + // rXCurrentSlide is the current slide before the change. + Reference< XDrawPagesSupplier > xDrawPages( mpDoc->getUnoModel(), UNO_QUERY_THROW ); + Reference< XIndexAccess > xSlides( xDrawPages->getDrawPages(), UNO_QUERY_THROW ); + const sal_Int32 nNewSlideCount(xSlides.is() ? xSlides->getCount() : 0); + + if (nNewSlideCount != mpSlideController->getSlideNumberCount()) + { + // need to reinitialize AnimationSlideController + OUString aPresSlide( maPresSettings.maPresPage ); + createSlideList( maPresSettings.mbAll, aPresSlide ); + } + + // Check if current slide before change is still valid (maybe removed) + const sal_Int32 nSlideCount(mpSlideController->getSlideNumberCount()); + bool bSlideStillValid(false); + + for (sal_Int32 nSlide(0); !bSlideStillValid && nSlide < nSlideCount; nSlide++) + { + if (rXCurrentSlide == mpSlideController->getSlideByNumber(nSlide)) + { + bSlideStillValid = true; + } + } + + if(bSlideStillValid) + { + // stay on that slide + gotoSlide(rXCurrentSlide); + } + else + { + // not possible to stay on that slide, go to 1st slide (kinda restart) + gotoFirstSlide(); + } + } +} + void SlideshowImpl::Notify(SfxBroadcaster& /*rBC*/, const SfxHint& rHint) { if (SfxHintId::ThisIsAnSdrHint != rHint.GetId()) @@ -3106,6 +3168,10 @@ void SlideshowImpl::Notify(SfxBroadcaster& /*rBC*/, const SfxHint& rHint) if (SdrHintKind::ObjectChange == eHintKind) { + if (nullptr != mnEventObjectChange) + // avoid multiple events + return; + // Object changed, object & involved page included in rHint. uno::Reference< css::drawing::XDrawPage > XCurrentSlide(getCurrentSlide()); if (!XCurrentSlide.is()) @@ -3143,13 +3209,27 @@ void SlideshowImpl::Notify(SfxBroadcaster& /*rBC*/, const SfxHint& rHint) // text edit changes EditEngine/Outliner are not progressed far // enough (ObjectChanged broadcast which we are in here seems // to early for some cases) - AsyncUpdateSlideshow_Impl::AsyncUpdateSlideshow(this, XCurrentSlide); + mnEventObjectChange = AsyncUpdateSlideshow_Impl::AsyncUpdateSlideshow(this, XCurrentSlide, eHintKind); } else if (SdrHintKind::PageOrderChange == eHintKind) { + // Unfortunately we get multiple events, e.g. when drag/drop position change in + // slide sorter on left side of EditView. This includes some with page number +1, + // then again -1 (it's a position change). Problem is that in-between already + // a re-schedule seems to happen, so indeed AsyncNotifyEvent will change to +1/-1 + // already. Since we get even more, at least try to take the last one. I found no + // good solution yet for this. + if (nullptr != mnEventPageOrderChange) + Application::RemoveUserEvent( mnEventPageOrderChange ); + // order of pages (object pages or master pages) changed (Insert/Remove/ChangePos) - // probably needs refresh of AnimationSlideController in mpSlideController - gotoFirstSlide(); + uno::Reference< css::drawing::XDrawPage > XCurrentSlide(getCurrentSlide()); + mnEventPageOrderChange = AsyncUpdateSlideshow_Impl::AsyncUpdateSlideshow(this, XCurrentSlide, eHintKind); + } + else if (SdrHintKind::ModelCleared == eHintKind) + { + // immediately end presentation + endPresentation(); } // maybe need to add reactions here to other Hint-Types diff --git a/sd/source/ui/slideshow/slideshowimpl.hxx b/sd/source/ui/slideshow/slideshowimpl.hxx index b235a78358f0..9c0ae75dd5e9 100644 --- a/sd/source/ui/slideshow/slideshowimpl.hxx +++ b/sd/source/ui/slideshow/slideshowimpl.hxx @@ -198,6 +198,10 @@ public: /// ends the presentation async void endPresentation(); + // possibly triggered from events @SlideshowImpl::Notify if needed, but asychron to + // allow the noted event to completely finish in the core + void AsyncNotifyEvent(const css::uno::Reference< css::drawing::XDrawPage >&, const SdrHintKind); + ViewShell* getViewShell() const { return mpViewShell; } void paint(); @@ -339,6 +343,8 @@ private: ImplSVEvent * mnEndShowEvent; ImplSVEvent * mnContextMenuEvent; + ImplSVEvent * mnEventObjectChange; + ImplSVEvent * mnEventPageOrderChange; css::uno::Reference< css::presentation::XPresentation2 > mxPresentation; ::rtl::Reference< SlideShowListenerProxy > mxListenerProxy; commit a2fec14e75bb8d52185c6ac1db8eedeaec2205c3 Author: Armin Le Grand (allotropia) <armin.le.grand.ext...@allotropia.de> AuthorDate: Wed Nov 15 15:23:20 2023 +0100 Commit: Thorsten Behrens <thorsten.behr...@allotropia.de> CommitDate: Fri Feb 23 10:34:07 2024 +0100 Update SlideShow on DrawModel changes It may happen that DrawModel changes while a SlideShow is running, e.g. from EditView/Scripts/UNO API. We can try to suppress these as we already try with EditView in that mode. As an alternative it is also possible to react to these changes in the SLideShow in a useful manner. This is the 2nd try, main change is to do all of this directly in SlideShow, so no chechs/tests in common code are needed. Change-Id: Iaa393d78af1fc40003c83d896508abe31cd790d5 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/159447 Tested-by: Jenkins Reviewed-by: Armin Le Grand <armin.le.gr...@me.com> diff --git a/sd/source/ui/slideshow/slideshowimpl.cxx b/sd/source/ui/slideshow/slideshowimpl.cxx index a9f16b86b8d4..245aaa7efd9d 100644 --- a/sd/source/ui/slideshow/slideshowimpl.cxx +++ b/sd/source/ui/slideshow/slideshowimpl.cxx @@ -59,6 +59,7 @@ #include <svx/srchdlg.hxx> #include <svx/hyperdlg.hxx> #include <svx/svxids.hrc> +#include <svx/unoapi.hxx> #include <AnimationChildWindow.hxx> #include <notifydocumentevent.hxx> #include "slideshowimpl.hxx" @@ -543,10 +544,19 @@ SlideshowImpl::SlideshowImpl( const Reference< XPresentation2 >& xPresentation, mnUserPaintColor = pOptions->GetPresentationPenColor(); mdUserPaintStrokeWidth = pOptions->GetPresentationPenWidth(); } + + // to be able to react on various changes in the DrawModel, this class + // is now derived from SfxListener and registers itself at the DrawModel + if (nullptr != mpDoc) + StartListening(*mpDoc); } SlideshowImpl::~SlideshowImpl() { + // stop listening to DrawModel (see above) + if (nullptr != mpDoc) + EndListening(*mpDoc); + SdModule *pModule = SD_MOD(); //rhbz#806663 SlideshowImpl can outlive SdModule SdOptions* pOptions = pModule ? @@ -3049,6 +3059,102 @@ sal_Bool SAL_CALL SlideshowImpl::hasElements( ) return getSlideCount() != 0; } +namespace +{ + class AsyncUpdateSlideshow_Impl + { + public: + struct AsyncUpdateSlideshowData + { + SlideshowImpl* pSlideshowImpl; + uno::Reference< css::drawing::XDrawPage > XCurrentSlide; + }; + + static void AsyncUpdateSlideshow( + SlideshowImpl* pSlideshowImpl, + uno::Reference< css::drawing::XDrawPage >& rXCurrentSlide) + { + AsyncUpdateSlideshowData* pNew(new AsyncUpdateSlideshowData); + pNew->pSlideshowImpl = pSlideshowImpl; + pNew->XCurrentSlide = rXCurrentSlide; + Application::PostUserEvent(LINK(nullptr, AsyncUpdateSlideshow_Impl, Update), pNew); + // coverity[leaked_storage] - pDisruptor takes care of its own destruction at idle time + } + + DECL_STATIC_LINK(AsyncUpdateSlideshow_Impl, Update, void*, void); + }; + + IMPL_STATIC_LINK(AsyncUpdateSlideshow_Impl, Update, void*, pData, void) + { + AsyncUpdateSlideshowData* pSlideData(static_cast<AsyncUpdateSlideshowData*>(pData)); + pSlideData->pSlideshowImpl->gotoSlide(pSlideData->XCurrentSlide); + delete pSlideData; + } +} + +void SlideshowImpl::Notify(SfxBroadcaster& /*rBC*/, const SfxHint& rHint) +{ + if (SfxHintId::ThisIsAnSdrHint != rHint.GetId()) + // nothing to do for non-SdrHints + return; + + if (nullptr == mpDoc) + // better do nothing when no DrawModel (should not happen) + return; + + const SdrHintKind eHintKind(static_cast<const SdrHint&>(rHint).GetKind()); + + if (SdrHintKind::ObjectChange == eHintKind) + { + // Object changed, object & involved page included in rHint. + uno::Reference< css::drawing::XDrawPage > XCurrentSlide(getCurrentSlide()); + if (!XCurrentSlide.is()) + return; + + SdrPage* pCurrentSlide(GetSdrPageFromXDrawPage(XCurrentSlide)); + if (nullptr == pCurrentSlide) + return; + + const SdrPage* pHintPage(static_cast<const SdrHint&>(rHint).GetPage()); + if (nullptr == pHintPage) + return; + + bool bCurrentSlideIsInvolved(false); + + if (pHintPage->IsMasterPage()) + { + if (pCurrentSlide->TRG_HasMasterPage()) + { + // current slide uses MasterPage on which the change happened + bCurrentSlideIsInvolved = (pHintPage == &pCurrentSlide->TRG_GetMasterPage()); + } + } + else + { + // object on current slide was changed + bCurrentSlideIsInvolved = (pHintPage == pCurrentSlide); + } + + if (!bCurrentSlideIsInvolved) + // nothing to do when current slide is not involved + return; + + // Refresh current slide. Need to do that asynchronous, else e.g. + // text edit changes EditEngine/Outliner are not progressed far + // enough (ObjectChanged broadcast which we are in here seems + // to early for some cases) + AsyncUpdateSlideshow_Impl::AsyncUpdateSlideshow(this, XCurrentSlide); + } + else if (SdrHintKind::PageOrderChange == eHintKind) + { + // order of pages (object pages or master pages) changed (Insert/Remove/ChangePos) + // probably needs refresh of AnimationSlideController in mpSlideController + gotoFirstSlide(); + } + + // maybe need to add reactions here to other Hint-Types +} + Reference< XSlideShow > SAL_CALL SlideshowImpl::getSlideShow() { return mxShow; diff --git a/sd/source/ui/slideshow/slideshowimpl.hxx b/sd/source/ui/slideshow/slideshowimpl.hxx index 48802ba54499..b235a78358f0 100644 --- a/sd/source/ui/slideshow/slideshowimpl.hxx +++ b/sd/source/ui/slideshow/slideshowimpl.hxx @@ -127,7 +127,7 @@ private: typedef comphelper::WeakComponentImplHelper< css::presentation::XSlideShowController, css::container::XIndexAccess > SlideshowImplBase; -class SlideshowImpl final : public SlideshowImplBase +class SlideshowImpl final : public SlideshowImplBase, public SfxListener { friend class SlideShow; friend class SlideShowView; @@ -183,6 +183,9 @@ public: virtual css::uno::Type SAL_CALL getElementType( ) override; virtual sal_Bool SAL_CALL hasElements( ) override; + // SfxListener + virtual void Notify(SfxBroadcaster& rBC, const SfxHint& rHint) override; + // will be called from the SlideShowListenerProxy when this event is fired from the XSlideShow void slideEnded(const bool bReverse); void contextMenuShow(const css::awt::Point& point);