updated renaming utility
- allow usage of QJSEngine instead of deprecated QScriptEngine - moved variables and functions from global object to tageditor object
This commit is contained in:
parent
10bfa8aeea
commit
1c4d577264
|
@ -60,7 +60,8 @@ set(WIDGETS_HEADER_FILES
|
||||||
renamingutility/filesystemitemmodel.h
|
renamingutility/filesystemitemmodel.h
|
||||||
renamingutility/filteredfilesystemitemmodel.h
|
renamingutility/filteredfilesystemitemmodel.h
|
||||||
renamingutility/renamingengine.h
|
renamingutility/renamingengine.h
|
||||||
renamingutility/scriptfunctions.h
|
renamingutility/scriptdefs.h
|
||||||
|
renamingutility/tageditorobject.h
|
||||||
)
|
)
|
||||||
set(WIDGETS_SRC_FILES
|
set(WIDGETS_SRC_FILES
|
||||||
gui/attachmentsedit.cpp
|
gui/attachmentsedit.cpp
|
||||||
|
@ -77,7 +78,6 @@ set(WIDGETS_SRC_FILES
|
||||||
gui/infowidgetbase.cpp
|
gui/infowidgetbase.cpp
|
||||||
gui/initiate.cpp
|
gui/initiate.cpp
|
||||||
gui/javascripthighlighter.cpp
|
gui/javascripthighlighter.cpp
|
||||||
gui/previousvaluehandling.cpp
|
|
||||||
gui/renamefilesdialog.cpp
|
gui/renamefilesdialog.cpp
|
||||||
gui/settingsdialog.cpp
|
gui/settingsdialog.cpp
|
||||||
gui/tagedit.cpp
|
gui/tagedit.cpp
|
||||||
|
@ -86,7 +86,7 @@ set(WIDGETS_SRC_FILES
|
||||||
renamingutility/filesystemitemmodel.cpp
|
renamingutility/filesystemitemmodel.cpp
|
||||||
renamingutility/filteredfilesystemitemmodel.cpp
|
renamingutility/filteredfilesystemitemmodel.cpp
|
||||||
renamingutility/renamingengine.cpp
|
renamingutility/renamingengine.cpp
|
||||||
renamingutility/scriptfunctions.cpp
|
renamingutility/tageditorobject.h
|
||||||
resources/icons.qrc
|
resources/icons.qrc
|
||||||
resources/scripts.qrc
|
resources/scripts.qrc
|
||||||
)
|
)
|
||||||
|
|
|
@ -113,7 +113,10 @@ Here are some Bash examples which illustrate getting and setting tag information
|
||||||
## Build instructions
|
## Build instructions
|
||||||
The application depends on c++utilities, qtutilities and tagparser and is built in the same way as these libaries.
|
The application depends on c++utilities, qtutilities and tagparser and is built in the same way as these libaries.
|
||||||
|
|
||||||
The following Qt 5 modules are requried: core gui script widgets webenginewidgets/webkitwidgets
|
The following Qt 5 modules are requried: core gui qml/script widgets webenginewidgets/webkitwidgets
|
||||||
|
|
||||||
|
If script is installed on the system, the editor will link against it. Otherwise it will link against qml.
|
||||||
|
To force usage of qml add "CONFIG+=forcejsengine" to the qmake arguments.
|
||||||
|
|
||||||
If webkitwidgets is installed on the system, the editor will link against it. Otherwise it will link against webenginewidgets.
|
If webkitwidgets is installed on the system, the editor will link against it. Otherwise it will link against webenginewidgets.
|
||||||
To force usage of webenginewidgets add "CONFIG+=forcewebengine" to the qmake arguments.
|
To force usage of webenginewidgets add "CONFIG+=forcewebengine" to the qmake arguments.
|
||||||
|
|
|
@ -4,11 +4,6 @@
|
||||||
|
|
||||||
namespace QtGui {
|
namespace QtGui {
|
||||||
|
|
||||||
/*
|
|
||||||
TRANSLATOR QtGui::FileFilterProxyModel
|
|
||||||
Necessary for lupdate.
|
|
||||||
*/
|
|
||||||
|
|
||||||
FileFilterProxyModel::FileFilterProxyModel(QObject *parent) :
|
FileFilterProxyModel::FileFilterProxyModel(QObject *parent) :
|
||||||
QSortFilterProxyModel(parent),
|
QSortFilterProxyModel(parent),
|
||||||
m_filterEnabled(true)
|
m_filterEnabled(true)
|
||||||
|
|
|
@ -23,11 +23,6 @@ using namespace Media;
|
||||||
|
|
||||||
namespace QtGui {
|
namespace QtGui {
|
||||||
|
|
||||||
/*
|
|
||||||
TRANSLATOR QtGui::InfoWidgetBase
|
|
||||||
Necessary for lupdate.
|
|
||||||
*/
|
|
||||||
|
|
||||||
InfoWidgetBase::InfoWidgetBase(QWidget *parent) :
|
InfoWidgetBase::InfoWidgetBase(QWidget *parent) :
|
||||||
QWidget(parent),
|
QWidget(parent),
|
||||||
m_notificationModel(nullptr)
|
m_notificationModel(nullptr)
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
|
|
||||||
// include configuration from separate header file when building with CMake
|
// include configuration from separate header file when building with CMake
|
||||||
#ifndef APP_METADATA_AVAIL
|
#ifndef APP_METADATA_AVAIL
|
||||||
#include "resources/config.h"
|
# include "resources/config.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <qtutilities/resources/qtconfigarguments.h>
|
#include <qtutilities/resources/qtconfigarguments.h>
|
||||||
|
|
|
@ -64,11 +64,6 @@ using namespace Widgets;
|
||||||
|
|
||||||
namespace QtGui {
|
namespace QtGui {
|
||||||
|
|
||||||
/*
|
|
||||||
TRANSLATOR QtGui::MainWindow
|
|
||||||
Necessary for lupdate.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief The LoadingResult enum specifies whether the file could be parsed.
|
* \brief The LoadingResult enum specifies whether the file could be parsed.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -27,9 +27,6 @@ NotificationLabel::NotificationLabel(QWidget *parent) :
|
||||||
m_updateTimer.setInterval(80);
|
m_updateTimer.setInterval(80);
|
||||||
}
|
}
|
||||||
|
|
||||||
NotificationLabel::~NotificationLabel()
|
|
||||||
{}
|
|
||||||
|
|
||||||
void NotificationLabel::paintEvent(QPaintEvent *event)
|
void NotificationLabel::paintEvent(QPaintEvent *event)
|
||||||
{
|
{
|
||||||
QStyle *style = QWidget::style();
|
QStyle *style = QWidget::style();
|
||||||
|
|
|
@ -33,7 +33,6 @@ class NotificationLabel : public QWidget
|
||||||
Q_PROPERTY(int maxIconSize READ maxIconSize WRITE setMaxIconSize)
|
Q_PROPERTY(int maxIconSize READ maxIconSize WRITE setMaxIconSize)
|
||||||
public:
|
public:
|
||||||
explicit NotificationLabel(QWidget *parent = nullptr);
|
explicit NotificationLabel(QWidget *parent = nullptr);
|
||||||
virtual ~NotificationLabel();
|
|
||||||
|
|
||||||
const QString &text() const;
|
const QString &text() const;
|
||||||
NotificationType notificationType() const;
|
NotificationType notificationType() const;
|
||||||
|
|
|
@ -12,11 +12,6 @@ using namespace Media;
|
||||||
|
|
||||||
namespace QtGui {
|
namespace QtGui {
|
||||||
|
|
||||||
/*
|
|
||||||
TRANSLATOR QtGui::NotificationModel
|
|
||||||
Necessary for lupdate.
|
|
||||||
*/
|
|
||||||
|
|
||||||
NotificationModel::NotificationModel(QObject *parent) :
|
NotificationModel::NotificationModel(QObject *parent) :
|
||||||
QAbstractListModel(parent)
|
QAbstractListModel(parent)
|
||||||
{}
|
{}
|
||||||
|
|
|
@ -15,18 +15,10 @@ using namespace Widgets;
|
||||||
|
|
||||||
namespace QtGui {
|
namespace QtGui {
|
||||||
|
|
||||||
/*
|
|
||||||
TRANSLATOR QtGui::PathLineEdit
|
|
||||||
Necessary for lupdate.
|
|
||||||
*/
|
|
||||||
|
|
||||||
PathLineEdit::PathLineEdit(QWidget *parent) :
|
PathLineEdit::PathLineEdit(QWidget *parent) :
|
||||||
ClearLineEdit(parent)
|
ClearLineEdit(parent)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
PathLineEdit::~PathLineEdit()
|
|
||||||
{}
|
|
||||||
|
|
||||||
QAbstractItemModel *PathLineEdit::completionModel() const
|
QAbstractItemModel *PathLineEdit::completionModel() const
|
||||||
{
|
{
|
||||||
if(QCompleter *c = completer()) {
|
if(QCompleter *c = completer()) {
|
||||||
|
|
|
@ -18,7 +18,6 @@ class PathLineEdit : public Widgets::ClearLineEdit
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit PathLineEdit(QWidget *parent = nullptr);
|
explicit PathLineEdit(QWidget *parent = nullptr);
|
||||||
virtual ~PathLineEdit();
|
|
||||||
|
|
||||||
QAbstractItemModel *completionModel() const;
|
QAbstractItemModel *completionModel() const;
|
||||||
void setCompletionModel(QAbstractItemModel *model);
|
void setCompletionModel(QAbstractItemModel *model);
|
||||||
|
|
|
@ -35,11 +35,6 @@ using namespace Media;
|
||||||
|
|
||||||
namespace QtGui {
|
namespace QtGui {
|
||||||
|
|
||||||
/*
|
|
||||||
TRANSLATOR QtGui::PicturePreviewSelection
|
|
||||||
Necessary for lupdate.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Constructs a new PicturePreviewSelection for the specified \a tag and \a field.
|
* \brief Constructs a new PicturePreviewSelection for the specified \a tag and \a field.
|
||||||
*/
|
*/
|
||||||
|
@ -65,7 +60,7 @@ PicturePreviewSelection::PicturePreviewSelection(Tag *tag, KnownField field, QWi
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Destroys the PicturePreviewSelection.
|
* \brief Destroys the instance.
|
||||||
*/
|
*/
|
||||||
PicturePreviewSelection::~PicturePreviewSelection()
|
PicturePreviewSelection::~PicturePreviewSelection()
|
||||||
{}
|
{}
|
||||||
|
|
|
@ -35,7 +35,7 @@ class PicturePreviewSelection : public QWidget
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit PicturePreviewSelection(Media::Tag *tag = nullptr, Media::KnownField field = Media::KnownField::Invalid, QWidget *parent = nullptr);
|
explicit PicturePreviewSelection(Media::Tag *tag = nullptr, Media::KnownField field = Media::KnownField::Invalid, QWidget *parent = nullptr);
|
||||||
virtual ~PicturePreviewSelection();
|
~PicturePreviewSelection();
|
||||||
|
|
||||||
Media::Tag *tag() const;
|
Media::Tag *tag() const;
|
||||||
Media::KnownField field() const;
|
Media::KnownField field() const;
|
||||||
|
|
|
@ -1,5 +0,0 @@
|
||||||
#include "./previousvaluehandling.h"
|
|
||||||
|
|
||||||
namespace QtGui {
|
|
||||||
|
|
||||||
}
|
|
|
@ -13,7 +13,6 @@
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
#include <QFileDialog>
|
#include <QFileDialog>
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include <QScriptEngine>
|
|
||||||
#include <QItemSelectionModel>
|
#include <QItemSelectionModel>
|
||||||
#include <QMenu>
|
#include <QMenu>
|
||||||
#include <QClipboard>
|
#include <QClipboard>
|
||||||
|
@ -26,11 +25,6 @@ using namespace RenamingUtility;
|
||||||
|
|
||||||
namespace QtGui {
|
namespace QtGui {
|
||||||
|
|
||||||
/*
|
|
||||||
TRANSLATOR QtGui::RenameFilesDialog
|
|
||||||
Necessary for lupdate.
|
|
||||||
*/
|
|
||||||
|
|
||||||
RenameFilesDialog::RenameFilesDialog(QWidget *parent) :
|
RenameFilesDialog::RenameFilesDialog(QWidget *parent) :
|
||||||
QDialog(parent),
|
QDialog(parent),
|
||||||
m_ui(new Ui::RenameFilesDialog),
|
m_ui(new Ui::RenameFilesDialog),
|
||||||
|
@ -44,7 +38,7 @@ RenameFilesDialog::RenameFilesDialog(QWidget *parent) :
|
||||||
setStyleSheet(dialogStyle() + QStringLiteral("QSplitter:handle { background-color: palette(base); }"));
|
setStyleSheet(dialogStyle() + QStringLiteral("QSplitter:handle { background-color: palette(base); }"));
|
||||||
#endif
|
#endif
|
||||||
// setup javascript editor and script file selection
|
// setup javascript editor and script file selection
|
||||||
QFont font("Courier", 10);
|
QFont font(QStringLiteral("Courier"), 10);
|
||||||
font.setFixedPitch(true);
|
font.setFixedPitch(true);
|
||||||
m_ui->javaScriptPlainTextEdit->setFont(font);
|
m_ui->javaScriptPlainTextEdit->setFont(font);
|
||||||
m_highlighter = new JavaScriptHighlighter(m_ui->javaScriptPlainTextEdit->document());
|
m_highlighter = new JavaScriptHighlighter(m_ui->javaScriptPlainTextEdit->document());
|
||||||
|
@ -124,7 +118,6 @@ void RenameFilesDialog::startGeneratingPreview()
|
||||||
QDir selectedDir(directory());
|
QDir selectedDir(directory());
|
||||||
m_ui->notificationLabel->setHidden(false);
|
m_ui->notificationLabel->setHidden(false);
|
||||||
if(selectedDir.exists()) {
|
if(selectedDir.exists()) {
|
||||||
QScriptEngine engine;
|
|
||||||
QString program;
|
QString program;
|
||||||
if(m_ui->sourceFileStackedWidget->currentIndex() == 0) {
|
if(m_ui->sourceFileStackedWidget->currentIndex() == 0) {
|
||||||
program = m_ui->javaScriptPlainTextEdit->toPlainText();
|
program = m_ui->javaScriptPlainTextEdit->toPlainText();
|
||||||
|
@ -143,18 +136,17 @@ void RenameFilesDialog::startGeneratingPreview()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(!program.isEmpty()) {
|
if(!program.isEmpty()) {
|
||||||
QScriptSyntaxCheckResult res = engine.checkSyntax(program);
|
if(m_engine->setProgram(program)) {
|
||||||
if(res.state() != QScriptSyntaxCheckResult::Error) {
|
|
||||||
m_ui->notificationLabel->setText(tr("Generating preview ..."));
|
m_ui->notificationLabel->setText(tr("Generating preview ..."));
|
||||||
m_ui->notificationLabel->setNotificationType(NotificationType::Progress);
|
m_ui->notificationLabel->setNotificationType(NotificationType::Progress);
|
||||||
m_ui->abortClosePushButton->setText(tr("Abort"));
|
m_ui->abortClosePushButton->setText(tr("Abort"));
|
||||||
m_ui->generatePreviewPushButton->setHidden(true);
|
m_ui->generatePreviewPushButton->setHidden(true);
|
||||||
m_ui->applyChangingsPushButton->setHidden(true);
|
m_ui->applyChangingsPushButton->setHidden(true);
|
||||||
m_engine->generatePreview(program, directory(), m_ui->includeSubdirsCheckBox->isChecked());
|
m_engine->generatePreview(directory(), m_ui->includeSubdirsCheckBox->isChecked());
|
||||||
} else {
|
} else {
|
||||||
m_engine->clearPreview();
|
m_engine->clearPreview();
|
||||||
m_ui->notificationLabel->setText(tr("The script is not valid.\nError in line %1 and column %2:\n %3")
|
m_ui->notificationLabel->setText(tr("The script is not valid.\nError in line %1: %3")
|
||||||
.arg(res.errorLineNumber()).arg(res.errorColumnNumber()).arg(res.errorMessage()));
|
.arg(m_engine->errorLineNumber()).arg(m_engine->errorMessage()));
|
||||||
m_ui->notificationLabel->setNotificationType(NotificationType::Warning);
|
m_ui->notificationLabel->setNotificationType(NotificationType::Warning);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -191,7 +183,7 @@ void RenameFilesDialog::showPreviewProgress(int itemsProcessed, int errorsOccure
|
||||||
m_errorsOccured = errorsOccured;
|
m_errorsOccured = errorsOccured;
|
||||||
QString text = tr("%1 files/directories processed", 0, itemsProcessed).arg(itemsProcessed);
|
QString text = tr("%1 files/directories processed", 0, itemsProcessed).arg(itemsProcessed);
|
||||||
if(m_errorsOccured > 0) {
|
if(m_errorsOccured > 0) {
|
||||||
text.append(QStringLiteral("\n"));
|
text.append(QChar('\n'));
|
||||||
text.append(tr("%1 error(s) occured", 0, errorsOccured).arg(errorsOccured));
|
text.append(tr("%1 error(s) occured", 0, errorsOccured).arg(errorsOccured));
|
||||||
}
|
}
|
||||||
m_ui->notificationLabel->setText(text);
|
m_ui->notificationLabel->setText(text);
|
||||||
|
|
|
@ -20,11 +20,6 @@ using namespace Media;
|
||||||
|
|
||||||
namespace QtGui {
|
namespace QtGui {
|
||||||
|
|
||||||
/*
|
|
||||||
TRANSLATOR QtGui::TagEdit
|
|
||||||
Necessary for lupdate.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \class QtGui::TagEdit
|
* \class QtGui::TagEdit
|
||||||
* \brief The TagEdit widget allows the user to edit Media::Tag objects.
|
* \brief The TagEdit widget allows the user to edit Media::Tag objects.
|
||||||
|
@ -55,14 +50,6 @@ TagEdit::TagEdit(QWidget *parent) :
|
||||||
setLayout(mainLayout);
|
setLayout(mainLayout);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
|
||||||
* \brief Destroys the tag edit.
|
|
||||||
*
|
|
||||||
* Does not destroy assigned tags.
|
|
||||||
*/
|
|
||||||
TagEdit::~TagEdit()
|
|
||||||
{}
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Assigns the specified \a tag to the edit.
|
* \brief Assigns the specified \a tag to the edit.
|
||||||
* \param updateUi Specifies whether the UI of should be updated.
|
* \param updateUi Specifies whether the UI of should be updated.
|
||||||
|
|
|
@ -31,7 +31,6 @@ class TagEdit : public QWidget
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit TagEdit(QWidget *parent = nullptr);
|
explicit TagEdit(QWidget *parent = nullptr);
|
||||||
~TagEdit();
|
|
||||||
const QList<Media::Tag *> &tags() const;
|
const QList<Media::Tag *> &tags() const;
|
||||||
void setTag(Media::Tag *tag, bool updateUi = true);
|
void setTag(Media::Tag *tag, bool updateUi = true);
|
||||||
void setTags(const QList<Media::Tag *> &tags, bool updateUi = true);
|
void setTags(const QList<Media::Tag *> &tags, bool updateUi = true);
|
||||||
|
|
|
@ -49,11 +49,6 @@ using namespace ConversionUtilities;
|
||||||
|
|
||||||
namespace QtGui {
|
namespace QtGui {
|
||||||
|
|
||||||
/*
|
|
||||||
TRANSLATOR QtGui::TagFieldEdit
|
|
||||||
Necessary for lupdate.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \class QtGui::TagFieldEdit
|
* \class QtGui::TagFieldEdit
|
||||||
* \brief The TagFieldEdit widget allows the user to edit a specified tag field.
|
* \brief The TagFieldEdit widget allows the user to edit a specified tag field.
|
||||||
|
@ -83,14 +78,6 @@ TagFieldEdit::TagFieldEdit(const QList<Media::Tag *> &tags, Media::KnownField fi
|
||||||
updateValue();
|
updateValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
|
||||||
* \brief Destroys the object.
|
|
||||||
*
|
|
||||||
* Does not destroy the assigned tags.
|
|
||||||
*/
|
|
||||||
TagFieldEdit::~TagFieldEdit()
|
|
||||||
{}
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Assigns the specified \a tags and sets the specified \a fields using the given \a previousValueHandling.
|
* \brief Assigns the specified \a tags and sets the specified \a fields using the given \a previousValueHandling.
|
||||||
*
|
*
|
||||||
|
|
|
@ -39,7 +39,6 @@ class TagFieldEdit : public QWidget
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit TagFieldEdit(const QList<Media::Tag *> &tags, Media::KnownField field, QWidget *parent = nullptr);
|
explicit TagFieldEdit(const QList<Media::Tag *> &tags, Media::KnownField field, QWidget *parent = nullptr);
|
||||||
virtual ~TagFieldEdit();
|
|
||||||
|
|
||||||
const QList<Media::Tag *> &tags() const;
|
const QList<Media::Tag *> &tags() const;
|
||||||
Media::KnownField field() const;
|
Media::KnownField field() const;
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
namespace RenamingUtility {
|
namespace RenamingUtility {
|
||||||
|
|
||||||
enum class ActionType {
|
enum class ActionType {
|
||||||
|
None,
|
||||||
Rename,
|
Rename,
|
||||||
Skip
|
Skip
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,13 +1,12 @@
|
||||||
#include "./renamingengine.h"
|
#include "./renamingengine.h"
|
||||||
#include "./filesystemitemmodel.h"
|
#include "./filesystemitemmodel.h"
|
||||||
#include "./filteredfilesystemitemmodel.h"
|
#include "./filteredfilesystemitemmodel.h"
|
||||||
#include "./scriptfunctions.h"
|
#include "./tageditorobject.h"
|
||||||
|
|
||||||
#include <c++utilities/misc/memory.h>
|
#include <c++utilities/misc/memory.h>
|
||||||
|
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include <QScriptEngine>
|
#include <QStringBuilder>
|
||||||
#include <QScriptProgram>
|
|
||||||
|
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
|
||||||
|
@ -15,14 +14,10 @@ using namespace std;
|
||||||
|
|
||||||
namespace RenamingUtility {
|
namespace RenamingUtility {
|
||||||
|
|
||||||
/*
|
|
||||||
TRANSLATOR RenamingUtility::RemamingEngine
|
|
||||||
Necessary for lupdate.
|
|
||||||
*/
|
|
||||||
|
|
||||||
RemamingEngine::RemamingEngine(QObject *parent) :
|
RemamingEngine::RemamingEngine(QObject *parent) :
|
||||||
QObject(parent),
|
QObject(parent),
|
||||||
m_go(m_engine.globalObject()),
|
m_tagEditorQObj(new TagEditorObject(&m_engine)),
|
||||||
|
m_tagEditorJsObj(TAGEDITOR_JS_QOBJECT(m_engine, m_tagEditorQObj)),
|
||||||
m_itemsProcessed(0),
|
m_itemsProcessed(0),
|
||||||
m_errorsOccured(0),
|
m_errorsOccured(0),
|
||||||
m_aborted(false),
|
m_aborted(false),
|
||||||
|
@ -31,21 +26,40 @@ RemamingEngine::RemamingEngine(QObject *parent) :
|
||||||
m_currentModel(nullptr),
|
m_currentModel(nullptr),
|
||||||
m_previewModel(nullptr)
|
m_previewModel(nullptr)
|
||||||
{
|
{
|
||||||
|
m_engine.globalObject().setProperty(QStringLiteral("tageditor"), m_tagEditorJsObj);
|
||||||
connect(this, &RemamingEngine::previewGenerated, this, &RemamingEngine::processPreviewGenerated);
|
connect(this, &RemamingEngine::previewGenerated, this, &RemamingEngine::processPreviewGenerated);
|
||||||
connect(this, &RemamingEngine::changingsApplied, this, &RemamingEngine::processChangingsApplied);
|
connect(this, &RemamingEngine::changingsApplied, this, &RemamingEngine::processChangingsApplied);
|
||||||
}
|
}
|
||||||
|
|
||||||
RemamingEngine::~RemamingEngine()
|
bool RemamingEngine::setProgram(const TAGEDITOR_JS_VALUE &program)
|
||||||
{}
|
{
|
||||||
|
if(TAGEDITOR_JS_IS_VALID_PROG(program)) {
|
||||||
|
m_errorMessage.clear();
|
||||||
|
m_errorLineNumber = 0;
|
||||||
|
m_program = program;
|
||||||
|
return true;
|
||||||
|
} else if(program.isError()) {
|
||||||
|
m_errorMessage = program.property(QStringLiteral("message")).toString();
|
||||||
|
m_errorLineNumber = TAGEDITOR_JS_INT(program.property(QStringLiteral("lineNumber")));
|
||||||
|
} else {
|
||||||
|
m_errorMessage = tr("Program is not callable.");
|
||||||
|
m_errorLineNumber = 0;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool RemamingEngine::generatePreview(const QScriptProgram &scriptProgram, const QDir &rootDirectory, bool includeSubdirs)
|
bool RemamingEngine::setProgram(const QString &program)
|
||||||
|
{
|
||||||
|
return setProgram(m_engine.evaluate(QStringLiteral("(function(){") % program % QStringLiteral("})")));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RemamingEngine::generatePreview(const QDir &rootDirectory, bool includeSubdirs)
|
||||||
{
|
{
|
||||||
if(!m_mutex.try_lock()) {
|
if(!m_mutex.try_lock()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
lock_guard<mutex> guard(m_mutex, adopt_lock);
|
lock_guard<mutex> guard(m_mutex, adopt_lock);
|
||||||
setRootItem();
|
setRootItem();
|
||||||
m_program = scriptProgram;
|
|
||||||
m_includeSubdirs = includeSubdirs;
|
m_includeSubdirs = includeSubdirs;
|
||||||
m_dir = rootDirectory;
|
m_dir = rootDirectory;
|
||||||
auto startFunc = [this] () {
|
auto startFunc = [this] () {
|
||||||
|
@ -54,7 +68,6 @@ bool RemamingEngine::generatePreview(const QScriptProgram &scriptProgram, const
|
||||||
m_aborted.store(false);
|
m_aborted.store(false);
|
||||||
m_itemsProcessed = 0;
|
m_itemsProcessed = 0;
|
||||||
m_errorsOccured = 0;
|
m_errorsOccured = 0;
|
||||||
m_go.setProperty("persistent", m_persistent = m_engine.newObject(), QScriptValue::Undeletable);
|
|
||||||
m_newlyGeneratedRootItem = generatePreview(m_dir);
|
m_newlyGeneratedRootItem = generatePreview(m_dir);
|
||||||
}
|
}
|
||||||
emit previewGenerated();
|
emit previewGenerated();
|
||||||
|
@ -174,8 +187,7 @@ unique_ptr<FileSystemItem> RemamingEngine::generatePreview(const QDir &dir, File
|
||||||
{
|
{
|
||||||
auto item = make_unique<FileSystemItem>(ItemStatus::Current, ItemType::Dir, dir.dirName(), parent);
|
auto item = make_unique<FileSystemItem>(ItemStatus::Current, ItemType::Dir, dir.dirName(), parent);
|
||||||
item->setApplied(false);
|
item->setApplied(false);
|
||||||
QFileInfoList entries = dir.entryInfoList();
|
for(const QFileInfo &entry : dir.entryInfoList()) {
|
||||||
foreach(const QFileInfo &entry, entries) {
|
|
||||||
if(entry.fileName() == QLatin1String("..")
|
if(entry.fileName() == QLatin1String("..")
|
||||||
|| entry.fileName() == QLatin1String(".")) {
|
|| entry.fileName() == QLatin1String(".")) {
|
||||||
continue;
|
continue;
|
||||||
|
@ -280,7 +292,7 @@ void RemamingEngine::applyChangings(FileSystemItem *parentItem)
|
||||||
|
|
||||||
void RemamingEngine::setError(const QList<FileSystemItem *> items)
|
void RemamingEngine::setError(const QList<FileSystemItem *> items)
|
||||||
{
|
{
|
||||||
foreach(FileSystemItem *item, items) {
|
for(FileSystemItem *item : items) {
|
||||||
item->setErrorOccured(true);
|
item->setErrorOccured(true);
|
||||||
item->setNote(tr("skipped due to error of superior item"));
|
item->setNote(tr("skipped due to error of superior item"));
|
||||||
}
|
}
|
||||||
|
@ -288,33 +300,30 @@ void RemamingEngine::setError(const QList<FileSystemItem *> items)
|
||||||
|
|
||||||
void RemamingEngine::executeScriptForItem(const QFileInfo &fileInfo, FileSystemItem *item)
|
void RemamingEngine::executeScriptForItem(const QFileInfo &fileInfo, FileSystemItem *item)
|
||||||
{
|
{
|
||||||
|
// make file info for the specified item available in the script
|
||||||
|
m_tagEditorQObj->setFileInfo(fileInfo, item);
|
||||||
// execute script
|
// execute script
|
||||||
setupGlobalObject(fileInfo, item);
|
auto scriptResult = m_program.call();
|
||||||
QScriptValue res = m_engine.evaluate(m_program);
|
if(scriptResult.isError()) {
|
||||||
if(m_engine.hasUncaughtException()) {
|
|
||||||
// handle error
|
// handle error
|
||||||
item->setErrorOccured(true);
|
item->setErrorOccured(true);
|
||||||
item->setNote(res.toString());
|
item->setNote(scriptResult.toString());
|
||||||
m_engine.clearExceptions();
|
|
||||||
} else {
|
} else {
|
||||||
// create preview for action
|
// create preview for action
|
||||||
QScriptValue newName = m_go.property("newName");
|
const QString &newName = m_tagEditorQObj->newName();
|
||||||
QScriptValue newRelativeDirectory = m_go.property("newRelativeDirectory");
|
const QString &newRelativeDirectory = m_tagEditorQObj->newRelativeDirectory();
|
||||||
ActionType action = ActionType::Skip;
|
switch(m_tagEditorQObj->action()) {
|
||||||
if(m_go.property("action").isNumber()) {
|
case ActionType::None:
|
||||||
action = static_cast<ActionType>(m_go.property("action").toInt32());
|
item->setNote(tr("no action specified"));
|
||||||
}
|
break;
|
||||||
switch(action) {
|
|
||||||
case ActionType::Rename:
|
case ActionType::Rename:
|
||||||
if(newRelativeDirectory.isString()) {
|
if(!newRelativeDirectory.isEmpty()) {
|
||||||
FileSystemItem *counterpartParent = item->root()->makeChildAvailable(newRelativeDirectory.toString());
|
FileSystemItem *counterpartParent = item->root()->makeChildAvailable(newRelativeDirectory);
|
||||||
if(counterpartParent->status() == ItemStatus::New
|
if(counterpartParent->status() == ItemStatus::New
|
||||||
&& counterpartParent->note().isEmpty()) {
|
&& counterpartParent->note().isEmpty()) {
|
||||||
counterpartParent->setNote(tr("will be created"));
|
counterpartParent->setNote(tr("will be created"));
|
||||||
}
|
}
|
||||||
QString counterpartName = newName.isString()
|
const QString &counterpartName = newName.isEmpty() ? item->name() : newName;
|
||||||
? newName.toString()
|
|
||||||
: item->name();
|
|
||||||
if(counterpartParent->findChild(counterpartName, item)) {
|
if(counterpartParent->findChild(counterpartName, item)) {
|
||||||
item->setNote(tr("name is already used at new location"));
|
item->setNote(tr("name is already used at new location"));
|
||||||
item->setErrorOccured(true);
|
item->setErrorOccured(true);
|
||||||
|
@ -324,8 +333,8 @@ void RemamingEngine::executeScriptForItem(const QFileInfo &fileInfo, FileSystemI
|
||||||
counterpart->setCheckable(true);
|
counterpart->setCheckable(true);
|
||||||
counterpart->setChecked(true);
|
counterpart->setChecked(true);
|
||||||
}
|
}
|
||||||
} else if(newName.isString()) {
|
} else if(!newName.isEmpty()) {
|
||||||
item->setNewName(newName.toString());
|
item->setNewName(newName);
|
||||||
}
|
}
|
||||||
if(FileSystemItem *newItem = item->counterpart()) {
|
if(FileSystemItem *newItem = item->counterpart()) {
|
||||||
if((newItem->name().isEmpty() || newItem->name() == item->name())
|
if((newItem->name().isEmpty() || newItem->name() == item->name())
|
||||||
|
@ -347,34 +356,8 @@ void RemamingEngine::executeScriptForItem(const QFileInfo &fileInfo, FileSystemI
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
item->setNote(tr("skipped"));
|
item->setNote(tr("skipped"));
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RemamingEngine::setupGlobalObject(const QFileInfo &file, FileSystemItem *item)
|
|
||||||
{
|
|
||||||
// create new global object to clean previous variables ...
|
|
||||||
m_go = m_engine.newObject();
|
|
||||||
// ... except the persistent object
|
|
||||||
m_go.setProperty("persistent", m_persistent, QScriptValue::Undeletable);
|
|
||||||
// provide properties/functions
|
|
||||||
m_go.setProperty("currentPath", file.absoluteFilePath(), QScriptValue::ReadOnly);
|
|
||||||
m_go.setProperty("currentName", item->name(), QScriptValue::ReadOnly);
|
|
||||||
m_go.setProperty("currentRelativeDirectory", item->relativeDir(), QScriptValue::ReadOnly);
|
|
||||||
m_go.setProperty("isDir", item->type() == ItemType::Dir, QScriptValue::ReadOnly);
|
|
||||||
m_go.setProperty("isFile", item->type() == ItemType::File, QScriptValue::ReadOnly);
|
|
||||||
m_go.setProperty("action", QScriptValue(static_cast<int>(ActionType::Rename)), QScriptValue::Undeletable);
|
|
||||||
m_go.setProperty("parseFileInfo", m_engine.newFunction(ScriptFunctions::parseFileInfo), QScriptValue::ReadOnly);
|
|
||||||
m_go.setProperty("parseFileName", m_engine.newFunction(ScriptFunctions::parseFileName), QScriptValue::ReadOnly);
|
|
||||||
m_go.setProperty("allFiles", m_engine.newFunction(ScriptFunctions::allFiles), QScriptValue::ReadOnly);
|
|
||||||
m_go.setProperty("firstFile", m_engine.newFunction(ScriptFunctions::firstFile), QScriptValue::ReadOnly);
|
|
||||||
m_go.setProperty("writeLog", m_engine.newFunction(ScriptFunctions::writeLog), QScriptValue::ReadOnly);
|
|
||||||
QScriptValue actionObject = m_engine.newObject();
|
|
||||||
actionObject.setProperty("rename", QScriptValue(static_cast<int>(ActionType::Rename)), QScriptValue::ReadOnly);
|
|
||||||
actionObject.setProperty("skip", QScriptValue(static_cast<int>(ActionType::Skip)), QScriptValue::ReadOnly);
|
|
||||||
m_go.setProperty("actionType", actionObject, QScriptValue::ReadOnly);
|
|
||||||
m_engine.setGlobalObject(m_go);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace RenamingUtility
|
} // namespace RenamingUtility
|
||||||
|
|
|
@ -2,26 +2,31 @@
|
||||||
#define RENAMINGUTILITY_RENAMINGENGINE_H
|
#define RENAMINGUTILITY_RENAMINGENGINE_H
|
||||||
|
|
||||||
#include "./filesystemitem.h"
|
#include "./filesystemitem.h"
|
||||||
|
#include "./scriptdefs.h"
|
||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QList>
|
#include <QList>
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include <QScriptProgram>
|
|
||||||
#include <QScriptEngine>
|
#if TAGEDITOR_USE_JSENGINE
|
||||||
#include <QScriptValue>
|
# include <QJSEngine>
|
||||||
|
# include <QJSValue>
|
||||||
|
#else
|
||||||
|
# include <QScriptEngine>
|
||||||
|
# include <QScriptValue>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
|
|
||||||
QT_FORWARD_DECLARE_CLASS(QFileInfo)
|
QT_FORWARD_DECLARE_CLASS(QFileInfo)
|
||||||
QT_FORWARD_DECLARE_CLASS(QScriptProgram)
|
|
||||||
QT_FORWARD_DECLARE_CLASS(QScriptContext)
|
|
||||||
|
|
||||||
namespace RenamingUtility {
|
namespace RenamingUtility {
|
||||||
|
|
||||||
class FileSystemItemModel;
|
class FileSystemItemModel;
|
||||||
class FilteredFileSystemItemModel;
|
class FilteredFileSystemItemModel;
|
||||||
|
class TagEditorObject;
|
||||||
|
|
||||||
class RemamingEngine : public QObject
|
class RemamingEngine : public QObject
|
||||||
{
|
{
|
||||||
|
@ -29,10 +34,11 @@ class RemamingEngine : public QObject
|
||||||
|
|
||||||
public:
|
public:
|
||||||
RemamingEngine(QObject *parent = nullptr);
|
RemamingEngine(QObject *parent = nullptr);
|
||||||
virtual ~RemamingEngine();
|
|
||||||
|
|
||||||
FileSystemItem *rootItem() const;
|
FileSystemItem *rootItem() const;
|
||||||
const QScriptProgram &scriptProgram() const;
|
const TAGEDITOR_JS_VALUE &scriptProgram() const;
|
||||||
|
bool setProgram(const TAGEDITOR_JS_VALUE &program);
|
||||||
|
bool setProgram(const QString &program);
|
||||||
const QDir &rootDirectory() const;
|
const QDir &rootDirectory() const;
|
||||||
bool subdirsIncluded() const;
|
bool subdirsIncluded() const;
|
||||||
bool isBusy();
|
bool isBusy();
|
||||||
|
@ -41,9 +47,11 @@ public:
|
||||||
FileSystemItemModel *model();
|
FileSystemItemModel *model();
|
||||||
FilteredFileSystemItemModel *currentModel();
|
FilteredFileSystemItemModel *currentModel();
|
||||||
FilteredFileSystemItemModel *previewModel();
|
FilteredFileSystemItemModel *previewModel();
|
||||||
|
const QString &errorMessage() const;
|
||||||
|
int errorLineNumber() const;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
bool generatePreview(const QScriptProgram &scriptProgram, const QDir &rootDirectory, bool includeSubdirs);
|
bool generatePreview(const QDir &rootDirectory, bool includeSubdirs);
|
||||||
bool applyChangings();
|
bool applyChangings();
|
||||||
void abort();
|
void abort();
|
||||||
|
|
||||||
|
@ -63,23 +71,24 @@ private:
|
||||||
void applyChangings(FileSystemItem *parentItem);
|
void applyChangings(FileSystemItem *parentItem);
|
||||||
static void setError(const QList<FileSystemItem *> items);
|
static void setError(const QList<FileSystemItem *> items);
|
||||||
void executeScriptForItem(const QFileInfo &fileInfo, FileSystemItem *item);
|
void executeScriptForItem(const QFileInfo &fileInfo, FileSystemItem *item);
|
||||||
void setupGlobalObject(const QFileInfo &file, FileSystemItem *item);
|
|
||||||
|
|
||||||
QScriptEngine m_engine;
|
TagEditorObject *m_tagEditorQObj;
|
||||||
QScriptValue m_go;
|
TAGEDITOR_JS_ENGINE m_engine;
|
||||||
QScriptValue m_persistent;
|
TAGEDITOR_JS_VALUE m_tagEditorJsObj;
|
||||||
std::unique_ptr<FileSystemItem> m_rootItem;
|
std::unique_ptr<FileSystemItem> m_rootItem;
|
||||||
std::unique_ptr<FileSystemItem> m_newlyGeneratedRootItem;
|
std::unique_ptr<FileSystemItem> m_newlyGeneratedRootItem;
|
||||||
int m_itemsProcessed;
|
int m_itemsProcessed;
|
||||||
int m_errorsOccured;
|
int m_errorsOccured;
|
||||||
std::atomic<bool> m_aborted;
|
std::atomic<bool> m_aborted;
|
||||||
QScriptProgram m_program;
|
TAGEDITOR_JS_VALUE m_program;
|
||||||
QDir m_dir;
|
QDir m_dir;
|
||||||
bool m_includeSubdirs;
|
bool m_includeSubdirs;
|
||||||
std::mutex m_mutex;
|
std::mutex m_mutex;
|
||||||
FileSystemItemModel *m_model;
|
FileSystemItemModel *m_model;
|
||||||
FilteredFileSystemItemModel *m_currentModel;
|
FilteredFileSystemItemModel *m_currentModel;
|
||||||
FilteredFileSystemItemModel *m_previewModel;
|
FilteredFileSystemItemModel *m_previewModel;
|
||||||
|
QString m_errorMessage;
|
||||||
|
int m_errorLineNumber;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline FileSystemItem *RemamingEngine::rootItem() const
|
inline FileSystemItem *RemamingEngine::rootItem() const
|
||||||
|
@ -87,7 +96,7 @@ inline FileSystemItem *RemamingEngine::rootItem() const
|
||||||
return m_rootItem.get();
|
return m_rootItem.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline const QScriptProgram &RemamingEngine::scriptProgram() const
|
inline const TAGEDITOR_JS_VALUE &RemamingEngine::scriptProgram() const
|
||||||
{
|
{
|
||||||
return m_program;
|
return m_program;
|
||||||
}
|
}
|
||||||
|
@ -102,6 +111,16 @@ inline bool RemamingEngine::subdirsIncluded() const
|
||||||
return m_includeSubdirs;
|
return m_includeSubdirs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline const QString &RemamingEngine::errorMessage() const
|
||||||
|
{
|
||||||
|
return m_errorMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline int RemamingEngine::errorLineNumber() const
|
||||||
|
{
|
||||||
|
return m_errorLineNumber;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace RenamingUtility
|
} // namespace RenamingUtility
|
||||||
|
|
||||||
#endif // RENAMINGUTILITY_RENAMINGENGINE_H
|
#endif // RENAMINGUTILITY_RENAMINGENGINE_H
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
#ifndef SCRIPTDEFS_H
|
||||||
|
#define SCRIPTDEFS_H
|
||||||
|
|
||||||
|
#include <QtGlobal>
|
||||||
|
|
||||||
|
#if TAGEDITOR_USE_JSENGINE
|
||||||
|
# define TAGEDITOR_JS_ENGINE QJSEngine
|
||||||
|
# define TAGEDITOR_JS_VALUE QJSValue
|
||||||
|
# define TAGEDITOR_JS_READONLY
|
||||||
|
# define TAGEDITOR_JS_UNDELETABLE
|
||||||
|
# define TAGEDITOR_JS_QOBJECT(engine, obj) engine.newQObject(obj)
|
||||||
|
# define TAGEDITOR_JS_INT(value) value.toInt()
|
||||||
|
# define TAGEDITOR_JS_IS_VALID_PROG(program) (!program.isError() && program.isCallable())
|
||||||
|
QT_FORWARD_DECLARE_CLASS(QJSValue)
|
||||||
|
QT_FORWARD_DECLARE_CLASS(QJSEngine)
|
||||||
|
#else
|
||||||
|
# define TAGEDITOR_JS_ENGINE QScriptEngine
|
||||||
|
# define TAGEDITOR_JS_VALUE QScriptValue
|
||||||
|
# define TAGEDITOR_JS_READONLY ,QScriptValue::ReadOnly
|
||||||
|
# define TAGEDITOR_JS_UNDELETABLE ,QScriptValue::Undeletable
|
||||||
|
# define TAGEDITOR_JS_QOBJECT(engine, obj) engine.newQObject(obj, QScriptEngine::ScriptOwnership)
|
||||||
|
# define TAGEDITOR_JS_INT(value) value.toInt32()
|
||||||
|
# define TAGEDITOR_JS_IS_VALID_PROG(program) (!program.isError() && program.isFunction())
|
||||||
|
QT_FORWARD_DECLARE_CLASS(QScriptValue)
|
||||||
|
QT_FORWARD_DECLARE_CLASS(QScriptEngine)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // SCRIPTDEFS_H
|
|
@ -1,200 +0,0 @@
|
||||||
#include "./scriptfunctions.h"
|
|
||||||
|
|
||||||
#include "../misc/utility.h"
|
|
||||||
|
|
||||||
#include <tagparser/mediafileinfo.h>
|
|
||||||
#include <tagparser/tag.h>
|
|
||||||
#include <tagparser/tagvalue.h>
|
|
||||||
#include <tagparser/exceptions.h>
|
|
||||||
|
|
||||||
#include <c++utilities/conversion/conversionexception.h>
|
|
||||||
|
|
||||||
#include <QDir>
|
|
||||||
#include <QScriptEngine>
|
|
||||||
#include <QScriptContext>
|
|
||||||
#include <QScriptValue>
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
using namespace ConversionUtilities;
|
|
||||||
using namespace Utility;
|
|
||||||
using namespace Media;
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
namespace RenamingUtility {
|
|
||||||
|
|
||||||
/*
|
|
||||||
TRANSLATOR RenamingUtility::ScriptFunctions
|
|
||||||
Necessary for lupdate.
|
|
||||||
*/
|
|
||||||
|
|
||||||
QScriptValue &operator <<(QScriptValue ¬ificationsObject, const StatusProvider &statusProvider)
|
|
||||||
{
|
|
||||||
quint32 counter = 0;
|
|
||||||
for(const auto ¬ification : statusProvider.notifications()) {
|
|
||||||
QScriptValue val;
|
|
||||||
val.setProperty("msg", QString::fromLocal8Bit(notification.message().data()), QScriptValue::ReadOnly);
|
|
||||||
val.setProperty("critical", notification.type() == NotificationType::Critical, QScriptValue::ReadOnly);
|
|
||||||
notificationsObject.setProperty(counter, val);
|
|
||||||
++counter;
|
|
||||||
}
|
|
||||||
return notificationsObject;
|
|
||||||
}
|
|
||||||
|
|
||||||
QScriptValue &operator <<(QScriptValue &tagObject, const Tag &tag)
|
|
||||||
{
|
|
||||||
// text fields
|
|
||||||
tagObject.setProperty("title", tagValueToQString(tag.value(KnownField::Title)), QScriptValue::ReadOnly);
|
|
||||||
tagObject.setProperty("artist", tagValueToQString(tag.value(KnownField::Artist)), QScriptValue::ReadOnly);
|
|
||||||
tagObject.setProperty("album", tagValueToQString(tag.value(KnownField::Album)), QScriptValue::ReadOnly);
|
|
||||||
tagObject.setProperty("year", tagValueToQString(tag.value(KnownField::Year)), QScriptValue::ReadOnly);
|
|
||||||
tagObject.setProperty("comment", tagValueToQString(tag.value(KnownField::Comment)), QScriptValue::ReadOnly);
|
|
||||||
tagObject.setProperty("genre", tagValueToQString(tag.value(KnownField::Genre)), QScriptValue::ReadOnly);
|
|
||||||
tagObject.setProperty("encoder", tagValueToQString(tag.value(KnownField::Encoder)), QScriptValue::ReadOnly);
|
|
||||||
tagObject.setProperty("language", tagValueToQString(tag.value(KnownField::Language)), QScriptValue::ReadOnly);
|
|
||||||
tagObject.setProperty("descriptions", tagValueToQString(tag.value(KnownField::Description)), QScriptValue::ReadOnly);
|
|
||||||
// numeric fields
|
|
||||||
try {
|
|
||||||
tagObject.setProperty("partNumber", tag.value(KnownField::PartNumber).toInteger(), QScriptValue::ReadOnly);
|
|
||||||
} catch(ConversionException &) {}
|
|
||||||
try {
|
|
||||||
tagObject.setProperty("totalParts", tag.value(KnownField::TotalParts).toInteger(), QScriptValue::ReadOnly);
|
|
||||||
} catch(ConversionException &) {}
|
|
||||||
PositionInSet pos;
|
|
||||||
try {
|
|
||||||
pos = tag.value(KnownField::TrackPosition).toPositionIntSet();
|
|
||||||
} catch(ConversionException &) {}
|
|
||||||
tagObject.setProperty("trackPos", pos.position(), QScriptValue::ReadOnly);
|
|
||||||
tagObject.setProperty("trackTotal", pos.total(), QScriptValue::ReadOnly);
|
|
||||||
pos = PositionInSet();
|
|
||||||
try {
|
|
||||||
pos = tag.value(KnownField::DiskPosition).toPositionIntSet();
|
|
||||||
} catch(ConversionException &) {}
|
|
||||||
tagObject.setProperty("diskPos", pos.position(), QScriptValue::ReadOnly);
|
|
||||||
tagObject.setProperty("diskTotal", pos.total(), QScriptValue::ReadOnly);
|
|
||||||
// notifications
|
|
||||||
tagObject.setProperty("hasCriticalNotifications", tag.hasCriticalNotifications(), QScriptValue::ReadOnly);
|
|
||||||
return tagObject;
|
|
||||||
}
|
|
||||||
|
|
||||||
QScriptValue ScriptFunctions::parseFileInfo(QScriptContext *context, QScriptEngine *engine)
|
|
||||||
{
|
|
||||||
if(context->argumentCount() != 1 && !context->argument(0).isString()) {
|
|
||||||
return QScriptValue();
|
|
||||||
}
|
|
||||||
auto fileName = context->argument(0).toString();
|
|
||||||
MediaFileInfo fileInfo(fileName.toLocal8Bit().data());
|
|
||||||
|
|
||||||
QScriptValue fileInfoObject = engine->newObject();
|
|
||||||
fileInfoObject.setProperty("currentName", QString::fromLocal8Bit(fileInfo.fileName(false).data()));
|
|
||||||
fileInfoObject.setProperty("currentBaseName", QString::fromLocal8Bit(fileInfo.fileName(true).data()));
|
|
||||||
QString suffix = QString::fromLocal8Bit(fileInfo.extension().data());
|
|
||||||
if(suffix.startsWith('.')) {
|
|
||||||
suffix.remove(0, 1);
|
|
||||||
}
|
|
||||||
fileInfoObject.setProperty("currentSuffix", suffix, QScriptValue::ReadOnly);
|
|
||||||
bool critical = false;
|
|
||||||
try {
|
|
||||||
fileInfo.parseEverything();
|
|
||||||
} catch(Failure &) {
|
|
||||||
// parsing notifications will be addded anyways
|
|
||||||
critical = true;
|
|
||||||
} catch(ios_base::failure &) {
|
|
||||||
critical = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
QScriptValue mainNotificationObject = engine->newArray(fileInfo.notifications().size());
|
|
||||||
mainNotificationObject << fileInfo;
|
|
||||||
critical |= fileInfo.hasCriticalNotifications();
|
|
||||||
fileInfoObject.setProperty("hasCriticalNotifications", critical);
|
|
||||||
fileInfoObject.setProperty("notifications", mainNotificationObject);
|
|
||||||
|
|
||||||
fileInfoObject.setProperty("mimeType", QString::fromLocal8Bit(fileInfo.mimeType()), QScriptValue::ReadOnly);
|
|
||||||
fileInfoObject.setProperty("suitableSuffix", QString::fromLocal8Bit(fileInfo.containerFormatAbbreviation()), QScriptValue::ReadOnly);
|
|
||||||
|
|
||||||
vector<Tag *> tags;
|
|
||||||
fileInfo.tags(tags);
|
|
||||||
QScriptValue combinedTagObject = engine->newObject();
|
|
||||||
QScriptValue combinedTagNotifications = engine->newArray();
|
|
||||||
QScriptValue tagsObject = engine->newArray(tags.size());
|
|
||||||
uint32 tagIndex = 0;
|
|
||||||
|
|
||||||
for(auto tagIterator = tags.cbegin(), end = tags.cend(); tagIterator != end; ++tagIterator, ++tagIndex) {
|
|
||||||
const Tag &tag = **tagIterator;
|
|
||||||
QScriptValue tagObject = engine->newObject();
|
|
||||||
combinedTagObject << tag;
|
|
||||||
combinedTagNotifications << tag;
|
|
||||||
tagObject << tag;
|
|
||||||
QScriptValue tagNotificationsObject = engine->newArray(tag.notifications().size());
|
|
||||||
tagNotificationsObject << tag;
|
|
||||||
tagObject.setProperty("notifications", tagNotificationsObject, QScriptValue::ReadOnly);
|
|
||||||
tagsObject.setProperty(tagIndex, tagObject, QScriptValue::ReadOnly);
|
|
||||||
}
|
|
||||||
combinedTagObject.setProperty("notifications", combinedTagNotifications, QScriptValue::ReadOnly);
|
|
||||||
fileInfoObject.setProperty("tag", combinedTagObject, QScriptValue::ReadOnly);
|
|
||||||
fileInfoObject.setProperty("tags", tagsObject, QScriptValue::ReadOnly);
|
|
||||||
return fileInfoObject;
|
|
||||||
}
|
|
||||||
|
|
||||||
QScriptValue ScriptFunctions::parseFileName(QScriptContext *context, QScriptEngine *engine)
|
|
||||||
{
|
|
||||||
if(context->argumentCount() != 1 && !context->argument(0).isString()) {
|
|
||||||
return QScriptValue();
|
|
||||||
}
|
|
||||||
QString fileName = context->argument(0).toString();
|
|
||||||
QString title;
|
|
||||||
int trackNumber = 0;
|
|
||||||
Utility::parseFileName(fileName, title, trackNumber);
|
|
||||||
QScriptValue result = engine->newObject();
|
|
||||||
result.setProperty("title", QScriptValue(title), QScriptValue::ReadOnly);
|
|
||||||
result.setProperty("trackPos", QScriptValue(trackNumber), QScriptValue::ReadOnly);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
QScriptValue ScriptFunctions::allFiles(QScriptContext *context, QScriptEngine *engine)
|
|
||||||
{
|
|
||||||
if(context->argumentCount() != 1 && !context->argument(0).isString()) {
|
|
||||||
return QScriptValue();
|
|
||||||
}
|
|
||||||
QString dirName = context->argument(0).toString();
|
|
||||||
QDir dir(dirName);
|
|
||||||
if(dir.exists()) {
|
|
||||||
QStringList files = dir.entryList(QDir::Files);
|
|
||||||
QScriptValue entriesObj = engine->newArray(files.length());
|
|
||||||
quint32 counter = 0;
|
|
||||||
foreach(const QString &file, files) {
|
|
||||||
entriesObj.setProperty(counter, file, QScriptValue::ReadOnly);
|
|
||||||
++counter;
|
|
||||||
}
|
|
||||||
return entriesObj;
|
|
||||||
} else {
|
|
||||||
return QScriptValue();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QScriptValue ScriptFunctions::firstFile(QScriptContext *context, QScriptEngine *engine)
|
|
||||||
{
|
|
||||||
if(context->argumentCount() != 1 && !context->argument(0).isString()) {
|
|
||||||
return QScriptValue();
|
|
||||||
}
|
|
||||||
QString dirName = context->argument(0).toString();
|
|
||||||
QDir dir(dirName);
|
|
||||||
if(dir.exists()) {
|
|
||||||
QStringList files = dir.entryList(QDir::Files);
|
|
||||||
if(files.length() > 0) {
|
|
||||||
return engine->newVariant(files.first());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return QScriptValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
QScriptValue ScriptFunctions::writeLog(QScriptContext *context, QScriptEngine *)
|
|
||||||
{
|
|
||||||
if(context->argumentCount() != 1 && !context->argument(0).isString()) {
|
|
||||||
return QScriptValue();
|
|
||||||
}
|
|
||||||
cout << context->argument(0).toString().toStdString() << endl;
|
|
||||||
return QScriptValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace RenamingUtility
|
|
|
@ -1,26 +0,0 @@
|
||||||
#ifndef RENAMINGUTILITY_SCRIPTFUNCTIONS_H
|
|
||||||
#define RENAMINGUTILITY_SCRIPTFUNCTIONS_H
|
|
||||||
|
|
||||||
#include <QtGlobal>
|
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
|
||||||
class QScriptValue;
|
|
||||||
class QScriptContext;
|
|
||||||
class QScriptEngine;
|
|
||||||
QT_END_NAMESPACE
|
|
||||||
|
|
||||||
namespace RenamingUtility {
|
|
||||||
|
|
||||||
class ScriptFunctions
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
static QScriptValue parseFileInfo(QScriptContext *context, QScriptEngine *engine);
|
|
||||||
static QScriptValue parseFileName(QScriptContext *context, QScriptEngine *engine);
|
|
||||||
static QScriptValue allFiles(QScriptContext *context, QScriptEngine *engine);
|
|
||||||
static QScriptValue firstFile(QScriptContext *context, QScriptEngine *engine);
|
|
||||||
static QScriptValue writeLog(QScriptContext *context, QScriptEngine *);
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace RenamingUtility
|
|
||||||
|
|
||||||
#endif // RENAMINGUTILITY_SCRIPTFUNCTIONS_H
|
|
|
@ -0,0 +1,250 @@
|
||||||
|
#include "./tageditorobject.h"
|
||||||
|
#include "./filesystemitem.h"
|
||||||
|
|
||||||
|
#include "../misc/utility.h"
|
||||||
|
|
||||||
|
#include <tagparser/mediafileinfo.h>
|
||||||
|
#include <tagparser/tag.h>
|
||||||
|
#include <tagparser/tagvalue.h>
|
||||||
|
#include <tagparser/exceptions.h>
|
||||||
|
|
||||||
|
#include <c++utilities/conversion/conversionexception.h>
|
||||||
|
|
||||||
|
#include <QDir>
|
||||||
|
|
||||||
|
#ifdef TAGEDITOR_USE_JSENGINE
|
||||||
|
# include <QJSEngine>
|
||||||
|
# include <QJSValue>
|
||||||
|
#else
|
||||||
|
# include <QScriptEngine>
|
||||||
|
# include <QScriptValue>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
using namespace ConversionUtilities;
|
||||||
|
using namespace Utility;
|
||||||
|
using namespace Media;
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
namespace RenamingUtility {
|
||||||
|
|
||||||
|
TAGEDITOR_JS_VALUE &operator <<(TAGEDITOR_JS_VALUE ¬ificationsObject, const StatusProvider &statusProvider)
|
||||||
|
{
|
||||||
|
quint32 counter = 0;
|
||||||
|
for(const auto ¬ification : statusProvider.notifications()) {
|
||||||
|
TAGEDITOR_JS_VALUE val;
|
||||||
|
val.setProperty("msg", QString::fromLocal8Bit(notification.message().data()) TAGEDITOR_JS_READONLY);
|
||||||
|
val.setProperty("critical", notification.type() == NotificationType::Critical TAGEDITOR_JS_READONLY);
|
||||||
|
notificationsObject.setProperty(counter, val);
|
||||||
|
++counter;
|
||||||
|
}
|
||||||
|
return notificationsObject;
|
||||||
|
}
|
||||||
|
|
||||||
|
TAGEDITOR_JS_VALUE &operator <<(TAGEDITOR_JS_VALUE &tagObject, const Tag &tag)
|
||||||
|
{
|
||||||
|
// text fields
|
||||||
|
tagObject.setProperty("title", tagValueToQString(tag.value(KnownField::Title)) TAGEDITOR_JS_READONLY);
|
||||||
|
tagObject.setProperty("artist", tagValueToQString(tag.value(KnownField::Artist)) TAGEDITOR_JS_READONLY);
|
||||||
|
tagObject.setProperty("album", tagValueToQString(tag.value(KnownField::Album)) TAGEDITOR_JS_READONLY);
|
||||||
|
tagObject.setProperty("year", tagValueToQString(tag.value(KnownField::Year)) TAGEDITOR_JS_READONLY);
|
||||||
|
tagObject.setProperty("comment", tagValueToQString(tag.value(KnownField::Comment)) TAGEDITOR_JS_READONLY);
|
||||||
|
tagObject.setProperty("genre", tagValueToQString(tag.value(KnownField::Genre)) TAGEDITOR_JS_READONLY);
|
||||||
|
tagObject.setProperty("encoder", tagValueToQString(tag.value(KnownField::Encoder)) TAGEDITOR_JS_READONLY);
|
||||||
|
tagObject.setProperty("language", tagValueToQString(tag.value(KnownField::Language)) TAGEDITOR_JS_READONLY);
|
||||||
|
tagObject.setProperty("descriptions", tagValueToQString(tag.value(KnownField::Description)) TAGEDITOR_JS_READONLY);
|
||||||
|
// numeric fields
|
||||||
|
try {
|
||||||
|
tagObject.setProperty("partNumber", tag.value(KnownField::PartNumber).toInteger() TAGEDITOR_JS_READONLY);
|
||||||
|
} catch(ConversionException &) {}
|
||||||
|
try {
|
||||||
|
tagObject.setProperty("totalParts", tag.value(KnownField::TotalParts).toInteger() TAGEDITOR_JS_READONLY);
|
||||||
|
} catch(ConversionException &) {}
|
||||||
|
PositionInSet pos;
|
||||||
|
try {
|
||||||
|
pos = tag.value(KnownField::TrackPosition).toPositionIntSet();
|
||||||
|
} catch(ConversionException &) {}
|
||||||
|
tagObject.setProperty("trackPos", pos.position() TAGEDITOR_JS_READONLY);
|
||||||
|
tagObject.setProperty("trackTotal", pos.total() TAGEDITOR_JS_READONLY);
|
||||||
|
pos = PositionInSet();
|
||||||
|
try {
|
||||||
|
pos = tag.value(KnownField::DiskPosition).toPositionIntSet();
|
||||||
|
} catch(ConversionException &) {}
|
||||||
|
tagObject.setProperty("diskPos", pos.position() TAGEDITOR_JS_READONLY);
|
||||||
|
tagObject.setProperty("diskTotal", pos.total() TAGEDITOR_JS_READONLY);
|
||||||
|
// notifications
|
||||||
|
tagObject.setProperty("hasCriticalNotifications", tag.hasCriticalNotifications() TAGEDITOR_JS_READONLY);
|
||||||
|
return tagObject;
|
||||||
|
}
|
||||||
|
|
||||||
|
TagEditorObject::TagEditorObject(TAGEDITOR_JS_ENGINE *engine) :
|
||||||
|
m_engine(engine),
|
||||||
|
m_currentType(ItemType::Dir),
|
||||||
|
m_action(ActionType::None)
|
||||||
|
{}
|
||||||
|
|
||||||
|
void TagEditorObject::setFileInfo(const QFileInfo &file, FileSystemItem *item)
|
||||||
|
{
|
||||||
|
m_currentPath = file.absoluteFilePath();
|
||||||
|
m_currentName = file.fileName();
|
||||||
|
m_currentRelativeDirectory = item->relativeDir();
|
||||||
|
m_currentType = item->type();
|
||||||
|
m_action = ActionType::None;
|
||||||
|
m_newName.clear();
|
||||||
|
m_newRelativeDirectory.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
const QString &TagEditorObject::currentPath() const
|
||||||
|
{
|
||||||
|
return m_currentPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
const QString &TagEditorObject::currentName() const
|
||||||
|
{
|
||||||
|
return m_currentName;
|
||||||
|
}
|
||||||
|
|
||||||
|
const QString &TagEditorObject::currentRelativeDirectory() const
|
||||||
|
{
|
||||||
|
return m_currentRelativeDirectory;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TagEditorObject::isDir() const
|
||||||
|
{
|
||||||
|
return m_currentType == ItemType::Dir;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TagEditorObject::isFile() const
|
||||||
|
{
|
||||||
|
return m_currentType == ItemType::File;
|
||||||
|
}
|
||||||
|
|
||||||
|
const QString &TagEditorObject::newName() const
|
||||||
|
{
|
||||||
|
return m_newName;
|
||||||
|
}
|
||||||
|
|
||||||
|
const QString &TagEditorObject::newRelativeDirectory() const
|
||||||
|
{
|
||||||
|
return m_newRelativeDirectory;
|
||||||
|
}
|
||||||
|
|
||||||
|
TAGEDITOR_JS_VALUE TagEditorObject::parseFileInfo(const QString &fileName)
|
||||||
|
{
|
||||||
|
MediaFileInfo fileInfo(fileName.toLocal8Bit().data());
|
||||||
|
|
||||||
|
auto fileInfoObject = m_engine->newObject();
|
||||||
|
fileInfoObject.setProperty(QStringLiteral("currentName"), QString::fromLocal8Bit(fileInfo.fileName(false).data()));
|
||||||
|
fileInfoObject.setProperty(QStringLiteral("currentBaseName"), QString::fromLocal8Bit(fileInfo.fileName(true).data()));
|
||||||
|
QString suffix = QString::fromLocal8Bit(fileInfo.extension().data());
|
||||||
|
if(suffix.startsWith('.')) {
|
||||||
|
suffix.remove(0, 1);
|
||||||
|
}
|
||||||
|
fileInfoObject.setProperty(QStringLiteral("currentSuffix"), suffix TAGEDITOR_JS_READONLY);
|
||||||
|
bool critical = false;
|
||||||
|
try {
|
||||||
|
fileInfo.parseEverything();
|
||||||
|
} catch(Failure &) {
|
||||||
|
// parsing notifications will be addded anyways
|
||||||
|
critical = true;
|
||||||
|
} catch(ios_base::failure &) {
|
||||||
|
critical = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto mainNotificationObject = m_engine->newArray(fileInfo.notifications().size());
|
||||||
|
mainNotificationObject << fileInfo;
|
||||||
|
critical |= fileInfo.hasCriticalNotifications();
|
||||||
|
fileInfoObject.setProperty(QStringLiteral("hasCriticalNotifications"), critical);
|
||||||
|
fileInfoObject.setProperty(QStringLiteral("notifications"), mainNotificationObject);
|
||||||
|
|
||||||
|
fileInfoObject.setProperty(QStringLiteral("mimeType"), QString::fromLocal8Bit(fileInfo.mimeType()) TAGEDITOR_JS_READONLY);
|
||||||
|
fileInfoObject.setProperty(QStringLiteral("suitableSuffix"), QString::fromLocal8Bit(fileInfo.containerFormatAbbreviation()) TAGEDITOR_JS_READONLY);
|
||||||
|
|
||||||
|
vector<Tag *> tags;
|
||||||
|
fileInfo.tags(tags);
|
||||||
|
auto combinedTagObject = m_engine->newObject();
|
||||||
|
auto combinedTagNotifications = m_engine->newArray();
|
||||||
|
auto tagsObject = m_engine->newArray(tags.size());
|
||||||
|
uint32 tagIndex = 0;
|
||||||
|
|
||||||
|
for(auto tagIterator = tags.cbegin(), end = tags.cend(); tagIterator != end; ++tagIterator, ++tagIndex) {
|
||||||
|
const Tag &tag = **tagIterator;
|
||||||
|
auto tagObject = m_engine->newObject();
|
||||||
|
combinedTagObject << tag;
|
||||||
|
combinedTagNotifications << tag;
|
||||||
|
tagObject << tag;
|
||||||
|
auto tagNotificationsObject = m_engine->newArray(tag.notifications().size());
|
||||||
|
tagNotificationsObject << tag;
|
||||||
|
tagObject.setProperty(QStringLiteral("notifications"), tagNotificationsObject TAGEDITOR_JS_READONLY);
|
||||||
|
tagsObject.setProperty(tagIndex, tagObject TAGEDITOR_JS_READONLY);
|
||||||
|
}
|
||||||
|
combinedTagObject.setProperty(QStringLiteral("notifications"), combinedTagNotifications TAGEDITOR_JS_READONLY);
|
||||||
|
fileInfoObject.setProperty(QStringLiteral("tag"), combinedTagObject TAGEDITOR_JS_READONLY);
|
||||||
|
fileInfoObject.setProperty(QStringLiteral("tags"), tagsObject TAGEDITOR_JS_READONLY);
|
||||||
|
return fileInfoObject;
|
||||||
|
}
|
||||||
|
|
||||||
|
TAGEDITOR_JS_VALUE TagEditorObject::parseFileName(const QString &fileName)
|
||||||
|
{
|
||||||
|
QString title;
|
||||||
|
int trackNumber = 0;
|
||||||
|
Utility::parseFileName(fileName, title, trackNumber);
|
||||||
|
auto result = m_engine->newObject();
|
||||||
|
result.setProperty(QStringLiteral("title"), TAGEDITOR_JS_VALUE(title) TAGEDITOR_JS_READONLY);
|
||||||
|
result.setProperty(QStringLiteral("trackPos"), TAGEDITOR_JS_VALUE(trackNumber) TAGEDITOR_JS_READONLY);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
TAGEDITOR_JS_VALUE TagEditorObject::allFiles(const QString &dirName)
|
||||||
|
{
|
||||||
|
QDir dir(dirName);
|
||||||
|
if(dir.exists()) {
|
||||||
|
QStringList files = dir.entryList(QDir::Files);
|
||||||
|
auto entriesObj = m_engine->newArray(files.length());
|
||||||
|
quint32 counter = 0;
|
||||||
|
foreach(const QString &file, files) {
|
||||||
|
entriesObj.setProperty(counter, file TAGEDITOR_JS_READONLY);
|
||||||
|
++counter;
|
||||||
|
}
|
||||||
|
return entriesObj;
|
||||||
|
} else {
|
||||||
|
return TAGEDITOR_JS_VALUE();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TAGEDITOR_JS_VALUE TagEditorObject::firstFile(const QString &dirName)
|
||||||
|
{
|
||||||
|
QDir dir(dirName);
|
||||||
|
if(dir.exists()) {
|
||||||
|
QStringList files = dir.entryList(QDir::Files);
|
||||||
|
if(!files.empty()) {
|
||||||
|
return TAGEDITOR_JS_VALUE(files.first());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return TAGEDITOR_JS_VALUE();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TagEditorObject::writeLog(const QString &message)
|
||||||
|
{
|
||||||
|
cout << message.toStdString() << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TagEditorObject::rename(const QString &newName)
|
||||||
|
{
|
||||||
|
m_newName = newName;
|
||||||
|
m_action = ActionType::Rename;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TagEditorObject::move(const QString &newRelativeDirectory)
|
||||||
|
{
|
||||||
|
m_newRelativeDirectory = newRelativeDirectory;
|
||||||
|
m_action = ActionType::Rename;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TagEditorObject::skip()
|
||||||
|
{
|
||||||
|
m_action = ActionType::Skip;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace RenamingUtility
|
|
@ -0,0 +1,75 @@
|
||||||
|
#ifndef RENAMINGUTILITY_SCRIPTFUNCTIONS_H
|
||||||
|
#define RENAMINGUTILITY_SCRIPTFUNCTIONS_H
|
||||||
|
|
||||||
|
#include "./scriptdefs.h"
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#ifdef TAGEDITOR_USE_JSENGINE
|
||||||
|
# include <QJSValue>
|
||||||
|
#else
|
||||||
|
# include <QScriptValue>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
QT_FORWARD_DECLARE_CLASS(QFileInfo)
|
||||||
|
|
||||||
|
namespace RenamingUtility {
|
||||||
|
|
||||||
|
class FileSystemItem;
|
||||||
|
enum class ItemType;
|
||||||
|
enum class ActionType;
|
||||||
|
|
||||||
|
class TagEditorObject : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
Q_PROPERTY(QString currentPath READ currentPath)
|
||||||
|
Q_PROPERTY(QString currentName READ currentName)
|
||||||
|
Q_PROPERTY(QString currentRelativeDirectory READ currentRelativeDirectory)
|
||||||
|
Q_PROPERTY(bool isDir READ isDir)
|
||||||
|
Q_PROPERTY(bool isFile READ isFile)
|
||||||
|
Q_PROPERTY(QString newName READ newName WRITE rename)
|
||||||
|
Q_PROPERTY(QString newRelativeDirectory READ newRelativeDirectory WRITE move)
|
||||||
|
|
||||||
|
public:
|
||||||
|
TagEditorObject(TAGEDITOR_JS_ENGINE *engine);
|
||||||
|
|
||||||
|
ActionType action() const;
|
||||||
|
void setFileInfo(const QFileInfo &file, FileSystemItem *item);
|
||||||
|
|
||||||
|
const QString ¤tPath() const;
|
||||||
|
const QString ¤tName() const;
|
||||||
|
const QString ¤tRelativeDirectory() const;
|
||||||
|
bool isDir() const;
|
||||||
|
bool isFile() const;
|
||||||
|
const QString &newName() const;
|
||||||
|
const QString &newRelativeDirectory() const;
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
TAGEDITOR_JS_VALUE parseFileInfo(const QString &fileName);
|
||||||
|
TAGEDITOR_JS_VALUE parseFileName(const QString &fileName);
|
||||||
|
TAGEDITOR_JS_VALUE allFiles(const QString &dirName);
|
||||||
|
TAGEDITOR_JS_VALUE firstFile(const QString &dirName);
|
||||||
|
void writeLog(const QString &message);
|
||||||
|
void rename(const QString &newName);
|
||||||
|
void move(const QString &newRelativeDirectory);
|
||||||
|
void skip();
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
TAGEDITOR_JS_ENGINE *m_engine;
|
||||||
|
QString m_currentPath;
|
||||||
|
QString m_currentName;
|
||||||
|
QString m_currentRelativeDirectory;
|
||||||
|
ItemType m_currentType;
|
||||||
|
ActionType m_action;
|
||||||
|
QString m_newName;
|
||||||
|
QString m_newRelativeDirectory;
|
||||||
|
};
|
||||||
|
|
||||||
|
inline ActionType TagEditorObject::action() const
|
||||||
|
{
|
||||||
|
return m_action;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace RenamingUtility
|
||||||
|
|
||||||
|
#endif // RENAMINGUTILITY_SCRIPTFUNCTIONS_H
|
|
@ -21,27 +21,27 @@ var distDir = false;
|
||||||
// string used for "miscellaneous" category
|
// string used for "miscellaneous" category
|
||||||
var misc = "misc";
|
var misc = "misc";
|
||||||
|
|
||||||
// define helper functions
|
// define some helper functions
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Returns whether the specified \a value is not undefined
|
* Returns whether the specified \a value is not undefined
|
||||||
and not an empty string.
|
* and not an empty string.
|
||||||
*/
|
*/
|
||||||
function notEmpty(value) {
|
function notEmpty(value) {
|
||||||
return value !== undefined && value !== "";
|
return value !== undefined && value !== "";
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Returns whether the specified \a value is not undefined
|
* Returns whether the specified \a value is not undefined
|
||||||
and not zero.
|
* and not zero.
|
||||||
*/
|
*/
|
||||||
function notNull(value) {
|
function notNull(value) {
|
||||||
return value !== undefined && value !== 0;
|
return value !== undefined && value !== 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Returns the string representation of \a pos using at least as
|
* Returns the string representation of \a pos using at least as
|
||||||
many digits as \a total has.
|
* many digits as \a total has.
|
||||||
*/
|
*/
|
||||||
function appropriateDigitCount(pos, total) {
|
function appropriateDigitCount(pos, total) {
|
||||||
var res = pos + "";
|
var res = pos + "";
|
||||||
|
@ -53,8 +53,8 @@ function appropriateDigitCount(pos, total) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Returns a copy of the specified \a name with characters that might be
|
* Returns a copy of the specified \a name with characters that might be
|
||||||
avoided in file names striped out.
|
* avoided in file names striped out.
|
||||||
*/
|
*/
|
||||||
function validFileName(name) {
|
function validFileName(name) {
|
||||||
if(name !== undefined) {
|
if(name !== undefined) {
|
||||||
|
@ -65,8 +65,8 @@ function validFileName(name) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Returns a copy of the specified \a name with characters that might be
|
* Returns a copy of the specified \a name with characters that might be
|
||||||
avoided in directory names striped out.
|
* avoided in directory names striped out.
|
||||||
*/
|
*/
|
||||||
function validDirectoryName(name) {
|
function validDirectoryName(name) {
|
||||||
if(name !== undefined) {
|
if(name !== undefined) {
|
||||||
|
@ -79,21 +79,21 @@ function validDirectoryName(name) {
|
||||||
// the actual script
|
// the actual script
|
||||||
|
|
||||||
// check whether we have to deal with a file or a directory
|
// check whether we have to deal with a file or a directory
|
||||||
if(isFile) {
|
if(tageditor.isFile) {
|
||||||
// parse file using the built-in parseFileInfo function
|
// parse file using the built-in parseFileInfo function
|
||||||
var fileInfo = parseFileInfo(currentPath);
|
var fileInfo = tageditor.parseFileInfo(tageditor.currentPath);
|
||||||
var tag = fileInfo.tag; // get the tag information
|
var tag = fileInfo.tag; // get the tag information
|
||||||
// read title and track number from the file name using the built-in parseFileName function
|
// read title and track number from the file name using the built-in parseFileName function
|
||||||
var infoFromFileName = parseFileName(fileInfo.currentBaseName);
|
var infoFromFileName = tageditor.parseFileName(fileInfo.currentBaseName);
|
||||||
// read the suffix from the file info object to filter backup and temporary files
|
// read the suffix from the file info object to filter backup and temporary files
|
||||||
if(fileInfo.currentName === "desktop.ini") {
|
if(fileInfo.currentName === "desktop.ini") {
|
||||||
action = actionType.skip; // skip these files
|
tageditor.skip(); // skip these files
|
||||||
} else if(fileInfo.currentSuffix === "bak") {
|
} else if(fileInfo.currentSuffix === "bak") {
|
||||||
// filter backup files by setting newRelativeDirectory to put them in a separate directory
|
// filter backup by putting them in a separate directory
|
||||||
newRelativeDirectory = "backups";
|
tageditor.move("backups");
|
||||||
} else if(fileInfo.currentSuffix === "tmp") {
|
} else if(fileInfo.currentSuffix === "tmp") {
|
||||||
// filter temporary files in the same way as backup files
|
// filter temporary files in the same way as backup files
|
||||||
newRelativeDirectory = "temp";
|
tageditor.move("temp");
|
||||||
} else {
|
} else {
|
||||||
// define an array for the fields; will be joined later
|
// define an array for the fields; will be joined later
|
||||||
var fields = [];
|
var fields = [];
|
||||||
|
@ -135,7 +135,7 @@ if(isFile) {
|
||||||
fields.push(appropriateDigitCount(infoFromFileName.trackPos, 10));
|
fields.push(appropriateDigitCount(infoFromFileName.trackPos, 10));
|
||||||
}
|
}
|
||||||
// join the first part of the new name
|
// join the first part of the new name
|
||||||
newName = fields.join(separator);
|
var newName = fields.join(separator);
|
||||||
// get the title
|
// get the title
|
||||||
var title = validFileName(tag.title);
|
var title = validFileName(tag.title);
|
||||||
// append the title (if configured and present)
|
// append the title (if configured and present)
|
||||||
|
@ -163,6 +163,8 @@ if(isFile) {
|
||||||
if(notEmpty(suffix)) {
|
if(notEmpty(suffix)) {
|
||||||
newName = newName.concat(".", suffix);
|
newName = newName.concat(".", suffix);
|
||||||
}
|
}
|
||||||
|
// apply new name
|
||||||
|
tageditor.rename(newName);
|
||||||
// set the distribution directory
|
// set the distribution directory
|
||||||
if(distDir) {
|
if(distDir) {
|
||||||
var path = [distDir];
|
var path = [distDir];
|
||||||
|
@ -185,13 +187,11 @@ if(isFile) {
|
||||||
if(tag.diskTotal >= 2) {
|
if(tag.diskTotal >= 2) {
|
||||||
path.push("Disk " + appropriateDigitCount(tag.diskPos, tag.diskTotal));
|
path.push("Disk " + appropriateDigitCount(tag.diskPos, tag.diskTotal));
|
||||||
}
|
}
|
||||||
newRelativeDirectory = path.join("/");
|
// apply new relative directory
|
||||||
|
tageditor.move(path.join("/"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// set the action to "actionType.renaming"
|
} else if(tageditor.isDir) {
|
||||||
// (this is the default action, actually there is no need to set it explicitly)
|
// skip directories in this example script
|
||||||
action = actionType.rename;
|
tageditor.skip();
|
||||||
} else if(isDir) {
|
|
||||||
// skip directories in this example script by setting the action to "actionType.skip"
|
|
||||||
action = actionType.skip;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@ VERSION = 1.3.0
|
||||||
|
|
||||||
# basic configuration: application
|
# basic configuration: application
|
||||||
TEMPLATE = app
|
TEMPLATE = app
|
||||||
QT += core gui widgets script
|
QT += core gui widgets
|
||||||
# use webkitwidgets if available; otherwise use webenginewidgets
|
# use webkitwidgets if available; otherwise use webenginewidgets
|
||||||
!forcewebengine:qtHaveModule(webkitwidgets) {
|
!forcewebengine:qtHaveModule(webkitwidgets) {
|
||||||
QT += webkitwidgets
|
QT += webkitwidgets
|
||||||
|
@ -23,9 +23,17 @@ QT += core gui widgets script
|
||||||
QT += webenginewidgets
|
QT += webenginewidgets
|
||||||
DEFINES += TAGEDITOR_USE_WEBENGINE
|
DEFINES += TAGEDITOR_USE_WEBENGINE
|
||||||
}
|
}
|
||||||
|
# use script if available; otherwise use qml
|
||||||
|
!forcejsengine:qtHaveModule(script) {
|
||||||
|
QT += script
|
||||||
|
} else {
|
||||||
|
QT += qml
|
||||||
|
DEFINES += TAGEDITOR_USE_JSENGINE
|
||||||
|
}
|
||||||
|
|
||||||
# add project files
|
# add project files
|
||||||
HEADERS += application/main.h \
|
HEADERS += \
|
||||||
|
application/main.h \
|
||||||
application/knownfieldmodel.h \
|
application/knownfieldmodel.h \
|
||||||
application/settings.h \
|
application/settings.h \
|
||||||
gui/filefilterproxymodel.h \
|
gui/filefilterproxymodel.h \
|
||||||
|
@ -44,7 +52,8 @@ HEADERS += application/main.h \
|
||||||
renamingutility/filesystemitemmodel.h \
|
renamingutility/filesystemitemmodel.h \
|
||||||
renamingutility/filteredfilesystemitemmodel.h \
|
renamingutility/filteredfilesystemitemmodel.h \
|
||||||
renamingutility/renamingengine.h \
|
renamingutility/renamingengine.h \
|
||||||
renamingutility/scriptfunctions.h \
|
renamingutility/scriptdefs.h \
|
||||||
|
renamingutility/tageditorobject.h \
|
||||||
misc/htmlinfo.h \
|
misc/htmlinfo.h \
|
||||||
gui/previousvaluehandling.h \
|
gui/previousvaluehandling.h \
|
||||||
gui/initiate.h \
|
gui/initiate.h \
|
||||||
|
@ -55,7 +64,8 @@ HEADERS += application/main.h \
|
||||||
gui/attachmentsedit.h \
|
gui/attachmentsedit.h \
|
||||||
gui/codeedit.h
|
gui/codeedit.h
|
||||||
|
|
||||||
SOURCES += application/main.cpp \
|
SOURCES += \
|
||||||
|
application/main.cpp \
|
||||||
application/knownfieldmodel.cpp \
|
application/knownfieldmodel.cpp \
|
||||||
application/settings.cpp \
|
application/settings.cpp \
|
||||||
gui/filefilterproxymodel.cpp \
|
gui/filefilterproxymodel.cpp \
|
||||||
|
@ -74,9 +84,8 @@ SOURCES += application/main.cpp \
|
||||||
renamingutility/filesystemitemmodel.cpp \
|
renamingutility/filesystemitemmodel.cpp \
|
||||||
renamingutility/filteredfilesystemitemmodel.cpp \
|
renamingutility/filteredfilesystemitemmodel.cpp \
|
||||||
renamingutility/renamingengine.cpp \
|
renamingutility/renamingengine.cpp \
|
||||||
renamingutility/scriptfunctions.cpp \
|
renamingutility/tageditorobject.cpp \
|
||||||
misc/htmlinfo.cpp \
|
misc/htmlinfo.cpp \
|
||||||
gui/previousvaluehandling.cpp \
|
|
||||||
gui/initiate.cpp \
|
gui/initiate.cpp \
|
||||||
cli/mainfeatures.cpp \
|
cli/mainfeatures.cpp \
|
||||||
misc/utility.cpp \
|
misc/utility.cpp \
|
||||||
|
|
Loading…
Reference in New Issue