diff options
author | Armin Le Grand (Allotropia) <Armin.Le.Grand@me.com> | 2022-05-10 15:59:29 +0200 |
---|---|---|
committer | Armin Le Grand <Armin.Le.Grand@me.com> | 2022-05-11 14:17:34 +0200 |
commit | 1e016920769ae524575e40b1ec317c700ba0daa3 (patch) | |
tree | 24dc1a6cb9f35ea07879564eb82376fcb0fbd313 /cui/source | |
parent | 5b9b07dcb3e0065ddb616a0a5b0e69c1c3841fa7 (diff) |
Advanced Diagram support: UNDO/REDO support for Diagram DataModel
Added support for UNDO/REDO for changes in Diagram ModelData.
This is currenly applied/used in the DiagramDialog for it's
Add/Remove actions (also supports Cancel of that dialog 1st
time ever). But it is defined more general to add/support
manipulating actions like clone/change_text etc. Also the
UI/dialog at he end will not be/stay modal, so this is a
test implemenation how to use it.
It uses an extract/apply mechanism to get/set the Diagram
ModelData at/for the UNDO action. That may be expanded as
needed for additional data in he future. It may also be
considered to modify the Connection/Point ModelData to
shared_ptr internally completely to avoid copying these
at all. OTOH it is not that much data to handle at all.
Change-Id: I4702ed908b79a476177fe66c0e3284898c6adda5
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/134118
Tested-by: Jenkins
Reviewed-by: Armin Le Grand <Armin.Le.Grand@me.com>
Diffstat (limited to 'cui/source')
-rw-r--r-- | cui/source/dialogs/DiagramDialog.cxx | 90 | ||||
-rw-r--r-- | cui/source/factory/dlgfact.cxx | 6 | ||||
-rw-r--r-- | cui/source/factory/dlgfact.hxx | 2 | ||||
-rw-r--r-- | cui/source/inc/DiagramDialog.hxx | 9 |
4 files changed, 93 insertions, 14 deletions
diff --git a/cui/source/dialogs/DiagramDialog.cxx b/cui/source/dialogs/DiagramDialog.cxx index 9c5816cf4b2b..ea592767461d 100644 --- a/cui/source/dialogs/DiagramDialog.cxx +++ b/cui/source/dialogs/DiagramDialog.cxx @@ -11,12 +11,15 @@ #include <comphelper/dispatchcommand.hxx> #include <svx/svdogrp.hxx> +#include <svx/svdmodel.hxx> +#include <svx/svdundo.hxx> #include <com/sun/star/beans/PropertyValue.hpp> +#include <svx/diagram/datamodel.hxx> -DiagramDialog::DiagramDialog(weld::Window* pWindow, - const std::shared_ptr<IDiagramHelper>& pDiagramHelper) +DiagramDialog::DiagramDialog(weld::Window* pWindow, SdrObjGroup& rDiagram) : GenericDialogController(pWindow, "cui/ui/diagramdialog.ui", "DiagramDialog") - , mpDiagramHelper(pDiagramHelper) + , m_rDiagram(rDiagram) + , m_nUndos(0) , mpBtnOk(m_xBuilder->weld_button("btnOk")) , mpBtnCancel(m_xBuilder->weld_button("btnCancel")) , mpBtnAdd(m_xBuilder->weld_button("btnAdd")) @@ -24,6 +27,7 @@ DiagramDialog::DiagramDialog(weld::Window* pWindow, , mpTreeDiagram(m_xBuilder->weld_tree_view("treeDiagram")) , mpTextAdd(m_xBuilder->weld_text_view("textAdd")) { + mpBtnCancel->connect_clicked(LINK(this, DiagramDialog, OnAddCancel)); mpBtnAdd->connect_clicked(LINK(this, DiagramDialog, OnAddClick)); mpBtnRemove->connect_clicked(LINK(this, DiagramDialog, OnRemoveClick)); @@ -37,13 +41,51 @@ DiagramDialog::DiagramDialog(weld::Window* pWindow, }); } +IMPL_LINK_NOARG(DiagramDialog, OnAddCancel, weld::Button&, void) +{ + // If the user cancels the dialog, undo all changes done so far. It may + // even be feasible to then delete the redo-stack, since it stays + // available (?) - but it does no harm either... + while (0 != m_nUndos) + { + comphelper::dispatchCommand(".uno:Undo", {}); + m_nUndos--; + } + + m_xDialog->response(RET_CANCEL); +} + IMPL_LINK_NOARG(DiagramDialog, OnAddClick, weld::Button&, void) { + if (!m_rDiagram.isDiagram()) + return; + OUString sText = mpTextAdd->get_text(); + const std::shared_ptr<IDiagramHelper>& pDiagramHelper(m_rDiagram.getDiagramHelper()); - if (!sText.isEmpty()) + if (pDiagramHelper && !sText.isEmpty()) { - OUString sNodeId = mpDiagramHelper->addNode(sText); + SdrModel& rDrawModel(m_rDiagram.getSdrModelFromSdrObject()); + const bool bUndo(rDrawModel.IsUndoEnabled()); + svx::diagram::DiagramDataStatePtr aStartState; + + if (bUndo) + { + // rescue all start state Diagram-defining data + aStartState = pDiagramHelper->extractDiagramDataState(); + } + + OUString sNodeId = pDiagramHelper->addNode(sText); + + if (bUndo) + { + // create undo action. That will internally secure the + // current Diagram-defining data as end state + rDrawModel.AddUndo( + rDrawModel.GetSdrUndoFactory().CreateUndoDiagramModelData(m_rDiagram, aStartState)); + m_nUndos++; + } + std::unique_ptr<weld::TreeIter> pEntry(mpTreeDiagram->make_iterator()); mpTreeDiagram->insert(nullptr, -1, &sText, &sNodeId, nullptr, nullptr, false, pEntry.get()); mpTreeDiagram->select(*pEntry); @@ -53,11 +95,35 @@ IMPL_LINK_NOARG(DiagramDialog, OnAddClick, weld::Button&, void) IMPL_LINK_NOARG(DiagramDialog, OnRemoveClick, weld::Button&, void) { + if (!m_rDiagram.isDiagram()) + return; + std::unique_ptr<weld::TreeIter> pEntry(mpTreeDiagram->make_iterator()); - if (mpTreeDiagram->get_selected(pEntry.get())) + const std::shared_ptr<IDiagramHelper>& pDiagramHelper(m_rDiagram.getDiagramHelper()); + + if (pDiagramHelper && mpTreeDiagram->get_selected(pEntry.get())) { - if (mpDiagramHelper->removeNode(mpTreeDiagram->get_id(*pEntry))) + SdrModel& rDrawModel(m_rDiagram.getSdrModelFromSdrObject()); + const bool bUndo(rDrawModel.IsUndoEnabled()); + svx::diagram::DiagramDataStatePtr aStartState; + + if (bUndo) + { + // rescue all start state Diagram-defining data + aStartState = pDiagramHelper->extractDiagramDataState(); + } + + if (pDiagramHelper->removeNode(mpTreeDiagram->get_id(*pEntry))) { + if (bUndo) + { + // create undo action. That will internally secure the + // current Diagram-defining data as end state + rDrawModel.AddUndo(rDrawModel.GetSdrUndoFactory().CreateUndoDiagramModelData( + m_rDiagram, aStartState)); + m_nUndos++; + } + mpTreeDiagram->remove(*pEntry); comphelper::dispatchCommand(".uno:RegenerateDiagram", {}); } @@ -66,7 +132,15 @@ IMPL_LINK_NOARG(DiagramDialog, OnRemoveClick, weld::Button&, void) void DiagramDialog::populateTree(const weld::TreeIter* pParent, const OUString& rParentId) { - auto aItems = mpDiagramHelper->getChildren(rParentId); + if (!m_rDiagram.isDiagram()) + return; + + const std::shared_ptr<IDiagramHelper>& pDiagramHelper(m_rDiagram.getDiagramHelper()); + + if (!pDiagramHelper) + return; + + auto aItems = pDiagramHelper->getChildren(rParentId); for (auto& aItem : aItems) { std::unique_ptr<weld::TreeIter> pEntry(mpTreeDiagram->make_iterator()); diff --git a/cui/source/factory/dlgfact.cxx b/cui/source/factory/dlgfact.cxx index c7a8a204e075..28d473479ac7 100644 --- a/cui/source/factory/dlgfact.cxx +++ b/cui/source/factory/dlgfact.cxx @@ -1524,10 +1524,12 @@ AbstractDialogFactory_Impl::CreateToolbarmodeDialog(weld::Window* pParent) } VclPtr<AbstractDiagramDialog> -AbstractDialogFactory_Impl::CreateDiagramDialog(weld::Window* pParent, const std::shared_ptr<IDiagramHelper>& pDiagramHelper) +AbstractDialogFactory_Impl::CreateDiagramDialog( + weld::Window* pParent, + SdrObjGroup& rDiagram) { return VclPtr<AbstractDiagramDialog_Impl>::Create( - std::make_unique<DiagramDialog>(pParent, pDiagramHelper)); + std::make_unique<DiagramDialog>(pParent, rDiagram)); } #ifdef _WIN32 diff --git a/cui/source/factory/dlgfact.hxx b/cui/source/factory/dlgfact.hxx index 3ce135927f14..1b9c85f66841 100644 --- a/cui/source/factory/dlgfact.hxx +++ b/cui/source/factory/dlgfact.hxx @@ -608,7 +608,7 @@ public: virtual VclPtr<AbstractDiagramDialog> CreateDiagramDialog( weld::Window* pParent, - const std::shared_ptr<IDiagramHelper>& pDiagramHelper) override; + SdrObjGroup& rDiagram) override; #ifdef _WIN32 virtual VclPtr<VclAbstractDialog> CreateFileExtCheckDialog(weld::Window* pParent, diff --git a/cui/source/inc/DiagramDialog.hxx b/cui/source/inc/DiagramDialog.hxx index 397aab44f50f..71a5bd9b79c4 100644 --- a/cui/source/inc/DiagramDialog.hxx +++ b/cui/source/inc/DiagramDialog.hxx @@ -12,17 +12,19 @@ #include <tools/link.hxx> #include <vcl/weld.hxx> -class IDiagramHelper; +class SdrObjGroup; /** Edit Diagram dialog */ class DiagramDialog : public weld::GenericDialogController { public: - DiagramDialog(weld::Window* pWindow, const std::shared_ptr<IDiagramHelper>& pDiagramHelper); + DiagramDialog(weld::Window* pWindow, SdrObjGroup& rDiagram); virtual ~DiagramDialog() override; private: - const std::shared_ptr<IDiagramHelper> mpDiagramHelper; + SdrObjGroup& m_rDiagram; + sal_uInt32 m_nUndos; + std::unique_ptr<weld::Button> mpBtnOk; std::unique_ptr<weld::Button> mpBtnCancel; std::unique_ptr<weld::Button> mpBtnAdd; @@ -30,6 +32,7 @@ private: std::unique_ptr<weld::TreeView> mpTreeDiagram; std::unique_ptr<weld::TextView> mpTextAdd; + DECL_LINK(OnAddCancel, weld::Button&, void); DECL_LINK(OnAddClick, weld::Button&, void); DECL_LINK(OnRemoveClick, weld::Button&, void); |