New runPharos tool :

- an easy way to run pharos 
     - supports several technologies
     - show/hide a console that catch all pharos' outputs
     - supports settings to save technologies / directories
This commit is contained in:
Damien Dupuis 2010-02-19 14:28:07 +00:00
parent d0fe4e359d
commit 4cf533b392
12 changed files with 662 additions and 0 deletions

View File

@ -0,0 +1,21 @@
## VERSION 1.0 --- 19 février 2010
- First releasable version tested on Mac Os and Linux
## VERSION 0.6 --- 19 février 2010
- Adds settings support to configure the application.
## VERSION 0.5 --- 16 février 2010
- Adds compile.sh script to easily compile the application.
The script uses cmake and can be run under Mac / Linux.
## VERSION 0.4
- Adds support for several technologies.
## VERSION 0.3 --- novembre 2010
- Can Show / Hide console.
## VERSION 0.2
- Adds a text console to catch all output from Pharos.
## VERSION 0.1
- First version : can run Pharos.

View File

@ -0,0 +1,22 @@
PROJECT(RUNPHAROS)
CMAKE_MINIMUM_REQUIRED(VERSION 2.4.0)
SET(CMAKE_BUILD_TYPE release)
FIND_PACKAGE(Qt4 REQUIRED)
INCLUDE(${QT_USE_FILE})
SET(CPP_FILES main.cpp MainWindow.cpp MyWidget.cpp ConfigDialog.cpp TechnoRow.cpp)
QT4_WRAP_CPP(MOC_RUNPHAROS MainWindow.h MyWidget.h ConfigDialog.h TechnoRow.h)
IF(APPLE)
ADD_EXECUTABLE(runPharos MACOSX_BUNDLE ${MOC_RUNPHAROS} ${CPP_FILES})
ELSE(APPLE)
ADD_EXECUTABLE(runPharos ${MOC_RUNPHAROS} ${CPP_FILES})
ENDIF(APPLE)
TARGET_LINK_LIBRARIES(runPharos ${QT_LIBRARIES})
INSTALL(TARGETS runPharos DESTINATION /)

View File

