From e1984bd32ea8cd1b11636a4608e3ae53867651be Mon Sep 17 00:00:00 2001 From: Martin Hanzik <martin@hanzik.com> Date: Sun, 6 May 2018 17:06:59 +0200 Subject: [PATCH] Add output saving --- agui2/src/Converter.cpp | 11 ++++ agui2/src/Converter.hpp | 2 + agui2/src/Graphics/Dialogs/OutputDialog.cpp | 73 +++++++++++++++++++++ agui2/src/Graphics/Dialogs/OutputDialog.hpp | 11 ++++ agui2/src/Graphics/Dialogs/OutputDialog.ui | 7 ++ agui2/src/GraphvizIntegrator.cpp | 13 +++- agui2/src/GraphvizIntegrator.hpp | 2 + 7 files changed, 117 insertions(+), 2 deletions(-) diff --git a/agui2/src/Converter.cpp b/agui2/src/Converter.cpp index d23992b2e8..27b654ae96 100644 --- a/agui2/src/Converter.cpp +++ b/agui2/src/Converter.cpp @@ -138,4 +138,15 @@ namespace Converter { } return nullptr; } + + void saveToImage(const std::shared_ptr<abstraction::OperationAbstraction>& data, const QString& filename) { + if (auto dot = Converter::toDOT(data)) { + if (!GraphvizIntegrator::createImageFile(*dot, filename, GraphvizIntegrator::formatFromFilename(filename))) { + throw std::runtime_error { "Failed to write to file." }; + } + } + else { + throw std::runtime_error { "Failed to convert data to DOT." }; + } + } } diff --git a/agui2/src/Converter.hpp b/agui2/src/Converter.hpp index 84916a7437..efc091f582 100644 --- a/agui2/src/Converter.hpp +++ b/agui2/src/Converter.hpp @@ -17,6 +17,8 @@ namespace Converter { std::shared_ptr<abstraction::OperationAbstraction> tryParse(const QString& input); std::shared_ptr<abstraction::OperationAbstraction> parseXML(const QString& xml); std::shared_ptr<abstraction::OperationAbstraction> parseText(const QString& txt); + + void saveToImage(const std::shared_ptr<abstraction::OperationAbstraction>& data, const QString& filename); }; diff --git a/agui2/src/Graphics/Dialogs/OutputDialog.cpp b/agui2/src/Graphics/Dialogs/OutputDialog.cpp index b2bd3a5c0c..c4fc0bf5cd 100644 --- a/agui2/src/Graphics/Dialogs/OutputDialog.cpp +++ b/agui2/src/Graphics/Dialogs/OutputDialog.cpp @@ -3,6 +3,9 @@ #include <utility> #include <Converter.hpp> #include <registry/StringWriterRegistry.hpp> +#include <QtWidgets/QFileDialog> +#include <QtWidgets/QMessageBox> +#include <QtCore/QTextStream> OutputDialog::OutputDialog(std::shared_ptr<abstraction::OperationAbstraction> object) : ui(new Ui::OutputDialog) @@ -43,3 +46,73 @@ OutputDialog::OutputDialog(std::shared_ptr<abstraction::OperationAbstraction> ob void OutputDialog::hideTab(QWidget* tab) { ui->tabWidget->setTabEnabled(ui->tabWidget->indexOf(tab), false); } + +void OutputDialog::on_saveBtn_clicked() { + auto [filter, extension] = this->getCurrentTabFileFilter(); + QString filename(QFileDialog::getSaveFileName(this, + tr("Save file"), + QDir::homePath(), + filter)); + if (filename.isEmpty()) { + return; + } + + if (!filename.endsWith(extension)) { + filename += extension; + } + + auto type = this->getCurrentTabType(); + if (type == TabType::Image) { + Converter::saveToImage(this->object, filename); + } + else { + QFile file(filename); + if (!file.open(QFile::WriteOnly | QFile::Text | QFile::Truncate)) { + QMessageBox::warning(this, "Warning", "Failed to open file."); + return; + } + + QTextStream stream(&file); + switch (type) { + case TabType::Text: + stream << ui->textEdit_text->toPlainText(); + break; + case TabType::XML: + stream << ui->textEdit_xml->toPlainText(); + break; + case TabType::DOT: + stream << ui->textEdit_dot->toPlainText(); + break; + case TabType::Image: + Q_ASSERT(false); + break; + } + file.close(); + } +} + +TabType OutputDialog::getCurrentTabType() const { + if (ui->tabWidget->currentWidget() == ui->tab_text) { + return TabType::Text; + } + else if (ui->tabWidget->currentWidget() == ui->tab_xml) { + return TabType::XML; + } + else if (ui->tabWidget->currentWidget() == ui->tab_dot) { + return TabType::DOT; + } + else if (ui->tabWidget->currentWidget() == ui->tab_image) { + return TabType::Image; + } + + Q_ASSERT(false); +} + +std::pair<QString, QString> OutputDialog::getCurrentTabFileFilter() const { + switch (this->getCurrentTabType()) { + case TabType::Text: return { "Text files (*.txt)", ".txt" }; + case TabType::XML: return { "XML files (*.xml)", ".xml" }; + case TabType::DOT: return { "DOT files (*.dot)", ".dot" }; + case TabType::Image: return { "PNG files (*.png)", ".png" }; + } +} diff --git a/agui2/src/Graphics/Dialogs/OutputDialog.hpp b/agui2/src/Graphics/Dialogs/OutputDialog.hpp index 2a0578ae7a..f7457e67d3 100644 --- a/agui2/src/Graphics/Dialogs/OutputDialog.hpp +++ b/agui2/src/Graphics/Dialogs/OutputDialog.hpp @@ -7,6 +7,13 @@ #include <ui_OutputDialog.h> +enum class TabType { + Text, + XML, + DOT, + Image +}; + class OutputDialog : public QDialog { Q_OBJECT @@ -15,10 +22,14 @@ public: explicit OutputDialog(std::shared_ptr<abstraction::OperationAbstraction> object); private slots: + void on_saveBtn_clicked(); private: void hideTab(QWidget* tab); + TabType getCurrentTabType() const; + std::pair<QString, QString> getCurrentTabFileFilter() const; + std::unique_ptr<Ui::OutputDialog> ui; std::shared_ptr<abstraction::OperationAbstraction> object; }; diff --git a/agui2/src/Graphics/Dialogs/OutputDialog.ui b/agui2/src/Graphics/Dialogs/OutputDialog.ui index 00bdd5daee..3341e58e46 100644 --- a/agui2/src/Graphics/Dialogs/OutputDialog.ui +++ b/agui2/src/Graphics/Dialogs/OutputDialog.ui @@ -93,6 +93,13 @@ </widget> </widget> </item> + <item row="1" column="0"> + <widget class="QPushButton" name="saveBtn"> + <property name="text"> + <string>Save</string> + </property> + </widget> + </item> </layout> </widget> <resources/> diff --git a/agui2/src/GraphvizIntegrator.cpp b/agui2/src/GraphvizIntegrator.cpp index 06a7113e9e..a2ed55b78e 100644 --- a/agui2/src/GraphvizIntegrator.cpp +++ b/agui2/src/GraphvizIntegrator.cpp @@ -5,9 +5,9 @@ QString selectFormat(GraphvizIntegrator::PictureFormat format) { switch (format) { case GraphvizIntegrator::PictureFormat::PNG: - return QString("png"); + return "png"; case GraphvizIntegrator::PictureFormat::SVG: - return QString("svg"); + return "svg"; } } @@ -46,4 +46,13 @@ namespace GraphvizIntegrator { agclose(G); return true; } + + + PictureFormat formatFromFilename(const QString& format) { + if (format.endsWith("svg")) + return SVG; + if (format.endsWith("png")) + return PNG; + throw std::runtime_error { "Failed to determine output format from filename." }; + } } \ No newline at end of file diff --git a/agui2/src/GraphvizIntegrator.hpp b/agui2/src/GraphvizIntegrator.hpp index 93ca41b3f0..e20be0374c 100644 --- a/agui2/src/GraphvizIntegrator.hpp +++ b/agui2/src/GraphvizIntegrator.hpp @@ -11,6 +11,8 @@ namespace GraphvizIntegrator QImage createImage(const QString& dotData , PictureFormat format); bool createImageFile(const QString& dotData, QString filename , PictureFormat format); + + PictureFormat formatFromFilename(const QString& qString); }; -- GitLab