sd/inc/strings.hrc                                          |    2 
 sd/qa/unit/uiimpress.cxx                                    |   58 ++++++++++
 sd/source/ui/inc/unmodpg.hxx                                |   28 ++++
 sd/source/ui/slidesorter/controller/SlsPageSelector.cxx     |   18 +++
 sd/source/ui/slidesorter/controller/SlsSlotManager.cxx      |    9 +
 sd/source/ui/slidesorter/inc/controller/SlsPageSelector.hxx |   14 ++
 sd/source/ui/view/unmodpg.cxx                               |   69 ++++++++++++
 7 files changed, 198 insertions(+)

New commits:
commit 2b3a950e937efe77ad39b034819c9f7a707fe29e
Author:     Andreas Heinisch <andreas.heini...@yahoo.de>
AuthorDate: Wed Jun 21 10:07:02 2023 +0200
Commit:     Andreas Heinisch <andreas.heini...@yahoo.de>
CommitDate: Mon Jul 17 09:11:29 2023 +0200

    tdf#130581 - Add undo command for hide/show slides
    
    Change-Id: I7305e222df65fda6523940ca63f5759857c94bea
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/153375
    Tested-by: Jenkins
    Reviewed-by: Andreas Heinisch <andreas.heini...@yahoo.de>

diff --git a/sd/inc/strings.hrc b/sd/inc/strings.hrc
index 0d9303e18bea..afcf1d4e3be3 100644
--- a/sd/inc/strings.hrc
+++ b/sd/inc/strings.hrc
@@ -130,6 +130,8 @@
 #define STR_UNDO_INSERT_FILE                            
NC_("STR_UNDO_INSERT_FILE", "Insert file")
 #define STR_UNDO_INSERT_SPECCHAR                        
NC_("STR_UNDO_INSERT_SPECCHAR", "Insert special character")
 #define STR_UNDO_SET_PRESLAYOUT                         
NC_("STR_UNDO_SET_PRESLAYOUT", "Apply presentation layout")
+#define STR_UNDO_HIDE_SLIDE                             
NC_("STR_UNDO_HIDE_SLIDE", "Hide slide")
+#define STR_UNDO_SHOW_SLIDE                             
NC_("STR_UNDO_SHOW_SLIDE", "Show slide")
 #define STR_PLAY                                        NC_("STR_PLAY", 
"~Play")
 #define STR_STOP                                        NC_("STR_STOP", 
"Sto~p")
 #define STR_UNDO_ORIGINALSIZE                           
NC_("STR_UNDO_ORIGINALSIZE", "Original Size")
diff --git a/sd/qa/unit/uiimpress.cxx b/sd/qa/unit/uiimpress.cxx
index c4cdc0a5e338..3a1c2ad911aa 100644
--- a/sd/qa/unit/uiimpress.cxx
+++ b/sd/qa/unit/uiimpress.cxx
@@ -56,6 +56,8 @@
 #include <unomodel.hxx>
 #include <osl/thread.hxx>
 #include <slideshow.hxx>
+#include <sdresid.hxx>
+#include <strings.hrc>
 
 using namespace ::com::sun::star;
 
@@ -491,6 +493,62 @@ CPPUNIT_TEST_FIXTURE(SdUiImpressTest, testTdf100950)
     CPPUNIT_ASSERT(rPageSelector.IsPageSelected(2));
 }
 
