sd/source/ui/slideshow/slideshowimpl.cxx |  246 +++++++++++++++++++------------
 sd/source/ui/slideshow/slideshowimpl.hxx |    5 
 2 files changed, 161 insertions(+), 90 deletions(-)

New commits:
commit c7616ef5a473c50df360d3b69bad74c577ab78c7
Author:     Armin Le Grand (allotropia) <[email protected]>
AuthorDate: Thu Feb 22 23:25:39 2024 +0100
Commit:     Armin Le Grand <[email protected]>
CommitDate: Fri Feb 23 10:40:03 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 <[email protected]>

diff --git a/sd/source/ui/slideshow/slideshowimpl.cxx 
b/sd/source/ui/slideshow/slideshowimpl.cxx
index 61e8bcf8f90a..12a8cc31dcae 100644
--- a/sd/source/ui/slideshow/slideshowimpl.cxx
+++ b/sd/source/ui/slideshow/slideshowimpl.cxx
@@ -565,6 +565,8 @@ SlideshowImpl::SlideshowImpl( const Reference< 
XPresentation2 >& xPresentation,
 , mnEndShowEvent(nullptr)
 , mnContextMenuEvent(nullptr)
 , mnEventObjectChange(nullptr)
+, mnEventObjectInserted(nullptr)
+, mnEventObjectRemoved(nullptr)
 , mnEventPageOrderChange(nullptr)
 , mxPresentation( xPresentation )
 , mxListenerProxy()
@@ -658,6 +660,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 );
 
@@ -3305,53 +3311,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)
@@ -3372,75 +3429,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 80e44cb22f99..7d0d759680f1 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;

Reply via email to