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

« back to all changes in this revision

Viewing changes to src/qt4gui/controlPanel/WQtControlPanel.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 <iostream>
 
26
#include <list>
 
27
#include <map>
 
28
#include <set>
 
29
#include <string>
 
30
#include <vector>
 
31
 
 
32
#include <QtCore/QList>
 
33
#include <QtGui/QMenu>
 
34
#include <QtGui/QScrollArea>
 
35
#include <QtGui/QShortcut>
 
36
#include <QtGui/QSplitter>
 
37
#include <QtGui/QMessageBox>
 
38
 
 
39
#include "core/common/WLogger.h"
 
40
#include "core/common/WPredicateHelper.h"
 
41
#include "core/dataHandler/WDataSet.h"
 
42
#include "core/kernel/WDataModule.h"
 
43
#include "core/kernel/WKernel.h"
 
44
#include "core/kernel/WModule.h"
 
45
#include "core/kernel/WModuleContainer.h"
 
46
#include "core/kernel/WModuleFactory.h"
 
47
#include "core/kernel/WROIManager.h"
 
48
#include "../WMainWindow.h"
 
49
#include "../WQt4Gui.h"
 
50
#include "../WQtCombinerActionList.h"
 
51
#include "../WQtModuleConfig.h"
 
52
#include "../events/WEventTypes.h"
 
53
#include "../events/WModuleAssocEvent.h"
 
54
#include "../events/WModuleConnectEvent.h"
 
55
#include "../events/WModuleConnectorEvent.h"
 
56
#include "../events/WModuleDeleteEvent.h"
 
57
#include "../events/WModuleDisconnectEvent.h"
 
58
#include "../events/WModuleReadyEvent.h"
 
59
#include "../events/WModuleRemovedEvent.h"
 
60
#include "../events/WRoiAssocEvent.h"
 
61
#include "../events/WRoiRemoveEvent.h"
 
62
#include "../guiElements/WQtModuleMetaInfo.h"
 
63
#include "../guiElements/WQtMenuFiltered.h"
 
64
#include "../networkEditor/WQtNetworkEditor.h"
 
65
#include "WQtBranchTreeItem.h"
 
66
#include "WQtColormapper.h"
 
67
 
 
68
#include "WQtControlPanel.h"
 
69
#include "WQtControlPanel.moc"
 
70
 
 
71
WQtControlPanel::WQtControlPanel( WMainWindow* parent )
 
72
    : QDockWidget( "Control Panel", parent ),
 
73
    m_ignoreSelectionChange( false ),
 
74
    m_activeModule( WModule::SPtr() ),
 
75
    m_previousTab()
 
76
{
 
77
    setObjectName( "Control Panel Dock" );
 
78
 
 
79
    m_mainWindow = parent;
 
80
    setMinimumWidth( 200 );
 
81
 
 
82
    m_moduleTreeWidget = new WQtTreeWidget();
 
83
    m_moduleTreeWidget->setContextMenuPolicy( Qt::ActionsContextMenu );
 
84
 
 
85
    m_moduleTreeWidget->setHeaderLabel( QString( "Module Tree" ) );
 
86
    m_moduleTreeWidget->setDragEnabled( false );
 
87
    m_moduleTreeWidget->viewport()->setAcceptDrops( true );
 
88
    m_moduleTreeWidget->setDropIndicatorShown( true );
 
89
    m_moduleTreeWidget->setMinimumHeight( 100 );
 
90
 
 
91
    // create context menu for tree items
 
92
 
 
93
    // a separator to clean up the tree widget's context menu
 
94
    QAction* separator = new QAction( m_moduleTreeWidget );
 
95
    separator->setSeparator( true );
 
96
    m_moduleTreeWidget->addAction( separator );
 
97
 
 
98
    m_addModuleAction = new QAction( WQt4Gui::getMainWindow()->getIconManager()->getIcon( "add" ), "Add Module", m_moduleTreeWidget );
 
99
    m_moduleTreeWidget->addAction( m_addModuleAction );
 
100
    m_connectWithPrototypeAction = new QAction( WQt4Gui::getMainWindow()->getIconManager()->getIcon( "addAndLink" ), "Add Module and Connect",
 
101
                                                m_moduleTreeWidget );
 
102
    m_moduleTreeWidget->addAction( m_connectWithPrototypeAction );
 
103
    m_connectWithModuleAction = new QAction( WQt4Gui::getMainWindow()->getIconManager()->getIcon( "link" ), "Connect Existing Module",
 
104
                                            m_moduleTreeWidget );
 
105
    m_moduleTreeWidget->addAction( m_connectWithModuleAction );
 
106
    m_disconnectAction = new QAction( WQt4Gui::getMainWindow()->getIconManager()->getIcon( "unlink" ), "Disconnect", m_moduleTreeWidget );
 
107
    m_moduleTreeWidget->addAction( m_disconnectAction );
 
108
 
 
109
    // a separator to clean up the tree widget's context menu
 
110
    m_moduleTreeWidget->addAction( separator );
 
111
 
 
112
    m_deleteModuleAction = new QAction( WQt4Gui::getMainWindow()->getIconManager()->getIcon( "remove" ), "Remove Module", m_moduleTreeWidget );
 
113
    {
 
114
        // Set the key for removing modules
 
115
        //m_deleteModuleAction->setShortcutContext( Qt::WidgetShortcut );
 
116
        m_deleteModuleAction->setShortcutContext( Qt::WidgetWithChildrenShortcut );
 
117
        m_deleteModuleAction->setShortcut( QKeySequence::Delete );
 
118
        m_deleteModuleAction->setIconVisibleInMenu( true );
 
119
    }
 
120
    connect( m_deleteModuleAction, SIGNAL( triggered() ), this, SLOT( deleteModule() ) );
 
121
    m_moduleTreeWidget->addAction( m_deleteModuleAction );
 
122
 
 
123
    // a separator to clean up the tree widget's context menu
 
124
    m_moduleTreeWidget->addAction( separator );
 
125
 
 
126
    // add an entry for those who search their module without luck
 
127
    m_missingModuleAction = new QAction( WQt4Gui::getMainWindow()->getIconManager()->getIcon( "missingModule" ), "Missing Module?",
 
128
                                          m_moduleTreeWidget );
 
129
    m_missingModuleAction->setToolTip( "Having trouble finding your module? This opens the module configuration, which allows you to define the "
 
130
                                       "modules that should be shown or hidden." );
 
131
    m_missingModuleAction->setIconVisibleInMenu( true );
 
132
    m_moduleTreeWidget->addAction( m_missingModuleAction );
 
133
 
 
134
    // the network editor also needs the context menu
 
135
    if( m_mainWindow->getNetworkEditor() )
 
136
    {
 
137
        m_mainWindow->getNetworkEditor()->getView()->setContextMenuPolicy( Qt::ActionsContextMenu );
 
138
        m_mainWindow->getNetworkEditor()->getView()->addAction( m_addModuleAction );
 
139
        m_mainWindow->getNetworkEditor()->getView()->addAction( m_connectWithPrototypeAction );
 
140
        m_mainWindow->getNetworkEditor()->getView()->addAction( m_connectWithModuleAction );
 
141
        m_mainWindow->getNetworkEditor()->getView()->addAction( m_disconnectAction );
 
142
        m_mainWindow->getNetworkEditor()->getView()->addAction( m_deleteModuleAction );
 
143
        m_mainWindow->getNetworkEditor()->getView()->addAction( separator );
 
144
        m_mainWindow->getNetworkEditor()->getView()->addAction( m_missingModuleAction );
 
145
    }
 
146
 
 
147
    m_colormapper = new WQtColormapper( m_mainWindow );
 
148
    m_colormapper->setToolTip( "Reorder the textures." );
 
149
 
 
150
    m_tabWidget = new QTabWidget(  );
 
151
    m_tabWidget->setMinimumHeight( 100 );
 
152
 
 
153
    m_moduleDock = new QDockWidget( "Module Tree", m_mainWindow );
 
154
    m_moduleDock->setObjectName( "Module Dock" );
 
155
    m_moduleDock->setWidget( m_moduleTreeWidget );
 
156
 
 
157
    m_roiDock = new QDockWidget( "ROIs", m_mainWindow );
 
158
    m_roiDock->setObjectName( "ROI Dock" );
 
159
    m_roiTreeWidget = new WQtTreeWidget();
 
160
    m_roiTreeWidget->setToolTip( "Regions of intrest (ROIs) for selecting fiber  clusters. Branches are combined using logic <b>or</b>, "
 
161
                                 "inside the branches the ROIs are combined using logic <b>and</b>." );
 
162
    m_roiTreeWidget->setHeaderLabel( QString( "ROIs" ) );
 
163
    m_roiTreeWidget->setHeaderHidden( true );
 
164
    m_roiTreeWidget->setDragEnabled( true );
 
165
    m_roiTreeWidget->viewport()->setAcceptDrops( true );
 
166
    m_roiTreeWidget->setDropIndicatorShown( true );
 
167
    m_roiTreeWidget->setDragDropMode( QAbstractItemView::InternalMove );
 
168
    m_roiDock->setWidget( m_roiTreeWidget );
 
169
 
 
170
    m_moduleExcluder = new WQtModuleConfig( parent );
 
171
    connect( m_missingModuleAction, SIGNAL( triggered( bool ) ), m_moduleExcluder, SLOT( configure() ) );
 
172
 
 
173
    this->setAllowedAreas( Qt::AllDockWidgetAreas );
 
174
    this->setFeatures( QDockWidget::DockWidgetClosable | QDockWidget::DockWidgetMovable | QDockWidget::DockWidgetFloatable );
 
175
    this->setWidget( m_tabWidget );
 
176
 
 
177
    m_tiModules = new WQtModuleHeaderTreeItem( m_moduleTreeWidget );
 
178
    m_tiModules->setText( 0, QString( "Subject-independent Modules" ) );
 
179
    m_tiModules->setToolTip( 0, "Subject-independent modules and modules for which no parent module could be detected." );
 
180
    m_tiRois = new WQtRoiHeaderTreeItem( m_roiTreeWidget );
 
181
    m_tiRois->setText( 0, QString( "ROIs" ) );
 
182
 
 
183
    connectSlots();
 
184
 
 
185
    // similar to the module delete action: a ROI delete action
 
186
    m_deleteRoiAction = new QAction( WQt4Gui::getMainWindow()->getIconManager()->getIcon( "remove" ), "Remove ROI", m_roiTreeWidget );
 
187
    {
 
188
        // Set the key for removing modules
 
189
        m_deleteRoiAction->setShortcutContext( Qt::WidgetShortcut );
 
190
        m_deleteRoiAction->setShortcut( QKeySequence::Delete );
 
191
        m_deleteRoiAction->setIconVisibleInMenu( true );
 
192
    }
 
193
    connect( m_deleteRoiAction, SIGNAL( triggered() ), this, SLOT( deleteROITreeItem() ) );
 
194
    m_roiTreeWidget->addAction( m_deleteModuleAction );
 
195
    m_roiTreeWidget->addAction( m_deleteRoiAction );
 
196
}
 
