WQtDatasetBrowser.cpp 27.2 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
//---------------------------------------------------------------------------
//
// Project: OpenWalnut ( http://www.openwalnut.org )
//
// Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
// For more information see http://www.openwalnut.org/copying
//
// This file is part of OpenWalnut.
//
// OpenWalnut is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// OpenWalnut is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
//
//---------------------------------------------------------------------------

25
#include <iostream>
26
#include <map>
Sebastian Eichelbaum's avatar
[MERGE]  
Sebastian Eichelbaum committed
27
#include <set>
28
#include <string>
29
#include <vector>
30

31
#include <QtCore/QList>
32
#include <QtGui/QScrollArea>
schurade's avatar
schurade committed
33
#include <QtGui/QShortcut>
34
#include <QtGui/QMenu>
35

36
#include "../../../common/WLogger.h"
37
#include "../../../common/WPreferences.h"
38

39 40
#include "../../../dataHandler/WDataSet.h"

41 42 43
#include "../../../kernel/WModuleFactory.h"
#include "../../../kernel/WKernel.h"
#include "../../../modules/data/WMData.h"
44
#include "../events/WModuleAssocEvent.h"
schurade's avatar
schurade committed
45
#include "../events/WRoiAssocEvent.h"
46
#include "../events/WRoiRemoveEvent.h"
47
#include "../events/WModuleReadyEvent.h"
48
#include "../events/WModuleDeleteEvent.h"
49
#include "../events/WEventTypes.h"
50
#include "../guiElements/WQtApplyModulePushButton.h"
51
#include "../WMainWindow.h"
52
#include "../WQt4Gui.h"
53
#include "WQtNumberEdit.h"
54
#include "WQtNumberEditDouble.h"
55
#include "WQtTextureSorter.h"
schurade's avatar
schurade committed
56
#include "WQtBranchTreeItem.h"
57

58
#include "WQtDatasetBrowser.h"
59

60
WQtDatasetBrowser::WQtDatasetBrowser( WMainWindow* parent )
61
    : QDockWidget( "Dataset Browser", parent )
62
{
63 64
    m_mainWindow = parent;

65
    m_panel = new QWidget( this );
66
    m_moduleTreeWidget = new WQtTreeWidget( m_panel );
67
    m_moduleTreeWidget->setContextMenuPolicy( Qt::ActionsContextMenu );
68

69 70 71 72 73 74
    m_moduleTreeWidget->setHeaderLabel( QString( "Dataset Browser" ) );
    m_moduleTreeWidget->setDragEnabled( true );
    m_moduleTreeWidget->viewport()->setAcceptDrops( true );
    m_moduleTreeWidget->setDropIndicatorShown( true );
    m_moduleTreeWidget->setDragDropMode( QAbstractItemView::InternalMove );
    m_moduleTreeWidget->setMinimumHeight( 250 );
75

76
    // create context menu for tree items
77 78 79
    m_deleteModuleAction = new QAction( WQt4Gui::getMainWindow()->getIconManager()->getIcon( "remove" ), "Remove Module", m_moduleTreeWidget );
    connect( m_deleteModuleAction, SIGNAL( triggered() ), this, SLOT( m_deleteModuleTreeItem() ) );
    m_moduleTreeWidget->addAction( m_deleteModuleAction );
80

81 82 83
    m_textureSorter = new WQtTextureSorter( m_panel );
    m_textureSorter->setToolTip( "Reorder the textures." );

84
    m_tabWidget = new QTabWidget( m_panel );
85
    m_tabWidget2 = new QTabWidget( m_panel );
schurade's avatar
schurade committed
86
    m_tabWidget->setMinimumHeight( 220 );
87 88

    m_layout = new QVBoxLayout();
89
    m_layout->addWidget( m_moduleTreeWidget );
90 91
    m_layout->addWidget( m_tabWidget2 );

Alexander Wiebel's avatar
Alexander Wiebel committed
92
    m_tabWidget2->addTab( m_textureSorter, QString( "Texture Sorter" ) );
93 94 95 96 97 98 99 100

    m_roiTreeWidget = new WQtTreeWidget();
    m_roiTreeWidget->setHeaderLabel( QString( "ROIs" ) );
    m_roiTreeWidget->setHeaderHidden( true );
    m_roiTreeWidget->setDragEnabled( true );
    m_roiTreeWidget->viewport()->setAcceptDrops( true );
    m_roiTreeWidget->setDropIndicatorShown( true );
    m_roiTreeWidget->setDragDropMode( QAbstractItemView::InternalMove );
Alexander Wiebel's avatar
Alexander Wiebel committed
101
    m_tabWidget2->addTab( m_roiTreeWidget, QString( "ROIs" ) );
102 103


104 105 106 107 108 109 110
    m_layout->addWidget( m_tabWidget );

    m_panel->setLayout( m_layout );

    this->setAllowedAreas( Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea );
    this->setFeatures( QDockWidget::DockWidgetMovable | QDockWidget::DockWidgetFloatable );
    this->setWidget( m_panel );
111

112
    m_tiModules = new WQtModuleHeaderTreeItem( m_moduleTreeWidget );
schurade's avatar
schurade committed
113
    m_tiModules->setText( 0, QString( "Modules" ) );
114
    m_tiRois = new WQtRoiHeaderTreeItem( m_roiTreeWidget );
Alexander Wiebel's avatar
Alexander Wiebel committed
115
    m_tiRois->setText( 0, QString( "ROIs" ) );
116

117
    connectSlots();
118 119 120 121

    // preset for toolbar text.
    m_showToolBarText = true;
    WPreferences::getPreference( "qt4gui.toolBarIconText", &m_showToolBarText );
schurade's avatar
schurade committed
122

123 124 125 126 127
    // These modules will be allowed to be shown.
    std::string moduleWhiteList;
    WPreferences::getPreference( "modules.whiteList", &moduleWhiteList );
    m_moduleWhiteList = string_utils::tokenize( moduleWhiteList, "," );

128
    QShortcut* shortcut = new QShortcut( QKeySequence( Qt::Key_Delete ), m_roiTreeWidget );
129 130 131
    connect( shortcut, SIGNAL( activated() ), this, SLOT( deleteROITreeItem() ) );
    QShortcut* shortcutDeleteModules = new QShortcut( QKeySequence( Qt::Key_Backspace ), m_moduleTreeWidget );
    connect( shortcutDeleteModules, SIGNAL( activated() ), this, SLOT( deleteModuleTreeItem() ) );
132 133 134 135 136 137 138
}