@ -0,0 +1,152 @@
#include <iostream>
using namespace std;
#include <QGridLayout>
#include <QDialogButtonBox>
#include <QLabel>
#include <QLineEdit>
#include <QPushButton>
#include <QFileDialog>
#include <QGroupBox>
#include <QVBoxLayout>
#include <QMessageBox>
#include "ConfigDialog.h"
#include "TechnoRow.h"
#define LINEEDITWIDTH 300
int ConfigDialog::_rowID = 0;
ConfigDialog::ConfigDialog() {
setStyleSheet("font-weight: normal;");
// First GroupBox : Directories
// Create widgets
QLabel* programL = new QLabel(tr("Pharos binary") , this);
QLabel* libraryL = new QLabel(tr("LD_LIBRARY_PATH") , this);
_programE = new QLineEdit ("", this);
_libraryE = new QLineEdit ("", this);
_programE->setFixedWidth(LINEEDITWIDTH);
_libraryE->setFixedWidth(LINEEDITWIDTH);
_programE->setToolTip(tr("Select <b>Pharos</b> binary file."));
_libraryE->setToolTip(tr("Select the directory containing c++ dynamic libraries used by <b>Pharos</b>."));
QPushButton* programB = new QPushButton(tr("&Browse"));
QPushButton* libraryB = new QPushButton(tr("&Browse"));
// Connect SIGNAL/SLOTS
connect(programB , SIGNAL(clicked()), this, SLOT(chooseProgram()));
connect(libraryB , SIGNAL(clicked()), this, SLOT(chooseLibrary()));
// Create GroupBox
QGroupBox* directories = new QGroupBox("Directories", this);
QGridLayout* gLayout = new QGridLayout(this);
gLayout->addWidget( programL , 0, 0, 1, 1);
gLayout->addWidget(_programE , 0, 1, 1, 1);
gLayout->addWidget( programB , 0, 2, 1, 1);
gLayout->addWidget( libraryL , 1, 0, 1, 1);
gLayout->addWidget(_libraryE , 1, 1, 1, 1);
gLayout->addWidget( libraryB , 1, 2, 1, 1);
directories->setLayout(gLayout);
// Second GroupBox : Technos
// Create Widgets / Layout
QLabel* name = new QLabel(tr("Name"));
QLabel* file = new QLabel(tr("XML Config File"));
name->setFixedWidth(80);
file->setFixedWidth(LINEEDITWIDTH);
_rowLayout = new QVBoxLayout();
_rowLayout->setContentsMargins(0,0,0,0);
_rowLayout->setSpacing(0);
addRow();
// Create GroupBox
QGroupBox* technos = new QGroupBox("Technologies", this);
QHBoxLayout* headerLayout = new QHBoxLayout();
headerLayout->addSpacing(20);
headerLayout->addWidget(name);
headerLayout->addWidget(file);
QVBoxLayout* techLayout = new QVBoxLayout();
techLayout->addLayout(headerLayout);
techLayout->addLayout(_rowLayout);
technos->setLayout(techLayout);
QDialogButtonBox* dbBox = new QDialogButtonBox(QDialogButtonBox::Ok);
_add = new QPushButton("&Add technology", this);
dbBox->addButton(_add, QDialogButtonBox::ActionRole);
connect(_add , SIGNAL(clicked()) , this, SLOT(addRow()));
connect(dbBox, SIGNAL(accepted()), this, SLOT(doConfig()));
QVBoxLayout* tLayout = new QVBoxLayout();
tLayout->setContentsMargins(0,0,0,0);
tLayout->addWidget(directories);
tLayout->addWidget(technos);
tLayout->addWidget(dbBox);
setLayout(tLayout);
setWindowTitle(tr("Configure runPharos"));
layout()->setSizeConstraint(QLayout::SetFixedSize);
}
void ConfigDialog::addRow() {
TechnoRow* row = new TechnoRow(_rowID++, this);
connect(row, SIGNAL(suppressed(int)), this, SLOT(removeRow(int)));
row->setContentsMargins(0,0,0,0);
_rows.push_back(row);
_rowLayout->addWidget(row);
}
void ConfigDialog::addRow(QString& name, QString& file) {
TechnoRow* row = new TechnoRow(_rowID++, this);
row->setName(name);
row->setFile(file);
connect(row, SIGNAL(suppressed(int)), this, SLOT(removeRow(int)));
row->setContentsMargins(0,0,0,0);
_rows.push_back(row);
_rowLayout->addWidget(row);
}
void ConfigDialog::removeRow(int id) {
TechnoRow* row = _rows[id];
_rowLayout->removeWidget(row);
row->hide();
}
void ConfigDialog::doConfig() {
QStringList list;
if ( _programE->text().isEmpty() || _libraryE->text().isEmpty() ) {
QMessageBox::warning(this, tr("runPharos warning"), tr("You must set all directories."));
return;
}
list << _programE->text() << _libraryE->text();
vector<pair<QString, QString> > technos;
for ( size_t i = 0 ; i < _rows.size() ; i++ ) {
TechnoRow* row = _rows[i];
if (row->isVisible()) {
if((row->getName() != "") && (row->getFile() != "")) {
technos.push_back(pair<QString, QString>(row->getName(), row->getFile()));
} else {
QMessageBox::warning(this, tr("runPharos warning"), tr("You must set a valid name and file for each technology."));
return;
}
}
}
if (technos.size() > 0) {
emit(configDone(list, technos));
accept();
} else {
QMessageBox::warning(this, tr("runPharos warning"), tr("You must set at least one valid technology."));
}
}
void ConfigDialog::chooseProgram() {
_programE->setText(QFileDialog::getOpenFileName(this, tr("Select Pharos binary file"), "", tr("Executable file (*)")));
}
void ConfigDialog::chooseLibrary() {
_libraryE->setText(QFileDialog::getExistingDirectory(this, tr("Select directory containing c++ dynamic libraries")));
}
void ConfigDialog::setProgram(QString program) {
_programE->setText(program);
}
void ConfigDialog::setLibrary(QString library) {
_libraryE->setText(library);
}

View File

@ -0,0 +1,43 @@
#ifndef CONFIGDIALOG_H
#define CONFIGDIALOG_H
#include <vector>
#include <QDialog>
class QVBoxLayout;
class QPushButton;
class QLineEdit;
class QStringList;
class TechnoRow;
class ConfigDialog : public QDialog {
Q_OBJECT
public:
ConfigDialog();
void setProgram(QString);
void setLibrary(QString);
signals:
void configDone(QStringList&, std::vector<std::pair<QString, QString> >&);
public slots:
void addRow();
void addRow(QString&, QString&);
void removeRow(int);
void doConfig();
void chooseProgram();
void chooseLibrary();
private:
QLineEdit* _programE;
QLineEdit* _libraryE;
static int _rowID;
QPushButton* _add;
QVBoxLayout* _rowLayout;
std::vector<TechnoRow*> _rows;
};
#endif