197
 
 
198
WQtControlPanel::~WQtControlPanel()
 
199
{
 
200
}
 
201
 
 
202
void WQtControlPanel::completeGuiSetup()
 
203
{
 
204
    m_mainWindow->addGlobalMenu( m_mainWindow->getNetworkEditor()->getView() );
 
205
}
 
206
 
 
207
void WQtControlPanel::connectSlots()
 
208
{
 
209
    // if the user changes some white/blacklist setting: update.
 
210
    connect( m_moduleExcluder, SIGNAL( updated() ), this, SLOT( reselectTreeItem() ) );
 
211
    connect( m_moduleTreeWidget, SIGNAL( itemSelectionChanged() ), this, SLOT( selectTreeItem() ) );
 
212
    connect( m_moduleTreeWidget, SIGNAL( itemClicked( QTreeWidgetItem*, int ) ), this, SLOT( changeTreeItem( QTreeWidgetItem*, int ) ) );
 
213
    connect( m_moduleTreeWidget, SIGNAL( itemClicked( QTreeWidgetItem*, int ) ),  m_roiTreeWidget, SLOT( clearSelection() ) );
 
214
    connect( m_roiTreeWidget, SIGNAL( itemClicked( QTreeWidgetItem*, int ) ), this, SLOT( selectRoiTreeItem() ) );
 
215
    connect( m_roiTreeWidget, SIGNAL( itemClicked( QTreeWidgetItem*, int ) ), m_moduleTreeWidget, SLOT( clearSelection() ) );
 
216
    connect( m_colormapper, SIGNAL( textureSelectionChanged( osg::ref_ptr< WGETexture3D > ) ),
 
217
             this, SLOT( selectDataModule( osg::ref_ptr< WGETexture3D > ) ) );
 
218
    connect( m_roiTreeWidget, SIGNAL( dragDrop() ), this, SLOT( handleRoiDragDrop() ) );
 
219
}
 
220
 
 
221
WQtSubjectTreeItem* WQtControlPanel::addSubject( std::string name )
 
222
{
 
223
    WQtSubjectTreeItem* subject = new WQtSubjectTreeItem( m_moduleTreeWidget );
 
224
    subject->setText( 0, QString::fromStdString( name ) );
 
225
    subject->setToolTip( 0, QString::fromStdString( "All data and modules that are children of this tree item belong to the subject \"" +
 
226
                name + "\"." ) );
 
227
 
 
228
    return subject;
 
229
}
 
230
 
 
231
bool WQtControlPanel::event( QEvent* event )
 
