OpenWalnut.cpp 8.4 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 <fstream>
26 27 28
#include <iostream>
#include <string>
#include <vector>
29

30 31
#ifdef OW_BOOST_PROGRAM_OPTIONS_FIX
// This circumvents an issue with boost program_options. The linker complains about missing "arg".
Sebastian Eichelbaum's avatar
[STYLE]  
Sebastian Eichelbaum committed
32 33 34 35 36 37 38
namespace boost
{
    namespace program_options
    {
        std::string arg;
    }
}
39 40
#endif  // OW_BOOST_PROGRAM_OPTIONS_FIX

41
#include <boost/program_options.hpp>
42
#include <boost/filesystem.hpp>
43

44
#include "core/common/WLogger.h"
45
#include "core/common/WIOTools.h"
46
#include "core/common/WLogStream.h"
47
#include "core/common/WThreadedRunner.h"
48
#include "core/common/WSegmentationFault.h"
49

50
#include "WQtGui.h"
51
#include "core/WVersion.h"   // NOTE: this file is auto-generated by CMAKE
ebaum's avatar
[ADD]  
ebaum committed
52

wiebel's avatar
wiebel committed
53
/**
wiebel's avatar
wiebel committed
54
 * \mainpage OpenWalnut Inline Documentation
Alexander Wiebel's avatar
Alexander Wiebel committed
55 56 57
 * \par
 * http://www.openwalnut.org
 * \par
58 59 60 61
 * Copyright 2009-2014 The OpenWalnut Community,
 *           2009-2014 Nemtics,
 *           2009-2014 Abteilung fuer Bild- und Signalverarbeitung, Universitaet Leipzig,
 *           2009-2013 Max-Planck Institute of Cognitive Neuroscience, Leipzig, Germany.
Alexander Wiebel's avatar
Alexander Wiebel committed
62 63 64
 * For more information see http://www.openwalnut.org/copying
 */

65
void printVersion()
66
{
67 68 69 70 71
    std::cout << "OpenWalnut -- Version: " << W_VERSION << " ( http://www.openwalnut.org )"
              << std::endl
              << std::endl;

    std::cout <<
72 73 74 75
    "Copyright 2009-2014 The OpenWalnut Community\n"
    "          2012-2014 Nemtics\n"
    "          2009-2014 Abteilung fuer Bild- und Signalverarbeitung, Universitaet Leipzig\n"
    "          2009-2013 Max-Planck Institute of Cognitive Neuroscience, Leipzig, Germany\n"
76
    "For more information see http://www.openwalnut.org/copying\n"
77 78 79 80
    "This program comes with ABSOLUTELY NO WARRANTY.\n"
    "This is free software, and you are welcome to redistribute it\n"
    "under the terms of the GNU Lesser General Public License.\n"
    "You should have received a copy of the GNU Lesser General Public License\n"
wiebel's avatar
wiebel committed
81
    "along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>." << std::endl;
wiebel's avatar
wiebel committed
82
    std::cout << std::endl;  // Create new line after message for clarity.
83

84
    std::cout << "Written by the OpenWalnut Community, Nemtics, BSV@Uni-Leipzig and CNCF@MPI-CBS." << std::endl;
85 86 87 88 89 90 91
}

/**
 * The main routine starting up the whole application.
 */
