]> Creatis software - cpPlugins.git/commitdiff
More on graph editor
authorLeonardo Florez-Valencia <florez-l@javeriana.edu.co>
Tue, 15 Dec 2015 22:54:08 +0000 (17:54 -0500)
committerLeonardo Florez-Valencia <florez-l@javeriana.edu.co>
Tue, 15 Dec 2015 22:54:08 +0000 (17:54 -0500)
19 files changed:
appli/cpPipelineEditor/CMakeLists.txt
appli/cpPipelineEditor/QNEBlock.cxx [new file with mode: 0644]
appli/cpPipelineEditor/QNEBlock.h [new file with mode: 0644]
appli/cpPipelineEditor/QNEConnection.cxx [new file with mode: 0644]
appli/cpPipelineEditor/QNEConnection.h [new file with mode: 0644]
appli/cpPipelineEditor/QNEMainWindow.cxx [new file with mode: 0644]
appli/cpPipelineEditor/QNEMainWindow.h [new file with mode: 0644]
appli/cpPipelineEditor/QNEMainWindow.ui [new file with mode: 0644]
appli/cpPipelineEditor/QNEPort.cxx [new file with mode: 0644]
appli/cpPipelineEditor/QNEPort.h [new file with mode: 0644]
appli/cpPipelineEditor/QNodesEditor.cxx [new file with mode: 0644]
appli/cpPipelineEditor/QNodesEditor.h [new file with mode: 0644]
appli/cpPipelineEditor/main.cxx
lib/cpExtensions/DataStructures/Graph.h
lib/cpExtensions/DataStructures/Graph.hxx
lib/cpPlugins/Interface/Workspace.cxx
lib/cpPlugins/Interface/Workspace.h
lib/cpPlugins/Interface/WorkspaceIO.cxx
lib/cpPlugins/Plugins/IO/ImageReader.cxx