WQtDatasetBrowser::~WQtDatasetBrowser()
{
}


139 140
void WQtDatasetBrowser::connectSlots()
{
141 142
    connect( m_moduleTreeWidget, SIGNAL( itemSelectionChanged() ), this, SLOT( selectTreeItem() ) );
    connect( m_moduleTreeWidget, SIGNAL( itemClicked( QTreeWidgetItem*, int ) ), this, SLOT( changeTreeItem() ) );
schurade's avatar
schurade committed
143 144
    connect( m_roiTreeWidget, SIGNAL( itemSelectionChanged() ), this, SLOT( selectRoiTreeItem() ) );
    connect( m_roiTreeWidget, SIGNAL( itemClicked( QTreeWidgetItem*, int ) ), this, SLOT( changeRoiTreeItem() ) );
145 146 147
}


148 149
WQtSubjectTreeItem* WQtDatasetBrowser::addSubject( std::string name )
{
150
    WQtSubjectTreeItem* subject = new WQtSubjectTreeItem( m_moduleTreeWidget );
151 152 153 154 155
    subject->setText( 0, QString( name.c_str() ) );

    return subject;
}

156 157
bool WQtDatasetBrowser::event( QEvent* event )
{
158 159 160 161 162 163
    // a subject singals a newly registered data set
    if ( event->type() == WQT_UPDATE_TEXTURE_SORTER_EVENT )
    {
        m_textureSorter->update();
    }

164 165 166 167
    // a module got associated with the root container -> add it to the list
    if ( event->type() == WQT_ASSOC_EVENT )
    {
        // convert event to assoc event
schurade's avatar
schurade committed
168 169
        WModuleAssocEvent* e1 = dynamic_cast< WModuleAssocEvent* >( event );     // NOLINT
        if ( e1 )
170
        {
schurade's avatar
schurade committed
171 172
            WLogger::getLogger()->addLogMessage( "Inserting module " + e1->getModule()->getName() + " to dataset browser.",
                                                 "DatasetBrowser", LL_DEBUG );
173

schurade's avatar
schurade committed
174 175 176 177 178 179 180 181 182 183
            // finally add the module
            // TODO(schurade): is this differentiation between data and "normal" modules really needed?
            if ( boost::shared_dynamic_cast< WMData >( e1->getModule() ).get() )
            {
                addDataset( e1->getModule(), 0 );
            }
            else
            {
                addModule( e1->getModule() );
            }
184
        }
schurade's avatar
schurade committed
185 186 187 188 189 190
        return true;
    }
    if ( event->type() == WQT_ROI_ASSOC_EVENT)
    {
        WRoiAssocEvent* e2 = dynamic_cast< WRoiAssocEvent* >( event );     // NOLINT
        if ( e2 )
191
        {
schurade's avatar
schurade committed
192 193
            addRoi( e2->getRoi() );
            WLogger::getLogger()->addLogMessage( "Inserting roi to dataset browser.", "DatasetBrowser", LL_DEBUG );
194 195 196 197
        }

        return true;
    }
198 199 200 201 202 203 204 205 206 207 208
    if( event->type() == WQT_ROI_REMOVE_EVENT )
    {
        WRoiRemoveEvent* e3 = dynamic_cast< WRoiRemoveEvent* >( event );
        if( e3 )
        {
            removeRoi( e3->getRoi() );
            WLogger::getLogger()->addLogMessage( "Removing roi from dataset browser.", "DatasetBrowser", LL_DEBUG );
        }

        return true;
    }
209

210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238
    // a module tree item should be deleted
    if ( event->type() == WQT_MODULE_REMOVE_EVENT )
    {
        WModuleDeleteEvent* e = dynamic_cast< WModuleDeleteEvent* >( event );     // NOLINT
        if ( !e )
        {
            // this should never happen, since the type is set to WQT_Ready_EVENT.
            WLogger::getLogger()->addLogMessage( "Event is not an WModuleRemoveEvent although its type claims it. Ignoring event.",
                                                 "DatasetBrowser", LL_WARNING );
            return true;
        }

        // grab the module reference and print some info
        boost::shared_ptr< WModule > module = e->getTreeItem()->getModule();
        WLogger::getLogger()->addLogMessage( "Removing module \"" + module->getName() + "\" from Tree.", "DatasetBrowser", LL_DEBUG );

        // remove it from the tree and free last ref count
        m_moduleTreeWidget->deleteItem( e->getTreeItem() );

        // ref count != 1?
        if ( module.use_count() != 1 )
        {
            wlog::warn( "DatasetBrowser" ) << "Removed module has strange usage count: " << module.use_count() << ". Should be 1 here. " <<
                                              "Module reference is held by someone else.";
        }

        return true;
    }

239 240 241 242 243 244 245 246
    // a module changed its state to "ready" -> activate it in dataset browser
    if ( event->type() == WQT_READY_EVENT )
    {
        // convert event to assoc event
        WModuleReadyEvent* e = dynamic_cast< WModuleReadyEvent* >( event );     // NOLINT
        if ( !e )
        {
            // this should never happen, since the type is set to WQT_Ready_EVENT.
Sebastian Eichelbaum's avatar
[STYLE]  
Sebastian Eichelbaum committed
247 248
            WLogger::getLogger()->addLogMessage( "Event is not an WModueReadyEvent although its type claims it. Ignoring event.",
                                                 "DatasetBrowser", LL_WARNING );
249 250

            return true;
251 252
        }

Sebastian Eichelbaum's avatar
[STYLE]  
Sebastian Eichelbaum committed
253 254
        WLogger::getLogger()->addLogMessage( "Activating module " + e->getModule()->getName() + " in dataset browser.",
                                             "DatasetBrowser", LL_DEBUG );
255 256

        // iterate tree items and find proper one
257
        QTreeWidgetItemIterator it( m_moduleTreeWidget );
258 259
        while ( *it )
        {
260
            WQtTreeItem* item = dynamic_cast< WQtTreeItem* >( *it );
261
            boost::shared_ptr< WModule > module = boost::shared_ptr< WModule >();
262
            if ( item )
263
            {
264
                module = item->getModule();
265 266 267 268 269 270 271 272 273 274 275 276 277
            }

            // if the pointer is NULL the item was none of the above
            if ( !module.get() )
            {
                ++it;
                continue;
            }

            // we found it
            if ( e->getModule() == module )
            {
                // activate it
278
                item->setDisabled( false );
279
                selectTreeItem();
280

281 282
                // if the type number is 1 (dataset item) emit change event
                if ( item->type() == 1 )
283 284 285
                {
                    emit dataSetBrowserEvent( QString( "dataSetAdded" ), true );
                }
286 287 288 289
            }

            ++it;
        }
290 291

        return true;
292 293
    }

294 295
    return QDockWidget::event( event );
}
296

