mirror of
https://github.com/tnodir/fort
synced 2024-11-15 06:15:15 +00:00
UI: Add SchedulePage.
This commit is contained in:
parent
fba0f88a6b
commit
48208ff8c6
@ -27,6 +27,7 @@ SOURCES += \
|
||||
form/controls/listview.cpp \
|
||||
form/controls/spincombo.cpp \
|
||||
form/controls/tabbar.cpp \
|
||||
form/controls/tableview.cpp \
|
||||
form/controls/textarea2splitter.cpp \
|
||||
form/controls/textarea2splitterhandle.cpp \
|
||||
form/graph/axistickerspeed.cpp \
|
||||
@ -56,7 +57,6 @@ SOURCES += \
|
||||
log/model/appblockedmodel.cpp \
|
||||
log/model/appstatmodel.cpp \
|
||||
log/model/iplistmodel.cpp \
|
||||
log/model/stringlistmodel.cpp \
|
||||
log/model/traflistmodel.cpp \
|
||||
main.cpp \
|
||||
mainwindow.cpp \
|
||||
@ -67,6 +67,7 @@ SOURCES += \
|
||||
task/taskinfo.cpp \
|
||||
task/taskinfotasix.cpp \
|
||||
task/taskinfoupdatechecker.cpp \
|
||||
task/tasklistmodel.cpp \
|
||||
task/taskmanager.cpp \
|
||||
task/tasktasix.cpp \
|
||||
task/taskupdatechecker.cpp \
|
||||
@ -87,6 +88,8 @@ SOURCES += \
|
||||
util/guiutil.cpp \
|
||||
util/hotkeymanager.cpp \
|
||||
util/logger.cpp \
|
||||
util/model/stringlistmodel.cpp \
|
||||
util/model/tableitemmodel.cpp \
|
||||
util/nativeeventfilter.cpp \
|
||||
util/net/hostinfo.cpp \
|
||||
util/net/hostinfocache.cpp \
|
||||
@ -124,6 +127,7 @@ HEADERS += \
|
||||
form/controls/listview.h \
|
||||
form/controls/spincombo.h \
|
||||
form/controls/tabbar.h \
|
||||
form/controls/tableview.h \
|
||||
form/controls/textarea2splitter.h \
|
||||
form/controls/textarea2splitterhandle.h \
|
||||
form/graph/axistickerspeed.h \
|
||||
@ -153,7 +157,6 @@ HEADERS += \
|
||||
log/model/appblockedmodel.h \
|
||||
log/model/appstatmodel.h \
|
||||
log/model/iplistmodel.h \
|
||||
log/model/stringlistmodel.h \
|
||||
log/model/traflistmodel.h \
|
||||
mainwindow.h \
|
||||
stat/quotamanager.h \
|
||||
@ -163,6 +166,7 @@ HEADERS += \
|
||||
task/taskinfo.h \
|
||||
task/taskinfotasix.h \
|
||||
task/taskinfoupdatechecker.h \
|
||||
task/tasklistmodel.h \
|
||||
task/taskmanager.h \
|
||||
task/tasktasix.h \
|
||||
task/taskupdatechecker.h \
|
||||
@ -183,6 +187,8 @@ HEADERS += \
|
||||
util/guiutil.h \
|
||||
util/hotkeymanager.h \
|
||||
util/logger.h \
|
||||
util/model/stringlistmodel.h \
|
||||
util/model/tableitemmodel.h \
|
||||
util/nativeeventfilter.h \
|
||||
util/net/hostinfo.h \
|
||||
util/net/hostinfocache.h \
|
||||
|
14
src/ui/form/controls/tableview.cpp
Normal file
14
src/ui/form/controls/tableview.cpp
Normal file
@ -0,0 +1,14 @@
|
||||
#include "tableview.h"
|
||||
|
||||
TableView::TableView(QWidget *parent) :
|
||||
QTableView(parent)
|
||||
{
|
||||
}
|
||||
|
||||
void TableView::currentChanged(const QModelIndex ¤t,
|
||||
const QModelIndex &previous)
|
||||
{
|
||||
QTableView::currentChanged(current, previous);
|
||||
|
||||
emit currentIndexChanged(current);
|
||||
}
|
21
src/ui/form/controls/tableview.h
Normal file
21
src/ui/form/controls/tableview.h
Normal file
@ -0,0 +1,21 @@
|
||||
#ifndef TABLEVIEW_H
|
||||
#define TABLEVIEW_H
|
||||
|
||||
#include <QTableView>
|
||||
|
||||
class TableView : public QTableView
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit TableView(QWidget *parent = nullptr);
|
||||
|
||||
signals:
|
||||
void currentIndexChanged(const QModelIndex &index);
|
||||
|
||||
protected:
|
||||
void currentChanged(const QModelIndex ¤t,
|
||||
const QModelIndex &previous) override;
|
||||
};
|
||||
|
||||
#endif // TABLEVIEW_H
|
@ -1,7 +1,219 @@
|
||||
#include "schedulepage.h"
|
||||
|
||||
#include <QCheckBox>
|
||||
#include <QDate>
|
||||
#include <QHBoxLayout>
|
||||
#include <QHeaderView>
|
||||
#include <QPushButton>
|
||||
#include <QSpinBox>
|
||||
#include <QTableView>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
#include "../../../task/taskinfo.h"
|
||||
#include "../../../task/tasklistmodel.h"
|
||||
#include "../../../task/taskmanager.h"
|
||||
#include "../../controls/checkspincombo.h"
|
||||
#include "../../controls/controlutil.h"
|
||||
#include "../../controls/tableview.h"
|
||||
#include "../optionscontroller.h"
|
||||
|
||||
namespace {
|
||||
|
||||
const ValuesList taskIntervalHourValues = {
|
||||
3, 1, 6, 12, 24, 24 * 7, 24 * 30
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
SchedulePage::SchedulePage(OptionsController *ctrl,
|
||||
QWidget *parent) :
|
||||
BasePage(ctrl, parent)
|
||||
BasePage(ctrl, parent),
|
||||
m_taskListModel(new TaskListModel(taskManager(), this))
|
||||
{
|
||||
setupTaskListModel();
|
||||
|
||||
setupUi();
|
||||
}
|
||||
|
||||
void SchedulePage::setScheduleEdited(bool v)
|
||||
{
|
||||
if (m_scheduleEdited != v) {
|
||||
m_scheduleEdited = v;
|
||||
|
||||
if (scheduleEdited()) {
|
||||
ctrl()->setOthersEdited(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SchedulePage::onEditResetted()
|
||||
{
|
||||
setScheduleEdited(false);
|
||||
|
||||
m_taskListModel->resetEdited();
|
||||
}
|
||||
|
||||
void SchedulePage::onSaved()
|
||||
{
|
||||
if (!scheduleEdited()) return;
|
||||
|
||||
m_taskListModel->saveChanges();
|
||||
}
|
||||
|
||||
void SchedulePage::onRetranslateUi()
|
||||
{
|
||||
m_taskListModel->refresh();
|
||||
|
||||
m_btTaskRun->setText(tr("Run"));
|
||||
m_btTaskAbort->setText(tr("Abort"));
|
||||
|
||||
retranslateTaskDetails();
|
||||
}
|
||||
|
||||
void SchedulePage::setupTaskListModel()
|
||||
{
|
||||
connect(m_taskListModel, &TaskListModel::dataChanged, [&] {
|
||||
setScheduleEdited(true);
|
||||
});
|
||||
}
|
||||
|
||||
void SchedulePage::retranslateTaskDetails()
|
||||
{
|
||||
const QStringList list = {
|
||||
tr("Custom"), tr("Hourly"), tr("Each 6 hours"),
|
||||
tr("Each 12 hours"), tr("Daily"), tr("Weekly"), tr("Monthly")
|
||||
};
|
||||
|
||||
m_lscTaskInterval->setNames(list);
|
||||
m_lscTaskInterval->spinBox()->setSuffix(tr(" hours"));
|
||||
}
|
||||
|
||||
void SchedulePage::setupUi()
|
||||
{
|
||||
auto layout = new QVBoxLayout();
|
||||
|
||||
// Tasks Table
|
||||
setupTableTasks();
|
||||
setupTableTasksHeader();
|
||||
layout->addWidget(m_tableTasks, 1);
|
||||
|
||||
// Task Details
|
||||
setupTaskDetails();
|
||||
layout->addWidget(m_taskDetailsRow);
|
||||
|
||||
// Actions on tasks table's current changed
|
||||
setupTableTasksChanged();
|
||||
|
||||
this->setLayout(layout);
|
||||
}
|
||||
|
||||
void SchedulePage::setupTableTasks()
|
||||
{
|
||||
m_tableTasks = new TableView();
|
||||
m_tableTasks->setSelectionMode(QAbstractItemView::SingleSelection);
|
||||
m_tableTasks->setSelectionBehavior(QAbstractItemView::SelectRows);
|
||||
|
||||
m_tableTasks->setModel(taskListModel());
|
||||
}
|
||||
|
||||
void SchedulePage::setupTableTasksHeader()
|
||||
{
|
||||
auto header = m_tableTasks->horizontalHeader();
|
||||
|
||||
header->setSectionResizeMode(0, QHeaderView::Fixed);
|
||||
header->setSectionResizeMode(1, QHeaderView::Stretch);
|
||||
header->setSectionResizeMode(2, QHeaderView::Stretch);
|
||||
header->setSectionResizeMode(3, QHeaderView::Stretch);
|
||||
|
||||
const auto refreshTableTasksHeader = [&] {
|
||||
auto hh = m_tableTasks->horizontalHeader();
|
||||
hh->resizeSection(0, qRound(hh->width() * 0.45));
|
||||
};
|
||||
|
||||
refreshTableTasksHeader();
|
||||
|
||||
connect(header, &QHeaderView::geometriesChanged, this, refreshTableTasksHeader);
|
||||
}
|
||||
|
||||
void SchedulePage::setupTaskDetails()
|
||||
{
|
||||
m_taskDetailsRow = new QWidget();
|
||||
|
||||
auto layout = new QHBoxLayout();
|
||||
layout->setMargin(0);
|
||||
m_taskDetailsRow->setLayout(layout);
|
||||
|
||||
setupTaskInterval();
|
||||
|
||||
m_btTaskRun = ControlUtil::createButton(":/images/run.png", [&] {
|
||||
currentTaskInfo()->run();
|
||||
});
|
||||
m_btTaskAbort = ControlUtil::createButton(":/images/cancel.png", [&] {
|
||||
currentTaskInfo()->abort();
|
||||
});
|
||||
|
||||
layout->addWidget(m_lscTaskInterval, 1);
|
||||
layout->addWidget(m_btTaskRun);
|
||||
layout->addWidget(m_btTaskAbort);
|
||||
}
|
||||
|
||||
void SchedulePage::setupTaskInterval()
|
||||
{
|
||||
m_lscTaskInterval = new CheckSpinCombo();
|
||||
m_lscTaskInterval->checkBox()->setFont(ControlUtil::createFont(QFont::DemiBold));
|
||||
m_lscTaskInterval->spinBox()->setRange(1, 24 * 30 * 12); // ~Year
|
||||
m_lscTaskInterval->setValues(taskIntervalHourValues);
|
||||
|
||||
connect(m_lscTaskInterval->checkBox(), &QCheckBox::toggled, [&](bool checked) {
|
||||
const int taskIndex = currentTaskIndex();
|
||||
const auto index = taskListModel()->index(taskIndex, 0);
|
||||
|
||||
taskListModel()->setData(index, checked, TaskListModel::RoleEnabled);
|
||||
});
|
||||
connect(m_lscTaskInterval->spinBox(), QOverload<int>::of(&QSpinBox::valueChanged), [&](int value) {
|
||||
const int taskIndex = currentTaskIndex();
|
||||
const auto index = taskListModel()->index(taskIndex, 1);
|
||||
|
||||
taskListModel()->setData(index, value, TaskListModel::RoleIntervalHours);
|
||||
});
|
||||
}
|
||||
|
||||
void SchedulePage::setupTableTasksChanged()
|
||||
{
|
||||
const auto refreshTableTasksChanged = [&] {
|
||||
const int taskIndex = currentTaskIndex();
|
||||
const bool taskSelected = taskIndex >= 0;
|
||||
|
||||
setCurrentTaskInfo(taskSelected
|
||||
? taskListModel()->taskInfoAt(taskIndex)
|
||||
: nullptr);
|
||||
m_taskDetailsRow->setVisible(taskSelected);
|
||||
|
||||
if (taskSelected) {
|
||||
const auto index = taskListModel()->index(taskIndex, 0);
|
||||
|
||||
m_lscTaskInterval->checkBox()->setChecked(
|
||||
taskListModel()->data(index, TaskListModel::RoleEnabled).toBool());
|
||||
m_lscTaskInterval->checkBox()->setText(
|
||||
taskListModel()->data(index).toString());
|
||||
m_lscTaskInterval->spinBox()->setValue(
|
||||
taskListModel()->data(index, TaskListModel::RoleIntervalHours).toInt());
|
||||
|
||||
const bool running = currentTaskInfo()->running();
|
||||
m_btTaskRun->setEnabled(!running);
|
||||
m_btTaskAbort->setEnabled(running);
|
||||
}
|
||||
};
|
||||
|
||||
refreshTableTasksChanged();
|
||||
|
||||
connect(m_tableTasks, &TableView::currentIndexChanged, this, refreshTableTasksChanged);
|
||||
connect(taskListModel(), &TaskListModel::dataChanged, this, refreshTableTasksChanged);
|
||||
connect(taskManager(), &TaskManager::taskStarted, this, refreshTableTasksChanged);
|
||||
connect(taskManager(), &TaskManager::taskFinished, this, refreshTableTasksChanged);
|
||||
}
|
||||
|
||||
int SchedulePage::currentTaskIndex() const
|
||||
{
|
||||
return m_tableTasks->currentIndex().row();
|
||||
}
|
||||
|
@ -3,6 +3,13 @@
|
||||
|
||||
#include "basepage.h"
|
||||
|
||||
QT_FORWARD_DECLARE_CLASS(QTableView)
|
||||
|
||||
QT_FORWARD_DECLARE_CLASS(CheckSpinCombo)
|
||||
QT_FORWARD_DECLARE_CLASS(TableView)
|
||||
QT_FORWARD_DECLARE_CLASS(TaskInfo)
|
||||
QT_FORWARD_DECLARE_CLASS(TaskListModel)
|
||||
|
||||
class SchedulePage : public BasePage
|
||||
{
|
||||
Q_OBJECT
|
||||
@ -11,8 +18,45 @@ public:
|
||||
explicit SchedulePage(OptionsController *ctrl = nullptr,
|
||||
QWidget *parent = nullptr);
|
||||
|
||||
signals:
|
||||
TaskListModel *taskListModel() const { return m_taskListModel; }
|
||||
|
||||
protected slots:
|
||||
void onEditResetted() override;
|
||||
void onSaved() override;
|
||||
|
||||
void onRetranslateUi() override;
|
||||
|
||||
private:
|
||||
bool scheduleEdited() const { return m_scheduleEdited; }
|
||||
void setScheduleEdited(bool v);
|
||||
|
||||
void retranslateTaskDetails();
|
||||
|
||||
void setupTaskListModel();
|
||||
|
||||
void setupUi();
|
||||
void setupTableTasks();
|
||||
void setupTableTasksHeader();
|
||||
void setupTaskDetails();
|
||||
void setupTaskInterval();
|
||||
void setupTableTasksChanged();
|
||||
|
||||
int currentTaskIndex() const;
|
||||
|
||||
TaskInfo *currentTaskInfo() const { return m_taskInfo; }
|
||||
void setCurrentTaskInfo(TaskInfo *v) { m_taskInfo = v; }
|
||||
|
||||
private:
|
||||
bool m_scheduleEdited = false;
|
||||
|
||||
TaskListModel *m_taskListModel = nullptr;
|
||||
TaskInfo *m_taskInfo = nullptr;
|
||||
|
||||
TableView *m_tableTasks = nullptr;
|
||||
QWidget *m_taskDetailsRow = nullptr;
|
||||
CheckSpinCombo *m_lscTaskInterval = nullptr;
|
||||
QPushButton *m_btTaskRun = nullptr;
|
||||
QPushButton *m_btTaskAbort = nullptr;
|
||||
};
|
||||
|
||||
#endif // SCHEDULEPAGE_H
|
||||
|
@ -734,7 +734,7 @@ void StatisticsPage::setupAppListViewChanged()
|
||||
|
||||
refreshAppListViewChanged();
|
||||
|
||||
connect(m_appListView, &ListView::currentIndexChanged, this , refreshAppListViewChanged);
|
||||
connect(m_appListView, &ListView::currentIndexChanged, this, refreshAppListViewChanged);
|
||||
}
|
||||
|
||||
void StatisticsPage::updatePage()
|
||||
|
@ -193,7 +193,7 @@ void FortManager::setupLogger()
|
||||
|
||||
void FortManager::setupTaskManager()
|
||||
{
|
||||
m_taskManager->loadSettings(settings(), m_confManager);
|
||||
m_taskManager->loadSettings();
|
||||
}
|
||||
|
||||
void FortManager::setupTranslationManager()
|
||||
|
@ -4,7 +4,7 @@
|
||||
#include <QHash>
|
||||
#include <QSet>
|
||||
|
||||
#include "stringlistmodel.h"
|
||||
#include "../../util/model/stringlistmodel.h"
|
||||
|
||||
QT_FORWARD_DECLARE_CLASS(IpListModel)
|
||||
QT_FORWARD_DECLARE_CLASS(LogEntryBlocked)
|
||||
|
@ -1,7 +1,7 @@
|
||||
#ifndef APPSTATMODEL_H
|
||||
#define APPSTATMODEL_H
|
||||
|
||||
#include "stringlistmodel.h"
|
||||
#include "../../util/model/stringlistmodel.h"
|
||||
|
||||
QT_FORWARD_DECLARE_CLASS(AppInfoCache)
|
||||
QT_FORWARD_DECLARE_CLASS(LogEntryProcNew)
|
||||
|
@ -1,7 +1,7 @@
|
||||
#ifndef IPLISTMODEL_H
|
||||
#define IPLISTMODEL_H
|
||||
|
||||
#include "stringlistmodel.h"
|
||||
#include "../../util/model/stringlistmodel.h"
|
||||
|
||||
class IpListModel : public StringListModel
|
||||
{
|
||||
|
@ -9,14 +9,7 @@
|
||||
|
||||
TrafListModel::TrafListModel(StatManager *statManager,
|
||||
QObject *parent) :
|
||||
QAbstractItemModel(parent),
|
||||
m_isEmpty(false),
|
||||
m_unit(UnitAdaptive),
|
||||
m_type(TrafHourly),
|
||||
m_appId(0),
|
||||
m_minTrafTime(0),
|
||||
m_maxTrafTime(0),
|
||||
m_trafCount(0),
|
||||
TableItemModel(parent),
|
||||
m_statManager(statManager)
|
||||
{
|
||||
}
|
||||
@ -36,28 +29,6 @@ void TrafListModel::setAppId(qint64 appId)
|
||||
m_appId = appId;
|
||||
}
|
||||
|
||||
QModelIndex TrafListModel::index(int row, int column,
|
||||
const QModelIndex &parent) const
|
||||
{
|
||||
return hasIndex(row, column, parent)
|
||||
? createIndex(row, column) : QModelIndex();
|
||||
}
|
||||
|
||||
QModelIndex TrafListModel::parent(const QModelIndex &child) const
|
||||
{
|
||||
Q_UNUSED(child)
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
QModelIndex TrafListModel::sibling(int row, int column,
|
||||
const QModelIndex &index) const
|
||||
{
|
||||
Q_UNUSED(index)
|
||||
|
||||
return this->index(row, column);
|
||||
}
|
||||
|
||||
int TrafListModel::rowCount(const QModelIndex &parent) const
|
||||
{
|
||||
Q_UNUSED(parent)
|
||||
@ -70,11 +41,6 @@ int TrafListModel::columnCount(const QModelIndex &parent) const
|
||||
return parent.isValid() ? 0 : 4;
|
||||
}
|
||||
|
||||
bool TrafListModel::hasChildren(const QModelIndex &parent) const
|
||||
{
|
||||
return !parent.isValid() && rowCount() > 0;
|
||||
}
|
||||
|
||||
QVariant TrafListModel::headerData(int section, Qt::Orientation orientation, int role) const
|
||||
{
|
||||
if (orientation == Qt::Horizontal
|
||||
@ -113,12 +79,6 @@ QVariant TrafListModel::data(const QModelIndex &index, int role) const
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
Qt::ItemFlags TrafListModel::flags(const QModelIndex &index) const
|
||||
{
|
||||
return QAbstractItemModel::flags(index)
|
||||
| (index.isValid() ? Qt::ItemNeverHasChildren : Qt::NoItemFlags);
|
||||
}
|
||||
|
||||
void TrafListModel::clear()
|
||||
{
|
||||
m_statManager->clear();
|
||||
|
@ -1,7 +1,7 @@
|
||||
#ifndef TRAFLISTMODEL_H
|
||||
#define TRAFLISTMODEL_H
|
||||
|
||||
#include <QAbstractItemModel>
|
||||
#include "../util/model/tableitemmodel.h"
|
||||
|
||||
QT_FORWARD_DECLARE_CLASS(StatManager)
|
||||
|
||||
@ -15,7 +15,7 @@ struct TrafficRow {
|
||||
qint64 outBytes = 0;
|
||||
};
|
||||
|
||||
class TrafListModel : public QAbstractItemModel
|
||||
class TrafListModel : public TableItemModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
@ -50,22 +50,13 @@ public:
|
||||
qint64 appId() const { return m_appId; }
|
||||
void setAppId(qint64 appId);
|
||||
|
||||
QModelIndex index(int row, int column,
|
||||
const QModelIndex &parent = QModelIndex()) const override;
|
||||
QModelIndex parent(const QModelIndex &child) const override;
|
||||
|
||||
QModelIndex sibling(int row, int column,
|
||||
const QModelIndex &index) const override;
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||
int columnCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||
bool hasChildren(const QModelIndex &parent = QModelIndex()) const override;
|
||||
|
||||
QVariant headerData(int section, Qt::Orientation orientation,
|
||||
int role = Qt::DisplayRole) const override;
|
||||
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
||||
|
||||
Qt::ItemFlags flags(const QModelIndex &index) const override;
|
||||
|
||||
public slots:
|
||||
void clear();
|
||||
|
||||
@ -91,20 +82,20 @@ private:
|
||||
static const char *getSqlSelectTraffic(TrafType type, qint64 appId);
|
||||
|
||||
private:
|
||||
bool m_isEmpty;
|
||||
bool m_isEmpty = false;
|
||||
|
||||
TrafUnit m_unit;
|
||||
TrafType m_type;
|
||||
TrafUnit m_unit = UnitAdaptive;
|
||||
TrafType m_type = TrafHourly;
|
||||
|
||||
qint64 m_appId;
|
||||
qint64 m_appId = 0;
|
||||
|
||||
qint32 m_minTrafTime;
|
||||
qint32 m_maxTrafTime;
|
||||
qint32 m_trafCount;
|
||||
qint32 m_minTrafTime = 0;
|
||||
qint32 m_maxTrafTime = 0;
|
||||
qint32 m_trafCount = 0;
|
||||
|
||||
StatManager *m_statManager = nullptr;
|
||||
|
||||
mutable TrafficRow m_rowCache;
|
||||
|
||||
StatManager *m_statManager;
|
||||
};
|
||||
|
||||
#endif // TRAFLISTMODEL_H
|
||||
|
@ -12,6 +12,7 @@
|
||||
TaskInfo::TaskInfo(TaskType type, QObject *parent) :
|
||||
QObject(parent),
|
||||
m_enabled(false),
|
||||
m_running(false),
|
||||
m_aborted(false),
|
||||
m_intervalHours(24),
|
||||
m_type(type),
|
||||
@ -33,6 +34,14 @@ void TaskInfo::setEnabled(bool enabled)
|
||||
}
|
||||
}
|
||||
|
||||
void TaskInfo::setRunning(bool running)
|
||||
{
|
||||
if (m_running != running) {
|
||||
m_running = running;
|
||||
emit enabledChanged();
|
||||
}
|
||||
}
|
||||
|
||||
void TaskInfo::setIntervalHours(int intervalHours)
|
||||
{
|
||||
if (m_intervalHours != intervalHours) {
|
||||
@ -159,6 +168,9 @@ void TaskInfo::run()
|
||||
|
||||
setTaskWorker(taskWorker);
|
||||
|
||||
setRunning(true);
|
||||
emit workStarted();
|
||||
|
||||
taskWorker->run();
|
||||
}
|
||||
|
||||
@ -185,6 +197,7 @@ void TaskInfo::handleFinished(bool success)
|
||||
setLastSuccess(lastRun());
|
||||
}
|
||||
|
||||
setRunning(false);
|
||||
emit workFinished(success);
|
||||
|
||||
abort();
|
||||
|
@ -37,6 +37,9 @@ public:
|
||||
bool enabled() const { return m_enabled; }
|
||||
void setEnabled(bool enabled);
|
||||
|
||||
bool running() const { return m_running; }
|
||||
void setRunning(bool running);
|
||||
|
||||
int intervalHours() const { return m_intervalHours; }
|
||||
void setIntervalHours(int intervalHours);
|
||||
|
||||
@ -62,8 +65,6 @@ public:
|
||||
TaskWorker *taskWorker() const { return m_taskWorker; }
|
||||
void setTaskWorker(TaskWorker *taskWorker);
|
||||
|
||||
bool running() const { return m_taskWorker != nullptr; }
|
||||
|
||||
void rawData(QByteArray &data) const;
|
||||
void setRawData(const QByteArray &data);
|
||||
|
||||
@ -72,12 +73,14 @@ public:
|
||||
|
||||
signals:
|
||||
void enabledChanged();
|
||||
void runningChanged();
|
||||
void intervalHoursChanged();
|
||||
void typeChanged();
|
||||
void lastRunChanged();
|
||||
void lastSuccessChanged();
|
||||
void taskWorkerChanged();
|
||||
|
||||
void workStarted();
|
||||
void workFinished(bool success);
|
||||
|
||||
public slots:
|
||||
@ -94,6 +97,7 @@ private:
|
||||
|
||||
private:
|
||||
quint8 m_enabled : 1;
|
||||
quint8 m_running : 1;
|
||||
quint8 m_aborted : 1; // transient
|
||||
|
||||
quint16 m_intervalHours;
|
||||
|
245
src/ui/task/tasklistmodel.cpp
Normal file
245
src/ui/task/tasklistmodel.cpp
Normal file
@ -0,0 +1,245 @@
|
||||
#include "tasklistmodel.h"
|
||||
|
||||
#include "taskinfo.h"
|
||||
#include "taskmanager.h"
|
||||
|
||||
TaskListModel::TaskListModel(TaskManager *taskManager,
|
||||
QObject *parent) :
|
||||
TableItemModel(parent),
|
||||
m_taskManager(taskManager)
|
||||
{
|
||||
setupTaskRows();
|
||||
|
||||
connect(m_taskManager, &TaskManager::taskFinished, this, &TaskListModel::refresh);
|
||||
}
|
||||
|
||||
TaskListModel::~TaskListModel()
|
||||
{
|
||||
clearTaskRows();
|
||||
}
|
||||
|
||||
const QList<TaskInfo *> &TaskListModel::taskInfosList() const
|
||||
{
|
||||
return taskManager()->taskInfosList();
|
||||
}
|
||||
|
||||
int TaskListModel::rowCount(const QModelIndex &parent) const
|
||||
{
|
||||
Q_UNUSED(parent)
|
||||
|
||||
return taskInfosList().size();
|
||||
}
|
||||
|
||||
int TaskListModel::columnCount(const QModelIndex &parent) const
|
||||
{
|
||||
return parent.isValid() ? 0 : 4;
|
||||
}
|
||||
|
||||
QVariant TaskListModel::headerData(int section, Qt::Orientation orientation, int role) const
|
||||
{
|
||||
if (orientation == Qt::Horizontal
|
||||
&& role == Qt::DisplayRole) {
|
||||
switch (section) {
|
||||
case 0: return tr("Name");
|
||||
case 1: return tr("Interval, hours");
|
||||
case 2: return tr("Last Run");
|
||||
case 3: return tr("Last Success");
|
||||
}
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
QVariant TaskListModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
if (!index.isValid())
|
||||
return QVariant();
|
||||
|
||||
switch (role) {
|
||||
case Qt::DisplayRole:
|
||||
{
|
||||
const int row = index.row();
|
||||
const int column = index.column();
|
||||
|
||||
const auto taskInfo = taskInfoAt(row);
|
||||
|
||||
switch (column) {
|
||||
case 0: return taskInfo->title();
|
||||
case 1: return taskIntervalHours(row);
|
||||
case 2: return formatDateTime(taskInfo->lastRun());
|
||||
case 3: return formatDateTime(taskInfo->lastSuccess());
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case Qt::CheckStateRole:
|
||||
case RoleEnabled:
|
||||
if (index.column() == 0) {
|
||||
return taskEnabled(index.row());
|
||||
}
|
||||
break;
|
||||
|
||||
case RoleIntervalHours:
|
||||
return taskIntervalHours(index.row());
|
||||
|
||||
case RoleRunning: {
|
||||
const auto taskInfo = taskInfoAt(index.row());
|
||||
return taskInfo->running();
|
||||
}
|
||||
}
|
||||
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
bool TaskListModel::setData(const QModelIndex &index, const QVariant &value, int role)
|
||||
{
|
||||
Q_UNUSED(value)
|
||||
|
||||
if (!index.isValid())
|
||||
return false;
|
||||
|
||||
switch (role) {
|
||||
case Qt::CheckStateRole:
|
||||
setTaskEnabled(index, !taskEnabled(index.row()));
|
||||
return true;
|
||||
|
||||
case RoleEnabled:
|
||||
setTaskEnabled(index, value.toBool());
|
||||
return true;
|
||||
|
||||
case RoleIntervalHours:
|
||||
setTaskIntervalHours(index, value.toInt());
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
Qt::ItemFlags TaskListModel::flags(const QModelIndex &index) const
|
||||
{
|
||||
if (!index.isValid())
|
||||
return Qt::NoItemFlags;
|
||||
|
||||
const int column = index.column();
|
||||
|
||||
return Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemNeverHasChildren
|
||||
| (column == 0 ? Qt::ItemIsUserCheckable : Qt::NoItemFlags);
|
||||
}
|
||||
|
||||
void TaskListModel::resetEdited()
|
||||
{
|
||||
beginResetModel();
|
||||
setupTaskRows();
|
||||
endResetModel();
|
||||
}
|
||||
|
||||
void TaskListModel::saveChanges()
|
||||
{
|
||||
const int taskCount = taskInfosList().size();
|
||||
for (int i = 0; i < taskCount; ++i) {
|
||||
const auto taskRow = taskRowAt(i);
|
||||
if (!taskRow) continue;
|
||||
|
||||
auto taskInfo = taskInfoAt(i);
|
||||
taskInfo->setEnabled(taskRow->enabled);
|
||||
taskInfo->setIntervalHours(taskRow->intervalHours);
|
||||
}
|
||||
|
||||
taskManager()->saveSettings();
|
||||
}
|
||||
|
||||
void TaskListModel::setupTaskRows()
|
||||
{
|
||||
clearTaskRows();
|
||||
|
||||
const int taskCount = taskInfosList().size();
|
||||
for (int i = 0; i < taskCount; ++i) {
|
||||
m_taskRows.append(nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
void TaskListModel::clearTaskRows()
|
||||
{
|
||||
qDeleteAll(m_taskRows);
|
||||
m_taskRows.clear();
|
||||
}
|
||||
|
||||
bool TaskListModel::taskEnabled(int index) const
|
||||
{
|
||||
const auto taskRow = taskRowAt(index);
|
||||
if (taskRow)
|
||||
return taskRow->enabled;
|
||||
|
||||
const auto taskInfo = taskInfoAt(index);
|
||||
return taskInfo->enabled();
|
||||
}
|
||||
|
||||
void TaskListModel::setTaskEnabled(const QModelIndex &index, bool v)
|
||||
{
|
||||
const int row = index.row();
|
||||
|
||||
auto taskRow = taskRowAt(row);
|
||||
if (!taskRow) {
|
||||
taskRow = addTaskRow(row);
|
||||
}
|
||||
|
||||
if (taskRow->enabled == v)
|
||||
return;
|
||||
|
||||
taskRow->enabled = v;
|
||||
|
||||
emit dataChanged(index, index, {Qt::CheckStateRole});
|
||||
}
|
||||
|
||||
int TaskListModel::taskIntervalHours(int index) const
|
||||
{
|
||||
const auto taskRow = taskRowAt(index);
|
||||
if (taskRow)
|
||||
return taskRow->intervalHours;
|
||||
|
||||
const auto taskInfo = taskInfoAt(index);
|
||||
return taskInfo->intervalHours();
|
||||
}
|
||||
|
||||
void TaskListModel::setTaskIntervalHours(const QModelIndex &index, int v)
|
||||
{
|
||||
const int row = index.row();
|
||||
|
||||
auto taskRow = taskRowAt(row);
|
||||
if (!taskRow) {
|
||||
taskRow = addTaskRow(row);
|
||||
}
|
||||
|
||||
if (taskRow->intervalHours == v)
|
||||
return;
|
||||
|
||||
taskRow->intervalHours = v;
|
||||
|
||||
emit dataChanged(index, index, {Qt::DisplayRole});
|
||||
}
|
||||
|
||||
TaskRow *TaskListModel::addTaskRow(int index)
|
||||
{
|
||||
auto taskRow = new TaskRow();
|
||||
m_taskRows.replace(index, taskRow);
|
||||
|
||||
auto taskInfo = taskInfoAt(index);
|
||||
taskRow->enabled = taskInfo->enabled();
|
||||
taskRow->intervalHours = taskInfo->intervalHours();
|
||||
|
||||
return taskRow;
|
||||
}
|
||||
|
||||
TaskInfo *TaskListModel::taskInfoAt(int index) const
|
||||
{
|
||||
return taskInfosList().at(index);
|
||||
}
|
||||
|
||||
TaskRow *TaskListModel::taskRowAt(int index) const
|
||||
{
|
||||
return m_taskRows.at(index);
|
||||
}
|
||||
|
||||
QString TaskListModel::formatDateTime(const QDateTime &dateTime)
|
||||
{
|
||||
return dateTime.toString("yyyy-MM-dd HH:mm:ss");
|
||||
}
|
74
src/ui/task/tasklistmodel.h
Normal file
74
src/ui/task/tasklistmodel.h
Normal file
@ -0,0 +1,74 @@
|
||||
#ifndef TASKLISTMODEL_H
|
||||
#define TASKLISTMODEL_H
|
||||
|
||||
#include <QList>
|
||||
|
||||
#include "../util/model/tableitemmodel.h"
|
||||
|
||||
QT_FORWARD_DECLARE_CLASS(TaskInfo)
|
||||
QT_FORWARD_DECLARE_CLASS(TaskManager)
|
||||
|
||||
struct TaskRow {
|
||||
bool enabled = false;
|
||||
int intervalHours = 0;
|
||||
};
|
||||
|
||||
class TaskListModel : public TableItemModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
enum Roles {
|
||||
RoleEnabled = Qt::UserRole,
|
||||
RoleIntervalHours,
|
||||
RoleRunning
|
||||
};
|
||||
Q_ENUM(Roles)
|
||||
|
||||
explicit TaskListModel(TaskManager *taskManager,
|
||||
QObject *parent = nullptr);
|
||||
~TaskListModel() override;
|
||||
|
||||
TaskManager *taskManager() const { return m_taskManager; }
|
||||
|
||||
const QList<TaskInfo *> &taskInfosList() const;
|
||||
TaskInfo *taskInfoAt(int index) const;
|
||||
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||
int columnCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||
|
||||
QVariant headerData(int section, Qt::Orientation orientation,
|
||||
int role = Qt::DisplayRole) const override;
|
||||
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
||||
bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override;
|
||||
|
||||
Qt::ItemFlags flags(const QModelIndex &index) const override;
|
||||
|
||||
public slots:
|
||||
void resetEdited();
|
||||
|
||||
void saveChanges();
|
||||
|
||||
private:
|
||||
void setupTaskRows();
|
||||
void clearTaskRows();
|
||||
|
||||
bool taskEnabled(int index) const;
|
||||
void setTaskEnabled(const QModelIndex &index, bool v);
|
||||
|
||||
int taskIntervalHours(int index) const;
|
||||
void setTaskIntervalHours(const QModelIndex &index, int v);
|
||||
|
||||
TaskRow *addTaskRow(int index);
|
||||
|
||||
TaskRow *taskRowAt(int index) const;
|
||||
|
||||
static QString formatDateTime(const QDateTime &dateTime);
|
||||
|
||||
private:
|
||||
TaskManager *m_taskManager = nullptr;
|
||||
|
||||
mutable QList<TaskRow *> m_taskRows;
|
||||
};
|
||||
|
||||
#endif // TASKLISTMODEL_H
|
@ -6,7 +6,6 @@
|
||||
#include "../util/dateutil.h"
|
||||
#include "taskinfotasix.h"
|
||||
#include "taskinfoupdatechecker.h"
|
||||
#include "taskworker.h"
|
||||
|
||||
TaskManager::TaskManager(FortManager *fortManager,
|
||||
QObject *parent) :
|
||||
@ -18,8 +17,17 @@ TaskManager::TaskManager(FortManager *fortManager,
|
||||
|
||||
m_timer.setSingleShot(true);
|
||||
|
||||
connect(&m_timer, &QTimer::timeout,
|
||||
this, &TaskManager::runExpiredTasks);
|
||||
connect(&m_timer, &QTimer::timeout, this, &TaskManager::runExpiredTasks);
|
||||
}
|
||||
|
||||
FortSettings *TaskManager::settings() const
|
||||
{
|
||||
return fortManager()->settings();
|
||||
}
|
||||
|
||||
ConfManager *TaskManager::confManager() const
|
||||
{
|
||||
return fortManager()->confManager();
|
||||
}
|
||||
|
||||
void TaskManager::setupTasks()
|
||||
@ -32,17 +40,16 @@ void TaskManager::setupTasks()
|
||||
|
||||
void TaskManager::appendTaskInfo(TaskInfo *taskInfo)
|
||||
{
|
||||
connect(taskInfo, &TaskInfo::workFinished,
|
||||
this, &TaskManager::handleTaskFinished);
|
||||
connect(taskInfo, &TaskInfo::workStarted, this, &TaskManager::handleTaskStarted);
|
||||
connect(taskInfo, &TaskInfo::workFinished, this, &TaskManager::handleTaskFinished);
|
||||
|
||||
m_taskInfos.append(taskInfo);
|
||||
}
|
||||
|
||||
void TaskManager::loadSettings(const FortSettings *fortSettings,
|
||||
ConfManager *confManager)
|
||||
void TaskManager::loadSettings()
|
||||
{
|
||||
if (!confManager->loadTasks(m_taskInfos)) {
|
||||
const TasksMap tasksMap = fortSettings->tasks();
|
||||
if (!confManager()->loadTasks(m_taskInfos)) {
|
||||
const TasksMap tasksMap = settings()->tasks();
|
||||
if (!tasksMap.isEmpty()) {
|
||||
for (TaskInfo *taskInfo : m_taskInfos) {
|
||||
const QByteArray taskData = tasksMap.value(taskInfo->name());
|
||||
@ -56,26 +63,33 @@ void TaskManager::loadSettings(const FortSettings *fortSettings,
|
||||
runExpiredTasks();
|
||||
}
|
||||
|
||||
bool TaskManager::saveSettings(FortSettings *fortSettings,
|
||||
ConfManager *confManager)
|
||||
bool TaskManager::saveSettings()
|
||||
{
|
||||
runExpiredTasks();
|
||||
|
||||
if (!confManager->saveTasks(m_taskInfos))
|
||||
if (!confManager()->saveTasks(m_taskInfos))
|
||||
return false;
|
||||
|
||||
fortSettings->removeTasks();
|
||||
settings()->removeTasks();
|
||||
return true;
|
||||
}
|
||||
|
||||
void TaskManager::handleTaskStarted()
|
||||
{
|
||||
auto taskInfo = qobject_cast<TaskInfo *>(sender());
|
||||
|
||||
emit taskStarted(taskInfo);
|
||||
}
|
||||
|
||||
void TaskManager::handleTaskFinished(bool success)
|
||||
{
|
||||
auto taskInfo = qobject_cast<TaskInfo *>(sender());
|
||||
|
||||
taskInfo->processResult(m_fortManager, success);
|
||||
|
||||
saveSettings(m_fortManager->settings(),
|
||||
m_fortManager->confManager());
|
||||
saveSettings();
|
||||
|
||||
emit taskFinished(taskInfo);
|
||||
}
|
||||
|
||||
void TaskManager::runExpiredTasks()
|
||||
|
@ -21,6 +21,8 @@ public:
|
||||
QObject *parent = nullptr);
|
||||
|
||||
FortManager *fortManager() const { return m_fortManager; }
|
||||
FortSettings *settings() const;
|
||||
ConfManager *confManager() const;
|
||||
|
||||
TaskInfoUpdateChecker *taskInfoUpdateChecker() const { return m_taskInfoUpdateChecker; }
|
||||
|
||||
@ -29,11 +31,15 @@ public:
|
||||
signals:
|
||||
void taskInfosChanged();
|
||||
|
||||
void taskStarted(TaskInfo *taskInfo);
|
||||
void taskFinished(TaskInfo *taskInfo);
|
||||
|
||||
public slots:
|
||||
void loadSettings(const FortSettings *fortSettings, ConfManager *confManager);
|
||||
bool saveSettings(FortSettings *fortSettings, ConfManager *confManager);
|
||||
void loadSettings();
|
||||
bool saveSettings();
|
||||
|
||||
private slots:
|
||||
void handleTaskStarted();
|
||||
void handleTaskFinished(bool success);
|
||||
|
||||
void runExpiredTasks();
|
||||
|
@ -62,6 +62,14 @@ void StringListModel::replace(const QString &text, int row)
|
||||
emit dataChanged(modelIndex, modelIndex);
|
||||
}
|
||||
|
||||
void StringListModel::refresh()
|
||||
{
|
||||
const auto firstCell = index(0, 0);
|
||||
const auto lastCell = index(rowCount() - 1, 0);
|
||||
|
||||
emit dataChanged(firstCell, lastCell);
|
||||
}
|
||||
|
||||
void StringListModel::removeRow(int row)
|
||||
{
|
||||
m_list.removeAt(row);
|
@ -30,6 +30,7 @@ public slots:
|
||||
beginResetModel();
|
||||
endResetModel();
|
||||
}
|
||||
void refresh();
|
||||
|
||||
protected:
|
||||
void removeRow(int row);
|
47
src/ui/util/model/tableitemmodel.cpp
Normal file
47
src/ui/util/model/tableitemmodel.cpp
Normal file
@ -0,0 +1,47 @@
|
||||
#include "tableitemmodel.h"
|
||||
|
||||
TableItemModel::TableItemModel(QObject *parent) :
|
||||
QAbstractItemModel(parent)
|
||||
{
|
||||
}
|
||||
|
||||
QModelIndex TableItemModel::index(int row, int column, const QModelIndex &parent) const
|
||||
{
|
||||
return hasIndex(row, column, parent)
|
||||
? createIndex(row, column) : QModelIndex();
|
||||
}
|
||||
|
||||
QModelIndex TableItemModel::parent(const QModelIndex &child) const
|
||||
{
|
||||
Q_UNUSED(child)
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
QModelIndex TableItemModel::sibling(int row, int column, const QModelIndex &index) const
|
||||
{
|
||||
Q_UNUSED(index)
|
||||
|
||||
return this->index(row, column);
|
||||
}
|
||||
|
||||
bool TableItemModel::hasChildren(const QModelIndex &parent) const
|
||||
{
|
||||
return !parent.isValid() && rowCount() > 0;
|
||||
}
|
||||
|
||||
Qt::ItemFlags TableItemModel::flags(const QModelIndex &index) const
|
||||
{
|
||||
if (!index.isValid())
|
||||
return Qt::NoItemFlags;
|
||||
|
||||
return Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemNeverHasChildren;
|
||||
}
|
||||
|
||||
void TableItemModel::refresh()
|
||||
{
|
||||
const auto firstCell = index(0, 0);
|
||||
const auto lastCell = index(rowCount() - 1, columnCount(firstCell) - 1);
|
||||
|
||||
emit dataChanged(firstCell, lastCell);
|
||||
}
|
31
src/ui/util/model/tableitemmodel.h
Normal file
31
src/ui/util/model/tableitemmodel.h
Normal file
@ -0,0 +1,31 @@
|
||||
#ifndef TABLEITEMMODEL_H
|
||||
#define TABLEITEMMODEL_H
|
||||
|
||||
#include <QAbstractItemModel>
|
||||
|
||||
class TableItemModel : public QAbstractItemModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit TableItemModel(QObject *parent = nullptr);
|
||||
|
||||
QModelIndex index(int row, int column,
|
||||
const QModelIndex &parent = QModelIndex()) const override;
|
||||
QModelIndex parent(const QModelIndex &child) const override;
|
||||
|
||||
QModelIndex sibling(int row, int column,
|
||||
const QModelIndex &index) const override;
|
||||
bool hasChildren(const QModelIndex &parent = QModelIndex()) const override;
|
||||
|
||||
Qt::ItemFlags flags(const QModelIndex &index) const override;
|
||||
|
||||
public slots:
|
||||
void reset() {
|
||||
beginResetModel();
|
||||
endResetModel();
|
||||
}
|
||||
void refresh();
|
||||
};
|
||||
|
||||
#endif // TABLEITEMMODEL_H
|
Loading…
Reference in New Issue
Block a user