/*
* Project: MoleCuilder
* Description: creates and alters molecular systems
* Copyright (C) 2010-2012 University of Bonn. All rights reserved.
*
*
* This file is part of MoleCuilder.
*
* MoleCuilder is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* MoleCuilder is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with MoleCuilder. If not, see .
*/
/*
* QtUIFactory.cpp
*
* Created on: Jan 14, 2010
* Author: crueger
*/
// include config.h
#ifdef HAVE_CONFIG_H
#include
#endif
#include
#include
#include
#include
#include
#include
#include "UIElements/Qt4/QtUIFactory.hpp"
#include "UIElements/Qt4/QtMainWindow.hpp"
#include "UIElements/Qt4/QtDialog.hpp"
// boost::python uses placement new which is incompatible with MemDebug.
#ifdef HAVE_PYTHON
#include "Python/PythonScripting.hpp"
#endif
#include "CodePatterns/MemDebug.hpp"
#include "Helpers/defs.hpp"
using namespace std;
QtUIFactory::QtUIFactory(int _argc, char **_argv) :
argc(1),
argv(new char*[1]),
testlauncher_Interrupted(false),
testlauncher_thread(NULL)
{
// check whether we are in test mode
if ((_argc > 1) && (isTestMode(_argv[1]))) {
#ifdef HAVE_BOOST_THREAD_HPP
std::vector scripts;
scripts.reserve(_argc-1);
for (int i=2;i<_argc;++i)
scripts.push_back(std::string(_argv[i]));
// check for line-by-line execution
const bool SingleLineStepping = (strncmp(&_argv[1][6], "single", 6) == 0);
// prepare an extra thread
std::cout << "TESTLAUNCHER: Preparing " << std::endl;
testlauncher_thread = new boost::thread(
boost::bind(&QtUIFactory::testrun, this, scripts, SingleLineStepping));
#else
std::cerr << "Boost::thread support missing! Cannot launch test scripts.\n";
#endif
// use fake commands to not pass test stuff
const int length = strlen(_argv[0]);
argv[0] = new char[length];
strncpy(_argv[0],_argv[0], length);
app = new QApplication(argc,argv);
} else {
app = new QApplication(_argc,_argv);
}
}
QtUIFactory::~QtUIFactory()
{
if (testlauncher_thread != NULL) {
// notify testlauncher_thread thread that we wish to terminate
testlauncher_thread->interrupt();
// wait till it ends
testlauncher_thread->join();
// and remove
delete testlauncher_thread;
}
// free fake command line argument arrays
delete[] argv[0];
delete[] argv;
}
Dialog* QtUIFactory::makeDialog(const std::string &_title) {
return new QtDialog(_title);
}
MainWindow* QtUIFactory::makeMainWindow() {
return new QtMainWindow(app);
}
QtUIFactory::description::description(int _argc, char **_argv) :
UIFactory::factoryDescription("Qt4"),
argc(_argc),
argv(_argv)
{}
QtUIFactory::description::~description()
{}
UIFactory* QtUIFactory::description::makeFactory(){
return new QtUIFactory(argc, argv);
}
bool QtUIFactory::isTestMode(const char *_argument)
{
return (strncmp(_argument,"--test", 6) == 0);
}
void QtUIFactory::testrun(const std::vector _scripts, const bool _singleLineStepping) const
{
std::cout << "TESTLAUNCHER: Waiting for GUI to set up" << std::endl;
testlauncher_sleep(boost::posix_time::seconds(3));
std::vector::const_iterator scriptiter = _scripts.begin();
do {
// then launch script
std::cout << "TESTLAUNCHER: Launching script " << *scriptiter
<< (_singleLineStepping ? " line by line." : ".") <quit(); // exit flag here is not relevant, end of main() sets the return code
}
void QtUIFactory::testlauncher_sleep(const boost::posix_time::time_duration& _period) const
{
try {
// first sleep for four seconds
#if BOOST_VERSION < 105000
testlauncher_thread->sleep(boost::get_system_time() + _period);
#else
boost::this_thread::sleep_for(boost::chrono::seconds(4));
#endif
} catch(boost::thread_interrupted &e) {
LOG(2, "INFO: testlauncher thread has received stop signal.");
}
}