297
WQtDatasetTreeItem* WQtDatasetBrowser::addDataset( boost::shared_ptr< WModule > module, int subjectId )
298
{
schurade's avatar
schurade committed
299
    int c = getFirstSubject();
300
    WQtSubjectTreeItem* subject = static_cast< WQtSubjectTreeItem* >( m_moduleTreeWidget->topLevelItem( subjectId + c ) );
schurade's avatar
schurade committed
301
    subject->setExpanded( true );
302
    WQtDatasetTreeItem* item = subject->addDatasetItem( module );
303
    m_moduleTreeWidget->setCurrentItem( item );
304
    item->setDisabled( true );
305
    return item;
306
}
307

308 309
WQtModuleTreeItem* WQtDatasetBrowser::addModule( boost::shared_ptr< WModule > module )
{
schurade's avatar
schurade committed
310 311
    m_tiModules->setExpanded( true );
    WQtModuleTreeItem* item = m_tiModules->addModuleItem( module );
312
    m_moduleTreeWidget->setCurrentItem( item );
313 314
    item->setDisabled( true );
    return item;
315 316
}

schurade's avatar
schurade committed
317 318
void WQtDatasetBrowser::addRoi( boost::shared_ptr< WRMROIRepresentation > roi )
{
319 320 321 322 323
    WQtRoiTreeItem* newItem;
    WQtBranchTreeItem* branchItem;

    m_tiRois->setExpanded( true );

324
    if ( m_roiTreeWidget->selectedItems().count() != 0 )
schurade's avatar
schurade committed
325
    {
326
        switch ( m_roiTreeWidget->selectedItems().at( 0 )->type() )
schurade's avatar
schurade committed
327
        {
328
            case ROI :
schurade's avatar
schurade committed
329
            {
330
                branchItem =( static_cast< WQtBranchTreeItem* >( m_roiTreeWidget->selectedItems().at( 0 )->parent() ) );
schurade's avatar
schurade committed
331 332
                break;
            }
schurade's avatar
schurade committed
333
            case ROIBRANCH :
schurade's avatar
schurade committed
334
            {
335
                branchItem =( static_cast< WQtBranchTreeItem* >( m_roiTreeWidget->selectedItems().at( 0 ) ) );
schurade's avatar
schurade committed
336 337 338 339
                break;
            }
            default:
            {
340
                branchItem = m_tiRois->addBranch( roi->getBranch() );
schurade's avatar
schurade committed
341 342 343 344 345 346
                break;
            }
        }
    }
    else
    {
347
        branchItem = m_tiRois->addBranch( roi->getBranch() );
schurade's avatar
schurade committed
348
    }
349 350 351 352 353 354

    m_tabWidget2->setCurrentIndex( m_tabWidget2->indexOf( m_roiTreeWidget ) );
    branchItem->setExpanded( true );
    newItem = branchItem->addRoiItem( roi );
    newItem->setDisabled( false );
    newItem->setSelected( true );
schurade's avatar
schurade committed
355 356
}

