WMainWindow.cpp 22.3 KB
Newer Older
1 2
//---------------------------------------------------------------------------
//
3
// Project: OpenWalnut ( http://www.openwalnut.org )
4
//
5 6
// Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
// For more information see http://www.openwalnut.org/copying
wiebel's avatar
wiebel committed
7
//
wiebel's avatar
wiebel committed
8
// This file is part of OpenWalnut.
wiebel's avatar
wiebel committed
9
//
wiebel's avatar
wiebel committed
10
// OpenWalnut is free software: you can redistribute it and/or modify
wiebel's avatar
wiebel committed
11 12 13 14
// 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.
//
wiebel's avatar
wiebel committed
15
// OpenWalnut is distributed in the hope that it will be useful,
wiebel's avatar
wiebel committed
16 17 18 19 20
// 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
wiebel's avatar
wiebel committed
21
// along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
wiebel's avatar
wiebel committed
22
//
23 24
//---------------------------------------------------------------------------

25
#include <iostream>
26 27
#include <string>
#include <vector>
28
#include <map>
29

30 31
#include <boost/thread.hpp>

32
#include <QtGui/QApplication>
33
#include <QtGui/QMainWindow>
wiebel's avatar
wiebel committed
34
#include <QtGui/QDockWidget>
35
#include <QtGui/QFileDialog>
36
#include <QtGui/QMessageBox>
37
#include <QtGui/QSlider>
38
#include <QtGui/QShortcut>
39
#include <QtGui/QVBoxLayout>
40 41
#include <QtGui/QMenuBar>
#include <QtGui/QMenu>
42

43
#include "WMainWindow.h"
44
#include "WOpenCustomDockWidgetEvent.h"
45
#include "WQtGLWidget.h"
46
#include "WQtNavGLWidget.h"
47
#include "WQtCustomDockWidget.h"
48
#include "events/WModuleReadyEvent.h"
49
#include "events/WModuleCrashEvent.h"
50 51
#include "events/WEventTypes.h"
#include "datasetbrowser/WPropertyBoolWidget.h"
52 53 54
#include "../../common/WColor.h"
#include "../../common/WPreferences.h"
#include "../../kernel/WKernel.h"
55
#include "../../kernel/WModuleProjectFileCombiner.h"
56
#include "../../modules/data/WMData.h"
57
#include "../../modules/navSlices/WMNavSlices.h"
58 59 60 61

#include "../../dataHandler/WEEG.h"
#include "../../dataHandler/WDataSetSingle.h"
#include "../../dataHandler/WDataSetFibers.h"
wiebel's avatar
wiebel committed
62

schurade's avatar
schurade committed
63 64
#include "../../graphicsEngine/WROIBox.h"

65
#include "../icons/WIcons.h"
66

67
WMainWindow::WMainWindow() :
68
    QMainWindow(),
69
    m_iconManager()
Sebastian Eichelbaum's avatar
Sebastian Eichelbaum committed
70
{
71
    setupGUI();
Sebastian Eichelbaum's avatar
Sebastian Eichelbaum committed
72
}
73

