summaryrefslogtreecommitdiff
path: root/oox
diff options
context:
space:
mode:
authorGrzegorz Araminowicz <grzegorz.araminowicz@collabora.com>2019-09-20 12:53:45 +0200
committerGrzegorz Araminowicz <grzegorz.araminowicz@collabora.com>2019-09-25 09:31:08 +0200
commit711c0b6331958da4fd53eb6c4f9ecd5a422bb186 (patch)
treee17b463e3f813cc4a4d849d91397adc610f121db /oox
parentb13421011d9377676e1adc282634991d5064a866 (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.cxx68
-rw-r--r--oox/source/drawingml/diagram/datamodel.hxx3
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;