WMainWindow.cpp 12 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/QSlider>
37
#include <QtGui/QShortcut>
38 39
#include <QtGui/QVBoxLayout>

40 41
#include "WMainWindow.h"
#include "WQtGLWidget.h"
42
#include "../../kernel/WKernel.h"
ebaum's avatar
ebaum committed
43

44
#include "WQtNavGLWidget.h"
45 46
#include "WCreateCustomDockWidgetEvent.h"
#include "WQtCustomDockWidget.h"
wiebel's avatar
wiebel committed
47

48
#include "../icons/WIcons.h"
49

50
WMainWindow::WMainWindow( boost::program_options::variables_map guiConfiguration ) :
51
    QMainWindow(),
52 53
    m_iconManager(),
    m_propertyManager()
Sebastian Eichelbaum's avatar
Sebastian Eichelbaum committed
54
{
55
    setupGUI( guiConfiguration );
Sebastian Eichelbaum's avatar
Sebastian Eichelbaum committed
56
}
57

58
void WMainWindow::setupGUI( boost::program_options::variables_map guiConfiguration )
59
{
60
    m_iconManager.addIcon( std::string( "logo" ), logoIcon_xpm );
61

62
    if( objectName().isEmpty() )
63
    {
64
        setObjectName( QString::fromUtf8( "MainWindow" ) );
65
    }
66 67 68
    resize( 946, 632 );
    setWindowIcon( m_iconManager.getIcon( "logo" ) );
    setWindowTitle( QApplication::translate( "MainWindow", "OpenWalnut", 0, QApplication::UnicodeUTF8 ) );
69

70
    m_centralwidget = new QWidget( this );
71
    m_centralwidget->setObjectName( QString::fromUtf8( "centralwidget" ) );
72
    setCentralWidget( m_centralwidget );
73

74
    m_mainGLWidget = boost::shared_ptr< WQtGLWidget >( new WQtGLWidget( "main", this, WGECamera::ORTHOGRAPHIC ) );
75 76
    m_mainGLWidget->initialize();
    setCentralWidget( m_mainGLWidget.get() );
wiebel's avatar
wiebel committed
77

78 79 80 81 82 83 84 85 86 87 88 89 90 91
    // initially 3 views
    m_navAxial = boost::shared_ptr< WQtNavGLWidget >( new WQtNavGLWidget( "axial", this, 160, "axialPos" ) );
    addDockWidget( Qt::LeftDockWidgetArea, m_navAxial.get() );

    m_navCoronal = boost::shared_ptr< WQtNavGLWidget >( new WQtNavGLWidget( "coronal", this, 200, "coronalPos" ) );
    addDockWidget( Qt::LeftDockWidgetArea, m_navCoronal.get() );

    m_navSagittal = boost::shared_ptr< WQtNavGLWidget >( new WQtNavGLWidget( "sagittal", this, 160, "sagittalPos" ) );
    addDockWidget( Qt::LeftDockWidgetArea, m_navSagittal.get() );

    connect( m_navAxial.get(), SIGNAL( navSliderValueChanged( QString, int ) ), &m_propertyManager, SLOT( slotIntChanged( QString, int ) ) );
    connect( m_navCoronal.get(), SIGNAL( navSliderValueChanged( QString, int ) ), &m_propertyManager, SLOT( slotIntChanged( QString, int ) ) );
    connect( m_navSagittal.get(), SIGNAL( navSliderValueChanged( QString, int ) ), &m_propertyManager, SLOT( slotIntChanged( QString, int ) ) );

92 93 94 95 96 97
    if( guiConfiguration.count( "ge.bgColor.r" ) && guiConfiguration.count( "ge.bgColor.g" ) && guiConfiguration.count( "ge.bgColor.b" ) )
    {
        WColor bgColor( guiConfiguration["ge.bgColor.r"].as< float >(),
                        guiConfiguration["ge.bgColor.g"].as< float >(),
                        guiConfiguration["ge.bgColor.b"].as< float >() );
        m_mainGLWidget->setBgColor( bgColor );
98 99 100
        m_navAxial->getGLWidget()->setBgColor( bgColor );
        m_navCoronal->getGLWidget()->setBgColor( bgColor );
        m_navSagittal->getGLWidget()->setBgColor( bgColor );
101 102
    }

103 104
    setupRibbonMenu();
    m_ribbonMenu->clearNonPersistentTabs();
105

106 107
    setupCompatiblesToolBar();

108
    m_datasetBrowser = new WQtDatasetBrowser( this );
109
    addDockWidget( Qt::RightDockWidgetArea, m_datasetBrowser );
110
    m_datasetBrowser->addSubject( "Default Subject" );
111

112
    connect( m_datasetBrowser, SIGNAL( dataSetBrowserEvent( QString, bool ) ), &m_propertyManager, SLOT( slotBoolChanged( QString, bool ) ) );
113
}
114

