/
waterstone
/
TaskList_Demo
Обзор
Документация
Войти
/
waterstone
/
TaskList_Demo
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
src/tasklist_main_view.cpp
370 строк
11 KB
Peter Sakhno
Model code review
21 янв 2026, 16:07
21 янв 2026, 16:07
a4bb872
Код
Авторство
О чём код?
#include "tasklist_main_view.h" #include <QPointer> #include <QMessageBox> #include <QInputDialog> #include <QApplication> #include <QStyleFactory> #include "ui_tasklist_main_view.h" #include "tasklist_table_model.h" #include "tasklist_proxy_table_model.h" #include "tasklist_action_cell_delegate.h" #include "tasklist_progress_cell_delegate.h" namespace { TaskListProxyTableModelQP GetProxyModel(QPointer<QTableView> table_view) { if (!table_view) return {}; return qobject_cast<TaskListProxyTableModel*>(table_view->model()); } TaskListTableModelQP GetSourceModel(QPointer<QTableView> table_view) { TaskListProxyTableModelQP proxy_model = GetProxyModel(table_view); if (!proxy_model) return {}; return qobject_cast<TaskListTableModel*>(proxy_model->sourceModel()); } void GetRowsFromSelection(const QItemSelection& selection, std::set<int>& out) { for (const auto& range : selection) { if (!range.isEmpty()) { for (int row = range.top(); row <= range.bottom(); row++) out.insert(row); } } } } TaskListMainView::TaskListMainView (QWidget *parent) : QWidget (parent), m_ui (new Ui::TaskListMainView) { QObject::connect(QApplication::instance(), &QApplication::aboutToQuit, this, &TaskListMainView::OnAppAboutToQuit); m_ui->setupUi(this); { const QString defaultStyleName = QApplication::style()->objectName(); QStringList styleNames = QStyleFactory::keys(); for (int i = 1, size = styleNames.size(); i < size; ++i) { if (defaultStyleName.compare(styleNames.at(i), Qt::CaseInsensitive) == 0) { styleNames.swapItemsAt(0, i); break; } } m_ui->selectStyle->addItems(styleNames); } auto proxy_model = new TaskListProxyTableModel(this); proxy_model->setSourceModel(new TaskListTableModel(this)); m_ui->tableTaskList->setModel(proxy_model); m_ui->tableTaskList->setItemDelegateForColumn( TaskListTableModel::ActionColumn, new TaskListActionCellDelegate(this)); m_ui->tableTaskList->setItemDelegateForColumn( TaskListTableModel::ProgressColumn, new TaskListProgressCellDelegate(this)); m_ui->tableTaskList->setMouseTracking(true); QPointer<QItemSelectionModel> sel = m_ui->tableTaskList->selectionModel(); if (sel) { QObject::connect(sel, &QItemSelectionModel::selectionChanged, this, &TaskListMainView::OnTableSelectionChanged); } QPointer<QHeaderView> hv = m_ui->tableTaskList->horizontalHeader(); if (hv) { hv->setSortIndicatorClearable(true); hv->setSectionResizeMode(TaskListTableModel::TimestampColumn, QHeaderView::ResizeToContents); hv->setSectionResizeMode(TaskListTableModel::CaptionColumn, QHeaderView::Stretch); } UpdateTaskGroup(); UpdateFilterGroup(); UpdateSelectionGroup(); } TaskListMainView::~TaskListMainView () { } void TaskListMainView::closeEvent(QCloseEvent* event) { auto model = GetSourceModel(m_ui->tableTaskList); if (model && model->HasActiveRows()) { const auto res = QMessageBox::question(this, tr("Application quit"), tr("Some tasks may still be active") % QString("\n") % tr("It may take some time to stop all tasks") % QString("\n") % tr("Do you really want do quit?")); if (QMessageBox::Ok != res and QMessageBox::Yes != res) { event->ignore(); return; } } return QWidget::closeEvent(event); } void TaskListMainView::OnAddNewTask() { TaskListTableModelQP model = GetSourceModel(m_ui->tableTaskList); if (!model) { QMessageBox::critical(this, tr("Add new task", "message_box_caption"), tr("New task adding is not possible")); return; } bool ok{ false }; QString caption = QInputDialog::getText(this, tr("Add new task", "message_box_caption"), tr("New task caption:"), QLineEdit::Normal, model->GenerateTaskName(), &ok); if (!ok) return; model->AddTask(caption); UpdateTaskGroup(); UpdateFilterGroup(); UpdateSelectionGroup(); } void TaskListMainView::OnDeleteAllTasks() { TaskListTableModelQP model = GetSourceModel(m_ui->tableTaskList); if (!model) { QMessageBox::critical(this, tr("Delete all tasks"), tr("Deleting of all tasks is not possible")); return; } if (model->HasActiveRows()) { const auto res = QMessageBox::question(this, tr("Delete all tasks"), tr("Some tasks may still be active") % QString("\n") % tr("Do you really want do delete all tasks?")); if (QMessageBox::Ok != res and QMessageBox::Yes != res) return; } if (model->RemoveAll()) { UpdateTaskGroup(); UpdateFilterGroup(); UpdateSelectionGroup(); } } void TaskListMainView::OnDeleteSelectedTasks() { auto proxy_model = GetProxyModel(m_ui->tableTaskList); auto src_model = GetSourceModel(m_ui->tableTaskList); QPointer<QItemSelectionModel> sel = m_ui->tableTaskList->selectionModel(); if (!proxy_model or !src_model or !sel) { QMessageBox::critical(this, tr("Delete selected tasks"), tr("Deleting of selected tasks is not possible")); return; } std::set<int> selected_rows; GetRowsFromSelection(proxy_model->mapSelectionToSource(sel->selection()), selected_rows); if (selected_rows.empty()) return; if (src_model->HasActiveRows(selected_rows)) { const auto res = QMessageBox::question(this, tr("Delete selected tasks"), tr("Some of selected tasks may still be active") % QString("\n") % tr("Do you really want do delete selected tasks?")); if (QMessageBox::Ok != res and QMessageBox::Yes != res) return; } if (src_model->RemoveSelected(selected_rows)) { UpdateTaskGroup(); UpdateFilterGroup(); UpdateSelectionGroup(); } } void TaskListMainView::OnStartSelectedTasks() { auto proxy_model = GetProxyModel(m_ui->tableTaskList); auto src_model = GetSourceModel(m_ui->tableTaskList); QPointer<QItemSelectionModel> sel = m_ui->tableTaskList->selectionModel(); if (!proxy_model or !src_model or !sel) { QMessageBox::critical(this, tr("Start selected tasks"), tr("Starting of selected tasks is not possible")); return; } std::set<int> selected_rows; GetRowsFromSelection(proxy_model->mapSelectionToSource(sel->selection()), selected_rows); if (!selected_rows.empty()) src_model->ActivateSelected(selected_rows, true); } void TaskListMainView::OnStopSelectedTasks() { auto proxy_model = GetProxyModel(m_ui->tableTaskList); auto src_model = GetSourceModel(m_ui->tableTaskList); QPointer<QItemSelectionModel> sel = m_ui->tableTaskList->selectionModel(); if (!proxy_model or !src_model or !sel) { QMessageBox::critical(this, tr("Stop selected tasks"), tr("Stopping of selected tasks is not possible")); return; } std::set<int> selected_rows; GetRowsFromSelection(proxy_model->mapSelectionToSource(sel->selection()), selected_rows); if (!selected_rows.empty()) src_model->ActivateSelected(selected_rows, false); } void TaskListMainView::OnFilterChanged() { TaskListProxyTableModelQP proxy = qobject_cast<TaskListProxyTableModel*>(m_ui->tableTaskList->model()); if (!proxy) return; switch (m_ui->selectFilterMode->currentIndex()) { case TaskListMainView::NoFilter: proxy->SetRunStateFilter({}); break; case TaskListMainView::RunningFilter: proxy->SetRunStateFilter({ true }); break; case TaskListMainView::StoppedFilter: proxy->SetRunStateFilter({ false }); break; } UpdateTaskGroup(); UpdateSelectionGroup(); } void TaskListMainView::OnSelectAll() { QPointer<QAbstractItemModel> model = m_ui->tableTaskList->model(); if (!model) return; QPointer<QItemSelectionModel> sel = m_ui->tableTaskList->selectionModel(); if (!sel) return; QModelIndex top_left = model->index(0, 0); QModelIndex bottom_right = model->index(model->rowCount() - 1, model->columnCount() - 1); sel->select({ top_left, bottom_right }, QItemSelectionModel::ClearAndSelect); } void TaskListMainView::OnClearSelection() { m_ui->tableTaskList->clearSelection(); } void TaskListMainView::OnTableSelectionChanged(const QItemSelection& /*selected*/, const QItemSelection& /*deselected*/) { UpdateSelectedTasksGroup(); UpdateSelectionGroup(); } void TaskListMainView::OnTableCellClicked(const QModelIndex& proxy_index) { if (!proxy_index.isValid()) return; auto proxy_model = GetProxyModel(m_ui->tableTaskList); if (!proxy_model) return; QModelIndex src_index = proxy_model->mapToSource(proxy_index); if (!src_index.isValid()) return; if (src_index.column() != TaskListTableModel::ActionColumn) return; TaskListTableModelQP src_model = qobject_cast<TaskListTableModel*>(proxy_model->sourceModel()); if (!src_model) return; const QVariant var = src_index.data(Qt::UserRole); if (var.userType() != QMetaType::Bool) return; const bool current_state = var.toBool(); const bool switch_task_state_res = src_model->setData(src_index, !current_state); if (!switch_task_state_res) { QMessageBox::critical(this, tr("Switch task"), tr("Failed to switch task state")); } UpdateTaskGroup(); UpdateSelectionGroup(); } void TaskListMainView::OnAppAboutToQuit() { auto model = GetSourceModel(m_ui->tableTaskList); if (!model) return; if (!model->HasActiveRows()) return; QGuiApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); model->StopAllTasks(); QGuiApplication::restoreOverrideCursor(); } void TaskListMainView::OnSelectStyle(const QString& style_name) { QApplication::setStyle(QStyleFactory::create(style_name)); } void TaskListMainView::UpdateTaskGroup() { auto src_model = GetSourceModel(m_ui->tableTaskList); m_ui->buttonAddNewTask->setEnabled(src_model); m_ui->buttonDeleteAll->setEnabled(src_model and src_model->rowCount() > 0); UpdateSelectedTasksGroup(); } void TaskListMainView::UpdateSelectedTasksGroup() { QPointer<QItemSelectionModel> sel = m_ui->tableTaskList->selectionModel(); m_ui->buttonDeleteSelectedTasks->setEnabled(sel and !sel->selectedIndexes().empty()); m_ui->buttonStartSelectedTasks->setEnabled(sel and !sel->selectedIndexes().empty()); m_ui->buttonStopSelectedTasks->setEnabled(sel and !sel->selectedIndexes().empty()); } void TaskListMainView::UpdateFilterGroup() { auto src_model = GetSourceModel(m_ui->tableTaskList); const bool enable = src_model and src_model->rowCount() > 0; m_ui->selectFilterMode->setEnabled(enable); } void TaskListMainView::UpdateSelectionGroup() { int model_row_count = 0; QPointer<QAbstractItemModel> model = m_ui->tableTaskList->model(); if (model) model_row_count = model->rowCount(); const bool filled = (model and model_row_count != 0); QPointer<QItemSelectionModel> sel = m_ui->tableTaskList->selectionModel(); QItemSelection selection; if (sel) selection = sel->selection(); m_ui->buttonUnselectAll->setEnabled(filled and !selection.isEmpty()); int selected_rows = 0; for (const auto& r : selection) selected_rows += r.height(); m_ui->buttonSelectAll->setEnabled(filled and model_row_count > selected_rows); }