index 002e6e26ef9df23a86a7cc2d0b89ca7774272849..b978bcd11b97c581008c59943078cf1ad651b70a 100644 (file)
@@ -10,10 +10,15 @@ IF(USE_QT4)
 
   SET(
     App_QT_SOURCES
-    Edge.cxx
-    GraphCanvas.cxx
-    Node.cxx
-    cpPipelineEditor.cxx
+    QNEBlock.cxx
+    QNEConnection.cxx
+    QNEPort.cxx
+    QNodesEditor.cxx
+    QNEMainWindow.cxx
+    #Edge.cxx
+    #GraphCanvas.cxx
+    #Node.cxx
+    #cpPipelineEditor.cxx
     )
   SET(
     App_SOURCES
@@ -21,8 +26,10 @@ IF(USE_QT4)
     )
   SET(
     App_QT_HEADERS
-    GraphCanvas.h
-    cpPipelineEditor.h
+    QNodesEditor.h
+    QNEMainWindow.h
+    #GraphCanvas.h
+    #cpPipelineEditor.h
     )
   SET(
     App_HEADERS
diff --git a/appli/cpPipelineEditor/QNEBlock.cxx b/appli/cpPipelineEditor/QNEBlock.cxx
new file mode 100644 (file)
index 0000000..d1e0109
--- /dev/null
@@ -0,0 +1,260 @@
+/* Copyright (c) 2012, STANISLAW ADASZEWSKI\r
+   All rights reserved.\r
+\r
+   Redistribution and use in source and binary forms, with or without\r
+   modification, are permitted provided that the following conditions are met:\r
+   * Redistributions of source code must retain the above copyright\r
+   notice, this list of conditions and the following disclaimer.\r
+   * Redistributions in binary form must reproduce the above copyright\r
+   notice, this list of conditions and the following disclaimer in the\r
+   documentation and/or other materials provided with the distribution.\r
+   * Neither the name of STANISLAW ADASZEWSKI nor the\r
+   names of its contributors may be used to endorse or promote products\r
+   derived from this software without specific prior written permission.\r
+\r
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND\r
+   ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\r
+   WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\r
+   DISCLAIMED. IN NO EVENT SHALL STANISLAW ADASZEWSKI BE LIABLE FOR ANY\r
+   DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r
+   (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\r
+   LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\r
+   ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
+   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\r
+   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+*/\r
+\r
+#include "QNEBlock.h"\r
+\r
+#include <QPen>\r
+#include <QGraphicsScene>\r
+#include <QFontMetrics>\r
+#include <QPainter>\r
+#include <QStyleOptionGraphicsItem>\r
+\r
+#include "QNEPort.h"\r
+\r
+// -------------------------------------------------------------------------\r
+PipelineEditor::QNEBlock::\r
+QNEBlock( QGraphicsItem* parent, QGraphicsScene* scene )\r
+  : Superclass( parent, scene ),\r
+    m_HorzMargin( 20 ),\r
+    m_VertMargin( 5 )\r
+{\r
+  QPainterPath p;\r
+  p.addRoundedRect( -50, -15, 100, 30, 5, 5 );\r
+  this->setPath( p );\r
+  this->setPen( QPen( Qt::darkGreen ) );\r
+  this->setBrush( Qt::green );\r
+  this->setFlag( QGraphicsItem::ItemIsMovable );\r
+  this->setFlag( QGraphicsItem::ItemIsSelectable );\r
+  this->m_Width = this->m_HorzMargin;\r
+  this->m_Height = this->m_VertMargin;\r
+}\r
+\r
+// -------------------------------------------------------------------------\r
+PipelineEditor::QNEBlock::\r
+~QNEBlock( )\r
+{\r
+}\r
+\r
+// -------------------------------------------------------------------------\r
+PipelineEditor::QNEPort* PipelineEditor::QNEBlock::\r
+addPort( const QString& name, bool isOutput, int flags, int ptr )\r
+{\r
+  QNEPort* port = new QNEPort( this );\r
+  port->setName( name );\r
+  port->setIsOutput( isOutput );\r
+  port->setNEBlock( this );\r
+  port->setPortFlags( flags );\r
+  port->setPtr( ptr );\r
+\r
+  QFontMetrics fm( this->scene( )->font( ) );\r
+  int w = fm.width( name );\r
+  int h = fm.height( );\r
+  if( w > this->m_Width - this->m_HorzMargin )\r
+    this->m_Width = w + this->m_HorzMargin;\r
+  this->m_Height += h;\r
+\r
+  QPainterPath p;\r
+  p.addRoundedRect(\r
+    -this->m_Width / 2,\r
+    -this->m_Height / 2,\r
+    this->m_Width,\r
+    this->m_Height, 5, 5\r
+    );\r
+  this->setPath( p );\r
+\r
+  int y = -this->m_Height / 2 + this->m_VertMargin + port->radius( );\r
+  foreach( QGraphicsItem* port_, children( ) )\r
+  {\r
+    if( port_->type( ) != QNEPort::Type )\r
+      continue;\r
+\r
+    QNEPort* port = ( QNEPort* ) port_;\r
+    if( port->isOutput( ) )\r
+      port->setPos( this->m_Width/2 + port->radius( ), y );\r
+    else\r
+      port->setPos( -this->m_Width/2 - port->radius( ), y );\r
+    y += h;\r
+\r
+  } // rof\r
+  return( port );\r
+}\r
+\r
+// -------------------------------------------------------------------------\r
+void PipelineEditor::QNEBlock::\r
+addInputPort( const QString& name )\r
+{\r
+  this->addPort( name, false );\r
+}\r
+\r
+// -------------------------------------------------------------------------\r
+void PipelineEditor::QNEBlock::\r
+addOutputPort( const QString& name )\r
+{\r
+  this->addPort( name, true );\r
+}\r
+\r
+// -------------------------------------------------------------------------\r
+void PipelineEditor::QNEBlock::\r
+addInputPorts( const QStringList& names )\r
+{\r
+  foreach( QString n, names )\r
+    this->addInputPort( n );\r
+}\r
+\r
+// -------------------------------------------------------------------------\r
+void PipelineEditor::QNEBlock::\r
+addOutputPorts( const QStringList& names )\r
+{\r
+  foreach( QString n, names )\r
+    this->addOutputPort( n );\r
+}\r
+\r
+// -------------------------------------------------------------------------\r
+void PipelineEditor::QNEBlock::\r
+save( QDataStream& ds )\r
+{\r
+  ds << pos( );\r
+\r
+  int count( 0 );\r
+\r
+  foreach( QGraphicsItem* port_, children( ) )\r
+  {\r
+    if( port_->type( ) != QNEPort::Type )\r
+      continue;\r
+    count++;\r
+\r
+  } // rof\r
+\r
+  ds << count;\r
+\r
+  foreach( QGraphicsItem* port_, children( ) )\r
+  {\r
+    if( port_->type( ) != QNEPort::Type )\r
+      continue;\r
+\r
+    QNEPort* port = ( QNEPort* ) port_;\r
+    ds << ( quint64 ) port;\r
+    ds << port->portName( );\r
+    ds << port->isOutput( );\r
+    ds << port->portFlags( );\r
+\r
+  } // rof\r
+}\r
+\r
+// -------------------------------------------------------------------------\r
+void PipelineEditor::QNEBlock::\r
+load( QDataStream& ds, QMap<quint64, QNEPort*>& portMap )\r
+{\r
+  QPointF p;\r
+  ds >> p;\r
+  this->setPos( p );\r
+  int count;\r
+  ds >> count;\r
+  for( int i = 0; i < count; i++ )\r
+  {\r
+    QString name;\r
+    bool output;\r
+    int flags;\r
+    quint64 ptr;\r
+\r
+    ds >> ptr;\r
+    ds >> name;\r
+    ds >> output;\r
+    ds >> flags;\r
+    portMap[ptr] = this->addPort( name, output, flags, ptr );\r
+\r
+  } // rof\r
+}\r
+\r
+// -------------------------------------------------------------------------\r
+void PipelineEditor::QNEBlock::\r
+paint(\r
+  QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget\r
+  )\r
+{\r
+  Q_UNUSED( option );\r
+  Q_UNUSED( widget );\r
+\r
+  if( this->isSelected( ) )\r
+  {\r
+    painter->setPen( QPen( Qt::darkYellow ) );\r
+    painter->setBrush( Qt::yellow );\r
+  }\r
+  else\r
+  {\r
+    painter->setPen( QPen( Qt::darkGreen ) );\r
+    painter->setBrush( Qt::green );\r
+\r
+  } // fi\r
+  painter->drawPath( this->path( ) );\r
+}\r
+\r
+// -------------------------------------------------------------------------\r
+PipelineEditor::QNEBlock* PipelineEditor::QNEBlock::\r
+clone( )\r
+{\r
+  QNEBlock* b = new QNEBlock( 0, this->scene( ) );\r
+\r
+  foreach( QGraphicsItem* port_, childItems( ) )\r
+  {\r
+    if( port_->type( ) == QNEPort::Type )\r
+    {\r
+      QNEPort* port = ( QNEPort* ) port_;\r
+      b->addPort(\r
+        port->portName( ),\r
+        port->isOutput( ),\r
+        port->portFlags( ),\r
+        port->ptr( )\r
+        );\r
+\r
+    } // fi\r
+\r
+  } // rof\r
+  return( b );\r
+}\r
+\r
+// -------------------------------------------------------------------------\r
+QVector< PipelineEditor::QNEPort* > PipelineEditor::QNEBlock::\r
+ports( )\r
+{\r
+  QVector< PipelineEditor::QNEPort* > res;\r
+  foreach( QGraphicsItem* port_, childItems( ) )\r
+  {\r
+    if( port_->type( ) == QNEPort::Type )\r
+      res.append( ( QNEPort* ) port_ );\r
+\r
+  } // rof\r
+  return( res );\r
+}\r
+\r
+// -------------------------------------------------------------------------\r
+QVariant PipelineEditor::QNEBlock::\r
+itemChange( GraphicsItemChange change, const QVariant& value )\r
+{\r
+  return( value );\r
+}\r
+\r
+// eof - $RCSfile$\r
diff --git a/appli/cpPipelineEditor/QNEBlock.h b/appli/cpPipelineEditor/QNEBlock.h
new file mode 100644 (file)
index 0000000..516e871
--- /dev/null
@@ -0,0 +1,82 @@
+/* Copyright (c) 2012, STANISLAW ADASZEWSKI\r
+   All rights reserved.\r
+\r
+   Redistribution and use in source and binary forms, with or without\r
+   modification, are permitted provided that the following conditions are met:\r
+   * Redistributions of source code must retain the above copyright\r
+   notice, this list of conditions and the following disclaimer.\r
+   * Redistributions in binary form must reproduce the above copyright\r
+   notice, this list of conditions and the following disclaimer in the\r
+   documentation and/or other materials provided with the distribution.\r
+   * Neither the name of STANISLAW ADASZEWSKI nor the\r
+   names of its contributors may be used to endorse or promote products\r
+   derived from this software without specific prior written permission.\r
+\r
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND\r
+   ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\r
+   WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\r
+   DISCLAIMED. IN NO EVENT SHALL STANISLAW ADASZEWSKI BE LIABLE FOR ANY\r
+   DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r
+   (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\r
+   LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\r
+   ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
+   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\r
+   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */\r
+\r
+#ifndef __PIPELINEEDITOR__QNEBLOCK__H__\r
+#define __PIPELINEEDITOR__QNEBLOCK__H__\r
+\r
+#include <QGraphicsPathItem>\r
+\r
+namespace PipelineEditor\r
+{\r
+  class QNEPort;\r
+\r
+  class QNEBlock\r
+    : public QGraphicsPathItem\r
+  {\r
+  public:\r
+    typedef QNEBlock          Self;\r
+    typedef QGraphicsPathItem Superclass;\r
+  \r
+  public:\r
+    enum { Type = QGraphicsItem::UserType + 3 };\r
+\r
+    QNEBlock( QGraphicsItem* parent = NULL, QGraphicsScene* scene = NULL );\r
+    virtual ~QNEBlock( );\r
+\r
+    QNEPort* addPort(\r
+      const QString& name, bool isOutput, int flags = 0, int ptr = 0\r
+      );\r
+    void addInputPort( const QString& name );\r
+    void addOutputPort( const QString& name );\r
+    void addInputPorts( const QStringList& names );\r
+    void addOutputPorts( const QStringList& names );\r
+    void save( QDataStream& ds );\r
+    void load( QDataStream& ds, QMap< quint64, QNEPort* >& portMap );\r
+    void paint(\r
+      QPainter* painter,\r
+      const QStyleOptionGraphicsItem* option,\r
+      QWidget* widget\r
+      );\r
+    QNEBlock* clone( );\r
+    QVector< QNEPort* > ports( );\r
+\r
+    int type( ) const\r
+      { return( this->Type ); }\r
+\r
+  protected:\r
+    QVariant itemChange( GraphicsItemChange change, const QVariant& value );\r
+\r
+  private:\r
+    int m_HorzMargin;\r
+    int m_VertMargin;\r
+    int m_Width;\r
+    int m_Height;\r
+  };\r
+\r
+} // ecapseman\r
+\r
+#endif // __PIPELINEEDITOR__QNEBLOCK__H__\r
+\r
+// eof - $RCSfile$\r
diff --git a/appli/cpPipelineEditor/QNEConnection.cxx b/appli/cpPipelineEditor/QNEConnection.cxx
new file mode 100644 (file)
index 0000000..e038c5f
--- /dev/null
@@ -0,0 +1,155 @@
+/* Copyright (c) 2012, STANISLAW ADASZEWSKI\r
+   All rights reserved.\r
+\r
+   Redistribution and use in source and binary forms, with or without\r
+   modification, are permitted provided that the following conditions are met:\r
+   * Redistributions of source code must retain the above copyright\r
+   notice, this list of conditions and the following disclaimer.\r
+   * Redistributions in binary form must reproduce the above copyright\r
+   notice, this list of conditions and the following disclaimer in the\r
+   documentation and/or other materials provided with the distribution.\r
+   * Neither the name of STANISLAW ADASZEWSKI nor the\r
+   names of its contributors may be used to endorse or promote products\r
+   derived from this software without specific prior written permission.\r
+\r
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND\r
+   ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\r
+   WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\r
+   DISCLAIMED. IN NO EVENT SHALL STANISLAW ADASZEWSKI BE LIABLE FOR ANY\r
+   DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r
+   (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\r
+   LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\r
+   ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
+   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\r
+   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+*/\r
+\r
+#include "QNEConnection.h"\r
+\r
+#include "QNEPort.h"\r
+\r
+#include <QBrush>\r
+#include <QPen>\r
+#include <QGraphicsScene>\r
+\r
+// -------------------------------------------------------------------------\r
+PipelineEditor::QNEConnection::\r
+QNEConnection( QGraphicsItem* parent, QGraphicsScene* scene )\r
+  : Superclass( parent, scene )\r
+{\r
+  this->setPen( QPen( Qt::black, 2 ) );\r
+  this->setBrush( Qt::NoBrush );\r
+  this->setZValue( -1 );\r
+  this->m_Port1 = 0;\r
+  this->m_Port2 = 0;\r
+}\r
+\r
+// -------------------------------------------------------------------------\r
+PipelineEditor::QNEConnection::\r
+~QNEConnection( )\r
+{\r
+  if ( this->m_Port1 )\r
+    this->m_Port1->connections( ).remove(\r
+      this->m_Port1->connections( ).indexOf( this )\r
+      );\r
+  if ( this->m_Port2 )\r
+    this->m_Port2->connections( ).remove(\r
+      this->m_Port2->connections( ).indexOf( this )\r
+      );\r
+}\r
+\r
+// -------------------------------------------------------------------------\r
+void PipelineEditor::QNEConnection::\r
+setPos1( const QPointF& p )\r
+{\r
+  this->m_Pos1 = p;\r
+}\r
+\r
+// -------------------------------------------------------------------------\r
+void PipelineEditor::QNEConnection::\r
+setPos2( const QPointF& p )\r
+{\r
+  this->m_Pos2 = p;\r
+}\r
+\r
+// -------------------------------------------------------------------------\r
+void PipelineEditor::QNEConnection::\r
+setPort1( QNEPort* p )\r
+{\r
+  this->m_Port1 = p;\r
+  this->m_Port1->connections( ).append( this );\r
+}\r
+\r
+// -------------------------------------------------------------------------\r
+void PipelineEditor::QNEConnection::\r
+setPort2( QNEPort* p )\r
+{\r
+  this->m_Port2 = p;\r
+  this->m_Port2->connections( ).append( this );\r
+}\r
+\r
+// -------------------------------------------------------------------------\r
+void PipelineEditor::QNEConnection::\r
+updatePosFromPorts( )\r
+{\r
+  this->m_Pos1 = this->m_Port1->scenePos( );\r
+  this->m_Pos2 = this->m_Port2->scenePos( );\r
+}\r
+\r
+// -------------------------------------------------------------------------\r
+void PipelineEditor::QNEConnection::\r
+updatePath( )\r
+{\r
+  QPainterPath p;\r
+\r
+  p.moveTo( this->m_Pos1 );\r
+\r
+  qreal dx = this->m_Pos2.x( ) - this->m_Pos1.x( );\r
+  qreal dy = this->m_Pos2.y( ) - this->m_Pos1.y( );\r
+\r
+  QPointF ctr1( this->m_Pos1.x( ) + dx * 0.25, this->m_Pos1.y( ) + dy * 0.1 );\r
+  QPointF ctr2( this->m_Pos1.x( ) + dx * 0.75, this->m_Pos1.y( ) + dy * 0.9 );\r
+\r
+  p.cubicTo( ctr1, ctr2, this->m_Pos2 );\r
+\r
+  this->setPath( p );\r
+}\r
+\r
+// -------------------------------------------------------------------------\r
+PipelineEditor::QNEPort* PipelineEditor::QNEConnection::\r
+port1( ) const\r
+{\r
+  return( this->m_Port1 );\r
+}\r
+\r
+// -------------------------------------------------------------------------\r
+PipelineEditor::QNEPort* PipelineEditor::QNEConnection::\r
+port2( ) const\r
+{\r
+  return( this->m_Port2 );\r
+}\r
+\r
+// -------------------------------------------------------------------------\r
+void PipelineEditor::QNEConnection::\r
+save( QDataStream& ds )\r
+{\r
+  ds << ( quint64 ) this->m_Port1;\r
+  ds << ( quint64 ) this->m_Port2;\r
+}\r
+\r
+// -------------------------------------------------------------------------\r
+void PipelineEditor::QNEConnection::\r
+load( QDataStream& ds, const QMap< quint64, QNEPort* >& portMap )\r
+{\r
+  quint64 ptr1;\r
+  quint64 ptr2;\r
+  ds >> ptr1;\r
+  ds >> ptr2;\r
+\r
+  this->setPort1( portMap[ ptr1 ] );\r
+  this->setPort2( portMap[ ptr2 ] );\r
+  this->updatePosFromPorts( );\r
+  this->updatePath( );\r
+}\r
+\r
+// eof - $RCSfile$\r
diff --git a/appli/cpPipelineEditor/QNEConnection.h b/appli/cpPipelineEditor/QNEConnection.h
new file mode 100644 (file)
index 0000000..869e283
--- /dev/null
@@ -0,0 +1,76 @@
+/* Copyright (c) 2012, STANISLAW ADASZEWSKI\r
+   All rights reserved.\r
+\r
+   Redistribution and use in source and binary forms, with or without\r
+   modification, are permitted provided that the following conditions are met:\r
+   * Redistributions of source code must retain the above copyright\r
+   notice, this list of conditions and the following disclaimer.\r
+   * Redistributions in binary form must reproduce the above copyright\r
+   notice, this list of conditions and the following disclaimer in the\r
+   documentation and/or other materials provided with the distribution.\r
+   * Neither the name of STANISLAW ADASZEWSKI nor the\r
+   names of its contributors may be used to endorse or promote products\r
+   derived from this software without specific prior written permission.\r
+\r
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND\r
+   ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\r
+   WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\r
+   DISCLAIMED. IN NO EVENT SHALL STANISLAW ADASZEWSKI BE LIABLE FOR ANY\r
+   DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r
+   (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\r
+   LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\r
+   ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
+   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\r
+   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+*/\r
+\r
+#ifndef __PIPELINEEDITOR__QNECONNECTION__H__\r
+#define __PIPELINEEDITOR__QNECONNECTION__H__\r
+\r
+#include <QGraphicsPathItem>\r
+\r
+namespace PipelineEditor\r
+{\r
+  class QNEPort;\r
+\r
+  /**\r
+   */\r
+  class QNEConnection\r
+    : public QGraphicsPathItem\r
+  {\r
+  public:\r
+    typedef QNEConnection     Self;\r
+    typedef QGraphicsPathItem Superclass;\r
+\r
+  public:\r
+    enum { Type = QGraphicsItem::UserType + 2 };\r
+\r
+    QNEConnection( QGraphicsItem* parent = 0, QGraphicsScene* scene = 0 );\r
+    virtual ~QNEConnection( );\r
+\r
+    void setPos1( const QPointF& p );\r
+    void setPos2( const QPointF& p );\r
+    void setPort1( QNEPort* p );\r
+    void setPort2( QNEPort* p );\r
+    void updatePosFromPorts( );\r
+    void updatePath( );\r
+    QNEPort* port1( ) const;\r
+    QNEPort* port2( ) const;\r
+\r
+    void save( QDataStream& ds );\r
+    void load( QDataStream& ds, const QMap< quint64, QNEPort* >& portMap );\r
+\r
+    int type( ) const { return Type; }\r
+\r
+  private:\r
+    QPointF m_Pos1;\r
+    QPointF m_Pos2;\r
+    QNEPort* m_Port1;\r
+    QNEPort* m_Port2;\r
+  };\r
+\r
+} // ecapseman\r
+\r
+#endif // __PIPELINEEDITOR__QNECONNECTION__H__\r
+\r
+// eof - $RCSfile$\r
diff --git a/appli/cpPipelineEditor/QNEMainWindow.cxx b/appli/cpPipelineEditor/QNEMainWindow.cxx
new file mode 100644 (file)
index 0000000..5d7f7fe
--- /dev/null
@@ -0,0 +1,112 @@
+/* Copyright (c) 2012, STANISLAW ADASZEWSKI\r
+All rights reserved.\r
+\r
+Redistribution and use in source and binary forms, with or without\r
+modification, are permitted provided that the following conditions are met:\r
+    * Redistributions of source code must retain the above copyright\r
+      notice, this list of conditions and the following disclaimer.\r
+    * Redistributions in binary form must reproduce the above copyright\r
+      notice, this list of conditions and the following disclaimer in the\r
+      documentation and/or other materials provided with the distribution.\r
+    * Neither the name of STANISLAW ADASZEWSKI nor the\r
+      names of its contributors may be used to endorse or promote products\r
+      derived from this software without specific prior written permission.\r
+\r
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND\r
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\r
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\r
+DISCLAIMED. IN NO EVENT SHALL STANISLAW ADASZEWSKI BE LIABLE FOR ANY\r
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\r
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\r
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\r
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */\r
+\r
+#include "QNEMainWindow.h"\r
+#include "ui_QNEMainWindow.h"\r
+\r
+#include "QNEBlock.h"\r
+#include "QNodesEditor.h"\r
+\r
+#include <QGraphicsScene>\r
+#include <QFileDialog>\r
+\r
+#include "QNEPort.h"\r
+\r
+QNEMainWindow::QNEMainWindow(QWidget *parent) :\r
+    QMainWindow(parent),\r
+    ui(new Ui::QNEMainWindow)\r
+{\r
+    ui->setupUi(this);\r
+\r
+    QGraphicsScene *s = new QGraphicsScene();\r
+    ui->graphicsView->setScene(s);\r
+    ui->graphicsView->setRenderHint(QPainter::Antialiasing);\r
+    // ui->graphicsView->setDragMode(QGraphicsView::ScrollHandDrag);\r
+\r
+    QNEBlock *b = new QNEBlock(0, s);\r
+    b->addPort("test", 0, QNEPort::NamePort);\r
+    b->addPort("TestBlock", 0, QNEPort::TypePort);\r
+    b->addInputPort("in1");\r
+    b->addInputPort("in2");\r
+    b->addInputPort("in3");\r
+    b->addOutputPort("out1");\r
+    b->addOutputPort("out2");\r
+    b->addOutputPort("out3");\r
+\r
+    b = b->clone();\r
+    b->setPos(150, 0);\r
+\r
+    b = b->clone();\r
+    b->setPos(150, 150);\r
+\r
+    nodesEditor = new QNodesEditor(this);\r
+    nodesEditor->install(s);\r
+\r
+    connect(ui->action_Save, SIGNAL(triggered()), this, SLOT(saveFile()));\r
+    connect(ui->action_Load, SIGNAL(triggered()), this, SLOT(loadFile()));\r
+    connect(ui->action_Quit, SIGNAL(triggered()), qApp, SLOT(quit()));\r
+\r
+    ui->toolBar->addAction("Add block", this, SLOT(addBlock()));\r
+}\r
+\r
+QNEMainWindow::~QNEMainWindow()\r
+{\r
+    delete ui;\r
+}\r
+\r
+void QNEMainWindow::saveFile()\r
+{\r
+       QString fname = QFileDialog::getSaveFileName();\r
+       if (fname.isEmpty())\r
+               return;\r
+\r
+       QFile f(fname);\r
+       f.open(QFile::WriteOnly);\r
+       QDataStream ds(&f);\r
+       nodesEditor->save(ds);\r
+}\r
+\r
+void QNEMainWindow::loadFile()\r
+{\r
+       QString fname = QFileDialog::getOpenFileName();\r
+       if (fname.isEmpty())\r
+               return;\r
+\r
+       QFile f(fname);\r
+       f.open(QFile::ReadOnly);\r
+       QDataStream ds(&f);\r
+       nodesEditor->load(ds);\r
+}\r
+\r
+void QNEMainWindow::addBlock()\r
+{\r
+       QNEBlock *b = new QNEBlock(0, ui->graphicsView->scene());\r
+       static const char* names[] = {"Vin", "Voutsadfasdf", "Imin", "Imax", "mul", "add", "sub", "div", "Conv", "FFT"};\r
+       for (int i = 0; i < 4 + rand() % 3; i++)\r
+       {\r
+               b->addPort(names[rand() % 10], rand() % 2, 0, 0);\r
+               b->setPos(ui->graphicsView->sceneRect().center().toPoint());\r
+       }\r
+}\r
diff --git a/appli/cpPipelineEditor/QNEMainWindow.h b/appli/cpPipelineEditor/QNEMainWindow.h
new file mode 100644 (file)
index 0000000..4ee1100
--- /dev/null
@@ -0,0 +1,55 @@
+/* Copyright (c) 2012, STANISLAW ADASZEWSKI\r
+All rights reserved.\r
+\r
+Redistribution and use in source and binary forms, with or without\r
+modification, are permitted provided that the following conditions are met:\r
+    * Redistributions of source code must retain the above copyright\r
+      notice, this list of conditions and the following disclaimer.\r
+    * Redistributions in binary form must reproduce the above copyright\r
+      notice, this list of conditions and the following disclaimer in the\r
+      documentation and/or other materials provided with the distribution.\r
+    * Neither the name of STANISLAW ADASZEWSKI nor the\r
+      names of its contributors may be used to endorse or promote products\r
+      derived from this software without specific prior written permission.\r
+\r
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND\r
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\r
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\r
+DISCLAIMED. IN NO EVENT SHALL STANISLAW ADASZEWSKI BE LIABLE FOR ANY\r
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\r
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\r
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\r
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */\r
+\r
+#ifndef QNEMAINWINDOW_H\r
+#define QNEMAINWINDOW_H\r
+\r
+#include <QMainWindow>\r
+\r
+namespace Ui {\r
+       class QNEMainWindow;\r
+}\r
+\r
+class QNodesEditor;\r
+\r
+class QNEMainWindow : public QMainWindow\r
+{\r
+       Q_OBJECT\r
+\r
+public:\r
+       explicit QNEMainWindow(QWidget *parent = 0);\r
+       ~QNEMainWindow();\r
+\r
+private slots:\r
+       void saveFile();\r
+       void loadFile();\r
+       void addBlock();\r
+\r
+private:\r
+       Ui::QNEMainWindow *ui;\r
+       QNodesEditor *nodesEditor;\r
+};\r
+\r
+#endif // QNEMAINWINDOW_H\r
diff --git a/appli/cpPipelineEditor/QNEMainWindow.ui b/appli/cpPipelineEditor/QNEMainWindow.ui
new file mode 100644 (file)
index 0000000..29f3f8c
--- /dev/null
@@ -0,0 +1,73 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<ui version="4.0">\r
+ <class>QNEMainWindow</class>\r
+ <widget class="QMainWindow" name="QNEMainWindow">\r
+  <property name="geometry">\r
+   <rect>\r
+    <x>0</x>\r
+    <y>0</y>\r
+    <width>540</width>\r
+    <height>389</height>\r
+   </rect>\r
+  </property>\r
+  <property name="windowTitle">\r
+   <string>QNodesEditor Demo (c) 2012 STANISLAW ADASZEWSKI, http://algoholic.eu</string>\r
+  </property>\r
+  <widget class="QWidget" name="centralWidget">\r
+   <layout class="QVBoxLayout" name="verticalLayout">\r
+    <item>\r
+     <widget class="QGraphicsView" name="graphicsView"/>\r
+    </item>\r
+   </layout>\r
+  </widget>\r
+  <widget class="QMenuBar" name="menuBar">\r
+   <property name="geometry">\r
+    <rect>\r
+     <x>0</x>\r
+     <y>0</y>\r
+     <width>540</width>\r
+     <height>20</height>\r
+    </rect>\r
+   </property>\r
+   <widget class="QMenu" name="menu_File">\r
+    <property name="title">\r
+     <string>&amp;File</string>\r
+    </property>\r
+    <addaction name="action_Save"/>\r
+    <addaction name="action_Load"/>\r
+    <addaction name="separator"/>\r
+    <addaction name="action_Quit"/>\r
+   </widget>\r
+   <addaction name="menu_File"/>\r
+  </widget>\r
+  <widget class="QToolBar" name="toolBar">\r
+   <property name="windowTitle">\r
+    <string>toolBar</string>\r
+   </property>\r
+   <attribute name="toolBarArea">\r
+    <enum>TopToolBarArea</enum>\r
+   </attribute>\r
+   <attribute name="toolBarBreak">\r
+    <bool>false</bool>\r
+   </attribute>\r
+  </widget>\r
+  <action name="action_Save">\r
+   <property name="text">\r
+    <string>&amp;Save</string>\r
+   </property>\r
+  </action>\r
+  <action name="action_Load">\r
+   <property name="text">\r
+    <string>&amp;Load</string>\r
+   </property>\r
+  </action>\r
+  <action name="action_Quit">\r
+   <property name="text">\r
+    <string>&amp;Quit</string>\r
+   </property>\r
+  </action>\r
+ </widget>\r
+ <layoutdefault spacing="6" margin="11"/>\r
+ <resources/>\r
+ <connections/>\r
+</ui>\r
diff --git a/appli/cpPipelineEditor/QNEPort.cxx b/appli/cpPipelineEditor/QNEPort.cxx
new file mode 100644 (file)
index 0000000..7c140bb
--- /dev/null
@@ -0,0 +1,191 @@
+/* Copyright (c) 2012, STANISLAW ADASZEWSKI\r
+   All rights reserved.\r
+\r
+   Redistribution and use in source and binary forms, with or without\r
+   modification, are permitted provided that the following conditions are met:\r
+   * Redistributions of source code must retain the above copyright\r
+   notice, this list of conditions and the following disclaimer.\r
+   * Redistributions in binary form must reproduce the above copyright\r
+   notice, this list of conditions and the following disclaimer in the\r
+   documentation and/or other materials provided with the distribution.\r
+   * Neither the name of STANISLAW ADASZEWSKI nor the\r
+   names of its contributors may be used to endorse or promote products\r
+   derived from this software without specific prior written permission.\r
+\r
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND\r
+   ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\r
+   WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\r
+   DISCLAIMED. IN NO EVENT SHALL STANISLAW ADASZEWSKI BE LIABLE FOR ANY\r
+   DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r
+   (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\r
+   LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\r
+   ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
+   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\r
+   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+*/\r
+\r
+#include "QNEPort.h"\r
+\r
+#include <QGraphicsScene>\r
+#include <QFontMetrics>\r
+#include <QPen>\r
+\r
+#include "QNEConnection.h"\r
+\r
+// -------------------------------------------------------------------------\r
+PipelineEditor::QNEPort::\r
+QNEPort( QGraphicsItem* parent, QGraphicsScene* scene )\r
+  : Superclass( parent, scene ),\r
+    m_Radius( 5 ),\r
+    m_Margin( 2 )\r
+{\r
+  this->m_Label = new QGraphicsTextItem( this );\r
+\r
+  QPainterPath p;\r
+  p.addEllipse( \r
+    -this->m_Radius, -this->m_Radius,\r
+    2 * this->m_Radius, 2 * this->m_Radius\r
+    );\r
+\r
+  this->setPath( p );\r
+  this->setPen( QPen( Qt::darkRed ) );\r
+  this->setBrush( Qt::red );\r
+  this->setFlag( QGraphicsItem::ItemSendsScenePositionChanges );\r
+  this->m_PortFlags = 0;\r
+}\r
+\r
+// -------------------------------------------------------------------------\r
+PipelineEditor::QNEPort::\r
+~QNEPort( )\r
+{\r
+  foreach( QNEConnection* conn, this->m_Connections )\r
+    delete conn;\r
+}\r
+\r
+// -------------------------------------------------------------------------\r
+void PipelineEditor::QNEPort::\r
+setNEBlock( QNEBlock *b )\r
+{\r
+  this->m_Block = b;\r
+}\r
+\r
+// -------------------------------------------------------------------------\r
+void PipelineEditor::QNEPort::\r
+setName( const QString &n )\r
+{\r
+  this->m_Name = n;\r
+  this->m_Label->setPlainText( n );\r
+}\r
+\r
+// -------------------------------------------------------------------------\r
+void PipelineEditor::QNEPort::\r
+setIsOutput( bool o )\r
+{\r
+  this->m_IsOutput = o;\r
+\r
+  QFontMetrics fm( this->scene( )->font( ) );\r
+  QRect r = fm.boundingRect( this->m_Name );\r
+\r
+  int rm = this->m_Radius + this->m_Margin;\r
+  int h = -this->m_Label->boundingRect( ).height( ) / 2;\r
+  if( this->m_IsOutput )\r
+    this->m_Label->setPos(\r
+      -rm - this->m_Label->boundingRect( ).width( ), h\r
+      );\r
+  else\r
+    this->m_Label->setPos( rm, h );\r
+}\r
+\r
+// -------------------------------------------------------------------------\r
+int PipelineEditor::QNEPort::\r
+radius( )\r
+{\r
+  return( this->m_Radius );\r
+}\r
+\r
+// -------------------------------------------------------------------------\r
+bool PipelineEditor::QNEPort::\r
+isOutput( )\r
+{\r
+  return( this->m_IsOutput );\r
+}\r
+\r
+// -------------------------------------------------------------------------\r
+QVector< PipelineEditor::QNEConnection* >& PipelineEditor::QNEPort::\r
+connections( )\r
+{\r
+  return( this->m_Connections );\r
+}\r
+\r
+// -------------------------------------------------------------------------\r
+void PipelineEditor::QNEPort::\r
+setPortFlags( int f )\r
+{\r
+  this->m_PortFlags = f;\r
+\r
+  if( this->m_PortFlags & Self::TypePort )\r
+  {\r
+    QFont font( this->scene( )->font( ) );\r
+    font.setItalic( true );\r
+    this->m_Label->setFont( font );\r
+    this->setPath( QPainterPath( ) );\r
+  }\r
+  else if( this->m_PortFlags & Self::NamePort )\r
+  {\r
+    QFont font( this->scene( )->font( ) );\r
+    font.setBold( true );\r
+    this->m_Label->setFont( font );\r
+    this->setPath( QPainterPath( ) );\r
+\r
+  } // fi\r
+}\r
+\r
+// -------------------------------------------------------------------------\r
+PipelineEditor::QNEBlock* PipelineEditor::QNEPort::\r
+block( ) const\r
+{\r
+  return( this->m_Block );\r
+}\r
+\r
+// -------------------------------------------------------------------------\r
+quint64 PipelineEditor::QNEPort::\r
+ptr( )\r
+{\r
+  return( this->m_Ptr );\r
+}\r
+\r
+// -------------------------------------------------------------------------\r
+void PipelineEditor::QNEPort::\r
+setPtr( quint64 p )\r
+{\r
+  this->m_Ptr = p;\r
+}\r
+\r
+// -------------------------------------------------------------------------\r
+bool PipelineEditor::QNEPort::\r
+isConnected( QNEPort* other )\r
+{\r
+  foreach( QNEConnection* conn, this->m_Connections )\r
+    if( conn->port1( ) == other || conn->port2( ) == other )\r
+      return( true );\r
+  return( false );\r
+}\r
+\r
+// -------------------------------------------------------------------------\r
+QVariant PipelineEditor::QNEPort::\r
+itemChange( GraphicsItemChange change, const QVariant& value )\r
+{\r
+  if( change == ItemScenePositionHasChanged )\r
+  {\r
+    foreach( QNEConnection* conn, this->m_Connections )\r
+    {\r
+      conn->updatePosFromPorts( );\r
+      conn->updatePath( );\r
+\r
+    } // rof\r
+\r
+  } // fi\r
+  return( value );\r
+}\r
+\r
+// eof - $RCSfile$\r
diff --git a/appli/cpPipelineEditor/QNEPort.h b/appli/cpPipelineEditor/QNEPort.h
new file mode 100644 (file)
index 0000000..638e413
--- /dev/null
@@ -0,0 +1,92 @@
+/* Copyright (c) 2012, STANISLAW ADASZEWSKI\r
+   All rights reserved.\r
+\r
+   Redistribution and use in source and binary forms, with or without\r
+   modification, are permitted provided that the following conditions are met:\r
+   * Redistributions of source code must retain the above copyright\r
+   notice, this list of conditions and the following disclaimer.\r
+   * Redistributions in binary form must reproduce the above copyright\r
+   notice, this list of conditions and the following disclaimer in the\r
+   documentation and/or other materials provided with the distribution.\r
+   * Neither the name of STANISLAW ADASZEWSKI nor the\r
+   names of its contributors may be used to endorse or promote products\r
+   derived from this software without specific prior written permission.\r
+\r
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND\r
+   ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\r
+   WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\r
+   DISCLAIMED. IN NO EVENT SHALL STANISLAW ADASZEWSKI BE LIABLE FOR ANY\r
+   DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r
+   (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\r
+   LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\r
+   ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
+   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\r
+   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+*/\r
+\r
+#ifndef __PIPELINEEDITOR__QNEPORT__H__\r
+#define __PIPELINEEDITOR__QNEPORT__H__\r
+\r
+#include <QGraphicsPathItem>\r
+\r
+namespace PipelineEditor\r
+{\r
+  class QNEBlock;\r
+  class QNEConnection;\r
+\r
+  /**\r
+   */\r
+  class QNEPort\r
+    : public QGraphicsPathItem\r
+  {\r
+  public:\r
+    typedef QNEPort Self;\r
+    typedef QGraphicsPathItem Superclass;\r
+\r
+  public:\r
+    enum { Type = QGraphicsItem::UserType + 1 };\r
+    enum { NamePort = 1, TypePort = 2 };\r
+\r
+    QNEPort( QGraphicsItem* parent = 0, QGraphicsScene* scene = NULL );\r
+    virtual ~QNEPort( );\r
+\r
+    void setNEBlock( QNEBlock* b );\r
+    void setName( const QString& n );\r
+    void setIsOutput( bool o );\r
+    int radius( );\r
+    bool isOutput( );\r
+    QVector< QNEConnection* >& connections( );\r
+    void setPortFlags( int f );\r
+\r
+    inline const QString& portName( ) const\r
+      { return( this->m_Name ); }\r
+    inline int portFlags( ) const\r
+      { return( this->m_PortFlags ); }\r
+    int type( ) const\r
+      { return( this->Type ); }\r
+\r
+    QNEBlock* block( ) const;\r
+    quint64 ptr( );\r
+    void setPtr( quint64 p );\r
+    bool isConnected( QNEPort* other );\r
+\r
+  protected:\r
+    QVariant itemChange( GraphicsItemChange change, const QVariant& value );\r
+\r
+  private:\r
+    QNEBlock* m_Block;\r
+    QString m_Name;\r
+    bool m_IsOutput;\r
+    QGraphicsTextItem* m_Label;\r
+    int m_Radius;\r
+    int m_Margin;\r
+    QVector< QNEConnection* > m_Connections;\r
+    int m_PortFlags;\r
+    quint64 m_Ptr;\r
+  };\r
+\r
+} // ecapseman\r
+\r
+#endif // __PIPELINEEDITOR__QNEPORT__H__\r
+\r
+// eof - $RCSfile$\r
diff --git a/appli/cpPipelineEditor/QNodesEditor.cxx b/appli/cpPipelineEditor/QNodesEditor.cxx
new file mode 100644 (file)
index 0000000..9669eea
--- /dev/null
@@ -0,0 +1,200 @@
+/* Copyright (c) 2012, STANISLAW ADASZEWSKI\r
+   All rights reserved.\r
+\r
+   Redistribution and use in source and binary forms, with or without\r
+   modification, are permitted provided that the following conditions are met:\r
+   * Redistributions of source code must retain the above copyright\r
+   notice, this list of conditions and the following disclaimer.\r
+   * Redistributions in binary form must reproduce the above copyright\r
+   notice, this list of conditions and the following disclaimer in the\r
+   documentation and/or other materials provided with the distribution.\r
+   * Neither the name of STANISLAW ADASZEWSKI nor the\r
+   names of its contributors may be used to endorse or promote products\r
+   derived from this software without specific prior written permission.\r
+\r
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND\r
+   ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\r
+   WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\r
+   DISCLAIMED. IN NO EVENT SHALL STANISLAW ADASZEWSKI BE LIABLE FOR ANY\r
+   DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r
+   (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\r
+   LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\r
+   ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
+   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\r
+   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+*/\r
+\r
+#include "QNodesEditor.h"\r
+\r
+#include <QGraphicsScene>\r
+#include <QEvent>\r
+#include <QGraphicsSceneMouseEvent>\r
+\r
+#include "QNEPort.h"\r
+#include "QNEConnection.h"\r
+#include "QNEBlock.h"\r
+\r
+// -------------------------------------------------------------------------\r
+PipelineEditor::QNodesEditor::\r
+QNodesEditor( QObject* parent )\r
+ : Superclass( parent )\r
+{\r
+  this->m_Conn = NULL;\r
+}\r
+\r
+// -------------------------------------------------------------------------\r
+PipelineEditor::QNodesEditor::\r
+~QNodesEditor( )\r
+{\r
+}\r
+\r
+// -------------------------------------------------------------------------\r
+void PipelineEditor::QNodesEditor::\r
+install( QGraphicsScene* s )\r
+{\r
+  s->installEventFilter( this );\r
+  this->m_Scene = s;\r
+}\r
+\r
+// -------------------------------------------------------------------------\r
+QGraphicsItem* PipelineEditor::QNodesEditor::\r
+itemAt( const QPointF& pos )\r
+{\r
+  QList< QGraphicsItem* > items =\r
+    this->m_Scene->items( QRectF( pos - QPointF( 1, 1 ), QSize( 3, 3 ) ) );\r
+\r
+  foreach( QGraphicsItem* item, items )\r
+    if( item->type( ) > QGraphicsItem::UserType )\r
+      return( item );\r
+  return( NULL );\r
+}\r
+\r
+// -------------------------------------------------------------------------\r
+bool PipelineEditor::QNodesEditor::\r
+eventFilter( QObject* o, QEvent* e )\r
+{\r
+  QGraphicsSceneMouseEvent* me = ( QGraphicsSceneMouseEvent* ) e;\r
+\r
+  switch ( ( int ) e->type( ) )\r
+  {\r
+  case QEvent::GraphicsThis->M_SceneMousePress:\r
+  {\r
+    switch ( ( int ) me->button( ) )\r
+    {\r
+    case Qt::LeftButton:\r
+    {\r
+      QGraphicsItem* item = this->itemAt( me->this->m_ScenePos( ) );\r
+      if( item && item->type( ) == QNEPort::Type )\r
+      {\r
+        this->m_Conn = new QNEConnection( 0, this->m_Scene );\r
+        this->m_Conn->setPort1( ( QNEPort* ) item );\r
+        this->m_Conn->setPos1( item->this->m_ScenePos( ) );\r
+        this->m_Conn->setPos2( me->this->m_ScenePos( ) );\r
+        this->m_Conn->updatePath( );\r
+\r
+        return( true );\r
+      }\r
+      else if( item && item->type( ) == QNEBlock::Type )\r
+      {\r
+        /* if( selBlock )\r
+           selBlock->setSelected( ); */\r
+        // selBlock = ( QNEBlock* ) item;\r
+\r
+      } // fi\r
+      break;\r
+    }\r
+    case Qt::RightButton:\r
+    {\r
+      QGraphicsItem* item = itemAt( me->this->m_ScenePos( ) );\r
+      if( item && ( item->type( ) == QNEConnection::Type || item->type( ) == QNEBlock::Type ) )\r
+        delete item;\r
+      // if( selBlock == ( QNEBlock* ) item )\r
+      // selBlock = 0;\r
+      break;\r
+    }\r
+    }\r
+  }\r
+  case QEvent::GraphicsThis->M_SceneMouseMove:\r
+  {\r
+    if( this->m_Conn )\r
+    {\r
+      this->m_Conn->setPos2( me->this->m_ScenePos( ) );\r
+      this->m_Conn->updatePath( );\r
+      return( true );\r
+    }\r
+    break;\r
+  }\r
+  case QEvent::GraphicsThis->M_SceneMouseRelease:\r
+  {\r
+    if( this->m_Conn && me->button( ) == Qt::LeftButton )\r
+    {\r
+      QGraphicsItem* item = itemAt( me->this->m_ScenePos( ) );\r
+      if( item && item->type( ) == QNEPort::Type )\r
+      {\r
+        QNEPort* port1 = this->m_Conn->port1( );\r
+        QNEPort* port2 = ( QNEPort* ) item;\r
+\r
+        if( port1->block( ) != port2->block( ) && port1->isOutput( ) != port2->isOutput( ) && !port1->isThis->M_Connected( port2 ) )\r
+        {\r
+          this->m_Conn->setPos2( port2->this->m_ScenePos( ) );\r
+          this->m_Conn->setPort2( port2 );\r
+          this->m_Conn->updatePath( );\r
+          this->m_Conn = NULL;\r
+          return( true );\r
+        }\r
+      }\r
+\r
+      delete this->m_Conn;\r
+      this->m_Conn = NULL;\r
+      return( true );\r
+    }\r
+    break;\r
+  }\r
+  }\r
+  return( this->Superclass::eventFilter( o, e ) );\r
+}\r
+\r
+// -------------------------------------------------------------------------\r
+void PipelineEditor::QNodesEditor::\r
+save( QDataStream& ds )\r
+{\r
+  foreach( QGraphicsItem* item, this->m_Scene->items( ) )\r
+    if( item->type( ) == QNEBlock::Type )\r
+    {\r
+      ds << item->type( );\r
+      ( ( QNEBlock* ) item )->save( ds );\r
+    }\r
+\r
+  foreach( QGraphicsItem* item, this->m_Scene->items( ) )\r
+    if( item->type( ) == QNEConnection::Type )\r
+    {\r
+      ds << item->type( );\r
+      ( ( QNEConnection* ) item )->save( ds );\r
+    }\r
+}\r
+\r
+// -------------------------------------------------------------------------\r
+void PipelineEditor::QNodesEditor::\r
+load( QDataStream& ds )\r
+{\r
+  this->m_Scene->clear( );\r
+\r
+  QMap<quint64, QNEPort*> portMap;\r
+\r
+  while ( !ds.atEnd( ) )\r
+  {\r
+    int type;\r
+    ds >> type;\r
+    if( type == QNEBlock::Type )\r
+    {\r
+      QNEBlock* block = new QNEBlock( 0, this->m_Scene );\r
+      block->load( ds, portMap );\r
+    } else if( type == QNEConnection::Type )\r
+    {\r
+      QNEConnection* this->m_Conn = new QNEConnection( 0, this->m_Scene );\r
+      this->m_Conn->load( ds, portMap );\r
+    }\r
+  }\r
+}\r
+\r
+// eof - $RCSfile$\r
diff --git a/appli/cpPipelineEditor/QNodesEditor.h b/appli/cpPipelineEditor/QNodesEditor.h
new file mode 100644 (file)
index 0000000..3e90b50
--- /dev/null
@@ -0,0 +1,73 @@
+/* Copyright (c) 2012, STANISLAW ADASZEWSKI\r
+   All rights reserved.\r
+\r
+   Redistribution and use in source and binary forms, with or without\r
+   modification, are permitted provided that the following conditions are met:\r
+   * Redistributions of source code must retain the above copyright\r
+   notice, this list of conditions and the following disclaimer.\r
+   * Redistributions in binary form must reproduce the above copyright\r
+   notice, this list of conditions and the following disclaimer in the\r
+   documentation and/or other materials provided with the distribution.\r
+   * Neither the name of STANISLAW ADASZEWSKI nor the\r
+   names of its contributors may be used to endorse or promote products\r
+   derived from this software without specific prior written permission.\r
+\r
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND\r
+   ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\r
+   WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\r
+   DISCLAIMED. IN NO EVENT SHALL STANISLAW ADASZEWSKI BE LIABLE FOR ANY\r
+   DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r
+   (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\r
+   LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\r
+   ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
+   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\r
+   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */\r
+\r
+#ifndef __PIPELINEEDITOR__QNODESEDITOR__H__\r
+#define __PIPELINEEDITOR__QNODESEDITOR__H__\r
+\r
+#include <QObject>\r
+\r
+namespace PipelineEditor\r
+{\r
+  class QGraphicsScene;\r
+  class QNEConnection;\r
+  class QGraphicsItem;\r
+  class QPointF;\r
+  class QNEBlock;\r
+\r
+  /**\r
+   */\r
+  class QNodesEditor\r
+    : public QObject\r
+  {\r
+    Q_OBJECT;\r
+\r
+  public:\r
+    typedef QNodesEditor Self;\r
+    typedef QObject      Superclass;\r
+\r
+  public:\r
+    explicit QNodesEditor( QObject* parent = 0 );\r
+    virtual ~QNodesEditor( );\r
+\r
+    void install( QGraphicsScene* s );\r
+\r
+    bool eventFilter( QObject* o, QEvent* e );\r
+\r
+    void save( QDataStream& ds );\r
+    void load( QDataStream& ds );\r
+\r
+  private:\r
+    QGraphicsItem* itemAt( const QPointF& pos );\r
+\r
+  private:\r
+    QGraphicsScene* m_Scene;\r
+    QNEConnection* m_Conn;\r
+  };\r
+\r
+} // ecapseman\r
+\r
+#endif // __PIPELINEEDITOR__QNODESEDITOR__H__\r
+\r
+// eof - $RCSfile$\r
index 7154469095791cce503aae713bad7940473805a0..531d13e2a5c596c2783eaf186f5769c7a8a5804b 100644 (file)
@@ -1,4 +1,4 @@
-#include "cpPipelineEditor.h"
+#include "QNEMainWindow.h"
 #include <cstdlib>
 #include <QApplication>
 
@@ -6,7 +6,7 @@
 int main( int argc, char* argv[] )
 {
   QApplication a( argc, argv );
-  cpPipelineEditor w;
+  QNEMainWindow w;
   w.show( );
 
   return( a.exec( ) );
index a23582ff03346c2b215456031458603c0fbfc080..5fb2707f5def3e5257054285d6805d59acd9e63f 100644 (file)
@@ -48,6 +48,8 @@ namespace cpExtensions
       typename TMatrix::const_iterator BeginEdgesRows( ) const;
       typename TMatrix::const_iterator EndEdgesRows( ) const;
 
+      void Clear( );
+
       bool HasVertexIndex( const I& index ) const;
       void InsertVertex( const I& index, V& vertex );
       V& GetVertex( const I& index );
index 9322977597fdbeed7be3208866e1f13351ad2b03..c567f39dafe16c315623f3d20f20f423df68f1fc 100644 (file)
@@ -73,6 +73,15 @@ EndEdgesRows( ) const
   return( this->m_Matrix.end( ) );
 }
 
+// -------------------------------------------------------------------------
+template< class V, class C, class I >
+void cpExtensions::DataStructures::Graph< V, C, I >::
+Clear( )
+{
+  this->m_Vertices.clear( );
+  this->m_Matrix.clear( );
+}
+
 // -------------------------------------------------------------------------
 template< class V, class C, class I >
 bool cpExtensions::DataStructures::Graph< V, C, I >::
index 4e5f51a515fa1227eff9660a2987573e3148bd69..849e7cc132cba8d8b83a57d60b772734d94f1b17 100644 (file)
@@ -105,6 +105,14 @@ GetLoadedPluginFilters( const std::string& category ) const
     return( EMPTY );
 }
 