232
{
 
233
    if( event->type() == WQT_ROI_ASSOC_EVENT )
 
234
    {
 
235
        WRoiAssocEvent* e2 = dynamic_cast< WRoiAssocEvent* >( event );     // NOLINT
 
236
        if( e2 )
 
237
        {
 
238
            addRoi( e2->getRoi() );
 
239
            WLogger::getLogger()->addLogMessage( "Inserting ROI to control panel.", "ControlPanel", LL_DEBUG );
 
240
        }
 
241
 
 
242
        return true;
 
243
    }
 
244
    if( event->type() == WQT_ROI_REMOVE_EVENT )
 
245
    {
 
246
        WRoiRemoveEvent* e3 = dynamic_cast< WRoiRemoveEvent* >( event );
 
247
        if( e3 )
 
248
        {
 
249
            removeRoi( e3->getRoi() );
 
250
            WLogger::getLogger()->addLogMessage( "Removing ROI from control panel.", "ControlPanel", LL_DEBUG );
 
251
        }
 
252
 
 
253
        return true;
 
254
    }
 
255
 
 
256
    // a module got associated with the root container -> add it to the list
 
257
    if( event->type() == WQT_ASSOC_EVENT )
 
258
    {
 
259
        // convert event to assoc event
 
260
        WModuleAssocEvent* e1 = dynamic_cast< WModuleAssocEvent* >( event );     // NOLINT
 
261
        if( e1 )
 
262
        {
 
263
            WLogger::getLogger()->addLogMessage( "Inserting module " + e1->getModule()->getName() + " to control panel.",
 
264
                                                 "ControlPanel", LL_DEBUG );
 
265
 
 
266
            // show deprecation message?
 
267
            if( e1->getModule()->isDeprecated() )
 
268
            {
 
269
                std::string d = e1->getModule()->getDeprecationMessage();
 
270
                std::string m = "The module \"" + e1->getModule()->getName() + "\" is marked deprecated. You should avoid using it."
 
271
                                "<br><br>"
 
272
                                "Message: " + d;
 
273
                QMessageBox::warning( this, "Deprecation Warning", QString::fromStdString( m ) );
 
274
            }
 
275
 
 
276
            // finally add the module
 
277
            // TODO(schurade): is this differentiation between data and "normal" modules really needed?
 
278
            if( boost::shared_dynamic_cast< WDataModule >( e1->getModule() ).get() )
 
279
            {
 
280
                addDataset( e1->getModule(), 0 );
 
281
            }
 
282
            else
 
283
            {
 
284
                addModule( e1->getModule() );
 
285
            }
 
286
        }
 
287
        return true;
 
288
    }
 
289
 
 
290
    // a module changed its state to "ready" -> activate it in control panel
 
291
    if( event->type() == WQT_READY_EVENT )
 
292
    {
 
293
        // convert event to assoc event
 
294
        WModuleReadyEvent* e = dynamic_cast< WModuleReadyEvent* >( event );     // NOLINT
 
295
        if( !e )
 
296
        {
 
297
            // this should never happen, since the type is set to WQT_READY_EVENT.
 
298
            WLogger::getLogger()->addLogMessage( "Event is not an WModueReadyEvent although its type claims it. Ignoring event.",
 
299
                                                 "ControlPanel", LL_WARNING );
 
300
 
 
301
            return true;
 
302
        }
 
303
 
 
304
        std::list< WQtTreeItem* > items = findItemsByModule( e->getModule() );
 
305
        for( std::list< WQtTreeItem* >::const_iterator it = items.begin(); it != items.end(); ++it )
 
306
        {
 
307
            ( *it )->setDisabled( false );
 
308
        }
 
309
 
 
310
        setActiveModule( e->getModule() );
 
311
 
 
312
        return true;
 
313
    }
 
314
 
 
315
    // a module tree item was connected to another one
 
316
    if( event->type() == WQT_MODULE_CONNECT_EVENT )
 
317
    {
 
318
        WModuleConnectEvent* e = dynamic_cast< WModuleConnectEvent* >( event );     // NOLINT
 
319
        if( !e )
 
320
        {
 
321
            // this should never happen, since the type is set to WQT_MODULE_CONNECT_EVENT.
 
322
            WLogger::getLogger()->addLogMessage( "Event is not an WModuleConnectEvent although its type claims it. Ignoring event.",
 
323
                                                 "ControlPanel", LL_WARNING );
 
324
            return true;
 
325
        }
 
326
 
 
327
        // get the module of the input involved in this connection
 
328
        boost::shared_ptr< WModule > mIn = e->getInput()->getModule();
 
329
        boost::shared_ptr< WModule > mOut = e->getOutput()->getModule();
 
330
 
 
331
        // NOTE: the following is ugly. We definitely should rethink our GUI
 
332
 
 
333
        // at this moment items for each input connector are inside the tree.
 
334
        // search the items not yet associated with some other module for the first item
 
335
        std::list< WQtTreeItem* > items = findItemsByModule( mIn, m_tiModules );
 
336
        for( std::list< WQtTreeItem* >::const_iterator iter = items.begin(); iter != items.end(); ++iter )
 
337
        {
 
338
            ( *iter )->setHidden( false );
 
339
            ( *iter )->setHandledInput( e->getInput()->getName() );
 
340
            ( *iter )->setHandledOutput( e->getOutput()->getName() );
 
341
 
 
342
            // move it to the module with the involved output
 
343
            std::list< WQtTreeItem* > possibleParents = findItemsByModule( mOut );
 
344
            for( std::list< WQtTreeItem* >::const_iterator parIter = possibleParents.begin(); parIter != possibleParents.end(); ++parIter )
 
345
            {
 
346
                // remove child from tiModules
 
347
                m_tiModules->removeChild( *iter );
 
348
                if( !( *parIter )->isHidden() )
 
349
                {
 
350
                    ( *parIter )->addChild( *iter );
 
351
                    ( *parIter )->setExpanded( true );
 
352
                    break;
 
353
                }
 
354
            }
 
355
 
 
356
            // job done.
 
357
            break;
 
358
        }
 
359
    }
 
360
 
 
361
    // a module tree item was disconnected from another one
 
362
    if( event->type() == WQT_MODULE_DISCONNECT_EVENT )
 
363
    {
 
364
        WModuleDisconnectEvent* e = dynamic_cast< WModuleDisconnectEvent* >( event );     // NOLINT
 
365
        if( !e )
 
366
        {
 
367
            // this should never happen, since the type is set to WQT_MODULE_DISCONNECT_EVENT.
 
368
            WLogger::getLogger()->addLogMessage( "Event is not an WModuleDisconnectEvent although its type claims it. Ignoring event.",
 
369
                                                 "ControlPanel", LL_WARNING );
 
370
            return true;
 
371
        }
 
372
 
 
373
        // get the module of the input involved in this connection
 
374
        boost::shared_ptr< WModule > mIn = e->getInput()->getModule();
 
375
        boost::shared_ptr< WModule > mOut = e->getOutput()->getModule();
 
376
 
 
377
        // NOTE: the following is ugly. We definitely should rethink our GUI
 
378
 
 
379
        // at this moment items for each input connector are inside the tree.
 
380
        // search all items an find those containing a children which belongs to the connection input
 
381
        std::list< WQtTreeItem* > items = findItemsByModule( mOut );
 
382
        for( std::list< WQtTreeItem* >::const_iterator iter = items.begin(); iter != items.end(); ++iter )
 
383
        {
 
384
            // each of them can contain a child with the involved input
 
385
            std::list< WQtTreeItem* > childs = findItemsByModule( mIn, *iter );
 
386
            for( std::list< WQtTreeItem* >::const_iterator citer = childs.begin(); citer != childs.end(); ++citer )
 
387
            {
 
388
                if( ( *citer )->getHandledInput() == e->getInput()->getName() )
 
389
                {
 
390
                    ( *iter )->removeChild( *citer );
 
391
 
 
392
                    // move it back to the reservoir in m_tiModules
 
393
                    m_tiModules->addChild( *citer );
 
394
                    ( *citer )->setHidden( true );
 
395
                    ( *citer )->setHandledInput( "" );
 
396
                    ( *citer )->setHandledOutput( "" );
 
397
                }
 
398
            }
 
399
        }
 
400
 
 
401
        // we need to ensure that at least one item for mIn is visible somewhere
 
402
        items = findItemsByModule( mIn );
 
403
        bool oneVisible = false;
 
404
        for( std::list< WQtTreeItem* >::const_iterator iter = items.begin(); iter != items.end(); ++iter )
 
405
        {
 
406
            oneVisible = oneVisible || !( *iter )->isHidden();
 
407
        }
 
408
        if( !oneVisible )
 
409
        {
 
410
            ( *items.begin() )->setHidden( false );
 
411
        }
 
412
    }
 
413
 
 
414
    // a module tree item should be deleted
 
415
    if( event->type() == WQT_MODULE_DELETE_EVENT )
 
416
    {
 
417
        WModuleDeleteEvent* e = dynamic_cast< WModuleDeleteEvent* >( event );
 
418
        if( !e )
 
419
        {
 
420
            // this should never happen, since the type is set to WQT_MODULE_DELETE_EVENT.
 
421
            WLogger::getLogger()->addLogMessage( "Event is not an WModuleDeleteEvent although its type claims it. Ignoring event.",
 
422
                                                 "ControlPanel", LL_WARNING );
 
423
            return true;
 
424
        }
 
425
 
 
426
        // grab the module reference and print some info
 
427
        boost::shared_ptr< WModule > module = e->getTreeItem()->getModule();
 
428
        WLogger::getLogger()->addLogMessage( "Deleting module \"" + module->getName() + "\" from Tree.",
 
429
                                             "ControlPanel", LL_DEBUG );
 
430
 
 
431
        // remove it from the tree and free last ref count
 
432
        m_moduleTreeWidget->deleteItem( e->getTreeItem() );
 
433
 
 
434
        // ref count != 1? (only if there are now tree items left)
 
435
        bool lastTreeItem = !findItemsByModule( module ).size();
 
436
        if( lastTreeItem && ( module.use_count() != 1 ) )
 
437
        {
 
438
            wlog::error( "ControlPanel" ) << "Removed module has strange usage count: " << module.use_count() << ". Should be 1 here. " <<
 
439
                                              "Module reference is held by someone else.";
 
440
        }
 
441
 
 
442
        return true;
 
443
    }
 
444
 
 
445
    // a module was removed from the container
 
446
    if( event->type() == WQT_MODULE_REMOVE_EVENT )
 
447
    {
 
448
        WModuleRemovedEvent* e = dynamic_cast< WModuleRemovedEvent* >( event );
 
449
        if( !e )
 
450
        {
 
451
            // this should never happen, since the type is set to WQT_MODULE_REMOVE_EVENT.
 
452
            WLogger::getLogger()->addLogMessage( "Event is not an WModuleRemovedEvent although its type claims it. Ignoring event.",
 
453
                                                 "ControlPanel", LL_WARNING );
 
454
            return true;
 
455
        }
 
456
 
 
457
        // iterate tree items and find proper one
 
458
        std::list< WQtTreeItem* > items = findItemsByModule( e->getModule() );
 
459
        for( std::list< WQtTreeItem* >::const_iterator iter = items.begin(); iter != items.end(); ++iter )
 
460
        {
 
461
            ( *iter )->gotRemoved();
 
462
        }
 
463
 
 
464
        // be nice and print some info
 
465
        WLogger::getLogger()->addLogMessage( "Removing module \"" + e->getModule()->getName() + "\" from Tree.", "ControlPanel", LL_DEBUG );
 
466
 
 
467
        // stop the module
 
468
        e->getModule()->requestStop();
 
469
        WLogger::getLogger()->addLogMessage( "Waiting for module \"" + e->getModule()->getName() + "\" to finish before deleting.",
 
470
                                             "ControlPanel", LL_DEBUG );
 
471
 
 
472
        return true;
 
473
    }
 
474
 
 
475
    // a connector was updated
 
476
    if( event->type() == WQT_MODULE_CONNECTOR_EVENT )
 
477
    {
 
478
        // convert event to ready event
 
479
        WModuleConnectorEvent* e1 = dynamic_cast< WModuleConnectorEvent* >( event );     // NOLINT
 
480
        if( e1 )
 
481
        {
 
482
            // iterate tree items and find proper one -> check if selected
 
483
            // NOTE: This could return multiple items here. But, the GUI always selects all of the same module or none. So it is enough to check
 
484
            // the first item if it is selected to check whether the current module is active.
 
485
            std::list< WQtTreeItem* > items = findItemsByModule( e1->getModule() );
 
486
            if( !items.empty() && ( *items.begin() )->isSelected() )
 
487
            {
 
488
                // ok, the module is selected. Now, update the connectables lists (buttons and menu)
 
489
                createCompatibleButtons( e1->getModule() );
 
490
            }
 
491
        }
 
492
 
 
493
        return true;
 
494
    }
 
495
 
 
496
    return QDockWidget::event( event );
 
497
}
 
