WQt4Gui.cpp 8.67 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
#include <boost/program_options.hpp>
31
#include <boost/shared_ptr.hpp>
32

33
#include <QtGui/QApplication>
34 35
#include <QtGui/QFileDialog>

Mathias Goldau's avatar
Mathias Goldau committed
36
#include "WMainWindow.h" // this has to be included before any other includes
37 38
#include "../../common/WConditionOneShot.h"
#include "../../common/WIOTools.h"
39
#include "../../graphicsEngine/WGraphicsEngine.h"
Mathias Goldau's avatar
Mathias Goldau committed
40
#include "../../kernel/WKernel.h"
41
#include "../../common/WProjectFile.h"
42 43
#include "../../dataHandler/WDataHandler.h"
#include "../../dataHandler/WSubject.h"
44
#include "WOpenCustomDockWidgetEvent.h"
Mathias Goldau's avatar
Mathias Goldau committed
45
#include "WQt4Gui.h"
46
#include "events/WModuleAssocEvent.h"
schurade's avatar
schurade committed
47
#include "events/WRoiAssocEvent.h"
48
#include "events/WModuleReadyEvent.h"
49
#include "events/WModuleCrashEvent.h"
50
#include "events/WUpdateTextureSorterEvent.h"
ebaum's avatar
ebaum committed
51

Mathias Goldau's avatar
[ADD]  
Mathias Goldau committed
52 53
WQt4Gui::WQt4Gui( int argc, char** argv )
    : WGUI( argc, argv )
ebaum's avatar
ebaum committed
54 55 56
{
}

57
WQt4Gui::~WQt4Gui()
58
{
ebaum's avatar
ebaum committed
59
}
Sebastian Eichelbaum's avatar
[STYLE]  
Sebastian Eichelbaum committed
60

Mathias Goldau's avatar
[ADD]  
Mathias Goldau committed
61
bool WQt4Gui::parseOptions()
62
{
Mathias Goldau's avatar
Mathias Goldau committed
63 64
    namespace po = boost::program_options; // since the namespace is far to big we use a shortcut here
    po::options_description desc( "Allowed options" );
65 66 67

    desc.add_options()
        ( "help,h", "Prints this help message" )
68
        ( "project,p", po::value< std::string >(), "Project file to be loaded on startup." )
69 70
        ( "input,i", po::value< std::vector< std::string > >(), "Input data files that should be loaded automatically" )
        ( "timed-output,t", "Flag indicating if all log strings should have a time string preceding" );
71 72 73 74

    po::positional_options_description p;
    p.add( "input", -1 );

75 76
    try
    {
Mathias Goldau's avatar
[ADD]  
Mathias Goldau committed
77
        po::store( po::command_line_parser( m_argc, m_argv ).options( desc ).positional( p ).run(), m_optionsMap );
78
    }
Mathias Goldau's avatar
Mathias Goldau committed
79
    catch( const po::error &e )
80
    {
Mathias Goldau's avatar
Mathias Goldau committed
81
        std::cerr << e.what() << std::endl;
82 83 84 85 86 87 88 89 90 91
        return false;
    }

    po::notify( m_optionsMap );

    // print usage information if command line asks for help.
    if( m_optionsMap.count( "help" ) )
    {
        std::cout << desc << std::endl;
    }
92 93 94 95 96
    else if( m_optionsMap.count( "timed-output" ) )
    {
        WLogger::getLogger()->setDefaultFormat( "[%t] *%l [%s] %m \n" );
        wlog::info( "GUI" ) << "Timed output enabled";
    }
97 98 99
    return true;
}

100 101 102 103 104
void WQt4Gui::moduleError( boost::shared_ptr< WModule > module, const WException& exception )
{
    QCoreApplication::postEvent( m_mainWindow, new WModuleCrashEvent( module, exception.what() ) );
}

