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

Grzegorz Araminowicz (via logerrit) logerrit at kemper.freedesktop.org
Mon Sep 2 10:39:10 UTC 2019


 cui/source/dialogs/DiagramDialog.cxx     |   20 ++++++++
 cui/source/inc/DiagramDialog.hxx         |    4 +
 cui/uiconfig/ui/diagramdialog.ui         |   39 +++++++++++++++
 include/svx/DiagramDataInterface.hxx     |    3 +
 oox/source/drawingml/diagram/diagram.cxx |   76 +++++++++++++++++++++++++++++++
 oox/source/drawingml/diagram/diagram.hxx |    2 
 6 files changed, 142 insertions(+), 2 deletions(-)

New commits:
commit 6eb7dd4a2683fb4c28506a464317d7ee54cfe1de
Author:     Grzegorz Araminowicz <grzegorz.araminowicz at collabora.com>
AuthorDate: Fri Aug 30 10:20:38 2019 +0200
Commit:     Grzegorz Araminowicz <grzegorz.araminowicz at collabora.com>
CommitDate: Mon Sep 2 12:38:31 2019 +0200

    SmartArt edit UI: add new node
    
    First approach to adding new node. Currently it's possible only to add
    top-level node to the end of diagram.
    
    Change-Id: Icd9530ab2fb8987a1690ffc96c244cc845b72eba
    Reviewed-on: https://gerrit.libreoffice.org/78286
    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 c48e8f58089d..f3b84c0fcc4e 100644
--- a/cui/source/dialogs/DiagramDialog.cxx
+++ b/cui/source/dialogs/DiagramDialog.cxx
@@ -9,7 +9,9 @@
 
 #include <DiagramDialog.hxx>
 
+#include <comphelper/dispatchcommand.hxx>
 #include <svx/DiagramDataInterface.hxx>
+#include <com/sun/star/beans/PropertyValue.hpp>
 
 DiagramDialog::DiagramDialog(weld::Window* pWindow,
                              std::shared_ptr<DiagramDataInterface> pDiagramData)
@@ -17,8 +19,12 @@ DiagramDialog::DiagramDialog(weld::Window* pWindow,
     , mpDiagramData(pDiagramData)
     , mpBtnOk(m_xBuilder->weld_button("btnOk"))
     , mpBtnCancel(m_xBuilder->weld_button("btnCancel"))
+    , mpBtnAdd(m_xBuilder->weld_button("btnAdd"))
     , mpTreeDiagram(m_xBuilder->weld_tree_view("treeDiagram"))
+    , mpTextAdd(m_xBuilder->weld_text_view("textAdd"))
 {
+    mpBtnAdd->connect_clicked(LINK(this, DiagramDialog, OnAddClick));
+
     populateTree(nullptr, OUString());
 
     // expand all items
@@ -29,6 +35,20 @@ DiagramDialog::DiagramDialog(weld::Window* pWindow,
     });
 }
 
+IMPL_LINK_NOARG(DiagramDialog, OnAddClick, weld::Button&, void)
+{
+    OUString sText = mpTextAdd->get_text();
+    if (!sText.isEmpty())
+    {
+        std::unique_ptr<weld::TreeIter> pEntry(mpTreeDiagram->make_iterator());
+        mpTreeDiagram->insert(nullptr, -1, &sText, nullptr, nullptr, nullptr, nullptr, false,
+                              pEntry.get());
+        mpTreeDiagram->select(*pEntry);
+        mpDiagramData->addNode(sText);
+        comphelper::dispatchCommand(".uno:RegenerateDiagram", {});
+    }
+}
+
 void DiagramDialog::populateTree(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 ec47de6414bd..c1ce3316427e 100644
--- a/cui/source/inc/DiagramDialog.hxx
+++ b/cui/source/inc/DiagramDialog.hxx
@@ -26,7 +26,11 @@ private:
     std::shared_ptr<DiagramDataInterface> mpDiagramData;
     std::unique_ptr<weld::Button> mpBtnOk;
     std::unique_ptr<weld::Button> mpBtnCancel;
+    std::unique_ptr<weld::Button> mpBtnAdd;
     std::unique_ptr<weld::TreeView> mpTreeDiagram;
+    std::unique_ptr<weld::TextView> mpTextAdd;
+
+    DECL_LINK(OnAddClick, weld::Button&, void);
 
     void populateTree(weld::TreeIter* pParent, const OUString& rParentId);
 };
