From a3288c9a7275ec62cf394a01068cad1f728dadb3 Mon Sep 17 00:00:00 2001
From: Vaclav Mares <maresva2@fit.cvut.cz>
Date: Thu, 13 Apr 2017 13:55:09 +0200
Subject: [PATCH] Add DoubleGraphicsBox

- fixing graphics connection
---
 agui2/ALIB.pro                        |  6 ++-
 agui2/graphics/doublegraphicsbox.cpp  | 57 +++++++++++++++++++++++++++
 agui2/graphics/doublegraphicsbox.h    | 21 ++++++++++
 agui2/graphics/graphicsbox.cpp        |  2 +-
 agui2/graphics/graphicsbox.h          | 10 ++---
 agui2/graphics/graphicsconnection.cpp | 22 ++++++++---
 agui2/graphics/graphicsconnection.h   |  2 +
 agui2/mainwindow.cpp                  |  4 ++
 agui2/models/doublemodelbox.cpp       |  9 +++--
 agui2/models/doublemodelbox.h         |  6 +--
 agui2/wrapperfactory.cpp              |  5 +++
 agui2/wrapperfactory.h                |  1 +
 12 files changed, 124 insertions(+), 21 deletions(-)
 create mode 100644 agui2/graphics/doublegraphicsbox.cpp
 create mode 100644 agui2/graphics/doublegraphicsbox.h

diff --git a/agui2/ALIB.pro b/agui2/ALIB.pro
index fc4ec119e0..dc01b9c07a 100644
--- a/agui2/ALIB.pro
+++ b/agui2/ALIB.pro
@@ -46,7 +46,8 @@ SOURCES += main.cpp\
     models/inputmodelbox.cpp \
     models/outputmodelbox.cpp \
     models/singlemodelbox.cpp \
-    models/doublemodelbox.cpp
+    models/doublemodelbox.cpp \
+    graphics/doublegraphicsbox.cpp
 
 HEADERS  += mainwindow.h \
     connectionhelper.h \
@@ -65,7 +66,8 @@ HEADERS  += mainwindow.h \
     models/inputmodelbox.h \
     models/outputmodelbox.h \
     models/singlemodelbox.h \
-    models/doublemodelbox.h
+    models/doublemodelbox.h \
+    graphics/doublegraphicsbox.h
 
 FORMS    += mainwindow.ui \
     inputdialog.ui \
