diff options
author | Grzegorz Araminowicz <grzegorz.araminowicz@collabora.com> | 2019-09-20 12:53:45 +0200 |
---|---|---|
committer | Grzegorz Araminowicz <grzegorz.araminowicz@collabora.com> | 2019-09-25 09:31:08 +0200 |
commit | 711c0b6331958da4fd53eb6c4f9ecd5a422bb186 (patch) | |
tree | e17b463e3f813cc4a4d849d91397adc610f121db /oox | |
parent | b13421011d9377676e1adc282634991d5064a866 (diff) |
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@collabora.com>
Diffstat (limited to 'oox')
-rw-r--r-- | oox/source/drawingml/diagram/datamodel.cxx | 68 | ||||
-rw-r--r-- | oox/source/drawingml/diagram/datamodel.hxx | 3 |
2 files changed, 67 insertions, 4 deletions
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; |