[Libreoffice-commits] core.git: cui/source cui/uiconfig include/svx oox/source

Grzegorz Araminowicz (via logerrit) logerrit at kemper.freedesktop.org
Wed Sep 25 07:31:43 UTC 2019


 cui/source/dialogs/DiagramDialog.cxx       |   19 +++++++-
 cui/source/inc/DiagramDialog.hxx           |    2 
 cui/uiconfig/ui/diagramdialog.ui           |   14 +++++
 include/svx/DiagramDataInterface.hxx       |    6 +-
 oox/source/drawingml/diagram/datamodel.cxx |   68 +++++++++++++++++++++++++++--
 oox/source/drawingml/diagram/datamodel.hxx |    3 -
 6 files changed, 104 insertions(+), 8 deletions(-)

New commits:
commit 711c0b6331958da4fd53eb6c4f9ecd5a422bb186
Author:     Grzegorz Araminowicz <grzegorz.araminowicz at collabora.com>
AuthorDate: Fri Sep 20 12:53:45 2019 +0200
Commit:     Grzegorz Araminowicz <grzegorz.araminowicz at collabora.com>
CommitDate: Wed Sep 25 09:31:08 2019 +0200

    SmartArt Edit UI: remove node
    
    Removes data node from data model including associated presentation nodes,
    transition nodes and all connections between them (child-parent and
    presentation-of).
    It still doesn't update order of remaining connections after removal, so
    empty entries can happen. Additional step is needed or using better data
    structures.
    
    Change-Id: I96e0752b6ec5a19ae8e972dbd421314e6c442b53
    Reviewed-on: https://gerrit.libreoffice.org/79279
    Tested-by: Jenkins
    Reviewed-by: Grzegorz Araminowicz <grzegorz.araminowicz at collabora.com>