diff --git a/agui2/graphics/doublegraphicsbox.cpp b/agui2/graphics/doublegraphicsbox.cpp
new file mode 100644
index 0000000000..8ac1291262
--- /dev/null
+++ b/agui2/graphics/doublegraphicsbox.cpp
@@ -0,0 +1,57 @@
+#include "doublegraphicsbox.h"
+
+#include <iostream>
+#include <QGraphicsScene>
+
+DoubleGraphicsBox::~DoubleGraphicsBox()
+{
+    delete m_InConnectionTwo;
+}
+
+void DoubleGraphicsBox::addInput(GraphicsConnection *connection)
+{
+    if( m_InConnection == NULL )
+        m_InConnection = connection;
+    else
+        m_InConnectionTwo = connection;
+}
+
+void DoubleGraphicsBox::removeInput(GraphicsConnection *connection)
+{
+    if( m_InConnection == connection )
+        m_InConnection = NULL;
+    else if ( m_InConnectionTwo == connection )
+        m_InConnectionTwo = NULL;
+}
+
+QPointF DoubleGraphicsBox::getConnectionTarget(GraphicsConnection *connection)
+{
+    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( m_InConnection && m_InConnectionTwo )
+    {
+        if( m_InConnection == connection )
+        {
+            if( m_InConnection->getOriginPoint().y() < m_InConnectionTwo->getOriginPoint().y() )
+                return topPoint;
+            else
+                return bottomPoint;
+        }
+        else
+        {
+            if( m_InConnection->getOriginPoint().y() < m_InConnectionTwo->getOriginPoint().y() )
+                return bottomPoint;
+            else
+                return topPoint;
+        }
+
+    }
+    else
+    {
+        if( connection->getOriginPoint().y() < m_boundRect.center().y() )
+            return topPoint;
+        else
+            return bottomPoint;
+    }
+}
diff --git a/agui2/graphics/doublegraphicsbox.h b/agui2/graphics/doublegraphicsbox.h
new file mode 100644
index 0000000000..fdc49328ec
--- /dev/null
+++ b/agui2/graphics/doublegraphicsbox.h
@@ -0,0 +1,21 @@
+#ifndef DOUBLEGRAPHICSBOX_H
+#define DOUBLEGRAPHICSBOX_H
+
+#include "graphicsbox.h"
+
+
+class DoubleGraphicsBox : public GraphicsBox
+{
+    Q_OBJECT
+public:
+    DoubleGraphicsBox(QString text, qreal x = 0, qreal y = 0) : GraphicsBox( text, x, y ) {}
+    // Decide which end handles the top or bottom in connecting
+    virtual ~DoubleGraphicsBox();
+    virtual void addInput( GraphicsConnection* connection );
+    virtual void removeInput( GraphicsConnection* connection );
+    virtual QPointF getConnectionTarget( GraphicsConnection* connection );
+private:
+    GraphicsConnection* m_InConnectionTwo = NULL;
+};
+
+#endif // DOUBLEGRAPHICSBOX_H
diff --git a/agui2/graphics/graphicsbox.cpp b/agui2/graphics/graphicsbox.cpp
index 6e8cd070dd..8ae979f0f9 100644
--- a/agui2/graphics/graphicsbox.cpp
+++ b/agui2/graphics/graphicsbox.cpp
@@ -69,7 +69,7 @@ QPointF GraphicsBox::getConnectionOrigin()
     return QPointF(m_boundRect.right(), m_boundRect.center().y());
 }
 
-QPointF GraphicsBox::getConnectionTarget()
+QPointF GraphicsBox::getConnectionTarget(GraphicsConnection *connection)
 {
     return QPointF(m_boundRect.left(), m_boundRect.center().y());
 }
diff --git a/agui2/graphics/graphicsbox.h b/agui2/graphics/graphicsbox.h
index ba7c24c60a..867aee70c1 100644
--- a/agui2/graphics/graphicsbox.h
+++ b/agui2/graphics/graphicsbox.h
@@ -23,19 +23,19 @@ public:
     virtual ~GraphicsBox() {}
     void paint(QPainter *painter, const QStyleOptionGraphicsItem *options, QWidget *widget);
     void addOutput( GraphicsConnection* connection );
-    void addInput( GraphicsConnection* connection );
+    virtual void addInput( GraphicsConnection* connection );
     void removeOutput();
-    void removeInput( GraphicsConnection* connection );
+    virtual void removeInput( GraphicsConnection* connection );
     QRectF boundingRect() const;
     QPointF getConnectionOrigin();
-    QPointF getConnectionTarget();
+    virtual QPointF getConnectionTarget( GraphicsConnection* connection );
     friend class WrapperBox;
 protected:
     QFont m_font;
     QString m_text;
     QRectF m_boundRect;
-    GraphicsConnection* m_OutConnection;
-    GraphicsConnection* m_InConnection;
+    GraphicsConnection* m_OutConnection = NULL;
+    GraphicsConnection* m_InConnection = NULL;
     WrapperBox* m_wrapper;
     void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
     void finishMenu( QMenu * menu );
diff --git a/agui2/graphics/graphicsconnection.cpp b/agui2/graphics/graphicsconnection.cpp
index 936e7d2186..115562db1d 100644
--- a/agui2/graphics/graphicsconnection.cpp
+++ b/agui2/graphics/graphicsconnection.cpp
@@ -19,9 +19,7 @@ GraphicsConnection::GraphicsConnection(WrapperBox * origin, WrapperBox * target)
     origin->addOutput( target, this );
     target->addInput( m_origin, this );
 
