~ubuntu-branches/ubuntu/raring/openwalnut/raring

« back to all changes in this revision

Viewing changes to src/qt4gui/qt4/networkEditor/WQtNetworkEditor.cpp

  • Committer: Package Import Robot
  • Author(s): Sebastian Eichelbaum
  • Date: 2012-12-12 11:26:32 UTC
  • mfrom: (3.1.1 sid)
  • Revision ID: package-import@ubuntu.com-20121212112632-xhiuwkxuz5h0idkh
Tags: 1.3.1+hg5849-1
* Minor changes compared to 1.3.0 but included several bug fixes.
* See http://www.openwalnut.org/versions/4

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
//---------------------------------------------------------------------------
2
 
//
3
 
// Project: OpenWalnut ( http://www.openwalnut.org )
4
 
//
5
 
// Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
6
 
// For more information see http://www.openwalnut.org/copying
7
 
//
8
 
// This file is part of OpenWalnut.
9
 
//
10
 
// OpenWalnut is free software: you can redistribute it and/or modify
11
 
// it under the terms of the GNU Lesser General Public License as published by
12
 
// the Free Software Foundation, either version 3 of the License, or
13
 
// (at your option) any later version.
14
 
//
15
 
// OpenWalnut is distributed in the hope that it will be useful,
16
 
// but WITHOUT ANY WARRANTY; without even the implied warranty of
17
 
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
 
// GNU Lesser General Public License for more details.
19
 
//
20
 
// You should have received a copy of the GNU Lesser General Public License
21
 
// along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
22
 
//
23
 
//---------------------------------------------------------------------------
24
 
 
25
 
#include <string>
26
 
#include <cstdlib>
27
 
#include <iostream>
28
 
 
29
 
#include <boost/shared_ptr.hpp>
30
 
 
31
 
#include <QtGui/QKeyEvent>
32
 
#include <QtGui/QGraphicsView>
33
 
#include <QtGui/QGraphicsItem>
34
 
#include <QtGui/QGraphicsItemGroup>
35
 
 
36
 
#include "../WMainWindow.h"
37
 
#include "WQtNetworkPort.h"
38
 
 
39
 
#include "core/kernel/combiner/WDisconnectCombiner.h"
40
 
#include "core/kernel/WKernel.h"
41
 
#include "core/kernel/WModule.h"
42
 
#include "core/kernel/WModuleFactory.h"
43
 
#include "../controlPanel/WQtControlPanel.h"
44
 
#include "../events/WEventTypes.h"
45
 
#include "../events/WModuleAssocEvent.h"
46
 
#include "../events/WModuleConnectEvent.h"
47
 
#include "../events/WModuleDeleteEvent.h"
48
 
#include "../events/WModuleDisconnectEvent.h"
49
 
#include "../events/WModuleReadyEvent.h"
50
 
#include "../events/WModuleRemovedEvent.h"
51
 
 
52
 
#include "WQtNetworkEditor.h"
53
 
#include "WQtNetworkEditor.moc"
54
 
 
55
 
WQtNetworkEditor::WQtNetworkEditor( WMainWindow* parent )
56
 
    : QDockWidget( "Module Graph", parent ),
57
 
    timerId( 0 )
58
 