498
 
 
499
std::list< WQtTreeItem* > WQtControlPanel::findItemsByModule( boost::shared_ptr< WModule > module, QTreeWidgetItem* where )
 
500
{
 
501
    std::list< WQtTreeItem* > l;
 
502
 
 
503
    // iterate tree items and find proper one
 
504
    QTreeWidgetItemIterator it( where );
 
505
    while( *it )
 
506
    {
 
507
        WQtTreeItem* item = dynamic_cast< WQtTreeItem* >( *it );
 
508
        boost::shared_ptr< WModule > itemModule = boost::shared_ptr< WModule >();
 
509
        if( item )
 
510
        {
 
511
            itemModule = item->getModule();
 
512
        }
 
513
 
 
514
        // if the pointer is NULL the item was none of the above
 
515
        if( !itemModule.get() )
 
516
        {
 
517
            ++it;
 
518
            continue;
 
519
        }
 
520
 
 
521
        // we found it
 
522
        if( module == itemModule )
 
523
        {
 
524
            l.push_back( item );
 
525
        }
 
526
 
 
527
        ++it;
 
528
    }
 
529
    return l;
 
530
}
 
531
 
 
532
std::list< WQtTreeItem* > WQtControlPanel::findItemsByModule( boost::shared_ptr< WModule > module )
 
533
{
 
534
    std::list< WQtTreeItem* > ret = findItemsByModule( module, m_moduleTreeWidget->invisibleRootItem() );
 
535
    std::list< WQtTreeItem* > ret2 = findItemsByModule( module, m_moduleTreeWidget->topLevelItem( 0 ) );
 
536
    ret.merge( ret2 );
 
537
    return ret;
 
538
}
 
539
 
 
540
WQtDatasetTreeItem* WQtControlPanel::addDataset( boost::shared_ptr< WModule > module, int subjectId )
 
541
{
 
542
    int c = getFirstSubject();
 
543
    WQtSubjectTreeItem* subject = static_cast< WQtSubjectTreeItem* >( m_moduleTreeWidget->topLevelItem( subjectId + c ) );
 
544
    subject->setExpanded( true );
 
545
    WQtDatasetTreeItem* item = subject->addDatasetItem( module );
 
546
    item->setDisabled( true );
 
547
    item->setExpanded( true );
 
548
 
 
549
    return item;
 
550
}
 
551
 
 
552
WQtModuleTreeItem* WQtControlPanel::addModule( boost::shared_ptr< WModule > module )
 
553
{
 
554
    m_tiModules->setExpanded( true );
 
555
    WQtModuleTreeItem* item;
 
556
    // for each input, create an item
 
557
    m_moduleTreeWidget->setCurrentItem( NULL );
 
558
    bool firstItem = true;
 
559
    WModule::InputConnectorList cons = module->getInputConnectors();
 
560
    for( WModule::InputConnectorList::const_iterator iter = cons.begin(); iter != cons.end(); ++iter )
 
561
    {
 
562
        // every module gets added to tiModules first. The connection events then move these things to the right parent
 
563
        item = m_tiModules->addModuleItem( module );
 
564
        item->setDisabled( true );
 
565
        item->setExpanded( true );
 
566
 
 
567
        // all but the first item get hidden by default. They get visible after a connection event has been fired
 
568
        if( !firstItem )
 
569
        {
 
570
            item->setHidden( true );
 
571
        }
 
572
 
 
573
        firstItem = false;
 
574
    }
 
575
 
 
576
    // this module has not inputs. So we simply add it to the tiModules
 
577
    if( firstItem )
 
578
    {
 
579
        item = m_tiModules->addModuleItem( module );
 
580
        item->setDisabled( true );
 
581
    }
 
582
 
 
583
    return item;
 
584
}
 
585
 
 
586
void WQtControlPanel::addRoi( osg::ref_ptr< WROI > roi )
 