-    QPointF originPoint = mapFromItem(m_originGraphics, m_originGraphics->getConnectionOrigin());
-    QPointF targetPoint = mapFromItem(m_targetGraphics, m_targetGraphics->getConnectionTarget());
-    m_boundRect = new QRectF( originPoint, targetPoint );
+    m_boundRect = new QRectF( getOriginPoint(), getTargetPoint() );
 
     m_originGraphics->scene()->addItem(this);
     m_originGraphics->scene()->update();
@@ -40,8 +38,8 @@ QRectF GraphicsConnection::boundingRect() const
 void GraphicsConnection::paint(QPainter *painter, const QStyleOptionGraphicsItem *options, QWidget *widget)
 {
 
-    QPointF originPoint = mapFromItem(m_originGraphics, m_originGraphics->getConnectionOrigin());
-    QPointF targetPoint = mapFromItem(m_targetGraphics, m_targetGraphics->getConnectionTarget());
+    QPointF originPoint = getOriginPoint();
+    QPointF targetPoint = getTargetPoint();
     recalculateBoundingRect( originPoint, targetPoint );
     painter->setPen(QPen(Qt::black,1));
 
@@ -55,7 +53,19 @@ void GraphicsConnection::paint(QPainter *painter, const QStyleOptionGraphicsItem
 
 ////    Debug bounding rectangle
 //    painter->setPen(QPen(Qt::red,1));
-//    painter->drawRect(*m_boundRect);
+    //    painter->drawRect(*m_boundRect);
+}
+
+// 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)
diff --git a/agui2/graphics/graphicsconnection.h b/agui2/graphics/graphicsconnection.h
index 82a3cb1b84..7ce4d35656 100644
--- a/agui2/graphics/graphicsconnection.h
+++ b/agui2/graphics/graphicsconnection.h
@@ -17,6 +17,8 @@ public:
     virtual ~GraphicsConnection();
     QRectF boundingRect() const;
     void paint(QPainter *painter, const QStyleOptionGraphicsItem *options, QWidget *widget);
+    QPointF getOriginPoint();
+    QPointF getTargetPoint();
 protected:
     void mousePressEvent(QGraphicsSceneMouseEvent *event);
     void contextMenuEvent(QGraphicsSceneContextMenuEvent *event);
diff --git a/agui2/mainwindow.cpp b/agui2/mainwindow.cpp
index a831aac920..c4d18a4db4 100644
--- a/agui2/mainwindow.cpp
+++ b/agui2/mainwindow.cpp
@@ -25,8 +25,12 @@ MainWindow::MainWindow(QWidget *parent) :
 
     WrapperBox * inputBox = WrapperFactory::create( WrapperFactory::INPUT, 0, 0 );
     scene->addItem(inputBox->getGraphics());
+    WrapperBox * inputBox2 = WrapperFactory::create( WrapperFactory::INPUT, 0, 50 );
+    scene->addItem(inputBox2->getGraphics());
     WrapperBox * outputBox = WrapperFactory::create( WrapperFactory::OUTPUT, 400, 0 );
     scene->addItem(outputBox->getGraphics());
+    WrapperBox * testBox = WrapperFactory::create( WrapperFactory::TEST, 200, 0 );
+    scene->addItem(testBox->getGraphics());
 
     m_output = outputBox;
 }
diff --git a/agui2/models/doublemodelbox.cpp b/agui2/models/doublemodelbox.cpp
index 7fb10c3e5e..9e0a10f370 100644
--- a/agui2/models/doublemodelbox.cpp
+++ b/agui2/models/doublemodelbox.cpp
@@ -1,6 +1,7 @@
 #include "doublemodelbox.h"
 
-DoubleModelBox::DoubleModelBox(func func)
+
+DoubleModelBox::DoubleModelBox(functwo func)
 {
     m_func = func;
 }
