Files
tenmon/batchprocessing.cpp
T

219 lines
6.5 KiB
C++

#include "batchprocessing.h"
#include "ui_batchprocessing.h"
#include <QDir>
#include <QFileDialog>
#include <QStandardPaths>
#include <QProcess>
#include <QSettings>
#include <QCloseEvent>
#include <QMessageBox>
#include "scriptengine.h"
#ifdef Q_OS_LINUX
#include <QCloseEvent>
#include <QDBusConnection>
#include <QDBusMessage>
#include <QMessageBox>
#endif
void scanDirectory(const QString &path, QStringList &files)
{
QFileInfo info(path);
if(info.isDir())
{
QDir dir(path);
QStringList entries = dir.entryList(QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot);
for(QString &entry : entries)
scanDirectory(dir.absoluteFilePath(entry), files);
}
else if(info.isFile())
{
files.append(path);
}
}
QStringList scanDirectories(const QStringList &paths)
{
QStringList files;
for(const QString &path : paths)
scanDirectory(path, files);
return files;
}
void BatchProcessing::scanScriptDir()
{
_ui->scriptsList->clear();
QDir dir(_scriptBasePath);
for(const QString &script : dir.entryList(QDir::Files | QDir::Readable))
{
_ui->scriptsList->addItem(script);
}
}
BatchProcessing::BatchProcessing(QWidget *parent) : QDialog(parent)
{
_ui = new Ui::BatchProcessing;
_ui->setupUi(this);
QStringList scriptsPath = QStandardPaths::standardLocations(QStandardPaths::AppDataLocation);
if(scriptsPath.size())
{
QDir dir(scriptsPath.first());
if(!dir.exists("scripts"))
{
if(!dir.mkpath("scripts"))
qWarning() << "Failed to create scripts directory";
}
dir.cd("scripts");
_scriptBasePath = dir.absolutePath() + "/";
scanScriptDir();
_fileWatcher.addPath(_scriptBasePath);
connect(&_fileWatcher, &QFileSystemWatcher::directoryChanged, this, &BatchProcessing::scanScriptDir);
}
else
{
qWarning() << "Failed to get app data location";
}
connect(_ui->addFilesButton, &QPushButton::released, this, &BatchProcessing::addFiles);
connect(_ui->addDirButton, &QPushButton::released, this, &BatchProcessing::addDir);
connect(_ui->removeButton, &QPushButton::released, this, &BatchProcessing::removePath);
connect(_ui->removeAllButton, &QPushButton::released, this, &BatchProcessing::removeAllPaths);
connect(_ui->startButton, &QPushButton::released, this, &BatchProcessing::runScript);
connect(_ui->stopButton, &QPushButton::released, this, &BatchProcessing::stopScript);
connect(_ui->browseButton, &QPushButton::released, this, &BatchProcessing::browse);
connect(_ui->openScriptsButton, &QPushButton::released, this, &BatchProcessing::openScriptDir);
QSettings settings;
_ui->outputPath->setText(settings.value("batchprocessing/outputpath", QStandardPaths::standardLocations(QStandardPaths::PicturesLocation).first()).toString());
}
BatchProcessing::~BatchProcessing()
{
delete _engineThread;
QSettings settings;
settings.setValue("batchprocessing/outputpath", _ui->outputPath->text());
delete _ui;
}
void BatchProcessing::closeEvent(QCloseEvent *event)
{
if(_engineThread)
{
QMessageBox::StandardButton ret = QMessageBox::question(this, tr("Interrupt running script?"), tr("Interrupt running script?"));
if(ret == QMessageBox::StandardButton::Yes)
{
_engineThread->interrupt();
event->accept();
}
else
{
event->ignore();
}
}
else
{
event->accept();
}
}
void BatchProcessing::addFiles()
{
QStringList files = QFileDialog::getOpenFileNames(this, tr("Select files"), "/home/nou/Obrázky/astro");
_ui->pathsList->addItems(files);
}
void BatchProcessing::addDir()
{
QString dir = QFileDialog::getExistingDirectory(this, tr("Select directory"), "/home/nou/Obrázky/astro");
if(!dir.isEmpty())
_ui->pathsList->addItem(dir);
}
void BatchProcessing::removePath()
{
for(auto &item : _ui->pathsList->selectedItems())
delete item;
}
void BatchProcessing::removeAllPaths()
{
_ui->pathsList->clear();
}
void BatchProcessing::browse()
{
QString output = QFileDialog::getExistingDirectory(this, tr("Select output directory"), "/home/nou/Obrázky");
if(!output.isEmpty())
_ui->outputPath->setText(output);
}
void BatchProcessing::openScriptDir()
{
#ifdef Q_OS_LINUX
QDBusConnection con = QDBusConnection::sessionBus();
QDBusMessage message = QDBusMessage::createMethodCall("org.freedesktop.FileManager1", "/org/freedesktop/FileManager1", "org.freedesktop.FileManager1", "ShowFolders");
QList<QVariant> args = {QStringList(QUrl::fromLocalFile(_scriptBasePath).toString()), QString()};
message.setArguments(args);
con.call(message);
#endif
#ifdef Q_OS_WINDOWS
QProcess::startDetached("explorer.exe", {QDir::toNativeSeparators(_scriptBasePath)});
#endif
}
void BatchProcessing::runScript()
{
_ui->log->clear();
auto selectedItems = _ui->scriptsList->selectedItems();
if(selectedItems.size())
{
_engineThread = new Script::ScriptEngineThread(this);
connect(_engineThread, &Script::ScriptEngineThread::newMessage, this, &BatchProcessing::newMessage);
connect(_engineThread, &Script::ScriptEngineThread::finished, this, &BatchProcessing::scriptFinished);
QStringList paths;
for(int i=0; i<_ui->pathsList->count(); i++)
paths.append(_ui->pathsList->item(i)->text());
QFileInfo outDir(_ui->outputPath->text());
if(outDir.exists() && outDir.isWritable())
{
_engineThread->setParams(_scriptBasePath + selectedItems.first()->text(), scanDirectories(paths), _ui->outputPath->text());
_engineThread->start();
_ui->startButton->setEnabled(false);
_ui->stopButton->setEnabled(true);
}
else
{
QMessageBox::warning(this, tr("Invalid output directory"), tr("Output directory path doesn't exist or is not writable"));
}
}
}
void BatchProcessing::stopScript()
{
qDebug() << "Stop script";
if(_engineThread)
_engineThread->interrupt();
}
void BatchProcessing::scriptFinished()
{
_ui->startButton->setEnabled(true);
_ui->stopButton->setEnabled(false);
qDebug() << "script finished";
delete _engineThread;
_engineThread = nullptr;
}
void BatchProcessing::newMessage(const QString &message, bool error)
{
QColor color = _ui->log->textColor();
if(error)_ui->log->setTextColor(Qt::red);
_ui->log->append(message);
if(error)_ui->log->setTextColor(color);
}