357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379
void WQtDatasetBrowser::removeRoi( boost::shared_ptr< WRMROIRepresentation > roi )
{
    for( int branchID = 0; branchID < m_tiRois->childCount(); ++branchID )
    {
        QTreeWidgetItem* branchTreeItem = m_tiRois->child( branchID );
        for( int roiID = 0; roiID < branchTreeItem->childCount(); ++roiID )
        {
            WQtRoiTreeItem* roiTreeItem = dynamic_cast< WQtRoiTreeItem* >( branchTreeItem->child( roiID ) );
            if( roiTreeItem && roiTreeItem->getRoi() == roi )
            {
                delete roiTreeItem;

                if( branchTreeItem->childCount() == 0 )
                {
                    delete branchTreeItem;
                }

                break;
            }
        }
    }
}

380 381
boost::shared_ptr< WModule > WQtDatasetBrowser::getSelectedModule()
{
382
    if ( m_moduleTreeWidget->selectedItems().at( 0 )->type() == 1 )
383
    {
384
        return ( static_cast< WQtDatasetTreeItem* >( m_moduleTreeWidget->selectedItems().at( 0 ) )->getModule() );
385
    }
386
    else if ( m_moduleTreeWidget->selectedItems().at( 0 )->type() == 3 )
387
    {
388
        return ( static_cast< WQtModuleTreeItem* >( m_moduleTreeWidget->selectedItems().at( 0 ) )->getModule() );
389 390 391 392
    }

    return boost::shared_ptr< WModule >();
}
393

