diff options
-rw-r--r-- | sd/source/ui/inc/PresentationViewShell.hxx | 3 | ||||
-rw-r--r-- | sd/source/ui/inc/slideshow.hxx | 3 | ||||
-rw-r--r-- | sd/source/ui/slideshow/slideshow.cxx | 20 | ||||
-rw-r--r-- | sd/source/ui/view/presvish.cxx | 29 | ||||
-rw-r--r-- | sd/source/ui/view/viewshel.cxx | 7 |
5 files changed, 45 insertions, 17 deletions
diff --git a/sd/source/ui/inc/PresentationViewShell.hxx b/sd/source/ui/inc/PresentationViewShell.hxx index c0020685c02e..7adbc6631461 100644 --- a/sd/source/ui/inc/PresentationViewShell.hxx +++ b/sd/source/ui/inc/PresentationViewShell.hxx @@ -58,9 +58,12 @@ protected: private: ::tools::Rectangle maOldVisArea; + ImplSVEvent* mnAbortSlideShowEvent; virtual void Activate (bool bIsMDIActivate) override; virtual void Paint (const ::tools::Rectangle& rRect, ::sd::Window* pWin) override; + + DECL_LINK(AbortSlideShowHdl, void*, void); }; } // end of namespace sd diff --git a/sd/source/ui/inc/slideshow.hxx b/sd/source/ui/inc/slideshow.hxx index 90a45ac826ab..9b6087a5d311 100644 --- a/sd/source/ui/inc/slideshow.hxx +++ b/sd/source/ui/inc/slideshow.hxx @@ -157,7 +157,8 @@ public: // events void resize( const Size &rSize ); - void activate(ViewShellBase& rBase); + // return false if the activate failed. callers should call end in response to failre + bool activate(ViewShellBase& rBase); void deactivate(); void paint(); diff --git a/sd/source/ui/slideshow/slideshow.cxx b/sd/source/ui/slideshow/slideshow.cxx index 74bbe395d92d..d253bce66b4a 100644 --- a/sd/source/ui/slideshow/slideshow.cxx +++ b/sd/source/ui/slideshow/slideshow.cxx @@ -972,7 +972,7 @@ void SlideShow::resize( const Size &rSize ) mxController->resize( rSize ); } -void SlideShow::activate( ViewShellBase& rBase ) +bool SlideShow::activate( ViewShellBase& rBase ) { if( (mpFullScreenViewShellBase == &rBase) && !mxController.is() ) { @@ -984,23 +984,19 @@ void SlideShow::activate( ViewShellBase& rBase ) CreateController( pShell.get(), pShell->GetView(), rBase.GetViewWindow() ); - if( mxController->startShow(mxCurrentSettings.get()) ) - { - pShell->Resize(); - // Defer the sd::ShowWindow's GrabFocus to here. so that the accessible event can be fired correctly. - pShell->GetActiveWindow()->GrabFocus(); - } - else - { - end(); - return; - } + if (!mxController->startShow(mxCurrentSettings.get())) + return false; + + pShell->Resize(); + // Defer the sd::ShowWindow's GrabFocus to here. so that the accessible event can be fired correctly. + pShell->GetActiveWindow()->GrabFocus(); } } if( mxController.is() ) mxController->activate(); + return true; } void SlideShow::deactivate() diff --git a/sd/source/ui/view/presvish.cxx b/sd/source/ui/view/presvish.cxx index e324b5803f7b..34a789f4dd18 100644 --- a/sd/source/ui/view/presvish.cxx +++ b/sd/source/ui/view/presvish.cxx @@ -61,7 +61,8 @@ void PresentationViewShell::InitInterface_Impl() PresentationViewShell::PresentationViewShell( ViewShellBase& rViewShellBase, vcl::Window* pParentWindow, FrameView* pFrameView) -: DrawViewShell( rViewShellBase, pParentWindow, PageKind::Standard, pFrameView) + : DrawViewShell(rViewShellBase, pParentWindow, PageKind::Standard, pFrameView) + , mnAbortSlideShowEvent(nullptr) { if( GetDocSh() && GetDocSh()->GetCreateMode() == SfxObjectCreateMode::EMBEDDED ) maOldVisArea = GetDocSh()->GetVisArea( ASPECT_CONTENT ); @@ -70,6 +71,9 @@ PresentationViewShell::PresentationViewShell( ViewShellBase& rViewShellBase, vcl PresentationViewShell::~PresentationViewShell() { + if (mnAbortSlideShowEvent) + Application::RemoveUserEvent(mnAbortSlideShowEvent); + if( GetDocSh() && GetDocSh()->GetCreateMode() == SfxObjectCreateMode::EMBEDDED && !maOldVisArea.IsEmpty() ) GetDocSh()->SetVisArea( maOldVisArea ); } @@ -102,6 +106,14 @@ VclPtr<SvxRuler> PresentationViewShell::CreateVRuler(::sd::Window*) return nullptr; } +IMPL_LINK_NOARG(PresentationViewShell, AbortSlideShowHdl, void*, void) +{ + mnAbortSlideShowEvent = nullptr; + rtl::Reference<SlideShow> xSlideShow(SlideShow::GetSlideShow(GetViewShellBase())); + if (xSlideShow.is()) + xSlideShow->end(); +} + void PresentationViewShell::Activate( bool bIsMDIActivate ) { DrawViewShell::Activate( bIsMDIActivate ); @@ -115,7 +127,20 @@ void PresentationViewShell::Activate( bool bIsMDIActivate ) rtl::Reference< SlideShow > xSlideShow( SlideShow::GetSlideShow( GetViewShellBase() ) ); if( xSlideShow.is() ) - xSlideShow->activate(GetViewShellBase()); + { + bool bSuccess = xSlideShow->activate(GetViewShellBase()); + if (!bSuccess) + { + /* tdf#64711 PresentationViewShell is deleted by 'end' due to end closing + the object shell. So if we call xSlideShow->end during Activate there are + a lot of places in the call stack of Activate which understandable don't + expect this ViewShell to be deleted during use. Defer to the next event + loop the abort of the slideshow + */ + if (!mnAbortSlideShowEvent) + mnAbortSlideShowEvent = Application::PostUserEvent(LINK(this, PresentationViewShell, AbortSlideShowHdl)); + } + } if( HasCurrentFunction() ) GetCurrentFunction()->Activate(); diff --git a/sd/source/ui/view/viewshel.cxx b/sd/source/ui/view/viewshel.cxx index ca99e3f7a214..cd7534a89893 100644 --- a/sd/source/ui/view/viewshel.cxx +++ b/sd/source/ui/view/viewshel.cxx @@ -320,8 +320,11 @@ void ViewShell::Activate(bool bIsMDIActivate) rBindings.Invalidate( SID_3D_STATE, true ); rtl::Reference< SlideShow > xSlideShow( SlideShow::GetSlideShow( GetViewShellBase() ) ); - if(xSlideShow.is() && xSlideShow->isRunning() ) - xSlideShow->activate(GetViewShellBase()); + if (xSlideShow.is() && xSlideShow->isRunning()) + { + bool bSuccess = xSlideShow->activate(GetViewShellBase()); + assert(bSuccess && "can only return false with a PresentationViewShell"); (void)bSuccess; + } if(HasCurrentFunction()) GetCurrentFunction()->Activate(); |