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);

Reply via email to