394 395
void WQtDatasetBrowser::selectTreeItem()
{
396 397
    // TODO(schurade): qt doc says clear() doesn't delete tabs so this is possibly a memory leak
    m_tabWidget->clear();
398
    m_mainWindow->getCompatiblesToolBar()->clearButtons();
399

400
    boost::shared_ptr< WModule > module;
401
    boost::shared_ptr< WProperties > props;
402
    boost::shared_ptr< WProperties > infoProps;
Sebastian Eichelbaum's avatar
[MERGE]  
Sebastian Eichelbaum committed
403

404
    if ( m_moduleTreeWidget->selectedItems().size() != 0  )
405
    {
406
        switch ( m_moduleTreeWidget->selectedItems().at( 0 )->type() )
schurade's avatar
schurade committed
407
        {
408
            case SUBJECT:
409 410 411 412
            case MODULEHEADER:
                // Here we just take a prototype module with no output connectors
                // to get the modules with no input connector.
                module = WModuleFactory::getModuleFactory()->getPrototypeByName( "HUD" );
413 414 415

                // deletion of headers and subjects is not allowed
                m_deleteModuleAction->setEnabled( false );
416
                createCompatibleButtons( module );
schurade's avatar
schurade committed
417
                break;
418
            case DATASET:
419
                module = ( static_cast< WQtDatasetTreeItem* >( m_moduleTreeWidget->selectedItems().at( 0 ) ) )->getModule();
420
                // crashed modules should not provide any props
421 422 423 424
                if ( module->isCrashed()() )
                {
                    return;
                }
425 426 427 428

                // enable the delete action as it might be disabled before.
                m_deleteModuleAction->setEnabled( true );

429
                props = module->getProperties();
430
                infoProps = module->getInformationProperties();
schurade's avatar
schurade committed
431 432
                createCompatibleButtons( module );
                break;
433
            case MODULE:
434
                module = ( static_cast< WQtModuleTreeItem* >( m_moduleTreeWidget->selectedItems().at( 0 ) ) )->getModule();
435 436 437 438 439 440 441 442 443 444 445
                // NOTE: this hack prevents the navigation slices to be removed as they are buggy and crash OpenWalnut if they get removed
                if ( module->getName() == "Navigation Slices" )
                {
                    m_deleteModuleAction->setEnabled( false );
                }
                else
                {
                    m_deleteModuleAction->setEnabled( true );
                }

                // crashed modules should not provide any props
446 447 448 449
                if ( module->isCrashed()() )
                {
                    return;
                }
450
                props = module->getProperties();
451
                infoProps = module->getInformationProperties();
452 453
                createCompatibleButtons( module );
                break;
454 455 456 457 458 459 460 461
            case ROIHEADER:
            case ROIBRANCH:
            case ROI:
                break;
            default:
                break;
        }
    }
462
    buildPropTab( props, infoProps );
463 464 465 466 467 468 469 470 471
}

void WQtDatasetBrowser::selectRoiTreeItem()
{
    // TODO(schurade): qt doc says clear() doesn't delete tabs so this is possibly a memory leak
    m_tabWidget->clear();
    m_mainWindow->getCompatiblesToolBar()->clearButtons();

    boost::shared_ptr< WModule > module;
472
    boost::shared_ptr< WProperties > props;
473 474 475 476 477 478 479 480 481

    if ( m_roiTreeWidget->selectedItems().size() != 0  )
    {
        switch ( m_roiTreeWidget->selectedItems().at( 0 )->type() )
        {
            case SUBJECT:
            case DATASET:
            case MODULEHEADER:
            case MODULE:
482
            case ROIHEADER:
schurade's avatar
schurade committed
483
                break;
schurade's avatar
schurade committed
484
            case ROIBRANCH:
485
                props = ( static_cast< WQtBranchTreeItem* >( m_roiTreeWidget->selectedItems().at( 0 ) ) )->getBranch()->getProperties();
schurade's avatar
schurade committed
486
                break;
487
            case ROI:
488
                props = ( static_cast< WQtRoiTreeItem* >( m_roiTreeWidget->selectedItems().at( 0 ) ) )->getRoi()->getProperties();
schurade's avatar
schurade committed
489 490 491 492
                break;
            default:
                break;
        }
493
    }
494
    WKernel::getRunningKernel()->getRoiManager()->setSelectedRoi( getFirstRoiInSelectedBranch() );
495
    buildPropTab( props, boost::shared_ptr< WProperties >() );
496
}
497

