diff options
author | Grzegorz Araminowicz <grzegorz.araminowicz@collabora.com> | 2019-08-30 10:20:38 +0200 |
---|---|---|
committer | Grzegorz Araminowicz <grzegorz.araminowicz@collabora.com> | 2019-09-02 12:38:31 +0200 |
commit | 6eb7dd4a2683fb4c28506a464317d7ee54cfe1de (patch) | |
tree | efb2905d640dfcb080355afd228c0c76864026d9 | |
parent | 1485bcc796dd8bd53762368ec4a1345ddb7cda72 (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.cxx | 20 | ||||
-rw-r--r-- | cui/source/inc/DiagramDialog.hxx | 4 | ||||
-rw-r--r-- | cui/uiconfig/ui/diagramdialog.ui | 39 | ||||
-rw-r--r-- | include/svx/DiagramDataInterface.hxx | 3 | ||||
-rw-r--r-- | oox/source/drawingml/diagram/diagram.cxx | 76 | ||||
-rw-r--r-- | oox/source/drawingml/diagram/diagram.hxx | 2 |
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; |