74
void WMainWindow::setupGUI()
75
{
76
    m_iconManager.addIcon( std::string( "load" ), fileopen_xpm );
77
    m_iconManager.addIcon( std::string( "loadProject" ), projOpen_xpm );
78
    m_iconManager.addIcon( std::string( "logo" ), logoIcon_xpm );
79
    m_iconManager.addIcon( std::string( "help" ), question_xpm );
80
    m_iconManager.addIcon( std::string( "quit" ), quit_xpm );
81

82
    if( objectName().isEmpty() )
83
    {
84
        setObjectName( QString::fromUtf8( "MainWindow" ) );
85
    }
86 87 88
    resize( 946, 632 );
    setWindowIcon( m_iconManager.getIcon( "logo" ) );
    setWindowTitle( QApplication::translate( "MainWindow", "OpenWalnut", 0, QApplication::UnicodeUTF8 ) );
89

90 91 92 93 94 95 96 97 98
    m_menuBar = new QMenuBar( 0 );
    QMenu* fileMenu = m_menuBar->addMenu( "File" );
    fileMenu->addAction( m_iconManager.getIcon( "load" ), "Load", this, SLOT( openLoadDialog() ), QKeySequence( "Ctrl+L" ) );
    fileMenu->addAction( m_iconManager.getIcon( "quit" ), "Quit", this, SLOT( close() ), QKeySequence( "Ctrl+Q" ) );

    QMenu* helpMenu = m_menuBar->addMenu( "Help" );
    helpMenu->addAction( m_iconManager.getIcon( "help" ), "About OpenWalnut", this, SLOT( openAboutDialog() ), QKeySequence( "F1" ) );
    setMenuBar( m_menuBar );

99
    m_centralwidget = new QWidget( this );
100
    m_centralwidget->setObjectName( QString::fromUtf8( "centralwidget" ) );
101
    setCentralWidget( m_centralwidget );
102

103
    m_mainGLWidget = boost::shared_ptr< WQtGLWidget >( new WQtGLWidget( "main", this, WGECamera::ORTHOGRAPHIC ) );
104 105
    m_mainGLWidget->initialize();
    setCentralWidget( m_mainGLWidget.get() );
wiebel's avatar
wiebel committed
106

107 108 109 110 111
    // initially 3 navigation views
    {
        bool hideWidget;
        if( !( WPreferences::getPreference( "qt4gui.hideAxial", &hideWidget ) && hideWidget) )
        {
112
            m_navAxial = boost::shared_ptr< WQtNavGLWidget >( new WQtNavGLWidget( "axial", this, 160, "Axial Slice" ) );
113
            m_navAxial->setFeatures( QDockWidget::AllDockWidgetFeatures );
114 115 116 117
            addDockWidget( Qt::LeftDockWidgetArea, m_navAxial.get() );
        }
        if( !( WPreferences::getPreference( "qt4gui.hideCoronal", &hideWidget ) && hideWidget) )
        {
118
            m_navCoronal = boost::shared_ptr< WQtNavGLWidget >( new WQtNavGLWidget( "coronal", this, 200, "Coronal Slice" ) );
119
            m_navCoronal->setFeatures( QDockWidget::AllDockWidgetFeatures );
120 121 122 123
            addDockWidget( Qt::LeftDockWidgetArea, m_navCoronal.get() );
        }
        if( !( WPreferences::getPreference( "qt4gui.hideSagittal", &hideWidget ) && hideWidget) )
        {
124
            m_navSagittal = boost::shared_ptr< WQtNavGLWidget >( new WQtNavGLWidget( "sagittal", this, 160, "Sagittal Slice" ) );
125
            m_navSagittal->setFeatures( QDockWidget::AllDockWidgetFeatures );
126 127 128
            addDockWidget( Qt::LeftDockWidgetArea, m_navSagittal.get() );
        }
    }
129

Mathias Goldau's avatar
[MERGE]  
Mathias Goldau committed
130 131 132 133 134 135 136 137 138
    // we do not need the dummy widget if there are no other widgets.
    if( m_navAxial || m_navCoronal || m_navSagittal )
    {
        m_dummyWidget = new QDockWidget( this );
        m_dummyWidget->setFeatures( QDockWidget::NoDockWidgetFeatures );
        m_dummyWidget->setSizePolicy( QSizePolicy::Preferred, QSizePolicy::Ignored );
        addDockWidget( Qt::LeftDockWidgetArea, m_dummyWidget );
    }

139
    // Default background color from config file
140
    {
141 142 143 144 145 146 147 148 149 150 151
        WColor bgColor;
        double r;
        double g;
        double b;
        if( WPreferences::getPreference( "ge.bgColor.r", &r )
            && WPreferences::getPreference( "ge.bgColor.g", &g )
            && WPreferences::getPreference( "ge.bgColor.b", &b ) )
        {
            bgColor.setRGB( r, g, b );
            m_mainGLWidget->setBgColor( bgColor );
        }
152 153
    }

154
    setupPermanentToolBar();
155

156 157
    setupCompatiblesToolBar();

158
    m_datasetBrowser = new WQtDatasetBrowser( this );
159
    m_datasetBrowser->setFeatures( QDockWidget::AllDockWidgetFeatures );
160
    addDockWidget( Qt::RightDockWidgetArea, m_datasetBrowser );
161
    m_datasetBrowser->addSubject( "Default Subject" );
162
}
163

