summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sd/source/ui/inc/PresentationViewShell.hxx3
-rw-r--r--sd/source/ui/inc/slideshow.hxx3
-rw-r--r--sd/source/ui/slideshow/slideshow.cxx20
-rw-r--r--sd/source/ui/view/presvish.cxx29
-rw-r--r--sd/source/ui/view/viewshel.cxx7
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();