115
void WMainWindow::setupRibbonMenu()
116
{
117
    m_ribbonMenu = new WQtRibbonMenu( this );
118

119 120 121
    m_iconManager.addIcon( std::string( "quit" ), quit_xpm );
    m_iconManager.addIcon( std::string( "save" ), disc_xpm );
    m_iconManager.addIcon( std::string( "load" ), fileopen_xpm );
122

123 124 125 126
    m_ribbonMenu->addTab( QString( "File" ) );
    m_ribbonMenu->addPushButton( QString( "buttonLoad" ), QString( "File" ), m_iconManager.getIcon( "load" ), QString( "Load" ) );
    m_ribbonMenu->addPushButton( QString( "buttonSave" ), QString( "File" ), m_iconManager.getIcon( "save" ), QString( "Save" ) );
    m_ribbonMenu->addPushButton( QString( "buttonQuit" ), QString( "File" ), m_iconManager.getIcon( "quit" ), QString( "Exit" ) );
127

128 129 130 131
    // the parent (this) will take care for deleting the shortcut
    QShortcut* shortcut = new QShortcut( QKeySequence( tr( "Ctrl+Q", "File|Exit" ) ), this );
    connect( shortcut, SIGNAL( activated() ), this, SLOT( close() ) );

132 133
    connect( m_ribbonMenu->getButton( QString( "buttonQuit" ) ), SIGNAL( pressed() ), this, SLOT( close() ) );
    connect( m_ribbonMenu->getButton( QString( "buttonLoad" ) ), SIGNAL( pressed() ), this, SLOT( openLoadDialog() ) );
134

135 136
    m_ribbonMenu->addTab( QString( "Modules" ) );
    m_ribbonMenu->addTab( QString( "Help" ) );
137

138 139 140
    m_iconManager.addIcon( std::string( "axial" ), axial_xpm );
    m_iconManager.addIcon( std::string( "coronal" ), cor_xpm );
    m_iconManager.addIcon( std::string( "sagittal" ), sag_xpm );
141

142 143 144
    m_ribbonMenu->addPushButton( QString( "showAxial" ), QString( "Modules" ), m_iconManager.getIcon( "axial" ) );
    m_ribbonMenu->addPushButton( QString( "showCoronal" ), QString( "Modules" ), m_iconManager.getIcon( "coronal" ) );
    m_ribbonMenu->addPushButton( QString( "showSagittal" ), QString( "Modules" ), m_iconManager.getIcon( "sagittal" ) );
145

146 147 148
    m_ribbonMenu->getButton( QString( "showAxial" ) )->setMaximumSize( 24, 24 );
    m_ribbonMenu->getButton( QString( "showCoronal" ) )->setMaximumSize( 24, 24 );
    m_ribbonMenu->getButton( QString( "showSagittal" ) )->setMaximumSize( 24, 24 );
149

150 151 152
    m_ribbonMenu->getButton( QString( "showAxial" ) )->setCheckable( true );
    m_ribbonMenu->getButton( QString( "showCoronal" ) )->setCheckable( true );
    m_ribbonMenu->getButton( QString( "showSagittal" ) )->setCheckable( true );
153

154 155 156
    m_ribbonMenu->getButton( QString( "showAxial" ) )->setChecked( true );
    m_ribbonMenu->getButton( QString( "showCoronal" ) )->setChecked( true );
    m_ribbonMenu->getButton( QString( "showSagittal" ) )->setChecked( true );
157

158 159 160
    m_ribbonMenu->getButton( QString( "showAxial" ) )->setToolTip( "Axial" );
    m_ribbonMenu->getButton( QString( "showCoronal" ) )->setToolTip( "Coronal" );
    m_ribbonMenu->getButton( QString( "showSagittal" ) )->setToolTip( "Sagittal" );
161

162
    connect( m_ribbonMenu->getButton( QString( "showAxial" ) ),
163
            SIGNAL( pushButtonToggled( QString, bool ) ), &m_propertyManager, SLOT( slotBoolChanged( QString, bool ) ) );
164
    connect( m_ribbonMenu->getButton( QString( "showCoronal" ) ),
165
            SIGNAL( pushButtonToggled( QString, bool ) ), &m_propertyManager, SLOT( slotBoolChanged( QString, bool ) ) );
166
    connect( m_ribbonMenu->getButton( QString( "showSagittal" ) ),
167
            SIGNAL( pushButtonToggled( QString, bool ) ), &m_propertyManager, SLOT( slotBoolChanged( QString, bool ) ) );
168

169
    addToolBar( Qt::TopToolBarArea, m_ribbonMenu );
wiebel's avatar
wiebel committed
170
}
171

172 173 174 175 176 177
void WMainWindow::setupCompatiblesToolBar()
{
    m_compatiblesToolBar = new WQtRibbonMenu( this );

    addToolBar( Qt::TopToolBarArea, m_compatiblesToolBar );
}
178

