From a33fa1d2749971a07fac6f541227a9e57f8ef499 Mon Sep 17 00:00:00 2001 From: Martin Hanzik <martin@hanzik.com> Date: Sat, 31 Mar 2018 16:06:47 +0200 Subject: [PATCH] Major refactoring of Graphics/Model boxes --- agui2/CMakeLists.txt | 32 ++- agui2/ConnectionHelper.cpp | 37 ---- agui2/ConnectionHelper.h | 17 -- .../Graphics/{ => Connection}/Connection.cpp | 28 ++- agui2/Graphics/{ => Connection}/Connection.h | 11 +- .../{ => Connection}/ConnectionBox.cpp | 44 ++-- .../Graphics/{ => Connection}/ConnectionBox.h | 22 +- .../Connection/InputConnectionBox.cpp | 17 ++ .../Graphics/Connection/InputConnectionBox.h | 21 ++ .../Connection/OutputConnectionBox.cpp | 16 ++ .../Graphics/Connection/OutputConnectionBox.h | 19 ++ agui2/Graphics/GraphicsBox.cpp | 204 +++--------------- agui2/Graphics/GraphicsBox.h | 62 ++---- agui2/Graphics/GraphicsConnection.cpp | 136 ------------ agui2/Graphics/GraphicsConnection.h | 37 ---- agui2/Graphics/GraphicsScene.cpp | 15 +- agui2/Graphics/GraphicsScene.h | 1 - agui2/Graphics/InputGraphicsBox.cpp | 62 ++---- agui2/Graphics/InputGraphicsBox.h | 17 +- agui2/Graphics/OutputGraphicsBox.cpp | 29 --- agui2/Graphics/OutputGraphicsBox.h | 14 -- agui2/MainWindow.cpp | 113 +++++----- agui2/MainWindow.h | 7 +- agui2/Models/AlgorithmModelBox.cpp | 71 ++++++ agui2/Models/AlgorithmModelBox.h | 14 ++ agui2/Models/DoubleModelBox.cpp | 82 ------- agui2/Models/DoubleModelBox.h | 25 --- agui2/Models/InputModelBox.cpp | 37 +--- agui2/Models/InputModelBox.h | 36 ++-- agui2/Models/ModelBox.cpp | 30 ++- agui2/Models/ModelBox.h | 59 +++-- agui2/Models/OutputModelBox.cpp | 195 +---------------- agui2/Models/OutputModelBox.h | 40 +--- agui2/Models/SingleModelBox.cpp | 52 ----- agui2/Models/SingleModelBox.h | 25 --- agui2/WrapperBox.cpp | 72 ------- agui2/WrapperBox.h | 27 --- agui2/WrapperFactory.cpp | 113 +++++----- agui2/WrapperFactory.h | 7 +- 39 files changed, 537 insertions(+), 1309 deletions(-) delete mode 100644 agui2/ConnectionHelper.cpp delete mode 100644 agui2/ConnectionHelper.h rename agui2/Graphics/{ => Connection}/Connection.cpp (63%) rename agui2/Graphics/{ => Connection}/Connection.h (55%) rename agui2/Graphics/{ => Connection}/ConnectionBox.cpp (70%) rename agui2/Graphics/{ => Connection}/ConnectionBox.h (66%) create mode 100644 agui2/Graphics/Connection/InputConnectionBox.cpp create mode 100644 agui2/Graphics/Connection/InputConnectionBox.h create mode 100644 agui2/Graphics/Connection/OutputConnectionBox.cpp create mode 100644 agui2/Graphics/Connection/OutputConnectionBox.h delete mode 100644 agui2/Graphics/GraphicsConnection.cpp delete mode 100644 agui2/Graphics/GraphicsConnection.h delete mode 100644 agui2/Graphics/OutputGraphicsBox.cpp delete mode 100644 agui2/Graphics/OutputGraphicsBox.h create mode 100644 agui2/Models/AlgorithmModelBox.cpp create mode 100644 agui2/Models/AlgorithmModelBox.h delete mode 100644 agui2/Models/DoubleModelBox.cpp delete mode 100644 agui2/Models/DoubleModelBox.h delete mode 100644 agui2/Models/SingleModelBox.cpp delete mode 100644 agui2/Models/SingleModelBox.h delete mode 100644 agui2/WrapperBox.cpp delete mode 100644 agui2/WrapperBox.h diff --git a/agui2/CMakeLists.txt b/agui2/CMakeLists.txt index 0bd4c60051..857dd699ba 100644 --- a/agui2/CMakeLists.txt +++ b/agui2/CMakeLists.txt @@ -39,51 +39,45 @@ link_directories(${ALIB_PATH}/bin-debug) add_executable(${PROJECT_NAME} AlibExceptionHandler.cpp AlibExceptionHandler.h - ConnectionHelper.cpp - ConnectionHelper.h Converter.cpp Converter.h - Graphics/Connection.cpp - Graphics/Connection.h - Graphics/ConnectionBox.cpp - Graphics/ConnectionBox.h + Graphics/Connection/Connection.cpp + Graphics/Connection/Connection.h + Graphics/Connection/ConnectionBox.cpp + Graphics/Connection/ConnectionBox.h + Graphics/Connection/InputConnectionBox.cpp + Graphics/Connection/InputConnectionBox.h + Graphics/Connection/OutputConnectionBox.cpp + Graphics/Connection/OutputConnectionBox.h Graphics/Dialogs/InputDialog.cpp Graphics/Dialogs/InputDialog.h Graphics/Dialogs/OutputDialog.cpp Graphics/Dialogs/OutputDialog.h Graphics/Dialogs/ResultDialog.cpp Graphics/Dialogs/ResultDialog.h - Graphics/GraphicsBox.cpp - Graphics/GraphicsBox.h - Graphics/GraphicsConnection.cpp - Graphics/GraphicsConnection.h Graphics/GraphicsScene.cpp Graphics/GraphicsScene.h + Graphics/GraphicsBox.cpp + Graphics/GraphicsBox.h Graphics/InputGraphicsBox.cpp Graphics/InputGraphicsBox.h - Graphics/OutputGraphicsBox.cpp - Graphics/OutputGraphicsBox.h GraphvizIntegrator.cpp GraphvizIntegrator.h main.cpp MainWindow.cpp MainWindow.h - Models/DoubleModelBox.cpp - Models/DoubleModelBox.h + Models/InputSettings.h + Models/AlgorithmModelBox.cpp + Models/AlgorithmModelBox.h Models/InputModelBox.cpp Models/InputModelBox.h - Models/InputSettings.h Models/ModelBox.cpp Models/ModelBox.h Models/OutputModelBox.cpp Models/OutputModelBox.h Models/OutputSettings.h - Models/SingleModelBox.cpp - Models/SingleModelBox.h Utils.cpp Utils.h - WrapperBox.cpp - WrapperBox.h WrapperFactory.cpp WrapperFactory.h ) diff --git a/agui2/ConnectionHelper.cpp b/agui2/ConnectionHelper.cpp deleted file mode 100644 index 6ca08a63eb..0000000000 --- a/agui2/ConnectionHelper.cpp +++ /dev/null @@ -1,37 +0,0 @@ -#include <ConnectionHelper.h> - -#include <QGraphicsScene> - -#include <WrapperBox.h> - -ConnectionHelper &ConnectionHelper::getInstance() -{ - static ConnectionHelper instance; - return instance; -} - -void ConnectionHelper::startConnection(WrapperBox *origin) -{ - m_origin = origin; - m_origin->disconnectOutput(); -} - -void ConnectionHelper::completeConnection(WrapperBox *target) -{ - if( target == nullptr || m_origin == nullptr || m_origin == target ) - { - m_origin = nullptr; - return; - } - if( target->getModel()->acceptInput() ) - { - target->getAvailableInput(); - m_Connection = new GraphicsConnection( m_origin, target); - } - m_origin = nullptr; -} - -ConnectionHelper::ConnectionHelper() -{ - m_Connection = nullptr; -} diff --git a/agui2/ConnectionHelper.h b/agui2/ConnectionHelper.h deleted file mode 100644 index 7290597d38..0000000000 --- a/agui2/ConnectionHelper.h +++ /dev/null @@ -1,17 +0,0 @@ -#pragma once -class GraphicsConnection; -class WrapperBox; - -class ConnectionHelper -{ -public: - static ConnectionHelper& getInstance(); - void startConnection(WrapperBox* origin ); - void completeConnection(WrapperBox* target); -private: - GraphicsConnection* m_Connection; - WrapperBox* m_origin; - ConnectionHelper(); -}; - - diff --git a/agui2/Graphics/Connection.cpp b/agui2/Graphics/Connection/Connection.cpp similarity index 63% rename from agui2/Graphics/Connection.cpp rename to agui2/Graphics/Connection/Connection.cpp index 94197631e7..b313fadf95 100644 --- a/agui2/Graphics/Connection.cpp +++ b/agui2/Graphics/Connection/Connection.cpp @@ -1,27 +1,29 @@ -#include <Graphics/Connection.h> +#include <Graphics/Connection/Connection.h> #include <QGraphicsScene> #include <QPainter> -#include <Graphics/ConnectionBox.h> +#include <Graphics/Connection/ConnectionBox.h> +#include <Graphics/Connection/InputConnectionBox.h> +#include <Graphics/Connection/OutputConnectionBox.h> #include <Graphics/GraphicsBox.h> #include <Utils.h> -#include <WrapperBox.h> -Connection::Connection(ConnectionBox* origin, ConnectionBox* target) +Connection::Connection(OutputConnectionBox* origin, InputConnectionBox* target) : originConnectionBox(origin) , targetConnectionBox(target) { - Q_ASSERT(origin->getType() == ConnectionBox::Type::Output); - Q_ASSERT(target->getType() == ConnectionBox::Type::Input); this->setZValue(2); this->boundRect = Utils::pointsToRect(origin->pos(), target->pos()); this->boundRect.adjust(-1, -1, 1, 1); origin->scene()->addItem(this); origin->scene()->update(); - origin->getWrapperBox()->addOutput(target->getWrapperBox(), nullptr); - target->getWrapperBox()->addInput(origin->getWrapperBox(), nullptr); + auto* originModel = origin->getParent()->getModelBox(); + auto* targetModel = target->getParent()->getModelBox(); + + originModel->addOutput(targetModel, target->getSlot()); + targetModel->setInput(target->getSlot(), originModel); } QRectF Connection::boundingRect() const { @@ -52,3 +54,13 @@ void Connection::recalculateBoundingRect(const QPointF& a, const QPointF& b) { this->boundRect = Utils::pointsToRect(a, b); this->boundRect.adjust(-1, -1, 1, 1); } + +void Connection::destroy() { + auto& conns = this->originConnectionBox->connections; + conns.erase(std::remove(conns.begin(), conns.end(), this), conns.end()); + + Q_ASSERT(this->targetConnectionBox->connection == this); + this->targetConnectionBox->connection = nullptr; + + delete this; +} diff --git a/agui2/Graphics/Connection.h b/agui2/Graphics/Connection/Connection.h similarity index 55% rename from agui2/Graphics/Connection.h rename to agui2/Graphics/Connection/Connection.h index d5aceb1425..54a530e784 100644 --- a/agui2/Graphics/Connection.h +++ b/agui2/Graphics/Connection/Connection.h @@ -3,25 +3,26 @@ #include <QtWidgets/QGraphicsItem> class ConnectionBox; +class InputConnectionBox; +class OutputConnectionBox; class Connection : public QGraphicsItem { public: - Connection(ConnectionBox* origin, ConnectionBox* target); + Connection(OutputConnectionBox* origin, InputConnectionBox* target); QRectF boundingRect() const override; void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) override; - ConnectionBox* getOriginConnectionBox() const { return this->originConnectionBox; } - ConnectionBox* getTargetConnectionBox() const { return this->targetConnectionBox; } + void destroy(); private: void recalculateBoundingRect(const QPointF& topLeft, const QPointF& bottomRight); QRectF boundRect; - ConnectionBox* originConnectionBox; - ConnectionBox* targetConnectionBox; + OutputConnectionBox* originConnectionBox; + InputConnectionBox* targetConnectionBox; }; diff --git a/agui2/Graphics/ConnectionBox.cpp b/agui2/Graphics/Connection/ConnectionBox.cpp similarity index 70% rename from agui2/Graphics/ConnectionBox.cpp rename to agui2/Graphics/Connection/ConnectionBox.cpp index b404c4475b..d7303d25a2 100644 --- a/agui2/Graphics/ConnectionBox.cpp +++ b/agui2/Graphics/Connection/ConnectionBox.cpp @@ -1,19 +1,21 @@ -#include <Graphics/ConnectionBox.h> +#include <Graphics/Connection/ConnectionBox.h> #include <utility> #include <QtGui/QDrag> #include <QtWidgets/QApplication> +#include <Graphics/Connection/InputConnectionBox.h> +#include <Graphics/Connection/OutputConnectionBox.h> #include <Graphics/GraphicsBox.h> #include <Graphics/GraphicsScene.h> -#include <WrapperBox.h> +#include <QtWidgets/QMenu> const QColor ConnectionBox::defaultColor = Qt::white; ConnectionBox::ConnectionBox(GraphicsBox* parent, Type type) : QGraphicsRectItem(-8, -8, 16, 16, parent) - , _type(type) + , type(type) { this->setBrush(ConnectionBox::defaultColor); @@ -68,18 +70,20 @@ void ConnectionBox::mouseReleaseEvent(QGraphicsSceneMouseEvent* event) { { this->setColor(ConnectionBox::defaultColor); other->setColor(ConnectionBox::defaultColor); - ConnectionBox::connect(this, other); + + auto* origin = this; + auto* target = other; + if (origin->getType() != ConnectionBox::Type::Output) + std::swap(origin, target); + + ConnectionBox::connect(dynamic_cast<OutputConnectionBox*>(origin), dynamic_cast<InputConnectionBox*>(target)); } } -void ConnectionBox::connect(ConnectionBox* a, ConnectionBox* b) { - Q_ASSERT(a->getType() != b->getType()); - auto* origin = a; - auto* target = b; - if (origin->getType() == ConnectionBox::Type::Input) - std::swap(origin, target); - - origin->connection = target->connection = std::make_shared<Connection>(origin, target); +void ConnectionBox::connect(gsl::not_null<OutputConnectionBox*> origin, gsl::not_null<InputConnectionBox*> target) { + auto connection = new Connection(origin, target); + origin->addConnection(connection); + target->setConnection(connection); } void ConnectionBox::contextMenuEvent(QGraphicsSceneContextMenuEvent* event) { @@ -90,22 +94,14 @@ void ConnectionBox::contextMenuEvent(QGraphicsSceneContextMenuEvent* event) { event->accept(); } -void ConnectionBox::on_Disconnect() { - auto* origin = this->connection->getOriginConnectionBox(); - auto* target = this->connection->getTargetConnectionBox(); - origin->getWrapperBox()->removeOutput(); - target->getWrapperBox()->removeInput(origin->getWrapperBox(), nullptr); - - origin->connection.reset(); - target->connection.reset(); -} - void ConnectionBox::setColor(QColor color) { QBrush brush = this->brush(); brush.setColor(color); this->setBrush(brush); } -WrapperBox* ConnectionBox::getWrapperBox() const { - return dynamic_cast<GraphicsBox*>(this->parentObject())->getWrapperBox(); +GraphicsBox* ConnectionBox::getParent() const { + auto* parent = dynamic_cast<GraphicsBox*>(this->parentObject()); + Q_ASSERT(parent); + return parent; } diff --git a/agui2/Graphics/ConnectionBox.h b/agui2/Graphics/Connection/ConnectionBox.h similarity index 66% rename from agui2/Graphics/ConnectionBox.h rename to agui2/Graphics/Connection/ConnectionBox.h index c560aae739..b7fb98f786 100644 --- a/agui2/Graphics/ConnectionBox.h +++ b/agui2/Graphics/Connection/ConnectionBox.h @@ -3,10 +3,13 @@ #include <QtWidgets/QGraphicsRectItem> -#include <Graphics/Connection.h> +#include <gsl/pointers> +#include <Graphics/Connection/Connection.h> + +class InputConnectionBox; class GraphicsBox; -class WrapperBox; +class OutputConnectionBox; class ConnectionBox : public QObject, public QGraphicsRectItem { Q_OBJECT @@ -18,31 +21,30 @@ public: Output }; - ConnectionBox(GraphicsBox* parent, Type type); - static const QColor defaultColor; - Type getType() const { return this->_type; } - WrapperBox* getWrapperBox() const; + Type getType() const { return this->type; } + GraphicsBox* getParent() const; protected: + ConnectionBox(GraphicsBox* parent, Type type); + void mousePressEvent(QGraphicsSceneMouseEvent* event) override; void mouseMoveEvent(QGraphicsSceneMouseEvent* event) override; void mouseReleaseEvent(QGraphicsSceneMouseEvent* event) override; void contextMenuEvent(QGraphicsSceneContextMenuEvent* event) override; - static void connect(ConnectionBox* a, ConnectionBox* b); + static void connect(gsl::not_null<OutputConnectionBox*> origin, gsl::not_null<InputConnectionBox*> target); private: void setColor(QColor color); - std::shared_ptr<Connection> connection; QGraphicsLineItem* tempLine = nullptr; - Type _type; + Type type; private slots: - void on_Disconnect(); + virtual void on_Disconnect() = 0; }; diff --git a/agui2/Graphics/Connection/InputConnectionBox.cpp b/agui2/Graphics/Connection/InputConnectionBox.cpp new file mode 100644 index 0000000000..99222ff246 --- /dev/null +++ b/agui2/Graphics/Connection/InputConnectionBox.cpp @@ -0,0 +1,17 @@ +#include <Graphics/Connection/InputConnectionBox.h> + +InputConnectionBox::InputConnectionBox(GraphicsBox* parent, uint8_t slot) + : ConnectionBox(parent, ConnectionBox::Type::Input) + , slot(slot) +{} + +void InputConnectionBox::setConnection(Connection* connection) { + Q_ASSERT(!this->connection); + this->connection = connection; +} + +void InputConnectionBox::on_Disconnect() { + Q_ASSERT(this->connection); + this->connection->destroy(); + Q_ASSERT(!this->connection); +} diff --git a/agui2/Graphics/Connection/InputConnectionBox.h b/agui2/Graphics/Connection/InputConnectionBox.h new file mode 100644 index 0000000000..e27a8d10b6 --- /dev/null +++ b/agui2/Graphics/Connection/InputConnectionBox.h @@ -0,0 +1,21 @@ +#pragma once +#include <Graphics/Connection/ConnectionBox.h> + +class InputConnectionBox : public ConnectionBox { + friend class Connection; + +public: + explicit InputConnectionBox(GraphicsBox* parent, uint8_t slot); + + void setConnection(Connection* connection); + uint8_t getSlot() const { return this->slot; } + +private: + void on_Disconnect() override; + +protected: + Connection* connection = nullptr; + uint8_t slot; +}; + + diff --git a/agui2/Graphics/Connection/OutputConnectionBox.cpp b/agui2/Graphics/Connection/OutputConnectionBox.cpp new file mode 100644 index 0000000000..97d4ba784f --- /dev/null +++ b/agui2/Graphics/Connection/OutputConnectionBox.cpp @@ -0,0 +1,16 @@ +#include <Graphics/Connection/OutputConnectionBox.h> + +OutputConnectionBox::OutputConnectionBox(GraphicsBox* parent) + : ConnectionBox(parent, ConnectionBox::Type::Output) +{} + +void OutputConnectionBox::addConnection(Connection* connection) { + this->connections.push_back(connection); +} + +void OutputConnectionBox::on_Disconnect() { + Q_ASSERT(!this->connections.empty()); + for (auto* connection: this->connections) + connection->destroy(); + Q_ASSERT(this->connections.empty()); +} diff --git a/agui2/Graphics/Connection/OutputConnectionBox.h b/agui2/Graphics/Connection/OutputConnectionBox.h new file mode 100644 index 0000000000..5f228e1c01 --- /dev/null +++ b/agui2/Graphics/Connection/OutputConnectionBox.h @@ -0,0 +1,19 @@ +#pragma once +#include <Graphics/Connection/ConnectionBox.h> + +class OutputConnectionBox : public ConnectionBox { + friend class Connection; + +public: + explicit OutputConnectionBox(GraphicsBox* parent); + + void addConnection(Connection* connection); + +private: + void on_Disconnect() override; + +protected: + std::vector<Connection*> connections; +}; + + diff --git a/agui2/Graphics/GraphicsBox.cpp b/agui2/Graphics/GraphicsBox.cpp index 8805ca9ced..9406e3a153 100644 --- a/agui2/Graphics/GraphicsBox.cpp +++ b/agui2/Graphics/GraphicsBox.cpp @@ -2,195 +2,55 @@ #include <utility> -#include <QDialog> -#include <QGraphicsScene> -#include <QGraphicsSceneContextMenuEvent> +#include <QtCore/QRectF> +#include <QtGui/QPainter> +#include <QtWidgets/QStyleOptionGraphicsItem> -#include <ConnectionHelper.h> -#include <Graphics/ConnectionBox.h> -#include <Graphics/GraphicsConnection.h> -#include <Graphics/GraphicsScene.h> -#include <WrapperBox.h> +#include <Graphics/Connection/InputConnectionBox.h> +#include <Graphics/Connection/OutputConnectionBox.h> -GraphicsBox::GraphicsBox(QString text, qreal x, qreal y, uint8_t inputs, uint8_t outputs) - : m_text(std::move(text)) - , m_color(Qt::blue) +GraphicsBox::GraphicsBox(std::unique_ptr<ModelBox> modelBox, QString text, QPointF pos) + : color(Qt::blue) + , text(std::move(text)) + , modelBox(std::move(modelBox)) { - m_font.setBold(true); - m_font.setPixelSize(18); + this->font.setBold(true); + this->font.setPixelSize(18); - setPos(x, y); - setFlags(ItemIsMovable); - setZValue(1); + this->setPos(pos); + this->setFlags(ItemIsMovable); + this->setZValue(1); + this->setBoundingRectangle(); - setBoundingRectangle(); - - this->inConnections.fill(nullptr); - - this->inputConnections.reserve(inputs); - for (uint8_t i = 0; i < inputs; ++i) + uint8_t maxInputCount = this->modelBox->getMaxInputCount(); + for (uint8_t i = 0; i < maxInputCount; ++i) { - auto* box = new ConnectionBox(this, ConnectionBox::Type::Input); - box->setPos(this->m_boundRect.left(), this->m_boundRect.top() + ((i + 1) * this->m_boundRect.height()) / float(inputs + 1)); - this->inputConnections.push_back(box); + auto* box = new InputConnectionBox(this, i); + box->setPos(this->boundRect.left(), this->boundRect.top() + ((i + 1) * this->boundRect.height()) / float(maxInputCount + 1)); + this->inputConnectionBoxes.push_back(box); } - this->outputConnections.reserve(outputs); - for (uint8_t i = 0; i < outputs; ++i) - { - auto* box = new ConnectionBox(this, ConnectionBox::Type::Output); - box->setPos(this->m_boundRect.right(), this->m_boundRect.top() + ((i + 1) * this->m_boundRect.height()) / float(outputs + 1)); - this->outputConnections.push_back(box); + if (this->modelBox->canHaveOutput()) { + this->outputConnectionBox = new OutputConnectionBox(this); + this->outputConnectionBox->setPos(this->boundRect.right(), this->boundRect.top() + this->boundRect.height() / 2.0); } } -GraphicsBox::~GraphicsBox() -{ - for (auto* conn: this->inConnections) - if (conn) - conn->on_Disconnect(); - if(m_OutConnection) - m_OutConnection->on_Disconnect(); -} - void GraphicsBox::setBoundingRectangle() { - m_boundRect = QFontMetrics(m_font).boundingRect(m_text); - m_boundRect.adjust(-BOX_MARGIN, -BOX_MARGIN, BOX_MARGIN, BOX_MARGIN); + this->boundRect = QFontMetrics(this->font).boundingRect(this->text); + this->boundRect.adjust(-20, -20, 20, 20); } -QRectF GraphicsBox::boundingRect() const -{ - return m_boundRect; +QRectF GraphicsBox::boundingRect() const { + return this->boundRect; } -void GraphicsBox::paint(QPainter *painter, const QStyleOptionGraphicsItem *options __attribute__((unused)), QWidget *widget __attribute__((unused))) -{ - painter->setFont(m_font); +void GraphicsBox::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) { + painter->setFont(this->font); painter->setPen(Qt::white); - painter->fillRect(m_boundRect,m_color); + painter->fillRect(this->boundRect, this->color); prepareGeometryChange(); - painter->drawText(m_boundRect, Qt::AlignCenter, m_text, &m_boundRect ); - m_boundRect.adjust(-BOX_MARGIN, -BOX_MARGIN, BOX_MARGIN, BOX_MARGIN); -} - -void GraphicsBox::addOutput(GraphicsConnection *connection) -{ - m_OutConnection = connection; -} - -void GraphicsBox::addInput(GraphicsConnection* connection) -{ - if (this->inputConnections.size() == 1) { - this->inConnections[0] = connection; - } - else { - if (this->inConnections[0] == nullptr) { - this->inConnections[0] = connection; - } - else { - Q_ASSERT(this->inputConnections.size() > 1); - this->inConnections[1] = connection; - } - } -} - -void GraphicsBox::removeOutput() -{ - m_OutConnection = nullptr; -} - -void GraphicsBox::removeInput(GraphicsConnection *connection __attribute__((unused))) -{ - if (this->inputConnections.size() == 1) { - this->inConnections[0] = nullptr; - } - else { - if (this->inConnections[0] == connection) { - this->inConnections[0] = nullptr; - } else if (this->inConnections[1] == connection) { - Q_ASSERT(this->inputConnections.size() > 1); - this->inConnections[1] = nullptr; - } - } + painter->drawText(this->boundRect, Qt::AlignCenter, this->text, &this->boundRect); + this->boundRect.adjust(-20, -20, 20, 20); } - -QPointF GraphicsBox::getConnectionOrigin() -{ - return {m_boundRect.right(), m_boundRect.center().y()}; -} - -QPointF GraphicsBox::getConnectionTarget(GraphicsConnection *connection __attribute__((unused))) -{ - if (this->inputConnections.size() == 1) - return {m_boundRect.left(), m_boundRect.center().y()}; - - QPointF topPoint (m_boundRect.left(), m_boundRect.y() + (m_boundRect.height() / 3.0)); - QPointF bottomPoint (m_boundRect.left(), m_boundRect.y() + (2.0 * m_boundRect.height() / 3.0)); - - if (this->inConnections[0] && this->inConnections[1]) { - if (this->inConnections[0] == connection) - { - if (this->inConnections[0]->getOriginPoint().y() < this->inConnections[1]->getOriginPoint().y()) - return topPoint; - else - return bottomPoint; - } - else { - if (this->inConnections[0]->getOriginPoint().y() < this->inConnections[1]->getOriginPoint().y()) - return bottomPoint; - else - return topPoint; - } - } - else { - if (connection->getOriginPoint().y() < m_boundRect.center().y()) - return topPoint; - else - return bottomPoint; - } -} - -void GraphicsBox::setWrapper(WrapperBox *wrapper) -{ - m_wrapper = wrapper; -} - -void GraphicsBox::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) -{ - if( event->button() == Qt::LeftButton ) - { - event->accept(); - ConnectionHelper::getInstance().completeConnection( m_wrapper ); - } - QGraphicsObject::mouseReleaseEvent(event); -} - -void GraphicsBox::finishMenu(QMenu *menu) -{ - QAction * a; - a = menu->addAction( m_wrapper->getModel()->isOutputSet() ? "Re&connect" : "&Connect"); - QObject::connect(a,SIGNAL(triggered()), this, SLOT(on_Connect())); - a = menu->addAction("&Delete"); - QObject::connect(a,SIGNAL(triggered()), this, SLOT(on_Delete())); -} - -void GraphicsBox::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) -{ - QMenu menu; - finishMenu(&menu); - menu.exec(event->screenPos()); - ungrabMouse(); - event->accept(); -} - -void GraphicsBox::on_Connect() -{ - ConnectionHelper::getInstance().startConnection( m_wrapper ); -} - -void GraphicsBox::on_Delete() -{ - delete m_wrapper; -} - diff --git a/agui2/Graphics/GraphicsBox.h b/agui2/Graphics/GraphicsBox.h index 5fdcbcc1ed..1d23bd97e9 100644 --- a/agui2/Graphics/GraphicsBox.h +++ b/agui2/Graphics/GraphicsBox.h @@ -1,56 +1,38 @@ #pragma once -#include <QAction> -#include <QBrush> -#include <QPainter> -#include <QGraphicsItem> -#include <QFont> -#include <QMenu> -#include <Graphics/GraphicsConnection.h> +#include <QtGui/QFont> +#include <QtWidgets/QGraphicsObject> -#define BOX_MARGIN 20 +#include <gsl/pointers> + +#include <Models/ModelBox.h> class ConnectionBox; -class GraphicsConnection; -class WrapperBox; -class GraphicsBox : public QGraphicsObject -{ +class GraphicsBox : public QGraphicsObject { Q_OBJECT public: - friend class WrapperBox; + GraphicsBox(std::unique_ptr<ModelBox> modelBox, QString text, QPointF pos); - explicit GraphicsBox(QString text, qreal x = 0, qreal y = 0, uint8_t inputs = 1, uint8_t outputs = 1); - ~GraphicsBox() override; + void setBoundingRectangle(); - void paint(QPainter *painter, const QStyleOptionGraphicsItem *options, QWidget *widget) override; - void addOutput( GraphicsConnection* connection ); - virtual void addInput( GraphicsConnection* connection ); - void removeOutput(); - virtual void removeInput( GraphicsConnection* connection ); QRectF boundingRect() const override; - QPointF getConnectionOrigin(); - virtual QPointF getConnectionTarget( GraphicsConnection* connection ); - WrapperBox* getWrapperBox() const { return this->m_wrapper; } + void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) override; + + ModelBox* getModelBox() const { return this->modelBox.get(); } + protected: - QFont m_font; - QColor m_color; - QString m_text; - QRectF m_boundRect; - GraphicsConnection* m_OutConnection = nullptr; - std::array<GraphicsConnection*, 2> inConnections; - WrapperBox* m_wrapper; - std::vector<ConnectionBox*> inputConnections; - std::vector<ConnectionBox*> outputConnections; - void finishMenu( QMenu * menu ); - void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override ; - void contextMenuEvent(QGraphicsSceneContextMenuEvent *event) override; + QColor color; + private: - void setWrapper( WrapperBox* wrapper ); - void setBoundingRectangle(); -private slots: - void on_Connect(); - void on_Delete(); + QRectF boundRect; + QString text; + QFont font; + + std::unique_ptr<ModelBox> modelBox; + + std::vector<ConnectionBox*> inputConnectionBoxes; + ConnectionBox* outputConnectionBox; }; diff --git a/agui2/Graphics/GraphicsConnection.cpp b/agui2/Graphics/GraphicsConnection.cpp deleted file mode 100644 index 1fea9259e5..0000000000 --- a/agui2/Graphics/GraphicsConnection.cpp +++ /dev/null @@ -1,136 +0,0 @@ -#include <Graphics/GraphicsConnection.h> - -#include <QAction> -#include <QGraphicsScene> -#include <QMenu> -#include <QPainter> - -#include <ConnectionHelper.h> -#include <WrapperBox.h> - -#define SHORTEST_LINE 20.0 - -GraphicsConnection::GraphicsConnection(WrapperBox * origin, WrapperBox * target) - : m_origin(origin) - , m_target(target) - , m_originGraphics(origin->getGraphics()) - , m_targetGraphics(target->getGraphics()) - , m_boundRect(getOriginPoint(), getTargetPoint()) -{ - setPos(0, 0); - setZValue(0.5); - - origin->addOutput( target, this ); - target->addInput( m_origin, this ); - - m_originGraphics->scene()->addItem(this); - m_originGraphics->scene()->update(); -} - -QRectF GraphicsConnection::boundingRect() const -{ - return m_boundRect; -} - -void GraphicsConnection::paint(QPainter *painter, const QStyleOptionGraphicsItem *options __attribute__((unused)), QWidget *widget __attribute__((unused))) -{ - - QPointF originPoint = getOriginPoint(); - QPointF targetPoint = getTargetPoint(); - recalculateBoundingRect( originPoint, targetPoint ); - - painter->setPen(QPen(Qt::black,1)); - if( (targetPoint.x() - originPoint.x()) > SHORTEST_LINE ) - drawDirectConnection( painter, originPoint, targetPoint ); - else - drawAroundConnection( painter, originPoint, targetPoint ); -} - -// Local coordinates -QPointF GraphicsConnection::getOriginPoint() -{ - return mapFromItem(m_originGraphics, m_originGraphics->getConnectionOrigin()); -} - -// Local coordinates -QPointF GraphicsConnection::getTargetPoint() -{ - return mapFromItem(m_targetGraphics, m_targetGraphics->getConnectionTarget( this )); -} - -void GraphicsConnection::mousePressEvent(QGraphicsSceneMouseEvent *event) -{ - if( event->button() == Qt::LeftButton ) - { - ConnectionHelper::getInstance().completeConnection(nullptr); - } - this->QGraphicsItem::mouseReleaseEvent(event); -} - -void GraphicsConnection::recalculateBoundingRect(const QPointF & topLeft , const QPointF & bottomRight) -{ - prepareGeometryChange(); - m_boundRect.setTopLeft( topLeft ); - m_boundRect.setBottomRight( bottomRight ); - m_boundRect.adjust( -1, -1, 1, 1 ); -} - -void GraphicsConnection::drawDirectConnection(QPainter * painter, const QPointF &originPoint, const QPointF &targetPoint) -{ - qreal midWidth = originPoint.x() + qAbs( originPoint.x() - targetPoint.x() )/2.0; - painter->drawLine(originPoint.x(), originPoint.y(), - midWidth, originPoint.y()); - painter->drawLine(midWidth, originPoint.y(), - midWidth, targetPoint.y()); - painter->drawLine(midWidth, targetPoint.y(), - targetPoint.x(), targetPoint.y()); - if( originPoint.y() < targetPoint.y() ) - recalculateBoundingRect( originPoint, targetPoint ); - else - { - QPointF topLeft( originPoint.x(), targetPoint.y() ); - QPointF bottomRight( targetPoint.x(), originPoint.y() ); - recalculateBoundingRect( topLeft, bottomRight ); - } -} - -void GraphicsConnection::drawAroundConnection(QPainter *painter, const QPointF &originPoint, const QPointF &targetPoint) -{ - qreal midHeight; - QPointF topLeft; - QPointF bottomRight; - - if( originPoint.y() < targetPoint.y() ) - { - midHeight = originPoint.y() + qAbs( originPoint.y() - targetPoint.y() )/2.0; - topLeft = QPointF( targetPoint.x() - SHORTEST_LINE, originPoint.y() ); - bottomRight = QPointF( originPoint.x() + SHORTEST_LINE, targetPoint.y() ); - } - else - { - midHeight = targetPoint.y() + qAbs( originPoint.y() - targetPoint.y() )/2.0; - topLeft = QPointF( targetPoint.x() - SHORTEST_LINE, targetPoint.y() ); - bottomRight = QPointF( originPoint.x() + SHORTEST_LINE, originPoint.y() ); - } - - painter->drawLine(originPoint.x(), originPoint.y(), - bottomRight.x(), originPoint.y()); - painter->drawLine(bottomRight.x(), originPoint.y(), - bottomRight.x(), midHeight); - painter->drawLine(bottomRight.x(), midHeight, - topLeft.x(), midHeight); - painter->drawLine(topLeft.x(), midHeight, - topLeft.x(), targetPoint.y()); - painter->drawLine(topLeft.x(), targetPoint.y(), - targetPoint.x(), targetPoint.y()); - recalculateBoundingRect( topLeft, bottomRight ); -} - -void GraphicsConnection::on_Disconnect() -{ - m_origin->removeOutput(); - m_target->removeInput( m_origin, this ); - delete this; -} - - diff --git a/agui2/Graphics/GraphicsConnection.h b/agui2/Graphics/GraphicsConnection.h deleted file mode 100644 index 5735d65e1c..0000000000 --- a/agui2/Graphics/GraphicsConnection.h +++ /dev/null @@ -1,37 +0,0 @@ -#pragma once -#include <tuple> - -#include <QGraphicsItem> -#include <QGraphicsSceneMouseEvent> - -#include <Graphics/GraphicsBox.h> - -class GraphicsBox; -class WrapperBox; - -class GraphicsConnection : public QGraphicsObject -{ - Q_OBJECT -public: - GraphicsConnection(WrapperBox * origin, WrapperBox * target); - ~GraphicsConnection() override = default; - QRectF boundingRect() const override; - void paint(QPainter *painter, const QStyleOptionGraphicsItem *options, QWidget *widget) override; - QPointF getOriginPoint(); - QPointF getTargetPoint(); -protected: - void mousePressEvent(QGraphicsSceneMouseEvent *event) override; -private: - void recalculateBoundingRect(const QPointF &topLeft, const QPointF &bottomRight); - void drawDirectConnection(QPainter * painter, const QPointF &originPoint, const QPointF &targetPoint); - void drawAroundConnection(QPainter * painter, const QPointF &originPoint, const QPointF &targetPoint); - GraphicsBox * m_targetGraphics; - GraphicsBox * m_originGraphics; - WrapperBox * m_target; - WrapperBox * m_origin; - QRectF m_boundRect; -public slots: - void on_Disconnect(); -}; - - diff --git a/agui2/Graphics/GraphicsScene.cpp b/agui2/Graphics/GraphicsScene.cpp index 405284d7d1..abdccd3423 100644 --- a/agui2/Graphics/GraphicsScene.cpp +++ b/agui2/Graphics/GraphicsScene.cpp @@ -2,8 +2,6 @@ #include <QGraphicsView> -#include <ConnectionHelper.h> - GraphicsScene::GraphicsScene(QObject *parent) : QGraphicsScene(parent) {} @@ -17,15 +15,4 @@ void GraphicsScene::wheelEvent(QGraphicsSceneWheelEvent *event) if( factor > 1.0 ) view->centerOn(event->scenePos()); event->accept(); -} - -void GraphicsScene::mousePressEvent(QGraphicsSceneMouseEvent *event) -{ - if( event->button() == Qt::LeftButton ) - { - QGraphicsItem* item = itemAt(event->scenePos(), views().first()->transform()); - if( item == nullptr ) - ConnectionHelper::getInstance().completeConnection(nullptr); - } - QGraphicsScene::mousePressEvent(event); -} +} \ No newline at end of file diff --git a/agui2/Graphics/GraphicsScene.h b/agui2/Graphics/GraphicsScene.h index 7153b336a6..942ea9c904 100644 --- a/agui2/Graphics/GraphicsScene.h +++ b/agui2/Graphics/GraphicsScene.h @@ -11,7 +11,6 @@ public: protected: void wheelEvent(QGraphicsSceneWheelEvent *event) override; - void mousePressEvent(QGraphicsSceneMouseEvent *event) override; }; diff --git a/agui2/Graphics/InputGraphicsBox.cpp b/agui2/Graphics/InputGraphicsBox.cpp index 19fc1bec3b..9d8cdb2023 100644 --- a/agui2/Graphics/InputGraphicsBox.cpp +++ b/agui2/Graphics/InputGraphicsBox.cpp @@ -1,59 +1,43 @@ #include <Graphics/InputGraphicsBox.h> -#include <QMenu> -#include <QAction> -#include <QObject> +#include <memory> -#include <ConnectionHelper.h> -#include <Graphics/Dialogs/InputDialog.h> -#include <Models/InputModelBox.h> -#include <WrapperBox.h> +#include <QtCore/QString> +#include <QtCore/QPointF> +#include <QGraphicsSceneContextMenuEvent> +#include <QtWidgets/QMenu> -class ModelBox; +#include <Graphics/Dialogs/InputDialog.h> -void InputGraphicsBox::paint(QPainter *painter, const QStyleOptionGraphicsItem *options, QWidget *widget) +InputGraphicsBox::InputGraphicsBox(std::unique_ptr<InputModelBox> modelBox, + const QString& text, + const QPointF& pos) + : GraphicsBox(std::move(modelBox), text, pos) { - if(dynamic_cast<InputModelBox*>(m_wrapper->getModel())->isInputEmpty() ) - m_color = Qt::red; - else - m_color = Qt::blue; - GraphicsBox::paint( painter, options, widget ); + this->color = Qt::red; } void InputGraphicsBox::on_SetInput() { - auto * model = dynamic_cast<InputModelBox*>(m_wrapper->getModel()); - auto * inputDialog = new InputDialog(); + auto* model = dynamic_cast<InputModelBox*>(this->getModelBox()); + Q_ASSERT(model); + auto inputDialog = std::make_unique<InputDialog>(); - inputDialog->setSettings( model->getSettings() ); - inputDialog->setAutomaton( model->getAutomaton() ); + inputDialog->setSettings(model->getSettings()); + inputDialog->setAutomaton(model->getAutomaton()); - if(inputDialog->exec()) - { - model->setAutomaton( inputDialog->getAutomaton() ); - model->setSettings( inputDialog->getSettings() ); + if (inputDialog->exec()) { + model->setAutomaton(inputDialog->getAutomaton()); + model->setSettings(inputDialog->getSettings()); } - delete inputDialog; -} - -void InputGraphicsBox::on_Connect() -{ - ConnectionHelper::getInstance().startConnection( m_wrapper ); -} -void InputGraphicsBox::on_Delete() -{ - delete m_wrapper; + this->color = model->getAutomaton() ? Qt::blue : Qt::red; } -void InputGraphicsBox::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) -{ +void InputGraphicsBox::contextMenuEvent(QGraphicsSceneContextMenuEvent* event) { QMenu menu; - QAction * a; - a = menu.addAction("&Set Input"); - QObject::connect(a,SIGNAL(triggered()), this, SLOT(on_SetInput())); - menu.addSeparator(); - finishMenu(&menu); + auto* a = menu.addAction("&Set input"); + QObject::connect(a, SIGNAL(triggered()), this, SLOT(on_SetInput())); menu.exec(event->screenPos()); ungrabMouse(); event->accept(); diff --git a/agui2/Graphics/InputGraphicsBox.h b/agui2/Graphics/InputGraphicsBox.h index e6dafb753b..2d844074ae 100644 --- a/agui2/Graphics/InputGraphicsBox.h +++ b/agui2/Graphics/InputGraphicsBox.h @@ -1,19 +1,18 @@ #pragma once #include <Graphics/GraphicsBox.h> -class InputGraphicsBox : public GraphicsBox -{ +#include <Models/InputModelBox.h> + +class InputGraphicsBox : public GraphicsBox { Q_OBJECT public: - InputGraphicsBox(qreal x = 0, qreal y = 0): GraphicsBox("Input", x, y, 0, 1) {} - virtual ~InputGraphicsBox() {} - virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *options, QWidget *widget); + InputGraphicsBox(std::unique_ptr<InputModelBox> modelBox, const QString& text, const QPointF& pos); + +protected: + void contextMenuEvent(QGraphicsSceneContextMenuEvent* event) override; + private slots: void on_SetInput(); - void on_Connect(); - void on_Delete(); -protected: - void contextMenuEvent(QGraphicsSceneContextMenuEvent *event); }; diff --git a/agui2/Graphics/OutputGraphicsBox.cpp b/agui2/Graphics/OutputGraphicsBox.cpp deleted file mode 100644 index 849c997c8c..0000000000 --- a/agui2/Graphics/OutputGraphicsBox.cpp +++ /dev/null @@ -1,29 +0,0 @@ -#include <Graphics/OutputGraphicsBox.h> - -#include <QMenu> -#include <QAction> - -#include <Graphics/Dialogs/OutputDialog.h> -#include <Models/OutputModelBox.h> -#include <WrapperBox.h> - -void OutputGraphicsBox::on_SetOutput() -{ - auto * model = dynamic_cast<OutputModelBox*>(m_wrapper->getModel()); - auto * outputDialog = new OutputDialog(); - outputDialog->setSettings( model->getSettings() ); - if( outputDialog->exec() ) - model->setSettings( outputDialog->getSettings() ); - delete outputDialog; -} - -void OutputGraphicsBox::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) -{ - QMenu menu; - QAction * a; - a = menu.addAction("&Set Output"); - QObject::connect(a,SIGNAL(triggered()), this, SLOT(on_SetOutput())); - menu.exec(event->screenPos()); - ungrabMouse(); - event->accept(); -} diff --git a/agui2/Graphics/OutputGraphicsBox.h b/agui2/Graphics/OutputGraphicsBox.h deleted file mode 100644 index d4673ce3c0..0000000000 --- a/agui2/Graphics/OutputGraphicsBox.h +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once -#include <Graphics/GraphicsBox.h> - -class OutputGraphicsBox : public GraphicsBox -{ - Q_OBJECT -public: - OutputGraphicsBox( qreal x = 0, qreal y = 0 ): GraphicsBox( "Output", x, y, 1, 0 ) {} - virtual void contextMenuEvent(QGraphicsSceneContextMenuEvent *event); -private slots: - void on_SetOutput(); -}; - - diff --git a/agui2/MainWindow.cpp b/agui2/MainWindow.cpp index 3426f74459..d23916a1a3 100644 --- a/agui2/MainWindow.cpp +++ b/agui2/MainWindow.cpp @@ -5,12 +5,16 @@ #include <QFileDialog> #include <QGraphicsItem> -#include <ConnectionHelper.h> +#include <AlibExceptionHandler.h> #include <Graphics/Dialogs/InputDialog.h> #include <Graphics/InputGraphicsBox.h> -#include <Graphics/OutputGraphicsBox.h> +#include <Graphics/GraphicsBox.h> +#include <Models/InputModelBox.h> #include <ui_MainWindow.h> #include <WrapperFactory.h> +#include <QtWidgets/QMessageBox> +#include <Graphics/Dialogs/ResultDialog.h> +#include "Converter.h" MainWindow::MainWindow() : ui(new Ui::MainWindow) @@ -19,40 +23,50 @@ MainWindow::MainWindow() ui->setupUi(this); ui->graphicsView->setScene(this->scene.get()); - WrapperBox * inputBox = WrapperFactory::create( WrapperFactory::INPUT, 0, 0 ); - scene->addItem(inputBox->getGraphics()); - WrapperBox * outputBox = WrapperFactory::create( WrapperFactory::OUTPUT, 400, 0 ); - scene->addItem(outputBox->getGraphics()); - m_output = outputBox; + this->scene->addItem(WrapperFactory::createNew(WrapperFactory::INPUT, 0, 200)); + outputBox = WrapperFactory::createNew(WrapperFactory::OUTPUT, 400, 200); + this->scene->addItem(outputBox); +} + +void MainWindow::displayError(const QString& text) const { + QMessageBox::critical(this->ui->graphicsView, "Error", text, QMessageBox::Close); } void MainWindow::on_RunBtn_clicked() { - m_output->getModel()->run(); + AlibExceptionHandler::getInstance().reset(); + auto result = this->outputBox->getModelBox()->run(); + if (!result) { + if (AlibExceptionHandler::getInstance().isActive()) + this->displayError(AlibExceptionHandler::getInstance().getMessage()); + else + this->displayError("Nothing was outputted."); + } + else { + auto* resultDlg = new ResultDialog(); + resultDlg->setImageContent(Converter::automatonToPNG(result)); + resultDlg->exec(); + } } void MainWindow::on_DeterminizeBtn_clicked() { - WrapperBox * box = WrapperFactory::create( WrapperFactory::DETERMINIZE, 200, 50 ); - scene->addItem(box->getGraphics()); + this->scene->addItem(WrapperFactory::createNew(WrapperFactory::DETERMINIZE, 200, 50)); } void MainWindow::on_TotalBtn_clicked() { - WrapperBox * box = WrapperFactory::create( WrapperFactory::TOTAL, 300, 50 ); - scene->addItem(box->getGraphics()); + this->scene->addItem(WrapperFactory::createNew(WrapperFactory::TOTAL, 300, 50)); } void MainWindow::on_CompactBtn_clicked() { - WrapperBox * box = WrapperFactory::create( WrapperFactory::COMPACT, 200, -50 ); - scene->addItem(box->getGraphics()); + this->scene->addItem(WrapperFactory::createNew(WrapperFactory::COMPACT, 200, -50)); } void MainWindow::on_SingleInitialBtn_clicked() { - WrapperBox * box = WrapperFactory::create( WrapperFactory::SINGLE_INITIAL, 200, 30 ); - scene->addItem(box->getGraphics()); + this->scene->addItem(WrapperFactory::createNew(WrapperFactory::SINGLE_INITIAL, 200, 30)); } void MainWindow::on_EpsilonRemoveBtn_clicked() @@ -63,62 +77,53 @@ void MainWindow::on_EpsilonRemoveBtn_clicked() QObject::connect(a,SIGNAL(triggered()), this, SLOT(on_EpsilonRemoveIncoming())); a = menu.addAction("&Outgoing"); QObject::connect(a,SIGNAL(triggered()), this, SLOT(on_EpsilonRemoveOutgoing())); - QPoint point = ui->EpsilonRemoveBtn->mapToGlobal( ui->EpsilonRemoveBtn->rect().topRight() ); - menu.exec( point ); + QPoint point = ui->EpsilonRemoveBtn->mapToGlobal(ui->EpsilonRemoveBtn->rect().topRight()); + menu.exec(point); } void MainWindow::on_MinimizeBtn_clicked() { - WrapperBox * box = WrapperFactory::create( WrapperFactory::MINIMIZE, 200, 100 ); - scene->addItem(box->getGraphics()); + this->scene->addItem(WrapperFactory::createNew(WrapperFactory::MINIMIZE, 200, 100)); } void MainWindow::on_NormilizeBtn_clicked() { - WrapperBox * box = WrapperFactory::create( WrapperFactory::NORMALIZE, 200, 100 ); - scene->addItem(box->getGraphics()); + this->scene->addItem(WrapperFactory::createNew(WrapperFactory::NORMALIZE, 200, 100)); } void MainWindow::on_EpsilonRemoveIncoming() { - WrapperBox * box = WrapperFactory::create( WrapperFactory::EPSILON_REMOVE_IN, 200, 30 ); - scene->addItem(box->getGraphics()); + this->scene->addItem(WrapperFactory::createNew(WrapperFactory::EPSILON_REMOVE_IN, 200, 30)); } void MainWindow::on_EpsilonRemoveOutgoing() { - WrapperBox * box = WrapperFactory::create( WrapperFactory::EPSILON_REMOVE_OUT, 200, 30 ); - scene->addItem(box->getGraphics()); + this->scene->addItem(WrapperFactory::createNew(WrapperFactory::EPSILON_REMOVE_OUT, 200, 30)); } void MainWindow::on_RenameBtn_clicked() { - WrapperBox * box = WrapperFactory::create( WrapperFactory::RENAME, 200, 30 ); - scene->addItem(box->getGraphics()); + this->scene->addItem(WrapperFactory::createNew(WrapperFactory::RENAME, 200, 30)); } void MainWindow::on_TrimBtn_clicked() { - WrapperBox * box = WrapperFactory::create( WrapperFactory::TRIM, 200, 30 ); - scene->addItem(box->getGraphics()); + this->scene->addItem(WrapperFactory::createNew(WrapperFactory::TRIM, 200, 30)); } void MainWindow::on_RemoveUselessBtn_clicked() { - WrapperBox * box = WrapperFactory::create( WrapperFactory::REMOVE_USELES, 200, 30 ); - scene->addItem(box->getGraphics()); + this->scene->addItem(WrapperFactory::createNew(WrapperFactory::REMOVE_USELES, 200, 30)); } void MainWindow::on_RemoveUnreachableBtn_clicked() { - WrapperBox * box = WrapperFactory::create( WrapperFactory::REMOVE_UNREACHABLE, 200, 30 ); - scene->addItem(box->getGraphics()); + this->scene->addItem(WrapperFactory::createNew(WrapperFactory::REMOVE_UNREACHABLE, 200, 30)); } void MainWindow::on_ReverseBtn_clicked() { - WrapperBox * box = WrapperFactory::create( WrapperFactory::REVERSE, 200, 30 ); - scene->addItem(box->getGraphics()); + this->scene->addItem(WrapperFactory::createNew(WrapperFactory::REVERSE, 200, 30)); } void MainWindow::on_IterateBtn_clicked() @@ -129,20 +134,18 @@ void MainWindow::on_IterateBtn_clicked() QObject::connect(a,SIGNAL(triggered()), this, SLOT(on_Iterate())); a = menu.addAction("&Epsilon transitions"); QObject::connect(a,SIGNAL(triggered()), this, SLOT(on_IterateEpsilon())); - QPoint point = ui->IterateBtn->mapToGlobal( ui->IterateBtn->rect().topRight() ); - menu.exec( point ); + QPoint point = ui->IterateBtn->mapToGlobal(ui->IterateBtn->rect().topRight()); + menu.exec(point); } void MainWindow::on_Iterate() { - WrapperBox * box = WrapperFactory::create( WrapperFactory::ITERATE, 200, 30 ); - scene->addItem(box->getGraphics()); + this->scene->addItem(WrapperFactory::createNew(WrapperFactory::ITERATE, 200, 30)); } void MainWindow::on_IterateEpsilon() { - WrapperBox * box = WrapperFactory::create( WrapperFactory::ITERATE_EPSILON, 200, 30 ); - scene->addItem(box->getGraphics()); + this->scene->addItem(WrapperFactory::createNew(WrapperFactory::ITERATE_EPSILON, 200, 30)); } void MainWindow::on_ConcatenateBtn_clicked() @@ -153,20 +156,18 @@ void MainWindow::on_ConcatenateBtn_clicked() QObject::connect(a,SIGNAL(triggered()), this, SLOT(on_Concatenate())); a = menu.addAction("&Epsilon transitions"); QObject::connect(a,SIGNAL(triggered()), this, SLOT(on_ConcatenateEpsilon())); - QPoint point = ui->ConcatenateBtn->mapToGlobal( ui->ConcatenateBtn->rect().topRight() ); - menu.exec( point ); + QPoint point = ui->ConcatenateBtn->mapToGlobal(ui->ConcatenateBtn->rect().topRight()); + menu.exec(point); } void MainWindow::on_Concatenate() { - WrapperBox * box = WrapperFactory::create( WrapperFactory::CONCATENATE, 200, 100 ); - scene->addItem(box->getGraphics()); + this->scene->addItem(WrapperFactory::createNew(WrapperFactory::CONCATENATE, 200, 100)); } void MainWindow::on_ConcatenateEpsilon() { - WrapperBox * box = WrapperFactory::create( WrapperFactory::CONCATENATE_EPSILON, 200, 100 ); - scene->addItem(box->getGraphics()); + this->scene->addItem(WrapperFactory::createNew(WrapperFactory::CONCATENATE_EPSILON, 200, 100)); } void MainWindow::on_UnionBtn_clicked() @@ -177,31 +178,27 @@ void MainWindow::on_UnionBtn_clicked() QObject::connect(a,SIGNAL(triggered()), this, SLOT(on_Union())); a = menu.addAction("&Epsilon transitions"); QObject::connect(a,SIGNAL(triggered()), this, SLOT(on_UnionEpsilon())); - QPoint point = ui->UnionBtn->mapToGlobal( ui->UnionBtn->rect().topRight() ); - menu.exec( point ); + QPoint point = ui->UnionBtn->mapToGlobal(ui->UnionBtn->rect().topRight()); + menu.exec(point); } void MainWindow::on_Union() { - WrapperBox * box = WrapperFactory::create( WrapperFactory::UNION, 200, 100 ); - scene->addItem(box->getGraphics()); + this->scene->addItem(WrapperFactory::createNew(WrapperFactory::UNION, 200, 100)); } void MainWindow::on_UnionEpsilon() { - WrapperBox * box = WrapperFactory::create( WrapperFactory::UNION_EPSILON, 200, 100 ); - scene->addItem(box->getGraphics()); + this->scene->addItem(WrapperFactory::createNew(WrapperFactory::UNION_EPSILON, 200, 100)); } void MainWindow::on_IntersectBtn_clicked() { - WrapperBox * box = WrapperFactory::create( WrapperFactory::INTERSECT, 200, 100 ); - scene->addItem(box->getGraphics()); + this->scene->addItem(WrapperFactory::createNew(WrapperFactory::INTERSECT, 200, 100)); } void MainWindow::on_AddInputBtn_clicked() { int y = qrand()%4 * 100; - WrapperBox * box = WrapperFactory::create( WrapperFactory::INPUT, 0, y ); - scene->addItem(box->getGraphics()); + this->scene->addItem(WrapperFactory::createNew(WrapperFactory::INPUT, 0, y)); } diff --git a/agui2/MainWindow.h b/agui2/MainWindow.h index f7f83910e5..30c55aec01 100644 --- a/agui2/MainWindow.h +++ b/agui2/MainWindow.h @@ -9,7 +9,7 @@ #include <Graphics/GraphicsScene.h> #include <ui_MainWindow.h> -class WrapperBox; +class GraphicsBox; class MainWindow : public QMainWindow { @@ -18,6 +18,9 @@ class MainWindow : public QMainWindow public: explicit MainWindow(); +private: + void displayError(const QString& text) const; + private slots: void on_AddInputBtn_clicked(); void on_RunBtn_clicked(); @@ -50,7 +53,7 @@ private slots: private: std::unique_ptr<Ui::MainWindow> ui; std::unique_ptr<GraphicsScene> scene; - WrapperBox* m_output; + GraphicsBox* outputBox; }; diff --git a/agui2/Models/AlgorithmModelBox.cpp b/agui2/Models/AlgorithmModelBox.cpp new file mode 100644 index 0000000000..3cf697fc25 --- /dev/null +++ b/agui2/Models/AlgorithmModelBox.cpp @@ -0,0 +1,71 @@ +#include <Models/AlgorithmModelBox.h> + +#include <string> + +#include <registry/AlgorithmRegistry.hpp> +#include <common/AlgorithmHelper.h> +#include <exception/CommonException.h> + +#include <AlibExceptionHandler.h> + +namespace { + uint8_t determineNumberOfInputs(const std::string& name) { + ext::set<ext::tuple<abstraction::AlgorithmCategories::AlgorithmCategory, + ext::pair<std::string, + ext::set<abstraction::ParamQualifiers::ParamQualifier>>, + ext::vector<ext::tuple<std::string, + ext::set<abstraction::ParamQualifiers::ParamQualifier>, + std::string>>>> data = abstraction::AlgorithmRegistry::listOverloads(name, {}); + for (const auto& tup: data) { + const auto& out = std::get<1>(tup).first; + if (out.find("automaton::DFA") == 0 || out.find("automaton::NFA") == 0) + { + bool ok = true; + for (const auto& tup2: std::get<2>(tup)) + { + const auto& in = std::get<0>(tup2); + if (in.find("automaton::DFA") != 0 && in.find("automaton::NFA") != 0) + { + ok = false; + break; + } + } + if (!ok) + continue; + return static_cast<uint8_t>(std::get<2>(tup).size()); + } + } + Q_ASSERT(false && "Failed to determine proper overload."); + return 0; + } +} + +AlgorithmModelBox::AlgorithmModelBox(std::string name) + : ModelBox(ModelType::Algorithm, determineNumberOfInputs(name)) + , name(std::move(name)) { + Q_ASSERT(!this->name.empty()); +} + +std::shared_ptr<abstraction::OperationAbstraction> AlgorithmModelBox::run() { + ext::vector<std::shared_ptr<abstraction::OperationAbstraction>> params; + for (const auto& p: this->inputs) + { + if (!p.second) + return nullptr; + params.push_back(p.second->run()); + if (!params.back()) + return nullptr; + } + + std::vector<bool> moves(params.size(), true); + try { + return abstraction::AlgorithmHelper::eval(this->name, + {}, + params, + moves, + abstraction::AlgorithmCategories::AlgorithmCategory::DEFAULT); + } catch (const exception::CommonException& e) { + AlibExceptionHandler::getInstance().setMessage(QString::fromStdString(e.getCause())); + return nullptr; + } +} diff --git a/agui2/Models/AlgorithmModelBox.h b/agui2/Models/AlgorithmModelBox.h new file mode 100644 index 0000000000..95987d92ea --- /dev/null +++ b/agui2/Models/AlgorithmModelBox.h @@ -0,0 +1,14 @@ +#pragma once +#include <Models/ModelBox.h> + +class AlgorithmModelBox : public ModelBox { +public: + explicit AlgorithmModelBox(std::string name); + + std::shared_ptr<abstraction::OperationAbstraction> run() override; + +private: + std::string name; +}; + + diff --git a/agui2/Models/DoubleModelBox.cpp b/agui2/Models/DoubleModelBox.cpp deleted file mode 100644 index 13709540d5..0000000000 --- a/agui2/Models/DoubleModelBox.cpp +++ /dev/null @@ -1,82 +0,0 @@ -#include <Models/DoubleModelBox.h> - -#include <common/AlgorithmHelper.h> - -#include <AlibExceptionHandler.h> - -DoubleModelBox::DoubleModelBox(std::string func) -{ - m_func = func; -} - -bool DoubleModelBox::addInput(ModelBox *origin) -{ - if( m_InConnectionOne && m_InConnectionTwo ) - return false; - if( m_InConnectionOne == nullptr ) - { - m_InConnectionOne = origin; - return true; - } - else - { - m_InConnectionTwo = origin; - return true; - } -} - -bool DoubleModelBox::addOutput(ModelBox *target) -{ - if( m_OutConnection ) - return false; - else - m_OutConnection = target; - return true; -} - -void DoubleModelBox::removeInput(ModelBox *origin) -{ - if( m_InConnectionOne == origin ) - m_InConnectionOne = nullptr; - if ( m_InConnectionTwo == origin ) - m_InConnectionTwo = nullptr; -} - -bool DoubleModelBox::isInputAvailable() -{ - return (m_InConnectionOne == nullptr || m_InConnectionTwo == nullptr ); -} - -std::shared_ptr < abstraction::OperationAbstraction > DoubleModelBox::run() -{ - std::shared_ptr < abstraction::OperationAbstraction > inOne = nullptr; - std::shared_ptr < abstraction::OperationAbstraction > inTwo = nullptr; - std::shared_ptr < abstraction::OperationAbstraction > res = nullptr; - if( m_InConnectionOne && m_InConnectionTwo ) - { - inOne = m_InConnectionOne->run(); - inTwo = m_InConnectionTwo->run(); - } - if( inOne && inTwo ) - { - try - { - ext::vector < std::shared_ptr < abstraction::OperationAbstraction > > params; - params.push_back ( inOne ); - params.push_back ( inTwo ); - - std::vector < bool > moves; - moves.push_back ( true ); - moves.push_back ( true ); - - res = abstraction::AlgorithmHelper::eval( m_func, {}, params, moves, abstraction::AlgorithmCategories::AlgorithmCategory::DEFAULT ); - } - catch (const exception::CommonException& e) - { - QString mes = QString::fromStdString( e.getCause() ); - AlibExceptionHandler::getInstance().setMessage( mes ); - res = nullptr; - } - } - return res; -} diff --git a/agui2/Models/DoubleModelBox.h b/agui2/Models/DoubleModelBox.h deleted file mode 100644 index fc3990aa2f..0000000000 --- a/agui2/Models/DoubleModelBox.h +++ /dev/null @@ -1,25 +0,0 @@ -#pragma once -#include <Models/ModelBox.h> - -class DoubleModelBox : public ModelBox -{ -public: - DoubleModelBox(std::string func); - // Inherited - virtual bool addInput( ModelBox * origin ); - virtual bool addOutput( ModelBox * target ); - virtual void removeInput( ModelBox * origin ); - virtual void removeOutput() { m_OutConnection = nullptr; } - virtual bool isInputAvailable(); - virtual bool isOutputAvailable() { return m_OutConnection == nullptr; } - virtual bool acceptInput() { return true; } - virtual bool isOutputSet() { return m_OutConnection != nullptr; } - virtual std::shared_ptr < abstraction::OperationAbstraction > run(); -private: - ModelBox * m_OutConnection = nullptr; - ModelBox * m_InConnectionOne = nullptr; - ModelBox * m_InConnectionTwo = nullptr; - std::string m_func; -}; - - diff --git a/agui2/Models/InputModelBox.cpp b/agui2/Models/InputModelBox.cpp index 735a353189..52c16b8d52 100644 --- a/agui2/Models/InputModelBox.cpp +++ b/agui2/Models/InputModelBox.cpp @@ -1,36 +1,9 @@ #include <Models/InputModelBox.h> -void InputModelBox::setAutomaton(std::shared_ptr < abstraction::OperationAbstraction > automaton) -{ - m_automaton = automaton; -} - -const std::shared_ptr < abstraction::OperationAbstraction > InputModelBox::getAutomaton() -{ - return m_automaton; -} - -bool InputModelBox::addOutput(ModelBox *target) -{ - if( m_OutConnection ) - return false; - else - m_OutConnection = target; - return true; -} +InputModelBox::InputModelBox() + : ModelBox(ModelType::Input, 0) +{} -std::shared_ptr < abstraction::OperationAbstraction > InputModelBox::run() -{ - return m_automaton; +std::shared_ptr<abstraction::OperationAbstraction> InputModelBox::run() { + return this->automaton; } - -void InputModelBox::setSettings(const InputSettings &settings) -{ - m_settings = settings; -} - -InputSettings InputModelBox::getSettings() -{ - return m_settings; -} - diff --git a/agui2/Models/InputModelBox.h b/agui2/Models/InputModelBox.h index c215b5fb3f..ab3e650f63 100644 --- a/agui2/Models/InputModelBox.h +++ b/agui2/Models/InputModelBox.h @@ -1,32 +1,22 @@ #pragma once #include <Models/ModelBox.h> -#include <Models/InputSettings.h> +#include <utility> -class InputModelBox : public ModelBox -{ +class InputModelBox : public ModelBox { public: - InputModelBox() = default; - void setAutomaton( std::shared_ptr < abstraction::OperationAbstraction > automaton ); - const std::shared_ptr < abstraction::OperationAbstraction > getAutomaton(); + explicit InputModelBox(); + + std::shared_ptr<abstraction::OperationAbstraction> run() override; + + const InputSettings& getSettings() const { return this->settings; } + void setSettings(const InputSettings& settings) { this->settings = settings; } + + const std::shared_ptr<abstraction::OperationAbstraction> getAutomaton() const { return this->automaton; } + void setAutomaton(std::shared_ptr<abstraction::OperationAbstraction> automaton) { this->automaton = std::move(automaton); } - // Inherited - virtual ~InputModelBox() {} - virtual bool addInput( ModelBox * origin __attribute__((unused)) ) { return false; } - virtual bool addOutput( ModelBox * target ); - virtual void removeInput( ModelBox * origin __attribute__((unused)) ){} - virtual void removeOutput() { m_OutConnection = nullptr; } - virtual bool isInputAvailable() { return false; } - virtual bool isOutputAvailable() { return m_OutConnection == nullptr; } - virtual bool acceptInput() { return false; } - virtual bool isOutputSet() { return m_OutConnection != nullptr; } - virtual std::shared_ptr < abstraction::OperationAbstraction > run(); - bool isInputEmpty() { return m_automaton == nullptr; } - void setSettings( const InputSettings & settings ); - InputSettings getSettings(); private: - ModelBox * m_OutConnection = nullptr; - std::shared_ptr < abstraction::OperationAbstraction > m_automaton = nullptr; - InputSettings m_settings; + InputSettings settings; + std::shared_ptr<abstraction::OperationAbstraction> automaton; }; diff --git a/agui2/Models/ModelBox.cpp b/agui2/Models/ModelBox.cpp index c62c7205f4..164e00cdd5 100644 --- a/agui2/Models/ModelBox.cpp +++ b/agui2/Models/ModelBox.cpp @@ -1,6 +1,32 @@ #include <Models/ModelBox.h> -void ModelBox::setWrapper(WrapperBox* wrapper) +#include <utility> + +#include <qplatformdefs.h> +#include <common/AlgorithmHelper.h> +#include <exception/CommonException.h> +#include <QtCore/QString> +#include <AlibExceptionHandler.h> + +ModelBox::ModelBox(ModelType type, uint8_t maxInputCount) + : type(type) + , maxInputCount(maxInputCount) { - m_wrapper = wrapper; + // Input box cannot have inputs, other boxes must have inputs + Q_ASSERT((this->type == ModelType::Input) == (this->maxInputCount == 0)); +} + +void ModelBox::setInput(uint8_t slot, ModelBox* model) { + Q_ASSERT(slot < this->maxInputCount); + this->inputs[slot] = model; } + +void ModelBox::addOutput(ModelBox* model, uint8_t slot) { + Q_ASSERT(this->canHaveOutput()); + this->outputs.emplace(model, slot); +} + +void ModelBox::removeOutput(ModelBox* model, uint8_t slot) { + Q_ASSERT(this->canHaveOutput()); + this->outputs.erase({model, slot}); +} \ No newline at end of file diff --git a/agui2/Models/ModelBox.h b/agui2/Models/ModelBox.h index a3c3146948..cc26ce4973 100644 --- a/agui2/Models/ModelBox.h +++ b/agui2/Models/ModelBox.h @@ -1,32 +1,49 @@ #pragma once -#include <memory> - -#include <QString> -#include <QList> +#include <map> +#include <set> +#include <string> +#include <utility> #include <abstraction/OperationAbstraction.hpp> -#include <exception/CommonException.h> -class WrapperBox; +#include <Models/OutputSettings.h> +#include <Models/InputSettings.h> + +class GraphicsBox; + +enum class ModelType { + Input, + Output, + Algorithm +}; + +class ModelBox { +protected: + explicit ModelBox(ModelType type, uint8_t maxInputCount); -class ModelBox -{ public: virtual ~ModelBox() = default; - virtual bool addInput( ModelBox * origin ) = 0; - virtual bool addOutput( ModelBox * target ) = 0; - virtual void removeInput( ModelBox * origin ) = 0; - virtual void removeOutput() = 0; - virtual bool isInputAvailable() = 0; - virtual bool isOutputAvailable() = 0; - virtual bool acceptInput() = 0; - virtual bool isOutputSet() = 0; - virtual std::shared_ptr < abstraction::OperationAbstraction > run() = 0; - friend class WrapperBox; + + void setGraphicsBox(GraphicsBox* graphicsBox) { this->graphicsBox = graphicsBox; } + ModelType getType() const { return this->type; } + + void setInput(uint8_t slot, ModelBox* model); + void addOutput(ModelBox* model, uint8_t slot); + void removeOutput(ModelBox* model, uint8_t slot); + + uint8_t getMaxInputCount() const { return this->maxInputCount; } + virtual bool canHaveOutput() const { return true; } + + virtual std::shared_ptr<abstraction::OperationAbstraction> run() = 0; + protected: - WrapperBox* m_wrapper = nullptr; -private: - void setWrapper( WrapperBox* wrapper ); + ModelType type; + + uint8_t maxInputCount = 0; + std::map<uint8_t, ModelBox*> inputs; + std::set<std::pair<ModelBox*, uint8_t>> outputs; + + GraphicsBox* graphicsBox = nullptr; }; diff --git a/agui2/Models/OutputModelBox.cpp b/agui2/Models/OutputModelBox.cpp index bf0988abaf..80da8e0b2e 100644 --- a/agui2/Models/OutputModelBox.cpp +++ b/agui2/Models/OutputModelBox.cpp @@ -1,190 +1,11 @@ #include <Models/OutputModelBox.h> -#include <QGraphicsScene> -#include <QGraphicsView> -#include <QMessageBox> -#include <QTextStream> - -#include <AlibExceptionHandler.h> -#include <Converter.h> -#include <Graphics/Dialogs/ResultDialog.h> -#include <WrapperBox.h> - -class ModelBox; - -std::shared_ptr < abstraction::OperationAbstraction > OutputModelBox::run() -{ - std::shared_ptr < abstraction::OperationAbstraction > res = nullptr; - AlibExceptionHandler::getInstance().reset(); - - if( m_InConnection ) - res = m_InConnection->run(); - if( res ) - { - switch (m_Settings.m_destination) { - case OutputSettings::RESULT_DIALOG: - displayResult( res ); - break; - case OutputSettings::FILE: - saveResultToFile( res ); - break; - default: - break; - } - } - else - { - if( AlibExceptionHandler::getInstance().isActive() ) - displayError( AlibExceptionHandler::getInstance().getMessage() ); - else - displayError( "Missing an input" ); - } - return nullptr; -} - -void OutputModelBox::setSettings(const OutputSettings & settings) -{ - m_Settings = settings; -} - -OutputSettings OutputModelBox::getSettings() -{ - return m_Settings; -} - -void OutputModelBox::displayError(const QString &text) -{ - QMessageBox::warning( m_wrapper->getGraphics()->scene()->views().first(), "Output fail", text, QMessageBox::Ok ); -} - -void OutputModelBox::displayResult(std::shared_ptr < abstraction::OperationAbstraction > automaton) -{ - switch (m_Settings.m_format) - { - case OutputSettings::XML: - displayXML( automaton ); - break; - case OutputSettings::TXT: - displayTXT( automaton ); - break; - case OutputSettings::PNG: - displayPNG( automaton ); - break; - case OutputSettings::SVG: - displaySVG( automaton ); - break; - default: - break; - } -} - -void OutputModelBox::displayXML( std::shared_ptr < abstraction::OperationAbstraction > automaton ) -{ - ResultDialog * resultDlg = new ResultDialog(); - resultDlg->setTextContent( Converter::automatonToXML( automaton) ); - resultDlg->exec(); -} - -void OutputModelBox::displayTXT(std::shared_ptr < abstraction::OperationAbstraction > automaton) -{ - QString text( Converter::automatonToTXT( automaton) ); - ResultDialog * resultDlg = new ResultDialog(); - resultDlg->setTextContent( text ); - resultDlg->exec(); -} - -void OutputModelBox::displayPNG(std::shared_ptr < abstraction::OperationAbstraction > automaton) -{ - displayImage( automaton, GraphvizIntegrator::PNG ); -} - -void OutputModelBox::displaySVG(std::shared_ptr < abstraction::OperationAbstraction > automaton) -{ - displayImage( automaton, GraphvizIntegrator::SVG ); -} - -void OutputModelBox::displayImage(std::shared_ptr < abstraction::OperationAbstraction > automaton, GraphvizIntegrator::PictureFormat format) -{ - ResultDialog * resultDlg = new ResultDialog(); - QImage img; - try - { - switch (format) - { - case GraphvizIntegrator::PNG: - img = Converter::automatonToPNG(automaton); - break; - case GraphvizIntegrator::SVG: - img = Converter::automatonToSVG(automaton); - break; - default: - break; - } - } catch (exception::CommonException e ) { - displayError( QString::fromStdString(e.getCause()) ); - } - - if( img.isNull() ) - resultDlg->setTextContent( "<span style=\" font-size:16pt; font-weight:600;\">Graphviz failed</span><b/>"); - else - resultDlg->setImageContent( img ); - resultDlg->exec(); -} - -void OutputModelBox::saveResultToFile(std::shared_ptr < abstraction::OperationAbstraction > automaton) -{ - switch (m_Settings.m_format) - { - case OutputSettings::XML: - saveXMLToFile( automaton ); - break; - case OutputSettings::TXT: - saveTXTToFile( automaton ); - break; - case OutputSettings::PNG: - savePNGToFile( automaton ); - break; - case OutputSettings::SVG: - saveSVGToFile( automaton ); - break; - default: - break; - } -} - -void OutputModelBox::saveXMLToFile(std::shared_ptr < abstraction::OperationAbstraction > automaton) -{ - QFile file(m_Settings.m_filename); - file.open(QFile::ReadWrite | QFile::Text); - QTextStream s1(&file); - s1 << Converter::automatonToXML(automaton) << endl; - file.close(); -} - -void OutputModelBox::saveTXTToFile(std::shared_ptr < abstraction::OperationAbstraction > automaton) -{ - QFile file(m_Settings.m_filename); - file.open(QFile::ReadWrite | QFile::Text); - QTextStream s1(&file); - s1 << Converter::automatonToTXT(automaton); - file.close(); -} - -void OutputModelBox::savePNGToFile(std::shared_ptr < abstraction::OperationAbstraction > automaton) -{ - GraphvizIntegrator::createImageFile(Converter::automatonToDOT(automaton), m_Settings.m_filename, GraphvizIntegrator::PNG); -} - -void OutputModelBox::saveSVGToFile(std::shared_ptr < abstraction::OperationAbstraction > automaton) -{ - GraphvizIntegrator::createImageFile(Converter::automatonToDOT(automaton), m_Settings.m_filename, GraphvizIntegrator::SVG); -} - -bool OutputModelBox::addInput(ModelBox *origin) -{ - if( m_InConnection ) - return false; - else - m_InConnection = origin; - return true; +OutputModelBox::OutputModelBox() + : ModelBox(ModelType::Output, 1) +{} + +std::shared_ptr<abstraction::OperationAbstraction> OutputModelBox::run() { + if (!this->inputs[0]) + return nullptr; + return inputs[0]->run(); } diff --git a/agui2/Models/OutputModelBox.h b/agui2/Models/OutputModelBox.h index 2f765afb57..656a063e96 100644 --- a/agui2/Models/OutputModelBox.h +++ b/agui2/Models/OutputModelBox.h @@ -1,40 +1,16 @@ #pragma once -#include <GraphvizIntegrator.h> #include <Models/ModelBox.h> -#include <Models/OutputSettings.h> -class OutputModelBox : public ModelBox -{ +class OutputModelBox : public ModelBox { public: - OutputModelBox() = default; - // Inherited - virtual bool addInput( ModelBox * origin ); - virtual bool addOutput( ModelBox * target __attribute__((unused)) ) { return false; } - virtual void removeInput( ModelBox * origin __attribute__((unused)) ) { m_InConnection = nullptr; } - virtual void removeOutput() {} - virtual bool isInputAvailable() { return m_InConnection == nullptr; } - virtual bool isOutputAvailable() { return false; } - virtual bool acceptInput() { return true; } - virtual bool isOutputSet() { return false; } - virtual std::shared_ptr < abstraction::OperationAbstraction > run(); - void setSettings(const OutputSettings &settings ); - OutputSettings getSettings(); -private: - void displayError(const QString & text); - void displayResult(std::shared_ptr < abstraction::OperationAbstraction > automaton); - void displayXML(std::shared_ptr < abstraction::OperationAbstraction > automaton); - void displayTXT(std::shared_ptr < abstraction::OperationAbstraction > automaton); - void displayPNG(std::shared_ptr < abstraction::OperationAbstraction > automaton); - void displaySVG(std::shared_ptr < abstraction::OperationAbstraction > automaton); - void displayImage(std::shared_ptr < abstraction::OperationAbstraction > automaton, GraphvizIntegrator::PictureFormat format); - void saveResultToFile(std::shared_ptr < abstraction::OperationAbstraction > automaton); - void saveXMLToFile(std::shared_ptr < abstraction::OperationAbstraction > automaton); - void saveTXTToFile(std::shared_ptr < abstraction::OperationAbstraction > automaton); - void savePNGToFile(std::shared_ptr < abstraction::OperationAbstraction > automaton); - void saveSVGToFile(std::shared_ptr < abstraction::OperationAbstraction > automaton); + explicit OutputModelBox(); + + bool canHaveOutput() const override { return false; } - ModelBox * m_InConnection = nullptr; - OutputSettings m_Settings; + std::shared_ptr<abstraction::OperationAbstraction> run() override; + +private: + OutputSettings settings; }; diff --git a/agui2/Models/SingleModelBox.cpp b/agui2/Models/SingleModelBox.cpp deleted file mode 100644 index ff8d71073c..0000000000 --- a/agui2/Models/SingleModelBox.cpp +++ /dev/null @@ -1,52 +0,0 @@ -#include <Models/SingleModelBox.h> - -#include <common/AlgorithmHelper.h> - -#include <AlibExceptionHandler.h> - -SingleModelBox::SingleModelBox( std::string func ) -{ - m_func = func; -} - -bool SingleModelBox::addInput(ModelBox *origin) -{ - if( m_InConnection ) - return false; - else - m_InConnection = origin; - return true; -} - -bool SingleModelBox::addOutput(ModelBox *target) -{ - if( m_OutConnection ) - return false; - else - m_OutConnection = target; - return true; -} - -std::shared_ptr < abstraction::OperationAbstraction > SingleModelBox::run() -{ - std::shared_ptr < abstraction::OperationAbstraction > res = nullptr; - if( m_InConnection ) - res = m_InConnection->run(); - if( res ) - { - try{ - ext::vector < std::shared_ptr < abstraction::OperationAbstraction > > params; - params.push_back ( res ); - - std::vector < bool > moves; - moves.push_back ( true ); - - res = abstraction::AlgorithmHelper::eval ( m_func, {}, params, moves, abstraction::AlgorithmCategories::AlgorithmCategory::DEFAULT ); - } catch (exception::CommonException e) { - QString mes = QString::fromStdString( e.getCause() ); - AlibExceptionHandler::getInstance().setMessage( mes ); - res = nullptr; - } - } - return res; -} diff --git a/agui2/Models/SingleModelBox.h b/agui2/Models/SingleModelBox.h deleted file mode 100644 index f4e3728d48..0000000000 --- a/agui2/Models/SingleModelBox.h +++ /dev/null @@ -1,25 +0,0 @@ -#pragma once -#include <Models/ModelBox.h> - -class SingleModelBox : public ModelBox -{ -public: - SingleModelBox(std::string); - // Inherited - virtual ~SingleModelBox() {} - virtual bool addInput( ModelBox * origin ); - virtual bool addOutput( ModelBox * target ); - virtual void removeInput( ModelBox * origin __attribute__((unused)) ) { m_InConnection = nullptr; } - virtual void removeOutput() { m_OutConnection = nullptr; } - virtual bool isInputAvailable() { return m_InConnection == nullptr; } - virtual bool isOutputAvailable() { return m_OutConnection == nullptr; } - virtual bool acceptInput() { return true; } - virtual bool isOutputSet() { return m_OutConnection != nullptr; } - virtual std::shared_ptr < abstraction::OperationAbstraction > run(); -private: - ModelBox * m_InConnection = nullptr; - ModelBox * m_OutConnection = nullptr; - std::string m_func; -}; - - diff --git a/agui2/WrapperBox.cpp b/agui2/WrapperBox.cpp deleted file mode 100644 index fe34203052..0000000000 --- a/agui2/WrapperBox.cpp +++ /dev/null @@ -1,72 +0,0 @@ -#include <WrapperBox.h> - -WrapperBox::WrapperBox( ModelBox * model, GraphicsBox * graphics ) : - m_model( model ), m_graphics( graphics ) -{ - model->setWrapper( this ); - graphics->setWrapper( this ); -} - -WrapperBox::~WrapperBox() -{ - delete m_graphics; - delete m_model; -} - -bool WrapperBox::addInput(WrapperBox *origin, GraphicsConnection *connection) -{ - if( !m_model->addInput( origin->getModel() ) ) - return false; - m_graphics->addInput( connection ); - return true; -} - -bool WrapperBox::addOutput(WrapperBox *target, GraphicsConnection *connection) -{ - if( !m_model->addOutput( target->getModel() )) - return false; - m_graphics->addOutput( connection ); - return true; -} - -void WrapperBox::removeInput(WrapperBox *origin, GraphicsConnection *connection) -{ - m_model->removeInput( origin->getModel() ); - m_graphics->removeInput( connection ); -} - -void WrapperBox::removeOutput() -{ - m_model->removeOutput(); - m_graphics->removeOutput(); -} - -void WrapperBox::disconnectOutput() -{ - if( m_model->isOutputSet() ) - m_graphics->m_OutConnection->on_Disconnect(); -} - -void WrapperBox::getAvailableInput() -{ - if( !m_model->isInputAvailable() ) - m_graphics->inConnections[0]->on_Disconnect(); -} - -ModelBox *WrapperBox::getModel() -{ - return m_model; -} - -GraphicsBox *WrapperBox::getGraphics() -{ - return m_graphics; -} - - - - - - - - diff --git a/agui2/WrapperBox.h b/agui2/WrapperBox.h deleted file mode 100644 index f57caf6f55..0000000000 --- a/agui2/WrapperBox.h +++ /dev/null @@ -1,27 +0,0 @@ -#pragma once -#include <Models/ModelBox.h> -#include <Graphics/GraphicsConnection.h> -#include <Graphics/GraphicsBox.h> - -class ModelBox; -class GraphicsBox; -class GraphicsConnection; - -class WrapperBox -{ -public: - WrapperBox(ModelBox *model, GraphicsBox *graphics); - ~WrapperBox(); - bool addInput( WrapperBox * origin, GraphicsConnection * connection ); - bool addOutput( WrapperBox * target, GraphicsConnection * connection ); - void removeInput( WrapperBox * origin, GraphicsConnection * connection ); - void removeOutput(); - void disconnectOutput(); - void getAvailableInput(); - ModelBox *getModel(); - GraphicsBox *getGraphics(); -private: - ModelBox *m_model; - GraphicsBox *m_graphics; -}; - diff --git a/agui2/WrapperFactory.cpp b/agui2/WrapperFactory.cpp index 6c2d6e8fdb..20d03e1e2c 100644 --- a/agui2/WrapperFactory.cpp +++ b/agui2/WrapperFactory.cpp @@ -4,70 +4,73 @@ #include <QString> #include <Graphics/InputGraphicsBox.h> -#include <Graphics/OutputGraphicsBox.h> -#include <Models/DoubleModelBox.h> #include <Models/InputModelBox.h> #include <Models/OutputModelBox.h> -#include <Models/SingleModelBox.h> -WrapperBox *WrapperFactory::create(WrapperFactory::Algorithms algorithm, qreal x = 0, qreal y = 0) +#include <Models/AlgorithmModelBox.h> +#include <Models/InputModelBox.h> +#include <Models/OutputModelBox.h> +#include <Graphics/GraphicsBox.h> +#include <Graphics/InputGraphicsBox.h> + +GraphicsBox* WrapperFactory::createNew(WrapperFactory::Algorithms algorithm, qreal x = 0, qreal y = 0) { - QString str( QChar(0xb5, 0x03) ); + QString eps (QChar(0xb5, 0x03)); switch( algorithm ) { - // Special - case INPUT: - return new WrapperBox( new InputModelBox(), new InputGraphicsBox( x, y ) ); - case OUTPUT: - return new WrapperBox( new OutputModelBox(), new OutputGraphicsBox( x, y ) ); + // Special + case INPUT: + return new InputGraphicsBox(std::make_unique<InputModelBox>(), "INPUT", {x, y}); + case OUTPUT: + return new GraphicsBox(std::make_unique<OutputModelBox>(), "OUTPUT", {x, y}); - // Single simplify - case DETERMINIZE: - return new WrapperBox( new SingleModelBox( "automaton::determinize::Determinize" ), new GraphicsBox( "Determinize", x, y ) ); - case TOTAL: - return new WrapperBox( new SingleModelBox( "automaton::simplify::Total" ), new GraphicsBox( "Total", x, y ) ); - case MINIMIZE: - return new WrapperBox( new SingleModelBox( "automaton::simplify::Minimize" ), new GraphicsBox( "Minimize", x, y ) ); - case NORMALIZE: - return new WrapperBox( new SingleModelBox( "automaton::simplify::Normalize" ), new GraphicsBox( "Normalize", x, y ) ); - case SINGLE_INITIAL: - return new WrapperBox( new SingleModelBox( "automaton::simplify::SingleInitialState" ), new GraphicsBox( "Single Initial", x, y ) ); - case EPSILON_REMOVE_IN: - return new WrapperBox( new SingleModelBox( "automaton::simplify::EpsilonRemoverIncoming" ), new GraphicsBox( str.append( "-Remove In" ), x, y ) ); - case EPSILON_REMOVE_OUT: - return new WrapperBox( new SingleModelBox( "automaton::simplify::EpsilonRemoverOutgoing" ), new GraphicsBox( str.append( "-Remove Out" ), x, y ) ); - case RENAME: - return new WrapperBox( new SingleModelBox( "automaton::simplify::Rename" ), new GraphicsBox( "Rename", x, y ) ); - case TRIM: - return new WrapperBox( new SingleModelBox( "automaton::simplify::Trim" ), new GraphicsBox( "Trim", x, y ) ); - case REMOVE_USELES: - return new WrapperBox( new SingleModelBox( "automaton::simplify::UselessStatesRemover" ), new GraphicsBox( "Remove Useless", x, y ) ); - case REMOVE_UNREACHABLE: - return new WrapperBox( new SingleModelBox( "automaton::simplify::UnreachableStatesRemover" ), new GraphicsBox( "Remove Unreachable", x, y ) ); + // Single simplify + case DETERMINIZE: + return new GraphicsBox(std::make_unique<AlgorithmModelBox>("automaton::determinize::Determinize"), "Determinize", {x, y}); + case TOTAL: + return new GraphicsBox(std::make_unique<AlgorithmModelBox>("automaton::simplify::Total"), "Total", {x, y}); + case MINIMIZE: + return new GraphicsBox(std::make_unique<AlgorithmModelBox>("automaton::simplify::Minimize"), "Minimize", {x, y}); + case NORMALIZE: + return new GraphicsBox(std::make_unique<AlgorithmModelBox>("automaton::simplify::Normalize"), "Normalize", {x, y}); + case SINGLE_INITIAL: + return new GraphicsBox(std::make_unique<AlgorithmModelBox>("automaton::simplify::SingleInitialState"), "Single Initial", {x, y}); + case EPSILON_REMOVE_IN: + return new GraphicsBox(std::make_unique<AlgorithmModelBox>("automaton::simplify::EpsilonRemoverIncoming"), eps.append("-Remove In"), {x, y}); + case EPSILON_REMOVE_OUT: + return new GraphicsBox(std::make_unique<AlgorithmModelBox>("automaton::simplify::EpsilonRemoverOutgoing"), eps.append("-Remove Out"), {x, y}); + case RENAME: + return new GraphicsBox(std::make_unique<AlgorithmModelBox>("automaton::simplify::Rename"), "Rename", {x, y}); + case TRIM: + return new GraphicsBox(std::make_unique<AlgorithmModelBox>("automaton::simplify::Trim"), "Trim", {x, y}); + case REMOVE_USELES: + return new GraphicsBox(std::make_unique<AlgorithmModelBox>("automaton::simplify::UselessStatesRemover"), "Remove Useless", {x, y}); + case REMOVE_UNREACHABLE: + return new GraphicsBox(std::make_unique<AlgorithmModelBox>("automaton::simplify::UnreachableStatesRemover"), "Remove Unreachable", {x, y}); - // Single transform - case COMPACT: - return new WrapperBox( new SingleModelBox( "automaton::transform::Compaction" ), new GraphicsBox( "Compact", x, y ) ); - case REVERSE: - return new WrapperBox( new SingleModelBox( "automaton::transform::Reverse" ), new GraphicsBox( "Reverse", x, y ) ); - case ITERATE: - return new WrapperBox( new SingleModelBox( "automaton::transform::AutomatonIteration" ), new GraphicsBox( "Iterate", x, y ) ); - case ITERATE_EPSILON: - return new WrapperBox( new SingleModelBox( "automaton::transform::AutomatonIterationEpsilonTransition" ), new GraphicsBox( str.append( "-Iterate" ), x, y ) ); + // Single transform + case COMPACT: + return new GraphicsBox(std::make_unique<AlgorithmModelBox>("automaton::transform::Compaction"), "Compact", {x, y}); + case REVERSE: + return new GraphicsBox(std::make_unique<AlgorithmModelBox>("automaton::transform::Reverse"), "Reverse", {x, y}); + case ITERATE: + return new GraphicsBox(std::make_unique<AlgorithmModelBox>("automaton::transform::AutomatonIteration"), "Iterate", {x, y}); + case ITERATE_EPSILON: + return new GraphicsBox(std::make_unique<AlgorithmModelBox>("automaton::transform::AutomatonIterationEpsilonTransition"), eps.append("-Iterate"), {x, y}); - //Double - case CONCATENATE: - return new WrapperBox( new DoubleModelBox( "automaton::transform::AutomataConcatenation" ), new GraphicsBox( "Concatenate", x, y, 2 ) ); - case CONCATENATE_EPSILON: - return new WrapperBox( new DoubleModelBox( "automaton::transform::AutomataConcatenationEpsilonTransition" ), new GraphicsBox( str.append( "-Concatenate" ), x, y, 2 ) ); - case UNION: - return new WrapperBox( new DoubleModelBox( "automaton::transform::AutomataUnionCartesianProduct" ), new GraphicsBox( "Union", x, y, 2 ) ); - case UNION_EPSILON: - return new WrapperBox( new DoubleModelBox( "automaton::transform::AutomataUnionEpsilonTransition" ), new GraphicsBox( str.append( "-Union" ), x, y, 2 ) ); - case INTERSECT: - return new WrapperBox( new DoubleModelBox( "automaton::transform::AutomataIntersectionCartesianProduct" ), new GraphicsBox( "Intersect", x, y, 2 ) ); - default: - return nullptr; + //Double + case CONCATENATE: + return new GraphicsBox(std::make_unique<AlgorithmModelBox>("automaton::transform::AutomataConcatenation"), "Concatenate", {x, y}); + case CONCATENATE_EPSILON: + return new GraphicsBox(std::make_unique<AlgorithmModelBox>("automaton::transform::AutomataConcatenationEpsilonTransition"), eps.append("-Concatenate"), {x, y}); + case UNION: + return new GraphicsBox(std::make_unique<AlgorithmModelBox>("automaton::transform::AutomataUnionCartesianProduct"), "Union", {x, y}); + case UNION_EPSILON: + return new GraphicsBox(std::make_unique<AlgorithmModelBox>("automaton::transform::AutomataUnionEpsilonTransition"), eps.append("-Union"), {x, y}); + case INTERSECT: + return new GraphicsBox(std::make_unique<AlgorithmModelBox>("automaton::transform::AutomataIntersectionCartesianProduct"), "Intersect", {x, y}); + default: + return nullptr; } } diff --git a/agui2/WrapperFactory.h b/agui2/WrapperFactory.h index d11e105934..202f215d94 100644 --- a/agui2/WrapperFactory.h +++ b/agui2/WrapperFactory.h @@ -1,7 +1,8 @@ #pragma once -#include <WrapperBox.h> -class WrapperBox; +#include <QRectF> + +class GraphicsBox; class WrapperFactory { @@ -31,7 +32,7 @@ public: ITERATE, ITERATE_EPSILON }; - static WrapperBox* create( WrapperFactory::Algorithms algorithm, qreal x, qreal y ); + static GraphicsBox* createNew( WrapperFactory::Algorithms algorithm, qreal x, qreal y ); }; -- GitLab