+// -------------------------------------------------------------------------
+void cpPlugins::Interface::Workspace::
+Clear( )
+{
+  if( this->m_Graph.IsNotNull( ) )
+    this->m_Graph->Clear( );
+}
+
 // -------------------------------------------------------------------------
 cpPlugins::Interface::Workspace::
 TGraph* cpPlugins::Interface::Workspace::
@@ -201,6 +209,30 @@ GetParameters( const std::string& name ) const
     return( NULL );
 }
 
+// -------------------------------------------------------------------------
+cpPlugins::Interface::Workspace::
+TFilter* cpPlugins::Interface::Workspace::
+GetFilter( const std::string& name )
+{
+  TFilter* f =
+    dynamic_cast< TFilter* >(
+      this->m_Graph->GetVertex( name ).GetPointer( )
+      );
+  return( f );
+}
+
+// -------------------------------------------------------------------------
+const cpPlugins::Interface::Workspace::
+TFilter* cpPlugins::Interface::Workspace::
+GetFilter( const std::string& name ) const
+{
+  const TFilter* f =
+    dynamic_cast< const TFilter* >(
+      this->m_Graph->GetVertex( name ).GetPointer( )
+      );
+  return( f );
+}
+
 // -------------------------------------------------------------------------
 bool cpPlugins::Interface::Workspace::
 Reduce( const std::string& name )
