/* * 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."); } }