#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include // ------------------------------------------------------------------------- #define cpBaseQtApplication_Editor_Callback_SWITCH( E, e ) \ case QEvent::GraphicsScene##E: \ { \ QGraphicsScene##E##Event* evt = \ dynamic_cast< QGraphicsScene##E##Event* >( e ); \ if( evt != NULL ) \ this->_##E##_cbk( evt ); \ } \ break; // ------------------------------------------------------------------------- #define cpBaseQtApplication_Editor_Callback_CODE( E ) \ void cpBaseQtApplication::Editor::_##E##_cbk( QGraphicsScene##E##Event* evt ) // ------------------------------------------------------------------------- cpBaseQtApplication::Editor:: Editor( QObject* parent ) : Superclass( parent ), m_ActualConnection( NULL ), m_Workspace( NULL ), m_MainWindow( NULL ) { // Infere MainWindow QObject* pIt = parent; while( pIt != NULL && dynamic_cast< MainWindow* >( pIt ) == NULL ) pIt = pIt->parent( ); this->m_MainWindow = dynamic_cast< MainWindow* >( pIt ); } // ------------------------------------------------------------------------- cpBaseQtApplication::Editor:: ~Editor( ) { } // ------------------------------------------------------------------------- cpBaseQtApplication::Editor:: TWorkspace* cpBaseQtApplication::Editor:: workspace( ) { return( this->m_Workspace ); } // ------------------------------------------------------------------------- const cpBaseQtApplication::Editor:: TWorkspace* cpBaseQtApplication::Editor:: workspace( ) const { return( this->m_Workspace ); } // ------------------------------------------------------------------------- void cpBaseQtApplication::Editor:: setWorkspace( TWorkspace* ws ) { this->m_Workspace = ws; this->redrawWorkspace( ); } // ------------------------------------------------------------------------- void cpBaseQtApplication::Editor:: redrawWorkspace( ) { this->clear( ); if( this->m_Workspace.IsNull( ) ) return; // Create blocks std::map< std::string, Block* > blocks; auto filters = this->m_Workspace->GetFiltersNames( ); for( auto f = filters.begin( ); f != filters.end( ); ++f ) { auto obj = this->m_Workspace->GetFilter( *f ); blocks[ *f ] = this->_createBlock( obj, f->c_str( ), QPointF( obj->GetViewX( ), obj->GetViewY( ) ) ); } // rof // Create edges for( auto f = filters.begin( ); f != filters.end( ); ++f ) { auto bf = blocks[ *f ]; for( auto e = filters.begin( ); e != filters.end( ); ++e ) { auto be = blocks[ *e ]; auto edges = this->m_Workspace->GetConnections( *f, *e ); for( auto c = edges.begin( ); c != edges.end( ); ++c ) { OutputPort* op = bf->outputPort( c->first.c_str( ) ); InputPort* ip = be->inputPort( c->second.c_str( ) ); if( op == NULL || ip == NULL ) continue; Connection* conn = new Connection( 0, this->m_Scene ); conn->setPort1( op ); conn->setPort2( ip ); conn->updatePosFromPorts( ); conn->updatePath( ); } // rof } // rof } // rof // Exposed inputs const auto& exp_inputs = this->m_Workspace->GetExposedInputs( ); for( auto eIt = exp_inputs.begin( ); eIt != exp_inputs.end( ); ++eIt ) { auto bl = blocks[ eIt->second.first ]; auto ip = bl->inputPort( eIt->second.second.c_str( ) ); ip->setExtend( true ); ip->setExtendedName( eIt->first.c_str( ) ); } // rof // Exposed outputs const auto& exp_outputs = this->m_Workspace->GetExposedOutputs( ); for( auto eIt = exp_outputs.begin( ); eIt != exp_outputs.end( ); ++eIt ) { auto bl = blocks[ eIt->second.first ]; auto op = bl->outputPort( eIt->second.second.c_str( ) ); op->setExtend( true ); op->setExtendedName( eIt->first.c_str( ) ); } // rof } // ------------------------------------------------------------------------- std::string cpBaseQtApplication::Editor:: createFilter( const std::string& category, const std::string& filter, const QPointF& pnt ) { std::string name = filter; while( this->m_Workspace->HasFilter( name ) ) name += std::string( "_" ); auto obj = this->m_Workspace->CreateFilter( category, filter, name ); if( obj != NULL ) { this->_createBlock( obj, name.c_str( ), pnt ); return( name ); } else return( "" ); } // ------------------------------------------------------------------------- bool cpBaseQtApplication::Editor:: deleteFilter( const std::string& name ) { if( this->m_Workspace.IsNotNull( ) ) return( this->m_Workspace->RemoveFilter( name ) ); else return( false ); } // ------------------------------------------------------------------------- bool cpBaseQtApplication::Editor:: deleteConnection( const std::string& src, const std::string& des, const std::string& in, const std::string& out ) { if( this->m_Workspace.IsNotNull( ) ) { this->m_Workspace->Disconnect( src, des, in, out ); return( true ); } else return( false ); } // ------------------------------------------------------------------------- void cpBaseQtApplication::Editor:: clear( ) { this->m_Scene->clear( ); auto views = this->m_Scene->views( ); for( auto i = views.begin( ); i != views.end( ); ++i ) ( *i )->viewport( )->update( ); } // ------------------------------------------------------------------------- void cpBaseQtApplication::Editor:: install( QGraphicsScene* s ) { s->installEventFilter( this ); this->m_Scene = s; } // ------------------------------------------------------------------------- QGraphicsItem* cpBaseQtApplication::Editor:: itemAt( const QPointF& pos ) { QList< QGraphicsItem* > items = this->m_Scene->items( QRectF( pos - QPointF( 1, 1 ), QSize( 3, 3 ) ) ); foreach( QGraphicsItem* item, items ) if( item->type( ) > QGraphicsItem::UserType ) return( item ); return( NULL ); } // ------------------------------------------------------------------------- cpBaseQtApplication::Block* cpBaseQtApplication::Editor:: _createBlock( TFilter* f, const QString& name, const QPointF& pnt ) { if( f == NULL ) return( NULL ); Block* b = new Block( f, name, 0, this->m_Scene ); b->setEditor( this ); b->setPos( pnt ); return( b ); } // ------------------------------------------------------------------------- bool cpBaseQtApplication::Editor:: eventFilter( QObject* o, QEvent* e ) { // Event type switch( int( e->type( ) ) ) { cpBaseQtApplication_Editor_Callback_SWITCH( ContextMenu, e ); cpBaseQtApplication_Editor_Callback_SWITCH( DragEnter, e ); cpBaseQtApplication_Editor_Callback_SWITCH( DragLeave, e ); cpBaseQtApplication_Editor_Callback_SWITCH( DragMove, e ); cpBaseQtApplication_Editor_Callback_SWITCH( Drop, e ); cpBaseQtApplication_Editor_Callback_SWITCH( Help, e ); cpBaseQtApplication_Editor_Callback_SWITCH( HoverEnter, e ); cpBaseQtApplication_Editor_Callback_SWITCH( HoverLeave, e ); cpBaseQtApplication_Editor_Callback_SWITCH( HoverMove, e ); cpBaseQtApplication_Editor_Callback_SWITCH( MouseDoubleClick, e ); cpBaseQtApplication_Editor_Callback_SWITCH( MouseMove, e ); cpBaseQtApplication_Editor_Callback_SWITCH( MousePress, e ); cpBaseQtApplication_Editor_Callback_SWITCH( MouseRelease, e ); cpBaseQtApplication_Editor_Callback_SWITCH( Move, e ); cpBaseQtApplication_Editor_Callback_SWITCH( Resize, e ); cpBaseQtApplication_Editor_Callback_SWITCH( Wheel, e ); default: break; } // hctiws return( this->Superclass::eventFilter( o, e ) ); } // ------------------------------------------------------------------------- void cpBaseQtApplication::Editor:: updateFilter( const std::string& filter_name ) { if( this->m_MainWindow != NULL ) this->m_MainWindow->updateFilter( filter_name ); } // ------------------------------------------------------------------------- void cpBaseQtApplication::Editor:: showData( const std::string& name, const std::string& port ) { if( this->m_MainWindow != NULL ) this->m_MainWindow->showData( name, port ); } // ------------------------------------------------------------------------- void cpBaseQtApplication::Editor:: hideData( const std::string& name, const std::string& port ) { /* TODO if( this->m_MainWindow != NULL ) this->m_MainWindow->hideData( name, port ); */ } // ------------------------------------------------------------------------- void cpBaseQtApplication::Editor:: dataProperties( const std::string& name, const std::string& port ) { if( this->m_MainWindow != NULL ) this->m_MainWindow->dataProperties( name, port ); } // ------------------------------------------------------------------------- cpBaseQtApplication_Editor_Callback_CODE( ContextMenu ) { } // ------------------------------------------------------------------------- cpBaseQtApplication_Editor_Callback_CODE( DragEnter ) { } // ------------------------------------------------------------------------- cpBaseQtApplication_Editor_Callback_CODE( DragLeave ) { } // ------------------------------------------------------------------------- cpBaseQtApplication_Editor_Callback_CODE( DragMove ) { } // ------------------------------------------------------------------------- cpBaseQtApplication_Editor_Callback_CODE( Drop ) { } // ------------------------------------------------------------------------- cpBaseQtApplication_Editor_Callback_CODE( Help ) { } // ------------------------------------------------------------------------- cpBaseQtApplication_Editor_Callback_CODE( HoverEnter ) { } // ------------------------------------------------------------------------- cpBaseQtApplication_Editor_Callback_CODE( HoverLeave ) { } // ------------------------------------------------------------------------- cpBaseQtApplication_Editor_Callback_CODE( HoverMove ) { } // ------------------------------------------------------------------------- cpBaseQtApplication_Editor_Callback_CODE( MouseDoubleClick ) { // Get clicked item QGraphicsItem* item = this->itemAt( evt->scenePos( ) ); if( item == NULL ) return; Block* block = dynamic_cast< Block* >( item ); Port* port = dynamic_cast< Port* >( item ); Connection* conn = dynamic_cast< Connection* >( item ); if( block != NULL && evt->button( ) == Qt::LeftButton ) { if( evt->modifiers( ) == Qt::NoModifier ) { QString old_name = block->namePort( ); bool ok; QString new_name = QInputDialog::getText( dynamic_cast< QWidget* >( this->parent( ) ), "Change filter name", "Filter name:", QLineEdit::Normal, old_name, &ok ); if( ok && !new_name.isEmpty( ) && old_name != new_name ) { if( this->m_Workspace->RenameFilter( old_name.toStdString( ), new_name.toStdString( ) ) ) block->setNamePort( new_name ); } // fi } // fi } else if( port != NULL && evt->button( ) == Qt::LeftButton ) { if( evt->modifiers( ) == Qt::ControlModifier ) { port->setExtend( !( port->isExtended( ) ) ); InputPort* in_port = dynamic_cast< InputPort* >( port ); OutputPort* out_port = dynamic_cast< OutputPort* >( port ); if( port->isExtended( ) ) { auto ename = port->extendedName( ).toStdString( ); if( ename == "" ) { auto fname = port->block( )->namePort( ).toStdString( ); auto pname = port->name( ).toStdString( ); ename = pname + std::string( "@" ) + fname; port->setExtendedName( ename.c_str( ) ); } // fi if( in_port != NULL ) this->m_Workspace->ExposeInput( in_port->extendedName( ).toStdString( ), in_port->block( )->namePort( ).toStdString( ), in_port->name( ).toStdString( ) ); else if( out_port != NULL ) this->m_Workspace->ExposeOutput( out_port->extendedName( ).toStdString( ), out_port->block( )->namePort( ).toStdString( ), out_port->name( ).toStdString( ) ); } else { if( in_port != NULL ) this->m_Workspace->HideInput( in_port->extendedName( ).toStdString( ) ); else if( out_port != NULL ) this->m_Workspace->HideOutput( out_port->extendedName( ).toStdString( ) ); } // fi } else if( evt->modifiers( ) == Qt::NoModifier ) { if( port->isExtended( ) ) { QString old_name = port->extendedName( ); bool ok; QString new_name = QInputDialog::getText( dynamic_cast< QWidget* >( this->parent( ) ), "Change filter name", "Filter name:", QLineEdit::Normal, old_name, &ok ); if( ok && !new_name.isEmpty( ) && old_name != new_name ) { InputPort* in_port = dynamic_cast< InputPort* >( port ); OutputPort* out_port = dynamic_cast< OutputPort* >( port ); bool success = false; if( in_port != NULL ) success = this->m_Workspace->RenameExposedInput( old_name.toStdString( ), new_name.toStdString( ) ); else if( out_port != NULL ) success = this->m_Workspace->RenameExposedOutput( old_name.toStdString( ), new_name.toStdString( ) ); if( success ) { port->setExtendedName( new_name ); this->m_Scene->update( ); } // fi } // fi } // fi } // fi } // fi } // ------------------------------------------------------------------------- cpBaseQtApplication_Editor_Callback_CODE( MouseMove ) { if( this->m_ActualConnection != NULL ) { if( this->m_ActualConnection->port1( ) == NULL ) this->m_ActualConnection->setPos1( evt->scenePos( ) ); else if( this->m_ActualConnection->port2( ) == NULL ) this->m_ActualConnection->setPos2( evt->scenePos( ) ); this->m_ActualConnection->updatePath( ); } // fi } // ------------------------------------------------------------------------- cpBaseQtApplication_Editor_Callback_CODE( MousePress ) { InputPort* in_port = dynamic_cast< InputPort* >( this->itemAt( evt->scenePos( ) ) ); OutputPort* out_port = dynamic_cast< OutputPort* >( this->itemAt( evt->scenePos( ) ) ); if( in_port == NULL && out_port == NULL ) return; switch( evt->button( ) ) { case Qt::LeftButton: { if( out_port != NULL ) { if( out_port->block( ) != NULL ) { // Start new connection this->m_ActualConnection = new Connection( 0, this->m_Scene ); this->m_ActualConnection->setPort1( out_port ); this->m_ActualConnection->setPos1( out_port->scenePos( ) ); this->m_ActualConnection->setPos2( evt->scenePos( ) ); this->m_ActualConnection->updatePosFromPorts( ); this->m_ActualConnection->updatePath( ); } // fi } // fi } break; default: break; } // hctiws } // ------------------------------------------------------------------------- cpBaseQtApplication_Editor_Callback_CODE( MouseRelease ) { if( this->m_ActualConnection == NULL ) return; switch( evt->button( ) ) { case Qt::LeftButton: { InputPort* in = dynamic_cast< InputPort* >( this->itemAt( evt->scenePos( ) ) ); OutputPort* out = dynamic_cast< OutputPort* >( this->m_ActualConnection->port1( ) ); if( in != NULL && out != NULL ) { if( in->block( ) != out->block( ) && ( !in->hasConnection( ) || in->isMultiple( ) ) && !in->isConnected( out ) && !out->isExtended( ) ) { std::string d_filter = in->block( )->namePort( ).toStdString( ); std::string o_filter = out->block( )->namePort( ).toStdString( ); std::string d_port = in->name( ).toStdString( ); std::string o_port = out->name( ).toStdString( ); try { this->m_Workspace->Connect( o_filter, d_filter, o_port, d_port ); this->m_ActualConnection->setPos2( in->scenePos( ) ); this->m_ActualConnection->setPort2( in ); this->m_ActualConnection->updatePosFromPorts( ); this->m_ActualConnection->updatePath( ); } catch( std::exception& err ) { delete this->m_ActualConnection; QMessageBox::critical( NULL, QMessageBox::tr( "Error connecting ports" ), QMessageBox::tr( err.what( ) ) ); } // yrt } else delete this->m_ActualConnection; } else delete this->m_ActualConnection; this->m_ActualConnection = NULL; } break; default: break; } // hctisw } // ------------------------------------------------------------------------- cpBaseQtApplication_Editor_Callback_CODE( Move ) { } // ------------------------------------------------------------------------- cpBaseQtApplication_Editor_Callback_CODE( Resize ) { } // ------------------------------------------------------------------------- cpBaseQtApplication_Editor_Callback_CODE( Wheel ) { } // eof - $RCSfile$