164
void WMainWindow::setupPermanentToolBar()
165
{
166
    m_permanentToolBar = new WQtToolBar( "Permanent Toolbar", this );
167

168 169 170 171
    m_iconManager.addIcon( std::string( "ROI" ), box_xpm );
    m_iconManager.addIcon( std::string( "axial" ), axial_xpm );
    m_iconManager.addIcon( std::string( "coronal" ), cor_xpm );
    m_iconManager.addIcon( std::string( "sagittal" ), sag_xpm );
172 173


174 175
    WQtPushButton* loadButton = new WQtPushButton( m_iconManager.getIcon( "load" ), "load", m_permanentToolBar );
    WQtPushButton* roiButton = new WQtPushButton( m_iconManager.getIcon( "ROI" ), "ROI", m_permanentToolBar );
176
    WQtPushButton* projectButton = new WQtPushButton( m_iconManager.getIcon( "loadProject" ), "loadProject", m_permanentToolBar );
177

178 179
    connect( loadButton, SIGNAL( pressed() ), this, SLOT( openLoadDialog() ) );
    connect( roiButton, SIGNAL( pressed() ), this, SLOT( newRoi() ) );
180
    connect( projectButton, SIGNAL( pressed() ), this, SLOT( projectLoad() ) );
181

182 183
    loadButton->setToolTip( "Load Data" );
    roiButton->setToolTip( "Create New ROI" );
184
    projectButton->setToolTip( "Load a project from file" );
185

186
    m_permanentToolBar->addWidget( loadButton );
187 188
    m_permanentToolBar->addWidget( projectButton );
    m_permanentToolBar->addSeparator();
189
    m_permanentToolBar->addWidget( roiButton );
190

191
    m_permanentToolBar->addSeparator();
192

193 194
    addToolBar( Qt::TopToolBarArea, m_permanentToolBar );
}
195

196 197 198 199 200 201 202 203 204 205
void WMainWindow::autoAdd( boost::shared_ptr< WModule > module, std::string proto )
{
    // get the prototype.
    if ( !WKernel::getRunningKernel()->getRootContainer()->applyModule( module, proto, true ) )
    {
        WLogger::getLogger()->addLogMessage( "Auto Display active but module " + proto + " could not be added.",
                                             "GUI", LL_ERROR );
    }
}