587
{
 
588
    WQtRoiTreeItem* newItem;
 
589
    WQtBranchTreeItem* branchItem;
 
590
 
 
591
    m_tiRois->setExpanded( true );
 
592
    bool found = false;
 
593
 
 
594
    // go through all branches
 
595
    for( int branchID = 0; branchID < m_tiRois->childCount(); ++branchID )
 
596
    {
 
597
        branchItem = dynamic_cast< WQtBranchTreeItem* >( m_tiRois->child( branchID ) );
 
598
        // if branch == roi branch
 
599
        if( branchItem->getBranch() == WKernel::getRunningKernel()->getRoiManager()->getBranch( roi ) )
 
600
        {
 
601
            found = true;
 
602
            break;
 
603
        }
 
604
    }
 
605
 
 
606
    if( !found )
 
607
    {
 
608
        branchItem = m_tiRois->addBranch( WKernel::getRunningKernel()->getRoiManager()->getBranch( roi ) );
 
609
    }
 
610
 
 
611
    branchItem->setExpanded( true );
 
612
    newItem = branchItem->addRoiItem( roi );
 
613
    newItem->setDisabled( false );
 
614
    newItem->setSelected( true );
 
615
    WKernel::getRunningKernel()->getRoiManager()->setSelectedRoi( getSelectedRoi() );
 
616
}
 
617
 
 
618
void WQtControlPanel::removeRoi( osg::ref_ptr< WROI > roi )
 
619
{
 
620
    for( int branchID = 0; branchID < m_tiRois->childCount(); ++branchID )
 
621
    {
 
622
        QTreeWidgetItem* branchTreeItem = m_tiRois->child( branchID );
 
623
        for( int roiID = 0; roiID < branchTreeItem->childCount(); ++roiID )
 
624
        {
 
625
            WQtRoiTreeItem* roiTreeItem = dynamic_cast< WQtRoiTreeItem* >( branchTreeItem->child( roiID ) );
 
626
            if( roiTreeItem && roiTreeItem->getRoi() == roi )
 
627
            {
 
628
                delete roiTreeItem;
 
629
 
 
630
                if( branchTreeItem->childCount() == 0 )
 
631
                {
 
632
                    delete branchTreeItem;
 
633
                }
 
634
 
 
635
                break;
 
636
            }
 
637
        }
 
638
    }
 
639
    WKernel::getRunningKernel()->getRoiManager()->setSelectedRoi( getSelectedRoi() );
 
640
}
 
641
 
 
642
boost::shared_ptr< WModule > WQtControlPanel::getSelectedModule()
 
643
{
 
644
    if( m_moduleTreeWidget->selectedItems().at( 0 )->type() == 1 )
 
645
    {
 
646
        return ( static_cast< WQtDatasetTreeItem* >( m_moduleTreeWidget->selectedItems().at( 0 ) )->getModule() );
 
647
    }
 
648
    else if( m_moduleTreeWidget->selectedItems().at( 0 )->type() == 3 )
 
649
    {
 
650
        return ( static_cast< WQtModuleTreeItem* >( m_moduleTreeWidget->selectedItems().at( 0 ) )->getModule() );
 
651
    }
 
652
 
 
653
    return boost::shared_ptr< WModule >();
 
654
}
 
655
 
 
656
void WQtControlPanel::reselectTreeItem()
 
657
{
 
658
    setActiveModule( getSelectedModule(), true );
 
659
}
 
660
 
 
661
void WQtControlPanel::selectTreeItem()
 
662
{
 
663
    if( m_ignoreSelectionChange )
 
664
    {
 
665
        return;
 
666
    }
 
667
 
 
668
    if( m_moduleTreeWidget->selectedItems().size() != 0  )
 
669
    {
 
670
        switch( m_moduleTreeWidget->selectedItems().at( 0 )->type() )
 
671
        {
 
672
            case SUBJECT:
 
673
            case MODULEHEADER:
 
674
                {
 
675
                    // deletion of headers and subjects is not allowed
 
676
                    deactivateModuleSelection( false );
 
677
                }
 
678
                break;
 
679
            case DATASET:
 
680
                {
 
681
                    WModule::SPtr module = ( static_cast< WQtDatasetTreeItem* >( m_moduleTreeWidget->selectedItems().at( 0 ) ) )->getModule();
 
682
                    setActiveModule( module );
 
683
                }
 
684
                break;
 
685
            case MODULE:
 
686
                {
 
687
                    WModule::SPtr module = ( static_cast< WQtModuleTreeItem* >( m_moduleTreeWidget->selectedItems().at( 0 ) ) )->getModule();
 
688
                    setActiveModule( module );
 
689
                }
 
690
                break;
 
691
            case ROIHEADER:
 
692
            case ROIBRANCH:
 
693
            case ROI:
 
694
            default:
 
695
                deactivateModuleSelection( false );
 
696
                break;
 
697
        }
 
698
    }
 
699
    else
 
700
    {
 
701
        // clean up if nothing is selected
 
702
        setActiveModule( WModule::SPtr() );  // module is NULL at this point
 
703
    }
 
704
}
 
705
 
 
706
void WQtControlPanel::selectRoiTreeItem()
 
707
{
 
708
    clearAndDeleteTabs();
 
709
 
 
710
    // Make compatibles toolbar empty
 
711
    {
 
712
        if( m_mainWindow->getCompatiblesToolbar() != 0 )
 
713
        {
 
714
            m_mainWindow->getCompatiblesToolbar()->makeEmpty();
 
715
        }
 
716
        else
 
717
        {
 
718
            m_mainWindow->setCompatiblesToolbar( new WQtCombinerToolbar( m_mainWindow ) );
 
719
        }
 
720
    }
 
721
 
 
722
    boost::shared_ptr< WModule > module;
 
723
    boost::shared_ptr< WProperties > props;
 
724
 
 
725
    if( m_roiTreeWidget->selectedItems().size() != 0  )
 
726
    {
 
727
        switch( m_roiTreeWidget->selectedItems().at( 0 )->type() )
 
728
        {
 
729
            case SUBJECT:
 
730
            case DATASET:
 
731
            case MODULEHEADER:
 
732
            case MODULE:
 
733
            case ROIHEADER:
 
734
                WKernel::getRunningKernel()->getRoiManager()->setSelectedRoi( getSelectedRoi() );
 
735
                break;
 
736
            case ROIBRANCH:
 
737
                props = ( static_cast< WQtBranchTreeItem* >( m_roiTreeWidget->selectedItems().at( 0 ) ) )->getBranch()->getProperties();
 
738
                WKernel::getRunningKernel()->getRoiManager()->setSelectedRoi( getFirstRoiInSelectedBranch() );
 
739
                break;
 
740
            case ROI:
 
741
                props = ( static_cast< WQtRoiTreeItem* >( m_roiTreeWidget->selectedItems().at( 0 ) ) )->getRoi()->getProperties();
 
742
                WKernel::getRunningKernel()->getRoiManager()->setSelectedRoi( getSelectedRoi() );
 
743
                break;
 
744
            default:
 
745
                break;
 
746
        }
 
747
    }
 
748
 
 
749
    if( m_roiTreeWidget->selectedItems().size() == 1 && m_roiTreeWidget->selectedItems().at( 0 )->type() == ROI )
 
750
    {
 
751
        osg::ref_ptr< WROI > roi = ( static_cast< WQtRoiTreeItem* >( m_roiTreeWidget->selectedItems().at( 0 ) ) )->getRoi();
 
752
        roi->getProperties()->getProperty( "active" )->toPropBool()->set( m_roiTreeWidget->selectedItems().at( 0 )->checkState( 0 ) );
 
753
    }
 
754
 
 
755
    buildPropTab( props, boost::shared_ptr< WProperties >() );
 
756
}
 