179
WQtDatasetBrowser* WMainWindow::getDatasetBrowser()
180
{
181
    return m_datasetBrowser;
182
}
183

184
WQtRibbonMenu* WMainWindow::getRibbonMenu()
185
{
186
    return m_ribbonMenu;
187
}
188

189 190 191 192 193
WQtRibbonMenu* WMainWindow::getCompatiblesToolBar()
{
    return m_compatiblesToolBar;
}

194
void WMainWindow::openLoadDialog()
195
{
196 197
    QFileDialog fd;
    fd.setFileMode( QFileDialog::ExistingFiles );
wiebel's avatar
wiebel committed
198 199

    QStringList filters;
200 201
    filters << "Known file types (*.edf *.asc *.nii *.nii.gz *.fib)"
            << "EEG files (*.asc *.edf)"
wiebel's avatar
wiebel committed
202
            << "NIfTI (*.nii *.nii.gz)"
203 204
            << "Fibers (*.fib)"
            << "Any files (*)";
wiebel's avatar
wiebel committed
205
    fd.setNameFilters( filters );
206 207 208 209 210 211 212 213 214 215 216 217 218 219
    fd.setViewMode( QFileDialog::Detail );
    QStringList fileNames;
    if ( fd.exec() )
    {
        fileNames = fd.selectedFiles();
    }

    std::vector< std::string >stdFileNames;

    QStringList::const_iterator constIterator;
    for ( constIterator = fileNames.constBegin(); constIterator != fileNames.constEnd(); ++constIterator )
    {
        stdFileNames.push_back( ( *constIterator ).toLocal8Bit().constData() );
    }
220 221
    m_loaderSignal( stdFileNames );
}
222

schurade's avatar
schurade committed
223
boost::signals2::signal1< void, std::vector< std::string > >* WMainWindow::getLoaderSignal()
224 225 226 227
{
    return &m_loaderSignal;
}

228
boost::signals2::signal2< void, boost::shared_ptr< WModule >, boost::shared_ptr< WModule > >* WMainWindow::getModuleButtonSignal()
229 230 231 232 233
{
    return &m_moduleButtonSignal;
}


schurade's avatar
schurade committed
234 235 236 237 238
boost::signals2::signal1< void, std::string >* WMainWindow::getPickSignal()
{
    return m_mainGLWidget->getPickSignal();
}

239
WPropertyManager*  WMainWindow::getPropertyManager()
240
{
241 242 243 244 245 246
    return &m_propertyManager;
}

WIconManager*  WMainWindow::getIconManager()
{
    return &m_iconManager;
247
}
248 249 250 251 252 253 254 255 256 257

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


    // handle close event
    if ( reallyClose )
    {
258 259
        // signal everybody to shut down properly.
        WKernel::getRunningKernel()->finalize();
260 261 262 263

        // now nobody acesses the osg anymore
        // clean up gl widgets
        m_mainGLWidget->close();
264

265 266 267
        m_navAxial->close();
        m_navCoronal->close();
        m_navSagittal->close();
268

269 270 271 272 273 274 275 276 277
        // 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();
        }
        m_customDockWidgetsLock.unlock();

278 279 280 281 282 283 284 285 286
        // finally close
        e->accept();
    }
    else
    {
        e->ignore();
    }
}

287 288 289 290 291 292 293 294 295 296 297 298 299 300 301
void WMainWindow::customEvent( QEvent* event )
{
    if( event->type() == WCreateCustomDockWidgetEvent::CUSTOM_TYPE )
    {
        // CreateCustomDockWidgetEvent
        WCreateCustomDockWidgetEvent* ccdwEvent = static_cast< WCreateCustomDockWidgetEvent* >( event );
        std::string title = ccdwEvent->getTitle();

        boost::shared_ptr< WQtCustomDockWidget > widget = boost::shared_ptr< WQtCustomDockWidget >( new WQtCustomDockWidget( title, this ) );
        addDockWidget( Qt::BottomDockWidgetArea, widget.get() );

        // store it in CustomDockWidget list
        boost::mutex::scoped_lock lock( m_customDockWidgetsLock );
        assert( m_customDockWidgets.insert( make_pair( title, widget ) ).second == true );
        m_customDockWidgetsLock.unlock();
302 303

        ccdwEvent->getCondition()->notify();
304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323
    }
    else
    {
        // other event
        QMainWindow::customEvent( event );
    }
}

void WMainWindow::closeCustomDockWidget( std::string title )
{
    boost::mutex::scoped_lock lock( m_customDockWidgetsLock );
    if (m_customDockWidgets.count( title ) > 0 )
    {
        m_customDockWidgets[title]->close();

        m_customDockWidgets.erase( title );
    }
    m_customDockWidgetsLock.unlock();
}

324 325
void WMainWindow::slotActivateModule( QString module )
{
326 327
    // 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() ) );
328
}
329