RsCheckerManager: port to IBackgroundChecker

Remove old RsErrorsWidget, replaced by BackgroundResultWidget
This commit is contained in:
Filippo Gentile 2022-11-02 10:23:49 +01:00
parent 232f4e1dcc
commit 5f165502f8
5 changed files with 75 additions and 335 deletions

View File

@ -1,14 +1,16 @@
set(MR_TIMETABLE_PLANNER_SOURCES
${MR_TIMETABLE_PLANNER_SOURCES}
rollingstock/rs_checker/error_data.h
rollingstock/rs_checker/rscheckermanager.h
rollingstock/rs_checker/rserrorswidget.h
rollingstock/rs_checker/rserrortreemodel.h
rollingstock/rs_checker/rsworker.h
rollingstock/rs_checker/rs_error_data.h
rollingstock/rs_checker/rscheckermanager.h
rollingstock/rs_checker/rscheckermanager.cpp
rollingstock/rs_checker/rserrorswidget.cpp
rollingstock/rs_checker/rserrortreemodel.h
rollingstock/rs_checker/rserrortreemodel.cpp
rollingstock/rs_checker/rsworker.h
rollingstock/rs_checker/rsworker.cpp
PARENT_SCOPE
)

View File

@ -1,128 +1,29 @@
#include "rscheckermanager.h"
#ifdef ENABLE_RS_CHECKER
#ifdef ENABLE_BACKGROUND_MANAGER
#include <QThreadPool>
#include "app/session.h"
#include "viewmanager/viewmanager.h"
#include "rsworker.h"
#include "rserrortreemodel.h"
RsCheckerManager::RsCheckerManager(QObject *parent) :
QObject(parent),
m_mainWorker(nullptr)
#include <QSet>
#include "utils/owningqpointer.h"
#include <QMenu>
RsCheckerManager::RsCheckerManager(sqlite3pp::database &db, QObject *parent) :
IBackgroundChecker(db, parent)
{
eventType = RsWorkerResultEvent::_Type;
errorsModel = new RsErrorTreeModel(this);
connect(Session, &MeetingSession::rollingStockPlanChanged, this, &RsCheckerManager::onRSPlanChanged);
}
RsCheckerManager::~RsCheckerManager()
{
if(m_mainWorker)
{
m_mainWorker->stop();
m_mainWorker->cleanup();
m_mainWorker = nullptr;
}
for(RsErrWorker *task : qAsConst(m_workers))
{
task->stop();
task->cleanup();
}
m_workers.clear();
}
bool RsCheckerManager::event(QEvent *e)
{
if(e->type() == RsWorkerProgressEvent::_Type)
{
e->setAccepted(true);
RsWorkerProgressEvent *ev = static_cast<RsWorkerProgressEvent *>(e);
if(ev->progress == 0)
{
emit progressMax(ev->progressMax);
}
emit progress(ev->progress);
return true;
}
else if(e->type() == RsWorkerResultEvent::_Type)
{
e->setAccepted(true);
RsWorkerResultEvent *ev = static_cast<RsWorkerResultEvent *>(e);
if(m_mainWorker && ev->task == m_mainWorker)
{
if(!m_mainWorker->wasStopped())
{
errorsModel->setErrors(ev->results);
}
delete m_mainWorker;
m_mainWorker = nullptr;
emit taskFinished();
}
else
{
int idx = m_workers.indexOf(ev->task);
if(idx != -1)
{
m_workers.removeAt(idx);
if(!ev->task->wasStopped())
errorsModel->mergeErrors(ev->results);
delete ev->task;
}
}
return true;
}
return QObject::event(e);
}
bool RsCheckerManager::startWorker()
{
if(m_mainWorker)
return false;
if(!Session->m_Db.db())
return false;
m_mainWorker = new RsErrWorker(Session->m_Db, this, {});
QThreadPool::globalInstance()->start(m_mainWorker);
for(RsErrWorker *task : qAsConst(m_workers))
{
if(!QThreadPool::globalInstance()->tryTake(task))
task->stop();
}
return true;
}
void RsCheckerManager::abortTasks()
{
if(m_mainWorker)
{
m_mainWorker->stop();
}
for(RsErrWorker *task : qAsConst(m_workers))
{
task->stop();
}
}
void RsCheckerManager::checkRs(const QSet<db_id> &rsIds)
{
if(rsIds.isEmpty() || !Session->m_Db.db())
@ -133,19 +34,43 @@ void RsCheckerManager::checkRs(const QSet<db_id> &rsIds)
vec.append(rsId);
RsErrWorker *task = new RsErrWorker(Session->m_Db, this, vec);
m_workers.append(task);
QThreadPool::globalInstance()->start(task);
addSubTask(task);
}
RsErrorTreeModel *RsCheckerManager::getErrorsModel() const
QString RsCheckerManager::getName() const
{
return errorsModel;
return tr("RS Errors");
}
void RsCheckerManager::clearModel()
{
errorsModel->clear();
static_cast<RsErrorTreeModel *>(errorsModel)->clear();
}
void RsCheckerManager::showContextMenu(QWidget *panel, const QPoint &pos, const QModelIndex &idx) const
{
const RsErrorTreeModel *model = static_cast<const RsErrorTreeModel *>(errorsModel);
auto item = model->getItem(idx);
if(!item)
return;
OwningQPointer<QMenu> menu = new QMenu(panel);
QAction *showInJobEditor = new QAction(tr("Show in Job Editor"), menu);
QAction *showRsPlan = new QAction(tr("Show rollingstock plan"), menu);
menu->addAction(showInJobEditor);
menu->addAction(showRsPlan);
QAction *act = menu->exec(pos);
if(act == showInJobEditor)
{
Session->getViewManager()->requestJobEditor(item->job.jobId, item->stopId);
}
else if(act == showRsPlan)
{
Session->getViewManager()->requestRSInfo(item->rsId);
}
}
void RsCheckerManager::onRSPlanChanged(const QSet<db_id> &rsIds)
@ -156,4 +81,19 @@ void RsCheckerManager::onRSPlanChanged(const QSet<db_id> &rsIds)
checkRs(rsIds);
}
#endif // ENABLE_RS_CHECKER
IQuittableTask *RsCheckerManager::createMainWorker()
{
return new RsErrWorker(mDb, this, {});
}
void RsCheckerManager::setErrors(QEvent *e, bool merge)
{
auto model = static_cast<RsErrorTreeModel *>(errorsModel);
auto ev = static_cast<RsWorkerResultEvent *>(e);
if(merge)
model->mergeErrors(ev->results);
else
model->setErrors(ev->results);
}
#endif // ENABLE_BACKGROUND_MANAGER

