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 --- OrbitingYeti.pro | 16 +++--- forms/mainwindow.ui | 12 +++- forms/painter.ui | 21 ------- forms/statementdialog.ui | 106 ++++++++++++++++++++++++++++++++++++ include/debugtools.h | 4 +- include/diagram/branch.h | 32 +++++++++++ include/diagram/branchstatement.h | 32 ----------- include/diagram/iterator.h | 30 ++++++++++ include/diagram/iteratorstatement.h | 30 ---------- include/diagram/scope.h | 11 +++- include/diagram/statement.h | 6 +- include/io/serializer.h | 4 +- include/ui/painter.h | 26 +++++++-- include/ui/statementdialog.h | 22 ++++++++ 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 +++++ 24 files changed, 478 insertions(+), 157 deletions(-) delete mode 100644 forms/painter.ui create mode 100644 forms/statementdialog.ui create mode 100644 include/diagram/branch.h delete mode 100644 include/diagram/branchstatement.h create mode 100644 include/diagram/iterator.h delete mode 100644 include/diagram/iteratorstatement.h create mode 100644 include/ui/statementdialog.h 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 diff --git a/OrbitingYeti.pro b/OrbitingYeti.pro index 7351c0c..1821c44 100644 --- a/OrbitingYeti.pro +++ b/OrbitingYeti.pro @@ -27,28 +27,30 @@ INCLUDEPATH += include SOURCES += \ src/main.cpp \ src/ui/mainwindow.cpp \ - src/diagram/branchstatement.cpp \ - src/diagram/iteratorstatement.cpp \ src/diagram/scope.cpp \ src/diagram/statement.cpp \ src/diagram/structogram.cpp \ src/ui/metadatadialog.cpp \ src/ui/painter.cpp \ - src/io/serializer.cpp + src/io/serializer.cpp \ + src/ui/statementdialog.cpp \ + src/diagram/branch.cpp \ + src/diagram/iterator.cpp HEADERS += \ include/ui/mainwindow.h \ include/diagram/structogram.h \ include/diagram/statement.h \ include/diagram/scope.h \ - include/diagram/iteratorstatement.h \ - include/diagram/branchstatement.h \ include/ui/metadatadialog.h \ include/ui/painter.h \ include/debugtools.h \ - include/io/serializer.h + include/io/serializer.h \ + include/ui/statementdialog.h \ + include/diagram/branch.h \ + include/diagram/iterator.h FORMS += \ forms/mainwindow.ui \ forms/metadatadialog.ui \ - forms/painter.ui + forms/statementdialog.ui diff --git a/forms/mainwindow.ui b/forms/mainwindow.ui index 23125a1..816ae01 100644 --- a/forms/mainwindow.ui +++ b/forms/mainwindow.ui @@ -130,7 +130,7 @@ - + 0 @@ -149,7 +149,7 @@ 0 0 824 - 28 + 29 @@ -335,6 +335,14 @@ + + + Painter + QWidget +
ui/painter.h
+ 1 +
+
diff --git a/forms/painter.ui b/forms/painter.ui deleted file mode 100644 index 1978a7c..0000000 --- a/forms/painter.ui +++ /dev/null @@ -1,21 +0,0 @@ - - - - - Painter - - - - 0 - 0 - 400 - 300 - - - - Form - - - - - diff --git a/forms/statementdialog.ui b/forms/statementdialog.ui new file mode 100644 index 0000000..d4e4fd9 --- /dev/null +++ b/forms/statementdialog.ui @@ -0,0 +1,106 @@ + + + StatementDialog + + + + 0 + 0 + 400 + 300 + + + + Dialog + + + + + + + 0 + 0 + + + + Statement Type + + + + + + + + Process + + + + + Decision + + + + + Switch + + + + + + + + Text + + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + buttonBox + accepted() + StatementDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + StatementDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/include/debugtools.h b/include/debugtools.h index cd6940b..1b34a2e 100644 --- a/include/debugtools.h +++ b/include/debugtools.h @@ -3,8 +3,8 @@ #ifdef QT_NO_DEBUG -void debug_msg(...) {} -void debug_err(...) {} +#define debug_msg(msg) +#define debug_err(msg) #else #include diff --git a/include/diagram/branch.h b/include/diagram/branch.h new file mode 100644 index 0000000..2024d78 --- /dev/null +++ b/include/diagram/branch.h @@ -0,0 +1,32 @@ +#ifndef DIAGRAM_BRANCHSTATEMENT_H +#define DIAGRAM_BRANCHSTATEMENT_H + +#include "diagram/statement.h" + +#include +#include + +namespace samb { + +/* Implementation for Statement::DECISION, Statement::SWITCH + */ +class Branch : public Statement +{ +public: + Branch(Type t, const QString &condition, pointer next); + + /* accessors */ + std::map& branches() { return _branches; } + std::size_t branchesCount() const { return _branchesCount; } + + inline const QString& condition() const { return text(); } + inline void condition(const QString &condition) { return text(condition); } + +private: + std::map _branches; + std::size_t _branchesCount = 0; +}; + +} /* namespace samb */ + +#endif /* DIAGRAM_BRANCHSTATEMENT_H */ diff --git a/include/diagram/branchstatement.h b/include/diagram/branchstatement.h deleted file mode 100644 index 3d8c385..0000000 --- a/include/diagram/branchstatement.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef DIAGRAM_BRANCHSTATEMENT_H -#define DIAGRAM_BRANCHSTATEMENT_H - -#include "diagram/statement.h" - -#include -#include - -namespace samb { - -/* Implementation for Statement::DECISION, Statement::SWITCH - */ -class BranchStatement : public Statement -{ -public: - BranchStatement(Type t, const QString &condition, pointer next); - - /* accessors */ - std::map& branches() { return _branches; } - std::size_t branches_count() const { return _branchesCount; } - - inline const QString& condition() const { return text(); } - inline void condition(const QString &condition) { return text(condition); } - -private: - std::map _branches; - std::size_t _branchesCount = 0; -}; - -} /* namespace samb */ - -#endif /* DIAGRAM_BRANCHSTATEMENT_H */ diff --git a/include/diagram/iterator.h b/include/diagram/iterator.h new file mode 100644 index 0000000..71c6a34 --- /dev/null +++ b/include/diagram/iterator.h @@ -0,0 +1,30 @@ +#ifndef DIAGRAM_ITERATORSTATEMENT_H +#define DIAGRAM_ITERATORSTATEMENT_H + +#include "diagram/statement.h" +#include "diagram/scope.h" + +#include + +namespace samb { + +/* Implementation for Statement::WHILE Statement::UNTIL + */ +class Iterator : public Statement +{ +public: + Iterator(Type t, const QString &condition, pointer next); + + /* accessors */ + Scope& inner() { return _inner; } + + inline const QString& condition() const { return text(); } + inline void condition(const QString &condition) { return text(condition); } + +private: + Scope _inner; +}; + +} /* namespace samb */ + +#endif /* DIAGRAM_ITERATORSTATEMENT_H */ diff --git a/include/diagram/iteratorstatement.h b/include/diagram/iteratorstatement.h deleted file mode 100644 index e7fbba0..0000000 --- a/include/diagram/iteratorstatement.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef DIAGRAM_ITERATORSTATEMENT_H -#define DIAGRAM_ITERATORSTATEMENT_H - -#include "diagram/statement.h" -#include "diagram/scope.h" - -#include - -namespace samb { - -/* Implementation for Statement::WHILE Statement::UNTIL - */ -class IteratorStatement : public Statement -{ -public: - IteratorStatement(Type t, const QString &condition, pointer next); - - /* accessors */ - Scope& inner() { return _inner; } - - inline const QString& condition() const { return text(); } - inline void condition(const QString &condition) { return text(condition); } - -private: - Scope _inner; -}; - -} /* namespace samb */ - -#endif /* DIAGRAM_ITERATORSTATEMENT_H */ diff --git a/include/diagram/scope.h b/include/diagram/scope.h index 63698dd..8ae7e79 100644 --- a/include/diagram/scope.h +++ b/include/diagram/scope.h @@ -22,6 +22,9 @@ public: explicit iterator(pointer statement); ~iterator(); + bool operator==(const iterator &other) const; + bool operator!=(const iterator &other) const; + iterator& operator++(); iterator& operator++(int); @@ -32,7 +35,7 @@ public: Statement::pointer _current; }; - explicit Scope(const QString &label); + Scope(const QString &label); Scope(const QString &label, Statement::pointer first); virtual ~Scope(); @@ -43,8 +46,10 @@ public: std::size_t size() const { return _size; } /* iterator */ - iterator begin() { return iterator(_head); } - iterator end() { return iterator(_tail); } + iterator begin(); + const iterator begin() const; + iterator end(); + const iterator end() const; private: Statement::pointer _head; diff --git a/include/diagram/statement.h b/include/diagram/statement.h index 5cce908..1d44d6a 100644 --- a/include/diagram/statement.h +++ b/include/diagram/statement.h @@ -26,7 +26,8 @@ namespace samb { class Statement { public: - using pointer = std::shared_ptr; +// using pointer = std::shared_ptr; + using pointer = Statement*; enum Type { PROCESS, @@ -40,6 +41,9 @@ public: const Type type; + template + static pointer make(Type t, Args&& ...args); + Statement(Type t, const QString &text); Statement(Type t, const QString &text, pointer next); virtual ~Statement(); diff --git a/include/io/serializer.h b/include/io/serializer.h index 901d913..e6a9b32 100644 --- a/include/io/serializer.h +++ b/include/io/serializer.h @@ -11,8 +11,8 @@ public: explicit Serializer(); virtual ~Serializer(); - bool write(const samb::Structogram &structogram, QFileInfo into); - bool load(samb::Structogram &structogram, QFileInfo from); + bool write(const samb::Structogram &structogram, const QFileInfo &into); + bool load(samb::Structogram &structogram, const QFileInfo &from); }; #endif // SERIALIZER_H diff --git a/include/ui/painter.h b/include/ui/painter.h index df62776..0a2accc 100644 --- a/include/ui/painter.h +++ b/include/ui/painter.h @@ -1,11 +1,15 @@ #ifndef PAINTER_H #define PAINTER_H -#include +#include "diagram/statement.h" +#include "diagram/structogram.h" -namespace Ui { -class Painter; -} +#include +#include +#include +#include +#include +#include class Painter : public QWidget { @@ -15,8 +19,20 @@ public: explicit Painter(QWidget *parent = 0); ~Painter(); + void structogram(samb::Structogram **structogram) { _structogram = structogram; } + const samb::Structogram structogram() const { return **_structogram; } + +protected: + void paintEvent(QPaintEvent *event); + private: - Ui::Painter *_ui; + samb::Structogram **_structogram = nullptr; + QFont _font; + QFontMetrics _fontMetrics; + + int _margin = 10; + + void drawStatement(QPainter &qp, samb::Statement &statement, const QRect &rect); }; #endif // PAINTER_H diff --git a/include/ui/statementdialog.h b/include/ui/statementdialog.h new file mode 100644 index 0000000..658ea53 --- /dev/null +++ b/include/ui/statementdialog.h @@ -0,0 +1,22 @@ +#ifndef STATEMENTDIALOG_H +#define STATEMENTDIALOG_H + +#include + +namespace Ui { +class StatementDialog; +} + +class StatementDialog : public QDialog +{ + Q_OBJECT + +public: + explicit StatementDialog(QWidget *parent = 0); + ~StatementDialog(); + +private: + Ui::StatementDialog *ui; +}; + +#endif // STATEMENTDIALOG_H 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