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
16 #include "Connection.h"
\r
19 // -------------------------------------------------------------------------
\r
20 #define cpPipelineEditor_Editor_Callback_SWITCH( E, e ) \
\r
21 case QEvent::GraphicsScene##E: \
\r
23 QGraphicsScene##E##Event* evt = \
\r
24 dynamic_cast< QGraphicsScene##E##Event* >( e ); \
\r
26 this->_##E##_cbk( evt ); \
\r
30 // -------------------------------------------------------------------------
\r
31 #define cpPipelineEditor_Editor_Callback_CODE( E ) \
\r
32 void cpPipelineEditor::Editor::_##E##_cbk( QGraphicsScene##E##Event* evt )
\r
34 // -------------------------------------------------------------------------
\r
35 cpPipelineEditor::Editor::
\r
36 Editor( QObject* parent )
\r
37 : Superclass( parent ),
\r
38 m_ActualConnection( NULL ),
\r
43 // -------------------------------------------------------------------------
\r
44 cpPipelineEditor::Editor::
\r
49 // -------------------------------------------------------------------------
\r
50 cpPipelineEditor::Editor::
\r
51 TWorkspace* cpPipelineEditor::Editor::
\r
54 return( this->m_Workspace );
\r
57 // -------------------------------------------------------------------------
\r
58 const cpPipelineEditor::Editor::
\r
59 TWorkspace* cpPipelineEditor::Editor::
\r
62 return( this->m_Workspace );
\r
65 // -------------------------------------------------------------------------
\r
66 void cpPipelineEditor::Editor::
\r
67 setWorkspace( TWorkspace* ws )
\r
69 this->m_Workspace = ws;
\r
70 this->m_Graph = TGraph::New( );
\r
73 auto vIt = this->m_Workspace->GetGraph( )->BeginVertices( );
\r
74 auto vIt_end = this->m_Workspace->GetGraph( )->EndVertices( );
\r
75 for( ; vIt != vIt_end; ++vIt )
\r
77 dynamic_cast< TFilter* >( vIt->second.GetPointer( ) ),
\r
78 QPointF( vIt->second->GetViewX( ), vIt->second->GetViewY( ) )
\r
82 auto rIt = this->m_Workspace->GetGraph( )->BeginEdgesRows( );
\r
83 auto rIt_end = this->m_Workspace->GetGraph( )->EndEdgesRows( );
\r
84 for( ; rIt != rIt_end; ++rIt )
\r
86 Block* orig = this->m_Graph->GetVertex( rIt->first );
\r
87 auto cIt = rIt->second.begin( );
\r
88 for( ; cIt != rIt->second.end( ); ++cIt )
\r
90 Block* dest = this->m_Graph->GetVertex( cIt->first );
\r
91 auto eIt = cIt->second.begin( );
\r
92 for( ; eIt != cIt->second.end( ); ++eIt )
\r
94 OutputPort* op = orig->outputPort( eIt->first.c_str( ) );
\r
95 InputPort* ip = dest->inputPort( eIt->second.c_str( ) );
\r
96 if( op == NULL || ip == NULL )
\r
99 Connection* c = new Connection( 0, this->m_Scene );
\r
102 c->updatePosFromPorts( );
\r
104 this->m_Graph->AddEdge( rIt->first, cIt->first, c );
\r
113 // -------------------------------------------------------------------------
\r
114 std::string cpPipelineEditor::Editor::
\r
115 createFilter( const std::string& filter, const QPointF& pnt )
\r
117 std::string name = filter;
\r
118 while( this->m_Workspace->HasFilter( name ) )
\r
119 name += std::string( "_" );
\r
120 if( this->m_Workspace->CreateFilter( filter, name ) )
\r
122 this->_createBlock( this->m_Workspace->GetFilter( name ), pnt );
\r
129 // -------------------------------------------------------------------------
\r
130 void cpPipelineEditor::Editor::
\r
131 install( QGraphicsScene* s )
\r
133 s->installEventFilter( this );
\r
137 // -------------------------------------------------------------------------
\r
138 QGraphicsItem* cpPipelineEditor::Editor::
\r
139 itemAt( const QPointF& pos )
\r
141 QList< QGraphicsItem* > items =
\r
142 this->m_Scene->items( QRectF( pos - QPointF( 1, 1 ), QSize( 3, 3 ) ) );
\r
144 foreach( QGraphicsItem* item, items )
\r
145 if( item->type( ) > QGraphicsItem::UserType )
\r
150 // -------------------------------------------------------------------------
\r
151 void cpPipelineEditor::Editor::
\r
152 _createBlock( TFilter* f, const QPointF& pnt )
\r
158 Block* b = new Block( f, 0, this->m_Scene );
\r
161 // Keep a trace of this visual graph
\r
162 this->m_Graph->SetVertex( f->GetName( ), b );
\r
165 // -------------------------------------------------------------------------
\r
166 bool cpPipelineEditor::Editor::
\r
167 eventFilter( QObject* o, QEvent* e )
\r
170 switch( int( e->type( ) ) )
\r
172 cpPipelineEditor_Editor_Callback_SWITCH( ContextMenu, e );
\r
173 cpPipelineEditor_Editor_Callback_SWITCH( DragEnter, e );
\r
174 cpPipelineEditor_Editor_Callback_SWITCH( DragLeave, e );
\r
175 cpPipelineEditor_Editor_Callback_SWITCH( DragMove, e );
\r
176 cpPipelineEditor_Editor_Callback_SWITCH( Drop, e );
\r
177 cpPipelineEditor_Editor_Callback_SWITCH( Help, e );
\r
178 cpPipelineEditor_Editor_Callback_SWITCH( HoverEnter, e );
\r
179 cpPipelineEditor_Editor_Callback_SWITCH( HoverLeave, e );
\r
180 cpPipelineEditor_Editor_Callback_SWITCH( HoverMove, e );
\r
181 cpPipelineEditor_Editor_Callback_SWITCH( MouseDoubleClick, e );
\r
182 cpPipelineEditor_Editor_Callback_SWITCH( MouseMove, e );
\r
183 cpPipelineEditor_Editor_Callback_SWITCH( MousePress, e );
\r
184 cpPipelineEditor_Editor_Callback_SWITCH( MouseRelease, e );
\r
185 cpPipelineEditor_Editor_Callback_SWITCH( Move, e );
\r
186 cpPipelineEditor_Editor_Callback_SWITCH( Resize, e );
\r
187 cpPipelineEditor_Editor_Callback_SWITCH( Wheel, e );
\r
191 return( this->Superclass::eventFilter( o, e ) );
\r
194 // -------------------------------------------------------------------------
\r
195 cpPipelineEditor_Editor_Callback_CODE( ContextMenu )
\r
199 // -------------------------------------------------------------------------
\r
200 cpPipelineEditor_Editor_Callback_CODE( DragEnter )
\r
204 // -------------------------------------------------------------------------
\r
205 cpPipelineEditor_Editor_Callback_CODE( DragLeave )
\r
209 // -------------------------------------------------------------------------
\r
210 cpPipelineEditor_Editor_Callback_CODE( DragMove )
\r
214 // -------------------------------------------------------------------------
\r
215 cpPipelineEditor_Editor_Callback_CODE( Drop )
\r
219 // -------------------------------------------------------------------------
\r
220 cpPipelineEditor_Editor_Callback_CODE( Help )
\r
224 // -------------------------------------------------------------------------
\r
225 cpPipelineEditor_Editor_Callback_CODE( HoverEnter )
\r
229 // -------------------------------------------------------------------------
\r
230 cpPipelineEditor_Editor_Callback_CODE( HoverLeave )
\r
234 // -------------------------------------------------------------------------
\r
235 cpPipelineEditor_Editor_Callback_CODE( HoverMove )
\r
239 // -------------------------------------------------------------------------
\r
240 cpPipelineEditor_Editor_Callback_CODE( MouseDoubleClick )
\r
242 QGraphicsItem* item = this->itemAt( evt->scenePos( ) );
\r
246 switch( evt->button( ) )
\r
248 case Qt::LeftButton:
\r
250 Block* block = dynamic_cast< Block* >( item );
\r
251 Port* port = dynamic_cast< Port* >( item );
\r
252 Connection* conn = dynamic_cast< Connection* >( item );
\r
254 if( block != NULL )
\r
256 QString old_name = block->namePort( );
\r
259 QInputDialog::getText(
\r
260 dynamic_cast< QWidget* >( this->parent( ) ),
\r
261 "Change filter name",
\r
267 if( ok && !new_name.isEmpty( ) && old_name != new_name )
\r
269 ok = this->m_Graph->RenameVertex(
\r
270 old_name.toStdString( ),
\r
271 new_name.toStdString( )
\r
275 block->setNamePort( new_name );
\r
276 this->m_Workspace->RenameFilter(
\r
277 old_name.toStdString( ),
\r
278 new_name.toStdString( )
\r
285 else if( port != NULL )
\r
287 if( evt->modifiers( ) == Qt::ControlModifier )
\r
289 port->setExtend( !( port->isExtended( ) ) );
\r
290 InputPort* in_port = dynamic_cast< InputPort* >( port );
\r
291 OutputPort* out_port = dynamic_cast< OutputPort* >( port );
\r
292 if( port->isExtended( ) )
\r
294 if( in_port != NULL )
\r
296 this->m_Workspace->ExposeInputPort(
\r
297 in_port->extendedName( ).toStdString( ),
\r
298 in_port->block( )->namePort( ).toStdString( ),
\r
299 in_port->name( ).toStdString( )
\r
302 else if( out_port != NULL )
\r
304 this->m_Workspace->ExposeOutputPort(
\r
305 out_port->extendedName( ).toStdString( ),
\r
306 out_port->block( )->namePort( ).toStdString( ),
\r
307 out_port->name( ).toStdString( )
\r
314 if( in_port != NULL )
\r
315 this->m_Workspace->HideInputPort(
\r
316 in_port->extendedName( ).toStdString( )
\r
318 else if( out_port != NULL )
\r
319 this->m_Workspace->HideOutputPort(
\r
320 out_port->extendedName( ).toStdString( )
\r
324 this->m_Scene->update( );
\r
326 else if( evt->modifiers( ) == Qt::NoModifier )
\r
328 if( port->isExtended( ) )
\r
330 QString old_name = port->extendedName( );
\r
333 QInputDialog::getText(
\r
334 dynamic_cast< QWidget* >( this->parent( ) ),
\r
335 "Change filter name",
\r
341 if( ok && !new_name.isEmpty( ) && old_name != new_name )
\r
343 port->setExtendedName( new_name );
\r
344 InputPort* in_port = dynamic_cast< InputPort* >( port );
\r
345 OutputPort* out_port = dynamic_cast< OutputPort* >( port );
\r
346 if( in_port != NULL )
\r
347 this->m_Workspace->
\r
348 RenameExposedInputPort(
\r
349 old_name.toStdString( ),
\r
350 new_name.toStdString( )
\r
352 else if( out_port != NULL )
\r
353 this->m_Workspace->
\r
354 RenameExposedOutputPort(
\r
355 old_name.toStdString( ),
\r
356 new_name.toStdString( )
\r
358 this->m_Scene->update( );
\r
366 else if( conn != NULL )
\r
372 case Qt::RightButton:
\r
376 case Qt::MiddleButton:
\r
386 // -------------------------------------------------------------------------
\r
387 cpPipelineEditor_Editor_Callback_CODE( MouseMove )
\r
389 if( this->m_ActualConnection != NULL )
\r
391 if( this->m_ActualConnection->port1( ) == NULL )
\r
392 this->m_ActualConnection->setPos1( evt->scenePos( ) );
\r
393 else if( this->m_ActualConnection->port2( ) == NULL )
\r
394 this->m_ActualConnection->setPos2( evt->scenePos( ) );
\r
395 this->m_ActualConnection->updatePath( );
\r
400 // -------------------------------------------------------------------------
\r
401 cpPipelineEditor_Editor_Callback_CODE( MousePress )
\r
403 InputPort* in_port =
\r
404 dynamic_cast< InputPort* >( this->itemAt( evt->scenePos( ) ) );
\r
405 OutputPort* out_port =
\r
406 dynamic_cast< OutputPort* >( this->itemAt( evt->scenePos( ) ) );
\r
407 if( in_port == NULL && out_port == NULL )
\r
410 switch( evt->button( ) )
\r
412 case Qt::LeftButton:
\r
414 if( out_port != NULL )
\r
416 if( out_port->block( ) != NULL )
\r
418 // Start new connection
\r
419 this->m_ActualConnection = new Connection( 0, this->m_Scene );
\r
420 this->m_ActualConnection->setPort1( out_port );
\r
421 this->m_ActualConnection->setPos1( out_port->scenePos( ) );
\r
422 this->m_ActualConnection->setPos2( evt->scenePos( ) );
\r
423 this->m_ActualConnection->updatePosFromPorts( );
\r
424 this->m_ActualConnection->updatePath( );
\r
437 // -------------------------------------------------------------------------
\r
438 cpPipelineEditor_Editor_Callback_CODE( MouseRelease )
\r
440 if( this->m_ActualConnection == NULL )
\r
443 switch( evt->button( ) )
\r
445 case Qt::LeftButton:
\r
448 dynamic_cast< InputPort* >( this->itemAt( evt->scenePos( ) ) );
\r
449 if( port2 != NULL )
\r
451 OutputPort* port1 =
\r
452 dynamic_cast< OutputPort* >( this->m_ActualConnection->port1( ) );
\r
453 if( port1 != NULL )
\r
456 port1->block( ) != port2->block( ) &&
\r
457 !port2->hasConnection( ) &&
\r
458 !port1->isConnected( port2 ) &&
\r
459 !port2->isExtended( )
\r
462 this->m_ActualConnection->setPos2( port2->scenePos( ) );
\r
463 this->m_ActualConnection->setPort2( port2 );
\r
464 this->m_ActualConnection->updatePosFromPorts( );
\r
465 this->m_ActualConnection->updatePath( );
\r
467 this->m_Workspace->Connect(
\r
468 port1->block( )->namePort( ).toStdString( ),
\r
469 port2->block( )->namePort( ).toStdString( ),
\r
470 port1->name( ).toStdString( ),
\r
471 port2->name( ).toStdString( )
\r
473 this->m_Graph->AddEdge(
\r
474 port1->block( )->namePort( ).toStdString( ),
\r
475 port2->block( )->namePort( ).toStdString( ),
\r
476 this->m_ActualConnection
\r
480 delete this->m_ActualConnection;
\r
483 delete this->m_ActualConnection;
\r
486 delete this->m_ActualConnection;
\r
487 this->m_ActualConnection = NULL;
\r
495 // -------------------------------------------------------------------------
\r
496 cpPipelineEditor_Editor_Callback_CODE( Move )
\r
500 // -------------------------------------------------------------------------
\r
501 cpPipelineEditor_Editor_Callback_CODE( Resize )
\r
505 // -------------------------------------------------------------------------
\r
506 cpPipelineEditor_Editor_Callback_CODE( Wheel )
\r