View File

@ -0,0 +1,23 @@
#include<QMenu>
#include<QMenuBar>
#include<QAction>
#include "MainWindow.h"
#include "MyWidget.h"
MainWindow::MainWindow()
{
MyWidget* mWidget = new MyWidget(this);
setCentralWidget(mWidget);
QAction* configAct = new QAction(tr("&Configure"), this);
configAct->setStatusTip(tr("Configure the application"));
connect(configAct, SIGNAL(triggered()), mWidget, SLOT(reconfig()));
QAction* aboutAct = new QAction(tr("&About"), this);
aboutAct->setStatusTip(tr("Show the about dialog box"));
connect(aboutAct, SIGNAL(triggered()), mWidget, SLOT(about()));
QMenu* editMenu = menuBar()->addMenu(tr("&Edit"));
editMenu->addAction(configAct);
QMenu* helpMenu = menuBar()->addMenu(tr("&Help"));
helpMenu->addAction(aboutAct);
}

View File

@ -0,0 +1,13 @@
#ifndef __MAINWINDOW_H
#define __MAINWINDOW_H
#include <QMainWindow>
class MainWindow : public QMainWindow {
Q_OBJECT
public:
MainWindow ();
~MainWindow () {};
};
#endif

View File

@ -0,0 +1,204 @@
#include <iostream>
using namespace std;
#include <QWidget>
#include <QPushButton>
#include <QDialogButtonBox>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QTextEdit>
#include <QByteArray>
#include <QComboBox>
#include <QMessageBox>
#include <QSettings>
#include <QStringList>
#include "MyWidget.h"
#include "ConfigDialog.h"
MyWidget::MyWidget(QWidget *parent) : QWidget(parent) {
setStyleSheet("font-weight: normal;");
_technoCB = new QComboBox(this);
_technoCB->setFixedWidth(120);
readSettings();
updateComboBox();
_console = new QTextEdit(this);
_console->setFixedSize(600,350);
_console->setFontPointSize(10);
_execute = new QPushButton ( "&Execute", this );
_execute->setDefault(true);
_stop = new QPushButton ( "&Stop", this );
_stop->setEnabled(false);
_show = new QPushButton ( "&Show console", this );
_clear = new QPushButton ( "&Clear", this );
QDialogButtonBox* buttons = new QDialogButtonBox();
buttons->addButton ( _execute, QDialogButtonBox::RejectRole );
buttons->addButton ( _stop , QDialogButtonBox::AcceptRole );
buttons->addButton ( _show , QDialogButtonBox::ResetRole );
buttons->addButton ( _clear , QDialogButtonBox::ResetRole );
connect ( _execute, SIGNAL(clicked()), this , SLOT(execute()) );
connect ( _stop , SIGNAL(clicked()), this , SLOT(stop()) );
connect ( _show , SIGNAL(clicked()), this , SLOT(showOrHide()) );
connect ( _clear , SIGNAL(clicked()), _console, SLOT(clear()) );
QHBoxLayout* hLayout = new QHBoxLayout();
hLayout->addWidget(buttons, Qt::AlignRight);
QVBoxLayout* layout = new QVBoxLayout();
layout->addWidget(_technoCB);
layout->addWidget(_console);
layout->addLayout(hLayout);
setLayout(layout);
_clear->hide();
_console->hide();
setWindowTitle("Run Pharos");
setFixedSize(400,110);
}
void MyWidget::readSettings() {
_settings = new QSettings("chams", "runPharos");
if ( !_settings->contains("Program") ) {
QMessageBox::warning(this, tr("runPharos"), tr("It seems you do not have configured the application. Let's configure it now."), QMessageBox::Ok, QMessageBox::Ok);
runConfigDialog(true);
} else {
_program = _settings->value("Program").toString();
_library = _settings->value("Library").toString();
_nbTechno = _settings->value("NbTechno").toInt();
_technos.clear();
for ( int i = 0 ; i < _nbTechno ; i++ ) {
QString name = QString("name_%1").arg(i);
QString file = QString("file_%1").arg(i);
_technos.push_back(pair<QString, QString>(_settings->value(name).toString(), _settings->value(file).toString()));
}
}
}
void MyWidget::runConfigDialog(bool first) {
ConfigDialog* cfg = new ConfigDialog;
connect(cfg, SIGNAL(configDone(QStringList&, std::vector<std::pair<QString, QString> >&)), this, SLOT(updateConfig(QStringList&, std::vector<std::pair<QString, QString> >&)));
if(!first) {
cfg->setProgram(_program);
cfg->setLibrary(_library);
// on enleve la row par defaut vide
cfg->removeRow(0);
// on rajoute toutes les technos lues dans les settings:
for ( size_t i = 0 ; i < _technos.size() ; i++ ) {
cfg->addRow(_technos[i].first, _technos[i].second);
}
}
cfg->exec();
writeSettings();
}
void MyWidget::reconfig() {
runConfigDialog(false);
}
void MyWidget::writeSettings() {
_settings->setValue("Program" , _program);
_settings->setValue("Library" , _library);
_settings->setValue("NbTechno" , _nbTechno);
for ( size_t i = 0 ; i < _technos.size() ; i++ ) {
QString name = QString("name_%1").arg(i);
QString file = QString("file_%1").arg(i);
_settings->setValue(name, _technos[i].first);
_settings->setValue(file, _technos[i].second);
}
}
void MyWidget::updateConfig(QStringList& list, vector<pair<QString, QString> >& technos) {
_program = list.value(0);
_library = list.value(1);
_technos.clear();
for ( size_t i = 0 ; i < technos.size() ; i++ ) {
_technos.push_back(pair<QString, QString>(technos[i].first, technos[i].second));
}
_nbTechno = _technos.size();
updateComboBox();
}
void MyWidget::updateComboBox() {
if (_technoCB->count() != 0)
_technoCB->clear();
QStringList choices;
for ( size_t i = 0 ; i < _technos.size() ; i++ ) {
choices << _technos[i].first;
}
_technoCB->addItems(choices);
}
void MyWidget::about() {
QMessageBox::about(this, tr("About runPharos"), tr("<p><h1 align=\"center\">runPharos</h1></p>"
"<p>This tool allows every one to easily run pharos on a specified technology.</p>"
"<p align=\"center\">Version 1.0<br>19/02/2010<br>by <b>D.Dupuis</b></p>"));
}
void MyWidget::execute() {
QStringList arguments;
QString techno ("");
QString name = _technoCB->currentText();
for ( size_t i = 0 ; i < _technos.size() ; i++ ) {
if ( _technos[i].first == name )
techno = _technos[i].second;
}
if ( techno == "" )
return;
arguments << techno;
_myProcess = new QProcess(this);
QStringList env = QProcess::systemEnvironment();
QString DYLD = QString("DYLD_LIBRARY_PATH=%1").arg(_library);
QString LD = QString("LD_LIBRARY_PATH=%1").arg(_library);
QString PP = QString("PYTHONPATH=%1/python").arg(_library);
env << DYLD << LD << PP;
_myProcess->setEnvironment(env);
connect(_myProcess, SIGNAL(readyReadStandardError()) , this, SLOT(updateError()));
connect(_myProcess, SIGNAL(readyReadStandardOutput()), this, SLOT(updateText()));
connect(_myProcess, SIGNAL(finished(int,QProcess::ExitStatus)), this, SLOT(finished(int, QProcess::ExitStatus)) );
_myProcess->start(_program, arguments);
_execute->setEnabled(false);
_stop->setEnabled(true);
}
void MyWidget::stop() {
_myProcess->terminate();
_execute->setEnabled(true);
_stop->setEnabled(false);
}
void MyWidget::showOrHide() {
if ( _console->isHidden() ) {
_show->setText("&Hide console");
_console->show();
_clear->show();
setFixedSize(620,450);
}
else {
_show->setText("&Show console");
_console->hide();
_clear->hide();
setFixedSize(400,110);
}
}
void MyWidget::updateError() {
QByteArray data = _myProcess->readAllStandardError();
_console->insertPlainText(QString(data));
}
void MyWidget::updateText() {
QByteArray data = _myProcess->readAllStandardOutput();
_console->insertPlainText(QString(data));
}
void MyWidget::finished(int exitCode, QProcess::ExitStatus exitStatus) {
_execute->setEnabled(true);
_stop->setEnabled(false);
}

