--- /dev/null
+#include <cpBaseQtApplication/Pipeline/Block.h>\r
+\r
+#include <QDialog>\r
+#include <QFontMetrics>\r
+#include <QGraphicsScene>\r
+#include <QGraphicsSceneContextMenuEvent>\r
+#include <QGraphicsWidget>\r
+#include <QMenu>\r
+#include <QMessageBox>\r
+#include <QPainter>\r
+#include <QPen>\r
+#include <QStyleOptionGraphicsItem>\r
+\r
+#include <cpBaseQtApplication/Blocker.h>\r
+#include <cpBaseQtApplication/Pipeline/Port.h>\r
+#include <cpBaseQtApplication/Pipeline/Connection.h>\r
+#include <cpPlugins/Pipeline/Widget.h>\r
+#include <cpPlugins/Pipeline/Events.h>\r
+\r
+// -------------------------------------------------------------------------\r
+QColor cpBaseQtApplication::Pipeline::Block::\r
+SelectedAndUpdated = Qt::green;\r
+QColor cpBaseQtApplication::Pipeline::Block::\r
+NotSelectedAndUpdated = Qt::blue;\r
+QColor cpBaseQtApplication::Pipeline::Block::\r
+SelectedAndNotUpdated = Qt::yellow;\r
+QColor cpBaseQtApplication::Pipeline::Block::\r
+NotSelectedAndNotUpdated = Qt::lightGray;\r
+\r
+// -------------------------------------------------------------------------\r
+void cpBaseQtApplication::Pipeline::Block::_TFilterObserver::\r
+Execute( const itk::Object* c, const itk::EventObject& e )\r
+{\r
+ typedef cpPlugins::Pipeline::Events::Modified _TModified;\r
+ const _TModified* mod_evt = dynamic_cast< const _TModified* >( &e );\r
+ if( mod_evt != NULL )\r
+ {\r
+ std::stringstream str;\r
+ str\r
+ << "(" << mod_evt->Time << "/"\r
+ << double( mod_evt->Span ) / double( 1000 ) << "s)";\r
+ this->ObservedBlock->setInfoPort( str.str( ).c_str( ) );\r
+\r
+ } // fi\r
+}\r
+\r
+// -------------------------------------------------------------------------\r
+cpBaseQtApplication::Pipeline::Block::\r
+Block(\r
+ TFilter* filter,\r
+ QGraphicsItem* parent, QGraphicsScene* scene\r
+ )\r
+ : Superclass( parent, scene ),\r
+ m_HorzMargin( 20 ),\r
+ m_VertMargin( 5 ),\r
+ m_NamePort( NULL ),\r
+ m_InfoPort( NULL ),\r
+ m_Filter( filter )\r
+{\r
+ QPainterPath p;\r
+ p.addRoundedRect( -50, -15, 100, 30, 5, 5 );\r
+\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
+\r
+ this->m_Width = this->m_HorzMargin;\r
+ this->m_Height = this->m_VertMargin;\r
+\r
+ // Configure names\r
+ this->setNamePort( filter->GetName( ) );\r
+ this->setInfoPort( "(-/-)" );\r
+ this->_setTypeInfo(\r
+ (\r
+ std::string( this->m_Filter->GetClassCategory( ) ) +\r
+ std::string( "::" ) +\r
+ std::string( this->m_Filter->GetClassName( ) )\r
+ ).c_str( )\r
+ );\r
+\r
+ // Add input ports\r
+ auto inputs = this->m_Filter->GetInputsNames( );\r
+ for( auto iIt = inputs.begin( ); iIt != inputs.end( ); ++iIt )\r
+ {\r
+ this->addInputPort(\r
+ iIt->c_str( ),\r
+ this->m_Filter->IsInputMultiple( iIt->c_str( ) )\r
+ );\r
+\r
+ } // rof\r
+\r
+ // Add output ports\r
+ auto outputs = this->m_Filter->GetOutputsNames( );\r
+ for( auto oIt = outputs.begin( ); oIt != outputs.end( ); ++oIt )\r
+ this->addOutputPort( oIt->c_str( ) );\r
+\r
+ // Add obvserver\r
+ this->m_FilterObserver = _TFilterObserver::New( );\r
+ this->m_FilterObserver->ObservedBlock = this;\r
+ this->m_FilterObserverId =\r
+ this->m_Filter->AddObserver(\r
+ cpPlugins::Pipeline::Events::Modified( ), this->m_FilterObserver\r
+ );\r
+}\r
+\r
+// -------------------------------------------------------------------------\r
+cpBaseQtApplication::Pipeline::Block::\r
+~Block( )\r
+{\r
+ this->m_Filter->RemoveObserver( this->m_FilterObserverId );\r
+}\r
+\r
+// -------------------------------------------------------------------------\r
+cpBaseQtApplication::Pipeline::Block::\r
+TFilter* cpBaseQtApplication::Pipeline::Block::\r
+filter( )\r
+{\r
+ return( this->m_Filter );\r
+}\r
+\r
+// -------------------------------------------------------------------------\r
+const cpBaseQtApplication::Pipeline::Block::\r
+TFilter* cpBaseQtApplication::Pipeline::Block::\r
+filter( ) const\r
+{\r
+ return( this->m_Filter );\r
+}\r
+\r
+// -------------------------------------------------------------------------\r
+void cpBaseQtApplication::Pipeline::Block::\r
+setNamePort( const QString& txt )\r
+{\r
+ if( this->m_NamePort == NULL )\r
+ this->m_NamePort = new NamePort( this );\r
+ this->m_NamePort->setName( txt );\r
+ this->_configPort( this->m_NamePort );\r
+}\r
+\r
+// -------------------------------------------------------------------------\r
+void cpBaseQtApplication::Pipeline::Block::\r
+setInfoPort( const QString& txt )\r
+{\r
+ if( this->m_InfoPort == NULL )\r
+ this->m_InfoPort = new InfoPort( this );\r
+ this->m_InfoPort->setName( txt );\r
+ this->_configPort( this->m_InfoPort );\r
+}\r
+\r
+// -------------------------------------------------------------------------\r
+cpBaseQtApplication::Pipeline::InputPort*\r
+cpBaseQtApplication::Pipeline::Block::\r
+addInputPort( const QString& txt, bool multiple )\r
+{\r
+ InputPort* ip = new InputPort( this, multiple );\r
+ ip->setExtendedName( "" );\r
+ ip->setName( txt );\r
+ this->m_InputPorts[ txt.toStdString( ) ] = ip;\r
+ this->_configPort( ip );\r
+ return( ip );\r
+}\r
+\r
+// -------------------------------------------------------------------------\r
+cpBaseQtApplication::Pipeline::OutputPort*\r
+cpBaseQtApplication::Pipeline::Block::\r
+addOutputPort( const QString& txt )\r
+{\r
+ OutputPort* op = new OutputPort( this );\r
+ op->setExtendedName( "" );\r
+ op->setName( txt );\r
+ this->m_OutputPorts[ txt.toStdString( ) ] = op;\r
+ this->_configPort( op );\r
+ return( op );\r
+}\r
+\r
+// -------------------------------------------------------------------------\r
+cpBaseQtApplication::Pipeline::InputPort*\r
+cpBaseQtApplication::Pipeline::Block::\r
+inputPort( const QString& txt )\r
+{\r
+ auto i = this->m_InputPorts.find( txt.toStdString( ) );\r
+ if( i != this->m_InputPorts.end( ) )\r
+ return( i->second );\r
+ else\r
+ return( NULL );\r
+}\r
+\r
+// -------------------------------------------------------------------------\r
+cpBaseQtApplication::Pipeline::OutputPort*\r
+cpBaseQtApplication::Pipeline::Block::\r
+outputPort( const QString& txt )\r
+{\r
+ auto o = this->m_OutputPorts.find( txt.toStdString( ) );\r
+ if( o != this->m_OutputPorts.end( ) )\r
+ return( o->second );\r
+ else\r
+ return( NULL );\r
+}\r
+\r
+// -------------------------------------------------------------------------\r
+QString cpBaseQtApplication::Pipeline::Block::\r
+namePort( ) const\r
+{\r
+ return( this->m_NamePort->name( ) );\r
+}\r
+\r
+// -------------------------------------------------------------------------\r
+const cpBaseQtApplication::Pipeline::InputPort*\r
+cpBaseQtApplication::Pipeline::Block::\r
+inputPort( const QString& txt ) const\r
+{\r
+ auto i = this->m_InputPorts.find( txt.toStdString( ) );\r
+ if( i != this->m_InputPorts.end( ) )\r
+ return( i->second );\r
+ else\r
+ return( NULL );\r
+}\r
+\r
+// -------------------------------------------------------------------------\r
+const cpBaseQtApplication::Pipeline::OutputPort*\r
+cpBaseQtApplication::Pipeline::Block::\r
+outputPort( const QString& txt ) const\r
+{\r
+ auto o = this->m_OutputPorts.find( txt.toStdString( ) );\r
+ if( o != this->m_OutputPorts.end( ) )\r
+ return( o->second );\r
+ else\r
+ return( NULL );\r
+}\r
+\r
+\r
+// -------------------------------------------------------------------------\r
+bool cpBaseQtApplication::Pipeline::Block::\r
+connectOutputPortSlot( QObject* receiver, const char* slot )\r
+{\r
+ bool ok = true;\r
+ for( auto p : this->m_OutputPorts )\r
+ ok &= QObject::connect(\r
+ p.second, SIGNAL( viewData( const std::string&, bool ) ),\r
+ receiver, slot\r
+ );\r
+ return( ok );\r
+}\r
+\r
+// -------------------------------------------------------------------------\r
+void cpBaseQtApplication::Pipeline::Block::\r
+setPos( const QPointF& pos )\r
+{\r
+ this->m_Filter->SetViewCoords( pos.x( ), pos.y( ) );\r
+ this->Superclass::setPos( pos );\r
+}\r
+\r
+// -------------------------------------------------------------------------\r
+void cpBaseQtApplication::Pipeline::Block::\r
+setPos( qreal x, qreal y )\r
+{\r
+ this->m_Filter->SetViewCoords( x, y );\r
+ this->Superclass::setPos( x, y );\r
+}\r
+\r
+// -------------------------------------------------------------------------\r
+void cpBaseQtApplication::Pipeline::Block::\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
+QVariant cpBaseQtApplication::Pipeline::Block::\r
+itemChange( GraphicsItemChange change, const QVariant& value )\r
+{\r
+ return( value );\r
+}\r
+\r
+// -------------------------------------------------------------------------\r
+void cpBaseQtApplication::Pipeline::Block::\r
+_setTypeInfo( const QString& txt )\r
+{\r
+ this->setToolTip( txt );\r
+}\r
+\r
+// -------------------------------------------------------------------------\r
+void cpBaseQtApplication::Pipeline::Block::\r
+_configPort( Port* port )\r
+{\r
+ port->setBlock( this );\r
+\r
+ QFontMetrics fm( this->scene( )->font( ) );\r
+ this->m_Width = 0;\r
+ foreach( QGraphicsItem* i, this->children( ) )\r
+ {\r
+ Port* p = dynamic_cast< Port* >( i );\r
+ if( p == NULL )\r
+ continue;\r
+ int w = fm.width( p->name( ) ) + ( 4 * p->radius( ) );\r
+ if( w > this->m_Width - this->m_HorzMargin )\r
+ this->m_Width = w + this->m_HorzMargin;\r
+\r
+ } // rof\r
+ int h = fm.height( );\r
+ this->m_Height = this->m_InputPorts.size( ) + this->m_OutputPorts.size( );\r
+ this->m_Height += 4;\r
+ this->m_Height *= h;\r
+\r
+ QPainterPath pth;\r
+ pth.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( pth );\r
+\r
+ int y = -this->m_Height / 2 + this->m_VertMargin + port->radius( );\r
+ foreach( QGraphicsItem* i, this->children( ) )\r
+ {\r
+ Port* p = dynamic_cast< Port* >( i );\r
+ if( p == NULL )\r
+ continue;\r
+\r
+ if(\r
+ dynamic_cast< NamePort* >( i ) != NULL ||\r
+ dynamic_cast< InfoPort* >( i ) != NULL\r
+ )\r
+ {\r
+ i->setPos( -this->m_Width / 2 + port->radius( ), y );\r
+ y += h >> 1;\r
+ }\r
+ else if( dynamic_cast< InputPort* >( i ) != NULL )\r
+ i->setPos( -this->m_Width / 2 - 2 * port->radius( ), y );\r
+ else if( dynamic_cast< OutputPort* >( i ) != NULL )\r
+ i->setPos( this->m_Width / 2, y );\r
+ y += h;\r
+\r
+ } // rof\r
+}\r
+\r
+// -------------------------------------------------------------------------\r
+void cpBaseQtApplication::Pipeline::Block::\r
+mouseReleaseEvent( QGraphicsSceneMouseEvent* evt )\r
+{\r
+ if( this->m_Filter.IsNotNull( ) )\r
+ this->m_Filter->SetViewCoords(\r
+ this->scenePos( ).x( ),\r
+ this->scenePos( ).y( )\r
+ );\r
+ this->Superclass::mouseReleaseEvent( evt );\r
+}\r
+\r
+// -------------------------------------------------------------------------\r
+void cpBaseQtApplication::Pipeline::Block::\r
+contextMenuEvent( QGraphicsSceneContextMenuEvent* evt )\r
+{\r
+ QMenu menu;\r
+ QAction* configureAction = menu.addAction( "Configure" );\r
+ QAction* updateAction = menu.addAction( "Update" );\r
+ auto widget =\r
+ dynamic_cast< cpPlugins::Pipeline::Widget* >(\r
+ this->m_Filter.GetPointer( )\r
+ );\r
+ QAction* enableAction = NULL;\r
+ if( widget != NULL )\r
+ enableAction =\r
+ menu.addAction( ( widget->GetEnabled( ) )? "Disable": "Enable" );\r
+\r
+ QAction* selectedAction = menu.exec( evt->screenPos( ) );\r
+ if( selectedAction == configureAction )\r
+ {\r
+ auto dlg = this->m_Filter->CreateQDialog( );\r
+ if( dlg != NULL )\r
+ dlg->exec( );\r
+ }\r
+ else if( selectedAction == enableAction )\r
+ {\r
+ if( widget != NULL )\r
+ widget->SetEnabled( !( widget->GetEnabled( ) ) );\r
+ }\r
+ else if( selectedAction == updateAction )\r
+ {\r
+ cpBaseQtApplication::Blocker blocker;\r
+ blocker.block( );\r
+ try\r
+ {\r
+ this->m_Filter->Update( );\r
+ blocker.unblock( );\r
+ }\r
+ catch( std::exception& err )\r
+ {\r
+ blocker.unblock( );\r
+ QMessageBox::critical(\r
+ NULL,\r
+ QMessageBox::tr( "Error updating filter" ),\r
+ QMessageBox::tr( err.what( ) )\r
+ );\r
+\r
+ } // yrt\r
+\r
+ } // fi\r
+}\r
+\r
+// eof - $RCSfile$\r