@@ -34,8 +35,8 @@ void DoubleModelBox::removeInput(ModelBox *origin)
 {
     if( m_InConnectionOne == origin )
         m_InConnectionOne = NULL;
-    else if ( m_InConnectionTwo == origin )
-        m_InConnectionTwo == NULL;
+    if ( m_InConnectionTwo == origin )
+        m_InConnectionTwo = NULL;
 }
 
 bool DoubleModelBox::isInputAvailable()
@@ -57,7 +58,7 @@ automaton::Automaton *DoubleModelBox::run()
     {
         try
         {
-            res->setData( m_func( *inOne, *inTwo ).getData() );
+            res = new automaton::Automaton( m_func( *inOne, *inTwo ) );
         }
         catch (exception::CommonException e)
         {
diff --git a/agui2/models/doublemodelbox.h b/agui2/models/doublemodelbox.h
index 4bca3313c7..273fa21e3a 100644
--- a/agui2/models/doublemodelbox.h
+++ b/agui2/models/doublemodelbox.h
@@ -3,12 +3,12 @@
 
 #include "modelbox.h"
 
-typedef automaton::Automaton(*func)(const automaton::Automaton&, const automaton::Automaton&);
+typedef automaton::Automaton(*functwo)(const automaton::Automaton&, const automaton::Automaton&);
 
 class DoubleModelBox : public ModelBox
 {
 public:
-    DoubleModelBox(func func);
+    DoubleModelBox(functwo func);
     // Inherited
     virtual bool addInput( ModelBox * origin );
     virtual bool addOutput( ModelBox * target );
@@ -23,7 +23,7 @@ private:
     ModelBox * m_OutConnection = NULL;
     ModelBox * m_InConnectionOne = NULL;
     ModelBox * m_InConnectionTwo = NULL;
-    func m_func;
+    functwo m_func;
 };
 
 #endif // DOUBLEMODELBOX_H
diff --git a/agui2/wrapperfactory.cpp b/agui2/wrapperfactory.cpp
index 48bcb528c1..1ba31b96b7 100644
--- a/agui2/wrapperfactory.cpp
+++ b/agui2/wrapperfactory.cpp
@@ -2,13 +2,16 @@
 #include "graphics/inputgraphicsbox.h"
 #include "graphics/outputgraphicsbox.h"
 #include "graphics/determinizegraphicsbox.h"
+#include "graphics/doublegraphicsbox.h"
 #include "models/inputmodelbox.h"
 #include "models/outputmodelbox.h"
 #include "models/singlemodelbox.h"
+#include "models/doublemodelbox.h"
 
 #include <automaton/determinize/Determinize.h>
 #include <automaton/simplify/Total.h>
 #include <automaton/transform/Compaction.h>
+#include <automaton/transform/AutomataConcatenationEpsilonTransition.h>
 
 WrapperBox *WrapperFactory::create(WrapperFactory::BoxActions action, qreal x = 0, qreal y = 0)
 {
@@ -24,5 +27,7 @@ WrapperBox *WrapperFactory::create(WrapperFactory::BoxActions action, qreal x =
         return new WrapperBox( new SingleModelBox( &automaton::simplify::Total::total ), new GraphicsBox( "Total", x, y ) );
     case COMPACT:
         return new WrapperBox( new SingleModelBox( &automaton::transform::Compaction::convert ), new GraphicsBox( "Compact", x, y ) );
+    case TEST:
+        return new WrapperBox( new DoubleModelBox( &automaton::transform::AutomataConcatenationEpsilonTransition::concatenation ), new DoubleGraphicsBox( "E-Concat", x, y ) );
     }
 }
diff --git a/agui2/wrapperfactory.h b/agui2/wrapperfactory.h
index 9a0b588791..868959de5c 100644
--- a/agui2/wrapperfactory.h
+++ b/agui2/wrapperfactory.h
@@ -14,6 +14,7 @@ public:
         DETERMINIZE,
         TOTAL,
         COMPACT,
+        TEST,
         OUTPUT
     };
     static WrapperBox* create( WrapperFactory::BoxActions action, qreal x, qreal y );
-- 
GitLab