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:
Martchus 2016-01-09 02:56:56 +01:00
parent 10bfa8aeea
commit 1c4d577264
29 changed files with 489 additions and 426 deletions

View File

@ -60,7 +60,8 @@ set(WIDGETS_HEADER_FILES
renamingutility/filesystemitemmodel.h
renamingutility/filteredfilesystemitemmodel.h
renamingutility/renamingengine.h
renamingutility/scriptfunctions.h
renamingutility/scriptdefs.h
renamingutility/tageditorobject.h
)
set(WIDGETS_SRC_FILES
gui/attachmentsedit.cpp
@ -77,7 +78,6 @@ set(WIDGETS_SRC_FILES
gui/infowidgetbase.cpp
gui/initiate.cpp
gui/javascripthighlighter.cpp
gui/previousvaluehandling.cpp
gui/renamefilesdialog.cpp
gui/settingsdialog.cpp
gui/tagedit.cpp
@ -86,7 +86,7 @@ set(WIDGETS_SRC_FILES
renamingutility/filesystemitemmodel.cpp
renamingutility/filteredfilesystemitemmodel.cpp
renamingutility/renamingengine.cpp
renamingutility/scriptfunctions.cpp
renamingutility/tageditorobject.h
resources/icons.qrc
resources/scripts.qrc
)

View File

@ -113,7 +113,10 @@ Here are some Bash examples which illustrate getting and setting tag information
## Build instructions
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.
To force usage of webenginewidgets add "CONFIG+=forcewebengine" to the qmake arguments.

View File

@ -4,11 +4,6 @@
namespace QtGui {
/*
TRANSLATOR QtGui::FileFilterProxyModel
Necessary for lupdate.
*/
FileFilterProxyModel::FileFilterProxyModel(QObject *parent) :
QSortFilterProxyModel(parent),
m_filterEnabled(true)

View File

@ -23,11 +23,6 @@ using namespace Media;
namespace QtGui {
/*
TRANSLATOR QtGui::InfoWidgetBase
Necessary for lupdate.
*/
InfoWidgetBase::InfoWidgetBase(QWidget *parent) :
QWidget(parent),
m_notificationModel(nullptr)

View File

@ -5,7 +5,7 @@
// include configuration from separate header file when building with CMake
#ifndef APP_METADATA_AVAIL
#include "resources/config.h"
# include "resources/config.h"
#endif
#include <qtutilities/resources/qtconfigarguments.h>

View File

@ -64,11 +64,6 @@ using namespace Widgets;
namespace QtGui {
/*
TRANSLATOR QtGui::MainWindow
Necessary for lupdate.
*/
/*!
* \brief The LoadingResult enum specifies whether the file could be parsed.
*/

View File

@ -27,9 +27,6 @@ NotificationLabel::NotificationLabel(QWidget *parent) :
m_updateTimer.setInterval(80);
}
NotificationLabel::~NotificationLabel()
{}
void NotificationLabel::paintEvent(QPaintEvent *event)
{
QStyle *style = QWidget::style();

View File

@ -33,7 +33,6 @@ class NotificationLabel : public QWidget
Q_PROPERTY(int maxIconSize READ maxIconSize WRITE setMaxIconSize)
public:
explicit NotificationLabel(QWidget *parent = nullptr);
virtual ~NotificationLabel();
const QString &text() const;
NotificationType notificationType() const;

View File

@ -12,11 +12,6 @@ using namespace Media;
namespace QtGui {
/*
TRANSLATOR QtGui::NotificationModel
Necessary for lupdate.
*/
NotificationModel::NotificationModel(QObject *parent) :
QAbstractListModel(parent)
{}

View File

@ -15,18 +15,10 @@ using namespace Widgets;
namespace QtGui {
/*
TRANSLATOR QtGui::PathLineEdit
Necessary for lupdate.
*/
PathLineEdit::PathLineEdit(QWidget *parent) :
ClearLineEdit(parent)
{}
PathLineEdit::~PathLineEdit()
{}
QAbstractItemModel *PathLineEdit::completionModel() const
{
if(QCompleter *c = completer()) {

View File

@ -18,7 +18,6 @@ class PathLineEdit : public Widgets::ClearLineEdit
public:
explicit PathLineEdit(QWidget *parent = nullptr);
virtual ~PathLineEdit();
QAbstractItemModel *completionModel() const;
void setCompletionModel(QAbstractItemModel *model);

View File

@ -35,11 +35,6 @@ using namespace Media;
namespace QtGui {
/*
TRANSLATOR QtGui::PicturePreviewSelection
Necessary for lupdate.
*/
/*!
* \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()
{}

View File

@ -35,7 +35,7 @@ class PicturePreviewSelection : public QWidget
public:
explicit PicturePreviewSelection(Media::Tag *tag = nullptr, Media::KnownField field = Media::KnownField::Invalid, QWidget *parent = nullptr);
virtual ~PicturePreviewSelection();
~PicturePreviewSelection();
Media::Tag *tag() const;
Media::KnownField field() const;

View File

@ -1,5 +0,0 @@
#include "./previousvaluehandling.h"
namespace QtGui {
}

View File

@ -13,7 +13,6 @@
#include <QMessageBox>
#include <QFileDialog>
#include <QDir>
#include <QScriptEngine>
#include <QItemSelectionModel>
#include <QMenu>
#include <QClipboard>
@ -26,11 +25,6 @@ using namespace RenamingUtility;
namespace QtGui {
/*
TRANSLATOR QtGui::RenameFilesDialog
Necessary for lupdate.
*/
RenameFilesDialog::RenameFilesDialog(QWidget *parent) :
QDialog(parent),
m_ui(new Ui::RenameFilesDialog),
@ -44,7 +38,7 @@ RenameFilesDialog::RenameFilesDialog(QWidget *parent) :
setStyleSheet(dialogStyle() + QStringLiteral("QSplitter:handle { background-color: palette(base); }"));
#endif
// setup javascript editor and script file selection
QFont font("Courier", 10);
QFont font(QStringLiteral("Courier"), 10);
font.setFixedPitch(true);
m_ui->javaScriptPlainTextEdit->setFont(font);
m_highlighter = new JavaScriptHighlighter(m_ui->javaScriptPlainTextEdit->document());
@ -124,7 +118,6 @@ void RenameFilesDialog::startGeneratingPreview()
QDir selectedDir(directory());
m_ui->notificationLabel->setHidden(false);
if(selectedDir.exists()) {
QScriptEngine engine;
QString program;
if(m_ui->sourceFileStackedWidget->currentIndex() == 0) {
program = m_ui->javaScriptPlainTextEdit->toPlainText();
@ -143,18 +136,17 @@ void RenameFilesDialog::startGeneratingPreview()
}
}
if(!program.isEmpty()) {
QScriptSyntaxCheckResult res = engine.checkSyntax(program);
if(res.state() != QScriptSyntaxCheckResult::Error) {
if(m_engine->setProgram(program)) {
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(program, directory(), m_ui->includeSubdirsCheckBox->isChecked());
m_engine->generatePreview(directory(), m_ui->includeSubdirsCheckBox->isChecked());
} else {
m_engine->clearPreview();
m_ui->notificationLabel->setText(tr("The script is not valid.\nError in line %1 and column %2:\n %3")
.arg(res.errorLineNumber()).arg(res.errorColumnNumber()).arg(res.errorMessage()));
m_ui->notificationLabel->setText(tr("The script is not valid.\nError in line %1: %3")
.arg(m_engine->errorLineNumber()).arg(m_engine->errorMessage()));
m_ui->notificationLabel->setNotificationType(NotificationType::Warning);
}
} else {
@ -191,7 +183,7 @@ void RenameFilesDialog::showPreviewProgress(int itemsProcessed, int errorsOccure
m_errorsOccured = errorsOccured;
QString text = tr("%1 files/directories processed", 0, itemsProcessed).arg(itemsProcessed);
if(m_errorsOccured > 0) {
text.append(QStringLiteral("\n"));
text.append(QChar('\n'));
text.append(tr("%1 error(s) occured", 0, errorsOccured).arg(errorsOccured));
}
m_ui->notificationLabel->setText(text);

View File

@ -20,11 +20,6 @@ using namespace Media;
namespace QtGui {
/*
TRANSLATOR QtGui::TagEdit
Necessary for lupdate.
*/
/*!
* \class QtGui::TagEdit
* \brief The TagEdit widget allows the user to edit Media::Tag objects.
@ -55,14 +50,6 @@ TagEdit::TagEdit(QWidget *parent) :
setLayout(mainLayout);
}
/*!
* \brief Destroys the tag edit.
*
* Does not destroy assigned tags.
*/
TagEdit::~TagEdit()
{}
/*!
* \brief Assigns the specified \a tag to the edit.
* \param updateUi Specifies whether the UI of should be updated.

View File

@ -31,7 +31,6 @@ class TagEdit : public QWidget
public:
explicit TagEdit(QWidget *parent = nullptr);
~TagEdit();
const QList<Media::Tag *> &tags() const;
void setTag(Media::Tag *tag, bool updateUi = true);
void setTags(const QList<Media::Tag *> &tags, bool updateUi = true);

View File

@ -49,11 +49,6 @@ using namespace ConversionUtilities;
namespace QtGui {
/*
TRANSLATOR QtGui::TagFieldEdit
Necessary for lupdate.
*/
/*!
* \class QtGui::TagFieldEdit
* \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();
}
/*!
* \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.
*

View File

@ -39,7 +39,6 @@ class TagFieldEdit : public QWidget
public:
explicit TagFieldEdit(const QList<Media::Tag *> &tags, Media::KnownField field, QWidget *parent = nullptr);
virtual ~TagFieldEdit();
const QList<Media::Tag *> &tags() const;
Media::KnownField field() const;

View File

@ -7,6 +7,7 @@
namespace RenamingUtility {
enum class ActionType {
None,
Rename,
Skip
};

View File

@ -1,13 +1,12 @@
#include "./renamingengine.h"
#include "./filesystemitemmodel.h"
#include "./filteredfilesystemitemmodel.h"
#include "./scriptfunctions.h"
#include "./tageditorobject.h"
#include <c++utilities/misc/memory.h>
#include <QDir>
#include <QScriptEngine>
#include <QScriptProgram>
#include <QStringBuilder>
#include <thread>
@ -15,14 +14,10 @@ using namespace std;
namespace RenamingUtility {
/*
TRANSLATOR RenamingUtility::RemamingEngine
Necessary for lupdate.
*/
RemamingEngine::RemamingEngine(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_errorsOccured(0),
m_aborted(false),
@ -31,21 +26,40 @@ RemamingEngine::RemamingEngine(QObject *parent) :
m_currentModel(nullptr),
m_previewModel(nullptr)
{
m_engine.globalObject().setProperty(QStringLiteral("tageditor"), m_tagEditorJsObj);
connect(this, &RemamingEngine::previewGenerated, this, &RemamingEngine::processPreviewGenerated);
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()) {
return false;
}
lock_guard<mutex> guard(m_mutex, adopt_lock);
setRootItem();
m_program = scriptProgram;
m_includeSubdirs = includeSubdirs;
m_dir = rootDirectory;
auto startFunc = [this] () {
@ -54,7 +68,6 @@ bool RemamingEngine::generatePreview(const QScriptProgram &scriptProgram, const
m_aborted.store(false);
m_itemsProcessed = 0;
m_errorsOccured = 0;
m_go.setProperty("persistent", m_persistent = m_engine.newObject(), QScriptValue::Undeletable);
m_newlyGeneratedRootItem = generatePreview(m_dir);
}
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);
item->setApplied(false);
QFileInfoList entries = dir.entryInfoList();
foreach(const QFileInfo &entry, entries) {
for(const QFileInfo &entry : dir.entryInfoList()) {
if(entry.fileName() == QLatin1String("..")
|| entry.fileName() == QLatin1String(".")) {
continue;
@ -280,7 +292,7 @@ void RemamingEngine::applyChangings(FileSystemItem *parentItem)
void RemamingEngine::setError(const QList<FileSystemItem *> items)
{
foreach(FileSystemItem *item, items) {
for(FileSystemItem *item : items) {
item->setErrorOccured(true);
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)
{
// make file info for the specified item available in the script
m_tagEditorQObj->setFileInfo(fileInfo, item);
// execute script
setupGlobalObject(fileInfo, item);
QScriptValue res = m_engine.evaluate(m_program);
if(m_engine.hasUncaughtException()) {
auto scriptResult = m_program.call();
if(scriptResult.isError()) {
// handle error
item->setErrorOccured(true);
item->setNote(res.toString());
m_engine.clearExceptions();
item->setNote(scriptResult.toString());
} else {
// create preview for action
QScriptValue newName = m_go.property("newName");
QScriptValue newRelativeDirectory = m_go.property("newRelativeDirectory");
ActionType action = ActionType::Skip;
if(m_go.property("action").isNumber()) {
action = static_cast<ActionType>(m_go.property("action").toInt32());
}
switch(action) {
const QString &newName = m_tagEditorQObj->newName();
const QString &newRelativeDirectory = m_tagEditorQObj->newRelativeDirectory();
switch(m_tagEditorQObj->action()) {
case ActionType::None:
item->setNote(tr("no action specified"));
break;
case ActionType::Rename:
if(newRelativeDirectory.isString()) {
FileSystemItem *counterpartParent = item->root()->makeChildAvailable(newRelativeDirectory.toString());
if(!newRelativeDirectory.isEmpty()) {
FileSystemItem *counterpartParent = item->root()->makeChildAvailable(newRelativeDirectory);
if(counterpartParent->status() == ItemStatus::New
&& counterpartParent->note().isEmpty()) {
counterpartParent->setNote(tr("will be created"));
}
QString counterpartName = newName.isString()
? newName.toString()
: item->name();
const QString &counterpartName = newName.isEmpty() ? item->name() : newName;
if(counterpartParent->findChild(counterpartName, item)) {
item->setNote(tr("name is already used at new location"));
item->setErrorOccured(true);
@ -324,8 +333,8 @@ void RemamingEngine::executeScriptForItem(const QFileInfo &fileInfo, FileSystemI
counterpart->setCheckable(true);
counterpart->setChecked(true);
}
} else if(newName.isString()) {
item->setNewName(newName.toString());
} else if(!newName.isEmpty()) {
item->setNewName(newName);
}
if(FileSystemItem *newItem = item->counterpart()) {
if((newItem->name().isEmpty() || newItem->name() == item->name())
@ -347,34 +356,8 @@ void RemamingEngine::executeScriptForItem(const QFileInfo &fileInfo, FileSystemI
break;
default:
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

View File

@ -2,26 +2,31 @@
#define RENAMINGUTILITY_RENAMINGENGINE_H
#include "./filesystemitem.h"
#include "./scriptdefs.h"
#include <QObject>
#include <QList>
#include <QDir>
#include <QScriptProgram>
#include <QScriptEngine>
#include <QScriptValue>
#if TAGEDITOR_USE_JSENGINE
# include <QJSEngine>
# include <QJSValue>
#else
# include <QScriptEngine>
# include <QScriptValue>
#endif
#include <memory>
#include <mutex>
#include <atomic>
QT_FORWARD_DECLARE_CLASS(QFileInfo)
QT_FORWARD_DECLARE_CLASS(QScriptProgram)
QT_FORWARD_DECLARE_CLASS(QScriptContext)
namespace RenamingUtility {
class FileSystemItemModel;
class FilteredFileSystemItemModel;
class TagEditorObject;
class RemamingEngine : public QObject
{
@ -29,10 +34,11 @@ class RemamingEngine : public QObject
public:
RemamingEngine(QObject *parent = nullptr);
virtual ~RemamingEngine();
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;
bool subdirsIncluded() const;
bool isBusy();
@ -41,9 +47,11 @@ public:
FileSystemItemModel *model();
FilteredFileSystemItemModel *currentModel();
FilteredFileSystemItemModel *previewModel();
const QString &errorMessage() const;
int errorLineNumber() const;
public slots:
bool generatePreview(const QScriptProgram &scriptProgram, const QDir &rootDirectory, bool includeSubdirs);
bool generatePreview(const QDir &rootDirectory, bool includeSubdirs);
bool applyChangings();
void abort();
@ -63,23 +71,24 @@ private:
void applyChangings(FileSystemItem *parentItem);
static void setError(const QList<FileSystemItem *> items);
void executeScriptForItem(const QFileInfo &fileInfo, FileSystemItem *item);
void setupGlobalObject(const QFileInfo &file, FileSystemItem *item);
QScriptEngine m_engine;
QScriptValue m_go;
QScriptValue m_persistent;
TagEditorObject *m_tagEditorQObj;
TAGEDITOR_JS_ENGINE m_engine;
TAGEDITOR_JS_VALUE m_tagEditorJsObj;
std::unique_ptr<FileSystemItem> m_rootItem;
std::unique_ptr<FileSystemItem> m_newlyGeneratedRootItem;
int m_itemsProcessed;
int m_errorsOccured;
std::atomic<bool> m_aborted;
QScriptProgram m_program;
TAGEDITOR_JS_VALUE m_program;
QDir m_dir;
bool m_includeSubdirs;
std::mutex m_mutex;
FileSystemItemModel *m_model;
FilteredFileSystemItemModel *m_currentModel;
FilteredFileSystemItemModel *m_previewModel;
QString m_errorMessage;
int m_errorLineNumber;
};
inline FileSystemItem *RemamingEngine::rootItem() const
@ -87,7 +96,7 @@ inline FileSystemItem *RemamingEngine::rootItem() const
return m_rootItem.get();
}
inline const QScriptProgram &RemamingEngine::scriptProgram() const
inline const TAGEDITOR_JS_VALUE &RemamingEngine::scriptProgram() const
{
return m_program;
}
@ -102,6 +111,16 @@ inline bool RemamingEngine::subdirsIncluded() const
return m_includeSubdirs;
}
inline const QString &RemamingEngine::errorMessage() const
{
return m_errorMessage;
}
inline int RemamingEngine::errorLineNumber() const
{
return m_errorLineNumber;
}
} // namespace RenamingUtility
#endif // RENAMINGUTILITY_RENAMINGENGINE_H

View File

@ -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

View File

@ -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 &notificationsObject, const StatusProvider &statusProvider)
{
quint32 counter = 0;
for(const auto &notification : 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

View File

@ -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

View File

@ -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 &notificationsObject, const StatusProvider &statusProvider)
{
quint32 counter = 0;
for(const auto &notification : 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

View File

@ -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 &currentPath() const;
const QString &currentName() const;
const QString &currentRelativeDirectory() 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

View File

@ -21,27 +21,27 @@ var distDir = false;
// string used for "miscellaneous" category
var misc = "misc";
// define helper functions
// define some helper functions
/*!
* \brief Returns whether the specified \a value is not undefined
and not an empty string.
* Returns whether the specified \a value is not undefined
* and not an empty string.
*/
function notEmpty(value) {
return value !== undefined && value !== "";
}
/*!
* \brief Returns whether the specified \a value is not undefined
and not zero.
* Returns whether the specified \a value is not undefined
* and not zero.
*/
function notNull(value) {
return value !== undefined && value !== 0;
}
/*!
* \brief Returns the string representation of \a pos using at least as
many digits as \a total has.
* Returns the string representation of \a pos using at least as
* many digits as \a total has.
*/
function appropriateDigitCount(pos, total) {
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
avoided in file names striped out.
* Returns a copy of the specified \a name with characters that might be
* avoided in file names striped out.
*/
function validFileName(name) {
if(name !== undefined) {
@ -65,8 +65,8 @@ function validFileName(name) {
}
/*!
* \brief Returns a copy of the specified \a name with characters that might be
avoided in directory names striped out.
* Returns a copy of the specified \a name with characters that might be
* avoided in directory names striped out.
*/
function validDirectoryName(name) {
if(name !== undefined) {
@ -79,21 +79,21 @@ function validDirectoryName(name) {
// the actual script
// 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
var fileInfo = parseFileInfo(currentPath);
var fileInfo = tageditor.parseFileInfo(tageditor.currentPath);
var tag = fileInfo.tag; // get the tag information
// 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
if(fileInfo.currentName === "desktop.ini") {
action = actionType.skip; // skip these files
tageditor.skip(); // skip these files
} else if(fileInfo.currentSuffix === "bak") {
// filter backup files by setting newRelativeDirectory to put them in a separate directory
newRelativeDirectory = "backups";
// filter backup by putting them in a separate directory
tageditor.move("backups");
} else if(fileInfo.currentSuffix === "tmp") {
// filter temporary files in the same way as backup files
newRelativeDirectory = "temp";
tageditor.move("temp");
} else {
// define an array for the fields; will be joined later
var fields = [];
@ -135,7 +135,7 @@ if(isFile) {
fields.push(appropriateDigitCount(infoFromFileName.trackPos, 10));
}
// join the first part of the new name
newName = fields.join(separator);
var newName = fields.join(separator);
// get the title
var title = validFileName(tag.title);
// append the title (if configured and present)
@ -163,6 +163,8 @@ if(isFile) {
if(notEmpty(suffix)) {
newName = newName.concat(".", suffix);
}
// apply new name
tageditor.rename(newName);
// set the distribution directory
if(distDir) {
var path = [distDir];
@ -185,13 +187,11 @@ if(isFile) {
if(tag.diskTotal >= 2) {
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"
// (this is the default action, actually there is no need to set it explicitly)
action = actionType.rename;
} else if(isDir) {
// skip directories in this example script by setting the action to "actionType.skip"
action = actionType.skip;
} else if(tageditor.isDir) {
// skip directories in this example script
tageditor.skip();
}

View File

@ -15,7 +15,7 @@ VERSION = 1.3.0
# basic configuration: application
TEMPLATE = app
QT += core gui widgets script
QT += core gui widgets
# use webkitwidgets if available; otherwise use webenginewidgets
!forcewebengine:qtHaveModule(webkitwidgets) {
QT += webkitwidgets
@ -23,9 +23,17 @@ QT += core gui widgets script
QT += webenginewidgets
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
HEADERS += application/main.h \
HEADERS += \
application/main.h \
application/knownfieldmodel.h \
application/settings.h \
gui/filefilterproxymodel.h \
@ -44,7 +52,8 @@ HEADERS += application/main.h \
renamingutility/filesystemitemmodel.h \
renamingutility/filteredfilesystemitemmodel.h \
renamingutility/renamingengine.h \
renamingutility/scriptfunctions.h \
renamingutility/scriptdefs.h \
renamingutility/tageditorobject.h \
misc/htmlinfo.h \
gui/previousvaluehandling.h \
gui/initiate.h \
@ -55,7 +64,8 @@ HEADERS += application/main.h \
gui/attachmentsedit.h \
gui/codeedit.h
SOURCES += application/main.cpp \
SOURCES += \
application/main.cpp \
application/knownfieldmodel.cpp \
application/settings.cpp \
gui/filefilterproxymodel.cpp \
@ -74,9 +84,8 @@ SOURCES += application/main.cpp \
renamingutility/filesystemitemmodel.cpp \
renamingutility/filteredfilesystemitemmodel.cpp \
renamingutility/renamingengine.cpp \
renamingutility/scriptfunctions.cpp \
renamingutility/tageditorobject.cpp \
misc/htmlinfo.cpp \
gui/previousvaluehandling.cpp \
gui/initiate.cpp \
cli/mainfeatures.cpp \
misc/utility.cpp \