From 5fa28b1cb5517ce2b97410127a942386362554c4 Mon Sep 17 00:00:00 2001
From: Martin Hanzik <martin@hanzik.com>
Date: Tue, 1 May 2018 23:23:14 +0200
Subject: [PATCH] Bunch of fixes

---
 agui2/src/Converter.cpp                 | 10 ++++---
 agui2/src/Converter.hpp                 |  2 +-
 agui2/src/Graphics/GraphicsBox.hpp      |  2 +-
 agui2/src/Graphics/InputGraphicsBox.cpp | 10 +++++--
 agui2/src/Graphics/InputGraphicsBox.hpp |  2 ++
 agui2/src/MainWindow.cpp                | 35 +++++++++++++++++++------
 6 files changed, 45 insertions(+), 16 deletions(-)

diff --git a/agui2/src/Converter.cpp b/agui2/src/Converter.cpp
index 6dc150df58..2994c99856 100644
--- a/agui2/src/Converter.cpp
+++ b/agui2/src/Converter.cpp
@@ -57,7 +57,7 @@ namespace Converter {
     }
 
 
-    std::optional<QString> toXML(const std::shared_ptr<abstraction::OperationAbstraction>& data) {
+    std::optional<QString> toXML(const std::shared_ptr<abstraction::OperationAbstraction>& data, bool indent) {
         try {
             auto res = abstraction::XmlRegistry::getXmlComposerAbstraction(data->getReturnType());
             res->attachInput(data, 0, true);
@@ -70,9 +70,11 @@ namespace Converter {
 
             auto text = QString::fromStdString(result);
 
-            QDomDocument doc;
-            if (doc.setContent(text, false))
-                return doc.toString(4);
+            if (indent) {
+                QDomDocument doc;
+                if (doc.setContent(text, false))
+                    return doc.toString(4);
+            }
             return text;
 
         }
diff --git a/agui2/src/Converter.hpp b/agui2/src/Converter.hpp
index 132e7e7820..84916a7437 100644
--- a/agui2/src/Converter.hpp
+++ b/agui2/src/Converter.hpp
@@ -11,7 +11,7 @@
 namespace Converter {
     std::optional<QString> toString(const std::shared_ptr<abstraction::OperationAbstraction>& data);
     std::optional<QString> toDOT(const std::shared_ptr<abstraction::OperationAbstraction>& data);
-    std::optional<QString> toXML(const std::shared_ptr<abstraction::OperationAbstraction>& data);
+    std::optional<QString> toXML(const std::shared_ptr<abstraction::OperationAbstraction>& data, bool indent = true);
     std::optional<QImage> toPNG(const std::shared_ptr<abstraction::OperationAbstraction>& data);
 
     std::shared_ptr<abstraction::OperationAbstraction> tryParse(const QString& input);
diff --git a/agui2/src/Graphics/GraphicsBox.hpp b/agui2/src/Graphics/GraphicsBox.hpp
index 98177c67fa..856d97c577 100644
--- a/agui2/src/Graphics/GraphicsBox.hpp
+++ b/agui2/src/Graphics/GraphicsBox.hpp
@@ -36,7 +36,7 @@ private:
     std::unique_ptr<ModelBox> modelBox;
 
     std::vector<InputConnectionBox*> inputConnectionBoxes;
-    OutputConnectionBox* outputConnectionBox;
+    OutputConnectionBox* outputConnectionBox = nullptr;
 
     static std::vector<GraphicsBox*> allGraphicsBoxes;
 };
diff --git a/agui2/src/Graphics/InputGraphicsBox.cpp b/agui2/src/Graphics/InputGraphicsBox.cpp
index 992b473aa0..fd74b603cb 100644
--- a/agui2/src/Graphics/InputGraphicsBox.cpp
+++ b/agui2/src/Graphics/InputGraphicsBox.cpp
@@ -26,8 +26,7 @@ void InputGraphicsBox::on_SetInput()
         model->setAutomaton(inputDialog->getAutomaton());
     }
 
-    this->color = model->getAutomaton() ? Qt::blue : Qt::red;
-    this->update();
+    this->updateColor();
 }
 
 void InputGraphicsBox::contextMenuEvent(QGraphicsSceneContextMenuEvent* event) {
@@ -38,3 +37,10 @@ void InputGraphicsBox::contextMenuEvent(QGraphicsSceneContextMenuEvent* event) {
     ungrabMouse();
     event->accept();
 }
+
+void InputGraphicsBox::updateColor() {
+    auto* model = dynamic_cast<InputModelBox*>(this->getModelBox());
+    Q_ASSERT(model);
+    this->color = model->getAutomaton() ? Qt::blue : Qt::red;
+    this->update();
+}
diff --git a/agui2/src/Graphics/InputGraphicsBox.hpp b/agui2/src/Graphics/InputGraphicsBox.hpp
index 28f3f9acf1..a5a6fccc16 100644
--- a/agui2/src/Graphics/InputGraphicsBox.hpp
+++ b/agui2/src/Graphics/InputGraphicsBox.hpp
@@ -8,6 +8,8 @@ class InputGraphicsBox : public GraphicsBox {
 public:
     InputGraphicsBox(std::unique_ptr<InputModelBox> modelBox, const QPointF& pos);
 
+    void updateColor();
+
 protected:
     void contextMenuEvent(QGraphicsSceneContextMenuEvent* event) override;
 
diff --git a/agui2/src/MainWindow.cpp b/agui2/src/MainWindow.cpp
index 88dca21d4e..34c6ae213e 100644
--- a/agui2/src/MainWindow.cpp
+++ b/agui2/src/MainWindow.cpp
@@ -141,6 +141,7 @@ void MainWindow::on_actionOpen_triggered() {
 
         // clear existing boxes
         this->scene->clear();
+        this->outputBox = nullptr;
 
         std::vector<GraphicsBox*> boxes;
         boxes.reserve(parsed["boxes"].size());
@@ -155,11 +156,24 @@ void MainWindow::on_actionOpen_triggered() {
                             "Invalid algorithm '"s + box["algorithm"].get<std::string>() + "'specified." };
                 }
             } else if (box["type"] == "input") {
-                boxes.push_back(new InputGraphicsBox(std::make_unique<InputModelBox>(), { box["x"], box["y"] }));
-                this->scene->addItem(boxes.back());
+                auto* graphicsBox = new InputGraphicsBox(std::make_unique<InputModelBox>(), { box["x"], box["y"] });
+
+                boxes.push_back(graphicsBox);
+                this->scene->addItem(graphicsBox);
+
+                if (box.count("data") && box["data"].is_string()) {
+                    auto* inputBox = dynamic_cast<InputModelBox*>(graphicsBox->getModelBox());
+                    assert(inputBox);
+                    inputBox->setAutomaton(Converter::parseXML(QString::fromStdString(box["data"].get<std::string>())));
+                    graphicsBox->updateColor();
+                }
             } else if (box["type"] == "output") {
                 boxes.push_back(new GraphicsBox(std::make_unique<OutputModelBox>(), { box["x"], box["y"] }));
                 this->scene->addItem(boxes.back());
+                if (this->outputBox) {
+                    throw std::runtime_error { "Multiple output boxes found." };
+                }
+                this->outputBox = boxes.back();
             }
         }
 
@@ -205,9 +219,6 @@ void MainWindow::on_actionSave_triggered() {
     if (filename.isEmpty())
         return;
 
-    QFile file(filename);
-    file.open(QFile::ReadWrite | QFile::Text);
-
     //TODO save inputs
     json data {
             {"boxes", json::array()},
@@ -229,8 +240,13 @@ void MainWindow::on_actionSave_triggered() {
             boxData["type"] = "algorithm";
             boxData["algorithm"] = algorithmBox->getAlgorithm()->getFullName();
         }
-        else if (dynamic_cast<InputModelBox*>(box->getModelBox())) {
+        else if (auto* inputBox = dynamic_cast<InputModelBox*>(box->getModelBox())) {
             boxData["type"] = "input";
+            if (auto automaton = inputBox->getAutomaton()) {
+                if (auto xml = Converter::toXML(automaton, false)) {
+                    boxData["data"] = xml->toStdString();
+                }
+            }
         }
         else if (dynamic_cast<OutputModelBox*>(box->getModelBox())) {
             boxData["type"] = "output";
@@ -239,8 +255,8 @@ void MainWindow::on_actionSave_triggered() {
             assert(false);
         }
 
-        if (box->getOutputConnectionBox()) {
-            for (const Connection* conn: box->getOutputConnectionBox()->getConnections()) {
+        if (auto* outputConnBox = box->getOutputConnectionBox()) {
+            for (const Connection* conn: outputConnBox->getConnections()) {
                 auto targetIndex =
                         std::find(allBoxes.begin(), allBoxes.end(), conn->getTargetConnectionBox()->getParent()) -
                         allBoxes.begin();
@@ -254,6 +270,9 @@ void MainWindow::on_actionSave_triggered() {
         boxes.push_back(boxData);
     }
 
+    QFile file(filename);
+    file.open(QFile::ReadWrite | QFile::Text | QFile::Truncate);
+
     QTextStream stream(&file);
     stream << QString::fromStdString(data.dump(4));
     file.close();
-- 
GitLab