View File

@ -1,52 +1,32 @@
#ifndef RSCHECKERMANAGER_H
#define RSCHECKERMANAGER_H
#ifdef ENABLE_RS_CHECKER
#ifdef ENABLE_BACKGROUND_MANAGER
#include <QObject>
#include <QVector>
#include <QSet>
#include "backgroundmanager/ibackgroundchecker.h"
#include "utils/types.h"
class RsErrWorker;
class RsErrorTreeModel;
class RsCheckerManager : public QObject
class RsCheckerManager : public IBackgroundChecker
{
Q_OBJECT
public:
explicit RsCheckerManager(QObject *parent = nullptr);
~RsCheckerManager();
bool event(QEvent *e) override;
bool startWorker();
void abortTasks();
inline bool isRunning() { return m_mainWorker || m_workers.size() > 0; }
RsCheckerManager(sqlite3pp::database &db, QObject *parent = nullptr);
void checkRs(const QSet<db_id> &rsIds);
RsErrorTreeModel *getErrorsModel() const;
void clearModel();
signals:
void progressMax(int max);
void progress(int val);
void taskFinished();
QString getName() const override;
void clearModel() override;
void showContextMenu(QWidget *panel, const QPoint& pos, const QModelIndex& idx) const override;
public slots:
void onRSPlanChanged(const QSet<db_id> &rsIds);
private:
RsErrWorker *m_mainWorker; //Checks all rollingstock
QVector<RsErrWorker *> m_workers; //Specific check for some RS
RsErrorTreeModel *errorsModel;
protected:
IQuittableTask *createMainWorker() override;
void setErrors(QEvent *e, bool merge) override;
};
#endif // ENABLE_RS_CHECKER
#endif // ENABLE_BACKGROUND_MANAGER
#endif // RSCHECKERMANAGER_H

View File