498
WQtDSBWidget*  WQtDatasetBrowser::buildPropWidget( boost::shared_ptr< WProperties > props )
499
{
500
    WQtDSBWidget* tab = new WQtDSBWidget( props->getName() );
501 502

    if ( props.get() )
503
    {
504
        WProperties::PropertyAccessType propAccess = props->getAccessObject();
505 506
        propAccess->beginRead();

507 508
        tab->setName( QString::fromStdString( props->getName() ) );

509
        // iterate all properties. This Locks the properties set -> use endIteration to unlock
510
        for ( WProperties::PropertyConstIterator iter = propAccess->get().begin(); iter != propAccess->get().end(); ++iter )
511
        {
512
            if ( !( *iter )->isHidden() )
513
            {
514
                switch ( ( *iter )->getType() )
515
                {
516
                    case PV_BOOL:
517
                        tab->addProp( ( *iter )->toPropBool() );
518 519
                        break;
                    case PV_INT:
520
                        tab->addProp( ( *iter )->toPropInt() );
521 522
                        break;
                    case PV_DOUBLE:
523
                        tab->addProp( ( *iter )->toPropDouble() );
524 525
                        break;
                    case PV_STRING:
526
                        tab->addProp( ( *iter )->toPropString() );
527 528
                        break;
                    case PV_PATH:
529
                        tab->addProp( ( *iter )->toPropFilename() );
530
                        break;
531 532
                    case PV_SELECTION:
                        WLogger::getLogger()->addLogMessage( "This property type \"PV_SELECTION\" is not yet supported by the GUI.", "DatasetBrowser",
Sebastian Eichelbaum's avatar
[STYLE]  
Sebastian Eichelbaum committed
533 534 535
                                LL_WARNING );
                        break;
                    case PV_COLOR:
536
                        tab->addProp( ( *iter )->toPropColor() );
Sebastian Eichelbaum's avatar
[STYLE]  
Sebastian Eichelbaum committed
537 538 539 540
                        break;
                    case PV_POSITION:
                        WLogger::getLogger()->addLogMessage( "This property type \"PV_POSITION\" is not yet supported by the GUI.", "DatasetBrowser",
                                LL_WARNING );
541
                        break;
542 543 544
                    case PV_TRIGGER:
                        tab->addProp( ( *iter )->toPropTrigger() );
                        break;
545 546 547
                    case PV_GROUP:
                        tab->addGroup( buildPropWidget( ( *iter )->toPropGroup() ) );
                        break;
548 549 550
                    default:
                        WLogger::getLogger()->addLogMessage( "This property type is not yet supported.", "DatasetBrowser", LL_WARNING );
                        break;
551
                }
552 553
            }
        }
554
        propAccess->endRead();
555
    }
556

557
    tab->addSpacer();
558 559 560
    return tab;
}

561
void WQtDatasetBrowser::buildPropTab( boost::shared_ptr< WProperties > props, boost::shared_ptr< WProperties > infoProps )
562
{
563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587
    WQtDSBWidget* tab = NULL;
    WQtDSBWidget* infoTab = NULL;
    if ( props )
    {
        tab = buildPropWidget( props );
        tab->setName( "Settings" );
    }
    if ( infoProps )
    {
        infoTab = buildPropWidget( infoProps );
        infoTab->setName( "Information" );
    }

    int infoIdx = addTabWidgetContent( infoTab );
    int propIdx = addTabWidgetContent( tab );

    // select the property widget preferably
    if ( propIdx != -1 )
    {
        m_tabWidget->setCurrentIndex( propIdx );
    }
    else if ( infoIdx != -1 )
    {
        m_tabWidget->setCurrentIndex( infoIdx );
    }
588 589
}