diff --git a/cui/uiconfig/ui/diagramdialog.ui b/cui/uiconfig/ui/diagramdialog.ui
index 000f340f028a..c52376f0b3a3 100644
--- a/cui/uiconfig/ui/diagramdialog.ui
+++ b/cui/uiconfig/ui/diagramdialog.ui
@@ -49,7 +49,7 @@
           <packing>
             <property name="expand">False</property>
             <property name="fill">False</property>
-            <property name="position">1</property>
+            <property name="position">2</property>
           </packing>
         </child>
         <child>
@@ -57,7 +57,6 @@
             <property name="visible">True</property>
             <property name="can_focus">True</property>
             <property name="headers_visible">False</property>
-            <property name="show_expanders">True</property>
             <child internal-child="selection">
               <object class="GtkTreeSelection"/>
             </child>
@@ -68,6 +67,42 @@
             <property name="position">0</property>
           </packing>
         </child>
+        <child>
+          <object class="GtkBox">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <child>
+              <object class="GtkTextView" id="textAdd">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+              </object>
+              <packing>
+                <property name="expand">True</property>
+                <property name="fill">True</property>
+                <property name="position">0</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkButton" id="btnAdd">
+                <property name="label">gtk-add</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">1</property>
+              </packing>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+            <property name="position">1</property>
+          </packing>
+        </child>
       </object>
     </child>
     <action-widgets>
diff --git a/include/svx/DiagramDataInterface.hxx b/include/svx/DiagramDataInterface.hxx
index 9174a2b2fefe..aaa3a46968b3 100644
--- a/include/svx/DiagramDataInterface.hxx
+++ b/include/svx/DiagramDataInterface.hxx
@@ -38,6 +38,9 @@ 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;
+
 protected:
     ~DiagramDataInterface() throw() {}
 };
diff --git a/oox/source/drawingml/diagram/diagram.cxx b/oox/source/drawingml/diagram/diagram.cxx
index 4fcfbe760699..a6e8ee28acf5 100644
--- a/oox/source/drawingml/diagram/diagram.cxx
+++ b/oox/source/drawingml/diagram/diagram.cxx
@@ -40,6 +40,7 @@
 #include <basegfx/matrix/b2dhommatrix.hxx>
 #include <svx/svdpage.hxx>
 #include <svx/DiagramDataInterface.hxx>
+#include <comphelper/xmltools.hxx>
 
 #include "diagramlayoutatoms.hxx"
 #include "layoutatomvisitors.hxx"
@@ -156,6 +157,76 @@ std::vector<std::pair<OUString, OUString>> DiagramData::getChildren(const OUStri
     return aChildren;
 }
 