{
59
 
    setObjectName( "Module Graph Dock" );
60
 
    m_mainWindow = parent;
61
 
 
62
 
    QWidget *panel = new QWidget( this );
63
 
 
64
 
    QGraphicsView *view = new QGraphicsView();
65
 
    view->setDragMode( QGraphicsView::RubberBandDrag );
66
 
    view->setRenderHint( QPainter::Antialiasing );
67
 
    view->setMinimumSize( 20, 20 );
68
 
 
69
 
    m_scene = new WQtNetworkScene();
70
 
//    m_scene->setSceneRect( -200.0, -200.0, 400.0, 400.0 );
71
 
    m_scene->setSceneRect( m_scene->itemsBoundingRect() );
72
 
 
73
 
    view->setScene( m_scene );
74
 
 
75
 
    QVBoxLayout *layout = new QVBoxLayout;
76
 
    layout->addWidget( view );
77
 
 
78
 
    panel->setLayout( layout );
79
 
 
80
 
    this->setAllowedAreas( Qt::AllDockWidgetAreas );
81
 
    this->setFeatures( QDockWidget::DockWidgetClosable |QDockWidget::DockWidgetMovable | QDockWidget::DockWidgetFloatable );
82
 
    setWidget( panel );
83
 
    connect( m_scene, SIGNAL( selectionChanged() ), this, SLOT( selectItem() ) );
84
 
 
85
 
    // this fakeitem is added to the scene to get a better behavior of the forced
86
 
    // based layout. ALL WQtNetworkItems in the scene are "connected" to this
87
 
    // object to avoid that conneceted groups push away each other.
88
 
    QGraphicsRectItem *fake = new QGraphicsRectItem();
89
 
    fake->setRect( 0, 0, 10, 10 );
90
 
    fake->setPos( 0, 0 );
91
 
    fake->setBrush( Qt::green );
92
 
    fake->setFlag( QGraphicsItem::ItemIsMovable, true );
93
 
    m_scene->addItem( fake );
94
 
    m_scene->setFakeItem( fake );
95
 
 
96
 
    m_layout = new WNetworkLayout();
97
 
}
98
 
 
99
 
WQtNetworkEditor::~WQtNetworkEditor()
100
 
{
101
 
    delete m_layout;
102
 
}
103
 
 
104
 
void WQtNetworkEditor::selectItem()
105
 
{
106
 
    boost::shared_ptr< WModule > module;
107
 
 
108
 
    if( m_scene->selectedItems().size() != 0 &&
109
 
         m_scene->selectedItems().at( 0 )->type() == WQtNetworkItem::Type )
110
 
    {
111
 
        if( m_scene->selectedItems().at(0)->type() == WQtNetworkItem::Type )
112
 
        {
113
 
            module = ( static_cast< WQtNetworkItem* >( m_scene->selectedItems().at( 0 ) ) )->getModule();
114
 
        }
115
 
 
116
 
        // crashed modules should not provide any props
117
 
        if( module->isCrashed()() )
118
 
        {
119
 
             return;
120
 
        }
121
 
 
122
 
        m_mainWindow->getControlPanel()->setNewActiveModule( module );
123
 
    }
124
 
    else
125
 
    {
126
 
        m_mainWindow->getControlPanel()->setNewActiveModule( module );
127
 
    }
128
 
}
129
 
 
130
 
void WQtNetworkEditor::deleteSelectedItems()
131
 
{
132
 
    QList< WQtNetworkItem *> itemList;
133
 
    QList< WQtNetworkArrow *> arrowList;
134
 
    foreach( QGraphicsItem *item, m_scene->selectedItems() )
135
 
    {
136
 
        if( item->type() == WQtNetworkItem::Type )
137
 
        {
138
 
            WQtNetworkItem *netItem = qgraphicsitem_cast<WQtNetworkItem *>( item );
139
 
            itemList.append( netItem );
140
 
        }
141
 
        else if( item->type() == WQtNetworkArrow::Type )
142
 
        {
143
 
            WQtNetworkArrow *netArrow = qgraphicsitem_cast<WQtNetworkArrow *>( item );
144
 
            arrowList.append( netArrow );
145
 
        }
146
 
    }
147
 
 
148
 
    foreach( WQtNetworkArrow *ar, arrowList )
149
 
    {
150
 
        if( ar != 0 )
151
 
        {
152
 
            boost::shared_ptr< WDisconnectCombiner > disconnectCombiner =
153
 
                boost::shared_ptr< WDisconnectCombiner >( new WDisconnectCombiner(
154
 
                            ar->getStartPort()->getConnector()->getModule(),
155
 
                            ar->getStartPort()->getConnector()->getName(),
156
 
                            ar->getEndPort()->getConnector()->getModule(),
157
 
                            ar->getEndPort()->getConnector()->getName() ) );
158
 
            disconnectCombiner->run();
159
 
            disconnectCombiner->wait();
160
 
        }
161
 
    }
162
 
 
163
 
    foreach( WQtNetworkItem *it, itemList )
164
 
    {
165
 
        if( it != 0 )
166
 
        {
167
 
            WKernel::getRunningKernel()->getRootContainer()->remove( it->getModule() );
168
 
            m_scene->removeItem( it );
169
 
        }
170
 
    }
171
 
    itemList.clear();
172
 
    arrowList.clear();
173
 
}
174
 
 
175
 
