tageditor/gui/renamefilesdialog.cpp

414 lines
16 KiB
C++
Raw Normal View History

2015-09-06 20:20:00 +02:00
#include "./renamefilesdialog.h"
#include "./javascripthighlighter.h"
2015-04-22 19:33:53 +02:00
2015-09-06 20:20:00 +02:00
#include "../renamingutility/filesystemitem.h"
#include "../renamingutility/filesystemitemmodel.h"
#include "../renamingutility/filteredfilesystemitemmodel.h"
2018-03-07 01:18:01 +01:00
#include "../renamingutility/renamingengine.h"
2015-09-06 15:41:17 +02:00
2016-01-09 03:38:58 +01:00
#include "../application/settings.h"
2015-12-05 22:55:05 +01:00
#include "ui_renamefilesdialog.h"
2015-04-22 19:33:53 +02:00
#include <qtutilities/misc/dialogutils.h>
2018-03-07 01:18:01 +01:00
#include <QClipboard>
2015-04-22 19:33:53 +02:00
#include <QDir>
2018-03-07 01:18:01 +01:00
#include <QFileDialog>
#include <QFontDatabase>
2015-04-22 19:33:53 +02:00
#include <QItemSelectionModel>
#include <QMenu>
2018-03-07 01:18:01 +01:00
#include <QMessageBox>
2018-06-05 22:45:43 +02:00
#include <QStyle>
2015-04-22 19:33:53 +02:00
#include <QTextStream>
2019-06-10 22:49:46 +02:00
using namespace QtUtilities;
2015-04-22 19:33:53 +02:00
using namespace RenamingUtility;
namespace QtGui {
2018-03-07 01:18:01 +01:00
RenameFilesDialog::RenameFilesDialog(QWidget *parent)
: QDialog(parent)
, m_ui(new Ui::RenameFilesDialog)
, m_itemsProcessed(0)
, m_errorsOccured(0)
, m_changingSelection(false)
, m_scriptModified(false)
2015-04-22 19:33:53 +02:00
{
setAttribute(Qt::WA_QuitOnClose, false);
m_ui->setupUi(this);
2023-03-26 22:19:27 +02:00
updateStyleSheet();
2015-04-22 19:33:53 +02:00
// setup javascript editor and script file selection
2016-09-10 17:19:48 +02:00
m_ui->javaScriptPlainTextEdit->setFont(QFontDatabase::systemFont(QFontDatabase::FixedFont));
2015-04-22 19:33:53 +02:00
m_highlighter = new JavaScriptHighlighter(m_ui->javaScriptPlainTextEdit->document());
m_ui->externalScriptPage->setBackgroundRole(QPalette::Base);
// setup preview tree view
2017-01-06 21:29:43 +01:00
m_engine = new RenamingEngine(this);
2015-04-22 19:33:53 +02:00
m_ui->currentTreeView->setModel(m_engine->currentModel());
m_ui->previewTreeView->setModel(m_engine->previewModel());
// setup notification label
m_ui->notificationLabel->setHidden(true);
// setup pasteScriptButton menu
auto *const pasteScriptButtonMenu = new QMenu(m_ui->pasteScriptPushButton);
pasteScriptButtonMenu->addAction(tr("File"), this, &RenameFilesDialog::showSelectScriptFileDlg);
pasteScriptButtonMenu->addAction(tr("Paste from clipboard"), this, &RenameFilesDialog::pasteScriptFromClipboard);
pasteScriptButtonMenu->addAction(tr("Simple example"), this, &RenameFilesDialog::pasteSimpleExampleScript);
pasteScriptButtonMenu->addAction(tr("Advanced example"), this, &RenameFilesDialog::pasteAdvancedExampleScript);
2015-04-22 19:33:53 +02:00
m_ui->pasteScriptPushButton->setMenu(pasteScriptButtonMenu);
// setup icons
m_ui->generatePreviewPushButton->setIcon(style()->standardIcon(QStyle::SP_BrowserReload, nullptr, m_ui->generatePreviewPushButton));
m_ui->applyChangingsPushButton->setIcon(style()->standardIcon(QStyle::SP_DialogApplyButton, nullptr, m_ui->applyChangingsPushButton));
m_ui->applyChangingsPushButton->setEnabled(false);
2016-03-03 22:21:15 +01:00
m_ui->abortClosePushButton->setIcon(style()->standardIcon(QStyle::SP_DialogCancelButton, nullptr, m_ui->abortClosePushButton));
2015-04-22 19:33:53 +02:00
2016-01-09 03:38:58 +01:00
// restore settings
2016-10-24 20:15:10 +02:00
const auto &settings = Settings::values().renamingUtility;
2018-03-07 01:18:01 +01:00
if (Settings::values().renamingUtility.scriptSource < m_ui->sourceFileStackedWidget->count()) {
2016-10-24 20:15:10 +02:00
m_ui->sourceFileStackedWidget->setCurrentIndex(settings.scriptSource);
2016-01-09 03:38:58 +01:00
}
2016-10-24 20:15:10 +02:00
m_ui->scriptFilePathLineEdit->setText(settings.externalScript);
2018-03-07 01:18:01 +01:00
if (!Settings::values().renamingUtility.editorScript.isEmpty()) {
2016-10-24 20:15:10 +02:00
m_ui->javaScriptPlainTextEdit->setPlainText(settings.editorScript);
m_scriptModified = true;
} else {
pasteSimpleExampleScript();
}
2016-01-09 03:38:58 +01:00
2015-04-22 19:33:53 +02:00
// connect signals and slots
connect(m_ui->generatePreviewPushButton, &QPushButton::clicked, this, &RenameFilesDialog::startGeneratingPreview);
connect(m_ui->applyChangingsPushButton, &QPushButton::clicked, this, &RenameFilesDialog::startApplyChangings);
connect(m_ui->abortClosePushButton, &QPushButton::clicked, this, &RenameFilesDialog::abortClose);
2017-01-06 21:29:43 +01:00
connect(m_engine, &RenamingEngine::previewGenerated, this, &RenameFilesDialog::showPreviewResults);
connect(m_engine, &RenamingEngine::changingsApplied, this, &RenameFilesDialog::showChangsingsResults);
connect(m_engine, &RenamingEngine::progress, this, &RenameFilesDialog::showPreviewProgress);
2015-04-22 19:33:53 +02:00
connect(m_ui->currentTreeView, &QTreeView::customContextMenuRequested, this, &RenameFilesDialog::showTreeViewContextMenu);
connect(m_ui->previewTreeView, &QTreeView::customContextMenuRequested, this, &RenameFilesDialog::showTreeViewContextMenu);
connect(m_ui->currentTreeView->selectionModel(), &QItemSelectionModel::selectionChanged, this, &RenameFilesDialog::currentItemSelected);
connect(m_ui->previewTreeView->selectionModel(), &QItemSelectionModel::selectionChanged, this, &RenameFilesDialog::previewItemSelected);
connect(m_ui->toggleScriptSourcePushButton, &QPushButton::clicked, this, &RenameFilesDialog::toggleScriptSource);
connect(m_ui->selectScriptFilePushButton, &QPushButton::clicked, this, &RenameFilesDialog::showScriptFileSelectionDlg);
connect(m_ui->javaScriptPlainTextEdit, &QPlainTextEdit::undoAvailable, this, &RenameFilesDialog::setScriptModified);
2015-04-22 19:33:53 +02:00
}
RenameFilesDialog::~RenameFilesDialog()
2018-03-07 01:18:01 +01:00
{
}
2015-04-22 19:33:53 +02:00
QString RenameFilesDialog::directory() const
{
2016-04-23 13:31:19 +02:00
return m_ui->directoryWidget->lineEdit()->text();
2015-04-22 19:33:53 +02:00
}
void RenameFilesDialog::setDirectory(const QString &directory)
{
2016-04-23 13:31:19 +02:00
m_ui->directoryWidget->lineEdit()->setText(directory);
2015-04-22 19:33:53 +02:00
}
2016-01-09 03:38:58 +01:00
bool RenameFilesDialog::event(QEvent *event)
{
2016-10-24 20:15:10 +02:00
auto &settings = Settings::values().renamingUtility;
2018-03-07 01:18:01 +01:00
switch (event->type()) {
2023-03-26 22:19:27 +02:00
case QEvent::PaletteChange:
updateStyleSheet();
break;
2016-01-09 03:38:58 +01:00
case QEvent::Close:
// save settings
2016-10-24 20:15:10 +02:00
settings.scriptSource = m_ui->sourceFileStackedWidget->currentIndex();
settings.externalScript = m_ui->scriptFilePathLineEdit->text();
2018-03-07 01:18:01 +01:00
if (m_scriptModified) {
2016-10-24 20:15:10 +02:00
settings.editorScript = m_ui->javaScriptPlainTextEdit->toPlainText();
} else {
2016-10-24 20:15:10 +02:00
settings.editorScript.clear();
}
2016-01-09 03:38:58 +01:00
break;
2018-03-07 01:18:01 +01:00
default:;
2016-01-09 03:38:58 +01:00
}
return QDialog::event(event);
}
2015-04-22 19:33:53 +02:00
void RenameFilesDialog::showScriptFileSelectionDlg()
{
QString file = QFileDialog::getOpenFileName(this, QApplication::applicationName(), m_ui->scriptFilePathLineEdit->text());
2018-03-07 01:18:01 +01:00
if (!file.isEmpty()) {
2015-04-22 19:33:53 +02:00
m_ui->scriptFilePathLineEdit->setText(file);
}
}
void RenameFilesDialog::startGeneratingPreview()
{
2018-03-07 01:18:01 +01:00
if (m_engine->isBusy()) {
2017-01-06 22:15:39 +01:00
return;
}
QDir selectedDir(directory());
m_ui->notificationLabel->setHidden(false);
2018-03-07 01:18:01 +01:00
if (selectedDir.exists()) {
2017-01-06 22:15:39 +01:00
QString program;
2018-03-07 01:18:01 +01:00
if (m_ui->sourceFileStackedWidget->currentIndex() == 0) {
2017-01-06 22:15:39 +01:00
program = m_ui->javaScriptPlainTextEdit->toPlainText();
} else {
QString fileName = m_ui->scriptFilePathLineEdit->text();
2018-03-07 01:18:01 +01:00
if (fileName.isEmpty()) {
2017-01-06 22:15:39 +01:00
m_ui->notificationLabel->setText(tr("There is no external script file is selected."));
2015-04-22 19:33:53 +02:00
} else {
2017-01-06 22:15:39 +01:00
QFile file(fileName);
2018-03-07 01:18:01 +01:00
if (file.open(QFile::ReadOnly)) {
2017-01-06 22:15:39 +01:00
QTextStream textStream(&file);
program = textStream.readAll();
2015-04-22 19:33:53 +02:00
} else {
2017-01-06 22:15:39 +01:00
m_ui->notificationLabel->setText(tr("Unable to open external script file."));
2015-04-22 19:33:53 +02:00
}
}
2017-01-06 22:15:39 +01:00
}
2018-03-07 01:18:01 +01:00
if (!program.isEmpty()) {
if (m_engine->setProgram(program)) {
2017-01-06 22:15:39 +01:00
m_ui->notificationLabel->setText(tr("Generating preview ..."));
m_ui->notificationLabel->setNotificationType(NotificationType::Progress);
m_ui->abortClosePushButton->setText(tr("Abort"));
m_ui->generatePreviewPushButton->setHidden(true);
m_ui->applyChangingsPushButton->setHidden(true);
m_engine->generatePreview(directory(), m_ui->includeSubdirsCheckBox->isChecked());
2015-04-22 19:33:53 +02:00
} else {
m_engine->clearPreview();
2018-03-07 01:18:01 +01:00
if (m_engine->errorLineNumber()) {
m_ui->notificationLabel->setText(
tr("The script is not valid.\nError in line %1: %3").arg(m_engine->errorLineNumber()).arg(m_engine->errorMessage()));
2017-01-06 22:15:39 +01:00
} else {
m_ui->notificationLabel->setText(tr("An error occurred when parsing the script: %1").arg(m_engine->errorMessage()));
2015-04-22 19:33:53 +02:00
}
2017-01-06 22:15:39 +01:00
m_ui->notificationLabel->setNotificationType(NotificationType::Warning);
2015-04-22 19:33:53 +02:00
}
} else {
m_engine->clearPreview();
m_ui->notificationLabel->setNotificationType(NotificationType::Warning);
2018-03-07 01:18:01 +01:00
if (m_ui->notificationLabel->text().isEmpty()) {
2017-01-06 22:15:39 +01:00
m_ui->notificationLabel->setText(tr("The script is empty."));
}
2015-04-22 19:33:53 +02:00
}
2017-01-06 22:15:39 +01:00
} else {
m_engine->clearPreview();
m_ui->notificationLabel->setText(tr("The selected directory doesn't exist."));
m_ui->notificationLabel->setNotificationType(NotificationType::Warning);
2015-04-22 19:33:53 +02:00
}
}
void RenameFilesDialog::startApplyChangings()
{
2018-03-07 01:18:01 +01:00
if (m_engine->isBusy()) {
2017-01-06 22:15:39 +01:00
return;
2015-04-22 19:33:53 +02:00
}
2017-01-06 22:15:39 +01:00
m_ui->notificationLabel->setText(tr("Applying changings ..."));
m_ui->notificationLabel->setNotificationType(NotificationType::Progress);
m_ui->abortClosePushButton->setText(tr("Abort"));
m_ui->generatePreviewPushButton->setHidden(true);
m_ui->applyChangingsPushButton->setHidden(true);
m_engine->applyChangings();
2015-04-22 19:33:53 +02:00
}
void RenameFilesDialog::showPreviewProgress(int itemsProcessed, int errorsOccured)
{
m_itemsProcessed = itemsProcessed;
m_errorsOccured = errorsOccured;
2019-06-10 22:49:46 +02:00
QString text = tr("%1 files/directories processed", nullptr, itemsProcessed).arg(itemsProcessed);
2018-03-07 01:18:01 +01:00
if (m_errorsOccured > 0) {
text.append(QChar('\n'));
text.append(tr("%1 error(s) occurred", nullptr, errorsOccured).arg(errorsOccured));
2015-04-22 19:33:53 +02:00
}
m_ui->notificationLabel->setText(text);
}
void RenameFilesDialog::showPreviewResults()
{
m_ui->abortClosePushButton->setText(tr("Close"));
m_ui->generatePreviewPushButton->setHidden(false);
m_ui->applyChangingsPushButton->setHidden(false);
2018-03-07 01:18:01 +01:00
if (m_engine->rootItem()) {
2015-04-22 19:33:53 +02:00
m_ui->notificationLabel->setText(tr("Preview has been generated."));
2019-06-10 22:49:46 +02:00
m_ui->notificationLabel->appendLine(tr("%1 files/directories have been processed.", nullptr, m_itemsProcessed).arg(m_itemsProcessed));
2015-04-22 19:33:53 +02:00
m_ui->notificationLabel->setNotificationType(NotificationType::Information);
m_ui->applyChangingsPushButton->setEnabled(true);
} else {
m_ui->notificationLabel->setText(tr("No files and directories have been found."));
m_ui->notificationLabel->setNotificationType(NotificationType::Warning);
m_ui->applyChangingsPushButton->setEnabled(false);
}
2018-03-07 01:18:01 +01:00
if (m_engine->isAborted()) {
2015-04-22 19:33:53 +02:00
m_ui->notificationLabel->appendLine(tr("Generation of preview has been aborted prematurely."));
m_ui->notificationLabel->setNotificationType(NotificationType::Warning);
}
2018-03-07 01:18:01 +01:00
if (m_errorsOccured) {
m_ui->notificationLabel->appendLine(tr("%1 error(s) occurred.", nullptr, m_errorsOccured).arg(m_errorsOccured));
2015-04-22 19:33:53 +02:00
m_ui->notificationLabel->setNotificationType(NotificationType::Warning);
}
}
void RenameFilesDialog::showChangsingsResults()
{
m_ui->abortClosePushButton->setText(tr("Close"));
m_ui->generatePreviewPushButton->setHidden(false);
m_ui->applyChangingsPushButton->setHidden(false);
m_ui->notificationLabel->setText(tr("Changins applied."));
2019-06-10 22:49:46 +02:00
m_ui->notificationLabel->appendLine(tr("%1 files/directories have been processed.", nullptr, m_itemsProcessed).arg(m_itemsProcessed));
2015-04-22 19:33:53 +02:00
m_ui->notificationLabel->setNotificationType(NotificationType::Information);
2018-03-07 01:18:01 +01:00
if (m_engine->isAborted()) {
2015-04-22 19:33:53 +02:00
m_ui->notificationLabel->appendLine(tr("Applying has been aborted prematurely."));
m_ui->notificationLabel->setNotificationType(NotificationType::Warning);
}
2018-03-07 01:18:01 +01:00
if (m_errorsOccured) {
m_ui->notificationLabel->appendLine(tr("%1 error(s) occurred.", nullptr, m_errorsOccured).arg(m_errorsOccured));
2015-04-22 19:33:53 +02:00
m_ui->notificationLabel->setNotificationType(NotificationType::Warning);
}
}
void RenameFilesDialog::currentItemSelected(const QItemSelection &, const QItemSelection &)
{
2018-03-07 01:18:01 +01:00
if (m_changingSelection) {
2017-01-06 22:15:39 +01:00
return;
}
m_changingSelection = true;
m_ui->previewTreeView->selectionModel()->clear();
2018-03-07 01:18:01 +01:00
for (const QModelIndex &row : m_ui->currentTreeView->selectionModel()->selectedRows()) {
2017-01-06 22:15:39 +01:00
QModelIndex currentIndex = m_engine->currentModel()->mapToSource(row);
2018-03-07 01:18:01 +01:00
QModelIndex counterpartIndex = m_engine->model()->counterpart(currentIndex, 1);
if (!counterpartIndex.isValid()) {
2017-01-06 22:15:39 +01:00
counterpartIndex = currentIndex;
}
QModelIndex previewIndex = m_engine->previewModel()->mapFromSource(counterpartIndex);
2018-03-07 01:18:01 +01:00
if (previewIndex.isValid()) {
2017-01-06 22:15:39 +01:00
QModelIndex parent = previewIndex.parent();
2018-03-07 01:18:01 +01:00
if (parent.isValid()) {
2017-01-06 22:15:39 +01:00
m_ui->previewTreeView->expand(m_engine->previewModel()->index(parent.row(), parent.column(), parent.parent()));
2015-04-22 19:33:53 +02:00
}
2017-01-06 22:15:39 +01:00
m_ui->previewTreeView->scrollTo(previewIndex);
m_ui->previewTreeView->selectionModel()->select(previewIndex, QItemSelectionModel::Rows | QItemSelectionModel::Select);
2015-04-22 19:33:53 +02:00
}
}
2017-01-06 22:15:39 +01:00
m_changingSelection = false;
2015-04-22 19:33:53 +02:00
}
void RenameFilesDialog::previewItemSelected(const QItemSelection &, const QItemSelection &)
{
2018-03-07 01:18:01 +01:00
if (m_changingSelection) {
2017-01-06 22:15:39 +01:00
return;
}
m_changingSelection = true;
m_ui->currentTreeView->selectionModel()->clear();
2018-03-07 01:18:01 +01:00
for (const QModelIndex &row : m_ui->previewTreeView->selectionModel()->selectedRows()) {
2017-01-06 22:15:39 +01:00
QModelIndex previewIndex = m_engine->previewModel()->mapToSource(row);
2018-03-07 01:18:01 +01:00
QModelIndex counterpartIndex = m_engine->model()->counterpart(previewIndex, 0);
if (!counterpartIndex.isValid()) {
2017-01-06 22:15:39 +01:00
counterpartIndex = previewIndex;
}
QModelIndex currentIndex = m_engine->currentModel()->mapFromSource(counterpartIndex);
2018-03-07 01:18:01 +01:00
if (currentIndex.isValid()) {
2017-01-06 22:15:39 +01:00
QModelIndex parent = currentIndex.parent();
2018-03-07 01:18:01 +01:00
if (parent.isValid()) {
2017-01-06 22:15:39 +01:00
m_ui->currentTreeView->expand(m_engine->currentModel()->index(parent.row(), parent.column(), parent.parent()));
2015-04-22 19:33:53 +02:00
}
2017-01-06 22:15:39 +01:00
m_ui->currentTreeView->scrollTo(currentIndex);
m_ui->currentTreeView->selectionModel()->select(currentIndex, QItemSelectionModel::Rows | QItemSelectionModel::Select);
2015-04-22 19:33:53 +02:00
}
}
2017-01-06 22:15:39 +01:00
m_changingSelection = false;
2015-04-22 19:33:53 +02:00
}
void RenameFilesDialog::pasteScriptFromFile(const QString &fileName)
{
QFile file(fileName);
2018-03-07 01:18:01 +01:00
if (file.open(QFile::ReadOnly)) {
2015-04-22 19:33:53 +02:00
QTextStream textStream(&file);
m_ui->javaScriptPlainTextEdit->setPlainText(textStream.readAll());
} else {
QMessageBox::warning(this, windowTitle(), tr("Unable to open script file."));
}
}
void RenameFilesDialog::showSelectScriptFileDlg()
{
QString fileName = QFileDialog::getOpenFileName(this, tr("Select script"));
2018-03-07 01:18:01 +01:00
if (!fileName.isEmpty()) {
2015-04-22 19:33:53 +02:00
pasteScriptFromFile(fileName);
}
}
void RenameFilesDialog::abortClose()
{
2018-03-07 01:18:01 +01:00
if (m_engine->isBusy()) {
2015-04-22 19:33:53 +02:00
m_engine->abort();
} else {
close();
}
}
void RenameFilesDialog::pasteScriptFromClipboard()
{
2017-01-06 22:15:39 +01:00
const QString script = QApplication::clipboard()->text();
2018-03-07 01:18:01 +01:00
if (script.isEmpty()) {
2015-04-22 19:33:53 +02:00
QMessageBox::warning(this, windowTitle(), tr("Clipboard contains no text."));
2017-01-06 22:15:39 +01:00
return;
2015-04-22 19:33:53 +02:00
}
2017-01-06 22:15:39 +01:00
m_ui->javaScriptPlainTextEdit->setPlainText(script);
2015-04-22 19:33:53 +02:00
}
void RenameFilesDialog::pasteSimpleExampleScript()
2015-04-22 19:33:53 +02:00
{
pasteScriptFromFile(QStringLiteral(":/scripts/renamefiles/simple-example"));
}
void RenameFilesDialog::pasteAdvancedExampleScript()
{
pasteScriptFromFile(QStringLiteral(":/scripts/renamefiles/advanced-example"));
2015-04-22 19:33:53 +02:00
}
void RenameFilesDialog::showTreeViewContextMenu(const QPoint &position)
2015-04-22 19:33:53 +02:00
{
2018-03-07 01:18:01 +01:00
if (const QTreeView *sender = qobject_cast<const QTreeView *>(QObject::sender())) {
2015-04-22 19:33:53 +02:00
QMenu menu;
menu.addAction(tr("Expand all"), sender, &QTreeView::expandAll);
menu.addAction(tr("Collapse all"), sender, &QTreeView::collapseAll);
menu.exec(sender->viewport()->mapToGlobal(position));
2015-04-22 19:33:53 +02:00
}
}
void RenameFilesDialog::toggleScriptSource()
{
int nextIndex;
2018-03-07 01:18:01 +01:00
switch (m_ui->sourceFileStackedWidget->currentIndex()) {
2015-04-22 19:33:53 +02:00
case 0:
nextIndex = 1;
break;
default:
nextIndex = 0;
}
m_ui->sourceFileStackedWidget->setCurrentIndex(nextIndex);
2018-03-07 01:18:01 +01:00
switch (nextIndex) {
2015-04-22 19:33:53 +02:00
case 0:
m_ui->pasteScriptPushButton->setVisible(true);
m_ui->toggleScriptSourcePushButton->setText("Use external file");
break;
default:
m_ui->pasteScriptPushButton->setVisible(false);
m_ui->toggleScriptSourcePushButton->setText("Use editor");
}
}
void RenameFilesDialog::setScriptModified(bool scriptModified)
{
m_scriptModified = scriptModified;
}
2023-03-26 22:19:27 +02:00
void RenameFilesDialog::updateStyleSheet()
{
#ifdef Q_OS_WINDOWS
setStyleSheet(dialogStyleForPalette(palette()) + QStringLiteral("QSplitter:handle { background-color: palette(base); }"));
#endif
}
2018-03-07 01:18:01 +01:00
} // namespace QtGui