+void DiagramData::addConnection(sal_Int32 nType, const OUString& sSourceId, const OUString& sDestId)
+{
+    sal_Int32 nMaxOrd = -1;
+    for (const auto& aCxn : maConnections)
+        if (aCxn.mnType == nType && aCxn.msSourceId == sSourceId)
+            nMaxOrd = std::max(nMaxOrd, aCxn.mnSourceOrder);
+
+    dgm::Connection& rCxn = maConnections.emplace_back();
+    rCxn.mnType = nType;
+    rCxn.msSourceId = sSourceId;
+    rCxn.msDestId = sDestId;
+    rCxn.mnSourceOrder = nMaxOrd + 1;
+}
+
+void DiagramData::addNode(const OUString& rText)
+{
+    const dgm::Point& rDataRoot = *getRootPoint();
+    OUString sPresRoot;
+    for (const auto& aCxn : maConnections)
+        if (aCxn.mnType == XML_presOf && aCxn.msSourceId == rDataRoot.msModelId)
+            sPresRoot = aCxn.msDestId;
+
+    if (sPresRoot.isEmpty())
+        return;
+
+    dgm::Point aDataPoint;
+    aDataPoint.mnType = XML_node;
+    aDataPoint.msModelId = OStringToOUString(comphelper::xml::generateGUIDString(), RTL_TEXTENCODING_UTF8);
+    aDataPoint.mpShape.reset(new Shape());
+    aDataPoint.mpShape->setTextBody(std::make_shared<TextBody>());
+    TextRunPtr pTextRun(new TextRun());
+    pTextRun->getText() = rText;
+    aDataPoint.mpShape->getTextBody()->addParagraph().addRun(pTextRun);
+
+    OUString sDataSibling;
+    for (const auto& aCxn : maConnections)
+        if (aCxn.mnType == XML_parOf && aCxn.msSourceId == rDataRoot.msModelId)
+            sDataSibling = aCxn.msDestId;
+
+    OUString sPresSibling;
+    for (const auto& aCxn : maConnections)
+        if (aCxn.mnType == XML_presOf && aCxn.msSourceId == sDataSibling)
+            sPresSibling = aCxn.msDestId;
+
+    dgm::Point aPresPoint;
+    aPresPoint.mnType = XML_pres;
+    aPresPoint.msModelId = OStringToOUString(comphelper::xml::generateGUIDString(), RTL_TEXTENCODING_UTF8);
+    aPresPoint.mpShape.reset(new Shape());
+    aPresPoint.msPresentationAssociationId = aDataPoint.msModelId;
+    if (!sPresSibling.isEmpty())
+    {
+        // no idea where to get these values from, so copy from previous sibling
+        const dgm::Point* pSiblingPoint = maPointNameMap[sPresSibling];
+        aPresPoint.msPresentationLayoutName = pSiblingPoint->msPresentationLayoutName;
+        aPresPoint.msPresentationLayoutStyleLabel = pSiblingPoint->msPresentationLayoutStyleLabel;
+        aPresPoint.mnLayoutStyleIndex = pSiblingPoint->mnLayoutStyleIndex;
+        aPresPoint.mnLayoutStyleCount = pSiblingPoint->mnLayoutStyleCount;
+    }
+
+    addConnection(XML_parOf, rDataRoot.msModelId, aDataPoint.msModelId);
+    addConnection(XML_presParOf, sPresRoot, aPresPoint.msModelId);
+    addConnection(XML_presOf, aDataPoint.msModelId, aPresPoint.msModelId);
+
+    // adding at the end, so that references are not invalidated inbetween
+    maPoints.push_back(aDataPoint);
+    maPoints.push_back(aPresPoint);
+
+    build();
+}
+
 #ifdef DEBUG_OOX_DIAGRAM
 OString normalizeDotName( const OUString& rStr )
 {
@@ -239,6 +310,11 @@ static void sortChildrenByZOrder(const ShapePtr& pShape)
 void DiagramData::build()
 {
     // build name-object maps
+    maPointNameMap.clear();
+    maPointsPresNameMap.clear();
+    maConnectionNameMap.clear();
+    maPresOfNameMap.clear();
+
 #ifdef DEBUG_OOX_DIAGRAM
     std::ofstream output("tree.dot");
 
diff --git a/oox/source/drawingml/diagram/diagram.hxx b/oox/source/drawingml/diagram/diagram.hxx
index 66b57b145c3b..84526a55425c 100644
--- a/oox/source/drawingml/diagram/diagram.hxx
+++ b/oox/source/drawingml/diagram/diagram.hxx
@@ -194,9 +194,11 @@ 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;
 
 private:
     void getChildrenString(OUStringBuffer& rBuf, const dgm::Point* pPoint, sal_Int32 nLevel) const;
+    void addConnection(sal_Int32 nType, const OUString& sSourceId, const OUString& sDestId);
 
     ::std::vector<OUString>  maExtDrawings;
     FillPropertiesPtr mpFillProperties;


More information about the Libreoffice-commits mailing list