+CPPUNIT_TEST_FIXTURE(SdUiImpressTest, testTdf130581)
+{
+    createSdImpressDoc();
+
+    // Hide slide and check the number of available undo actions
+    dispatchCommand(mxComponent, ".uno:ShowSlide", {});
+    dispatchCommand(mxComponent, ".uno:HideSlide", {});
+
+    // There should be a single undo action, i.e., hide slide
+    auto pXImpressDocument = 
dynamic_cast<SdXImpressDocument*>(mxComponent.get());
+    SdDrawDocument* pDocument = pXImpressDocument->GetDoc();
+    sd::UndoManager* pUndoManager = pDocument->GetUndoManager();
+    // Without the fix in place, this test would have failed with
+    // - Expected: 1
+    // - Actual  : 0
+    CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), 
pUndoManager->GetUndoActionCount());
+    CPPUNIT_ASSERT_EQUAL(SdResId(STR_UNDO_HIDE_SLIDE), 
pUndoManager->GetUndoActionComment());
+    sd::slidesorter::SlideSorterViewShell* pSSVS = getSlideSorterViewShell();
+
+    // Check if the page is actually hidden
+    auto& rSSController = pSSVS->GetSlideSorter().GetController();
+    auto& rPageSelector = rSSController.GetPageSelector();
+    CPPUNIT_ASSERT_EQUAL(true, rPageSelector.IsPageExcluded(0));
+
+    // Undo hide slide action and check the number of available redo actions
+    dispatchCommand(mxComponent, ".uno:Undo", {});
+    // Without the fix in place, this test would have failed with
+    // - Expected: 1
+    // - Actual  : 0
+    CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), 
pUndoManager->GetRedoActionCount());
+    CPPUNIT_ASSERT_EQUAL(SdResId(STR_UNDO_HIDE_SLIDE), 
pUndoManager->GetRedoActionComment());
+    CPPUNIT_ASSERT_EQUAL(false, rPageSelector.IsPageExcluded(0));
+
+    // Show slide and check the number of available undo actions
+    dispatchCommand(mxComponent, ".uno:Redo", {});
+    CPPUNIT_ASSERT_EQUAL(true, rPageSelector.IsPageExcluded(0));
+    dispatchCommand(mxComponent, ".uno:ShowSlide", {});
+    // Without the fix in place, this test would have failed with
+    // - Expected: 2
+    // - Actual  : 0
+    CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(2), 
pUndoManager->GetUndoActionCount());
+    CPPUNIT_ASSERT_EQUAL(SdResId(STR_UNDO_SHOW_SLIDE), 
pUndoManager->GetUndoActionComment());
+    CPPUNIT_ASSERT_EQUAL(false, rPageSelector.IsPageExcluded(0));
+
+    // Undo show slide action and check the number of available undo/redo 
actions
+    dispatchCommand(mxComponent, ".uno:Undo", {});
+    // Without the fix in place, this test would have failed with
+    // - Expected: 1
+    // - Actual  : 0
+    CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), 
pUndoManager->GetUndoActionCount());
+    CPPUNIT_ASSERT_EQUAL(SdResId(STR_UNDO_HIDE_SLIDE), 
pUndoManager->GetUndoActionComment());
+    CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), 
pUndoManager->GetRedoActionCount());
+    CPPUNIT_ASSERT_EQUAL(SdResId(STR_UNDO_SHOW_SLIDE), 
pUndoManager->GetRedoActionComment());
+    CPPUNIT_ASSERT_EQUAL(true, rPageSelector.IsPageExcluded(0));
+}
+
 CPPUNIT_TEST_FIXTURE(SdUiImpressTest, testTdf129346)
 {
     createSdImpressDoc();
diff --git a/sd/source/ui/inc/unmodpg.hxx b/sd/source/ui/inc/unmodpg.hxx
index 4dd1979d2b30..02920c27ab1c 100644
--- a/sd/source/ui/inc/unmodpg.hxx
+++ b/sd/source/ui/inc/unmodpg.hxx
@@ -19,6 +19,9 @@
 
 #pragma once
 
+#include <model/SlsPageDescriptor.hxx>
+#include <model/SlsSharedPageDescriptor.hxx>
+
 #include <xmloff/autolayout.hxx>
 
 #include <sdundo.hxx>
@@ -52,6 +55,31 @@ public:
     virtual void Redo() override;
 };
 
+class ChangeSlideExclusionStateUndoAction final : public SdUndoAction
+{
+public:
+    ChangeSlideExclusionStateUndoAction(SdDrawDocument* pDocument,
+                                        const 
sd::slidesorter::model::PageDescriptor::State eState,
+                                        const bool bOldStateValue);
+
+    ChangeSlideExclusionStateUndoAction(
+        SdDrawDocument* pDocument, const 
sd::slidesorter::model::SharedPageDescriptor& rpDescriptor,
+        const sd::slidesorter::model::PageDescriptor::State eState, const bool 
bOldStateValue);
+
+    virtual void Undo() override;
+    virtual void Redo() override;
+
+    virtual OUString GetComment() const override;
+
+    void AddPageDescriptor(const sd::slidesorter::model::SharedPageDescriptor& 
rpDescriptor);
+
+private:
+    sd::slidesorter::model::PageDescriptor::State meState;
+    bool mbOldStateValue;
+    std::vector<sd::slidesorter::model::SharedPageDescriptor> mrpDescriptors;
+    const OUString maComment;
+};
+
 class RenameLayoutTemplateUndoAction final : public SdUndoAction
 {
 public:
diff --git a/sd/source/ui/slidesorter/controller/SlsPageSelector.cxx 
b/sd/source/ui/slidesorter/controller/SlsPageSelector.cxx
index cf20d5cb530e..cdd4f99b1521 100644
--- a/sd/source/ui/slidesorter/controller/SlsPageSelector.cxx
+++ b/sd/source/ui/slidesorter/controller/SlsPageSelector.cxx
@@ -218,6 +218,24 @@ bool PageSelector::IsPageSelected(int nPageIndex)
         return false;
 }
 
