Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
180 changes: 75 additions & 105 deletions modules/editor/grapheditor/editor/graph/abstractnodegraph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include "graphnode.h"

#include <QFile>
#include <pugixml.hpp>

namespace {
const char *gGraph("graph");
Expand Down Expand Up @@ -194,107 +195,96 @@ void AbstractNodeGraph::load(const TString &path) {
}
m_nodes.clear();

QFile loadFile(path.data());
if(!loadFile.open(QIODevice::ReadOnly)) {
qWarning("Couldn't open file.");
return;
}
QByteArray data(loadFile.readAll());
loadFile.close();

QDomDocument doc;
doc.setContent(data);
pugi::xml_document doc;
QFile file(path.data());
if(file.open(QIODevice::ReadOnly | QIODevice::Text)) {
pugi::xml_document doc;
if(doc.load_string(file.readAll().data()).status == pugi::status_ok) {
pugi::xml_node document = doc.first_child();
int version = document.attribute("version").as_int();

QDomElement document = doc.documentElement();
int version = document.attribute("version", "0").toInt();
blockSignals(true);

blockSignals(true);

QDomNode p = document.firstChild();
while(!p.isNull()) {
QDomElement element = p.toElement();
if(!element.isNull()) {
loadGraph(element);
}

p = p.nextSiblingElement();
}
pugi::xml_node root = document.first_child();
if(root) {
loadGraph(root);
}

blockSignals(false);
blockSignals(false);

emit graphUpdated();
emit graphUpdated();

if(version != m_version) {
save(path);
if(version != m_version) {
save(path);
}
}
}

emit graphLoaded();
}

void AbstractNodeGraph::save(const TString &path) {
QDomDocument xml;

QDomElement document = xml.createElement("document");
pugi::xml_document xml;

document.setAttribute("version", m_version);
pugi::xml_node document = xml.append_child("document");

saveGraph(document, xml);
document.append_attribute("version") = m_version;

xml.appendChild(document);
saveGraph(document);

QFile saveFile(path.data());
if(saveFile.open(QIODevice::WriteOnly)) {
saveFile.write(xml.toByteArray(4));
saveFile.close();
}
xml.save_file(path.data(), " ");
}

StringList AbstractNodeGraph::nodeList() const {
return StringList();
}

void AbstractNodeGraph::loadGraph(const QDomElement &parent) {
if(parent.tagName() == gGraph) {
QDomElement nodes = parent.firstChildElement(gNodes);
if(!nodes.isNull()) {
QDomElement nodeElement = nodes.firstChildElement();
while(!nodeElement.isNull()) {
int32_t index = nodeElement.attribute(gIndex, "-1").toInt();
TString type = nodeElement.attribute(gType).toStdString();
GraphNode *node = nullptr;
if(type.isEmpty()) {
node = fallbackRoot();
} else {
node = nodeCreate(type, index);
}
if(node) {
node->fromXml(nodeElement);
void AbstractNodeGraph::loadGraph(const pugi::xml_node &parent) {
if(std::string(parent.name()) == gGraph) {
pugi::xml_node nodes = parent.first_child();
while(nodes) {
std::string name(nodes.name());
if(name == gNodes) {
pugi::xml_node nodeElement = nodes.first_child();
while(nodeElement) {
int32_t index = nodeElement.attribute(gIndex).as_int(-1);
TString type = nodeElement.attribute(gType).value();
GraphNode *node = nullptr;
if(type.isEmpty()) {
node = fallbackRoot();
} else {
node = nodeCreate(type, index);
}
if(node) {
node->fromXml(nodeElement);
}

nodeElement = nodeElement.next_sibling();
}

nodeElement = nodeElement.nextSiblingElement();
}
}

onNodesLoaded();
if(name == gLinks) {
onNodesLoaded();

QDomElement links = parent.firstChildElement(gLinks);
if(!links.isNull()) {
QDomElement linkElement = links.firstChildElement();
while(!linkElement.isNull()) {
GraphNode *snd = node(linkElement.attribute(gSender).toInt());
GraphNode *rcv = node(linkElement.attribute(gReceiver).toInt());
pugi::xml_node linkElement = nodes.first_child();
while(linkElement) {
GraphNode *snd = node(linkElement.attribute(gSender).as_int());
GraphNode *rcv = node(linkElement.attribute(gReceiver).as_int());

if(snd && rcv) {
int index1 = linkElement.attribute(gOut).toInt();
NodePort *op = (index1 > -1) ? snd->port(index1) : nullptr;
int index2 = linkElement.attribute(gIn).toInt();
NodePort *ip = (index2 > -1) ? rcv->port(index2) : nullptr;
if(snd && rcv) {
int index1 = linkElement.attribute(gOut).as_int();
NodePort *op = (index1 > -1) ? snd->port(index1) : nullptr;
int index2 = linkElement.attribute(gIn).as_int();
NodePort *ip = (index2 > -1) ? rcv->port(index2) : nullptr;

linkCreate(snd, op, rcv, ip);
}
linkCreate(snd, op, rcv, ip);
}

linkElement = linkElement.nextSiblingElement();
linkElement = linkElement.next_sibling();
}
}

nodes = nodes.next_sibling();
}
}
}
Expand All @@ -307,52 +297,32 @@ GraphNode *AbstractNodeGraph::fallbackRoot() {
return nullptr;
}

void AbstractNodeGraph::saveGraph(QDomElement &parent, QDomDocument &xml) const {
QDomElement graph = xml.createElement(gGraph);
void AbstractNodeGraph::saveGraph(pugi::xml_node &parent) const {
pugi::xml_node graph = parent.append_child(gGraph);

QVariantList links;

QDomElement nodesElement = xml.createElement(gNodes);
QDomElement linksElement = xml.createElement(gLinks);
pugi::xml_node nodesElement = graph.append_child(gNodes);
pugi::xml_node linksElement = graph.append_child(gLinks);

for(auto node : m_nodes) {
QDomElement nodeElement = node->toXml(xml);

nodesElement.appendChild(nodeElement);
pugi::xml_node nodeElement = node->toXml();

for(auto link : saveLinks(node)) {
QDomElement linkElement = xml.createElement(gLink);
nodesElement.append_copy(nodeElement);

QVariantMap fields = link.toMap();
for(auto &key : fields.keys()) {
linkElement.setAttribute(key, fields.value(key).toString());
}
linksElement.appendChild(linkElement);
}
saveLinks(node, linksElement);
}

graph.appendChild(nodesElement);
graph.appendChild(linksElement);

parent.appendChild(graph);
}

QVariantList AbstractNodeGraph::saveLinks(GraphNode *node) const {
QVariantList result;

void AbstractNodeGraph::saveLinks(GraphNode *node, pugi::xml_node &parent) const {
for(auto l : m_links) {
if(l->sender == node) {
QVariantMap link;
link[gSender] = AbstractNodeGraph::node(l->sender);
link[gOut] = (l->oport != nullptr) ? l->sender->portPosition(l->oport) : -1;
link[gReceiver] = AbstractNodeGraph::node(l->receiver);
link[gIn] = (l->iport != nullptr) ? l->receiver->portPosition(l->iport) : -1;
pugi::xml_node link = parent.append_child(gLink);

result.push_back(link);
link.append_attribute(gSender) = AbstractNodeGraph::node(l->sender);
link.append_attribute(gOut) = (l->oport != nullptr) ? l->sender->portPosition(l->oport) : -1;
link.append_attribute(gReceiver) = AbstractNodeGraph::node(l->receiver);
link.append_attribute(gIn) = (l->iport != nullptr) ? l->receiver->portPosition(l->iport) : -1;
}
}

return result;
}

const AbstractNodeGraph::NodeList &AbstractNodeGraph::nodes() const {
Expand Down
10 changes: 4 additions & 6 deletions modules/editor/grapheditor/editor/graph/abstractnodegraph.h
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
#ifndef ABSTRACTNODEGRAPH_H
#define ABSTRACTNODEGRAPH_H

#include <QVariant>
#include <QJsonDocument>
#include <QDomDocument>
#include <QObject>

#include <stdint.h>

Expand Down Expand Up @@ -77,15 +75,15 @@ class NODEGRAPH_EXPORT AbstractNodeGraph : public QObject {
void menuVisible(bool visible);

protected:
virtual void loadGraph(const QDomElement &parent);
virtual void loadGraph(const pugi::xml_node &parent);

virtual void onNodesLoaded();

virtual void saveGraph(QDomElement &parent, QDomDocument &xml) const;
virtual void saveGraph(pugi::xml_node &parent) const;

virtual GraphNode *fallbackRoot();

QVariantList saveLinks(GraphNode *node) const;
void saveLinks(GraphNode *node, pugi::xml_node &parent) const;

friend class DeleteNodes;

Expand Down
29 changes: 8 additions & 21 deletions modules/editor/grapheditor/editor/graph/actions/deletenodes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,45 +9,32 @@ DeleteNodes::DeleteNodes(const std::list<int32_t> &selection, GraphController *c
}

void DeleteNodes::undo() {
m_controller->graph()->loadGraph(m_document.firstChildElement());
m_controller->graph()->loadGraph(m_document.first_child());
m_controller->selectNodes(m_indices);
}

void DeleteNodes::redo() {
m_document.clear();
m_document.reset();

auto g = m_controller->graph();

QDomElement graphElement = m_document.createElement("graph");
pugi::xml_node graphElement = m_document.append_child("graph");

QDomElement nodesElement = m_document.createElement("nodes");
QDomElement linksElement = m_document.createElement("links");
pugi::xml_node nodesElement = graphElement.append_child("nodes");
pugi::xml_node linksElement = graphElement.append_child("links");

AbstractNodeGraph::NodeList list;
for(auto &it : m_indices) {
GraphNode *node = g->node(it);
list.push_back(node);
for(auto link : g->saveLinks(node)) {
QDomElement linkElement = m_document.createElement("link");

QVariantMap fields = link.toMap();
for(auto &key : fields.keys()) {
linkElement.setAttribute(key, fields.value(key).toString());
}
linksElement.appendChild(linkElement);
}

nodesElement.append_copy(node->toXml());
g->saveLinks(node, linksElement);
}

for(auto it : list) {
QDomElement element = it->toXml(m_document);
nodesElement.appendChild(element);
g->nodeDelete(it);
}

graphElement.appendChild(nodesElement);
graphElement.appendChild(linksElement);

m_document.appendChild(graphElement);

emit g->graphUpdated();
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@

#include "../graphcontroller.h"

#include <pugixml.hpp>

class DeleteNodes : public UndoCommand {
public:
DeleteNodes(const std::list<int32_t> &selection, GraphController *ctrl, const QString &name = QObject::tr("Delete Node"), QUndoCommand *parent = nullptr);
Expand All @@ -12,7 +14,7 @@ class DeleteNodes : public UndoCommand {

private:
std::list<int32_t> m_indices;
QDomDocument m_document;
pugi::xml_document m_document;

GraphController *m_controller;

Expand Down
12 changes: 6 additions & 6 deletions modules/editor/grapheditor/editor/graph/actions/pastenodes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ PasteNodes::PasteNodes(const std::string &data, int x, int y, GraphController *c
m_pos(x, y),
UndoCommand(name, ctrl, parent) {

m_document.setContent(QByteArray(data.c_str()));
m_document.load_string(data.c_str());
}

void PasteNodes::undo() {
Expand All @@ -30,11 +30,11 @@ void PasteNodes::redo() {

AbstractNodeGraph::NodeList nodes;

QDomElement nodesElement = m_document.firstChildElement();
QDomElement nodeElement = nodesElement.firstChildElement();
while(!nodeElement.isNull()) {
pugi::xml_node nodesElement = m_document.first_child();
pugi::xml_node nodeElement = nodesElement.first_child();
while(nodeElement) {
int32_t index = -1;
const std::string type = nodeElement.attribute("type").toStdString();
const std::string type = nodeElement.attribute("type").value();
GraphNode *node = g->nodeCreate(type, index);
if(node) {
node->fromXml(nodeElement);
Expand All @@ -46,7 +46,7 @@ void PasteNodes::redo() {
nodes.push_back(node);
}

nodeElement = nodeElement.nextSiblingElement();
nodeElement = nodeElement.next_sibling();
}

for(auto it : nodes) {
Expand Down
4 changes: 3 additions & 1 deletion modules/editor/grapheditor/editor/graph/actions/pastenodes.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@

#include "../graphcontroller.h"

#include <pugixml.hpp>

class PasteNodes : public UndoCommand {
public:
PasteNodes(const std::string &data, int x, int y, GraphController *ctrl, const QString &name = QObject::tr("Paste Node"), QUndoCommand *parent = nullptr);
Expand All @@ -13,7 +15,7 @@ class PasteNodes : public UndoCommand {
private:
GraphController *m_controller;

QDomDocument m_document;
pugi::xml_document m_document;
std::list<int32_t> m_list;
std::list<int32_t> m_lastSelect;

Expand Down
Loading
Loading