View File

@ -0,0 +1,56 @@
#ifndef __MY_WIDGET_H
#define __MY_WIDGET_H
#include <vector>
#include <QWidget>
#include <QProcess>
#include <QString>
class QComboBox;
class QPushButton;
class QTextEdit;
class QSettings;
class QStringList;
class MyWidget : public QWidget {
Q_OBJECT
public:
MyWidget (QWidget *parent =0);
~MyWidget () {};
QComboBox* _technoCB;
QPushButton* _execute;
QPushButton* _stop;
QPushButton* _show;
QPushButton* _clear;
QTextEdit* _console;
QProcess* _myProcess;
QSettings* _settings;
QString _program;
QString _library;
int _nbTechno;
std::vector<std::pair<QString, QString> > _technos;
private:
void readSettings();
void writeSettings();
void runConfigDialog(bool);
void updateComboBox();
public slots:
void about();
void reconfig();
void execute();
void stop();
void finished(int exitCode, QProcess::ExitStatus exitStatus);
void showOrHide();
void updateError();
void updateText();
void updateConfig(QStringList&, std::vector<std::pair<QString, QString> >&);
};
#endif

View File

@ -0,0 +1,68 @@
#include <iostream>
using namespace std;
#include <QWidget>
#include <QPushButton>
#include <QFileDialog>
#include <QDialogButtonBox>
#include <QHBoxLayout>
#include <QLineEdit>
#include "TechnoRow.h"
TechnoRow::TechnoRow(int id, QWidget *parent) : QWidget(parent), _id(id) {
_suppress = new QPushButton( tr("-"), this);
_suppress->setStyleSheet("font: bold 24pt; color: red; border: 0px");
_suppress->setFixedWidth(_suppress->height());
_name = new QLineEdit(this);
_name->setFixedWidth(80);
_file = new QLineEdit(this);
_file->setFixedWidth(300);
_browse = new QPushButton( tr("&browse"), this);
connect(_suppress, SIGNAL(clicked()), this, SLOT(suppress()));
connect(_browse , SIGNAL(clicked()), this, SLOT(chooseFile()));
//QDialogButtonBox* buttons = new QDialogButtonBox();
//buttons->addButton ( _execute, QDialogButtonBox::RejectRole );
//buttons->addButton ( _stop , QDialogButtonBox::AcceptRole );
//buttons->addButton ( _show , QDialogButtonBox::ResetRole );
//buttons->addButton ( _clear , QDialogButtonBox::ResetRole );
//connect ( _execute, SIGNAL(clicked()), this , SLOT(execute()) );
//connect ( _stop , SIGNAL(clicked()), this , SLOT(stop()) );
//connect ( _show , SIGNAL(clicked()), this , SLOT(showOrHide()) );
//connect ( _clear , SIGNAL(clicked()), _console, SLOT(clear()) );
QHBoxLayout* hLayout = new QHBoxLayout();
hLayout->setContentsMargins(0,0,0,0);
hLayout->addWidget(_suppress);
hLayout->addWidget(_name);
hLayout->addWidget(_file);
hLayout->addWidget(_browse);
setLayout(hLayout);
}
QString TechnoRow::getName() {
return _name->text();
}
QString TechnoRow::getFile() {
return _file->text();
}
void TechnoRow::setName(QString& name) {
_name->setText(name);
}
void TechnoRow::setFile(QString& file) {
_file->setText(file);
}
void TechnoRow::suppress() {
emit(suppressed(_id));
}
void TechnoRow::chooseFile() {
_file->setText(QFileDialog::getOpenFileName(this, tr("Select dtr file"), "", tr("Xml file (*.xml)")));
}

