summaryrefslogtreecommitdiff
path: root/cui/source
diff options
context:
space:
mode:
authorArmin Le Grand (Allotropia) <Armin.Le.Grand@me.com>2022-05-10 15:59:29 +0200
committerArmin Le Grand <Armin.Le.Grand@me.com>2022-05-11 14:17:34 +0200
commit1e016920769ae524575e40b1ec317c700ba0daa3 (patch)
tree24dc1a6cb9f35ea07879564eb82376fcb0fbd313 /cui/source
parent5b9b07dcb3e0065ddb616a0a5b0e69c1c3841fa7 (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.cxx90
-rw-r--r--cui/source/factory/dlgfact.cxx6
-rw-r--r--cui/source/factory/dlgfact.hxx2
-rw-r--r--cui/source/inc/DiagramDialog.hxx9
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);