schurade's avatar
schurade committed
590 591 592
void WQtDatasetBrowser::createCompatibleButtons( boost::shared_ptr< WModule >module )
{
    // every module may have compatibles: create ribbon menu entry
593
    std::vector< boost::shared_ptr< WApplyPrototypeCombiner > > comps = WModuleFactory::getModuleFactory()->getCompatiblePrototypes( module );
594

595
    for ( std::vector< boost::shared_ptr< WApplyPrototypeCombiner > >::const_iterator iter = comps.begin(); iter != comps.end(); ++iter )
schurade's avatar
schurade committed
596
    {
597 598
        if( !m_moduleWhiteList.empty() )
        {
599
            const std::string tmpName = ( *iter )->getTargetPrototype()->getName();
600 601
            if( std::find( m_moduleWhiteList.begin(), m_moduleWhiteList.end(), tmpName ) == m_moduleWhiteList.end() )
            {
602
                continue; // do nothing for modules that are not in white list
603 604 605
            }
        }

606 607 608 609
        WQtApplyModulePushButton* button = new WQtApplyModulePushButton( m_mainWindow->getCompatiblesToolBar(), m_mainWindow->getIconManager(),
                                                                         *iter, m_showToolBarText
        );
        m_mainWindow->getCompatiblesToolBar()->addWidget( button );
schurade's avatar
schurade committed
610 611 612
    }
}

613 614
void WQtDatasetBrowser::changeTreeItem()
{
615
    if ( m_moduleTreeWidget->selectedItems().size() == 1 && m_moduleTreeWidget->selectedItems().at( 0 )->type() == DATASET )
616
    {
617 618
        boost::shared_ptr< WModule > module =( static_cast< WQtDatasetTreeItem* >( m_moduleTreeWidget->selectedItems().at( 0 ) ) )->getModule();
        module->getProperties()->getProperty( "active" )->toPropBool()->set( m_moduleTreeWidget->selectedItems().at( 0 )->checkState( 0 ) );
619
    }
620
    else if ( m_moduleTreeWidget->selectedItems().size() == 1 && m_moduleTreeWidget->selectedItems().at( 0 )->type() == MODULE )
621
    {
622
        boost::shared_ptr< WModule > module =( static_cast< WQtModuleTreeItem* >( m_moduleTreeWidget->selectedItems().at( 0 ) ) )->getModule();
623

624
        module->getProperties()->getProperty( "active" )->toPropBool()->set( m_moduleTreeWidget->selectedItems().at( 0 )->checkState( 0 ) );
625 626 627
    }
}

schurade's avatar
schurade committed
628 629 630 631 632 633 634 635 636
void WQtDatasetBrowser::changeRoiTreeItem()
{
    if ( m_roiTreeWidget->selectedItems().size() == 1 && m_roiTreeWidget->selectedItems().at( 0 )->type() == ROI )
    {
        boost::shared_ptr< WRMROIRepresentation > roi =( static_cast< WQtRoiTreeItem* >( m_roiTreeWidget->selectedItems().at( 0 ) ) )->getRoi();
        roi->getProperties()->getProperty( "active" )->toPropBool()->set( m_roiTreeWidget->selectedItems().at( 0 )->checkState( 0 ) );
    }
}

637
int WQtDatasetBrowser::addTabWidgetContent( WQtDSBWidget* content )
638
{
639
    if ( !content || content->isEmpty() )
640 641 642 643
    {
        return -1;
    }

644 645 646 647
    QScrollArea* sa = new QScrollArea();
    sa->setWidget( content );
    sa->setWidgetResizable( true );

648
    return m_tabWidget->addTab( sa, content->getName() );
649
}
650

651 652
void WQtDatasetBrowser::moveTreeItemDown()
{
653
    m_moduleTreeWidget->moveTreeItemDown();
654 655 656 657
}

void WQtDatasetBrowser::moveTreeItemUp()
{
658
    m_moduleTreeWidget->moveTreeItemUp();
659 660
}

schurade's avatar
schurade committed
661 662 663
int WQtDatasetBrowser::getFirstSubject()
{
    int c = 0;
664
    for ( int i = 0; i < m_moduleTreeWidget->topLevelItemCount() ; ++i )
schurade's avatar
schurade committed
665
    {
666
        if ( m_moduleTreeWidget->topLevelItem( i )->type() == SUBJECT )
schurade's avatar
schurade committed
667 668 669 670 671 672 673 674 675 676 677
        {
            break;
        }
        ++c;
    }
    return c;
}

