From 7ea534dd1c8bf72200a999cae554d842d9035ba9 Mon Sep 17 00:00:00 2001 From: Nao Pross Date: Mon, 1 Jan 2018 18:44:35 +0100 Subject: New StatementDialog, rename diagram classes Other changes: - Use raw pointer instead of smart pointers to manage resources - Initial Painter implementation --- src/diagram/branch.cpp | 16 +++++++++++ src/diagram/branchstatement.cpp | 16 ----------- src/diagram/iterator.cpp | 18 ++++++++++++ src/diagram/iteratorstatement.cpp | 18 ------------ src/diagram/scope.cpp | 47 +++++++++++++++++++++++++----- src/diagram/statement.cpp | 41 +++++++++++++++++++++++++- src/io/serializer.cpp | 31 ++++++++++++++++++++ src/ui/mainwindow.cpp | 22 ++++++++++---- src/ui/painter.cpp | 60 ++++++++++++++++++++++++++++++++++++--- src/ui/statementdialog.cpp | 14 +++++++++ 10 files changed, 231 insertions(+), 52 deletions(-) create mode 100644 src/diagram/branch.cpp delete mode 100644 src/diagram/branchstatement.cpp create mode 100644 src/diagram/iterator.cpp delete mode 100644 src/diagram/iteratorstatement.cpp create mode 100644 src/ui/statementdialog.cpp (limited to 'src') diff --git a/src/diagram/branch.cpp b/src/diagram/branch.cpp new file mode 100644 index 0000000..ccb17de --- /dev/null +++ b/src/diagram/branch.cpp @@ -0,0 +1,16 @@ +#include "diagram/branch.h" + +using namespace samb; + +Branch::Branch(Type t, const QString &condition, pointer next) : + Statement(t, condition, next) +{ + switch (t) { + case Statement::Type::DECISION: + case Statement::Type::SWITCH: + break; + + default: + throw std::invalid_argument("BranchStatement can only be of type DECISION or SWITCH"); + } +} diff --git a/src/diagram/branchstatement.cpp b/src/diagram/branchstatement.cpp deleted file mode 100644 index 6511c6c..0000000 --- a/src/diagram/branchstatement.cpp +++ /dev/null @@ -1,16 +0,0 @@ -#include "diagram/branchstatement.h" - -using namespace samb; - -BranchStatement::BranchStatement(Type t, const QString &condition, pointer next) : - Statement(t, condition, next) -{ - switch (t) { - case Statement::Type::DECISION: - case Statement::Type::SWITCH: - break; - - default: - throw std::invalid_argument("BranchStatement can only be of type DECISION or SWITCH"); - } -} diff --git a/src/diagram/iterator.cpp b/src/diagram/iterator.cpp new file mode 100644 index 0000000..43085b4 --- /dev/null +++ b/src/diagram/iterator.cpp @@ -0,0 +1,18 @@ +#include "diagram/iterator.h" + +using namespace samb; + +Iterator::Iterator(Statement::Type t, const QString &condition, Statement::pointer next) : + Statement(t, condition, next), + _inner("") +{ + + switch (t) { + case Statement::Type::WHILE: + case Statement::Type::UNTIL: + break; + + default: + throw std::invalid_argument("IteratorStatement can only be of type WHILE or UNTIL"); + } +} diff --git a/src/diagram/iteratorstatement.cpp b/src/diagram/iteratorstatement.cpp deleted file mode 100644 index a68234b..0000000 --- a/src/diagram/iteratorstatement.cpp +++ /dev/null @@ -1,18 +0,0 @@ -#include "diagram/iteratorstatement.h" - -using namespace samb; - -IteratorStatement::IteratorStatement(Statement::Type t, const QString &condition, Statement::pointer next) : - Statement(t, condition, next), - _inner("") -{ - - switch (t) { - case Statement::Type::WHILE: - case Statement::Type::UNTIL: - break; - - default: - throw std::invalid_argument("IteratorStatement can only be of type WHILE or UNTIL"); - } -} diff --git a/src/diagram/scope.cpp b/src/diagram/scope.cpp index b0f56cf..7f64a0d 100644 --- a/src/diagram/scope.cpp +++ b/src/diagram/scope.cpp @@ -1,4 +1,5 @@ #include "diagram/scope.h" +#include "debugtools.h" using namespace samb; @@ -7,6 +8,9 @@ using namespace samb; Scope::iterator::iterator(Statement::pointer statement) : _current(statement) { + if (_current == nullptr) { + debug_err("invalid iterator interating nullptr"); + } } @@ -15,15 +19,24 @@ Scope::iterator::~iterator() } +bool Scope::iterator::operator==(const iterator &other) const +{ + return *_current == *other; +} + +bool Scope::iterator::operator!=(const iterator &other) const +{ + return !(*_current == *other); +} + Scope::iterator& Scope::iterator::operator++() { - if (_current->next() == nullptr) { - // TODO: remove throw - throw std::logic_error("Statement::iterator::operator++() m_current->next() is nullptr"); + if (_current->next() != nullptr) { + _current = _current->next(); + } else { + // throw std::logic_error("Statement::iterator::operator++() m_current->next() is nullptr"); } - _current = _current->next(); - return *this; } @@ -39,7 +52,7 @@ Scope::iterator& Scope::iterator::operator++(int) Statement& Scope::iterator::operator*() const { if (_current == nullptr) - throw std::logic_error("Statement::iterator::operator*() m_current is nullptr"); + throw std::logic_error("Scope::iterator::operator*() m_current is nullptr"); return *_current; } @@ -56,7 +69,7 @@ Scope::Scope(const QString &label) : Statement(Statement::Type::SCOPE, label, nullptr), _head(nullptr), _tail(nullptr) { - + _head = _tail = new Statement(Statement::PROCESS, ""); } Scope::Scope(const QString &label, Statement::pointer first) : @@ -92,3 +105,23 @@ Scope::iterator Scope::erase_after(Scope::iterator it) return it; } + +Scope::iterator Scope::begin() +{ + return iterator(_head); +} + +const Scope::iterator Scope::begin() const +{ + return begin(); +} + +Scope::iterator Scope::end() +{ + return iterator(_tail); +} + +const Scope::iterator Scope::end() const +{ + return end(); +} diff --git a/src/diagram/statement.cpp b/src/diagram/statement.cpp index eae5cd3..7f1109b 100644 --- a/src/diagram/statement.cpp +++ b/src/diagram/statement.cpp @@ -1,9 +1,48 @@ #include "diagram/statement.h" +#include "diagram/branch.h" +#include "diagram/iterator.h" +#include "diagram/scope.h" + +#include "debugtools.h" + using namespace samb; /* Statement */ +template +static Statement::pointer make(Statement::Type t, Args&& ...args) +{ + Statement::pointer stat; + + switch (t) { + case Statement::Type::PROCESS: + stat = new Statement(t, args...); + break; + + case Statement::Type::DECISION: + case Statement::Type::PARALLEL: + case Statement::Type::SWITCH: + stat = new Branch(t, args...); + break; + + case Statement::Type::WHILE: + case Statement::Type::UNTIL: + stat = new Iterator(t, args...); + break; + + case Statement::Type::SCOPE: + stat = new Scope(t, args...); + break; + + default: + debug_err("invalid type"); + break; + } + + return stat; +} + Statement::Statement(Type t, const QString &text) : type(t), _text(text), _next(nullptr) { @@ -21,7 +60,7 @@ Statement::~Statement() } -bool Statement::operator==(const Statement& other) const { +bool Statement::operator==(const Statement &other) const { // comparison by pointers return (this == &other); } diff --git a/src/io/serializer.cpp b/src/io/serializer.cpp index 6ebfa44..82e0f5a 100644 --- a/src/io/serializer.cpp +++ b/src/io/serializer.cpp @@ -1,4 +1,7 @@ #include "io/serializer.h" +#include "diagram/statement.h" + +#include "debugtools.h" Serializer::Serializer() { @@ -9,3 +12,31 @@ Serializer::~Serializer() { } + +bool Serializer::write(const samb::Structogram &structogram, const QFileInfo &into) +{ + for (auto it = structogram.begin(); it != structogram.end(); ++it) { + switch (it->type) { + case samb::Statement::Type::PROCESS: + break; + + case samb::Statement::Type::DECISION: + case samb::Statement::Type::SWITCH: + case samb::Statement::Type::PARALLEL: + break; + + case samb::Statement::Type::WHILE: + case samb::Statement::Type::UNTIL: + break; + + case samb::Statement::Type::SCOPE: + break; + + default: + debug_err("invalid statement type"); + break; + } + } + + return true; +} diff --git a/src/ui/mainwindow.cpp b/src/ui/mainwindow.cpp index 5776db7..8b40c1b 100644 --- a/src/ui/mainwindow.cpp +++ b/src/ui/mainwindow.cpp @@ -1,9 +1,12 @@ #include "debugtools.h" #include "ui/metadatadialog.h" +#include "ui/statementdialog.h" #include "ui/mainwindow.h" #include "ui_mainwindow.h" +#include "diagram/statement.h" + #include #include @@ -15,6 +18,7 @@ MainWindow::MainWindow(samb::Structogram *structogram, QWidget *parent) : _structogram(structogram) { _ui->setupUi(this); + _ui->painter->structogram(&_structogram); toolButtonsEnabled((_structogram != nullptr)); } @@ -53,7 +57,7 @@ void MainWindow::on_openButton_clicked() return; QString fileName = QFileDialog::getOpenFileName(this, - tr("Load diagram"), "", "NS Diagram (*.nsdg);;All Files (*)"); + tr("Load diagram"), "", tr("NS Diagram (*.nsdg);;All Files (*)")); if (fileName.isEmpty()) return; @@ -86,18 +90,24 @@ void MainWindow::on_metadataButton_clicked() if (_structogram == nullptr) return; - MetadataDialog *dialog = new MetadataDialog(this); - dialog->setMetadata(_structogram->title(), _structogram->author()); + MetadataDialog dialog(this); + dialog.setMetadata(_structogram->title(), _structogram->author()); - if (dialog->exec() == QDialog::Accepted) { - _structogram->title(dialog->title()); - _structogram->author(dialog->author()); + if (dialog.exec() == QDialog::Accepted) { + _structogram->title(dialog.title()); + _structogram->author(dialog.author()); } } void MainWindow::on_newStatementButton_clicked() { + if (_structogram == nullptr) + return; + + StatementDialog dialog(this); + if (dialog.exec() == QDialog::Accepted) { + } } /**** private methods ****/ diff --git a/src/ui/painter.cpp b/src/ui/painter.cpp index b04e389..74f140e 100644 --- a/src/ui/painter.cpp +++ b/src/ui/painter.cpp @@ -1,14 +1,66 @@ #include "ui/painter.h" -#include "ui_painter.h" + +#include "debugtools.h" + +#include + Painter::Painter(QWidget *parent) : QWidget(parent), - _ui(new Ui::Painter) + _font("Latin Modern Roman"), + _fontMetrics(_font) { - _ui->setupUi(this); + // default font size + _font.setPixelSize(15); } Painter::~Painter() { - delete _ui; + +} + +void Painter::paintEvent(QPaintEvent *event) +{ + Q_UNUSED(event); + + if (_structogram == nullptr) { + return; + } + + if (*_structogram == nullptr) { + return; + } + + QPainter qp(this); + qp.setFont(_font); + + // TODO default values should not be magic numbers + QRect rect(50, 50, 600, 00); + for (auto it = (*_structogram)->begin(); it != (*_structogram)->end(); ++it) { + drawStatement(qp, *it, rect); + rect.setY(rect.y() + rect.height()); + } +} + +void Painter::drawStatement(QPainter &qp, samb::Statement &statement, const QRect &rect) +{ + QRect textRect(rect.x() + _margin, + rect.y() + _margin, + rect.width() - 2*_margin, + rect.height() - 2*_margin); + + int textHeight; + if (textRect.width() < _fontMetrics.width(statement.text())) { + textHeight = (_fontMetrics.height() + _fontMetrics.lineSpacing()) * + (int) ceil(_fontMetrics.width(statement.text()) / (double) textRect.width()); + } else { + textHeight = _fontMetrics.height(); + } + + if (textRect.height() < textHeight) { + debug_msg("painter error, textRect.height() < height"); + } + + qp.drawRect(rect); + qp.drawText(textRect, Qt::AlignVCenter, statement.text()); } diff --git a/src/ui/statementdialog.cpp b/src/ui/statementdialog.cpp new file mode 100644 index 0000000..a543f95 --- /dev/null +++ b/src/ui/statementdialog.cpp @@ -0,0 +1,14 @@ +#include "include/ui/statementdialog.h" +#include "ui_statementdialog.h" + +StatementDialog::StatementDialog(QWidget *parent) : + QDialog(parent), + ui(new Ui::StatementDialog) +{ + ui->setupUi(this); +} + +StatementDialog::~StatementDialog() +{ + delete ui; +} -- cgit v1.2.1