@ -1,144 +0,0 @@
#ifdef ENABLE_RS_CHECKER
#include "rserrorswidget.h"
#include <QTreeView>
#include <QHeaderView>
#include <QProgressBar>
#include <QPushButton>
#include <QGridLayout>
#include "app/session.h"
#include "rserrortreemodel.h"
#include "backgroundmanager/backgroundmanager.h"
#include "rscheckermanager.h"
#include "utils/owningqpointer.h"
#include <QMenu>
#include <QAction>
#include <QTimerEvent>
#include "viewmanager/viewmanager.h"
RsErrorsWidget::RsErrorsWidget(QWidget *parent) :
QWidget(parent),
timerId(0)
{
view = new QTreeView;
view->setUniformRowHeights(true);
view->setSelectionBehavior(QTreeView::SelectRows);
progressBar = new QProgressBar;
startBut = new QPushButton(tr("Start"));
stopBut = new QPushButton(tr("Stop"));
startBut->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred);
stopBut->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred);
auto mgr = Session->getBackgroundManager()->getRsChecker();
view->setModel(mgr->getErrorsModel());
view->header()->setStretchLastSection(true);
view->setSelectionBehavior(QTreeView::SelectRows);
QGridLayout *grid = new QGridLayout(this);
grid->addWidget(view, 0, 0, 1, 3);
grid->addWidget(startBut, 1, 0, 1, 1);
grid->addWidget(stopBut, 1, 1, 1, 1);
grid->addWidget(progressBar, 1, 2, 1, 1);
connect(mgr, &RsCheckerManager::progress, progressBar, &QProgressBar::setValue);
connect(mgr, &RsCheckerManager::progressMax, this, &RsErrorsWidget::taskProgressMax);
connect(mgr, &RsCheckerManager::taskFinished, this, &RsErrorsWidget::taskFinished);
connect(startBut, &QPushButton::clicked, this, &RsErrorsWidget::startTask);
connect(stopBut, &QPushButton::clicked, this, &RsErrorsWidget::stopTask);
view->setContextMenuPolicy(Qt::CustomContextMenu);
connect(view, &QTreeView::customContextMenuRequested, this, &RsErrorsWidget::showContextMenu);
setWindowTitle(tr("Rollingstock Errors"));
progressBar->hide();
}
void RsErrorsWidget::startTask()
{
progressBar->setValue(0);
if(Session->getBackgroundManager()->getRsChecker()->startWorker())
{
if(timerId)
{
killTimer(timerId); //Stop progressBar from hiding in 1 second
timerId = 0;
}
}
}
void RsErrorsWidget::stopTask()
{
Session->getBackgroundManager()->abortAllTasks();
}
void RsErrorsWidget::taskProgressMax(int max)
{
progressBar->setMaximum(max);
progressBar->show();
}
void RsErrorsWidget::taskFinished()
{
progressBar->setValue(progressBar->maximum());
if(timerId)
killTimer(timerId);
timerId = startTimer(1000); //Hide progressBar after 1 second
}
void RsErrorsWidget::timerEvent(QTimerEvent *e)
{
if(e->timerId() == timerId)
{
killTimer(timerId);
timerId = 0;
progressBar->hide();
}
}
void RsErrorsWidget::showContextMenu(const QPoint& pos)
{
QModelIndex idx = view->indexAt(pos);
if(!idx.isValid())
return;
const RsErrorTreeModel *model = static_cast<const RsErrorTreeModel *>(view->model());
auto item = model->getItem(idx);
if(!item)
return;
OwningQPointer<QMenu> menu = new QMenu(this);
QAction *showInJobEditor = new QAction(tr("Show in Job Editor"), menu);
QAction *showRsPlan = new QAction(tr("Show rollingstock plan"), menu);
menu->addAction(showInJobEditor);
menu->addAction(showRsPlan);
QAction *act = menu->exec(view->viewport()->mapToGlobal(pos));
if(act == showInJobEditor)
{
Session->getViewManager()->requestJobEditor(item->job.jobId, item->stopId);
}
else if(act == showRsPlan)
{
Session->getViewManager()->requestRSInfo(item->rsId);
}
}
#endif // ENABLE_RS_CHECKER

View File

@ -1,38 +0,0 @@
#ifndef RSERRORSWIDGET_H
#define RSERRORSWIDGET_H
#ifdef ENABLE_RS_CHECKER
#include <QWidget>
class QTreeView;
class QProgressBar;
class QPushButton;
class RsErrorsWidget : public QWidget
{
Q_OBJECT
public:
explicit RsErrorsWidget(QWidget *parent = nullptr);
protected:
void timerEvent(QTimerEvent *e) override;
private slots:
void startTask();
void stopTask();
void taskProgressMax(int max);
void taskFinished();
void showContextMenu(const QPoint &pos);
private:
QTreeView *view;
QProgressBar *progressBar;
QPushButton *startBut;
QPushButton *stopBut;
int timerId;
};
#endif // ENABLE_RS_CHECKER
#endif // RSERRORSWIDGET_H