206 207
void WMainWindow::moduleSpecificSetup( boost::shared_ptr< WModule > module )
{
208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228
    // Add all special handlings here. This method is called whenever a module is marked "ready". You can set up the gui for special modules,
    // load certain modules for datasets and so on.

    // The Data Modules also play an special role. To have modules being activated when certain data got loaded, we need to hook it up here.
    bool useAutoDisplay = true;
    WPreferences::getPreference( "qt4gui.useAutoDisplay", &useAutoDisplay );
    if ( useAutoDisplay && module->getType() == MODULE_DATA )
    {
        WLogger::getLogger()->addLogMessage( "Auto Display active and Data module added. The proper module will be added.",
                                             "GUI", LL_DEBUG );

        // data modules contain an member denoting the real data type. Currently we only have one data module and a not very modulated data
        // structures.
        boost::shared_ptr< WMData > dataModule = boost::shared_static_cast< WMData >( module );

        // grab data and identify type
        if ( dataModule->getDataSet()->isA< WDataSetSingle >() )
        {
            // it is a dataset single
            // load a nav slice module if a WDataSetSingle is available!?

229 230 231 232 233
            // if it already is running: add it
            if ( !WMNavSlices::isRunning() )
            {
                autoAdd( module, "Navigation Slice Module" );
            }
234 235 236 237 238 239 240 241 242 243 244 245 246
        }
        else if ( dataModule->getDataSet()->isA< WDataSetFibers >() )
        {
            // it is a fiber dataset -> add the FiberDisplay module
            autoAdd( module, "Fiber Display" );
        }
        else if ( dataModule->getDataSet()->isA< WEEG >() )
        {
            // it is a eeg dataset -> add the eegView module?
            autoAdd( module, "EEG View" );
        }
    }

247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264
    // nav slices use separate buttons for slice on/off switching
    if ( module->getName() == "Navigation Slice Module" )
    {
        boost::shared_ptr< WPropertyBase > prop = module->getProperties2()->findProperty( "showAxial" );
        if ( !prop )
        {
               WLogger::getLogger()->
                   addLogMessage( "Navigation Slice Module does not provide the property \"showAxial\", which is required by the GUI.", "GUI",
                                  LL_ERROR );
        }
        else
        {
            WPropertyBoolWidget* button = new WPropertyBoolWidget( prop->toPropBool(), NULL, m_permanentToolBar, true );
            button->setToolTip( "Toggle Axial Slice" );
            button->getButton()->setMaximumSize( 24, 24 );
            button->getButton()->setIcon( m_iconManager.getIcon( "axial" ) );
            m_permanentToolBar->addWidget( button );
        }
265

266 267 268 269 270 271 272 273 274 275 276 277 278 279 280
        prop = module->getProperties2()->findProperty( "showCoronal" );
        if ( !prop )
        {
               WLogger::getLogger()->
                   addLogMessage( "Navigation Slice Module does not provide the property \"showCoronal\", which is required by the GUI.", "GUI",
                                  LL_ERROR );
        }
        else
        {
            WPropertyBoolWidget* button = new WPropertyBoolWidget( prop->toPropBool(), NULL, m_permanentToolBar, true );
            button->setToolTip( "Toggle Coronal Slice" );
            button->getButton()->setMaximumSize( 24, 24 );
            button->getButton()->setIcon( m_iconManager.getIcon( "coronal" ) );
            m_permanentToolBar->addWidget( button );
        }
281

282 283 284 285 286 287 288 289 290 291 292 293 294 295 296
        prop = module->getProperties2()->findProperty( "showSagittal" );
        if ( !prop )
        {
               WLogger::getLogger()->
                   addLogMessage( "Navigation Slice Module does not provide the property \"showSagittal\", which is required by the GUI.", "GUI",
                                  LL_ERROR );
        }
        else
        {
            WPropertyBoolWidget* button = new WPropertyBoolWidget( prop->toPropBool(), NULL, m_permanentToolBar, true );
            button->setToolTip( "Toggle Sagittal Slice" );
            button->getButton()->setMaximumSize( 24, 24 );
            button->getButton()->setIcon( m_iconManager.getIcon( "sagittal" ) );
            m_permanentToolBar->addWidget( button );
        }
297 298

        // now setup the nav widget sliders
299
        prop = module->getProperties2()->findProperty( "Axial Slice" );
300 301 302
        if ( !prop )
        {
               WLogger::getLogger()->
303
                   addLogMessage( "Navigation Slice Module does not provide the property \"Axial Slice\", which is required by the GUI.", "GUI",
304 305 306 307
                                  LL_ERROR );
        }
        else
        {
308 309 310 311
            if( m_navAxial )
            {
                m_navAxial->setSliderProperty( prop->toPropInt() );
            }
312 313
        }

314
        prop = module->getProperties2()->findProperty( "Coronal Slice" );
315 316 317
        if ( !prop )
        {
               WLogger::getLogger()->
318
                   addLogMessage( "Navigation Slice Module does not provide the property \"Coronal Slice\", which is required by the GUI.", "GUI",
319 320 321 322
                                  LL_ERROR );
        }
        else
        {
323 324 325 326
            if( m_navCoronal )
            {
                m_navCoronal->setSliderProperty( prop->toPropInt() );
            }
327 328
        }

329
        prop = module->getProperties2()->findProperty( "Sagittal Slice" );
330 331 332
        if ( !prop )
        {
               WLogger::getLogger()->
333
                   addLogMessage( "Navigation Slice Module does not provide the property \"Sagittal Slice\", which is required by the GUI.", "GUI",
334 335 336 337
                                  LL_ERROR );
        }
        else
        {
338 339 340 341
            if( m_navSagittal )
            {
               m_navSagittal->setSliderProperty( prop->toPropInt() );
            }
342
        }
343
    }
wiebel's avatar
wiebel committed
344
}
345