void WQtNetworkEditor::addModule( boost::shared_ptr< WModule > module )
176
 
{
177
 
    WQtNetworkItem *netItem = new WQtNetworkItem( this, module );
178
 
    m_items.push_back( netItem );
179
 
 
180
 
    // set the object at a random start position
181
 
    time( &m_time );
182
 
    netItem->setPos( ( std::rand() + m_time ) % 200, ( std::rand() + m_time ) % 200 );  // NOLINT - no we want std::rand instead of rand_r
183
 
 
184
 
    m_scene->addItem( netItem );
185
 
 
186
 
    //itemMoved();
187
 
}
188
 
 
189
 
bool WQtNetworkEditor::event( QEvent* event )
190
 
{
191
 
    // a module got associated with the root container -> add it to the list
192
 
    if( event->type() == WQT_ASSOC_EVENT )
193
 
    {
194
 
        // convert event to assoc event
195
 
        WModuleAssocEvent* e1 = dynamic_cast< WModuleAssocEvent* >( event );     // NOLINT
196
 
        if( e1 )
197
 
        {
198
 
            WLogger::getLogger()->addLogMessage( "Inserting \"" + e1->getModule()->getName() + "\".",
199
 
                                                "NetworkEditor", LL_DEBUG );
200
 
            //addModule( e1->getModule() );
201
 
            WQtNetworkItem *item = new WQtNetworkItem( this, e1->getModule() );
202
 
            m_items.push_back( item );
203
 
            m_layout->addItem( item );
204
 
            m_scene->addItem( item );
205
 
        }
206
 
 
207
 
        //TODO(skiunke): disablen des moduls solange nicht rdy!
208
 
        return true;
209
 
    }
210
 
 
211
 
    // a module changed its state to "ready" -> activate it in dataset browser
212
 
    if( event->type() == WQT_READY_EVENT )
213
 
    {
214
 
        // convert event to ready event
215
 
        WModuleReadyEvent* e = dynamic_cast< WModuleReadyEvent* >( event );     // NOLINT
216
 
        if( !e )
217
 
        {
218
 
            // this should never happen, since the type is set to WQT_READY_EVENT.
219
 
            WLogger::getLogger()->addLogMessage( "Event is not an WModueReadyEvent although its type claims it. Ignoring event.",
220
 
                                                 "NetworkEditor", LL_WARNING );
221
 
 
222
 
            return true;
223
 
        }
224
 
 
225
 
        WLogger::getLogger()->addLogMessage( "Activating \"" + e->getModule()->getName() + "\".",
226
 
                                             "NetworkEditor", LL_DEBUG );
227
 
 
228
 
        // search all the item matching the module
229
 
        WQtNetworkItem *item = findItemByModule( e->getModule() );
230
 
        if( item != 0 )
231
 
        {
232
 
            item->activate( true );
233
 
        }
234
 
 
235
 
        return true;
236
 
    }
237
 
 
238
 
    // a module tree item was connected to another one
239
 
    if( event->type() == WQT_MODULE_CONNECT_EVENT )
240
 
    {
241
 
        WModuleConnectEvent* e = dynamic_cast< WModuleConnectEvent* >( event );     // NOLINT
242
 
        if( !e )
243
 
        {
244
 
            // this should never happen, since the type is set to WQT_MODULE_CONNECT_EVENT.
245
 
            WLogger::getLogger()->addLogMessage( "Event is not an WModuleConnectEvent although its type claims it. Ignoring event.",
246
 
                                                 "NetworkEditor", LL_WARNING );
247
 
            return true;
248
 
        }
249
 
 
250
 
        WLogger::getLogger()->addLogMessage( "Connecting \"" + e->getInput()->getModule()->getName() +
251
 
                "\" and \"" + e->getOutput()->getModule()->getName() + "\".", "NetworkEditor", LL_DEBUG );
252
 
 
253
 
        boost::shared_ptr< WModule > mIn;
254
 
        boost::shared_ptr< WModule > mOut;
255
 
 
256
 
        if( e->getInput()->isInputConnector() == true &&
257
 
            e->getOutput()->isOutputConnector() == true )
258
 
        {
259
 
            mIn = e->getInput()->getModule();
260
 
            mOut = e->getOutput()->getModule();
261
 
        }
262
 
        else if( e->getInput()->isOutputConnector() == true &&
263
 
                    e->getOutput()->isInputConnector() == true )
264
 
        {
265
 
            mIn = e->getOutput()->getModule();
266
 
            mOut = e->getInput()->getModule();
267
 
        }
268
 
        else
269
 
        {
270
 
            return true;
271
 
            //TODO(skiunke): warning
272
 
        }
273
 
 
274
 
        WQtNetworkItem *inItem = findItemByModule( mIn );
275
 
        WQtNetworkItem *outItem = findItemByModule( mOut );
276
 
 
277
 
        WQtNetworkInputPort *ip = NULL;
278
 
        WQtNetworkOutputPort *op = NULL;
279
 
 
280
 
        for( QList< WQtNetworkInputPort* >::const_iterator iter = inItem->getInPorts().begin();
281
 
                iter != inItem->getInPorts().end();
282
 
                ++iter )
283
 
        {
284
 
            WQtNetworkInputPort *inP = dynamic_cast< WQtNetworkInputPort* >( *iter );
285
 
            if( e->getInput() == inP->getConnector() )
286
 
            {
287
 
                ip = inP;
288
 
            }
289
 
        }
290
 
 
291
 
        for( QList< WQtNetworkOutputPort* >::const_iterator iter = outItem->getOutPorts().begin();
292
 
                iter != outItem->getOutPorts().end();
293
 
                ++iter )
294
 
        {
295
 
            WQtNetworkOutputPort *outP = dynamic_cast< WQtNetworkOutputPort* >( *iter );
296
 
            if( e->getOutput() == outP->getConnector() )
297
 
            {
298
 
                op = outP;
299
 
            }
300
 
        }
301
 
 
302
 
        if( ip != NULL &&
303
 
            op != NULL )
304
 
        {
305
 
            WQtNetworkArrow *arrow = new WQtNetworkArrow( op, ip );
306
 
 
307
 
            arrow->setZValue( -1000.0 );
308
 
            op->addArrow( arrow );
309
 
            ip->addArrow( arrow );
310
 
            arrow->updatePosition();
311
 
 
312
 
            m_scene->addItem( arrow );
313
 
 
314
 
            m_layout->connectItems( outItem, inItem );
315
 
        }
316
 
    }
317
 
 
318
 
 
319
 
    // a module tree item was disconnected from another one
320
 
    if( event->type() == WQT_MODULE_DISCONNECT_EVENT )
321
 
    {
322
 
        WModuleDisconnectEvent* e = dynamic_cast< WModuleDisconnectEvent* >( event );     // NOLINT
323
 
        if( !e )
324
 
        {
325
 
            // this should never happen, since the type is set to WQT_MODULE_DISCONNECT_EVENT.
326
 
            WLogger::getLogger()->addLogMessage( "Event is not an WModuleDisconnectEvent although its type claims it. Ignoring event.",
327
 
                                                 "NetworkEditor", LL_WARNING );
328
 
            return true;
329
 
        }
330
 
 
331
 
        WLogger::getLogger()->addLogMessage( "Disconnecting \"" + e->getInput()->getCanonicalName() +
332
 
                                             "\" and \"" + e->getOutput()->getCanonicalName() +
333
 
                                             "\"." , "NetworkEditor", LL_DEBUG );
334
 
 
335
 
        boost::shared_ptr< WModule > mIn;
336
 
        boost::shared_ptr< WModule > mOut;
337
 
 
338
 
        if( e->getInput()->isInputConnector() == true &&
339
 
            e->getOutput()->isOutputConnector() == true )
340
 
        {
341
 
            mIn = e->getInput()->getModule();
342
 
            mOut = e->getOutput()->getModule();
343
 
        }
344
 
        else if( e->getInput()->isOutputConnector() == true &&
345
 
                    e->getOutput()->isInputConnector() == true )
346
 
        {
347
 
            mIn = e->getOutput()->getModule();
348
 
            mOut = e->getInput()->getModule();
349
 
        }
350
 
        else
351
 
        {
352
 
            return true;
353
 
            //TODO(skiunke): warning
354
 
        }
355
 
 
356
 
 
357
 
        WQtNetworkItem *inItem = findItemByModule( mIn );
358
 
        WQtNetworkItem *outItem = findItemByModule( mOut );
359
 
 
360
 
        WQtNetworkInputPort *ip = NULL;
361
 
        WQtNetworkOutputPort *op = NULL;
362
 
 
363
 
        for( QList< WQtNetworkInputPort* >::const_iterator iter = inItem->getInPorts().begin();
364
 
            iter != inItem->getInPorts().end();
365
 
            ++iter )
366
 
        {
367
 
           WQtNetworkInputPort *inP = dynamic_cast< WQtNetworkInputPort* >( *iter );
368
 
           if( e->getInput() == inP->getConnector() )
369
 
           {
370
 
               ip = inP;
371
 
           }
372
 
        }
373
 
            for( QList< WQtNetworkOutputPort* >::const_iterator iter = outItem->getOutPorts().begin();
374
 
                    iter != outItem->getOutPorts().end();
375
 
                    ++iter )
376
 
            {
377
 
                WQtNetworkOutputPort *outP = dynamic_cast< WQtNetworkOutputPort* >( *iter );
378
 
                if( e->getOutput() == outP->getConnector() )
379
 
                {
380
 
                    op = outP;
381
 
                }
382
 
            }
383
 
 
384
 
        WQtNetworkArrow *ar = NULL;
385
 
 
386
 
        for( QList< QGraphicsItem * >::const_iterator iter = m_scene->items().begin();
387
 
                iter != m_scene->items().end();
388
 
                ++iter )
389
 
        {
390
 
            ar = dynamic_cast< WQtNetworkArrow* >( *iter );
391
 
            if( ar &&
392
 
                ar->getStartPort() == op &&
393
 
                ar->getEndPort() == ip )
394
 
            {
395
 
                break;
396
 
            }
397
 
        }
398
 
        if( ar )
399
 
        {
400
 
            m_layout->disconnectNodes( outItem, inItem );
401
 
 
402
 
            op->removeArrow( ar );
403
 
            ip->removeArrow( ar );
404
 
            if( ar->scene() != NULL )
405
 
            {
406
 
                m_scene->removeItem( ar );
407
 
            }
408
 
            delete ar;
409
 
        }
410
 
        else
411
 
        {
412
 
            WLogger::getLogger()->addLogMessage( "Arrow not found!.", "NetworkEditor", LL_ERROR );
413
 
        }
414
 
 
415
 
        return true;
416
 
    }
417
 
 
418
 
    // a module was removed from the container
419
 
    if( event->type() == WQT_MODULE_REMOVE_EVENT )
420
 
    {
421
 
        WModuleRemovedEvent* e = dynamic_cast< WModuleRemovedEvent* >( event );
422
 
        if( !e )
423
 
        {
424
 
            // this should never happen, since the type is set to WQT_MODULE_REMOVE_EVENT.
425
 
            WLogger::getLogger()->addLogMessage( "Event is not an WModuleRemovedEvent although its type claims it. Ignoring event.",
426
 
                                                 "NetworkEditor", LL_WARNING );
427
 
            return true;
428
 
        }
429
 
 
430
 
        WLogger::getLogger()->addLogMessage( "Removing \"" + e->getModule()->getName() + "\".",
431
 
                                             "NetworkEditor", LL_DEBUG );
432
 
 
433
 
 
434
 
        WQtNetworkItem *item = findItemByModule( e->getModule() );
435
 
        if( item != 0 )
436
 
        {
437
 
            item->activate( false );
438
 
            e->getModule()->requestStop();
439
 
        }
440
 
 
441
 
        return true;
442
 
    }
443
 
 
444
 
    // a module tree item should be deleted
445
 
    if( event->type() == WQT_MODULE_DELETE_EVENT )
446
 
    {
447
 
        WModuleDeleteEvent* e = dynamic_cast< WModuleDeleteEvent* >( event );
448
 
        if( !e )
449
 
        {
450
 
            // this should never happen, since the type is set to WQT_MODULE_REMOVE_EVENT.
451
 
            WLogger::getLogger()->addLogMessage( "Event is not an WModuleRemovedEvent although"
452
 
                                                 "its type claims it. Ignoring event.",
453
 
                                                 "NetworkEditor", LL_WARNING );
454
 
            return true;
455
 
        }
456
 
 
457
 
        WLogger::getLogger()->addLogMessage( "Deleting \"" + e->getTreeItem()->getModule()->getName() + "\".",
458
 
                                             "NetworkEditor", LL_DEBUG );
459
 
 
460
 
        WQtNetworkItem *item = findItemByModule( e->getTreeItem()->getModule() );
461
 
 
462
 
        if( item != 0 )
463
 
        {
464
 
            m_layout->removeItem( item );
465
 
 
466
 
            if( item->scene() != NULL )
467
 
            {
468
 
                m_scene->removeItem( item );
469
 
            }
470
 
            m_items.removeAll( item );
471
 
            delete item;
472
 
        }
473
 
 
474
 
        return true;
475
 
    }
476
 
 
477
 
    return QDockWidget::event( event );
478
 
}
479
 
 
480
 
