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 <QInputDialog>
\r
14 #include <QMessageBox>
\r
16 #include <cpBaseQtApplication/Port.h>
\r
17 #include <cpBaseQtApplication/Connection.h>
\r
18 #include <cpBaseQtApplication/Block.h>
\r
20 // -------------------------------------------------------------------------
\r
21 #define cpBaseQtApplication_Editor_Callback_SWITCH( E, e ) \
\r
22 case QEvent::GraphicsScene##E: \
\r
24 QGraphicsScene##E##Event* evt = \
\r
25 dynamic_cast< QGraphicsScene##E##Event* >( e ); \
\r
27 this->_##E##_cbk( evt ); \
\r
31 // -------------------------------------------------------------------------
\r
32 #define cpBaseQtApplication_Editor_Callback_CODE( E ) \
\r
33 void cpBaseQtApplication::Editor::_##E##_cbk( QGraphicsScene##E##Event* evt )
\r
35 // -------------------------------------------------------------------------
\r
36 cpBaseQtApplication::Editor::
\r
37 Editor( QObject* parent )
\r
38 : Superclass( parent ),
\r
39 m_ActualConnection( NULL ),
\r
44 // -------------------------------------------------------------------------
\r
45 cpBaseQtApplication::Editor::
\r
50 // -------------------------------------------------------------------------
\r
51 cpBaseQtApplication::Editor::
\r
52 TWorkspace* cpBaseQtApplication::Editor::
\r
55 return( this->m_Workspace );
\r
58 // -------------------------------------------------------------------------
\r
59 const cpBaseQtApplication::Editor::
\r
60 TWorkspace* cpBaseQtApplication::Editor::
\r
63 return( this->m_Workspace );
\r
66 // -------------------------------------------------------------------------
\r
67 void cpBaseQtApplication::Editor::
\r
68 setWorkspace( TWorkspace* ws )
\r
70 this->m_Workspace = ws;
\r
71 this->redrawWorkspace( );
\r
74 // -------------------------------------------------------------------------
\r
75 void cpBaseQtApplication::Editor::
\r
78 if( this->m_Workspace == NULL )
\r
82 std::map< std::string, Block* > blocks;
\r
83 auto vIt = this->m_Workspace->GetGraph( )->BeginVertices( );
\r
84 auto vIt_end = this->m_Workspace->GetGraph( )->EndVertices( );
\r
85 for( ; vIt != vIt_end; ++vIt )
\r
87 auto b = this->_createBlock(
\r
88 dynamic_cast< TFilter* >( vIt->second.GetPointer( ) ),
\r
89 vIt->first.c_str( ),
\r
90 QPointF( vIt->second->GetViewX( ), vIt->second->GetViewY( ) )
\r
92 blocks[ vIt->first ] = b;
\r
97 auto rIt = this->m_Workspace->GetGraph( )->BeginEdgesRows( );
\r
98 auto rIt_end = this->m_Workspace->GetGraph( )->EndEdgesRows( );
\r
99 for( ; rIt != rIt_end; ++rIt )
\r
101 Block* orig = blocks[ rIt->first ];
\r
102 auto cIt = rIt->second.begin( );
\r
103 for( ; cIt != rIt->second.end( ); ++cIt )
\r
105 Block* dest = blocks[ cIt->first ];
\r
106 auto eIt = cIt->second.begin( );
\r
107 for( ; eIt != cIt->second.end( ); ++eIt )
\r
109 OutputPort* op = orig->outputPort( eIt->first.c_str( ) );
\r
110 InputPort* ip = dest->inputPort( eIt->second.c_str( ) );
\r
111 if( op == NULL || ip == NULL )
\r
114 Connection* c = new Connection( 0, this->m_Scene );
\r
117 c->updatePosFromPorts( );
\r
127 // -------------------------------------------------------------------------
\r
128 std::string cpBaseQtApplication::Editor::
\r
130 const std::string& category,
\r
131 const std::string& filter,
\r
135 std::string name = filter;
\r
136 while( this->m_Workspace->HasFilter( name ) )
\r
137 name += std::string( "_" );
\r
138 if( this->m_Workspace->CreateFilter( category, filter, name ) )
\r
140 auto b = this->_createBlock(
\r
141 this->m_Workspace->GetFilter( name ),
\r
151 // -------------------------------------------------------------------------
\r
152 bool cpBaseQtApplication::Editor::
\r
153 deleteFilter( const std::string& name )
\r
155 if( this->m_Workspace != NULL )
\r
156 return( this->m_Workspace->RemoveFilter( name ) );
\r
161 // -------------------------------------------------------------------------
\r
162 bool cpBaseQtApplication::Editor::
\r
164 const std::string& src, const std::string& des,
\r
165 const std::string& in, const std::string& out
\r
168 if( this->m_Workspace != NULL )
\r
169 return( this->m_Workspace->Disconnect( src, des, in, out ) );
\r
174 // -------------------------------------------------------------------------
\r
175 void cpBaseQtApplication::Editor::
\r
178 std::cout << "Editor: clear" << std::endl;
\r
180 auto vIt = this->m_Graph.BeginVertices( );
\r
181 for( ; vIt != this->m_Graph.EndVertices( ); ++vIt )
\r
187 // -------------------------------------------------------------------------
\r
188 void cpBaseQtApplication::Editor::
\r
189 install( QGraphicsScene* s )
\r
191 s->installEventFilter( this );
\r
195 // -------------------------------------------------------------------------
\r
196 QGraphicsItem* cpBaseQtApplication::Editor::
\r
197 itemAt( const QPointF& pos )
\r
199 QList< QGraphicsItem* > items =
\r
200 this->m_Scene->items( QRectF( pos - QPointF( 1, 1 ), QSize( 3, 3 ) ) );
\r
202 foreach( QGraphicsItem* item, items )
\r
203 if( item->type( ) > QGraphicsItem::UserType )
\r
208 // -------------------------------------------------------------------------
\r
209 cpBaseQtApplication::Block* cpBaseQtApplication::Editor::
\r
210 _createBlock( TFilter* f, const QString& name, const QPointF& pnt )
\r
216 Block* b = new Block( f, name, 0, this->m_Scene );
\r
217 b->setEditor( this );
\r
220 // Mark exposed inputs
\r
221 auto& e_in = this->m_Workspace->GetExposedInputPorts( );
\r
222 auto f_in = f->GetInputsNames( );
\r
223 for( auto iIt = f_in.begin( ); iIt != f_in.end( ); ++iIt )
\r
225 auto eIt = e_in.begin( );
\r
226 auto fIt = e_in.end( );
\r
227 for( ; eIt != e_in.end( ) && fIt == e_in.end( ); ++eIt )
\r
228 if( eIt->second.second == *iIt )
\r
230 if( fIt == e_in.end( ) )
\r
233 auto port = b->inputPort( iIt->c_str( ) );
\r
234 port->setExtendedName( fIt->first.c_str( ) );
\r
235 port->setExtend( true );
\r
239 // Mark exposed outputs
\r
240 auto& e_out = this->m_Workspace->GetExposedOutputPorts( );
\r
241 auto f_out = f->GetOutputsNames( );
\r
242 for( auto iIt = f_out.begin( ); iIt != f_out.end( ); ++iIt )
\r
244 auto eIt = e_out.begin( );
\r
245 auto fIt = e_out.end( );
\r
246 for( ; eIt != e_out.end( ) && fIt == e_out.end( ); ++eIt )
\r
247 if( eIt->second.second == *iIt )
\r
249 if( fIt == e_out.end( ) )
\r
252 auto port = b->outputPort( iIt->c_str( ) );
\r
253 port->setExtendedName( fIt->first.c_str( ) );
\r
254 port->setExtend( true );
\r
261 // -------------------------------------------------------------------------
\r
262 bool cpBaseQtApplication::Editor::
\r
263 eventFilter( QObject* o, QEvent* e )
\r
266 switch( int( e->type( ) ) )
\r
268 cpBaseQtApplication_Editor_Callback_SWITCH( ContextMenu, e );
\r
269 cpBaseQtApplication_Editor_Callback_SWITCH( DragEnter, e );
\r
270 cpBaseQtApplication_Editor_Callback_SWITCH( DragLeave, e );
\r
271 cpBaseQtApplication_Editor_Callback_SWITCH( DragMove, e );
\r
272 cpBaseQtApplication_Editor_Callback_SWITCH( Drop, e );
\r
273 cpBaseQtApplication_Editor_Callback_SWITCH( Help, e );
\r
274 cpBaseQtApplication_Editor_Callback_SWITCH( HoverEnter, e );
\r
275 cpBaseQtApplication_Editor_Callback_SWITCH( HoverLeave, e );
\r
276 cpBaseQtApplication_Editor_Callback_SWITCH( HoverMove, e );
\r
277 cpBaseQtApplication_Editor_Callback_SWITCH( MouseDoubleClick, e );
\r
278 cpBaseQtApplication_Editor_Callback_SWITCH( MouseMove, e );
\r
279 cpBaseQtApplication_Editor_Callback_SWITCH( MousePress, e );
\r
280 cpBaseQtApplication_Editor_Callback_SWITCH( MouseRelease, e );
\r
281 cpBaseQtApplication_Editor_Callback_SWITCH( Move, e );
\r
282 cpBaseQtApplication_Editor_Callback_SWITCH( Resize, e );
\r
283 cpBaseQtApplication_Editor_Callback_SWITCH( Wheel, e );
\r
287 return( this->Superclass::eventFilter( o, e ) );
\r
290 // -------------------------------------------------------------------------
\r
291 void cpBaseQtApplication::Editor::
\r
292 updateFilter( const std::string& filter_name )
\r
294 emit execFilter( filter_name );
\r
297 // -------------------------------------------------------------------------
\r
298 void cpBaseQtApplication::Editor::
\r
300 const std::string& filter_name, const std::string& output_name
\r
303 emit showFilterOutput( filter_name, output_name );
\r
306 // -------------------------------------------------------------------------
\r
307 void cpBaseQtApplication::Editor::
\r
309 const std::string& filter_name, const std::string& output_name
\r
312 emit hideFilterOutput( filter_name, output_name );
\r
315 // -------------------------------------------------------------------------
\r
316 void cpBaseQtApplication::Editor::
\r
317 visualPropertiesOutputData(
\r
318 const std::string& filter_name, const std::string& output_name
\r
321 emit visualPropertiesFilterOutput( filter_name, output_name );
\r
324 // -------------------------------------------------------------------------
\r
325 cpBaseQtApplication_Editor_Callback_CODE( ContextMenu )
\r
329 // -------------------------------------------------------------------------
\r
330 cpBaseQtApplication_Editor_Callback_CODE( DragEnter )
\r
334 // -------------------------------------------------------------------------
\r
335 cpBaseQtApplication_Editor_Callback_CODE( DragLeave )
\r
339 // -------------------------------------------------------------------------
\r
340 cpBaseQtApplication_Editor_Callback_CODE( DragMove )
\r
344 // -------------------------------------------------------------------------
\r
345 cpBaseQtApplication_Editor_Callback_CODE( Drop )
\r
349 // -------------------------------------------------------------------------
\r
350 cpBaseQtApplication_Editor_Callback_CODE( Help )
\r
354 // -------------------------------------------------------------------------
\r
355 cpBaseQtApplication_Editor_Callback_CODE( HoverEnter )
\r
359 // -------------------------------------------------------------------------
\r
360 cpBaseQtApplication_Editor_Callback_CODE( HoverLeave )
\r
364 // -------------------------------------------------------------------------
\r
365 cpBaseQtApplication_Editor_Callback_CODE( HoverMove )
\r
369 // -------------------------------------------------------------------------
\r
370 cpBaseQtApplication_Editor_Callback_CODE( MouseDoubleClick )
\r
373 QGraphicsItem* item = this->itemAt( evt->scenePos( ) );
\r
377 switch( evt->button( ) )
\r
379 case Qt::LeftButton:
\r
381 Block* block = dynamic_cast< Block* >( item );
\r
382 Port* port = dynamic_cast< Port* >( item );
\r
383 Connection* conn = dynamic_cast< Connection* >( item );
\r
385 if( block != NULL )
\r
387 QString old_name = block->namePort( );
\r
390 QInputDialog::getText(
\r
391 dynamic_cast< QWidget* >( this->parent( ) ),
\r
392 "Change filter name",
\r
398 if( ok && !new_name.isEmpty( ) && old_name != new_name )
\r
400 ok = this->m_Graph->RenameVertex(
\r
401 old_name.toStdString( ),
\r
402 new_name.toStdString( )
\r
404 block->setNamePort( new_name );
\r
405 this->m_Workspace->RenameFilter(
\r
406 old_name.toStdString( ),
\r
407 new_name.toStdString( )
\r
412 else if( port != NULL )
\r
414 if( evt->modifiers( ) == Qt::ControlModifier )
\r
416 port->setExtend( !( port->isExtended( ) ) );
\r
417 InputPort* in_port = dynamic_cast< InputPort* >( port );
\r
418 OutputPort* out_port = dynamic_cast< OutputPort* >( port );
\r
419 if( port->isExtended( ) )
\r
421 if( in_port != NULL )
\r
423 this->m_Workspace->ExposeInputPort(
\r
424 in_port->extendedName( ).toStdString( ),
\r
425 in_port->block( )->namePort( ).toStdString( ),
\r
426 in_port->name( ).toStdString( )
\r
429 else if( out_port != NULL )
\r
431 this->m_Workspace->ExposeOutputPort(
\r
432 out_port->extendedName( ).toStdString( ),
\r
433 out_port->block( )->namePort( ).toStdString( ),
\r
434 out_port->name( ).toStdString( )
\r
441 if( in_port != NULL )
\r
442 this->m_Workspace->HideInputPort(
\r
443 in_port->extendedName( ).toStdString( )
\r
445 else if( out_port != NULL )
\r
446 this->m_Workspace->HideOutputPort(
\r
447 out_port->extendedName( ).toStdString( )
\r
451 this->m_Scene->update( );
\r
453 else if( evt->modifiers( ) == Qt::NoModifier )
\r
455 if( port->isExtended( ) )
\r
457 QString old_name = port->extendedName( );
\r
460 QInputDialog::getText(
\r
461 dynamic_cast< QWidget* >( this->parent( ) ),
\r
462 "Change filter name",
\r
468 if( ok && !new_name.isEmpty( ) && old_name != new_name )
\r
470 port->setExtendedName( new_name );
\r
471 InputPort* in_port = dynamic_cast< InputPort* >( port );
\r
472 OutputPort* out_port = dynamic_cast< OutputPort* >( port );
\r
473 if( in_port != NULL )
\r
474 this->m_Workspace->
\r
475 RenameExposedInputPort(
\r
476 old_name.toStdString( ),
\r
477 new_name.toStdString( )
\r
479 else if( out_port != NULL )
\r
480 this->m_Workspace->
\r
481 RenameExposedOutputPort(
\r
482 old_name.toStdString( ),
\r
483 new_name.toStdString( )
\r
485 this->m_Scene->update( );
\r
493 else if( conn != NULL )
\r
498 case Qt::RightButton:
\r
502 case Qt::MiddleButton:
\r
512 // -------------------------------------------------------------------------
\r
513 cpBaseQtApplication_Editor_Callback_CODE( MouseMove )
\r
515 if( this->m_ActualConnection != NULL )
\r
517 if( this->m_ActualConnection->port1( ) == NULL )
\r
518 this->m_ActualConnection->setPos1( evt->scenePos( ) );
\r
519 else if( this->m_ActualConnection->port2( ) == NULL )
\r
520 this->m_ActualConnection->setPos2( evt->scenePos( ) );
\r
521 this->m_ActualConnection->updatePath( );
\r
526 // -------------------------------------------------------------------------
\r
527 cpBaseQtApplication_Editor_Callback_CODE( MousePress )
\r
529 InputPort* in_port =
\r
530 dynamic_cast< InputPort* >( this->itemAt( evt->scenePos( ) ) );
\r
531 OutputPort* out_port =
\r
532 dynamic_cast< OutputPort* >( this->itemAt( evt->scenePos( ) ) );
\r
533 if( in_port == NULL && out_port == NULL )
\r
536 switch( evt->button( ) )
\r
538 case Qt::LeftButton:
\r
540 if( out_port != NULL )
\r
542 if( out_port->block( ) != NULL )
\r
544 // Start new connection
\r
545 this->m_ActualConnection = new Connection( 0, this->m_Scene );
\r
546 this->m_ActualConnection->setPort1( out_port );
\r
547 this->m_ActualConnection->setPos1( out_port->scenePos( ) );
\r
548 this->m_ActualConnection->setPos2( evt->scenePos( ) );
\r
549 this->m_ActualConnection->updatePosFromPorts( );
\r
550 this->m_ActualConnection->updatePath( );
\r
563 // -------------------------------------------------------------------------
\r
564 cpBaseQtApplication_Editor_Callback_CODE( MouseRelease )
\r
566 if( this->m_ActualConnection == NULL )
\r
569 switch( evt->button( ) )
\r
571 case Qt::LeftButton:
\r
574 dynamic_cast< InputPort* >( this->itemAt( evt->scenePos( ) ) );
\r
575 if( port2 != NULL )
\r
577 OutputPort* port1 =
\r
578 dynamic_cast< OutputPort* >( this->m_ActualConnection->port1( ) );
\r
579 if( port1 != NULL )
\r
582 port1->block( ) != port2->block( ) &&
\r
583 !port2->hasConnection( ) &&
\r
584 !port1->isConnected( port2 ) &&
\r
585 !port2->isExtended( )
\r
588 this->m_ActualConnection->setPos2( port2->scenePos( ) );
\r
589 this->m_ActualConnection->setPort2( port2 );
\r
590 this->m_ActualConnection->updatePosFromPorts( );
\r
591 this->m_ActualConnection->updatePath( );
\r
593 this->m_Workspace->Connect(
\r
594 port1->block( )->namePort( ).toStdString( ),
\r
595 port2->block( )->namePort( ).toStdString( ),
\r
596 port1->name( ).toStdString( ),
\r
597 port2->name( ).toStdString( )
\r
601 delete this->m_ActualConnection;
\r
604 delete this->m_ActualConnection;
\r
607 delete this->m_ActualConnection;
\r
608 this->m_ActualConnection = NULL;
\r
616 // -------------------------------------------------------------------------
\r
617 cpBaseQtApplication_Editor_Callback_CODE( Move )
\r
621 // -------------------------------------------------------------------------
\r
622 cpBaseQtApplication_Editor_Callback_CODE( Resize )
\r
626 // -------------------------------------------------------------------------
\r
627 cpBaseQtApplication_Editor_Callback_CODE( Wheel )
\r