From 0704012542ff54ca6f1c8956f3baac1f3822edf6 Mon Sep 17 00:00:00 2001 From: 0xFEEDC0DE64 Date: Sun, 7 Apr 2019 18:20:01 +0200 Subject: [PATCH] Larger improvements --- common.h | 11 ++ dialogs/opendialog.cpp | 70 +++++++++++- dialogs/opendialog.h | 6 +- loganalyzer.pro | 9 +- mainwindow.cpp | 24 ++-- mainwindow.h | 8 +- mainwindow.ui | 5 +- models/checklistmodel.cpp | 167 +++++++++++++++++----------- models/checklistmodel.h | 31 ++++-- models/logmodel.cpp | 14 +++ models/logmodel.h | 13 +++ models/progressmodel.cpp | 148 ++++++++++++++++++++++++ models/progressmodel.h | 59 ++++++++++ models/sqlrelationaltablemodel.cpp | 14 --- models/sqlrelationaltablemodel.h | 13 --- threads/tablecreatorthread.cpp | 1 + widgets/databasewidget.cpp | 19 ++-- wizard/localimportpage.cpp | 2 +- wizard/remoteimportoverviewpage.cpp | 4 +- wizard/tablespage.cpp | 70 ++++++------ wizard/tablespage.h | 16 +-- wizard/tablespage.ui | 34 ++++++ 22 files changed, 553 insertions(+), 185 deletions(-) create mode 100644 models/logmodel.cpp create mode 100644 models/logmodel.h create mode 100644 models/progressmodel.cpp create mode 100644 models/progressmodel.h delete mode 100644 models/sqlrelationaltablemodel.cpp delete mode 100644 models/sqlrelationaltablemodel.h create mode 100644 wizard/tablespage.ui diff --git a/common.h b/common.h index 27efad1..f603110 100644 --- a/common.h +++ b/common.h @@ -5,6 +5,8 @@ #include #include #include +#include +#include #include @@ -28,3 +30,12 @@ inline bool scanResultEmpty(const ScanResult &result) }); }); } + +struct Project { + QMap hosts; + QMap processes; + QMap filenames; + QMap threads; + QMap types; + QSqlDatabase database; +}; diff --git a/dialogs/opendialog.cpp b/dialogs/opendialog.cpp index 086b3a1..b55f26c 100644 --- a/dialogs/opendialog.cpp +++ b/dialogs/opendialog.cpp @@ -4,6 +4,7 @@ #include #include #include +#include OpenDialog::OpenDialog(QWidget *parent) : QDialog(parent), @@ -16,21 +17,78 @@ OpenDialog::OpenDialog(QWidget *parent) : OpenDialog::~OpenDialog() = default; -QSqlDatabase OpenDialog::database() +std::unique_ptr &OpenDialog::project() { - return m_database; + return m_project; } void OpenDialog::submit() { - m_database = m_ui->databaseWidget->createConnection(); + auto project = std::make_unique(); + project->database = m_ui->databaseWidget->createConnection(); - if (!m_database.open()) + if (!project->database.open()) { - QMessageBox::warning(this, tr("Could not open database!"), tr("Could not open database!") % "\n\n" % m_database.lastError().text()); - m_database = {}; + QMessageBox::warning(this, tr("Could not open database!"), tr("Could not open database!") % "\n\n" % project->database.lastError().text()); return; } + { + QSqlQuery query("SELECT `ID`, `Name` FROM `Hosts`;", project->database); + if (query.lastError().isValid()) + { + QMessageBox::warning(this, tr("Could not open database!"), tr("Could not open database!") % "\n\n" % query.lastError().text()); + return; + } + while(query.next()) + project->hosts.insert(query.value(0).toInt(), query.value(1).toString()); + } + + { + QSqlQuery query("SELECT `ID`, `Name` FROM `Processes`;", project->database); + if (query.lastError().isValid()) + { + QMessageBox::warning(this, tr("Could not open database!"), tr("Could not open database!") % "\n\n" % query.lastError().text()); + return; + } + while(query.next()) + project->processes.insert(query.value(0).toInt(), query.value(1).toString()); + } + + { + QSqlQuery query("SELECT `ID`, `Name` FROM `Filenames`;", project->database); + if (query.lastError().isValid()) + { + QMessageBox::warning(this, tr("Could not open database!"), tr("Could not open database!") % "\n\n" % query.lastError().text()); + return; + } + while(query.next()) + project->filenames.insert(query.value(0).toInt(), query.value(1).toString()); + } + + { + QSqlQuery query("SELECT `ID`, `Name` FROM `Threads`;", project->database); + if (query.lastError().isValid()) + { + QMessageBox::warning(this, tr("Could not open database!"), tr("Could not open database!") % "\n\n" % query.lastError().text()); + return; + } + while(query.next()) + project->threads.insert(query.value(0).toInt(), query.value(1).toString()); + } + + { + QSqlQuery query("SELECT `ID`, `Name` FROM `Types`;", project->database); + if (query.lastError().isValid()) + { + QMessageBox::warning(this, tr("Could not open database!"), tr("Could not open database!") % "\n\n" % query.lastError().text()); + return; + } + while(query.next()) + project->types.insert(query.value(0).toInt(), query.value(1).toString()); + } + + m_project = std::move(project); + accept(); } diff --git a/dialogs/opendialog.h b/dialogs/opendialog.h index afa94b4..0df4e26 100644 --- a/dialogs/opendialog.h +++ b/dialogs/opendialog.h @@ -5,6 +5,8 @@ #include +#include "common.h" + namespace Ui { class OpenDialog; } class OpenDialog : public QDialog @@ -15,7 +17,7 @@ public: explicit OpenDialog(QWidget *parent = nullptr); ~OpenDialog() override; - QSqlDatabase database(); + std::unique_ptr &project(); private slots: void submit(); @@ -23,5 +25,5 @@ private slots: private: const std::unique_ptr m_ui; - QSqlDatabase m_database; + std::unique_ptr m_project; }; diff --git a/loganalyzer.pro b/loganalyzer.pro index cf8e3f6..6a3fa9f 100644 --- a/loganalyzer.pro +++ b/loganalyzer.pro @@ -37,7 +37,8 @@ SOURCES += main.cpp \ widgets/databasewidget.cpp \ gzipdevice.cpp \ dialogs/graphdialog.cpp \ - models/sqlrelationaltablemodel.cpp + models/logmodel.cpp \ + models/progressmodel.cpp HEADERS += \ mainwindow.h \ @@ -61,7 +62,8 @@ HEADERS += \ widgets/databasewidget.h \ gzipdevice.h \ dialogs/graphdialog.h \ - models/sqlrelationaltablemodel.h + models/logmodel.h \ + models/progressmodel.h FORMS += \ mainwindow.ui \ @@ -70,7 +72,8 @@ FORMS += \ widgets/databasewidget.ui \ wizard/intropage.ui \ wizard/databasepage.ui \ - dialogs/graphdialog.ui + dialogs/graphdialog.ui \ + wizard/tablespage.ui RESOURCES += \ resources.qrc diff --git a/mainwindow.cpp b/mainwindow.cpp index 7e0ed99..2cc1441 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -3,17 +3,16 @@ #include #include -#include #include #include #include #include #include -#include #include "wizard/importwizard.h" #include "dialogs/opendialog.h" #include "dialogs/graphdialog.h" +#include "models/logmodel.h" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), @@ -38,6 +37,10 @@ MainWindow::MainWindow(QWidget *parent) : connect(m_ui->pushButton, &QPushButton::pressed, this, &MainWindow::updateQuery); connect(m_ui->tableView, &QWidget::customContextMenuRequested, this, &MainWindow::showContextMenu); + + m_ui->tableView->horizontalHeader()->setSectionsClickable(true); + QObject::connect(m_ui->tableView->horizontalHeader(), &QHeaderView::sectionClicked, [this](int index){ + }); } MainWindow::~MainWindow() = default; @@ -54,7 +57,7 @@ void MainWindow::newClicked() m_ui->lineEdit->setEnabled(true); m_ui->pushButton->setEnabled(true); - m_database = wizard.database(); + //m_project->database = wizard.database(); setupModel(); } } @@ -71,7 +74,7 @@ void MainWindow::openClicked() m_ui->lineEdit->setEnabled(true); m_ui->pushButton->setEnabled(true); - m_database = dialog.database(); + m_project = std::move(dialog.project()); setupModel(); } } @@ -87,13 +90,12 @@ void MainWindow::closeClicked() m_ui->tableView->setModel(nullptr); m_model = nullptr; - m_database.close(); - m_database = QSqlDatabase(); + m_project = nullptr; } void MainWindow::graphClicked() { - GraphDialog(m_database, this).exec(); + GraphDialog(m_project->database, this).exec(); } void MainWindow::updateQuery() @@ -138,9 +140,11 @@ void MainWindow::updateQuery() } sql.append("ORDER BY " - "`Logs`.`Timestamp` ASC;"); + "`Logs`.`Timestamp` ASC " + "LIMIT " + "0, 100;"); - QSqlQuery query(sql, m_database); + QSqlQuery query(sql, m_project->database); if (query.lastError().isValid()) { @@ -237,7 +241,7 @@ void MainWindow::showContextMenu(const QPoint &pos) void MainWindow::setupModel() { m_ui->tableView->setModel(nullptr); - m_model = std::make_unique(this); + m_model = std::make_unique(this); updateQuery(); m_ui->tableView->setModel(m_model.get()); m_ui->tableView->setColumnHidden(ColumnID, true); diff --git a/mainwindow.h b/mainwindow.h index d9f0f90..93f0c16 100644 --- a/mainwindow.h +++ b/mainwindow.h @@ -5,7 +5,9 @@ #include -class QSqlQueryModel; +#include "common.h" + +class LogModel; namespace Ui { class MainWindow; } @@ -33,6 +35,6 @@ private: const std::unique_ptr m_ui; - QSqlDatabase m_database; - std::unique_ptr m_model; + std::unique_ptr m_project; + std::unique_ptr m_model; }; diff --git a/mainwindow.ui b/mainwindow.ui index 0075381..3419d21 100644 --- a/mainwindow.ui +++ b/mainwindow.ui @@ -50,6 +50,9 @@ QAbstractItemView::NoEditTriggers + + QAbstractItemView::NoSelection + false @@ -66,7 +69,7 @@ 0 0 965 - 18 + 20 diff --git a/models/checklistmodel.cpp b/models/checklistmodel.cpp index dc451a4..7b0633c 100644 --- a/models/checklistmodel.cpp +++ b/models/checklistmodel.cpp @@ -9,23 +9,27 @@ ChecklistModel::ChecklistModel(const QStringList &items, QObject *parent) : QAbstractListModel(parent) { for (const auto &item : items) - m_items.append(std::make_pair(item, true)); + m_items.append({ item, item, true }); } -ChecklistModel::ChecklistModel(const QList > &items, QObject *parent) : +ChecklistModel::ChecklistModel(const QList &items, QObject *parent) : QAbstractListModel(parent), m_items(items) { } -QStringList ChecklistModel::items() const +const QList &ChecklistModel::items() const { - QStringList items; + return m_items; +} - for (const auto &pair : m_items) - items.append(std::get<0>(pair)); +void ChecklistModel::setItems(const QList &items) +{ + emit beginResetModel(); - return items; + m_items = items; + + emit endResetModel(); } void ChecklistModel::setItems(const QStringList &items) @@ -35,38 +39,93 @@ void ChecklistModel::setItems(const QStringList &items) m_items.clear(); for (const auto &item : items) - m_items.append(std::make_pair(item, true)); + m_items.append({ item, item, true }); emit endResetModel(); } -void ChecklistModel::setItems(const QList > &items) -{ - emit beginResetModel(); - - m_items = items; - - emit endResetModel(); -} - -QStringList ChecklistModel::enabledItems() const +QStringList ChecklistModel::itemTexts() const { QStringList items; - for (const auto &pair : m_items) - if (std::get<1>(pair)) - items.append(std::get<0>(pair)); + for (const auto &item : m_items) + items.append(item.displayText); return items; } -QStringList ChecklistModel::disabledItems() const +QVariantList ChecklistModel::itemDatas() const +{ + QVariantList items; + + for (const auto &item : m_items) + items.append(item.data); + + return items; +} + +QList ChecklistModel::enabledItems() const +{ + QList items; + + for (const auto &item : m_items) + if (item.checked) + items.append(item); + + return items; +} + +QList ChecklistModel::disabledItems() const +{ + QList items; + + for (const auto &item : m_items) + if (!item.checked) + items.append(item); + + return items; +} + +QStringList ChecklistModel::enabledTexts() const { QStringList items; - for (const auto &pair : m_items) - if (!std::get<1>(pair)) - items.append(std::get<0>(pair)); + for (const auto &item : m_items) + if (item.checked) + items.append(item.displayText); + + return items; +} + +QStringList ChecklistModel::disabledTexts() const +{ + QStringList items; + + for (const auto &item : m_items) + if (!item.checked) + items.append(item.displayText); + + return items; +} + +QVariantList ChecklistModel::enabledItemDatas() const +{ + QVariantList items; + + for (const auto &item : m_items) + if (item.checked) + items.append(item.data); + + return items; +} + +QVariantList ChecklistModel::disabledItemDatas() const +{ + QVariantList items; + + for (const auto &item : m_items) + if (!item.checked) + items.append(item.data); return items; } @@ -75,57 +134,38 @@ int ChecklistModel::rowCount(const QModelIndex &parent) const { if (parent.isValid()) return 0; + return m_items.count(); } -QModelIndex ChecklistModel::sibling(int row, int column, const QModelIndex &idx) const -{ - if (!idx.isValid() || column != 0 || row >= m_items.count() || row < 0) - return QModelIndex(); - return createIndex(row, 0); -} - -QMap ChecklistModel::itemData(const QModelIndex &index) const -{ - if (!checkIndex(index, CheckIndexOption::IndexIsValid | CheckIndexOption::ParentIsInvalid)) - return QMap{}; - const auto &item = m_items.at(index.row()); - return QMap{{ - std::make_pair(Qt::DisplayRole, std::get<0>(item)), - std::make_pair(Qt::EditRole, std::get<0>(item)), - std::make_pair(Qt::CheckStateRole, std::get<1>(item) ? Qt::Checked : Qt::Unchecked) - }}; -} - -bool ChecklistModel::setItemData(const QModelIndex &index, const QMap &roles) -{ - if (roles.isEmpty()) - return false; - if (std::any_of(roles.keyBegin(), roles.keyEnd(), [](int role) { return role != Qt::CheckStateRole; })) - return false; - auto roleIter = roles.constFind(Qt::CheckStateRole); - Q_ASSERT(roleIter != roles.constEnd()); - return setData(index, roleIter.value(), roleIter.key()); -} - QVariant ChecklistModel::data(const QModelIndex &index, int role) const { if (index.row() < 0 || index.row() >= m_items.size()) - return QVariant(); + return {}; + const auto &item = m_items.at(index.row()); - if (role == Qt::DisplayRole || role == Qt::EditRole) - return std::get<0>(item); - if (role == Qt::CheckStateRole) - return std::get<1>(item) ? Qt::Checked : Qt::Unchecked; + + switch (role) + { + case Qt::DisplayRole: return item.displayText; + case Qt::EditRole: return item.data; + case Qt::CheckStateRole: return item.checked ? Qt::Checked : Qt::Unchecked; + } + return QVariant(); } bool ChecklistModel::setData(const QModelIndex &index, const QVariant &value, int role) { - if (index.row() >= 0 && index.row() < m_items.size() && role == Qt::CheckStateRole) + if (index.row() < 0 || index.row() >= m_items.size()) + return false; + + auto &item = m_items[index.row()]; + + switch (role) { - auto &item = m_items[index.row()]; - std::get<1>(item) = value.toBool(); + case Qt::CheckStateRole: + item.checked = value.toBool(); emit dataChanged(index, index, { Qt::CheckStateRole }); return true; } @@ -137,5 +177,6 @@ Qt::ItemFlags ChecklistModel::flags(const QModelIndex &index) const { if (!index.isValid()) return QAbstractListModel::flags(index); + return QAbstractListModel::flags(index) | Qt::ItemIsUserCheckable; } diff --git a/models/checklistmodel.h b/models/checklistmodel.h index f75401f..6a1fd2b 100644 --- a/models/checklistmodel.h +++ b/models/checklistmodel.h @@ -3,31 +3,40 @@ #include #include -#include - class Q_CORE_EXPORT ChecklistModel : public QAbstractListModel { Q_OBJECT public: + struct ChecklistItem + { + QString displayText; + QVariant data; + bool checked; + }; + explicit ChecklistModel(QObject *parent = nullptr); explicit ChecklistModel(const QStringList &items, QObject *parent = nullptr); - explicit ChecklistModel(const QList > &strings, QObject *parent = nullptr); + explicit ChecklistModel(const QList &strings, QObject *parent = nullptr); - QStringList items() const; + const QList &items() const; + void setItems(const QList &items); void setItems(const QStringList &items); - void setItems(const QList > &items); - QStringList enabledItems() const; - QStringList disabledItems() const; + + QStringList itemTexts() const; + QVariantList itemDatas() const; + QList enabledItems() const; + QList disabledItems() const; + QStringList enabledTexts() const; + QStringList disabledTexts() const; + QVariantList enabledItemDatas() const; + QVariantList disabledItemDatas() const; int rowCount(const QModelIndex &parent = QModelIndex()) const override; - QModelIndex sibling(int row, int column, const QModelIndex &idx) const override; - QMap itemData(const QModelIndex &index) const override; - bool setItemData(const QModelIndex &index, const QMap &roles) override; QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; bool setData(const QModelIndex &index, const QVariant &value, int role) override; Qt::ItemFlags flags(const QModelIndex &index) const override; private: - QList > m_items; + QList m_items; }; diff --git a/models/logmodel.cpp b/models/logmodel.cpp new file mode 100644 index 0000000..0177faa --- /dev/null +++ b/models/logmodel.cpp @@ -0,0 +1,14 @@ +#include "logmodel.h" + +LogModel::LogModel(QObject *parent) : + QSqlQueryModel(parent) +{ +} + +QVariant LogModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + if (orientation == Qt::Vertical) + return {}; + + return QSqlQueryModel::headerData(section, orientation, role); +} diff --git a/models/logmodel.h b/models/logmodel.h new file mode 100644 index 0000000..613520d --- /dev/null +++ b/models/logmodel.h @@ -0,0 +1,13 @@ +#pragma once + +#include + +class LogModel : public QSqlQueryModel +{ + Q_OBJECT + +public: + explicit LogModel(QObject *parent = nullptr); + + QVariant headerData(int section, Qt::Orientation orientation, int role) const override; +}; diff --git a/models/progressmodel.cpp b/models/progressmodel.cpp new file mode 100644 index 0000000..80d0d34 --- /dev/null +++ b/models/progressmodel.cpp @@ -0,0 +1,148 @@ +#include "progressmodel.h" + +#include + +#include + +ProgressModel::ProgressModel(QObject *parent) : + QAbstractListModel(parent) +{ + connect(&m_movieLoading, &QMovie::frameChanged, this, &ProgressModel::frameChanged); +} + +ProgressModel::ProgressModel(const QStringList &items, QObject *parent) : + QAbstractListModel(parent) +{ + connect(&m_movieLoading, &QMovie::frameChanged, this, &ProgressModel::frameChanged); + + m_items.reserve(items.count()); + for (const auto &item : items) + m_items.append({ item, Item::Status::None }); +} + +ProgressModel::ProgressModel(const QVector &items, QObject *parent) : + QAbstractListModel(parent), + m_items(items) +{ + connect(&m_movieLoading, &QMovie::frameChanged, this, &ProgressModel::frameChanged); + + if (anyLoading()) + m_movieLoading.start(); +} + +const QVector &ProgressModel::items() const +{ + return m_items; +} + +void ProgressModel::setItems(const QStringList &items) +{ + emit beginResetModel(); + m_items.clear(); + m_items.reserve(items.count()); + for (const auto &item : items) + m_items.append({ item, Item::Status::None }); + emit endResetModel(); + + m_movieLoading.stop(); +} + +void ProgressModel::setItems(const QVector &items) +{ + emit beginResetModel(); + m_items = items; + emit endResetModel(); + + updateMovieStatus(); +} + +void ProgressModel::setText(int row, const QString &text) +{ + m_items[row].text = text; + + const auto index = createIndex(row, 0); + emit dataChanged(index, index, { Qt::DisplayRole, Qt::EditRole }); +} + +void ProgressModel::setStatus(int row, ProgressModel::Item::Status status) +{ + m_items[row].status = status; + + const auto index = createIndex(row, 0); + emit dataChanged(index, index, { Qt::DecorationRole }); + + if (status == Item::Status::Loading) + m_movieLoading.start(); + else + updateMovieStatus(); +} + +void ProgressModel::clearItems() +{ + emit beginResetModel(); + m_items.clear(); + emit endResetModel(); + + m_movieLoading.stop(); +} + +int ProgressModel::rowCount(const QModelIndex &parent) const +{ + if (parent.isValid()) + return 0; + + return m_items.count(); +} + +QVariant ProgressModel::data(const QModelIndex &index, int role) const +{ + if (index.row() < 0 || index.row() >= m_items.size()) + return {}; + + const auto &item = m_items.at(index.row()); + + switch (role) { + case Qt::DisplayRole: + case Qt::EditRole: + return item.text; + case Qt::DecorationRole: + switch (item.status) + { + case Item::Status::None: + return m_pixmapEmpty; + case Item::Status::Loading: + return m_movieLoading.currentPixmap(); + case Item::Status::Succeeded: + return m_pixmapSucceeded; + case Item::Status::Failed: + return m_pixmapFailed; + } + } + + return {}; +} + +void ProgressModel::frameChanged() +{ + for (auto iter = m_items.constBegin(); iter != m_items.constEnd(); iter++) + { + if (iter->status == Item::Status::Loading) + { + const auto index = createIndex(std::distance(m_items.constBegin(), iter), 0); + emit dataChanged(index, index, { Qt::DecorationRole }); + } + } +} + +bool ProgressModel::anyLoading() const +{ + return std::any_of(m_items.constBegin(), m_items.constEnd(), [](const auto &item){ return item.status == Item::Status::Loading; }); +} + +void ProgressModel::updateMovieStatus() +{ + if (anyLoading()) + m_movieLoading.start(); + else + m_movieLoading.stop(); +} diff --git a/models/progressmodel.h b/models/progressmodel.h new file mode 100644 index 0000000..0a86940 --- /dev/null +++ b/models/progressmodel.h @@ -0,0 +1,59 @@ +#pragma once + +#include +#include +#include + +class ProgressModel : public QAbstractListModel +{ + Q_OBJECT + +public: + struct Item + { + enum class Status + { + None, + Loading, + Succeeded, + Failed + }; + + QString text; + Status status; + }; + + explicit ProgressModel(QObject *parent = nullptr); + ProgressModel(const QStringList &items, QObject *parent = nullptr); + ProgressModel(const QVector &items, QObject *parent = nullptr); + + const QVector &items() const; + void setItems(const QStringList &items); + void setItems(const QVector &items); + + void setText(int row, const QString &text); + void setStatus(int row, Item::Status status); + + void clearItems(); + + int rowCount(const QModelIndex &parent) const override; + QVariant data(const QModelIndex &index, int role) const override; + +private slots: + void frameChanged(); + +private: + bool anyLoading() const; + void updateMovieStatus(); + + QVector m_items; + + const QPixmap m_pixmapSucceeded { ":/loganalyzer/succeeded.png" }; + const QPixmap m_pixmapFailed { ":/loganalyzer/failed.png" }; + const QPixmap m_pixmapEmpty { [this](){ + QPixmap pixmap(m_pixmapSucceeded.size()); + pixmap.fill(); + return pixmap; + }() }; + QMovie m_movieLoading { ":/loganalyzer/loading.gif" }; +}; diff --git a/models/sqlrelationaltablemodel.cpp b/models/sqlrelationaltablemodel.cpp deleted file mode 100644 index ff5d3d2..0000000 --- a/models/sqlrelationaltablemodel.cpp +++ /dev/null @@ -1,14 +0,0 @@ -#include "sqlrelationaltablemodel.h" - -SqlRelationalTableModel::SqlRelationalTableModel(QObject *parent, QSqlDatabase db) : - QSqlRelationalTableModel(parent, db) -{ -} - -QVariant SqlRelationalTableModel::headerData(int section, Qt::Orientation orientation, int role) const -{ - if (orientation == Qt::Vertical) - return {}; - - return QSqlRelationalTableModel::headerData(section, orientation, role); -} diff --git a/models/sqlrelationaltablemodel.h b/models/sqlrelationaltablemodel.h deleted file mode 100644 index 03e7105..0000000 --- a/models/sqlrelationaltablemodel.h +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once - -#include - -class SqlRelationalTableModel : public QSqlRelationalTableModel -{ - Q_OBJECT - -public: - explicit SqlRelationalTableModel(QObject *parent = nullptr, QSqlDatabase db = QSqlDatabase()); - - QVariant headerData(int section, Qt::Orientation orientation, int role) const override; -}; diff --git a/threads/tablecreatorthread.cpp b/threads/tablecreatorthread.cpp index f09ac93..ee844aa 100644 --- a/threads/tablecreatorthread.cpp +++ b/threads/tablecreatorthread.cpp @@ -96,6 +96,7 @@ void TableCreatorThread::run() return; } + sleep(1); emit someSignal(index++); } } diff --git a/widgets/databasewidget.cpp b/widgets/databasewidget.cpp index bf7eae1..92da338 100644 --- a/widgets/databasewidget.cpp +++ b/widgets/databasewidget.cpp @@ -12,16 +12,17 @@ DatabaseWidget::DatabaseWidget(QWidget *parent) : // for debugging setDriver("QMYSQL"); -// setMysqlHostname("sql7.freemysqlhosting.net"); -// setMysqlUsername("sql7285815"); -// setMysqlPassword("BKhysrtqKl"); -// setMysqlDatabase("sql7285815"); + setMysqlHostname("sql7.freemysqlhosting.net"); + setMysqlUsername("sql7285815"); + setMysqlPassword("BKhysrtqKl"); + setMysqlDatabase("sql7285815"); - //setMysqlHostname("brunner.ninja"); - setMysqlHostname("localhost"); - setMysqlUsername("logtest"); - setMysqlPassword("logtest"); - setMysqlDatabase("logtest"); +// setMysqlHostname("brunner.ninja"); + +// setMysqlHostname("localhost"); +// setMysqlUsername("logtest"); +// setMysqlPassword("logtest"); +// setMysqlDatabase("logtest"); } DatabaseWidget::~DatabaseWidget() = default; diff --git a/wizard/localimportpage.cpp b/wizard/localimportpage.cpp index b7448ca..52a6cd3 100644 --- a/wizard/localimportpage.cpp +++ b/wizard/localimportpage.cpp @@ -144,7 +144,7 @@ void LocalImportPage::updateSummary() ScanResult LocalImportPage::filterResult(ScanResult result) const { - const auto processes = m_model.enabledItems().toSet(); + const auto processes = m_model.enabledTexts().toSet(); for (auto hostsIter = result.begin(); hostsIter != result.end(); hostsIter++) { diff --git a/wizard/remoteimportoverviewpage.cpp b/wizard/remoteimportoverviewpage.cpp index d45619b..42bee37 100644 --- a/wizard/remoteimportoverviewpage.cpp +++ b/wizard/remoteimportoverviewpage.cpp @@ -213,8 +213,8 @@ void RemoteImportOverviewPage::updateSummary() ScanResult RemoteImportOverviewPage::filterResult(ScanResult result) const { - const auto hosts = m_modelHosts.enabledItems().toSet(); - const auto processes = m_modelProcesses.enabledItems().toSet(); + const auto hosts = m_modelHosts.enabledTexts().toSet(); + const auto processes = m_modelProcesses.enabledTexts().toSet(); for (auto hostsIter = result.begin(); hostsIter != result.end(); ) { diff --git a/wizard/tablespage.cpp b/wizard/tablespage.cpp index 092f2aa..dc02981 100644 --- a/wizard/tablespage.cpp +++ b/wizard/tablespage.cpp @@ -1,4 +1,5 @@ #include "tablespage.h" +#include "ui_tablespage.h" #include #include @@ -7,27 +8,13 @@ #include "threads/tablecreatorthread.h" TablesPage::TablesPage(QWidget *parent) : - QWizardPage(parent) + QWizardPage(parent), + m_ui(std::make_unique()), + m_model(this) { - setTitle(tr("Tables")); - setSubTitle(tr("TODO...")); + m_ui->setupUi(this); - auto layout = new QGridLayout; - - m_statusLabels.resize(TableCreatorThread::tables().size()); - - int index { 0 }; - for (const QString &tableName : TableCreatorThread::tables()) - { - m_statusLabels[index] = new QLabel; - layout->addWidget(m_statusLabels[index], index, 0); - - auto label = new QLabel(tr("Create table %0").arg(tableName)); - label->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); - layout->addWidget(label, index++, 1); - } - - setLayout(layout); + m_ui->listView->setModel(&m_model); } TablesPage::~TablesPage() = default; @@ -43,29 +30,25 @@ void TablesPage::initializePage() Q_ASSERT(importWizard); Q_ASSERT(importWizard->database().isOpen()); - for (auto label : m_statusLabels) - { - label->setMovie(nullptr); - label->setPixmap({}); - } + QVector items; + items.reserve(TableCreatorThread::tables().size()); + + for (const QString &tableName : TableCreatorThread::tables()) + items.append({ tr("Create table %0").arg(tableName), ProgressModel::Item::Status::None }); + items.first().status = ProgressModel::Item::Status::Loading; + + m_model.setItems(items); m_thread = std::make_unique(importWizard->database(), this); connect(m_thread.get(), &TableCreatorThread::someSignal, this, &TablesPage::someSlot); m_thread->start(); - m_statusLabels[0]->setMovie(&m_movieLoading); - m_movieLoading.start(); } void TablesPage::cleanupPage() { - if (m_thread) - { - m_thread->requestInterruption(); - m_thread->wait(); - m_thread = nullptr; - } - m_movieLoading.stop(); + stopThread(); + m_model.clearItems(); } bool TablesPage::isComplete() const @@ -75,15 +58,24 @@ bool TablesPage::isComplete() const void TablesPage::someSlot(int index) { - Q_ASSERT(index < m_statusLabels.size()); + Q_ASSERT(index < m_model.rowCount({})); - m_statusLabels[index]->setMovie(nullptr); - m_statusLabels[index]->setPixmap(m_pixmapSucceeded); - if (index < m_statusLabels.size() - 1) - m_statusLabels[index+1]->setMovie(&m_movieLoading); + m_model.setStatus(index, ProgressModel::Item::Status::Succeeded); + if (index < m_model.rowCount({}) - 1) + m_model.setStatus(index + 1, ProgressModel::Item::Status::Loading); else { - cleanupPage(); + stopThread(); emit completeChanged(); } } + +void TablesPage::stopThread() +{ + if (m_thread) + { + m_thread->requestInterruption(); + m_thread->wait(); + m_thread = nullptr; + } +} diff --git a/wizard/tablespage.h b/wizard/tablespage.h index 1d46928..707907b 100644 --- a/wizard/tablespage.h +++ b/wizard/tablespage.h @@ -1,25 +1,21 @@ #pragma once #include -#include -#include -#include #include +#include "models/progressmodel.h" + class QLabel; class QSqlDatabase; class TableCreatorThread; +namespace Ui { class TablesPage; } class TablesPage : public QWizardPage { Q_OBJECT - const QPixmap m_pixmapSucceeded { ":/loganalyzer/succeeded.png" }; - const QPixmap m_pixmapFailed { ":/loganalyzer/failed.png" }; - QMovie m_movieLoading { ":/loganalyzer/loading.gif" }; - public: explicit TablesPage(QWidget *parent = nullptr); ~TablesPage() override; @@ -34,7 +30,11 @@ private slots: void someSlot(int index); private: - QVector m_statusLabels; + void stopThread(); + + const std::unique_ptr m_ui; + + ProgressModel m_model; std::unique_ptr m_thread; }; diff --git a/wizard/tablespage.ui b/wizard/tablespage.ui new file mode 100644 index 0000000..7de966d --- /dev/null +++ b/wizard/tablespage.ui @@ -0,0 +1,34 @@ + + + TablesPage + + + + 0 + 0 + 400 + 300 + + + + WizardPage + + + Tables + + + TODO... + + + + + + QAbstractItemView::NoSelection + + + + + + + +