+#include "QNodesEditorCanvas.h"
+#include "QNodesEditor.h"
+#include "QNEBlock.h"
+#include "QNEConnection.h"
+#include "QNEPort.h"
+
+#include <QDragEnterEvent>
+#include <QWheelEvent>
+#include <QTreeWidget>
+
+// -------------------------------------------------------------------------
+PipelineEditor::QNodesEditorCanvas::
+QNodesEditorCanvas( QWidget* parent )
+ : QGraphicsView( parent ),
+ m_Workspace( NULL )
+{
+ QGraphicsScene* scene = new QGraphicsScene( this );
+ this->setScene( scene );
+ this->setRenderHint( QPainter::Antialiasing );
+ this->setAcceptDrops( true );
+
+ this->m_Editor = new QNodesEditor( this );
+ this->m_Editor->install( scene );
+}
+
+// -------------------------------------------------------------------------
+PipelineEditor::QNodesEditorCanvas::
+~QNodesEditorCanvas( )
+{
+}
+
+// -------------------------------------------------------------------------
+PipelineEditor::QNodesEditorCanvas::
+TWorkspace* PipelineEditor::QNodesEditorCanvas::
+workspace( )
+{
+ return( this->m_Workspace );
+}
+
+// -------------------------------------------------------------------------
+const PipelineEditor::QNodesEditorCanvas::
+TWorkspace* PipelineEditor::QNodesEditorCanvas::
+workspace( ) const
+{
+ return( this->m_Workspace );
+}
+
+// -------------------------------------------------------------------------
+void PipelineEditor::QNodesEditorCanvas::
+setWorkspace( TWorkspace* ws )
+{
+ if( this->m_Workspace == ws )
+ return;
+ this->m_Workspace = ws;
+ QGraphicsScene* scene = this->scene( );
+
+ // Create graph
+ this->m_Graph = TGraph::New( );
+
+ // Add vertices and keep track of ports
+ std::map< std::string, std::map< std::string, QNEPort* > >
+ in_ports, out_ports;
+ auto vIt = this->m_Workspace->GetGraph( )->BeginVertices( );
+ auto vIt_end = this->m_Workspace->GetGraph( )->EndVertices( );
+ for( ; vIt != vIt_end; ++vIt )
+ {
+ this->_createBlock( dynamic_cast< TFilter* >( vIt->second.GetPointer( ) ) );
+#error ACA VOY
+ // Add block
+ QNEBlock* b = new QNEBlock( 0, scene );
+ b->addPort( vIt->second->GetName( ), 0, QNEPort::NamePort );
+ b->addPort( vIt->second->GetClassName( ).c_str( ), 0, QNEPort::TypePort );
+
+ // Get filter
+ if( f == NULL )
+ continue;
+
+ // Add input ports
+ std::set< std::string > inputs;
+ f->GetInputsNames( inputs );
+ for( auto iIt = inputs.begin( ); iIt != inputs.end( ); ++iIt )
+ in_ports[ vIt->first ][ *iIt ] = b->addInputPort( iIt->c_str( ) );
+
+ // Add output ports
+ std::set< std::string > outputs;
+ f->GetOutputsNames( outputs );
+ for( auto oIt = outputs.begin( ); oIt != outputs.end( ); ++oIt )
+ out_ports[ vIt->first ][ *oIt ] = b->addOutputPort( oIt->c_str( ) );
+
+ // Keep a trace of this visual graph
+ this->m_Graph->InsertVertex( vIt->first, b );
+
+ } // rof
+
+ // Add edges
+ /* TODO
+ auto rIt = this->m_Workspace->GetGraph( )->BeginEdgesRows( );
+ auto rIt_end = this->m_Workspace->GetGraph( )->EndEdgesRows( );
+ for( ; rIt != rIt_end; ++rIt )
+ {
+ auto cIt = rIt->second.begin( );
+ for( ; cIt != rIt->second.end( ); ++cIt )
+ {
+ auto eIt = cIt->second.begin( );
+ for( ; eIt != cIt->second.end( ); ++eIt )
+ {
+ QNEPort* p1 = out_ports[ rIt->first ][ eIt->first ];
+ QNEPort* p2 = in_ports[ cIt->first ][ eIt->second ];
+ if( p1 != NULL && p2 != NULL )
+ {
+ QNEConnection* conn = new QNEConnection( 0, scene );
+ conn->setPort1( p1 );
+ conn->setPort2( p2 );
+ this->m_Graph->AddConnection( rIt->first, cIt->first, conn );
+
+ } // fi
+
+ } // rof
+
+ } // rof
+
+ } // rof
+ */
+}
+
+// -------------------------------------------------------------------------
+/* TODO
+ void PipelineEditor::QNodesEditorCanvas::
+ keyPressEvent( QKeyEvent* event )
+ {
+ }
+
+ // -------------------------------------------------------------------------
+ void PipelineEditor::QNodesEditorCanvas::
+ timerEvent( QTimerEvent* event )
+ {
+ }
+*/
+
+// -------------------------------------------------------------------------
+void PipelineEditor::QNodesEditorCanvas::
+wheelEvent( QWheelEvent* event )
+{
+ this->_scaleView(
+ std::pow( double( 2 ), event->delta( ) / double( 240 ) )
+ );
+}
+
+// -------------------------------------------------------------------------
+void PipelineEditor::QNodesEditorCanvas::
+dragEnterEvent( QDragEnterEvent* event )
+{
+ const QMimeData* mime = event->mimeData( );
+ if( mime->hasFormat( "application/x-qabstractitemmodeldatalist" ) )
+ event->acceptProposedAction( );
+}
+
+// -------------------------------------------------------------------------
+void PipelineEditor::QNodesEditorCanvas::
+dragLeaveEvent( QDragLeaveEvent* event )
+{
+}
+
+// -------------------------------------------------------------------------
+void PipelineEditor::QNodesEditorCanvas::
+dragMoveEvent( QDragMoveEvent* event )
+{
+}
+
+// -------------------------------------------------------------------------
+void PipelineEditor::QNodesEditorCanvas::
+dropEvent( QDropEvent* event )
+{
+ if( this->m_Workspace == NULL )
+ return;
+ const QMimeData* mime = event->mimeData( );
+ if( !( mime->hasFormat( "application/x-qabstractitemmodeldatalist" ) ) )
+ return;
+
+ event->acceptProposedAction( );
+ auto tree = dynamic_cast< QTreeWidget* >( event->source( ) );
+ if( tree == NULL )
+ return;
+
+ QList< QTreeWidgetItem* > items = tree->selectedItems( );
+ for( auto iIt = items.begin( ); iIt != items.end( ); ++iIt )
+ {
+ std::string filter = ( *iIt )->text( 0 ).toStdString( );
+ std::string name = filter;
+ if( this->m_Workspace->GetFilter( name ) != NULL )
+ name += std::string( "_" );
+ if( this->m_Workspace->CreateFilter( filter, name ) )
+ {
+ } // fi
+
+ } // rof
+}
+
+// -------------------------------------------------------------------------
+void PipelineEditor::QNodesEditorCanvas::
+_scaleView( qreal scaleFactor )
+{
+ qreal factor = this->transform( ).
+ scale( scaleFactor, scaleFactor ).
+ mapRect( QRectF( 0, 0, 1, 1 ) ).
+ width( );
+ if( factor < qreal( 0.07 ) || factor > qreal( 100 ) )
+ return;
+ this->scale( scaleFactor, scaleFactor );
+}
+
+// -------------------------------------------------------------------------
+void PipelineEditor::QNodesEditorCanvas::
+_createBlock( TFilter* f )
+{
+ if( f == NULL )
+ return;
+
+ // Add block
+ QNEBlock* b = new QNEBlock( 0, this->scene( ) );
+ b->addPort( f->GetName( ), 0, QNEPort::NamePort );
+ b->addPort( f->GetClassName( ).c_str( ), 0, QNEPort::TypePort );
+
+ // Add input ports
+ std::set< std::string > inputs;
+ f->GetInputsNames( inputs );
+ for( auto iIt = inputs.begin( ); iIt != inputs.end( ); ++iIt )
+ b->addInputPort( iIt->c_str( ) );
+ //in_ports[ vIt->first ][ *iIt ] = b->addInputPort( iIt->c_str( ) );
+
+ // Add output ports
+ std::set< std::string > outputs;
+ f->GetOutputsNames( outputs );
+ for( auto oIt = outputs.begin( ); oIt != outputs.end( ); ++oIt )
+ b->addOutputPort( oIt->c_str( ) );
+ // out_ports[ vIt->first ][ *oIt ] = b->addOutputPort( oIt->c_str( ) );
+
+ // Keep a trace of this visual graph
+ this->m_Graph->InsertVertex( f->GetName( ), b );
+
+ // Add vertices and keep track of ports
+ /*
+ std::map< std::string, std::map< std::string, QNEPort* > >
+ in_ports, out_ports;
+ auto vIt = this->m_Workspace->GetGraph( )->BeginVertices( );
+ auto vIt_end = this->m_Workspace->GetGraph( )->EndVertices( );
+ for( ; vIt != vIt_end; ++vIt )
+ {
+ // Add block
+ QNEBlock* b = new QNEBlock( 0, scene );
+ b->addPort( vIt->second->GetName( ), 0, QNEPort::NamePort );
+ b->addPort( vIt->second->GetClassName( ).c_str( ), 0, QNEPort::TypePort );
+
+ // Get filter
+ auto f = dynamic_cast< TFilter* >( vIt->second.GetPointer( ) );
+ if( f == NULL )
+ continue;
+
+ // Add input ports
+ std::set< std::string > inputs;
+ f->GetInputsNames( inputs );
+ for( auto iIt = inputs.begin( ); iIt != inputs.end( ); ++iIt )
+ in_ports[ vIt->first ][ *iIt ] = b->addInputPort( iIt->c_str( ) );
+
+ // Add output ports
+ std::set< std::string > outputs;
+ f->GetOutputsNames( outputs );
+ for( auto oIt = outputs.begin( ); oIt != outputs.end( ); ++oIt )
+ out_ports[ vIt->first ][ *oIt ] = b->addOutputPort( oIt->c_str( ) );
+
+ // Keep a trace of this visual graph
+ this->m_Graph->InsertVertex( vIt->first, b );
+
+ } // rof
+ */
+}
+
+// eof - $RCSfile$
+
+
+/*
+
+// -------------------------------------------------------------------------
+void GraphWidget::
+draw( )
+{
+ if( this->m_Workspace == NULL )
+ return;
+}
+
+// -------------------------------------------------------------------------
+void GraphWidget::itemMoved()
+{
+ if (!timerId)
+ timerId = startTimer(1000 / 25);
+}
+
+void GraphWidget::keyPressEvent(QKeyEvent *event)
+{
+ switch (event->key()) {
+ case Qt::Key_Up:
+ centerNode->moveBy(0, -20);
+ break;
+ case Qt::Key_Down:
+ centerNode->moveBy(0, 20);
+ break;
+ case Qt::Key_Left:
+ centerNode->moveBy(-20, 0);
+ break;
+ case Qt::Key_Right:
+ centerNode->moveBy(20, 0);
+ break;
+ case Qt::Key_Plus:
+ zoomIn();
+ break;
+ case Qt::Key_Minus:
+ zoomOut();
+ break;
+ case Qt::Key_Space:
+ case Qt::Key_Enter:
+ shuffle();
+ break;
+ default:
+ QGraphicsView::keyPressEvent(event);
+ }
+}
+
+void GraphWidget::timerEvent(QTimerEvent *event)
+{
+ Q_UNUSED(event);
+
+ QList<Node *> nodes;
+ foreach (QGraphicsItem *item, scene()->items()) {
+ if (Node *node = qgraphicsitem_cast<Node *>(item))
+ nodes << node;
+ }
+
+ foreach (Node *node, nodes)
+ node->calculateForces();
+
+ bool itemsMoved = false;
+ foreach (Node *node, nodes) {
+ if (node->advance())
+ itemsMoved = true;
+ }
+
+ if (!itemsMoved) {
+ killTimer(timerId);
+ timerId = 0;
+ }
+}
+
+void GraphWidget::wheelEvent(QWheelEvent *event)
+{
+ scaleView(pow((double)2, -event->delta() / 240.0));
+}
+
+void GraphWidget::drawBackground(QPainter *painter, const QRectF &rect)
+{
+ //Q_UNUSED(rect);
+
+ // Shadow
+ QRectF sceneRect = rect;//this->sceneRect();
+ QRectF rightShadow(sceneRect.right(), sceneRect.top() + 5, 5, sceneRect.height());
+ QRectF bottomShadow(sceneRect.left() + 5, sceneRect.bottom(), sceneRect.width(), 5);
+ if (rightShadow.intersects(rect) || rightShadow.contains(rect))
+ painter->fillRect(rightShadow, Qt::darkGray);
+ if (bottomShadow.intersects(rect) || bottomShadow.contains(rect))
+ painter->fillRect(bottomShadow, Qt::darkGray);
+
+ // Fill
+ QLinearGradient gradient(sceneRect.topLeft(), sceneRect.bottomRight());
+ gradient.setColorAt(0, Qt::white);
+ gradient.setColorAt(1, Qt::lightGray);
+ painter->fillRect(rect.intersect(sceneRect), gradient);
+ painter->setBrush(Qt::NoBrush);
+ painter->drawRect(sceneRect);
+
+#if !defined(Q_OS_SYMBIAN) && !defined(Q_WS_MAEMO_5)
+ // Text
+ QRectF textRect(sceneRect.left() + 4, sceneRect.top() + 4,
+ sceneRect.width() - 4, sceneRect.height() - 4);
+ QString message(tr("Click and drag the nodes around, and zoom with the mouse "
+ "wheel or the '+' and '-' keys"));
+
+ QFont font = painter->font();
+ font.setBold(true);
+ font.setPointSize(14);
+ painter->setFont(font);
+ painter->setPen(Qt::lightGray);
+ painter->drawText(textRect.translated(2, 2), message);
+ painter->setPen(Qt::black);
+ painter->drawText(textRect, message);
+#endif
+}
+
+void GraphWidget::scaleView(qreal scaleFactor)
+{
+ qreal factor = transform().scale(scaleFactor, scaleFactor).mapRect(QRectF(0, 0, 1, 1)).width();
+ if (factor < 0.07 || factor > 100)
+ return;
+
+ scale(scaleFactor, scaleFactor);
+}
+
+void GraphWidget::shuffle()
+{
+ foreach (QGraphicsItem *item, scene()->items()) {
+ if (qgraphicsitem_cast<Node *>(item))
+ item->setPos(-150 + qrand() % 300, -150 + qrand() % 300);
+ }
+}
+
+void GraphWidget::zoomIn()
+{
+ scaleView(qreal(1.2));
+}
+
+void GraphWidget::zoomOut()
+{
+ scaleView(1 / qreal(1.2));
+}
+
+
+*/