Imported existing sources

This commit is contained in:
2019-04-01 10:43:36 +02:00
parent eb1c3bf259
commit cd9bfb8ffe
56 changed files with 3694 additions and 0 deletions
+54
View File
@@ -0,0 +1,54 @@
#include "conclusionpage.h"
#include <QVBoxLayout>
#include <QLabel>
#include <QCheckBox>
#include <QSqlQuery>
#include <QSqlError>
#include <QMessageBox>
#include <QStringBuilder>
#include <QVariant>
#include "importwizard.h"
ConclusionPage::ConclusionPage(QWidget *parent) :
QWizardPage(parent)
{
setTitle(tr("Conclusion"));
setSubTitle(tr("Import successfully finished!"));
auto layout = new QVBoxLayout;
m_label = new QLabel;
layout->addWidget(m_label);
layout->addStretch(1);
m_checkBox = new QCheckBox(tr("Open new database"));
m_checkBox->setChecked(true);
layout->addWidget(m_checkBox);
registerField("open", m_checkBox);
layout->addStretch(1);
setLayout(layout);
}
void ConclusionPage::initializePage()
{
auto importWizard = qobject_cast<ImportWizard*>(wizard());
Q_ASSERT(importWizard);
Q_ASSERT(importWizard->database().isOpen());
QSqlQuery query("SELECT COUNT(*) FROM `Logs`;", importWizard->database());
if (query.lastError().isValid())
{
QMessageBox::warning(nullptr, tr("Could not get count!"), tr("Could not get count!") % "\n\n" % query.lastError().text());
return;
}
const auto fetched = query.next();
Q_ASSERT(fetched);
m_label->setText(tr("<b>%0 rows</b> have been imported.").arg(query.value(0).toInt()));
}
+20
View File
@@ -0,0 +1,20 @@
#pragma once
#include <QWizardPage>
class QLabel;
class QCheckBox;
class ConclusionPage : public QWizardPage
{
Q_OBJECT
public:
explicit ConclusionPage(QWidget *parent = nullptr);
void initializePage() override;
private:
QLabel *m_label;
QCheckBox *m_checkBox;
};
+46
View File
@@ -0,0 +1,46 @@
#include "databasepage.h"
#include "ui_databasepage.h"
#include <QVBoxLayout>
#include <QSqlError>
#include <QMessageBox>
#include <QStringBuilder>
#include <QSqlQuery>
#include <QFileDialog>
#include "widgets/databasewidget.h"
#include "importwizard.h"
DatabasePage::DatabasePage(QWidget *parent) :
QWizardPage(parent),
m_ui(std::make_unique<Ui::DatabasePage>())
{
m_ui->setupUi(this);
setCommitPage(true);
}
DatabasePage::~DatabasePage() = default;
int DatabasePage::nextId() const
{
return int(ImportWizard::Pages::Tables);
}
bool DatabasePage::validatePage()
{
auto importWizard = qobject_cast<ImportWizard*>(wizard());
Q_ASSERT(importWizard);
Q_ASSERT(!importWizard->database().isOpen());
importWizard->database() = m_ui->databaseWidget->createConnection();
if (!importWizard->database().open())
{
QMessageBox::warning(this, tr("Could not open database!"), tr("Could not open database!") % "\n\n" % importWizard->database().lastError().text());
importWizard->database() = {};
return false;
}
return true;
}
+23
View File
@@ -0,0 +1,23 @@
#pragma once
#include <QWizardPage>
#include <memory>
namespace Ui { class DatabasePage; }
class DatabasePage : public QWizardPage
{
Q_OBJECT
public:
explicit DatabasePage(QWidget *parent = nullptr);
~DatabasePage() override;
int nextId() const override;
bool validatePage() override;
private:
const std::unique_ptr<Ui::DatabasePage> m_ui;
};
+51
View File
@@ -0,0 +1,51 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>DatabasePage</class>
<widget class="QWizardPage" name="DatabasePage">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>WizardPage</string>
</property>
<property name="title">
<string>Database</string>
</property>
<property name="subTitle">
<string>Please setup the database connection.</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout" stretch="0,1">
<item>
<widget class="DatabaseWidget" name="databaseWidget" native="true"/>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>263</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>DatabaseWidget</class>
<extends>QWidget</extends>
<header>widgets/databasewidget.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>
+117
View File
@@ -0,0 +1,117 @@
#include "importprogresspage.h"
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QLabel>
#include <QProgressBar>
#include <QPlainTextEdit>
#include "importwizard.h"
#include "threads/importthread.h"
ImportProgressPage::ImportProgressPage(QWidget *parent) :
QWizardPage(parent)
{
setTitle(tr("Import Progress"));
setSubTitle(tr("TODO..."));
auto layout = new QVBoxLayout;
{
auto hboxLayout = new QHBoxLayout;
m_labelIcon = new QLabel;
hboxLayout->addWidget(m_labelIcon);
m_labelStatus = new QLabel;
hboxLayout->addWidget(m_labelStatus, 1);
layout->addLayout(hboxLayout);
}
m_progressBar = new QProgressBar;
m_progressBar->setMaximum(100);
layout->addWidget(m_progressBar);
m_logView = new QPlainTextEdit;
m_logView->setReadOnly(true);
layout->addWidget(m_logView, 1);
setLayout(layout);
}
ImportProgressPage::~ImportProgressPage() = default;
void ImportProgressPage::initializePage()
{
auto importWizard = qobject_cast<ImportWizard*>(wizard());
Q_ASSERT(importWizard);
Q_ASSERT(importWizard->database().isOpen());
const auto result = wizard()->property("result").value<ScanResult>();
const auto timeFormat = wizard()->property("timeFormat").toString();
m_logView->clear();
m_thread = std::make_unique<ImportThread>(importWizard->database(), result, timeFormat, this);
connect(m_thread.get(), &ImportThread::statusUpdate, this, &ImportProgressPage::statusUpdate);
connect(m_thread.get(), &ImportThread::progressUpdate, this, &ImportProgressPage::progressUpdate);
connect(m_thread.get(), &ImportThread::logMessage, this, &ImportProgressPage::logMessage);
connect(m_thread.get(), &QThread::finished, this, &ImportProgressPage::finished);
m_thread->start();
m_labelIcon->setMovie(&m_movieLoading);
m_movieLoading.start();
}
void ImportProgressPage::cleanupPage()
{
if (m_thread)
{
m_thread->requestInterruption();
m_thread->wait();
m_thread = nullptr;
}
m_movieLoading.stop();
}
int ImportProgressPage::nextId() const
{
return int(ImportWizard::Pages::Conclusion);
}
bool ImportProgressPage::isComplete() const
{
return m_thread == nullptr;
}
void ImportProgressPage::statusUpdate(const QString &message)
{
m_labelStatus->setText(message);
}
void ImportProgressPage::progressUpdate(qint64 finished, qint64 total)
{
while (total & 0xFFFFFFFF00000000)
{
finished = finished >> 8;
total = total >> 8;
}
m_progressBar->setMaximum(total);
m_progressBar->setValue(finished);
}
void ImportProgressPage::logMessage(const QString &message)
{
m_logView->appendHtml(QString("%0: %1<br/>").arg(QTime::currentTime().toString(), message));
}
void ImportProgressPage::finished()
{
cleanupPage();
emit completeChanged();
m_labelIcon->setPixmap(m_pixmapSucceeded);
logMessage(tr("Finished."));
}
+46
View File
@@ -0,0 +1,46 @@
#pragma once
#include <QWizardPage>
#include <QPixmap>
#include <QMovie>
#include <memory>
class QLabel;
class QProgressBar;
class QPlainTextEdit;
class ImportThread;
class ImportProgressPage : 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 ImportProgressPage(QWidget *parent = nullptr);
~ImportProgressPage() override;
void initializePage() override;
void cleanupPage() override;
int nextId() const override;
bool isComplete() const override;
private slots:
void statusUpdate(const QString &message);
void progressUpdate(qint64 finished, qint64 total);
void logMessage(const QString &message);
void finished();
private:
QLabel *m_labelIcon;
QLabel *m_labelStatus;
QProgressBar *m_progressBar;
QPlainTextEdit *m_logView;
std::unique_ptr<ImportThread> m_thread;
};
+117
View File
@@ -0,0 +1,117 @@
#include "importtypepage.h"
#include <QVBoxLayout>
#include <QRadioButton>
#include <QHBoxLayout>
#include <QLineEdit>
#include <QToolButton>
#include <QDir>
#include <QMessageBox>
#include <QSet>
#include <QFileDialog>
#include "importwizard.h"
#include "common.h"
ImportTypePage::ImportTypePage(QWidget *parent) :
QWizardPage(parent)
{
setTitle(tr("Import type"));
setSubTitle(tr("Please select which type of log files you would like to import."));
auto layout = new QVBoxLayout;
m_radioLocal = new QRadioButton(tr("Local: Typically found under /tmp/testfw_log/tests"));
m_radioLocal->setChecked(true);
layout->addWidget(m_radioLocal);
m_radioRemote = new QRadioButton(tr("Remote: Typically found under /log or /log2"));
layout->addWidget(m_radioRemote);
layout->addStretch(1);
{
auto hboxLayout = new QHBoxLayout;
m_lineEdit = new QLineEdit;
hboxLayout->addWidget(m_lineEdit, 1);
registerField("folder", m_lineEdit);
{
auto toolButton = new QToolButton;
toolButton->setText(tr("Select..."));
connect(toolButton, &QAbstractButton::pressed, this, &ImportTypePage::selectFolder);
hboxLayout->addWidget(toolButton);
}
layout->addLayout(hboxLayout);
}
layout->addStretch(1);
setLayout(layout);
}
int ImportTypePage::nextId() const
{
if (m_radioLocal->isChecked())
return int(ImportWizard::Pages::LocalImport);
if (m_radioRemote->isChecked())
return int(ImportWizard::Pages::RemoteImportScan);
Q_UNREACHABLE();
}
bool ImportTypePage::validatePage()
{
if (m_lineEdit->text().isEmpty())
{
QMessageBox::warning(this, tr("No logfolder defined!"), tr("No logfolder defined!"));
return false;
}
QDir dir(m_lineEdit->text());
if (!dir.exists())
{
QMessageBox::warning(this, tr("Could not find logfolder!"), tr("Could not find logfolder!"));
return false;
}
if (m_radioLocal->isChecked())
{
ScanResult result;
auto &host = result["__dummyHost"];
for (const auto &fileInfo : dir.entryInfoList({ "*.log" }, QDir::Files))
{
if (fileInfo.baseName().endsWith("_console"))
continue;
host[fileInfo.baseName()][QDate()] = {
fileInfo.fileName(),
fileInfo.absoluteFilePath(),
fileInfo.size(),
false
};
}
if (host.isEmpty())
{
QMessageBox::warning(this, tr("Could not find any logs!"), tr("Could not find any logs!"));
return false;
}
wizard()->setProperty("result", QVariant::fromValue(result));
}
if (m_radioRemote->isChecked())
wizard()->setProperty("folder", dir.absolutePath());
return true;
}
void ImportTypePage::selectFolder()
{
const auto path = QFileDialog::getExistingDirectory(this, tr("Select log folder"));
if (!path.isEmpty())
m_lineEdit->setText(path);
}
+27
View File
@@ -0,0 +1,27 @@
#pragma once
#include <QWizardPage>
class QRadioButton;
class QLineEdit;
class ImportTypePage : public QWizardPage
{
Q_OBJECT
public:
explicit ImportTypePage(QWidget *parent = nullptr);
int nextId() const override;
bool validatePage() override;
private slots:
void selectFolder();
private:
QRadioButton *m_radioLocal;
QRadioButton *m_radioRemote;
QLineEdit *m_lineEdit;
};
+35
View File
@@ -0,0 +1,35 @@
#include "importwizard.h"
#include "intropage.h"
#include "databasepage.h"
#include "tablespage.h"
#include "importtypepage.h"
#include "localimportpage.h"
#include "remoteimportscanpage.h"
#include "remoteimportoverviewpage.h"
#include "importprogresspage.h"
#include "conclusionpage.h"
ImportWizard::ImportWizard(QWidget *parent, Qt::WindowFlags flags) :
QWizard(parent, flags)
{
setPage(int(Pages::Introduction), new IntroPage);
setPage(int(Pages::Database), new DatabasePage);
setPage(int(Pages::Tables), new TablesPage);
setPage(int(Pages::ImportType), new ImportTypePage);
setPage(int(Pages::LocalImport), new LocalImportPage);
setPage(int(Pages::RemoteImportScan), new RemoteImportScanPage);
setPage(int(Pages::RemoteImportOverview), new RemoteImportOverviewPage);
setPage(int(Pages::ImportProgress), new ImportProgressPage);
setPage(int(Pages::Conclusion), new ConclusionPage);
}
QSqlDatabase &ImportWizard::database()
{
return m_database;
}
const QSqlDatabase &ImportWizard::database() const
{
return m_database;
}
+20
View File
@@ -0,0 +1,20 @@
#pragma once
#include <QWizard>
#include <QSqlDatabase>
class ImportWizard : public QWizard
{
Q_OBJECT
public:
enum class Pages { Introduction, Database, Tables, ImportType, LocalImport, RemoteImportScan, RemoteImportOverview, ImportProgress, Conclusion };
ImportWizard(QWidget *parent = nullptr, Qt::WindowFlags flags = Qt::WindowFlags());
QSqlDatabase &database();
const QSqlDatabase &database() const;
private:
QSqlDatabase m_database;
};
+18
View File
@@ -0,0 +1,18 @@
#include "intropage.h"
#include "ui_intropage.h"
#include "importwizard.h"
IntroPage::IntroPage(QWidget *parent) :
QWizardPage(parent),
m_ui(std::make_unique<Ui::IntroPage>())
{
m_ui->setupUi(this);
}
IntroPage::~IntroPage() = default;
int IntroPage::nextId() const
{
return int(ImportWizard::Pages::Database);
}
+21
View File
@@ -0,0 +1,21 @@
#pragma once
#include <QWizardPage>
#include <memory>
namespace Ui { class IntroPage; }
class IntroPage : public QWizardPage
{
Q_OBJECT
public:
explicit IntroPage(QWidget *parent = nullptr);
~IntroPage() override;
int nextId() const override;
private:
const std::unique_ptr<Ui::IntroPage> m_ui;
};
+34
View File
@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>IntroPage</class>
<widget class="QWizardPage" name="IntroPage">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>WizardPage</string>
</property>
<property name="title">
<string>Introduction</string>
</property>
<property name="subTitle">
<string>TODO...</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>TODO: long introduction...</string>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>
+161
View File
@@ -0,0 +1,161 @@
#include "localimportpage.h"
#include <QVBoxLayout>
#include <QFormLayout>
#include <QLineEdit>
#include <QHostInfo>
#include <QDateEdit>
#include <QComboBox>
#include <QListView>
#include <QLabel>
#include <QMessageBox>
#include <QStringBuilder>
#include "importwizard.h"
LocalImportPage::LocalImportPage(QWidget *parent) :
QWizardPage(parent)
{
setTitle(tr("Local Import"));
setSubTitle(tr("TODO..."));
setCommitPage(true);
connect(&m_model, &ChecklistModel::dataChanged, this, &LocalImportPage::updateSummary);
auto layout = new QVBoxLayout;
{
auto hboxLayout = new QHBoxLayout;
{
auto formLayout = new QFormLayout;
m_lineEditHost = new QLineEdit(QHostInfo::localHostName());
formLayout->addRow(tr("Host:"), m_lineEditHost);
m_dateEdit = new QDateEdit(QDate::currentDate());
formLayout->addRow(tr("Date:"), m_dateEdit);
m_comboBox = new QComboBox;
m_comboBox->addItem(tr("Without milliseconds"), "HH:mm:ss");
m_comboBox->addItem(tr("With milliseconds"), "HH:mm:ss.zzz");
formLayout->addRow(tr("Timestamp:"), m_comboBox);
hboxLayout->addLayout(formLayout);
}
{
auto view = new QListView;
view->setModel(&m_model);
hboxLayout->addWidget(view, 1);
}
layout->addLayout(hboxLayout, 1);
}
m_labelSummary = new QLabel;
layout->addWidget(m_labelSummary);
setLayout(layout);
}
int LocalImportPage::nextId() const
{
return int(ImportWizard::Pages::ImportProgress);
}
void LocalImportPage::initializePage()
{
m_result = wizard()->property("result").value<ScanResult>();
Q_ASSERT(m_result.count() == 1);
{
auto processes = m_result.values().first().keys();
processes.sort();
m_model.setItems(processes);
}
updateSummary();
}
bool LocalImportPage::validatePage()
{
auto result = filterResult(m_result);
if (scanResultEmpty(result))
{
QMessageBox::warning(this, tr("No files to import!"), tr("No files to import!"));
return false;
}
Q_ASSERT(result.count() == 1);
auto host = result.values().first();
for (auto iter = host.begin(); iter != host.end(); iter++)
{
auto &dates = iter.value();
Q_ASSERT(dates.count() == 1);
const auto logfile = dates.values().first();
dates.clear();
dates.insert(m_dateEdit->date(), logfile);
}
result.clear();
result.insert(m_lineEditHost->text(), host);
wizard()->setProperty("result", QVariant::fromValue(result));
wizard()->setProperty("timeFormat", m_comboBox->currentData().toString());
return true;
}
void LocalImportPage::updateSummary()
{
if (m_result.isEmpty())
return;
const auto result = filterResult(m_result);
int logFiles { 0 };
qint64 totalSize { 0 };
for (auto hostsIter = result.constBegin(); hostsIter != result.constEnd(); hostsIter++)
for (auto processesIter = hostsIter.value().constBegin(); processesIter != hostsIter.value().constEnd(); processesIter++)
for (auto datesIter = processesIter.value().constBegin(); datesIter != processesIter.value().constEnd(); datesIter++)
{
logFiles++;
totalSize += datesIter.value().filesize;
}
QString sizeStr;
for (const QString prefix : { "K", "M", "G", "T" })
{
if (totalSize > 1024)
{
totalSize /= 1024;
sizeStr = QString::number(totalSize) % prefix;
}
}
m_labelSummary->setText(tr("Filters match %0 files (%1B)").arg(logFiles).arg(sizeStr));
}
ScanResult LocalImportPage::filterResult(ScanResult result) const
{
const auto processes = m_model.enabledItems().toSet();
for (auto hostsIter = result.begin(); hostsIter != result.end(); hostsIter++)
{
for (auto processesIter = hostsIter.value().begin(); processesIter != hostsIter.value().end(); )
{
if (processes.contains(processesIter.key()))
processesIter++;
else
processesIter = hostsIter.value().erase(processesIter);
}
}
return result;
}
+39
View File
@@ -0,0 +1,39 @@
#pragma once
#include <QWizardPage>
#include "models/checklistmodel.h"
#include "common.h"
class QLineEdit;
class QDateEdit;
class QComboBox;
class QLabel;
class LocalImportPage : public QWizardPage
{
Q_OBJECT
public:
explicit LocalImportPage(QWidget *parent = nullptr);
int nextId() const override;
void initializePage() override;
bool validatePage() override;
private slots:
void updateSummary();
private:
ScanResult filterResult(ScanResult result) const;
ScanResult m_result;
ChecklistModel m_model;
QLineEdit *m_lineEditHost;
QDateEdit *m_dateEdit;
QComboBox *m_comboBox;
QLabel *m_labelSummary;
};
+248
View File
@@ -0,0 +1,248 @@
#include "remoteimportoverviewpage.h"
#include <QVBoxLayout>
#include <QGroupBox>
#include <QHBoxLayout>
#include <QLabel>
#include <QDateEdit>
#include <QComboBox>
#include <QListView>
#include <QMessageBox>
#include <QDir>
#include <QDirIterator>
#include <QVariant>
#include <QRegularExpression>
#include <QSet>
#include <QDate>
#include <QStringBuilder>
#include "importwizard.h"
#include "common.h"
RemoteImportOverviewPage::RemoteImportOverviewPage(QWidget *parent) :
QWizardPage(parent)
{
setTitle(tr("Remote Import Overview"));
setSubTitle(tr("TODO...."));
setCommitPage(true);
connect(&m_modelHosts, &ChecklistModel::dataChanged, this, &RemoteImportOverviewPage::updateSummary);
connect(&m_modelProcesses, &ChecklistModel::dataChanged, this, &RemoteImportOverviewPage::updateSummary);
auto layout = new QVBoxLayout;
{
auto groupBox = new QGroupBox(tr("Date-Range:"));
auto hboxLayout = new QHBoxLayout;
{
auto label = new QLabel(tr("From:"));
hboxLayout->addWidget(label);
}
m_dateEditFrom = new QDateEdit;
connect(m_dateEditFrom, &QDateTimeEdit::dateChanged, this, &RemoteImportOverviewPage::updateSummary);
hboxLayout->addWidget(m_dateEditFrom);
hboxLayout->addStretch(1);
{
auto label = new QLabel(tr("To:"));
hboxLayout->addWidget(label);
}
m_dateEditTo = new QDateEdit;
connect(m_dateEditTo, &QDateTimeEdit::dateChanged, this, &RemoteImportOverviewPage::updateSummary);
hboxLayout->addWidget(m_dateEditTo);
hboxLayout->addStretch(1);
{
auto label = new QLabel(tr("Timestamp:"));
hboxLayout->addWidget(label);
}
m_comboBox = new QComboBox;
m_comboBox->addItem(tr("Without milliseconds"), "HH:mm:ss");
m_comboBox->addItem(tr("With milliseconds"), "HH:mm:ss.zzz");
hboxLayout->addWidget(m_comboBox);
groupBox->setLayout(hboxLayout);
layout->addWidget(groupBox);
}
{
auto hboxLayout = new QHBoxLayout;
{
auto vboxLayout = new QVBoxLayout;
{
auto label = new QLabel(tr("Hosts:"));
vboxLayout->addWidget(label);
}
{
auto view = new QListView;
view->setModel(&m_modelHosts);
vboxLayout->addWidget(view, 1);
}
hboxLayout->addLayout(vboxLayout);
}
{
auto vboxLayout = new QVBoxLayout;
{
auto label = new QLabel(tr("Processes:"));
vboxLayout->addWidget(label);
}
{
auto view = new QListView;
view->setModel(&m_modelProcesses);
vboxLayout->addWidget(view, 1);
}
hboxLayout->addLayout(vboxLayout);
}
layout->addLayout(hboxLayout, 1);
}
m_labelSummary = new QLabel;
layout->addWidget(m_labelSummary);
setLayout(layout);
}
void RemoteImportOverviewPage::initializePage()
{
m_result = wizard()->property("result").value<ScanResult>();
QDate minDate, maxDate;
QSet<QString> processes;
for (auto hostsIter = m_result.constBegin(); hostsIter != m_result.constEnd(); hostsIter++)
for (auto processesIter = hostsIter.value().constBegin(); processesIter != hostsIter.value().constEnd(); processesIter++)
{
processes.insert(processesIter.key());
for (auto datesIter = processesIter.value().constBegin(); datesIter != processesIter.value().constEnd(); datesIter++)
{
if (minDate.isNull() || datesIter.key() < minDate)
minDate = datesIter.key();
if (maxDate.isNull() || datesIter.key() > maxDate)
maxDate = datesIter.key();
}
}
m_dateEditFrom->setDate(minDate);
m_dateEditTo->setDate(maxDate);
{
auto hosts = m_result.keys();
hosts.sort();
m_modelHosts.setItems(hosts);
}
{
auto processesList = processes.toList();
processesList.sort();
m_modelProcesses.setItems(processesList);
}
updateSummary();
}
int RemoteImportOverviewPage::nextId() const
{
return int(ImportWizard::Pages::ImportProgress);
}
bool RemoteImportOverviewPage::validatePage()
{
const auto result = filterResult(m_result);
if (scanResultEmpty(result))
{
QMessageBox::warning(this, tr("No files to import!"), tr("No files to import!"));
return false;
}
wizard()->setProperty("result", QVariant::fromValue(result));
wizard()->setProperty("timeFormat", m_comboBox->currentData().toString());
return true;
}
void RemoteImportOverviewPage::updateSummary()
{
if (m_result.isEmpty())
return;
const auto result = filterResult(m_result);
int logFiles { 0 };
qint64 totalSize { 0 };
for (auto hostsIter = result.constBegin(); hostsIter != result.constEnd(); hostsIter++)
for (auto processesIter = hostsIter.value().constBegin(); processesIter != hostsIter.value().constEnd(); processesIter++)
for (auto datesIter = processesIter.value().constBegin(); datesIter != processesIter.value().constEnd(); datesIter++)
{
logFiles++;
totalSize += datesIter.value().filesize;
}
QString sizeStr;
for (const QString prefix : { "K", "M", "G", "T" })
{
if (totalSize > 1024)
{
totalSize /= 1024;
sizeStr = QString::number(totalSize) % prefix;
}
}
m_labelSummary->setText(tr("Filters match %0 files (%1B)").arg(logFiles).arg(sizeStr));
}
ScanResult RemoteImportOverviewPage::filterResult(ScanResult result) const
{
const auto hosts = m_modelHosts.enabledItems().toSet();
const auto processes = m_modelProcesses.enabledItems().toSet();
for (auto hostsIter = result.begin(); hostsIter != result.end(); )
{
if (hosts.contains(hostsIter.key()))
{
for (auto processesIter = hostsIter.value().begin(); processesIter != hostsIter.value().end(); )
{
if (processes.contains(processesIter.key()))
{
for (auto datesIter = processesIter.value().begin(); datesIter != processesIter.value().end(); )
{
if (datesIter.key() >= m_dateEditFrom->date() && datesIter.key() <= m_dateEditTo->date())
datesIter++;
else
datesIter = processesIter.value().erase(datesIter);
}
processesIter++;
}
else
processesIter = hostsIter.value().erase(processesIter);
}
hostsIter++;
}
else
hostsIter = result.erase(hostsIter);
}
return result;
}
+40
View File
@@ -0,0 +1,40 @@
#pragma once
#include <QWizardPage>
#include "models/checklistmodel.h"
#include "common.h"
class QDateEdit;
class QComboBox;
class QLabel;
class RemoteImportOverviewPage : public QWizardPage
{
Q_OBJECT
public:
explicit RemoteImportOverviewPage(QWidget *parent = nullptr);
void initializePage() override;
int nextId() const override;
bool validatePage() override;
private slots:
void updateSummary();
private:
ScanResult filterResult(ScanResult result) const;
QDateEdit *m_dateEditFrom;
QDateEdit *m_dateEditTo;
QComboBox *m_comboBox;
QLabel *m_labelSummary;
ChecklistModel m_modelHosts;
ChecklistModel m_modelProcesses;
ScanResult m_result;
};
+111
View File
@@ -0,0 +1,111 @@
#include "remoteimportscanpage.h"
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QLabel>
#include <QPlainTextEdit>
#include "importwizard.h"
#include "threads/remotescannerthread.h"
RemoteImportScanPage::RemoteImportScanPage(QWidget *parent) :
QWizardPage(parent)
{
setTitle(tr("Remote Import Scan"));
setSubTitle(tr("TODO..."));
auto layout = new QVBoxLayout;
{
auto hboxLayout = new QHBoxLayout;
m_labelAnimation = new QLabel;
hboxLayout->addWidget(m_labelAnimation);
m_labelStatus = new QLabel;
hboxLayout->addWidget(m_labelStatus, 1);
layout->addLayout(hboxLayout);
}
m_logView = new QPlainTextEdit;
m_logView->setReadOnly(true);
layout->addWidget(m_logView, 1);
setLayout(layout);
}
RemoteImportScanPage::~RemoteImportScanPage() = default;
int RemoteImportScanPage::nextId() const
{
return int(ImportWizard::Pages::RemoteImportOverview);
}
void RemoteImportScanPage::initializePage()
{
wizard()->setProperty("result", QVariant::fromValue(ScanResult()));
m_labelAnimation->setMovie(&m_movieLoading);
m_movieLoading.start();
m_logView->clear();
m_thread = std::make_unique<RemoteScannerThread>(field("folder").toString(), this);
connect(m_thread.get(), &RemoteScannerThread::progressUpdate, this, &RemoteImportScanPage::progressUpdate);
connect(m_thread.get(), &RemoteScannerThread::logMessage, this, &RemoteImportScanPage::logMessage);
connect(m_thread.get(), &RemoteScannerThread::finished, this, &RemoteImportScanPage::finished);
m_thread->start();
}
void RemoteImportScanPage::cleanupPage()
{
if (m_thread)
{
m_thread->requestInterruption();
m_thread->wait();
m_thread = nullptr;
}
m_movieLoading.stop();
}
bool RemoteImportScanPage::isComplete() const
{
return m_thread == nullptr && !scanResultEmpty(wizard()->property("result").value<ScanResult>());
}
void RemoteImportScanPage::progressUpdate(int totalFiles, int skippedFiles)
{
m_labelStatus->setText(tr("%0 files scanned... (%1 files skipped)").arg(totalFiles).arg(skippedFiles));
}
void RemoteImportScanPage::logMessage(const QString &message)
{
m_logView->appendHtml(QString("%0: %1<br/>").arg(QTime::currentTime().toString(), message));
}
void RemoteImportScanPage::finished(const ScanResult &result)
{
m_labelAnimation->setMovie(nullptr);
const auto success = !scanResultEmpty(result);
if (success)
{
logMessage(tr("Finished"));
m_labelAnimation->setPixmap(m_pixmapSucceeded);
wizard()->setProperty("result", QVariant::fromValue(result));
}
else
{
logMessage(tr("Scan failed."));
m_labelAnimation->setPixmap(m_pixmapFailed);
}
cleanupPage();
if (success)
emit completeChanged();
}
+45
View File
@@ -0,0 +1,45 @@
#pragma once
#include <QWizardPage>
#include <QPixmap>
#include <QMovie>
#include <memory>
#include "common.h"
class QLabel;
class QPlainTextEdit;
class RemoteScannerThread;
class RemoteImportScanPage : 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 RemoteImportScanPage(QWidget *parent = nullptr);
~RemoteImportScanPage() override;
int nextId() const override;
void initializePage() override;
void cleanupPage() override;
bool isComplete() const override;
private slots:
void progressUpdate(int totalFiles, int skippedFiles);
void logMessage(const QString &message);
void finished(const ScanResult &result);
private:
std::unique_ptr<RemoteScannerThread> m_thread;
QLabel *m_labelAnimation;
QLabel *m_labelStatus;
QPlainTextEdit *m_logView;
};
+89
View File
@@ -0,0 +1,89 @@
#include "tablespage.h"
#include <QGridLayout>
#include <QLabel>
#include "importwizard.h"
#include "threads/tablecreatorthread.h"
TablesPage::TablesPage(QWidget *parent) :
QWizardPage(parent)
{
setTitle(tr("Tables"));
setSubTitle(tr("TODO..."));
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);
}
TablesPage::~TablesPage() = default;
int TablesPage::nextId() const
{
return int(ImportWizard::Pages::ImportType);
}
void TablesPage::initializePage()
{
auto importWizard = qobject_cast<ImportWizard*>(wizard());
Q_ASSERT(importWizard);
Q_ASSERT(importWizard->database().isOpen());
for (auto label : m_statusLabels)
{
label->setMovie(nullptr);
label->setPixmap({});
}
m_thread = std::make_unique<TableCreatorThread>(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();
}
bool TablesPage::isComplete() const
{
return m_thread == nullptr;
}
void TablesPage::someSlot(int index)
{
Q_ASSERT(index < m_statusLabels.size());
m_statusLabels[index]->setMovie(nullptr);
m_statusLabels[index]->setPixmap(m_pixmapSucceeded);
if (index < m_statusLabels.size() - 1)
m_statusLabels[index+1]->setMovie(&m_movieLoading);
else
{
cleanupPage();
emit completeChanged();
}
}
+40
View File
@@ -0,0 +1,40 @@
#pragma once
#include <QWizardPage>
#include <QPixmap>
#include <QMovie>
#include <QVector>
#include <memory>
class QLabel;
class QSqlDatabase;
class TableCreatorThread;
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;
int nextId() const override;
void initializePage() override;
void cleanupPage() override;
bool isComplete() const override;
private slots:
void someSlot(int index);
private:
QVector<QLabel*> m_statusLabels;
std::unique_ptr<TableCreatorThread> m_thread;
};