From 28cf114c3fe007f892a09c3b85f6b48b9d9d6dda Mon Sep 17 00:00:00 2001 From: Mike Kremer Date: Mon, 22 Feb 2010 13:15:30 +0000 Subject: [PATCH] Added process manager widget that allows the user to view/control running thread attributes. Still work in progress... git-svn-id: http://www.openflipper.org/svnrepo/OpenFlipper/branches/Free@8588 383ad7c9-94d9-4d36-a494-682f7c89f535 --- BasePlugin/ProcessInterface.hh | 16 ++ Core/Core.cc | 1 + Core/Core.hh | 13 +- Core/PluginLoader.cc | 14 +- Core/process.cc | 90 ++++---- CoreApp/CMakeLists.txt | 1 + threads/JobInfo.cc | 11 +- threads/JobInfo.hh | 13 +- threads/OpenFlipperThread.hh | 3 - .../processManagerWidget.cc | 209 ++++++++++++++++++ .../processManagerWidget.hh | 131 +++++++++++ 11 files changed, 447 insertions(+), 55 deletions(-) create mode 100644 widgets/processManagerWidget/processManagerWidget.cc create mode 100644 widgets/processManagerWidget/processManagerWidget.hh diff --git a/BasePlugin/ProcessInterface.hh b/BasePlugin/ProcessInterface.hh index c91a65fc..9393163b 100644 --- a/BasePlugin/ProcessInterface.hh +++ b/BasePlugin/ProcessInterface.hh @@ -104,6 +104,22 @@ class ProcessInterface { */ virtual void setJobState(QString /*_jobId*/, int /*_value*/ ) {}; + /** \brief update job's name + * + * Emit this signal to tell the core to change a job's name. + * + * _caption The new name of the job + */ + virtual void setJobName(QString /*_jobId*/, QString /*_name*/ ) {}; + + /** \brief update job's description text + * + * Emit this signal to tell the core to change a job's widget's description. + * + * _text The text of the job's description + */ + virtual void setJobDescription(QString /*_jobId*/, QString /*_text*/ ) {}; + /** \brief Cancel your job */ virtual void cancelJob(QString /*_jobId*/ ) {}; diff --git a/Core/Core.cc b/Core/Core.cc index 78c7b51f..9cb6aea3 100644 --- a/Core/Core.cc +++ b/Core/Core.cc @@ -120,6 +120,7 @@ Core:: Core() : QObject(), capture_(false), + processManager_(0), nextBackupId_(0), objectRoot_(0), coreWidget_(0) diff --git a/Core/Core.hh b/Core/Core.hh index 7e95ce94..c46dd824 100644 --- a/Core/Core.hh +++ b/Core/Core.hh @@ -99,6 +99,9 @@ #include +// Process manager widget +#include + #include #include @@ -968,6 +971,8 @@ private slots: QList< JobInfo* > currentJobs; + ProcessManagerWidget* processManager_; + /// Find a job in the jobslist bool getJob(QString _jobId, int& _index); @@ -979,6 +984,12 @@ private slots: /// A job state has been updated by a plugin void slotSetJobState(QString _jobId, int _value ); + /// A job's widget caption has been updated by a plugin + void slotSetJobName(QString _jobId, QString _name ); + + /// A job's widget's status text has been updated by a plugin + void slotSetJobDescription(QString _jobId, QString _text ); + /// A job state has been canceled by a plugin void slotCancelJob(QString _jobId ); @@ -986,7 +997,7 @@ private slots: void slotFinishJob(QString _jobId ); /// Called by dialogs if cancel button is pressed - void slotJobCancelButtons(); + void slotJobCancelRequested(QString _jobId); signals: diff --git a/Core/PluginLoader.cc b/Core/PluginLoader.cc index 0bd078c0..4dfad4cd 100644 --- a/Core/PluginLoader.cc +++ b/Core/PluginLoader.cc @@ -990,7 +990,19 @@ void Core::loadPlugin(QString filename, bool silent){ connect(plugin , SIGNAL(setJobState(QString,int)), this , SLOT( slotSetJobState(QString,int) ) ,Qt::DirectConnection ); else - emit log(LOGERR,"Process Interface defined but no setJobState signal found!"); + emit log(LOGERR,"Process Interface defined but no setJobState signal found!"); + + if ( checkSignal(plugin,"setJobName(QString,QString)" ) ) + connect(plugin , SIGNAL(setJobName(QString, QString)), + this , SLOT( slotSetJobName(QString, QString) ) ,Qt::DirectConnection ); + else + emit log(LOGERR,"Process Interface defined but no setJobName signal found!"); + + if ( checkSignal(plugin,"setJobDescription(QString,QString)" ) ) + connect(plugin , SIGNAL(setJobDescription(QString, QString)), + this , SLOT( slotSetJobDescription(QString, QString) ) ,Qt::DirectConnection ); + else + emit log(LOGERR,"Process Interface defined but no setJobDescription signal found!"); if ( checkSignal(plugin,"cancelJob(QString)" ) ) connect(plugin , SIGNAL(cancelJob(QString)), diff --git a/Core/process.cc b/Core/process.cc index 2821cb29..5e51969a 100644 --- a/Core/process.cc +++ b/Core/process.cc @@ -61,34 +61,36 @@ void Core::slotStartJob( QString _jobId, QString _description , int _min , int _max, bool _blocking) { std::cerr << "StartJob: " << _jobId.toStdString() << " " << _description.toStdString() << " " << _min << " " << _max << " " << _blocking <addJob(_jobId, _description, _min, _max); + + // Show window + processManager_->show(); + JobInfo* info = new JobInfo(); - info->jobId = _jobId; + info->id = _jobId; info->description = _description; - info->min = _min; - info->max = _max; + info->currentStep = 0; + info->minSteps = _min; + info->maxSteps = _max; info->blocking = _blocking; - info->progressDialog = new QProgressDialog(coreWidget_); - info->progressDialog->setLabelText(_description); - info->progressDialog->setMinimum(_min); - info->progressDialog->setMaximum(_max); - info->progressDialog->setValue(_min); - info->progressDialog->resize(300,130); - info->progressDialog->setMinimumDuration(1); - if ( _blocking ) - info->progressDialog->setWindowModality(Qt::WindowModal); - - connect( info->progressDialog, SIGNAL(canceled()), - this,SLOT(slotJobCancelButtons())); currentJobs.push_back(info); - } //----------------------------------------------------------------------------- bool Core::getJob(QString _jobId, int& _index) { for ( int i = 0 ; i < currentJobs.size() ; ++i) { - if ( currentJobs[i]->jobId == _jobId ) { + if ( currentJobs[i]->id == _jobId ) { _index = i; return true; } @@ -106,21 +108,42 @@ void Core::slotSetJobState(QString _jobId, int _value ) { int id; if ( getJob(_jobId, id) ) { - currentJobs[id]->currentState = _value; - currentJobs[id]->progressDialog->setValue(_value); + currentJobs[id]->currentStep = _value; + processManager_->updateStatus(_jobId, _value); } } //----------------------------------------------------------------------------- +// A job's caption has been updated by a plugin +void Core::slotSetJobName(QString _jobId, QString _name ) { + int id; + + if ( getJob(_jobId, id) ) { + currentJobs[id]->id = _name; + processManager_->setJobName(_jobId, _name); + } +} +//----------------------------------------------------------------------------- + +// A job's widget's status text has been updated by a plugin +void Core::slotSetJobDescription(QString _jobId, QString _text ) { + int id; + + if ( getJob(_jobId, id) ) { + currentJobs[id]->description = _text; + processManager_->setJobDescription(_jobId, _text); + } +} + +//----------------------------------------------------------------------------- + // A job state has been canceled by a plugin void Core::slotCancelJob(QString _jobId ) { int id; if ( getJob(_jobId, id) ) { - currentJobs[id]->progressDialog->reset(); - currentJobs[id]->progressDialog->hide(); - delete currentJobs[id]->progressDialog; + processManager_->removeJob(_jobId); currentJobs.removeAt(id); } } @@ -132,25 +155,18 @@ void Core::slotFinishJob(QString _jobId ) { int id; if ( getJob(_jobId, id) ) { - currentJobs[id]->progressDialog->reset(); - currentJobs[id]->progressDialog->hide(); - delete currentJobs[id]->progressDialog; + processManager_->removeJob(_jobId); currentJobs.removeAt(id); } } -// The user canceled a job -void Core::slotJobCancelButtons( ) { - for ( int i = 0 ; i < currentJobs.size() ; ++i) { - if ( currentJobs[i]->progressDialog == sender() ) { - QString id = currentJobs[i]->jobId; - slotCancelJob(id); - emit jobCanceled( id ); - } - } -} - - +//----------------------------------------------------------------------------- +// A job has shall be canceled since the user pushed +// the cancel button +void Core::slotJobCancelRequested(QString /*_jobId*/) { + + // Cancel job still to be implemented... +} //============================================================================= diff --git a/CoreApp/CMakeLists.txt b/CoreApp/CMakeLists.txt index f11145c0..81e3fae9 100644 --- a/CoreApp/CMakeLists.txt +++ b/CoreApp/CMakeLists.txt @@ -52,6 +52,7 @@ set (directories ../widgets/loggerWidget ../widgets/coreWidget ../widgets/helpWidget + ../widgets/processManagerWidget ../widgets/loadWidget ../widgets/optionsWidget ../widgets/PluginDialog diff --git a/threads/JobInfo.cc b/threads/JobInfo.cc index e68b21fe..40a55bc0 100644 --- a/threads/JobInfo.cc +++ b/threads/JobInfo.cc @@ -35,12 +35,11 @@ JobInfo::JobInfo() : - jobId(""), + id(""), description(""), - currentState(0), - min(0), - max(100), - blocking(false), - progressDialog(0) + currentStep(0), + minSteps(0), + maxSteps(100), + blocking(false) { } diff --git a/threads/JobInfo.hh b/threads/JobInfo.hh index 7c49e453..a5bfe4e6 100644 --- a/threads/JobInfo.hh +++ b/threads/JobInfo.hh @@ -35,10 +35,10 @@ #ifndef OPENFLIPPERJOBINFO_HH #define OPENFLIPPERJOBINFO_HH -#include - #include +#include + /** \brief Job Information class * * This class stores information about currently running tasks in OpenFlipper @@ -48,13 +48,12 @@ class DLLEXPORT JobInfo { JobInfo(); public: - QString jobId; + QString id; QString description; - int currentState; - int min; - int max; + int currentStep; + int minSteps; + int maxSteps; bool blocking; - QProgressDialog* progressDialog; }; diff --git a/threads/OpenFlipperThread.hh b/threads/OpenFlipperThread.hh index ddd164e7..7eabba3b 100644 --- a/threads/OpenFlipperThread.hh +++ b/threads/OpenFlipperThread.hh @@ -37,12 +37,9 @@ #include #include -#include #include - - class OpenFlipperJob; class DLLEXPORT OpenFlipperThread : public QThread diff --git a/widgets/processManagerWidget/processManagerWidget.cc b/widgets/processManagerWidget/processManagerWidget.cc new file mode 100644 index 00000000..b4c657d7 --- /dev/null +++ b/widgets/processManagerWidget/processManagerWidget.cc @@ -0,0 +1,209 @@ +/*===========================================================================*\ + * * + * OpenFlipper * + * Copyright (C) 2001-2009 by Computer Graphics Group, RWTH Aachen * + * www.openflipper.org * + * * + *---------------------------------------------------------------------------* + * This file is part of OpenFlipper. * + * * + * OpenFlipper is free software: you can redistribute it and/or modify * + * 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 with the * + * following exceptions: * + * * + * If other files instantiate templates or use macros * + * or inline functions from this file, or you compile this file and * + * link it with other files to produce an executable, this file does * + * not by itself cause the resulting executable to be covered by the * + * GNU Lesser General Public License. This exception does not however * + * invalidate any other reasons why the executable file might be * + * covered by the GNU Lesser General Public License. * + * * + * OpenFlipper 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 Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU LesserGeneral Public * + * License along with OpenFlipper. If not, * + * see . * + * * +\*===========================================================================*/ + +/*===========================================================================*\ + * * + * $Revision: 83 $ * + * $Author: kremer $ * + * $Date: 2009-02-27 17:31:45 +0100 (Fr, 27. Feb 2009) $ * + * * +\*===========================================================================*/ + + +/* + * processManagerWidget.cc + * + * Created on: Apr 7, 2009 + * Author: kremer + */ + +#include "processManagerWidget.hh" + +#include + +void ProcessManagerWidget::updateStatus(QString _id, int _status) { + + JobContainer job; + std::map::iterator it = processMap_.begin(); + + // Find item + bool found = false; + for(; it != processMap_.end(); ++it) { + if((*it).first == _id) { + found = true; + job = (*it).second; + break; + } + } + + // No such item has been found -> returning + if(!found) return; + + // Set new status + (job.progress)->setValue(_status); +} + +void ProcessManagerWidget::setJobName(QString _id, QString _name) { + + JobContainer job; + std::map::iterator it = processMap_.begin(); + + // Find item + bool found = false; + for(; it != processMap_.end(); ++it) { + if((*it).first == _id) { + found = true; + job = (*it).second; + break; + } + } + + // No such item found -> return + if(!found) return; + + (job.id)->setText(_name); +} + +void ProcessManagerWidget::setJobDescription(QString _id, QString _desc) { + + JobContainer job; + std::map::iterator it = processMap_.begin(); + + // Find item + bool found = false; + for(; it != processMap_.end(); ++it) { + if((*it).first == _id) { + found = true; + job = (*it).second; + break; + } + } + + // No such item has been found -> returning + if(!found) return; + + // Set new description + (job.description)->setText(_desc); +} + +void ProcessManagerWidget::addJob(QString _id, QString _description, + int _minSteps, int _maxSteps) { + + std::map::iterator it = processMap_.begin(); + + // Find item + bool found = false; + for(; it != processMap_.end(); ++it) { + if((*it).first == _id) { + found = true; + break; + } + } + + // Item with the same id has already been added + if(found) return; + + QTableWidgetItem* name = new QTableWidgetItem(_id); + QTableWidgetItem* desc = new QTableWidgetItem(_description); + JobCancelButton* button = new JobCancelButton("Cancel", _id); + QProgressBar* progressBar = new QProgressBar(); + progressBar->setMaximum(_maxSteps); + progressBar->setMinimum(_minSteps); + progressBar->setValue(0); + + // Connect cancel button to event handler + connect(button, SIGNAL(pressed()), this, SLOT(cancelButtonPressed())); + + int newRow = this->processList->rowCount(); + + this->processList->insertRow(newRow); + + this->processList->setItem(newRow, 0, name); + this->processList->setItem(newRow, 1, desc); + this->processList->setCellWidget(newRow, 2, progressBar); + this->processList->setCellWidget(newRow, 3, button); + + // Insert job into local map + JobContainer job; + job.row = newRow; + job.id = name; + job.description = desc; + job.progress = progressBar; + job.button = button; + + processMap_.insert(std::pair(_id, job)); +} + +void ProcessManagerWidget::cancelButtonPressed() { + + // Get pushed button + JobCancelButton* button = 0; + button = dynamic_cast(QObject::sender()); + + // Some error has occurred + if(button == 0) return; + + // Emit signal to cancel job + emit cancelJobRequested(button->jobId()); +} + +void ProcessManagerWidget::removeJob(QString _id) { + + JobContainer job; + std::map::iterator it = processMap_.begin(); + + // Find item + bool found = false; + for(; it != processMap_.end(); ++it) { + if((*it).first == _id) { + found = true; + job = (*it).second; + break; + } + } + + // No such item has been found -> returning + if(!found) return; + + this->processList->removeRow(job.row); + + // Delete widget items + delete job.id; + delete job.description; + delete job.progress; + delete job.button; + + // Remove from local map + processMap_.erase(_id); +} \ No newline at end of file diff --git a/widgets/processManagerWidget/processManagerWidget.hh b/widgets/processManagerWidget/processManagerWidget.hh new file mode 100644 index 00000000..538ca782 --- /dev/null +++ b/widgets/processManagerWidget/processManagerWidget.hh @@ -0,0 +1,131 @@ +/*===========================================================================*\ + * * + * OpenFlipper * + * Copyright (C) 2001-2009 by Computer Graphics Group, RWTH Aachen * + * www.openflipper.org * + * * + *---------------------------------------------------------------------------* + * This file is part of OpenFlipper. * + * * + * OpenFlipper is free software: you can redistribute it and/or modify * + * 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 with the * + * following exceptions: * + * * + * If other files instantiate templates or use macros * + * or inline functions from this file, or you compile this file and * + * link it with other files to produce an executable, this file does * + * not by itself cause the resulting executable to be covered by the * + * GNU Lesser General Public License. This exception does not however * + * invalidate any other reasons why the executable file might be * + * covered by the GNU Lesser General Public License. * + * * + * OpenFlipper 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 Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU LesserGeneral Public * + * License along with OpenFlipper. If not, * + * see . * + * * +\*===========================================================================*/ + +/*===========================================================================*\ + * * + * $Revision: 83 $ * + * $Author: kremer $ * + * $Date: 2009-02-27 17:31:45 +0100 (Fr, 27. Feb 2009) $ * + * * +\*===========================================================================*/ + + +/* + * processManagerWidget.hh + * + * Created on: Apr 7, 2009 + * Author: kremer + */ + +#ifndef PROCESSMANAGERWIDGET_HH_ +#define PROCESSMANAGERWIDGET_HH_ + +#include +#include + +#include "ui_processManagerWidget.hh" + +// A button class that additionally stores +// an attached job's id. +class JobCancelButton : public QPushButton { + Q_OBJECT + +public: + JobCancelButton(QString _caption, QString _jobId, QWidget* _parent = 0) : + QPushButton(_caption, _parent), + jobId_(_jobId) {}; + + // Set job's id + void setJobId(const QString& _jobId) { jobId_ = _jobId; }; + + // Set job's id + QString jobId() { return jobId_; } + +private: + QString jobId_; +}; + +class ProcessManagerWidget : public QWidget, public Ui::ProcessManagerWidget +{ + Q_OBJECT + + signals: + + void cancelJobRequested(QString _jobId); + + public: + + ProcessManagerWidget(QWidget* parent = 0) : QWidget(parent) { + + setupUi(this); + + /*itemModel_ = new ProcessItemModel(); + + // set model + this->processList->setModel(itemModel_);*/ + }; + + virtual ~ProcessManagerWidget() {}; + + void updateStatus(QString _id, int _status); + + void setJobName(QString _id, QString _desc); + + void setJobDescription(QString _id, QString _desc); + + void addJob(QString _id, QString _description = "", + int _minSteps = 0, int _maxSteps = 100); + + void removeJob(QString _jobName); + + private slots: + + void cancelButtonPressed(); + + private: + + // A container to hold the widget items + struct JobContainer { + int row; + QTableWidgetItem* id; + QTableWidgetItem* description; + QProgressBar* progress; + JobCancelButton* button; + }; + + std::map processMap_; +}; + + +#endif /* PROCESSMANAGERWIDGET_HH_ */ -- GitLab