757
 
 
758
void WQtControlPanel::selectDataModule( osg::ref_ptr< WGETexture3D > texture )
 
759
{
 
760
    clearAndDeleteTabs();
 
761
    buildPropTab( texture->getProperties(), texture->getInformationProperties() );
 
762
}
 
763
 
 
764
QTreeWidgetItem* WQtControlPanel::findModuleItem( WModule::SPtr module ) const
 
765
{
 
766
    QTreeWidgetItemIterator it( m_moduleTreeWidget );
 
767
    QTreeWidgetItem* item = NULL;
 
768
    while( *it )
 
769
    {
 
770
        if( dynamic_cast< WQtModuleTreeItem* >( *it ) )
 
771
        {
 
772
            WModule::SPtr currentModule;
 
773
            currentModule = boost::shared_dynamic_cast< WModule >( ( dynamic_cast< WQtModuleTreeItem* >( *it ) )->getModule() );
 
774
            if( currentModule )
 
775
            {
 
776
                if( currentModule == module )
 
777
                {
 
778
                    item = *it;
 
779
                    break;
 
780
                }
 
781
            }
 
782
        }
 
783
        else if( dynamic_cast< WQtDatasetTreeItem* >( *it ) )
 
784
        {
 
785
            boost::shared_ptr< WDataModule > dataModule;
 
786
            dataModule = boost::shared_dynamic_cast< WDataModule >( ( dynamic_cast< WQtDatasetTreeItem* >( *it ) )->getModule() );
 
787
            if( dataModule )
 
788
            {
 
789
                if( dataModule == module )
 
790
                {
 
791
                    item = *it;
 
792
                    break;
 
793
                }
 
794
            }
 
795
        }
 
796
        ++it;
 
797
    }
 
798
 
 
799
    return item;
 
800
}
 
801
 
 
802
void WQtControlPanel::deactivateModuleSelection( bool selectTopmost )
 
803
{
 
804
    m_ignoreSelectionChange = true;
 
805
 
 
806
    m_activeModule = WModule::SPtr();
 
807
 
 
808
    // select top element and reset some menu actions
 
809
    if( selectTopmost )
 
810
    {
 
811
        m_moduleTreeWidget->clearSelection();
 
812
        selectUpperMostEntry();
 
813
    }
 
814
    m_deleteModuleAction->setEnabled( false );
 
815
 
 
816
    // remove properties tabs
 
817
    clearAndDeleteTabs();
 
818
 
 
819
    // clean compatibles toolbar, add only subject independent items
 
820
    createCompatibleButtons( m_activeModule );
 
821
 
 
822
    // also notify network editor
 
823
    WQtNetworkEditor* nwe = m_mainWindow->getNetworkEditor();
 
824
    if( nwe )
 
825
    {
 
826
        nwe->clearSelection();
 
827
    }
 
828
 
 
829
    m_ignoreSelectionChange = false;
 
830
 
 
831
    return;
 
832
}
 
833
 
 
834
void WQtControlPanel::setActiveModule( WModule::SPtr module, bool forceUpdate )
 
835
{
 
836
    m_ignoreSelectionChange = true;
 
837
 
 
838
    // is module NULL? remove everything
 
839
    if( !module )
 
840
    {
 
841
        deactivateModuleSelection();
 
842
        m_ignoreSelectionChange = false;
 
843
        return;
 
844
    }
 
845
 
 
846
    // only if something has changed
 
847
    if( ( m_activeModule == module ) && !forceUpdate )
 
848
    {
 
849
        m_ignoreSelectionChange = false;
 
850
        return;
 
851
    }
 
852
    m_activeModule = module;
 
853
 
 
854
    wlog::debug( "ControlPanel" ) << "Activating module \"" << module->getName() << "\".";
 
855
 
 
856
    // update the m_moduleTreeWidget
 
857
    std::list< WQtTreeItem* > items = findItemsByModule( module );
 
858
    WAssert( items.size(), "No item found for module " + module->getName() );
 
859
    m_moduleTreeWidget->clearSelection();
 
860
    for( std::list< WQtTreeItem* >::const_iterator it = items.begin(); it != items.end(); ++it )
 
861
    {
 
862
        ( *it )->setSelected( true );
 
863
    }
 
864
 
 
865
    // also notify network editor
 
866
    WQtNetworkEditor* nwe = m_mainWindow->getNetworkEditor();
 
867
    if( nwe )
 
868
    {
 
869
        nwe->selectByModule( module );
 
870
    }
 
871
 
 
872
    // remove property tabs
 
873
    clearAndDeleteTabs();
 
874
    // update module meta info tab also for crashed modules
 
875
    WQtModuleMetaInfo* metaInfoWidget = new WQtModuleMetaInfo( module );
 
876
    m_tabWidget->addTab( metaInfoWidget, "About && Help" );
 
877
 
 
878
    // set new property tabs if module is not crashed
 
879
    if( !module->isCrashed() )
 
880
    {
 
881
        buildPropTab( module->getProperties(), module->getInformationProperties() );
 
882
    }
 
883
 
 
884
    // re-select the previous tab
 
885
    bool foundTab = false;
 
886
    std::map< QString, int > priorityList;
 
887
    if( m_previousTab != "" )
 
888
    {
 
889
        // search the tab with the previous title
 
890
        for( int idx = 0; idx < m_tabWidget->count(); ++idx )
 
891
        {
 
892
            if( m_tabWidget->tabText( idx ) == m_previousTab )
 
893
            {
 
894
                m_tabWidget->setCurrentIndex( idx );
 
895
                foundTab = true;
 
896
                break;
 
897
            }
 
898
 
 
899
            // keep track of the indices in the tab. we use this map later as priority list. Please not that we add 1 to the index. This ensures
 
900
            // that the invalid index is 0, even if it is -1 in Qt.
 
901
            priorityList[ m_tabWidget->tabText( idx ) ] = idx + 1;
 
902
        }
 
903
 
 
904
        if( !foundTab )
 
905
        {
 
906
            // the tab does not exist anymore. We need to use our priority list
 
907
            if( priorityList[ "Settings" ] != 0 )
 
908
            {
 
909
                m_tabWidget->setCurrentIndex( priorityList[ "Settings" ] - 1 );
 
910
            }
 
911
            else if( priorityList[ "Information" ] != 0 )
 
912
            {
 
913
                m_tabWidget->setCurrentIndex( priorityList[ "Settings" ] - 1 );
 
914
            }
 
915
            else
 
916
            {
 
917
                // there is no info and no settings tab. Set the first tab.
 
918
                m_tabWidget->setCurrentIndex( 0 );
 
919
            }
 
920
        }
 
921
    }
 
922
 
 
923
    // update compatibles toolbar
 
924
    createCompatibleButtons( module );
 
925
 
 
926
    // disable delete action for tree items that have children.
 
927
    if( m_moduleTreeWidget->selectedItems().at( 0 )->childCount() != 0 )
 
928
    {
 
929
        m_deleteModuleAction->setEnabled( false );
 
930
    }
 
931
    else
 
932
    {
 
933
        m_deleteModuleAction->setEnabled( true );
 
934
    }
 
935
 
 
936
    m_ignoreSelectionChange = false;
 
937
}
 
938
 
 
939
void WQtControlPanel::buildPropTab( boost::shared_ptr< WProperties > props, boost::shared_ptr< WProperties > infoProps )
 
