1 #include <cpBaseQtApplication/Editor.h>
\r
3 #include <QGraphicsScene>
\r
5 #include <QGraphicsSceneContextMenuEvent>
\r
6 #include <QGraphicsSceneDragDropEvent>
\r
7 #include <QGraphicsSceneHelpEvent>
\r
8 #include <QGraphicsSceneHoverEvent>
\r
9 #include <QGraphicsSceneMouseEvent>
\r
10 #include <QGraphicsSceneMoveEvent>
\r
11 #include <QGraphicsSceneResizeEvent>
\r
12 #include <QGraphicsSceneWheelEvent>
\r
13 #include <QGraphicsView>
\r
14 #include <QInputDialog>
\r
15 #include <QMessageBox>
\r
17 #include <cpBaseQtApplication/Port.h>
\r
18 #include <cpBaseQtApplication/Connection.h>
\r
19 #include <cpBaseQtApplication/Block.h>
\r
20 #include <cpBaseQtApplication/MainWindow.h>
\r
22 // -------------------------------------------------------------------------
\r
23 #define cpBaseQtApplication_Editor_Callback_SWITCH( E, e ) \
\r
24 case QEvent::GraphicsScene##E: \
\r
26 QGraphicsScene##E##Event* evt = \
\r
27 dynamic_cast< QGraphicsScene##E##Event* >( e ); \
\r
29 this->_##E##_cbk( evt ); \
\r
33 // -------------------------------------------------------------------------
\r
34 #define cpBaseQtApplication_Editor_Callback_CODE( E ) \
\r
35 void cpBaseQtApplication::Editor::_##E##_cbk( QGraphicsScene##E##Event* evt )
\r
37 // -------------------------------------------------------------------------
\r
38 cpBaseQtApplication::Editor::
\r
39 Editor( QObject* parent )
\r
40 : Superclass( parent ),
\r
41 m_ActualConnection( NULL ),
\r
42 m_Workspace( NULL ),
\r
43 m_MainWindow( NULL )
\r
45 // Infere MainWindow
\r
46 QObject* pIt = parent;
\r
47 while( pIt != NULL && dynamic_cast< MainWindow* >( pIt ) == NULL )
\r
48 pIt = pIt->parent( );
\r
49 this->m_MainWindow = dynamic_cast< MainWindow* >( pIt );
\r
52 // -------------------------------------------------------------------------
\r
53 cpBaseQtApplication::Editor::
\r
58 // -------------------------------------------------------------------------
\r
59 cpBaseQtApplication::Editor::
\r
60 TWorkspace* cpBaseQtApplication::Editor::
\r
63 return( this->m_Workspace );
\r
66 // -------------------------------------------------------------------------
\r
67 const cpBaseQtApplication::Editor::
\r
68 TWorkspace* cpBaseQtApplication::Editor::
\r
71 return( this->m_Workspace );
\r
74 // -------------------------------------------------------------------------
\r
75 void cpBaseQtApplication::Editor::
\r
76 setWorkspace( TWorkspace* ws )
\r
78 this->m_Workspace = ws;
\r
79 this->redrawWorkspace( );
\r
82 // -------------------------------------------------------------------------
\r
83 void cpBaseQtApplication::Editor::
\r
87 if( this->m_Workspace.IsNull( ) )
\r
91 std::map< std::string, Block* > blocks;
\r
92 auto filters = this->m_Workspace->GetFiltersNames( );
\r
93 for( auto f = filters.begin( ); f != filters.end( ); ++f )
\r
95 auto obj = this->m_Workspace->GetFilter( *f );
\r
96 blocks[ *f ] = this->_createBlock(
\r
98 QPointF( obj->GetViewX( ), obj->GetViewY( ) )
\r
104 for( auto f = filters.begin( ); f != filters.end( ); ++f )
\r
106 auto bf = blocks[ *f ];
\r
107 for( auto e = filters.begin( ); e != filters.end( ); ++e )
\r
109 auto be = blocks[ *e ];
\r
110 auto edges = this->m_Workspace->GetConnections( *f, *e );
\r
111 for( auto c = edges.begin( ); c != edges.end( ); ++c )
\r
113 OutputPort* op = bf->outputPort( c->first.c_str( ) );
\r
114 InputPort* ip = be->inputPort( c->second.c_str( ) );
\r
115 if( op == NULL || ip == NULL )
\r
118 Connection* conn = new Connection( 0, this->m_Scene );
\r
119 conn->setPort1( op );
\r
120 conn->setPort2( ip );
\r
121 conn->updatePosFromPorts( );
\r
122 conn->updatePath( );
\r
131 const auto& exp_inputs = this->m_Workspace->GetExposedInputs( );
\r
132 for( auto eIt = exp_inputs.begin( ); eIt != exp_inputs.end( ); ++eIt )
\r
134 auto bl = blocks[ eIt->second.first ];
\r
135 auto ip = bl->inputPort( eIt->second.second.c_str( ) );
\r
136 ip->setExtend( true );
\r
137 ip->setExtendedName( eIt->first.c_str( ) );
\r
142 const auto& exp_outputs = this->m_Workspace->GetExposedOutputs( );
\r
143 for( auto eIt = exp_outputs.begin( ); eIt != exp_outputs.end( ); ++eIt )
\r
145 auto bl = blocks[ eIt->second.first ];
\r
146 auto op = bl->outputPort( eIt->second.second.c_str( ) );
\r
147 op->setExtend( true );
\r
148 op->setExtendedName( eIt->first.c_str( ) );
\r
153 // -------------------------------------------------------------------------
\r
154 std::string cpBaseQtApplication::Editor::
\r
156 const std::string& category, const std::string& filter, const QPointF& pnt
\r
159 std::string name = filter;
\r
160 while( this->m_Workspace->HasFilter( name ) )
\r
161 name += std::string( "_" );
\r
163 auto obj = this->m_Workspace->CreateFilter( category, filter, name );
\r
166 this->_createBlock( obj, name.c_str( ), pnt );
\r
173 // -------------------------------------------------------------------------
\r
174 bool cpBaseQtApplication::Editor::
\r
175 deleteFilter( const std::string& name )
\r
177 if( this->m_Workspace.IsNotNull( ) )
\r
178 return( this->m_Workspace->RemoveFilter( name ) );
\r
183 // -------------------------------------------------------------------------
\r
184 bool cpBaseQtApplication::Editor::
\r
186 const std::string& src, const std::string& des,
\r
187 const std::string& in, const std::string& out
\r
190 if( this->m_Workspace.IsNotNull( ) )
\r
192 this->m_Workspace->Disconnect( src, des, in, out );
\r
199 // -------------------------------------------------------------------------
\r
200 void cpBaseQtApplication::Editor::
\r
203 this->m_Scene->clear( );
\r
204 auto views = this->m_Scene->views( );
\r
205 for( auto i = views.begin( ); i != views.end( ); ++i )
\r
206 ( *i )->viewport( )->update( );
\r
209 // -------------------------------------------------------------------------
\r
210 void cpBaseQtApplication::Editor::
\r
211 install( QGraphicsScene* s )
\r
213 s->installEventFilter( this );
\r
217 // -------------------------------------------------------------------------
\r
218 QGraphicsItem* cpBaseQtApplication::Editor::
\r
219 itemAt( const QPointF& pos )
\r
221 QList< QGraphicsItem* > items =
\r
222 this->m_Scene->items( QRectF( pos - QPointF( 1, 1 ), QSize( 3, 3 ) ) );
\r
224 foreach( QGraphicsItem* item, items )
\r
225 if( item->type( ) > QGraphicsItem::UserType )
\r
230 // -------------------------------------------------------------------------
\r
231 cpBaseQtApplication::Block* cpBaseQtApplication::Editor::
\r
232 _createBlock( TFilter* f, const QString& name, const QPointF& pnt )
\r
236 Block* b = new Block( f, name, 0, this->m_Scene );
\r
237 b->setEditor( this );
\r
242 // -------------------------------------------------------------------------
\r
243 bool cpBaseQtApplication::Editor::
\r
244 eventFilter( QObject* o, QEvent* e )
\r
247 switch( int( e->type( ) ) )
\r
249 cpBaseQtApplication_Editor_Callback_SWITCH( ContextMenu, e );
\r
250 cpBaseQtApplication_Editor_Callback_SWITCH( DragEnter, e );
\r
251 cpBaseQtApplication_Editor_Callback_SWITCH( DragLeave, e );
\r
252 cpBaseQtApplication_Editor_Callback_SWITCH( DragMove, e );
\r
253 cpBaseQtApplication_Editor_Callback_SWITCH( Drop, e );
\r
254 cpBaseQtApplication_Editor_Callback_SWITCH( Help, e );
\r
255 cpBaseQtApplication_Editor_Callback_SWITCH( HoverEnter, e );
\r
256 cpBaseQtApplication_Editor_Callback_SWITCH( HoverLeave, e );
\r
257 cpBaseQtApplication_Editor_Callback_SWITCH( HoverMove, e );
\r
258 cpBaseQtApplication_Editor_Callback_SWITCH( MouseDoubleClick, e );
\r
259 cpBaseQtApplication_Editor_Callback_SWITCH( MouseMove, e );
\r
260 cpBaseQtApplication_Editor_Callback_SWITCH( MousePress, e );
\r
261 cpBaseQtApplication_Editor_Callback_SWITCH( MouseRelease, e );
\r
262 cpBaseQtApplication_Editor_Callback_SWITCH( Move, e );
\r
263 cpBaseQtApplication_Editor_Callback_SWITCH( Resize, e );
\r
264 cpBaseQtApplication_Editor_Callback_SWITCH( Wheel, e );
\r
268 return( this->Superclass::eventFilter( o, e ) );
\r
271 // -------------------------------------------------------------------------
\r
272 void cpBaseQtApplication::Editor::
\r
273 updateFilter( const std::string& filter_name )
\r
275 if( this->m_MainWindow != NULL )
\r
276 this->m_MainWindow->updateFilter( filter_name );
\r
279 // -------------------------------------------------------------------------
\r
280 void cpBaseQtApplication::Editor::
\r
281 showData( const std::string& name, const std::string& port )
\r
283 if( this->m_MainWindow != NULL )
\r
284 this->m_MainWindow->showData( name, port );
\r
287 // -------------------------------------------------------------------------
\r
288 void cpBaseQtApplication::Editor::
\r
289 hideData( const std::string& name, const std::string& port )
\r
292 if( this->m_MainWindow != NULL )
\r
293 this->m_MainWindow->hideData( name, port );
\r
297 // -------------------------------------------------------------------------
\r
298 void cpBaseQtApplication::Editor::
\r
299 dataProperties( const std::string& name, const std::string& port )
\r
301 if( this->m_MainWindow != NULL )
\r
302 this->m_MainWindow->dataProperties( name, port );
\r
307 // -------------------------------------------------------------------------
\r
308 void cpBaseQtApplication::Editor::
\r
310 const std::string& filter_name, const std::string& output_name
\r
313 emit showFilterOutput( filter_name, output_name );
\r
316 // -------------------------------------------------------------------------
\r
317 void cpBaseQtApplication::Editor::
\r
319 const std::string& filter_name, const std::string& output_name
\r
322 emit hideFilterOutput( filter_name, output_name );
\r
325 // -------------------------------------------------------------------------
\r
326 void cpBaseQtApplication::Editor::
\r
327 visualPropertiesOutputData(
\r
328 const std::string& filter_name, const std::string& output_name
\r
331 emit visualPropertiesFilterOutput( filter_name, output_name );
\r
335 // -------------------------------------------------------------------------
\r
336 cpBaseQtApplication_Editor_Callback_CODE( ContextMenu )
\r
340 // -------------------------------------------------------------------------
\r
341 cpBaseQtApplication_Editor_Callback_CODE( DragEnter )
\r
345 // -------------------------------------------------------------------------
\r
346 cpBaseQtApplication_Editor_Callback_CODE( DragLeave )
\r
350 // -------------------------------------------------------------------------
\r
351 cpBaseQtApplication_Editor_Callback_CODE( DragMove )
\r
355 // -------------------------------------------------------------------------
\r
356 cpBaseQtApplication_Editor_Callback_CODE( Drop )
\r
360 // -------------------------------------------------------------------------
\r
361 cpBaseQtApplication_Editor_Callback_CODE( Help )
\r
365 // -------------------------------------------------------------------------
\r
366 cpBaseQtApplication_Editor_Callback_CODE( HoverEnter )
\r
370 // -------------------------------------------------------------------------
\r
371 cpBaseQtApplication_Editor_Callback_CODE( HoverLeave )
\r
375 // -------------------------------------------------------------------------
\r
376 cpBaseQtApplication_Editor_Callback_CODE( HoverMove )
\r
380 // -------------------------------------------------------------------------
\r
381 cpBaseQtApplication_Editor_Callback_CODE( MouseDoubleClick )
\r
383 // Get clicked item
\r
384 QGraphicsItem* item = this->itemAt( evt->scenePos( ) );
\r
387 Block* block = dynamic_cast< Block* >( item );
\r
388 Port* port = dynamic_cast< Port* >( item );
\r
389 Connection* conn = dynamic_cast< Connection* >( item );
\r
391 if( block != NULL && evt->button( ) == Qt::LeftButton )
\r
393 if( evt->modifiers( ) == Qt::NoModifier )
\r
395 QString old_name = block->namePort( );
\r
398 QInputDialog::getText(
\r
399 dynamic_cast< QWidget* >( this->parent( ) ),
\r
400 "Change filter name",
\r
406 if( ok && !new_name.isEmpty( ) && old_name != new_name )
\r
409 this->m_Workspace->RenameFilter(
\r
410 old_name.toStdString( ), new_name.toStdString( )
\r
413 block->setNamePort( new_name );
\r
419 else if( port != NULL && evt->button( ) == Qt::LeftButton )
\r
421 if( evt->modifiers( ) == Qt::ControlModifier )
\r
423 port->setExtend( !( port->isExtended( ) ) );
\r
424 InputPort* in_port = dynamic_cast< InputPort* >( port );
\r
425 OutputPort* out_port = dynamic_cast< OutputPort* >( port );
\r
426 if( port->isExtended( ) )
\r
428 auto ename = port->extendedName( ).toStdString( );
\r
431 auto fname = port->block( )->namePort( ).toStdString( );
\r
432 auto pname = port->name( ).toStdString( );
\r
433 ename = pname + std::string( "@" ) + fname;
\r
434 port->setExtendedName( ename.c_str( ) );
\r
438 if( in_port != NULL )
\r
439 this->m_Workspace->ExposeInput(
\r
440 in_port->extendedName( ).toStdString( ),
\r
441 in_port->block( )->namePort( ).toStdString( ),
\r
442 in_port->name( ).toStdString( )
\r
444 else if( out_port != NULL )
\r
445 this->m_Workspace->ExposeOutput(
\r
446 out_port->extendedName( ).toStdString( ),
\r
447 out_port->block( )->namePort( ).toStdString( ),
\r
448 out_port->name( ).toStdString( )
\r
453 if( in_port != NULL )
\r
454 this->m_Workspace->HideInput(
\r
455 in_port->extendedName( ).toStdString( )
\r
457 else if( out_port != NULL )
\r
458 this->m_Workspace->HideOutput(
\r
459 out_port->extendedName( ).toStdString( )
\r
464 else if( evt->modifiers( ) == Qt::NoModifier )
\r
466 if( port->isExtended( ) )
\r
468 QString old_name = port->extendedName( );
\r
471 QInputDialog::getText(
\r
472 dynamic_cast< QWidget* >( this->parent( ) ),
\r
473 "Change filter name",
\r
479 if( ok && !new_name.isEmpty( ) && old_name != new_name )
\r
481 InputPort* in_port = dynamic_cast< InputPort* >( port );
\r
482 OutputPort* out_port = dynamic_cast< OutputPort* >( port );
\r
483 bool success = false;
\r
484 if( in_port != NULL )
\r
485 success = this->m_Workspace->RenameExposedInput(
\r
486 old_name.toStdString( ), new_name.toStdString( )
\r
488 else if( out_port != NULL )
\r
489 success = this->m_Workspace->RenameExposedOutput(
\r
490 old_name.toStdString( ), new_name.toStdString( )
\r
494 port->setExtendedName( new_name );
\r
495 this->m_Scene->update( );
\r
508 // -------------------------------------------------------------------------
\r
509 cpBaseQtApplication_Editor_Callback_CODE( MouseMove )
\r
511 if( this->m_ActualConnection != NULL )
\r
513 if( this->m_ActualConnection->port1( ) == NULL )
\r
514 this->m_ActualConnection->setPos1( evt->scenePos( ) );
\r
515 else if( this->m_ActualConnection->port2( ) == NULL )
\r
516 this->m_ActualConnection->setPos2( evt->scenePos( ) );
\r
517 this->m_ActualConnection->updatePath( );
\r
522 // -------------------------------------------------------------------------
\r
523 cpBaseQtApplication_Editor_Callback_CODE( MousePress )
\r
525 InputPort* in_port =
\r
526 dynamic_cast< InputPort* >( this->itemAt( evt->scenePos( ) ) );
\r
527 OutputPort* out_port =
\r
528 dynamic_cast< OutputPort* >( this->itemAt( evt->scenePos( ) ) );
\r
529 if( in_port == NULL && out_port == NULL )
\r
532 switch( evt->button( ) )
\r
534 case Qt::LeftButton:
\r
536 if( out_port != NULL )
\r
538 if( out_port->block( ) != NULL )
\r
540 // Start new connection
\r
541 this->m_ActualConnection = new Connection( 0, this->m_Scene );
\r
542 this->m_ActualConnection->setPort1( out_port );
\r
543 this->m_ActualConnection->setPos1( out_port->scenePos( ) );
\r
544 this->m_ActualConnection->setPos2( evt->scenePos( ) );
\r
545 this->m_ActualConnection->updatePosFromPorts( );
\r
546 this->m_ActualConnection->updatePath( );
\r
559 // -------------------------------------------------------------------------
\r
560 cpBaseQtApplication_Editor_Callback_CODE( MouseRelease )
\r
562 if( this->m_ActualConnection == NULL )
\r
565 switch( evt->button( ) )
\r
567 case Qt::LeftButton:
\r
570 dynamic_cast< InputPort* >( this->itemAt( evt->scenePos( ) ) );
\r
572 dynamic_cast< OutputPort* >( this->m_ActualConnection->port1( ) );
\r
573 if( in != NULL && out != NULL )
\r
576 in->block( ) != out->block( ) &&
\r
577 !in->hasConnection( ) &&
\r
578 !in->isConnected( out ) &&
\r
579 !out->isExtended( )
\r
582 std::string d_filter = in->block( )->namePort( ).toStdString( );
\r
583 std::string o_filter = out->block( )->namePort( ).toStdString( );
\r
584 std::string d_port = in->name( ).toStdString( );
\r
585 std::string o_port = out->name( ).toStdString( );
\r
588 this->m_Workspace->Connect( o_filter, d_filter, o_port, d_port );
\r
589 this->m_ActualConnection->setPos2( in->scenePos( ) );
\r
590 this->m_ActualConnection->setPort2( in );
\r
591 this->m_ActualConnection->updatePosFromPorts( );
\r
592 this->m_ActualConnection->updatePath( );
\r
594 catch( std::exception& err )
\r
596 delete this->m_ActualConnection;
\r
597 QMessageBox::critical(
\r
599 QMessageBox::tr( "Error connecting ports" ),
\r
600 QMessageBox::tr( err.what( ) )
\r
606 delete this->m_ActualConnection;
\r
609 delete this->m_ActualConnection;
\r
610 this->m_ActualConnection = NULL;
\r
618 // -------------------------------------------------------------------------
\r
619 cpBaseQtApplication_Editor_Callback_CODE( Move )
\r
623 // -------------------------------------------------------------------------
\r
624 cpBaseQtApplication_Editor_Callback_CODE( Resize )
\r
628 // -------------------------------------------------------------------------
\r
629 cpBaseQtApplication_Editor_Callback_CODE( Wheel )
\r