int main( int argc, char** argv )
{
92
    WThreadedRunner::setThisThreadName( "QT5 Gui" );
93

94 95 96 97 98
    // where to write the by default?
    std::string logFile = "openwalnut.log";

    // process user parameter
    namespace po = boost::program_options; // since the namespace is far to big we use a shortcut here
99
    po::options_description desc( "Options" );
100 101 102 103 104 105 106 107 108 109 110

    // NOTE: if you modify this, also modify the manual pages! (use help2man or do it manually) But be careful. There need
    // to be several manual changes to be done in the manual after help2man has done its job.
    desc.add_options()
        ( "help,h", "Prints this help message" )
        ( "version,v", "Prints the version information" )
        ( "log,l", po::value< std::string >(), ( std::string( "The log-file to use. If not specified, \"" ) + logFile +
                                                 std::string( "\" is used in the current directory." ) ).c_str() )
        ( "project,p", po::value< std::string >(), "Project file to be loaded on startup." )
        ( "input,i", po::value< std::vector< std::string > >(), "Input data files that should be loaded automatically" );

111 112
    po::positional_options_description pOptDesc;
    pOptDesc.add( "input", -1 );
113 114 115 116

    boost::program_options::variables_map optionsMap;
    try
    {
117
        po::store( po::command_line_parser( argc, argv ).options( desc ).positional( pOptDesc ).run(), optionsMap );
118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152
    }
    catch( const po::error &e )
    {
        std::cerr << e.what() << std::endl;
        return false;
    }

    po::notify( optionsMap );

    // print usage information if command line asks for help.
    if( optionsMap.count( "help" ) )
    {
        // NOTE: if you modify this, check that help2man still works properly! (http://www.gnu.org/software/help2man) But be careful. There need
        // to be several manual changes to be done in the manual after help2man has done its job.
        std::cout << "OpenWalnut is a highly expansible visualization system with focus on brain- and neurological data." << std::endl
                  << std::endl
                  << "Usage: openwalnut [OPTION]... [FILE]..." << std::endl
                  << std::endl
                  << desc << std::endl
                  << std::endl
                  << "Examples:" << std::endl
                  << "  openwalnut\t\t\t\tStartup OpenWalnut." << std::endl
                  << "  openwalnut -p myproject.owp\t\tStart OpenWalnut and load the project." << std::endl
                  << "  openwalnut t1.nii.gz fibers.fib\tStart OpenWalnut and load the two datasets." << std::endl
                  << std::endl;
        return 0;
    }
    else if( optionsMap.count( "version" ) )
    {
        printVersion();
        return 0;
    }

    printVersion();

ebaum's avatar
[ADD]  
ebaum committed
153 154 155
    // install signal handler as early as possible
    WSegmentationFault::installSignalHandler();

156
    // initialize logger here. It will be started by the GUI with one default console stream
157
    WLogger::startup();
158

159
    // add a crash-log.
160 161 162 163 164 165 166 167 168 169 170 171 172
    if( optionsMap.count( "log" ) )
    {
        logFile = optionsMap["log"].as< std::string >();
    }

    // determine log paths
    boost::filesystem::path logPath( logFile );
    logPath = boost::filesystem::system_complete( logPath );
    bool fallbackLog = false; // if true, the original log file could not be opened. A fallback is provided.
    boost::filesystem::path fallbackLogFile = tempFilename( "OpenWalnutLog-%%%%%%%%.log" );

    // is the log writeable?
    std::ofstream crashLogFile( logPath.string().c_str() );
173 174
    if( !crashLogFile.is_open() )
    {
175 176 177
        // try to create fallback
        crashLogFile.open( fallbackLogFile.string().c_str() );
        fallbackLog = true;
178
    }
179 180 181

    // create log stream
    if( crashLogFile.is_open() )
182 183 184 185
    {
        // create the WLogStream. Set special format and DISABLE colors.
        WLogStream::SharedPtr crashLog = WLogStream::SharedPtr( new WLogStream( crashLogFile, LL_DEBUG, "%t %l %s: %m\n", false ) );
        WLogger::getLogger()->addStream( crashLog );
186 187 188 189 190 191 192 193 194 195 196 197 198 199

        // NOTE: the stream flushes after each entry. This is needed if a crash occurs.
        if( !fallbackLog )
        {
            wlog::info( "Walnut" ) << "Using the file \"" << logPath.string() << "\" for logging.";
        }
        else
        {
            wlog::info( "Walnut" ) << "Using the fallback file \"" << fallbackLogFile.string() << "\" for logging.";
        }
    }
    else
    {
        wlog::warn( "Walnut" ) << "Could not open \"" << logPath.string() << "\" for writing. You will have no log-file.";
200
    }
201 202

    // the kernel, and the gui should print their version info. This helps processing crashlogs from users.
203
    wlog::info( "Walnut" ) << "Version: " << W_VERSION;
204

205 206 207 208 209
    // Help Qt find the platform specific libs/dlls
    #ifdef _WIN32
        QCoreApplication::addLibraryPath( "../libExt/qtPlugins" );
        QCoreApplication::addLibraryPath( "libExt/qtPlugins" );
    #endif
Sebastian Eichelbaum's avatar
[STYLE]  
Sebastian Eichelbaum committed
210

211
    // initialize GUI
212
    // NOTE: we need a shared_ptr here since WUI uses enable_shared_from_this.
213
    boost::shared_ptr< WQtGui > gui( new WQtGui( optionsMap, argc, argv ) );
Sebastian Eichelbaum's avatar
[STYLE]  
Sebastian Eichelbaum committed
214

215
    // Start GUI
216
    int result = gui->run();
217

218 219
    std::cout << "Closed OpenWalnut smoothly. Goodbye!" << std::endl;

220
    return result;
221
}
222