boost::shared_ptr< WRMROIRepresentation > WQtDatasetBrowser::getSelectedRoi()
{
    boost::shared_ptr< WRMROIRepresentation >roi;
678
    if ( m_roiTreeWidget->selectedItems().count() == 0 )
schurade's avatar
schurade committed
679 680 681
    {
        return roi;
    }
682
    if ( m_roiTreeWidget->selectedItems().at( 0 )->type() == ROI )
schurade's avatar
schurade committed
683
    {
684
        roi =( static_cast< WQtRoiTreeItem* >( m_roiTreeWidget->selectedItems().at( 0 ) ) )->getRoi();
schurade's avatar
schurade committed
685
    }
schurade's avatar
schurade committed
686 687 688 689 690 691
    return roi;
}

boost::shared_ptr< WRMROIRepresentation > WQtDatasetBrowser::getFirstRoiInSelectedBranch()
{
    boost::shared_ptr< WRMROIRepresentation >roi;
692
    if ( m_roiTreeWidget->selectedItems().count() == 0 )
schurade's avatar
schurade committed
693
    {
schurade's avatar
schurade committed
694 695
        return roi;
    }
696
    if ( m_roiTreeWidget->selectedItems().at( 0 )->type() == ROI )
schurade's avatar
schurade committed
697
    {
698
        WQtBranchTreeItem* branch = ( static_cast< WQtBranchTreeItem* >( m_roiTreeWidget->selectedItems().at( 0 )->parent() ) );
schurade's avatar
schurade committed
699 700
        roi =( static_cast< WQtRoiTreeItem* >( branch->child( 0 ) ) )->getRoi();
    }
701
    if ( m_roiTreeWidget->selectedItems().at( 0 )->type() == ROIBRANCH )
schurade's avatar
schurade committed
702
    {
703
        WQtBranchTreeItem* branch = ( static_cast< WQtBranchTreeItem* >( m_roiTreeWidget->selectedItems().at( 0 ) ) );
schurade's avatar
schurade committed
704 705 706 707
        if ( branch->childCount() > 0 )
        {
            roi =( static_cast< WQtRoiTreeItem* >( branch->child( 0 ) ) )->getRoi();
        }
schurade's avatar
schurade committed
708 709 710
    }
    return roi;
}
schurade's avatar
schurade committed
711

712
void WQtDatasetBrowser::deleteModuleTreeItem()
schurade's avatar
schurade committed
713
{
714 715
    if ( m_moduleTreeWidget->selectedItems().count() > 0 )
    {
716 717 718 719 720 721 722 723
        if ( ( m_moduleTreeWidget->selectedItems().at( 0 )->type() == MODULE ) ||
             ( m_moduleTreeWidget->selectedItems().at( 0 )->type() == DATASET ) )
        {
            // instead of deleting the tree item directly -> inform the tree item and let it do the job:
            static_cast< WQtTreeItem* >( m_moduleTreeWidget->selectedItems().at( 0 ) )->deleteSelf();
            // select another item
            m_moduleTreeWidget->setCurrentItem( m_moduleTreeWidget->topLevelItem( 0 ) );
        }
724 725 726 727 728 729
    }
}

void WQtDatasetBrowser::deleteROITreeItem()
{
    boost::shared_ptr< WRMROIRepresentation >roi;
730
    if ( m_roiTreeWidget->selectedItems().count() > 0 )
schurade's avatar
schurade committed
731
    {
732
        if ( m_roiTreeWidget->selectedItems().at( 0 )->type() == ROIBRANCH )
schurade's avatar
schurade committed
733
        {
734 735 736 737 738
            roi = getFirstRoiInSelectedBranch();
            if ( roi )
            {
                WKernel::getRunningKernel()->getRoiManager()->removeBranch( roi );
            }
739
            delete m_roiTreeWidget->selectedItems().at( 0 );
schurade's avatar
schurade committed
740
        }
741 742

        else if ( m_roiTreeWidget->selectedItems().at( 0 )->type() == ROI )
schurade's avatar
schurade committed
743
        {
744 745 746 747
            roi =( static_cast< WQtRoiTreeItem* >( m_roiTreeWidget->selectedItems().at( 0 ) ) )->getRoi();
            if ( roi )
            {
                WKernel::getRunningKernel()->getRoiManager()->removeRoi( roi );
748
                // Removing the roi from the tree widget is also done by WROIManagerFibers::removeRoi().
749
            }
schurade's avatar
schurade committed
750 751
        }
    }
752
    WKernel::getRunningKernel()->getRoiManager()->setSelectedRoi( getFirstRoiInSelectedBranch() );
schurade's avatar
schurade committed
753
}