105 106
int WQt4Gui::run()
{
Mathias Goldau's avatar
[ADD]  
Mathias Goldau committed
107
    bool parsingSuccessful = parseOptions();
108 109 110

    if( !parsingSuccessful )
    {
111 112
        return 1;
    }
113

114
    // exit as fast as possible if command line asked for help. The ,essage has been printed by parseOptions().
115 116
    if( m_optionsMap.count( "help" ) )
    {
117
        return 1;
118 119
    }

120
    WLogger::getLogger()->run();
121
    WLogger::getLogger()->addLogMessage( "Bringing up GUI", "GUI", LL_INFO );
122

Mathias Goldau's avatar
[ADD]  
Mathias Goldau committed
123
    QApplication appl( m_argc, m_argv, true );
124

125
    // startup graphics engine
126
    m_ge = WGraphicsEngine::getGraphicsEngine();
127

128 129 130
    // and startup kernel
    m_kernel = boost::shared_ptr< WKernel >( new WKernel( m_ge, shared_from_this() ) );
    m_kernel->run();
131 132 133
    t_ModuleErrorSignalHandlerType func = boost::bind( &WQt4Gui::moduleError, this, _1, _2 );
    m_kernel->getRootContainer()->addDefaultNotifier( WM_ERROR, func );

134
    // create the window
135
    m_mainWindow = new WMainWindow();
136
    m_mainWindow->show();
137

138
    // connect out loader signal with kernel
139 140 141
#ifdef _WIN32
    getLoadButtonSignal()->connect( boost::bind( &WKernel::loadDataSetsSynchronously, m_kernel, _1 ) );
#else
142
    getLoadButtonSignal()->connect( boost::bind( &WKernel::loadDataSets, m_kernel, _1 ) );
143
#endif
144

145 146 147
    WCondition::t_ConditionNotifierType newDatasetSignal = boost::bind( &WQt4Gui::slotUpdateTextureSorter, this );
    WDataHandler::getDefaultSubject()->getListChangeCondition()->subscribeSignal( newDatasetSignal );

148
    // bind the GUI's slot with the ready signal
149 150
    t_ModuleGenericSignalHandlerType assocSignal = boost::bind( &WQt4Gui::slotAddDatasetOrModuleToBrowser, this, _1 );
    m_kernel->getRootContainer()->addDefaultNotifier( WM_ASSOCIATED, assocSignal );
151 152
    t_ModuleGenericSignalHandlerType readySignal = boost::bind( &WQt4Gui::slotActivateDatasetOrModuleInBrowser, this, _1 );
    m_kernel->getRootContainer()->addDefaultNotifier( WM_READY, readySignal );
schurade's avatar
[STYLE]  
schurade committed
153
    boost::function< void( boost::shared_ptr< WRMROIRepresentation > ) > assocRoiSignal = boost::bind( &WQt4Gui::slotAddRoiToBrowser, this, _1 );
schurade's avatar
schurade committed
154
    m_kernel->getRoiManager()->addDefaultNotifier( assocRoiSignal );
155 156

    // now we are initialized
157
    m_isInitialized( true );
158

159 160 161
    // check if we want to load data due to command line and call the respective function
    if( m_optionsMap.count("input") )
    {
162
        m_kernel->loadDataSets( m_optionsMap["input"].as< std::vector< std::string > >() );
163 164
    }

165 166 167 168 169
    // Load project file
    if( m_optionsMap.count("project") )
    {
        try
        {
170 171
            boost::shared_ptr< WProjectFile > proj = boost::shared_ptr< WProjectFile >(
                    new WProjectFile( m_optionsMap["project"].as< std::string >() )
172
            );
173

174
            // This call is asynchronous. It parses the file and the starts a thread to actually do all the stuff
175
            proj->load();
176
        }
Sebastian Eichelbaum's avatar
[STYLE]  
Sebastian Eichelbaum committed
177
        catch( const WException& e )
178 179 180 181 182 183
        {
            wlog::error( "GUI" ) << "Project file \"" << m_optionsMap["project"].as< std::string >() << "\" could not be loaded. Message: " <<
                e.what();
        }
    }

184
    // run
185 186 187 188 189 190 191
    int qtRetCode = appl.exec();

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

    return qtRetCode;
192 193
}

194 195 196 197 198 199
void WQt4Gui::slotUpdateTextureSorter()
{
    // create a new event for this and insert it into event queue
    QCoreApplication::postEvent( m_mainWindow->getDatasetBrowser(), new WUpdateTextureSorterEvent() );
}

200
void WQt4Gui::slotAddDatasetOrModuleToBrowser( boost::shared_ptr< WModule > module )
201
{
202
    // create a new event for this and insert it into event queue
Sebastian Eichelbaum's avatar
[STYLE]  
Sebastian Eichelbaum committed
203
    QCoreApplication::postEvent( m_mainWindow->getDatasetBrowser(), new WModuleAssocEvent( module ) );
204 205
}

schurade's avatar
schurade committed
206 207 208 209 210
void WQt4Gui::slotAddRoiToBrowser( boost::shared_ptr< WRMROIRepresentation > roi )
{
    QCoreApplication::postEvent( m_mainWindow->getDatasetBrowser(), new WRoiAssocEvent( roi ) );
}

211 212 213
void WQt4Gui::slotActivateDatasetOrModuleInBrowser( boost::shared_ptr< WModule > module )
{
    // create a new event for this and insert it into event queue
Sebastian Eichelbaum's avatar
[STYLE]  
Sebastian Eichelbaum committed
214
    QCoreApplication::postEvent( m_mainWindow->getDatasetBrowser(), new WModuleReadyEvent( module ) );
215
    QCoreApplication::postEvent( m_mainWindow, new WModuleReadyEvent( module ) );
216 217
}

218 219
boost::shared_ptr< WModule > WQt4Gui::getSelectedModule()
{
220
    return m_mainWindow->getDatasetBrowser()->getSelectedModule();
221 222
}

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

228
boost::shared_ptr< WCustomWidget > WQt4Gui::openCustomWidget( std::string title, WGECamera::ProjectionMode projectionMode,
229
    boost::shared_ptr< WCondition > shutdownCondition )
230
{
231 232 233 234
    WConditionSet conditionSet;
    conditionSet.setResetable( true, false );
    conditionSet.add( shutdownCondition );

235 236
    boost::shared_ptr< WFlag< boost::shared_ptr< WCustomWidget > > > widgetFlag(
        new WFlag< boost::shared_ptr< WCustomWidget > >( new WConditionOneShot, boost::shared_ptr< WCustomWidget >() ) );
237 238
    conditionSet.add( widgetFlag->getCondition() );

239
    QCoreApplication::postEvent( m_mainWindow, new WOpenCustomDockWidgetEvent( title, projectionMode, widgetFlag ) );
240 241 242

    conditionSet.wait();
    return widgetFlag->get();
243 244 245 246
}

void WQt4Gui::closeCustomWidget( std::string title )
{
247
    m_mainWindow->closeCustomDockWidget( title );
248
}