summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGrzegorz Araminowicz <grzegorz.araminowicz@collabora.com>2019-08-30 10:20:38 +0200
committerGrzegorz Araminowicz <grzegorz.araminowicz@collabora.com>2019-09-02 12:38:31 +0200
commit6eb7dd4a2683fb4c28506a464317d7ee54cfe1de (patch)
treeefb2905d640dfcb080355afd228c0c76864026d9
parent1485bcc796dd8bd53762368ec4a1345ddb7cda72 (diff)
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@collabora.com>
-rw-r--r--cui/source/dialogs/DiagramDialog.cxx20
-rw-r--r--cui/source/inc/DiagramDialog.hxx4
-rw-r--r--cui/uiconfig/ui/diagramdialog.ui39
-rw-r--r--include/svx/DiagramDataInterface.hxx3
-rw-r--r--oox/source/drawingml/diagram/diagram.cxx76
-rw-r--r--oox/source/drawingml/diagram/diagram.hxx2
6 files changed, 142 insertions, 2 deletions
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;