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.Grand@me.com>
This commit is contained in:
committed by
Armin Le Grand
parent
a91892ec49
commit
7da04200f9
@@ -61,6 +61,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"
|
||||
@@ -545,10 +546,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 ?
|
||||
@@ -3045,6 +3055,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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user