WQt4Gui.cpp 12.7 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
7
//
wiebel's avatar
wiebel committed
8
// This file is part of OpenWalnut.
9
//
wiebel's avatar
wiebel committed
10
// OpenWalnut is free software: you can redistribute it and/or modify
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,
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/>.
22 23 24
//
//---------------------------------------------------------------------------

ebaum's avatar
ebaum committed
25
#include <iostream>
26
#include <fstream>
27 28
#include <string>
#include <vector>
29

30 31 32 33
// Use filesystem version 2 for compatibility with newer boost versions.
#ifndef BOOST_FILESYSTEM_VERSION
    #define BOOST_FILESYSTEM_VERSION 2
#endif
34
#include <boost/filesystem.hpp>
35
#include <boost/shared_ptr.hpp>
36

37
#include <QtGui/QApplication>
38
#include <QtGui/QFileDialog>
39 40
#include <QtCore/QSettings>

41

Mathias Goldau's avatar
Mathias Goldau committed
42
#include "WMainWindow.h" // this has to be included before any other includes
43 44 45 46 47 48 49 50 51 52 53
#include "core/common/WConditionOneShot.h"
#include "core/common/WIOTools.h"
#include "core/common/WPathHelper.h"
#include "core/dataHandler/WDataHandler.h"
#include "core/dataHandler/WSubject.h"
#include "core/graphicsEngine/WGraphicsEngine.h"
#include "core/kernel/modules/data/WMData.h"
#include "core/kernel/WKernel.h"
#include "core/kernel/WModuleContainer.h"
#include "core/kernel/WProjectFile.h"
#include "core/kernel/WROIManager.h"
54
#include "controlPanel/WQtControlPanel.h"
55
#include "events/WModuleAssocEvent.h"
56
#include "events/WModuleConnectEvent.h"
Mathias Goldau's avatar
Mathias Goldau committed
57
#include "events/WModuleCrashEvent.h"
58
#include "events/WModuleDisconnectEvent.h"
59
#include "events/WModuleReadyEvent.h"
60
#include "events/WModuleRemovedEvent.h"
61
#include "events/WOpenCustomDockWidgetEvent.h"
Mathias Goldau's avatar
Mathias Goldau committed
62 63
#include "events/WRoiAssocEvent.h"
#include "events/WRoiRemoveEvent.h"
64
#include "events/WUpdateTextureSorterEvent.h"
Mathias Goldau's avatar
Mathias Goldau committed
65
#include "WQt4Gui.h"
ebaum's avatar
ebaum committed
66

67 68
WMainWindow* WQt4Gui::m_mainWindow = NULL;

69 70
QSettings* WQt4Gui::m_settings = NULL;

71 72 73
WQt4Gui::WQt4Gui( const boost::program_options::variables_map& options, int argc, char** argv )
    : WGUI( argc, argv ),
    m_optionsMap( options )
ebaum's avatar
ebaum committed
74
{
75
    m_settings = new QSettings( "OpenWalnut.org", "OpenWalnut" );
ebaum's avatar
ebaum committed
76 77
}

78
WQt4Gui::~WQt4Gui()
79
{
80
    delete m_settings;
ebaum's avatar
ebaum committed
81
}
Sebastian Eichelbaum's avatar
[STYLE]  
Sebastian Eichelbaum committed
82

83 84 85 86 87
void WQt4Gui::moduleError( boost::shared_ptr< WModule > module, const WException& exception )
{
    QCoreApplication::postEvent( m_mainWindow, new WModuleCrashEvent( module, exception.what() ) );
}

88 89 90 91 92
WMainWindow* WQt4Gui::getMainWindow()
{
    return m_mainWindow;
}