@@ -219,7 +251,7 @@ Execute( )
   std::string err = "";
   for( auto sIt = sinks.begin( ); sIt != sinks.end( ); ++sIt )
   {
-    std::string lerr = this->Execute( *sIt );
+    std::string lerr = this->Execute( *sIt, NULL );
     if( lerr != "" )
       err += lerr + std::string( "\n" );
 
@@ -229,7 +261,7 @@ Execute( )
 
 // -------------------------------------------------------------------------
 std::string cpPlugins::Interface::Workspace::
-Execute( const std::string& name )
+Execute( const std::string& name, QWidget* p )
 {
   // Get filter
   TFilter* f =
@@ -243,7 +275,16 @@ Execute( const std::string& name )
       );
 
   // Execute and return
-  return( f->Update( ) );
+  if( p != NULL )
+  {
+    auto diag_res = f->ExecConfigurationDialog( p );
+    if( diag_res == TFilter::DialogResult_NoModal )
+      return( f->Update( ) );
+    else
+      return( "" );
+  }
+  else
+    return( f->Update( ) );
 }
 
 // -------------------------------------------------------------------------
index 9bad734953c89f98b01e526db4aa21ad9af13ef2..6cf157d37c7921f1e013310be4050871cd9553bd 100644 (file)
@@ -9,6 +9,9 @@
 #include <set>
 #include <string>
 