View File

@ -0,0 +1,35 @@
#ifndef __TECHNOROW_H
#define __TECHNOROW_H
#include <QWidget>
class QPushButton;
class QLineEdit;
class TechnoRow : public QWidget {
Q_OBJECT
public:
TechnoRow (int id, QWidget *parent =0);
~TechnoRow () {};
QString getName();
QString getFile();
void setName(QString&);
void setFile(QString&);
int _id;
QLineEdit* _name;
QLineEdit* _file;
QPushButton* _suppress;
QPushButton* _browse;
signals:
void suppressed(int);
public slots:
void suppress();
void chooseFile();
};
#endif

14
bootstrap/runPharos/compile.sh Executable file
View File

@ -0,0 +1,14 @@
#!/bin/bash
if [ ! -e "./compile.sh" ]; then
echo "You must run compile.sh in its own directory : ./compile.sh"
exit 1
fi
if [ ! -d "build" ]; then
echo "Creating build directory"
mkdir build
fi
cd build && cmake .. && make DESTDIR=.. -j2 install

View File

@ -0,0 +1,11 @@
#include <QApplication>
#include "MainWindow.h"
int main ( int argc, char **argv ) {
QApplication app ( argc, argv );
MainWindow mWindow;
mWindow.show();
return app.exec();
}