93 94
int WQt4Gui::run()
{
95 96
    // init logger
    m_loggerConnection = WLogger::getLogger()->subscribeSignal( WLogger::AddLog, boost::bind( &WQt4Gui::slotAddLog, this, _1 ) );
97

98 99 100
    // make qapp instance before using the applicationDirPath() function
    QApplication appl( m_argc, m_argv, true );

101
    // the call path of the application, this uses QApplication which needs to be instantiated.
102
    boost::filesystem::path walnutBin = boost::filesystem::path( QApplication::applicationDirPath().toStdString() );
103

104
    // setup path helper which provides several paths to others^
105
    WPathHelper::getPathHelper()->setAppPath( walnutBin );
106

107
    // get the minimum log level from preferences
108 109
    LogLevel logLevel = static_cast< LogLevel >( WQt4Gui::getSettings().value( "qt4gui/logLevel", LL_INFO ).toInt() );
    WLogger::getLogger()->setDefaultLogLevel( logLevel );
110 111

    // print the first output
112
    wlog::debug( "OpenWalnut" ) << "OpenWalnut binary path: " << walnutBin;
113
    wlog::info( "GUI" ) << "Bringing up GUI";
114

115
    // startup graphics engine
116
    m_ge = WGraphicsEngine::getGraphicsEngine();
117

118
    // and startup kernel
119
    m_kernel = boost::shared_ptr< WKernel >( WKernel::instance( m_ge, shared_from_this() ) );
120
    m_kernel->run();
121 122 123
    t_ModuleErrorSignalHandlerType func = boost::bind( &WQt4Gui::moduleError, this, _1, _2 );
    m_kernel->getRootContainer()->addDefaultNotifier( WM_ERROR, func );

124
    // create the window
125
    m_mainWindow = new WMainWindow();
126
    m_mainWindow->setupGUI();
127
    m_mainWindow->show();
128

129
    // connect out loader signal with kernel
130 131 132
#ifdef _WIN32
    getLoadButtonSignal()->connect( boost::bind( &WKernel::loadDataSetsSynchronously, m_kernel, _1 ) );
#else
133
    getLoadButtonSignal()->connect( boost::bind( &WKernel::loadDataSets, m_kernel, _1 ) );
134
#endif
135

136 137 138
    WCondition::t_ConditionNotifierType newDatasetSignal = boost::bind( &WQt4Gui::slotUpdateTextureSorter, this );
    WDataHandler::getDefaultSubject()->getListChangeCondition()->subscribeSignal( newDatasetSignal );

139
    // bind the GUI's slot with the ready signal
140 141

    // Assoc Event
142
    t_ModuleGenericSignalHandlerType assocSignal = boost::bind( &WQt4Gui::slotAddDatasetOrModuleToTree, this, _1 );
143
    m_kernel->getRootContainer()->addDefaultNotifier( WM_ASSOCIATED, assocSignal );
144 145

    // Ready Event
146
    t_ModuleGenericSignalHandlerType readySignal = boost::bind( &WQt4Gui::slotActivateDatasetOrModuleInTree, this, _1 );
147
    m_kernel->getRootContainer()->addDefaultNotifier( WM_READY, readySignal );
148 149

    // Remove Event
150
    t_ModuleGenericSignalHandlerType removedSignal = boost::bind( &WQt4Gui::slotRemoveDatasetOrModuleInTree, this, _1 );
151 152
    m_kernel->getRootContainer()->addDefaultNotifier( WM_REMOVED, removedSignal );

153 154 155 156 157 158 159 160
    // Connect Event
    t_GenericSignalHandlerType connectionEstablishedSignal = boost::bind( &WQt4Gui::slotConnectionEstablished, this, _1, _2 );
    m_kernel->getRootContainer()->addDefaultNotifier( CONNECTION_ESTABLISHED, connectionEstablishedSignal );

    // Disconnect Event
    t_GenericSignalHandlerType connectionClosedSignal = boost::bind( &WQt4Gui::slotConnectionClosed, this, _1, _2 );
    m_kernel->getRootContainer()->addDefaultNotifier( CONNECTION_CLOSED, connectionClosedSignal );

161 162 163 164
    boost::shared_ptr< boost::function< void( osg::ref_ptr< WROI > ) > > assocRoiSignal;
    assocRoiSignal =
        boost::shared_ptr< boost::function< void( osg::ref_ptr< WROI > ) > >(
            new boost::function< void( osg::ref_ptr< WROI > ) > ( boost::bind( &WQt4Gui::slotAddRoiToTree, this, _1 ) ) );
165
    m_kernel->getRoiManager()->addAddNotifier( assocRoiSignal );
166 167 168 169 170 171


    boost::shared_ptr< boost::function< void( osg::ref_ptr< WROI > ) > > removeRoiSignal;
    removeRoiSignal =
        boost::shared_ptr< boost::function< void( osg::ref_ptr< WROI > ) > >(
            new boost::function< void( osg::ref_ptr< WROI > ) > ( boost::bind( &WQt4Gui::slotRemoveRoiFromTree, this, _1 ) ) );
172
    m_kernel->getRoiManager()->addRemoveNotifier( removeRoiSignal );
173 174

    // now we are initialized
175
    m_isInitialized( true );
176

177 178 179
    // check if we want to load data due to command line and call the respective function
    if( m_optionsMap.count("input") )
    {
180
        m_kernel->loadDataSets( m_optionsMap["input"].as< std::vector< std::string > >() );
181 182
    }

183 184 185 186 187
    // Load project file
    if( m_optionsMap.count("project") )
    {
        try
        {
188 189
            boost::shared_ptr< WProjectFile > proj = boost::shared_ptr< WProjectFile >(
                    new WProjectFile( m_optionsMap["project"].as< std::string >() )
190
            );
191

192
            // This call is asynchronous. It parses the file and the starts a thread to actually do all the stuff
193
            proj->load();
194
        }
Sebastian Eichelbaum's avatar
[STYLE]  
Sebastian Eichelbaum committed
195
        catch( const WException& e )
196 197 198 199 200 201
        {
            wlog::error( "GUI" ) << "Project file \"" << m_optionsMap["project"].as< std::string >() << "\" could not be loaded. Message: " <<
                e.what();
        }
    }

202
    // run
203 204
    int qtRetCode = appl.exec();

205 206
    delete m_mainWindow;

207 208 209 210
    // signal everybody to shut down properly.
    WKernel::getRunningKernel()->wait( true );
    WKernel::getRunningKernel()->getGraphicsEngine()->wait( true );

211 212
    m_loggerConnection.disconnect();

213
    return qtRetCode;
214 215
}