+// Some forward declarations
+class QWidget;
+
 namespace cpPlugins
 {
   namespace Interface
@@ -52,6 +55,7 @@ namespace cpPlugins
       std::string SaveWorkspace( const std::string& fname ) const;
 
       // Graph management
+      void Clear( );
       TGraph* GetGraph( );
       const TGraph* GetGraph( ) const;
       bool CreateFilter( const std::string& filter, const std::string& name );
@@ -62,13 +66,15 @@ namespace cpPlugins
         );
       TParameters* GetParameters( const std::string& name );
       const TParameters* GetParameters( const std::string& name ) const;
+      TFilter* GetFilter( const std::string& name );
+      const TFilter* GetFilter( const std::string& name ) const;
 
       // Graph reduction
       bool Reduce( const std::string& name );
 
       // Pipeline execution
       std::string Execute( );
-      std::string Execute( const std::string& name );
+      std::string Execute( const std::string& name, QWidget* p = NULL );
 
     protected:
       void _UpdateLoadedPluginsInformation( );
index 0651011389400e09b01604fc174c82d9275e1125..e14a44ef7e4c94ee1e286128dcd9c8dd37ebd614 100644 (file)
@@ -8,6 +8,8 @@ LoadWorkspace( const std::string& fname )
   TiXmlDocument* doc = new TiXmlDocument( fname.c_str( ) );
   doc->LoadFile( );
   TiXmlElement* root = doc->RootElement( );