+bool PageSelector::IsPageVisible(int nPageIndex)
+{
+    SharedPageDescriptor pDescriptor (mrModel.GetPageDescriptor(nPageIndex));
+    if (pDescriptor)
+        return pDescriptor->HasState(PageDescriptor::ST_Visible);
+    else
+        return false;
+}
+
+bool PageSelector::IsPageExcluded(int nPageIndex)
+{
+    SharedPageDescriptor pDescriptor(mrModel.GetPageDescriptor(nPageIndex));
+    if (pDescriptor)
+        return pDescriptor->HasState(PageDescriptor::ST_Excluded);
+    else
+        return false;
+}
+
 int PageSelector::GetPageCount() const
 {
     return mrModel.GetPageCount();
diff --git a/sd/source/ui/slidesorter/controller/SlsSlotManager.cxx 
b/sd/source/ui/slidesorter/controller/SlsSlotManager.cxx
index 41a6b64708e0..bd58443b80be 100644
--- a/sd/source/ui/slidesorter/controller/SlsSlotManager.cxx
+++ b/sd/source/ui/slidesorter/controller/SlsSlotManager.cxx
@@ -1164,18 +1164,25 @@ void SlotManager::ChangeSlideExclusionState (
     const model::SharedPageDescriptor& rpDescriptor,
     const bool bExcludeSlide)
 {
+    SdDrawDocument* pDocument = mrSlideSorter.GetModel().GetDocument();
+    SfxUndoManager* pManager = pDocument->GetDocSh()->GetUndoManager();
     if (rpDescriptor)
     {
         mrSlideSorter.GetView().SetState(
             rpDescriptor,
             model::PageDescriptor::ST_Excluded,
             bExcludeSlide);
+        
pManager->AddUndoAction(std::make_unique<ChangeSlideExclusionStateUndoAction>(
+            pDocument, rpDescriptor, model::PageDescriptor::ST_Excluded, 
!bExcludeSlide));
     }
     else
     {
         model::PageEnumeration aSelectedPages (
             model::PageEnumerationProvider::CreateSelectedPagesEnumeration(
                 mrSlideSorter.GetModel()));
+        std::unique_ptr<ChangeSlideExclusionStateUndoAction> 
pChangeSlideExclusionStateUndoAction(
+            new ChangeSlideExclusionStateUndoAction(pDocument, 
model::PageDescriptor::ST_Excluded,
+                                                    !bExcludeSlide));
         while (aSelectedPages.HasMoreElements())
         {
             model::SharedPageDescriptor pDescriptor 
(aSelectedPages.GetNextElement());
@@ -1183,7 +1190,9 @@ void SlotManager::ChangeSlideExclusionState (
                 pDescriptor,
                 model::PageDescriptor::ST_Excluded,
                 bExcludeSlide);
+            
pChangeSlideExclusionStateUndoAction->AddPageDescriptor(pDescriptor);
         }
+        
pManager->AddUndoAction(std::move(pChangeSlideExclusionStateUndoAction));
     }
 
     SfxBindings& rBindings 
(mrSlideSorter.GetViewShell()->GetViewFrame()->GetBindings());
diff --git a/sd/source/ui/slidesorter/inc/controller/SlsPageSelector.hxx 
b/sd/source/ui/slidesorter/inc/controller/SlsPageSelector.hxx
index ae884416a1cd..6b720623a376 100644
--- a/sd/source/ui/slidesorter/inc/controller/SlsPageSelector.hxx
+++ b/sd/source/ui/slidesorter/inc/controller/SlsPageSelector.hxx
@@ -92,6 +92,20 @@ public:
     */
     SD_DLLPUBLIC bool IsPageSelected(int nPageIndex);
 
+    /** Return whether the specified page is visible.  This convenience
+        method is a substitute for
+        SlideSorterModel::GetPageDescriptor(i)->HasState(ST_Visible) is
+        included here to make this class more self contained.
+    */
+    bool IsPageVisible(int nPageIndex);
+
+    /** Return whether the specified page is excluded.  This convenience
+        method is a substitute for
+        SlideSorterModel::GetPageDescriptor(i)->HasState(ST_Excluded) is
+        included here to make this class more self contained.
+    */
+    SD_DLLPUBLIC bool IsPageExcluded(int nPageIndex);
+
     /** Deselect the descriptor that is associated with the given page.
         The current page is updated to the first slide
         of the remaining selection.
diff --git a/sd/source/ui/view/unmodpg.cxx b/sd/source/ui/view/unmodpg.cxx
index 383a84a7b2ba..4ca02f294269 100644
--- a/sd/source/ui/view/unmodpg.cxx
+++ b/sd/source/ui/view/unmodpg.cxx
@@ -36,6 +36,12 @@
 #include <drawdoc.hxx>
 #include <utility>
 
+#include <ViewShell.hxx>
+#include <ViewShellBase.hxx>
+#include <DrawDocShell.hxx>
+#include <SlideSorter.hxx>
+#include <SlideSorterViewShell.hxx>
+#include <view/SlideSorterView.hxx>
 
 ModifyPageUndoAction::ModifyPageUndoAction(
     SdDrawDocument* pTheDoc,
@@ -171,6 +177,69 @@ ModifyPageUndoAction::~ModifyPageUndoAction()
 {
 }
 
+ChangeSlideExclusionStateUndoAction::ChangeSlideExclusionStateUndoAction(
+    SdDrawDocument* pDocument, const 
sd::slidesorter::model::PageDescriptor::State eState,
+    const bool bOldStateValue)
+    : SdUndoAction(pDocument)
+    , meState(eState)
+    , mbOldStateValue(bOldStateValue)
+    , maComment(bOldStateValue ? SdResId(STR_UNDO_SHOW_SLIDE) : 
SdResId(STR_UNDO_HIDE_SLIDE))
+{
+}
+
+ChangeSlideExclusionStateUndoAction::ChangeSlideExclusionStateUndoAction(
+    SdDrawDocument* pDocument, const 
sd::slidesorter::model::SharedPageDescriptor& rpDescriptor,
+    const sd::slidesorter::model::PageDescriptor::State eState, const bool 
bOldStateValue)
+    : ChangeSlideExclusionStateUndoAction(pDocument, eState, bOldStateValue)
+{
+    mrpDescriptors.push_back(rpDescriptor);
+}
+
+void ChangeSlideExclusionStateUndoAction::AddPageDescriptor(
+    const sd::slidesorter::model::SharedPageDescriptor& rpDescriptor)
+{
+    mrpDescriptors.push_back(rpDescriptor);
+}
+
+void ChangeSlideExclusionStateUndoAction::Undo()
+{
+    sd::DrawDocShell* pDocShell = mpDoc ? mpDoc->GetDocSh() : nullptr;
+    sd::ViewShell* pViewShell = pDocShell ? pDocShell->GetViewShell() : 
nullptr;
+    if (pViewShell)
+    {
+        sd::slidesorter::SlideSorterViewShell* pSlideSorterViewShell
+            = 
sd::slidesorter::SlideSorterViewShell::GetSlideSorter(pViewShell->GetViewShellBase());
+        if (pSlideSorterViewShell)
+        {
+            for (const sd::slidesorter::model::SharedPageDescriptor& 
rpDescriptor : mrpDescriptors)
+                
pSlideSorterViewShell->GetSlideSorter().GetView().SetState(rpDescriptor, 
meState,
+                                                                           
mbOldStateValue);
+        }
+    }
+}
+
+void ChangeSlideExclusionStateUndoAction::Redo()
+{
+    sd::DrawDocShell* pDocShell = mpDoc ? mpDoc->GetDocSh() : nullptr;
+    sd::ViewShell* pViewShell = pDocShell ? pDocShell->GetViewShell() : 
nullptr;
+    if (pViewShell)
+    {
+        sd::slidesorter::SlideSorterViewShell* pSlideSorterViewShell
+            = 
sd::slidesorter::SlideSorterViewShell::GetSlideSorter(pViewShell->GetViewShellBase());
+        if (pSlideSorterViewShell)
+        {
+            for (const sd::slidesorter::model::SharedPageDescriptor& 
rpDescriptor : mrpDescriptors)
+                
pSlideSorterViewShell->GetSlideSorter().GetView().SetState(rpDescriptor, 
meState,
+                                                                           
!mbOldStateValue);
+        }
+    }
+}
+
+OUString ChangeSlideExclusionStateUndoAction::GetComment() const
+{
+    return maComment;
+}
+
 RenameLayoutTemplateUndoAction::RenameLayoutTemplateUndoAction(
     SdDrawDocument* pDocument,
     OUString aOldLayoutName,

Reply via email to