216 217 218
void WQt4Gui::slotUpdateTextureSorter()
{
    // create a new event for this and insert it into event queue
219
    QCoreApplication::postEvent( m_mainWindow->getControlPanel(), new WUpdateTextureSorterEvent() );
220 221
}

Sebastian Eichelbaum's avatar
Sebastian Eichelbaum committed
222
void WQt4Gui::slotAddLog( const WLogEntry& /*entry*/ )
223
{
Sebastian Eichelbaum's avatar
Sebastian Eichelbaum committed
224
    // TODO(rfrohl): create a new event for this and insert it into event queue
225 226
}

227
void WQt4Gui::slotAddDatasetOrModuleToTree( boost::shared_ptr< WModule > module )
228
{
229
    // create a new event for this and insert it into event queue
230
    QCoreApplication::postEvent( m_mainWindow->getControlPanel(), new WModuleAssocEvent( module ) );
231
    QCoreApplication::postEvent( m_mainWindow->getNetworkEditor(), new WModuleAssocEvent( module ) );
232 233
}

234
void WQt4Gui::slotAddRoiToTree( osg::ref_ptr< WROI > roi )
schurade's avatar
schurade committed
235
{
236
    QCoreApplication::postEvent( m_mainWindow->getControlPanel(), new WRoiAssocEvent( roi ) );
schurade's avatar
schurade committed
237 238
}

239
void WQt4Gui::slotRemoveRoiFromTree( osg::ref_ptr< WROI > roi )
240
{
241
    QCoreApplication::postEvent( m_mainWindow->getControlPanel(), new WRoiRemoveEvent( roi ) );
242 243
}

244
void WQt4Gui::slotActivateDatasetOrModuleInTree( boost::shared_ptr< WModule > module )
245 246
{
    // create a new event for this and insert it into event queue
247
    QCoreApplication::postEvent( m_mainWindow->getControlPanel(), new WModuleReadyEvent( module ) );
248
    QCoreApplication::postEvent( m_mainWindow, new WModuleReadyEvent( module ) );
249
    QCoreApplication::postEvent( m_mainWindow->getNetworkEditor(), new WModuleReadyEvent( module ) );
250 251
}