940
{
 
941
    WQtPropertyGroupWidget* tab = NULL;
 
942
    WQtPropertyGroupWidget* infoTab = NULL;
 
943
    if( props )
 
944
    {
 
945
        tab = new WQtPropertyGroupWidget( props );
 
946
        if( tab )
 
947
        {
 
948
            tab->setName( "Settings" );
 
949
        }
 
950
    }
 
951
    if( infoProps )
 
952
    {
 
953
        infoTab = new WQtPropertyGroupWidget( infoProps );
 
954
        if( infoTab )
 
955
        {
 
956
            infoTab->setName( "Information" );
 
957
        }
 
958
    }
 
959
 
 
960
    int infoIdx = addTabWidgetContent( infoTab );
 
961
    int propIdx = addTabWidgetContent( tab );
 
962
 
 
963
    // select the property widget preferably
 
964
    if( m_previousTab == "" )
 
965
    {
 
966
        if( propIdx != -1 )
 
967
        {
 
968
            m_tabWidget->setCurrentIndex( propIdx );
 
969
        }
 
970
        else if( infoIdx != -1 )
 
971
        {
 
972
            m_tabWidget->setCurrentIndex( infoIdx );
 
973
        }
 
974
    }
 
975
}
 
976
 
 
977
void WQtControlPanel::createCompatibleButtons( boost::shared_ptr< WModule > module )
 
978
{
 
979
    // we need to clean up the action lists
 
980
    WQtCombinerActionList::deepDeleteActionList( m_addModuleActionList );
 
981
    WQtCombinerActionList::deepDeleteActionList( m_connectWithPrototypeActionList );
 
982
    WQtCombinerActionList::deepDeleteActionList( m_connectWithModuleActionList );
 
983
    WQtCombinerActionList::deepDeleteActionList( m_disconnectActionList );
 
984
 
 
985
    // acquire new action lists
 
986
    m_connectWithPrototypeActionList = WQtCombinerActionList( this, m_mainWindow->getIconManager(),
 
987
                                                              WModuleFactory::getModuleFactory()->getCompatiblePrototypes( module ),
 
988
                                                              m_moduleExcluder );
 
989
    m_connectWithModuleActionList = WQtCombinerActionList( this, m_mainWindow->getIconManager(),
 
990
                                                           WKernel::getRunningKernel()->getRootContainer()->getPossibleConnections( module ),
 
991
                                                           0, true );
 
992
 
 
993
    m_addModuleActionList = WQtCombinerActionList( this, m_mainWindow->getIconManager(),
 
994
                                                           WModuleFactory::getModuleFactory()->getAllPrototypes(),
 
995
                                                           0, false );
 
996
    if( module )
 
997
    {
 
998
        m_disconnectActionList = WQtCombinerActionList( this, m_mainWindow->getIconManager(), module->getPossibleDisconnections() );
 
999
    }
 
1000
 
 
1001
    // build the add menu
 
1002
    QMenu* m = new WQtMenuFiltered( m_moduleTreeWidget );
 
1003
    m->addActions( m_addModuleActionList );
 
1004
    m_addModuleAction->setDisabled( !m_addModuleActionList.size() || module );  // disable if no entry inside or a module was selected
 
1005
    delete( m_addModuleAction->menu() ); // ensure that combiners get free'd
 
1006
    m_addModuleAction->setMenu( m );
 
1007
 
 
1008
    // build the prototype menu
 
1009
    m = new WQtMenuFiltered( m_moduleTreeWidget );
 
1010
    m->addActions( m_connectWithPrototypeActionList );
 
1011
    m_connectWithPrototypeAction->setDisabled( !m_connectWithPrototypeActionList.size() );  // disable if no entry inside
 
1012
    delete( m_connectWithPrototypeAction->menu() ); // ensure that combiners get free'd
 
1013
    m_connectWithPrototypeAction->setMenu( m );
 
1014
 
 
1015
    // build the module menu
 
1016
    m = new WQtMenuFiltered( m_moduleTreeWidget );
 
1017
    m->addActions( m_connectWithModuleActionList );
 
1018
    m_connectWithModuleAction->setDisabled( !m_connectWithModuleActionList.size() );  // disable if no entry inside
 
1019
    delete m_connectWithModuleAction->menu();
 
1020
    m_connectWithModuleAction->setMenu( m );
 
1021
 
 
1022
    // build the disconnect menu
 
1023
    m = new WQtMenuFiltered( m_moduleTreeWidget );
 
1024
    m->addActions( m_disconnectActionList );
 
1025
    m_disconnectAction->setDisabled( !m_disconnectActionList.size() );  // disable if no entry inside
 
1026
    delete( m_disconnectAction->menu() ); // ensure that combiners get free'd
 
1027
    m_disconnectAction->setMenu( m );
 
1028
 
 
1029
    // finally, set the actions to the compatibles toolbar.
 
1030
    if( m_mainWindow->getCompatiblesToolbar() != 0 )
 
1031
    {
 
1032
        m_mainWindow->getCompatiblesToolbar()->updateButtons( m_connectWithPrototypeActionList );
 
1033
    }
 
1034
    else
 
1035
    {
 
1036
        m_mainWindow->setCompatiblesToolbar( new WQtCombinerToolbar( m_mainWindow, m_connectWithPrototypeActionList ) );
 
1037
    }
 
1038
}
 
1039
 
 
1040
void WQtControlPanel::changeTreeItem( QTreeWidgetItem* item, int /* column */ )
 
1041
{
 
1042
    WQtTreeItem* witem = dynamic_cast< WQtTreeItem* >( item );
 
1043
    if( witem )
 
1044
    {
 
1045
        witem->handleCheckStateChange();
 
1046
    }
 
1047
}
 
1048
 
 
1049
int WQtControlPanel::addTabWidgetContent( WQtPropertyGroupWidget* content )
 
1050
{
 
1051
    if( !content || content->isEmpty() )
 
1052
    {
 
1053
        // we destroy the widget if we not use it to avoid empty widgets popping up
 
1054
        if( content )
 
1055
        {
 
1056
            delete content;
 
1057
        }
 
1058
        return -1;
 
1059
    }
 
1060
 
 
1061
    QScrollArea* sa = new QScrollArea();
 
1062
    sa->setWidget( content );
 
1063
    sa->setWidgetResizable( true );
 
1064
 
 
1065
    return m_tabWidget->addTab( sa, content->getName() );
 
1066
}
 
1067
 
 
1068
int WQtControlPanel::getFirstSubject()
 
1069
{
 
1070
    int c = 0;
 
1071
    for( int i = 0; i < m_moduleTreeWidget->topLevelItemCount() ; ++i )
 
1072
    {
 
1073
        if( m_moduleTreeWidget->topLevelItem( i )->type() == SUBJECT )
 
1074
        {
 
1075
            break;
 
1076
        }
 
1077
        ++c;
 
1078
    }
 
1079
    return c;
 
1080
}
 
1081
 
 
1082
osg::ref_ptr< WROI > WQtControlPanel::getSelectedRoi()
 
1083
{
 
1084
    osg::ref_ptr< WROI > roi;
 
1085
    if( m_roiTreeWidget->selectedItems().count() == 0 )
 
1086
    {
 
1087
        return roi;
 
1088
    }
 
1089
    if( m_roiTreeWidget->selectedItems().at( 0 )->type() == ROI )
 
1090
    {
 
1091
        roi =( static_cast< WQtRoiTreeItem* >( m_roiTreeWidget->selectedItems().at( 0 ) ) )->getRoi();
 
1092
    }
 
1093
    return roi;
 
1094
}
 
1095
 
 
1096
osg::ref_ptr< WROI > WQtControlPanel::getFirstRoiInSelectedBranch()
 
