gitignore, dialogues
This commit is contained in:
+61
@@ -0,0 +1,61 @@
|
||||
# CMake build directory
|
||||
build/
|
||||
|
||||
# Qt MOC files
|
||||
moc_*.cpp
|
||||
*.moc
|
||||
|
||||
# Qt resource compiler
|
||||
qrc_*.cpp
|
||||
|
||||
# Qt UI files
|
||||
ui_*.h
|
||||
|
||||
# Object files
|
||||
*.o
|
||||
*.obj
|
||||
|
||||
# Libraries
|
||||
*.a
|
||||
*.lib
|
||||
|
||||
# Executables
|
||||
*.exe
|
||||
*.out
|
||||
*.app
|
||||
screenshot-gallery
|
||||
|
||||
# Qt specific
|
||||
*.autosave
|
||||
*.qmlc
|
||||
*.jsc
|
||||
|
||||
# IDE and editor files
|
||||
.vscode/
|
||||
.idea/
|
||||
*.pro.user
|
||||
*.pro.user.*
|
||||
*~
|
||||
.DS_Store
|
||||
|
||||
# Cache and temporary files
|
||||
.cache/
|
||||
*.swp
|
||||
*.swo
|
||||
*.tmp
|
||||
|
||||
# CMake files (if generated in source directory)
|
||||
CMakeFiles/
|
||||
CMakeCache.txt
|
||||
cmake_install.cmake
|
||||
Makefile
|
||||
*.cmake
|
||||
|
||||
# Backup files
|
||||
*.bak
|
||||
*.backup
|
||||
*~
|
||||
|
||||
# System files
|
||||
.directory
|
||||
Thumbs.db
|
||||
@@ -0,0 +1,167 @@
|
||||
#include "updatedatabasedialog.h"
|
||||
|
||||
#include <QVBoxLayout>
|
||||
#include <QHBoxLayout>
|
||||
#include <QScrollBar>
|
||||
#include <QDateTime>
|
||||
#include <QFileInfo>
|
||||
#include <QTimer>
|
||||
|
||||
UpdateDatabaseDialog::UpdateDatabaseDialog(const QString &scriptPath,
|
||||
const QString &dbPath,
|
||||
const QString &screenshotsDir,
|
||||
QWidget *parent)
|
||||
: QDialog(parent)
|
||||
, m_scriptPath(scriptPath)
|
||||
, m_dbPath(dbPath)
|
||||
, m_screenshotsDir(screenshotsDir)
|
||||
, m_process(nullptr)
|
||||
{
|
||||
setWindowTitle(tr("Update Database"));
|
||||
setMinimumSize(600, 400);
|
||||
// Non-modal: caller uses show(), not exec()
|
||||
setWindowModality(Qt::NonModal);
|
||||
|
||||
// ----- Layout -----
|
||||
auto *mainLayout = new QVBoxLayout(this);
|
||||
|
||||
m_statusLabel = new QLabel(tr("Starting OCR process…"), this);
|
||||
mainLayout->addWidget(m_statusLabel);
|
||||
|
||||
m_progressBar = new QProgressBar(this);
|
||||
m_progressBar->setRange(0, 0); // indeterminate
|
||||
mainLayout->addWidget(m_progressBar);
|
||||
|
||||
m_logView = new QTextEdit(this);
|
||||
m_logView->setReadOnly(true);
|
||||
m_logView->setFont(QFont("monospace", 9));
|
||||
mainLayout->addWidget(m_logView);
|
||||
|
||||
auto *btnLayout = new QHBoxLayout();
|
||||
btnLayout->addStretch();
|
||||
|
||||
m_cancelButton = new QPushButton(tr("Cancel"), this);
|
||||
btnLayout->addWidget(m_cancelButton);
|
||||
|
||||
m_closeButton = new QPushButton(tr("Close"), this);
|
||||
m_closeButton->setEnabled(false);
|
||||
btnLayout->addWidget(m_closeButton);
|
||||
|
||||
mainLayout->addLayout(btnLayout);
|
||||
|
||||
connect(m_cancelButton, &QPushButton::clicked, this, &UpdateDatabaseDialog::onCancelClicked);
|
||||
connect(m_closeButton, &QPushButton::clicked, this, &QDialog::accept);
|
||||
|
||||
startProcess();
|
||||
}
|
||||
|
||||
UpdateDatabaseDialog::~UpdateDatabaseDialog()
|
||||
{
|
||||
if (m_process && m_process->state() != QProcess::NotRunning) {
|
||||
m_process->kill();
|
||||
m_process->waitForFinished(3000);
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateDatabaseDialog::startProcess()
|
||||
{
|
||||
QFileInfo scriptInfo(m_scriptPath);
|
||||
if (!scriptInfo.exists()) {
|
||||
appendLog(tr("Error: script not found at %1").arg(m_scriptPath), true);
|
||||
m_progressBar->setRange(0, 1);
|
||||
m_progressBar->setValue(1);
|
||||
m_statusLabel->setText(tr("Failed – script not found."));
|
||||
m_cancelButton->setEnabled(false);
|
||||
m_closeButton->setEnabled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
m_process = new QProcess(this);
|
||||
m_process->setProcessChannelMode(QProcess::SeparateChannels);
|
||||
|
||||
connect(m_process, &QProcess::readyReadStandardOutput,
|
||||
this, &UpdateDatabaseDialog::onReadyReadStdOut);
|
||||
connect(m_process, &QProcess::readyReadStandardError,
|
||||
this, &UpdateDatabaseDialog::onReadyReadStdErr);
|
||||
connect(m_process,
|
||||
QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished),
|
||||
this, &UpdateDatabaseDialog::onProcessFinished);
|
||||
|
||||
const QStringList args = {
|
||||
m_scriptPath,
|
||||
"--db", m_dbPath,
|
||||
"--screenshots-dir", m_screenshotsDir
|
||||
};
|
||||
|
||||
appendLog(tr("Running: python3 %1").arg(args.join(' ')));
|
||||
appendLog(QString());
|
||||
|
||||
m_process->start("python3", args);
|
||||
}
|
||||
|
||||
void UpdateDatabaseDialog::onReadyReadStdOut()
|
||||
{
|
||||
const QString text = QString::fromUtf8(m_process->readAllStandardOutput());
|
||||
for (const QString &line : text.split('\n', Qt::SkipEmptyParts))
|
||||
appendLog(line);
|
||||
}
|
||||
|
||||
void UpdateDatabaseDialog::onReadyReadStdErr()
|
||||
{
|
||||
const QString text = QString::fromUtf8(m_process->readAllStandardError());
|
||||
for (const QString &line : text.split('\n', Qt::SkipEmptyParts))
|
||||
appendLog(line, true);
|
||||
}
|
||||
|
||||
void UpdateDatabaseDialog::onProcessFinished(int exitCode, QProcess::ExitStatus exitStatus)
|
||||
{
|
||||
m_progressBar->setRange(0, 1);
|
||||
m_progressBar->setValue(1);
|
||||
m_cancelButton->setEnabled(false);
|
||||
m_closeButton->setEnabled(true);
|
||||
|
||||
if (exitStatus == QProcess::CrashExit || exitCode != 0) {
|
||||
m_statusLabel->setText(tr("OCR process failed (exit code %1).").arg(exitCode));
|
||||
appendLog(tr("\nProcess exited with code %1.").arg(exitCode), true);
|
||||
} else {
|
||||
m_statusLabel->setText(tr("OCR process completed successfully."));
|
||||
appendLog(tr("\nDone."));
|
||||
emit updateFinished();
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateDatabaseDialog::onCancelClicked()
|
||||
{
|
||||
if (m_process && m_process->state() != QProcess::NotRunning) {
|
||||
appendLog(tr("\nCancelling…"), true);
|
||||
m_cancelButton->setEnabled(false);
|
||||
m_statusLabel->setText(tr("Cancelling…"));
|
||||
|
||||
// SIGTERM – Python script's signal handler will clean up and exit
|
||||
m_process->terminate();
|
||||
|
||||
// If it hasn't exited after 3 s, send SIGKILL
|
||||
QTimer::singleShot(3000, this, [this]() {
|
||||
if (m_process && m_process->state() != QProcess::NotRunning) {
|
||||
appendLog(tr("Force-killing process…"), true);
|
||||
m_process->kill();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
reject();
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateDatabaseDialog::appendLog(const QString &text, bool isError)
|
||||
{
|
||||
if (isError)
|
||||
m_logView->setTextColor(QColor("#cc3333"));
|
||||
else
|
||||
m_logView->setTextColor(m_logView->palette().color(QPalette::Text));
|
||||
|
||||
m_logView->append(text);
|
||||
|
||||
// Auto-scroll to bottom
|
||||
QScrollBar *sb = m_logView->verticalScrollBar();
|
||||
sb->setValue(sb->maximum());
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
#ifndef UPDATEDATABASEDIALOG_H
|
||||
#define UPDATEDATABASEDIALOG_H
|
||||
|
||||
#include <QDialog>
|
||||
#include <QTextEdit>
|
||||
#include <QProgressBar>
|
||||
#include <QLabel>
|
||||
#include <QPushButton>
|
||||
#include <QProcess>
|
||||
#include <QString>
|
||||
|
||||
/**
|
||||
* @brief Non-modal dialog that runs the OCR update script and streams its output.
|
||||
*
|
||||
* The dialog stays open after the process finishes so the user can read the log.
|
||||
* It emits updateFinished() when the script exits successfully so the caller can
|
||||
* reload the gallery.
|
||||
*/
|
||||
class UpdateDatabaseDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit UpdateDatabaseDialog(const QString &scriptPath,
|
||||
const QString &dbPath,
|
||||
const QString &screenshotsDir,
|
||||
QWidget *parent = nullptr);
|
||||
~UpdateDatabaseDialog();
|
||||
|
||||
signals:
|
||||
/** Emitted when the OCR script exits with code 0. */
|
||||
void updateFinished();
|
||||
|
||||
private slots:
|
||||
void onReadyReadStdOut();
|
||||
void onReadyReadStdErr();
|
||||
void onProcessFinished(int exitCode, QProcess::ExitStatus exitStatus);
|
||||
void onCancelClicked();
|
||||
|
||||
private:
|
||||
void startProcess();
|
||||
void appendLog(const QString &text, bool isError = false);
|
||||
|
||||
QString m_scriptPath;
|
||||
QString m_dbPath;
|
||||
QString m_screenshotsDir;
|
||||
|
||||
QLabel *m_statusLabel;
|
||||
QTextEdit *m_logView;
|
||||
QProgressBar*m_progressBar;
|
||||
QPushButton *m_cancelButton;
|
||||
QPushButton *m_closeButton;
|
||||
|
||||
QProcess *m_process;
|
||||
};
|
||||
|
||||
#endif // UPDATEDATABASEDIALOG_H
|
||||
Reference in New Issue
Block a user