252
void WQt4Gui::slotRemoveDatasetOrModuleInTree( boost::shared_ptr< WModule > module )
253 254
{
    // create a new event for this and insert it into event queue
255 256 257 258 259
    if( module->getName() == "Data Module" )
    {
        boost::shared_ptr< WMData > dataModule = boost::shared_dynamic_cast< WMData >( module );
        WAssert( dataModule, "Internal failure." );
    }
260
    QCoreApplication::postEvent( m_mainWindow->getNetworkEditor(), new WModuleRemovedEvent( module ) );
261
    QCoreApplication::postEvent( m_mainWindow->getControlPanel(), new WModuleRemovedEvent( module ) );
262
    QCoreApplication::postEvent( m_mainWindow, new WModuleRemovedEvent( module ) );
263 264
}

265 266 267
void WQt4Gui::slotConnectionEstablished( boost::shared_ptr<WModuleConnector> in, boost::shared_ptr<WModuleConnector> out )
{
    // create a new event for this and insert it into event queue
268
    if( in->isInputConnector() )
269
    {
270
        QCoreApplication::postEvent( m_mainWindow->getControlPanel(), new WModuleConnectEvent( in, out ) );
271
        QCoreApplication::postEvent( m_mainWindow->getNetworkEditor(), new WModuleConnectEvent( in, out ) );
272 273 274
    }
    else
    {
275
        QCoreApplication::postEvent( m_mainWindow->getControlPanel(), new WModuleConnectEvent( out, in ) );
276
        QCoreApplication::postEvent( m_mainWindow->getNetworkEditor(), new WModuleConnectEvent( out, in ) );
277
    }
278 279 280 281 282
}

void WQt4Gui::slotConnectionClosed( boost::shared_ptr<WModuleConnector> in, boost::shared_ptr<WModuleConnector> out )
{
    // create a new event for this and insert it into event queue
283
    if( in->isInputConnector() )
284
    {
285
        QCoreApplication::postEvent( m_mainWindow->getNetworkEditor(), new WModuleDisconnectEvent( in, out ) );
286
        QCoreApplication::postEvent( m_mainWindow->getControlPanel(), new WModuleDisconnectEvent( in, out ) );
287 288 289
    }
    else
    {
290
        QCoreApplication::postEvent( m_mainWindow->getNetworkEditor(), new WModuleDisconnectEvent( out, in ) );
291
        QCoreApplication::postEvent( m_mainWindow->getControlPanel(), new WModuleDisconnectEvent( out, in ) );
292
    }
293 294
}

295 296
boost::shared_ptr< WModule > WQt4Gui::getSelectedModule()
{
297
    return m_mainWindow->getControlPanel()->getSelectedModule();
298 299
}

schurade's avatar
schurade committed
300
boost::signals2::signal1< void, std::vector< std::string > >* WQt4Gui::getLoadButtonSignal()
301
{
302
    return m_mainWindow->getLoaderSignal();
303 304
}

305
boost::shared_ptr< WCustomWidget > WQt4Gui::openCustomWidget( std::string title, WGECamera::ProjectionMode projectionMode,
306
    boost::shared_ptr< WCondition > shutdownCondition )
307
{
308 309 310 311
    WConditionSet conditionSet;
    conditionSet.setResetable( true, false );
    conditionSet.add( shutdownCondition );

312 313
    boost::shared_ptr< WFlag< boost::shared_ptr< WCustomWidget > > > widgetFlag(
        new WFlag< boost::shared_ptr< WCustomWidget > >( new WConditionOneShot, boost::shared_ptr< WCustomWidget >() ) );
314 315
    conditionSet.add( widgetFlag->getCondition() );

316
    QCoreApplication::postEvent( m_mainWindow, new WOpenCustomDockWidgetEvent( title, projectionMode, widgetFlag ) );
317 318 319

    conditionSet.wait();
    return widgetFlag->get();
320 321 322 323
}

void WQt4Gui::closeCustomWidget( std::string title )
{
324
    m_mainWindow->closeCustomDockWidget( title );
325
}
326 327 328 329 330 331

QSettings& WQt4Gui::getSettings()
{
    return *m_settings;
}