346 347
void WMainWindow::setupCompatiblesToolBar()
{
348 349
    m_iconManager.addIcon( std::string( "o" ), o_xpm ); // duumy icon for modules

350
    m_compatiblesToolBar = new WQtToolBar( "Compatible Modules Toolbar", this );
351 352 353 354 355 356 357 358 359 360 361

    // optional toolbar break
    {
        bool useToolBarBreak = true;
        WPreferences::getPreference( "qt4gui.useToolBarBreak", &useToolBarBreak );
        if( useToolBarBreak )
        {
            addToolBarBreak( Qt::TopToolBarArea );
        }
    }

362 363
    addToolBar( Qt::TopToolBarArea, m_compatiblesToolBar );
}
364

365
WQtDatasetBrowser* WMainWindow::getDatasetBrowser()
366
{
367
    return m_datasetBrowser;
368
}
369

370
WQtToolBar* WMainWindow::getCompatiblesToolBar()
371 372 373 374
{
    return m_compatiblesToolBar;
}

375 376 377 378 379 380
void WMainWindow::projectLoad()
{
    QFileDialog fd;
    fd.setFileMode( QFileDialog::ExistingFiles );

    QStringList filters;
381
    filters << "Simple Project File (*.owproj)"
382 383 384 385 386 387 388 389 390 391 392 393
            << "Any files (*)";
    fd.setNameFilters( filters );
    fd.setViewMode( QFileDialog::Detail );
    QStringList fileNames;
    if ( fd.exec() )
    {
        fileNames = fd.selectedFiles();
    }

    QStringList::const_iterator constIterator;
    for ( constIterator = fileNames.constBegin(); constIterator != fileNames.constEnd(); ++constIterator )
    {
394
        WModuleProjectFileCombiner proj = WModuleProjectFileCombiner( ( *constIterator ).toStdString() );
395
        proj.run();
396 397 398
    }
}

399
void WMainWindow::openLoadDialog()
400
{
401 402
    QFileDialog fd;
    fd.setFileMode( QFileDialog::ExistingFiles );
wiebel's avatar
wiebel committed
403 404

    QStringList filters;
405 406
    filters << "Known file types (*.cnt *.edf *.asc *.nii *.nii.gz *.fib)"
            << "EEG files (*.cnt *.edf *.asc)"
wiebel's avatar
wiebel committed
407
            << "NIfTI (*.nii *.nii.gz)"
408 409
            << "Fibers (*.fib)"
            << "Any files (*)";
wiebel's avatar
wiebel committed
410
    fd.setNameFilters( filters );
411 412 413 414 415 416 417
    fd.setViewMode( QFileDialog::Detail );
    QStringList fileNames;
    if ( fd.exec() )
    {
        fileNames = fd.selectedFiles();
    }

418
    std::vector< std::string > stdFileNames;
419 420 421 422 423 424

    QStringList::const_iterator constIterator;
    for ( constIterator = fileNames.constBegin(); constIterator != fileNames.constEnd(); ++constIterator )
    {
        stdFileNames.push_back( ( *constIterator ).toLocal8Bit().constData() );
    }
425 426
    m_loaderSignal( stdFileNames );
}
427

428 429 430 431 432 433 434 435 436 437 438 439 440 441 442
void WMainWindow::openAboutDialog()
{
    QMessageBox::about( this, "About OpenWalnut",
                        "OpenWalnut ( http://www.openwalnut.org )\n\n"
                        "Copyright (C) 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS. "
                        "For more information see http://www.openwalnut.org/copying.\n\n"
                        "This program comes with ABSOLUTELY NO WARRANTY. "
                        "This is free software, and you are welcome to redistribute it "
                        "under the terms of the GNU Lesser General Public License. "
                        "You should have received a copy of the GNU Lesser General Public License "
                        "along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.\n"
                        "\n"
                        "Thank you for using OpenWalnut." );
}