diff --git a/cui/source/dialogs/DiagramDialog.cxx b/cui/source/dialogs/DiagramDialog.cxx
index 4891ef93daee..f3a4a069a19c 100644
--- a/cui/source/dialogs/DiagramDialog.cxx
+++ b/cui/source/dialogs/DiagramDialog.cxx
@@ -20,10 +20,12 @@ DiagramDialog::DiagramDialog(weld::Window* pWindow,
     , mpBtnOk(m_xBuilder->weld_button("btnOk"))
     , mpBtnCancel(m_xBuilder->weld_button("btnCancel"))
     , mpBtnAdd(m_xBuilder->weld_button("btnAdd"))
+    , mpBtnRemove(m_xBuilder->weld_button("btnRemove"))
     , mpTreeDiagram(m_xBuilder->weld_tree_view("treeDiagram"))
     , mpTextAdd(m_xBuilder->weld_text_view("textAdd"))
 {
     mpBtnAdd->connect_clicked(LINK(this, DiagramDialog, OnAddClick));
+    mpBtnRemove->connect_clicked(LINK(this, DiagramDialog, OnRemoveClick));
 
     populateTree(nullptr, OUString());
 
@@ -40,15 +42,28 @@ IMPL_LINK_NOARG(DiagramDialog, OnAddClick, weld::Button&, void)
     OUString sText = mpTextAdd->get_text();
     if (!sText.isEmpty())
     {
+        OUString sNodeId = mpDiagramData->addNode(sText);
         std::unique_ptr<weld::TreeIter> pEntry(mpTreeDiagram->make_iterator());
-        mpTreeDiagram->insert(nullptr, -1, &sText, nullptr, nullptr, nullptr, nullptr, false,
+        mpTreeDiagram->insert(nullptr, -1, &sText, &sNodeId, nullptr, nullptr, nullptr, false,
                               pEntry.get());
         mpTreeDiagram->select(*pEntry);
-        mpDiagramData->addNode(sText);
         comphelper::dispatchCommand(".uno:RegenerateDiagram", {});
     }
 }
 
+IMPL_LINK_NOARG(DiagramDialog, OnRemoveClick, weld::Button&, void)
+{
+    std::unique_ptr<weld::TreeIter> pEntry(mpTreeDiagram->make_iterator());
+    if (mpTreeDiagram->get_selected(pEntry.get()))
+    {
+        if (mpDiagramData->removeNode(mpTreeDiagram->get_id(*pEntry)))
+        {
+            mpTreeDiagram->remove(*pEntry);
+            comphelper::dispatchCommand(".uno:RegenerateDiagram", {});
+        }
+    }
+}
+
 void DiagramDialog::populateTree(const weld::TreeIter* pParent, const OUString& rParentId)
 {
     auto aItems = mpDiagramData->getChildren(rParentId);
diff --git a/cui/source/inc/DiagramDialog.hxx b/cui/source/inc/DiagramDialog.hxx
index 461ffee9a7e6..e97144050a0e 100644
--- a/cui/source/inc/DiagramDialog.hxx
+++ b/cui/source/inc/DiagramDialog.hxx
@@ -27,10 +27,12 @@ private:
     std::unique_ptr<weld::Button> mpBtnOk;
     std::unique_ptr<weld::Button> mpBtnCancel;
     std::unique_ptr<weld::Button> mpBtnAdd;
+    std::unique_ptr<weld::Button> mpBtnRemove;
     std::unique_ptr<weld::TreeView> mpTreeDiagram;
     std::unique_ptr<weld::TextView> mpTextAdd;
 
     DECL_LINK(OnAddClick, weld::Button&, void);
+    DECL_LINK(OnRemoveClick, weld::Button&, void);
 
     void populateTree(const weld::TreeIter* pParent, const OUString& rParentId);
 };
diff --git a/cui/uiconfig/ui/diagramdialog.ui b/cui/uiconfig/ui/diagramdialog.ui
index 98a67717209a..c05031f19bc4 100644
--- a/cui/uiconfig/ui/diagramdialog.ui
+++ b/cui/uiconfig/ui/diagramdialog.ui
@@ -129,6 +129,20 @@
                 <property name="position">1</property>
               </packing>
             </child>
+            <child>
+              <object class="GtkButton" id="btnRemove">
+                <property name="label">gtk-remove</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="use_stock">True</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="position">2</property>
+              </packing>
+            </child>
           </object>
           <packing>
             <property name="expand">False</property>
diff --git a/include/svx/DiagramDataInterface.hxx b/include/svx/DiagramDataInterface.hxx
index aaa3a46968b3..f64dc3a09316 100644
--- a/include/svx/DiagramDataInterface.hxx
+++ b/include/svx/DiagramDataInterface.hxx
@@ -38,8 +38,10 @@ public:
     virtual std::vector<std::pair<OUString, OUString>>
     getChildren(const OUString& rParentId) const = 0;
 
-    // add new top-level node to data model
-    virtual void addNode(const OUString& rText) = 0;
+    // add new top-level node to data model, returns its id
+    virtual OUString addNode(const OUString& rText) = 0;
+
+    virtual bool removeNode(const OUString& rNodeId) = 0;
 
 protected:
     ~DiagramDataInterface() throw() {}
diff --git a/oox/source/drawingml/diagram/datamodel.cxx b/oox/source/drawingml/diagram/datamodel.cxx
index 1f1794b31854..6b7d05ebe58d 100644
--- a/oox/source/drawingml/diagram/datamodel.cxx
+++ b/oox/source/drawingml/diagram/datamodel.cxx
@@ -29,6 +29,7 @@
 #include <svx/DiagramDataInterface.hxx>
 #include <comphelper/xmltools.hxx>
 
+#include <unordered_set>
 #include <iostream>
 #include <fstream>
 
@@ -137,6 +138,12 @@ std::vector<std::pair<OUString, OUString>> DiagramData::getChildren(const OUStri
                     pChild->second->msModelId,
                     pChild->second->mpShape->getTextBody()->getParagraphs().front()->getRuns().front()->getText());
         }
+
+    // HACK: empty items shouldn't appear there
+    aChildren.erase(std::remove_if(aChildren.begin(), aChildren.end(),
+                                   [](const std::pair<OUString, OUString>& aItem) { return aItem.first.isEmpty(); }),
+                    aChildren.end());
+
     return aChildren;
 }
 
@@ -154,7 +161,7 @@ void DiagramData::addConnection(sal_Int32 nType, const OUString& sSourceId, cons
     rCxn.mnSourceOrder = nMaxOrd + 1;
 }
 