+  if( root == NULL )
+    return( "cpPlugins::Interface::Workspace: No valid file" );
   if( std::string( root->Value( ) ) != "cpPlugins_Workspace" )
     return( "cpPlugins::Interface::Workspace: No valid workspace" );
   std::stringstream err;
@@ -233,7 +235,43 @@ LoadWorkspace( const std::string& fname )
 std::string cpPlugins::Interface::Workspace::
 SaveWorkspace( const std::string& fname ) const
 {
-  return( "" );
+  std::stringstream err;
+  TiXmlDocument* doc = new TiXmlDocument( );
+  TiXmlElement* root = new TiXmlElement( "cpPlugins_Workspace" );
+
+  // Save plugins
+  for(
+    auto plugIt = this->m_LoadedPlugins.begin( );
+    plugIt != this->m_LoadedPlugins.end( );
+    ++plugIt
+    )
+  {
+    TiXmlElement* plugin = new TiXmlElement( "plugins" );
+    plugin->SetAttribute( "filename", plugIt->c_str( ) );
+    root->LinkEndChild( plugin );
+
+  } // rof
+
+  // Save vertices
+  auto vIt = this->m_Graph->BeginVertices( );
+  for( ; vIt != this->m_Graph->EndVertices( ); ++vIt )
+  {
+    auto filter = dynamic_cast< TFilter* >( vIt->second.GetPointer( ) );
+    auto data = dynamic_cast< TData* >( vIt->second.GetPointer( ) );
+    if( filter != NULL )
+    {
+    }
+    else if( data != NULL )
+    {
+    } // fi
+
+  } // rof
+
+  // Physical write and return
+  doc->LinkEndChild( root );
+  doc->SaveFile( fname.c_str( ) );
+  delete doc;
+  return( err.str( ) );
 }
 
 // eof - $RCSfile$
index a7c6687c199b1cbc9c80f8695f4843e3971f1f41..8866f7d2e6add18045f66f659667aeb40c916cd8 100644 (file)
@@ -106,7 +106,7 @@ _GenerateData( )
       r = "ImageReader: Could not CreateImageIO for \"" + names[ 0 ] + "\"";
   }
   else
-    r = "No image files given";
+    r = "ImageReader: No image files given";
   return( r );
 }