schurade's avatar
schurade committed
443
boost::signals2::signal1< void, std::vector< std::string > >* WMainWindow::getLoaderSignal()
444 445 446 447
{
    return &m_loaderSignal;
}

448
boost::signals2::signal2< void, boost::shared_ptr< WModule >, boost::shared_ptr< WModule > >* WMainWindow::getModuleButtonSignal()
449 450 451 452
{
    return &m_moduleButtonSignal;
}

453 454 455
WIconManager*  WMainWindow::getIconManager()
{
    return &m_iconManager;
456
}
457 458 459 460 461 462 463 464 465 466

void WMainWindow::closeEvent( QCloseEvent* e )
{
    // use some "Really Close?" Dialog here
    bool reallyClose = true;


    // handle close event
    if ( reallyClose )
    {
467 468
        // signal everybody to shut down properly.
        WKernel::getRunningKernel()->finalize();
469 470 471 472

        // now nobody acesses the osg anymore
        // clean up gl widgets
        m_mainGLWidget->close();
473 474 475 476 477 478 479 480 481 482 483 484
        if( m_navAxial )
        {
            m_navAxial->close();
        }
        if( m_navCoronal )
        {
            m_navCoronal->close();
        }
        if( m_navSagittal )
        {
            m_navSagittal->close();
        }
485

486 487 488 489 490 491 492
        // delete CustomDockWidgets
        boost::mutex::scoped_lock lock( m_customDockWidgetsLock );
        for( std::map< std::string, boost::shared_ptr< WQtCustomDockWidget > >::iterator it = m_customDockWidgets.begin();
             it != m_customDockWidgets.end(); ++it )
        {
            it->second->close();
        }
493
        //m_customDockWidgetsLock.unlock();
494

495 496 497 498 499 500 501 502 503
        // finally close
        e->accept();
    }
    else
    {
        e->ignore();
    }
}

504 505
void WMainWindow::customEvent( QEvent* event )
{
506
    if( event->type() == WOpenCustomDockWidgetEvent::CUSTOM_TYPE )
507
    {
508 509 510 511 512
        // OpenCustomDockWidgetEvent
        WOpenCustomDockWidgetEvent* ocdwEvent = static_cast< WOpenCustomDockWidgetEvent* >( event );
        std::string title = ocdwEvent->getTitle();

        boost::shared_ptr< WQtCustomDockWidget > widget;
513 514

        boost::mutex::scoped_lock lock( m_customDockWidgetsLock );
515 516
        if( m_customDockWidgets.count( title ) == 0 )
        {
517 518 519
            // create new custom dock widget
            widget = boost::shared_ptr< WQtCustomDockWidget >(
                new WQtCustomDockWidget( title, this, ocdwEvent->getProjectionMode() ) );
520 521 522 523 524 525 526
            addDockWidget( Qt::BottomDockWidgetArea, widget.get() );

            // store it in CustomDockWidget list
            m_customDockWidgets.insert( make_pair( title, widget ) );
        }
        else
        {
527 528
            widget = m_customDockWidgets[title];
            widget->increaseUseCount();
529
        }
530
        //m_customDockWidgetsLock.unlock();
531 532

        ocdwEvent->getFlag()->set( widget );
533 534 535 536 537 538 539 540
    }
    else
    {
        // other event
        QMainWindow::customEvent( event );
    }
}