1097
{
 
1098
    osg::ref_ptr< WROI >roi;
 
1099
    if( m_roiTreeWidget->selectedItems().count() == 0 )
 
1100
    {
 
1101
        return roi;
 
1102
    }
 
1103
    if( m_roiTreeWidget->selectedItems().at( 0 )->type() == ROI )
 
1104
    {
 
1105
        WQtBranchTreeItem* branch = ( static_cast< WQtBranchTreeItem* >( m_roiTreeWidget->selectedItems().at( 0 )->parent() ) );
 
1106
        roi =( static_cast< WQtRoiTreeItem* >( branch->child( 0 ) ) )->getRoi();
 
1107
    }
 
1108
    if( m_roiTreeWidget->selectedItems().at( 0 )->type() == ROIBRANCH )
 
1109
    {
 
1110
        WQtBranchTreeItem* branch = ( static_cast< WQtBranchTreeItem* >( m_roiTreeWidget->selectedItems().at( 0 ) ) );
 
1111
        if( branch->childCount() > 0 )
 
1112
        {
 
1113
            roi =( static_cast< WQtRoiTreeItem* >( branch->child( 0 ) ) )->getRoi();
 
1114
        }
 
1115
    }
 
1116
    return roi;
 
1117
}
 
1118
 
 
1119
QAction* WQtControlPanel::toggleViewAction() const
 
1120
{
 
1121
    QAction* result = QDockWidget::toggleViewAction();
 
1122
    QList< QKeySequence > shortcut;
 
1123
#if defined( __APPLE__ )
 
1124
    shortcut.append( QKeySequence( Qt::CTRL + Qt::Key_F9 ) ); // In Mac OS X F9 is already taken by window managment
 
1125
#else
 
1126
    shortcut.append( QKeySequence( Qt::Key_F9 ) );
 
1127
#endif
 
1128
    result->setShortcuts( shortcut );
 
1129
    return result;
 
1130
}
 
1131
 
 
1132
void WQtControlPanel::deleteModule()
 
1133
{
 
1134
    if( m_moduleTreeWidget->hasFocus() )
 
1135
    {
 
1136
        if( m_moduleTreeWidget->selectedItems().count() > 0 )
 
1137
        {
 
1138
            if( ( m_moduleTreeWidget->selectedItems().at( 0 )->type() == MODULE ) ||
 
1139
                    ( m_moduleTreeWidget->selectedItems().at( 0 )->type() == DATASET ) )
 
1140
            {
 
1141
                // deleting crashed modules is not really save as we do not know the internal state of it
 
1142
                if( static_cast< WQtTreeItem* >( m_moduleTreeWidget->selectedItems().at( 0 ) )->getModule()->isCrashed() )
 
1143
                {
 
1144
                    return;
 
1145
                }
 
1146
 
 
1147
                // remove from the container. It will create a new event in the GUI after it has been removed which is then handled by the tree item.
 
1148
                // This method deep removes the module ( it also removes depending modules )
 
1149
                WKernel::getRunningKernel()->getRootContainer()->remove(
 
1150
                        static_cast< WQtTreeItem* >( m_moduleTreeWidget->selectedItems().at( 0 ) )->getModule()
 
1151
                        );
 
1152
                // select another item
 
1153
                m_moduleTreeWidget->setCurrentItem( m_moduleTreeWidget->topLevelItem( 0 ) );
 
1154
            }
 
1155
        }
 
1156
    }
 
1157
    else if( m_mainWindow->getNetworkEditor()->hasFocus() )
 
1158
    {
 
1159
        if( m_mainWindow->getNetworkEditor()->selectedItems().count() > 0 )
 
1160
        {
 
1161
            // deleting crashed modules is not really save as we do not know the internal state of it
 
1162
            if( static_cast< WQtNetworkItem* >( m_mainWindow->getNetworkEditor()->selectedItems().at( 0 ) )->getModule()->isCrashed() )
 
1163
            {
 
1164
                return;
 
1165
            }
 
1166
 
 
1167
            // This method deep removes the module ( it also removes depending modules )
 
1168
            WKernel::getRunningKernel()->getRootContainer()->remove(
 
1169
                static_cast< WQtNetworkItem* >( m_mainWindow->getNetworkEditor()->selectedItems().at( 0 ) )->getModule()
 
1170
                );
 
1171
        }
 
1172
    }
 
1173
}
 
1174
 
 
1175
void WQtControlPanel::deleteROITreeItem()
 
1176
{
 
1177
    osg::ref_ptr< WROI >roi;
 
1178
    if( m_roiTreeWidget->selectedItems().count() > 0 )
 
1179
    {
 
1180
        if( m_roiTreeWidget->selectedItems().at( 0 )->type() == ROIBRANCH )
 
1181
        {
 
1182
            roi = getFirstRoiInSelectedBranch();
 
1183
            if( roi )
 
1184
            {
 
1185
                WKernel::getRunningKernel()->getRoiManager()->removeBranch( roi );
 
1186
            }
 
1187
            delete m_roiTreeWidget->selectedItems().at( 0 );
 
1188
        }
 
1189
 
 
1190
        else if( m_roiTreeWidget->selectedItems().at( 0 )->type() == ROI )
 
1191
        {
 
1192
            roi =( static_cast< WQtRoiTreeItem* >( m_roiTreeWidget->selectedItems().at( 0 ) ) )->getRoi();
 
1193
            if( roi )
 
1194
            {
 
1195
                WKernel::getRunningKernel()->getRoiManager()->removeRoi( roi );
 
1196
                // Removing the roi from the tree widget is also done by WROIManagerFibers::removeRoi().
 
1197
            }
 
1198
        }
 
1199
    }
 
1200
    WKernel::getRunningKernel()->getRoiManager()->setSelectedRoi( getFirstRoiInSelectedBranch() );
 
1201
}
 
1202
 
 
1203
void WQtControlPanel::selectUpperMostEntry()
 
1204
{
 
1205
    m_tiModules->setSelected( true );
 
1206
}
 
1207
 
 
1208
void WQtControlPanel::handleRoiDragDrop()
 
1209
{
 
1210
    WLogger::getLogger()->addLogMessage( "Drag and drop handler not implemented yet!", "ControlPanel", LL_DEBUG );
 
1211
}
 
1212
 
 
1213
QDockWidget* WQtControlPanel::getRoiDock() const
 
1214
{
 
1215
    return m_roiDock;
 
1216
}
 
1217
 
 
1218
QDockWidget* WQtControlPanel::getModuleDock() const
 
1219
{
 
1220
    return m_moduleDock;
 
1221
}
 
1222
 
 
1223
QDockWidget* WQtControlPanel::getColormapperDock() const
 
1224
{
 
1225
    return m_colormapper;
 
1226
}
 
1227
 
 
1228
WQtModuleConfig& WQtControlPanel::getModuleConfig() const
 
1229
{
 
1230
    return *m_moduleExcluder;
 
1231
}
 
1232
 
 
1233
QAction* WQtControlPanel::getMissingModuleAction() const
 
1234
{
 
1235
    return m_missingModuleAction;
 
1236
}
 
1237
 
 
1238
void WQtControlPanel::clearAndDeleteTabs()
 
1239
{
 
1240
    if( m_tabWidget->currentIndex() != -1 )
 
1241
    {
 
1242
        m_previousTab = m_tabWidget->tabText( m_tabWidget->currentIndex() );
 
1243
    }
 
1244
 
 
1245
    m_tabWidget->setDisabled( true );
 
1246
    QWidget *widget;
 
1247
    while( ( widget = m_tabWidget->widget( 0 ) ))
 
1248
    {
 
1249
        m_tabWidget->removeTab( 0 );
 
1250
        delete widget;
 
1251
    }
 
1252
    m_tabWidget->setEnabled( true );
 
1253
}
 
1254