WQtNetworkItem* WQtNetworkEditor::findItemByModule( boost::shared_ptr< WModule > module )
481
 
{
482
 
    for( QList< WQtNetworkItem* >::const_iterator iter = m_items.begin(); iter != m_items.end(); ++iter )
483
 
    {
484
 
       WQtNetworkItem *itemModule = dynamic_cast< WQtNetworkItem* >( *iter );
485
 
       if( itemModule && itemModule->getModule() == module )
486
 
       {
487
 
           return itemModule;
488
 
       }
489
 
    }
490
 
    return 0;
491
 
}
492
 
 
493
 
void WQtNetworkEditor::itemMoved()
494
 
{
495
 
    if( !timerId )
496
 
        timerId = startTimer( 1000 / 25 );
497
 
}
498
 
 
499
 
void WQtNetworkEditor::timerEvent( QTimerEvent* /*event*/ )
500
 
{
501
 
    //Q_UNUSED( event );
502
 
 
503
 
    //QList< WQtNetworkItem *> items;
504
 
    //foreach( QGraphicsItem *item, m_scene->items() )
505
 
    //{
506
 
    //    if( WQtNetworkItem *netItem = dynamic_cast< WQtNetworkItem  *>( item ) )
507
 
    //        items << netItem;
508
 
    //}
509
 
 
510
 
    //foreach( WQtNetworkItem *netItem, items )
511
 
    //    netItem->calculateForces();
512
 
 
513
 
    //bool itemsMoved = false;
514
 
    //foreach( WQtNetworkItem *netItem, items )
515
 
    //{
516
 
    //    if( netItem->advance() )
517
 
    //        itemsMoved = true;
518
 
    //}
519
 
 
520
 
    //if( !itemsMoved )
521
 
    //{
522
 
    //    killTimer( timerId );
523
 
    //    timerId = 0;
524
 
    //}
525
 
}
526