541 542 543 544 545 546 547 548 549 550 551 552 553
bool WMainWindow::event( QEvent* event )
{
    // a module got associated with the root container -> add it to the list
    if ( event->type() == WQT_READY_EVENT )
    {
        // convert event to ready event
        WModuleReadyEvent* e1 = dynamic_cast< WModuleReadyEvent* >( event );     // NOLINT
        if ( e1 )
        {
            moduleSpecificSetup( e1->getModule() );
        }
    }

554 555 556 557 558 559 560 561 562 563 564 565 566
    if ( event->type() == WQT_CRASH_EVENT )
    {
        // convert event to ready event
        WModuleCrashEvent* e1 = dynamic_cast< WModuleCrashEvent* >( event );     // NOLINT
        if ( e1 )
        {
            QString title = "Module crashed: " + QString::fromStdString( e1->getModule()->getName() );
            QString message = "<b>Module Crashed</b><br/><br/><b>Module:  </b>" + QString::fromStdString( e1->getModule()->getName() ) +
                              "<br/><b>Message:  </b>" + QString::fromStdString( e1->getMessage() );
            QMessageBox::critical( this, title, message );
        }
    }

567 568 569
    return QMainWindow::event( event );
}

570 571 572 573 574 575
boost::shared_ptr< WQtCustomDockWidget > WMainWindow::getCustomDockWidget( std::string title )
{
    boost::mutex::scoped_lock lock( m_customDockWidgetsLock );
    boost::shared_ptr< WQtCustomDockWidget > out = m_customDockWidgets.count( title ) > 0 ?
        m_customDockWidgets[title] :
        boost::shared_ptr< WQtCustomDockWidget >();
576
    //m_customDockWidgetsLock.unlock();
577 578 579 580
    return out;
}


581 582 583
void WMainWindow::closeCustomDockWidget( std::string title )
{
    boost::mutex::scoped_lock lock( m_customDockWidgetsLock );
584
    if( m_customDockWidgets.count( title ) > 0 )
585
    {
586 587 588 589 590
        if( m_customDockWidgets[title]->decreaseUseCount() )
        {
            // custom dock widget should be deleted
            m_customDockWidgets.erase( title );
        }
591
    }
592
    //m_customDockWidgetsLock.unlock();
593 594
}

595 596
void WMainWindow::slotActivateModule( QString module )
{
597 598
    // TODO(schurade): do we really need the signal? Why can't we use the kernel directly?
    m_moduleButtonSignal( getDatasetBrowser()->getSelectedModule(), WModuleFactory::getModuleFactory()->getPrototypeByName( module.toStdString() ) );
599
}
600

schurade's avatar
schurade committed
601 602
void WMainWindow::newRoi()
{
Mathias Goldau's avatar
[MERGE]  
Mathias Goldau committed
603
    // do nothing if we can not get
604
    if( !WKernel::getRunningKernel()->getRoiManager()->getBitField() )
Mathias Goldau's avatar
[MERGE]  
Mathias Goldau committed
605
    {
606
        wlog::warn( "WMainWindow" ) << "Refused to add ROI, as ROIManager does not have computed its bitfield yet.";
Mathias Goldau's avatar
[MERGE]  
Mathias Goldau committed
607 608 609
        return;
    }

schurade's avatar
schurade committed
610
    if ( m_datasetBrowser->getFirstRoiInSelectedBranch().get() == NULL )
schurade's avatar
schurade committed
611
    {
schurade's avatar
schurade committed
612
        osg::ref_ptr< WROIBox > newRoi = osg::ref_ptr< WROIBox >( new WROIBox( wmath::WPosition( 60., 60., 60. ),
schurade's avatar
[STYLE]  
schurade committed
613
                wmath::WPosition( 80., 80., 80. ) ) );
schurade's avatar
schurade committed
614 615 616 617
        WKernel::getRunningKernel()->getRoiManager()->addRoi( newRoi );
    }
    else
    {
schurade's avatar
schurade committed
618
        osg::ref_ptr< WROIBox > newRoi = osg::ref_ptr< WROIBox >( new WROIBox( wmath::WPosition( 60., 60., 60. ),
schurade's avatar
[STYLE]  
schurade committed
619
                wmath::WPosition( 80., 80., 80. ) ) );
schurade's avatar
schurade committed
620
        WKernel::getRunningKernel()->getRoiManager()->addRoi( newRoi, m_datasetBrowser->getFirstRoiInSelectedBranch()->getROI() );
schurade's avatar
schurade committed
621 622
    }
}