-void DiagramData::addNode(const OUString& rText)
+OUString DiagramData::addNode(const OUString& rText)
 {
     const dgm::Point& rDataRoot = *getRootPoint();
     OUString sPresRoot;
@@ -163,11 +170,13 @@ void DiagramData::addNode(const OUString& rText)
             sPresRoot = aCxn.msDestId;
 
     if (sPresRoot.isEmpty())
-        return;
+        return OUString();
+
+    OUString sNewNodeId = OStringToOUString(comphelper::xml::generateGUIDString(), RTL_TEXTENCODING_UTF8);
 
     dgm::Point aDataPoint;
     aDataPoint.mnType = XML_node;
-    aDataPoint.msModelId = OStringToOUString(comphelper::xml::generateGUIDString(), RTL_TEXTENCODING_UTF8);
+    aDataPoint.msModelId = sNewNodeId;
     aDataPoint.mpShape.reset(new Shape());
     aDataPoint.mpShape->setTextBody(std::make_shared<TextBody>());
     TextRunPtr pTextRun(new TextRun());
@@ -208,6 +217,59 @@ void DiagramData::addNode(const OUString& rText)
     maPoints.push_back(aPresPoint);
 
     build();
+    return sNewNodeId;
+}
+
+bool DiagramData::removeNode(const OUString& rNodeId)
+{
+    // check if it doesn't have children
+    for (const auto& aCxn : maConnections)
+        if (aCxn.mnType == XML_parOf && aCxn.msSourceId == rNodeId)
+        {
+            SAL_WARN("oox.drawingml", "Node has children - can't be removed");
+            return false;
+        }
+
+    dgm::Connection aParCxn;
+    for (const auto& aCxn : maConnections)
+        if (aCxn.mnType == XML_parOf && aCxn.msDestId == rNodeId)
+            aParCxn = aCxn;
+
+    std::unordered_set<OUString> aIdsToRemove;
+    aIdsToRemove.insert(rNodeId);
+    if (!aParCxn.msParTransId.isEmpty())
+        aIdsToRemove.insert(aParCxn.msParTransId);
+    if (!aParCxn.msSibTransId.isEmpty())
+        aIdsToRemove.insert(aParCxn.msSibTransId);
+
+    for (const dgm::Point& rPoint : maPoints)
+        if (aIdsToRemove.count(rPoint.msPresentationAssociationId))
+            aIdsToRemove.insert(rPoint.msModelId);
+
+    // instert also transition nodes
+    for (const auto& aCxn : maConnections)
+        if (aIdsToRemove.count(aCxn.msSourceId) || aIdsToRemove.count(aCxn.msDestId))
+            if (!aCxn.msPresId.isEmpty())
+                aIdsToRemove.insert(aCxn.msPresId);
+
+    // remove connections
+    maConnections.erase(std::remove_if(maConnections.begin(), maConnections.end(),
+                                       [aIdsToRemove](const dgm::Connection& rCxn) {
+                                           return aIdsToRemove.count(rCxn.msSourceId) || aIdsToRemove.count(rCxn.msDestId);
+                                       }),
+                        maConnections.end());
+
+    // remove data and presentation nodes
+    maPoints.erase(std::remove_if(maPoints.begin(), maPoints.end(),
+                                  [aIdsToRemove](const dgm::Point& rPoint) {
+                                      return aIdsToRemove.count(rPoint.msModelId);
+                                  }),
+                   maPoints.end());
+
+    // TODO: fix source/dest order
+
+    build();
+    return true;
 }
 
 #ifdef DEBUG_OOX_DIAGRAM
diff --git a/oox/source/drawingml/diagram/datamodel.hxx b/oox/source/drawingml/diagram/datamodel.hxx
index b4c7ce7f82f7..7f7f0f4910c5 100644
--- a/oox/source/drawingml/diagram/datamodel.hxx
+++ b/oox/source/drawingml/diagram/datamodel.hxx
@@ -182,7 +182,8 @@ public:
     void dump() const;
     OUString getString() const override;
     std::vector<std::pair<OUString, OUString>> getChildren(const OUString& rParentId) const override;
-    void addNode(const OUString& rText) override;
+    OUString addNode(const OUString& rText) override;
+    bool removeNode(const OUString& rNodeId) override;
 
 private:
     void getChildrenString(OUStringBuffer& rBuf, const dgm::Point* pPoint, sal_Int32 nLevel) const;


More information about the Libreoffice-commits mailing list