Refactor and improve coding style of renaming utility
This commit is contained in:
parent
adf78c6955
commit
db2f178542
|
@ -34,7 +34,7 @@ FileSystemItem::FileSystemItem(ItemStatus status, ItemType type, const QString &
|
||||||
|
|
||||||
FileSystemItem::~FileSystemItem()
|
FileSystemItem::~FileSystemItem()
|
||||||
{
|
{
|
||||||
for (FileSystemItem *child : m_children) {
|
for (auto *const child : m_children) {
|
||||||
child->m_parent = nullptr;
|
child->m_parent = nullptr;
|
||||||
delete child;
|
delete child;
|
||||||
}
|
}
|
||||||
|
@ -45,14 +45,15 @@ FileSystemItem::~FileSystemItem()
|
||||||
|
|
||||||
void FileSystemItem::setParent(FileSystemItem *parent)
|
void FileSystemItem::setParent(FileSystemItem *parent)
|
||||||
{
|
{
|
||||||
if (parent != m_parent) {
|
if (parent == m_parent) {
|
||||||
if (m_parent) {
|
return;
|
||||||
m_parent->m_children.removeAll(this);
|
}
|
||||||
}
|
if (m_parent) {
|
||||||
m_parent = parent;
|
m_parent->m_children.removeAll(this);
|
||||||
if (m_parent && !m_parent->m_children.contains(this)) {
|
}
|
||||||
m_parent->m_children << this;
|
m_parent = parent;
|
||||||
}
|
if (m_parent && !m_parent->m_children.contains(this)) {
|
||||||
|
m_parent->m_children << this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -100,19 +101,16 @@ bool FileSystemItem::setNewName(const QString &newName)
|
||||||
{
|
{
|
||||||
switch (m_status) {
|
switch (m_status) {
|
||||||
case ItemStatus::Current:
|
case ItemStatus::Current:
|
||||||
if (!m_counterpart) {
|
if (m_counterpart) {
|
||||||
if (m_parent) {
|
|
||||||
m_counterpart = new FileSystemItem(ItemStatus::New, m_type, newName);
|
|
||||||
m_counterpart->m_counterpart = this;
|
|
||||||
m_counterpart->setParent(m_parent);
|
|
||||||
} else {
|
|
||||||
// parent required
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
m_counterpart->setName(newName);
|
m_counterpart->setName(newName);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
return true;
|
if (m_parent) {
|
||||||
|
m_counterpart = new FileSystemItem(ItemStatus::New, m_type, newName, m_parent);
|
||||||
|
m_counterpart->m_counterpart = this;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
case ItemStatus::New:
|
case ItemStatus::New:
|
||||||
setName(newName);
|
setName(newName);
|
||||||
return true;
|
return true;
|
||||||
|
@ -122,7 +120,7 @@ bool FileSystemItem::setNewName(const QString &newName)
|
||||||
|
|
||||||
FileSystemItem *FileSystemItem::findChild(const QString &name) const
|
FileSystemItem *FileSystemItem::findChild(const QString &name) const
|
||||||
{
|
{
|
||||||
for (FileSystemItem *child : m_children) {
|
for (auto *const child : m_children) {
|
||||||
if (child->name() == name) {
|
if (child->name() == name) {
|
||||||
return child;
|
return child;
|
||||||
}
|
}
|
||||||
|
@ -132,7 +130,7 @@ FileSystemItem *FileSystemItem::findChild(const QString &name) const
|
||||||
|
|
||||||
FileSystemItem *FileSystemItem::findChild(const QString &name, const FileSystemItem *exclude) const
|
FileSystemItem *FileSystemItem::findChild(const QString &name, const FileSystemItem *exclude) const
|
||||||
{
|
{
|
||||||
for (FileSystemItem *child : m_children) {
|
for (auto *const child : m_children) {
|
||||||
if (child != exclude && child->name() == name) {
|
if (child != exclude && child->name() == name) {
|
||||||
return child;
|
return child;
|
||||||
}
|
}
|
||||||
|
@ -142,23 +140,24 @@ FileSystemItem *FileSystemItem::findChild(const QString &name, const FileSystemI
|
||||||
|
|
||||||
FileSystemItem *FileSystemItem::makeChildAvailable(const QString &relativePath)
|
FileSystemItem *FileSystemItem::makeChildAvailable(const QString &relativePath)
|
||||||
{
|
{
|
||||||
QStringList dirs = relativePath.split(QDir::separator(), QString::SkipEmptyParts);
|
auto dirs = relativePath.split(QDir::separator(), QString::SkipEmptyParts);
|
||||||
FileSystemItem *parent = this;
|
if (dirs.isEmpty()) {
|
||||||
if (!dirs.isEmpty()) {
|
return this;
|
||||||
if (relativePath.startsWith(QChar('/'))) {
|
}
|
||||||
// we actually just got an absolute path
|
|
||||||
// -> just leave the / there to handle absolute path as well
|
auto *parent = this;
|
||||||
dirs.front().prepend(QChar('/'));
|
if (relativePath.startsWith(QChar('/'))) {
|
||||||
}
|
// we actually just got an absolute path
|
||||||
for (const QString &dir : dirs) {
|
// -> just leave the / there to handle absolute path as well
|
||||||
FileSystemItem *child = parent->findChild(dir);
|
dirs.front().prepend(QChar('/'));
|
||||||
if (!child) {
|
}
|
||||||
child = new FileSystemItem(ItemStatus::New, ItemType::Dir, dir);
|
for (const QString &dir : dirs) {
|
||||||
child->setParent(parent);
|
auto *child = parent->findChild(dir);
|
||||||
child->setNote(QCoreApplication::translate("RenamingUtility::FileSystemItem", "will be created"));
|
if (!child) {
|
||||||
}
|
child = new FileSystemItem(ItemStatus::New, ItemType::Dir, dir, parent);
|
||||||
parent = child;
|
child->setNote(QCoreApplication::translate("RenamingUtility::FileSystemItem", "will be created"));
|
||||||
}
|
}
|
||||||
|
parent = child;
|
||||||
}
|
}
|
||||||
return parent;
|
return parent;
|
||||||
}
|
}
|
||||||
|
@ -179,13 +178,14 @@ QString FileSystemItem::relativeDir() const
|
||||||
|
|
||||||
void FileSystemItem::relativePath(QString &res) const
|
void FileSystemItem::relativePath(QString &res) const
|
||||||
{
|
{
|
||||||
if (m_parent) {
|
if (!m_parent) {
|
||||||
m_parent->relativePath(res);
|
return;
|
||||||
if (!res.isEmpty()) {
|
|
||||||
res.append(QLatin1Char('/'));
|
|
||||||
}
|
|
||||||
res.append(name());
|
|
||||||
}
|
}
|
||||||
|
m_parent->relativePath(res);
|
||||||
|
if (!res.isEmpty()) {
|
||||||
|
res.append(QLatin1Char('/'));
|
||||||
|
}
|
||||||
|
res.append(name());
|
||||||
}
|
}
|
||||||
|
|
||||||
QString FileSystemItem::relativePath() const
|
QString FileSystemItem::relativePath() const
|
||||||
|
@ -197,17 +197,16 @@ QString FileSystemItem::relativePath() const
|
||||||
|
|
||||||
bool FileSystemItem::hasSibling(const QString &name) const
|
bool FileSystemItem::hasSibling(const QString &name) const
|
||||||
{
|
{
|
||||||
if (m_parent) {
|
if (!m_parent) {
|
||||||
const QList<FileSystemItem *> &siblings = m_parent->children();
|
return false;
|
||||||
for (const FileSystemItem *siblingItem : siblings) {
|
}
|
||||||
if (siblingItem == this) {
|
const auto &siblings = m_parent->children();
|
||||||
continue;
|
for (const auto *const siblingItem : siblings) {
|
||||||
}
|
if (siblingItem == this) {
|
||||||
if (!siblingItem->newName().isEmpty() && siblingItem->newName() == name) {
|
continue;
|
||||||
return true;
|
}
|
||||||
} else if (siblingItem->name() == name) {
|
if ((!siblingItem->newName().isEmpty() && siblingItem->newName() == name) || siblingItem->name() == name) {
|
||||||
return true;
|
return true;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -48,7 +48,7 @@ public:
|
||||||
void setChecked(bool checked);
|
void setChecked(bool checked);
|
||||||
bool checkable() const;
|
bool checkable() const;
|
||||||
void setCheckable(bool checkable);
|
void setCheckable(bool checkable);
|
||||||
int row();
|
int row() const;
|
||||||
void relativeDir(QString &res) const;
|
void relativeDir(QString &res) const;
|
||||||
QString relativeDir() const;
|
QString relativeDir() const;
|
||||||
void relativePath(QString &res) const;
|
void relativePath(QString &res) const;
|
||||||
|
@ -186,9 +186,9 @@ inline void FileSystemItem::setCheckable(bool checkable)
|
||||||
m_checkable = checkable;
|
m_checkable = checkable;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline int FileSystemItem::row()
|
inline int FileSystemItem::row() const
|
||||||
{
|
{
|
||||||
return m_parent ? m_parent->children().indexOf(this) : -1;
|
return m_parent ? m_parent->children().indexOf(const_cast<FileSystemItem *>(this)) : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace RenamingUtility
|
} // namespace RenamingUtility
|
||||||
|
|
|
@ -23,119 +23,126 @@ FileSystemItemModel::FileSystemItemModel(FileSystemItem *rootItem, QObject *pare
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
FileSystemItemModel::~FileSystemItemModel()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void FileSystemItemModel::setRootItem(FileSystemItem *rootItem)
|
void FileSystemItemModel::setRootItem(FileSystemItem *rootItem)
|
||||||
{
|
{
|
||||||
if (m_rootItem != rootItem) {
|
if (m_rootItem == rootItem) {
|
||||||
beginResetModel();
|
return;
|
||||||
m_rootItem = rootItem;
|
|
||||||
endResetModel();
|
|
||||||
}
|
}
|
||||||
|
beginResetModel();
|
||||||
|
m_rootItem = rootItem;
|
||||||
|
endResetModel();
|
||||||
|
}
|
||||||
|
|
||||||
|
FileSystemItem *FileSystemItemModel::fileSystemItemFromIndex(const QModelIndex &index)
|
||||||
|
{
|
||||||
|
return index.isValid() ? reinterpret_cast<FileSystemItem *>(index.internalPointer()) : nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
const FileSystemItem *FileSystemItemModel::fileSystemItemFromIndex(const QModelIndex &index) const
|
||||||
|
{
|
||||||
|
return const_cast<FileSystemItemModel *>(this)->fileSystemItemFromIndex(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariant FileSystemItemModel::data(const QModelIndex &index, int role) const
|
QVariant FileSystemItemModel::data(const QModelIndex &index, int role) const
|
||||||
{
|
{
|
||||||
if (index.isValid()) {
|
const auto *const item = fileSystemItemFromIndex(index);
|
||||||
if (FileSystemItem *item = reinterpret_cast<FileSystemItem *>(index.internalPointer())) {
|
if (!item) {
|
||||||
switch (role) {
|
return QVariant();
|
||||||
case Qt::DisplayRole:
|
}
|
||||||
switch (index.column()) {
|
switch (role) {
|
||||||
case 0:
|
case Qt::DisplayRole:
|
||||||
switch (item->status()) {
|
switch (index.column()) {
|
||||||
case ItemStatus::Current:
|
case 0:
|
||||||
return item->name();
|
switch (item->status()) {
|
||||||
case ItemStatus::New:
|
case ItemStatus::Current:
|
||||||
return item->counterpart() ? item->counterpart()->name() : item->name();
|
return item->name();
|
||||||
}
|
case ItemStatus::New:
|
||||||
break;
|
return item->counterpart() ? item->counterpart()->name() : item->name();
|
||||||
case 1:
|
|
||||||
switch (item->status()) {
|
|
||||||
case ItemStatus::Current:
|
|
||||||
return item->counterpart() ? item->counterpart()->name() : item->name();
|
|
||||||
case ItemStatus::New:
|
|
||||||
return item->name();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
return item->note();
|
|
||||||
default:;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case Qt::DecorationRole:
|
|
||||||
switch (index.column()) {
|
|
||||||
case 0:
|
|
||||||
case 1:
|
|
||||||
switch (item->type()) {
|
|
||||||
case ItemType::Dir:
|
|
||||||
return QApplication::style()->standardIcon(QStyle::SP_DirIcon);
|
|
||||||
default:;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case Qt::FontRole: {
|
|
||||||
QFont font;
|
|
||||||
if ((index.column() == 0 && item->status() == ItemStatus::New && !item->counterpart())
|
|
||||||
|| (index.column() == 1 && item->status() == ItemStatus::Current && !item->counterpart())) {
|
|
||||||
font.setItalic(true);
|
|
||||||
}
|
|
||||||
return font;
|
|
||||||
}
|
}
|
||||||
case Qt::ForegroundRole:
|
break;
|
||||||
if (item->errorOccured()) {
|
case 1:
|
||||||
return QBrush(Qt::red);
|
switch (item->status()) {
|
||||||
} else if (item->applied()) {
|
case ItemStatus::Current:
|
||||||
return QBrush(Qt::darkGreen);
|
return item->counterpart() ? item->counterpart()->name() : item->name();
|
||||||
} else if ((index.column() == 0 && item->status() == ItemStatus::New && !item->counterpart())
|
case ItemStatus::New:
|
||||||
|| (index.column() == 1 && item->status() == ItemStatus::Current && !item->counterpart())) {
|
return item->name();
|
||||||
return QBrush(Qt::gray);
|
}
|
||||||
}
|
break;
|
||||||
break;
|
case 2:
|
||||||
case ErrorStatusRole:
|
return item->note();
|
||||||
return item->errorOccured();
|
default:;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Qt::DecorationRole:
|
||||||
|
switch (index.column()) {
|
||||||
|
case 0:
|
||||||
|
case 1:
|
||||||
|
switch (item->type()) {
|
||||||
|
case ItemType::Dir:
|
||||||
|
return QApplication::style()->standardIcon(QStyle::SP_DirIcon);
|
||||||
default:;
|
default:;
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
default:;
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
case Qt::FontRole: {
|
||||||
|
QFont font;
|
||||||
|
if ((index.column() == 0 && item->status() == ItemStatus::New && !item->counterpart())
|
||||||
|
|| (index.column() == 1 && item->status() == ItemStatus::Current && !item->counterpart())) {
|
||||||
|
font.setItalic(true);
|
||||||
|
}
|
||||||
|
return font;
|
||||||
|
}
|
||||||
|
case Qt::ForegroundRole:
|
||||||
|
if (item->errorOccured()) {
|
||||||
|
return QBrush(Qt::red);
|
||||||
|
} else if (item->applied()) {
|
||||||
|
return QBrush(Qt::darkGreen);
|
||||||
|
} else if ((index.column() == 0 && item->status() == ItemStatus::New && !item->counterpart())
|
||||||
|
|| (index.column() == 1 && item->status() == ItemStatus::Current && !item->counterpart())) {
|
||||||
|
return QBrush(Qt::gray);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ErrorStatusRole:
|
||||||
|
return item->errorOccured();
|
||||||
|
default:;
|
||||||
}
|
}
|
||||||
return QVariant();
|
return QVariant();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FileSystemItemModel::setData(const QModelIndex &index, const QVariant &value, int role)
|
bool FileSystemItemModel::setData(const QModelIndex &index, const QVariant &value, int role)
|
||||||
{
|
{
|
||||||
if (index.isValid()) {
|
auto *const item = fileSystemItemFromIndex(index);
|
||||||
if (FileSystemItem *item = reinterpret_cast<FileSystemItem *>(index.internalPointer())) {
|
if (!item) {
|
||||||
switch (role) {
|
return false;
|
||||||
case Qt::DisplayRole:
|
}
|
||||||
switch (index.column()) {
|
switch (role) {
|
||||||
case 0:
|
case Qt::DisplayRole:
|
||||||
if (item->setCurrentName(value.toString())) {
|
switch (index.column()) {
|
||||||
emit dataChanged(index, index, QVector<int>() << role);
|
case 0:
|
||||||
return true;
|
if (item->setCurrentName(value.toString())) {
|
||||||
} else {
|
emit dataChanged(index, index, QVector<int>() << role);
|
||||||
return false;
|
|
||||||
}
|
|
||||||
case 1:
|
|
||||||
item->setNewName(value.toString());
|
|
||||||
emit dataChanged(index, index, QVector<int>() << role);
|
|
||||||
return true;
|
|
||||||
case 2:
|
|
||||||
item->setNote(value.toString());
|
|
||||||
emit dataChanged(index, index, QVector<int>() << role);
|
|
||||||
return true;
|
|
||||||
default:;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case ErrorStatusRole:
|
|
||||||
item->setErrorOccured(value.toBool());
|
|
||||||
emit dataChanged(index, index, QVector<int>() << role << Qt::DecorationRole);
|
|
||||||
return true;
|
return true;
|
||||||
default:;
|
} else {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
case 1:
|
||||||
|
item->setNewName(value.toString());
|
||||||
|
emit dataChanged(index, index, QVector<int>() << role);
|
||||||
|
return true;
|
||||||
|
case 2:
|
||||||
|
item->setNote(value.toString());
|
||||||
|
emit dataChanged(index, index, QVector<int>() << role);
|
||||||
|
return true;
|
||||||
|
default:;
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
case ErrorStatusRole:
|
||||||
|
item->setErrorOccured(value.toBool());
|
||||||
|
emit dataChanged(index, index, QVector<int>() << role << Qt::DecorationRole);
|
||||||
|
return true;
|
||||||
|
default:;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -152,7 +159,7 @@ QVariant FileSystemItemModel::headerData(int section, Qt::Orientation orientatio
|
||||||
case 1:
|
case 1:
|
||||||
return tr("New name");
|
return tr("New name");
|
||||||
case 2:
|
case 2:
|
||||||
return tr("Notes");
|
return tr("Note");
|
||||||
default:;
|
default:;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -166,32 +173,32 @@ QVariant FileSystemItemModel::headerData(int section, Qt::Orientation orientatio
|
||||||
|
|
||||||
QModelIndex FileSystemItemModel::index(int row, int column, const QModelIndex &parent) const
|
QModelIndex FileSystemItemModel::index(int row, int column, const QModelIndex &parent) const
|
||||||
{
|
{
|
||||||
if (FileSystemItem *parentItem = parent.isValid() ? reinterpret_cast<FileSystemItem *>(parent.internalPointer()) : m_rootItem) {
|
const auto *const parentItem = parent.isValid() ? reinterpret_cast<FileSystemItem *>(parent.internalPointer()) : m_rootItem;
|
||||||
const QList<FileSystemItem *> &children = parentItem->children();
|
if (!parentItem) {
|
||||||
if (row < children.length()) {
|
return QModelIndex();
|
||||||
return createIndex(row, column, children.at(row));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return QModelIndex();
|
const auto &children = parentItem->children();
|
||||||
|
return row < children.size() ? createIndex(row, column, children.at(row)) : QModelIndex();
|
||||||
}
|
}
|
||||||
|
|
||||||
QModelIndex FileSystemItemModel::index(FileSystemItem *item, int column) const
|
QModelIndex FileSystemItemModel::index(FileSystemItem *item, int column) const
|
||||||
{
|
{
|
||||||
forward_list<FileSystemItem *> path;
|
forward_list<FileSystemItem *> path;
|
||||||
path.push_front(item);
|
path.push_front(item);
|
||||||
FileSystemItem *parent = item->parent();
|
auto *parent = item->parent();
|
||||||
while (parent) {
|
while (parent) {
|
||||||
path.push_front(parent);
|
path.push_front(parent);
|
||||||
parent = parent->parent();
|
parent = parent->parent();
|
||||||
}
|
}
|
||||||
if (path.front() == m_rootItem) {
|
if (path.front() != m_rootItem) {
|
||||||
path.pop_front();
|
return QModelIndex();
|
||||||
QModelIndex index;
|
}
|
||||||
for (FileSystemItem *pathItem : path) {
|
path.pop_front();
|
||||||
index = this->index(pathItem->row(), column, index);
|
QModelIndex index;
|
||||||
if (pathItem == item || !index.isValid()) {
|
for (auto *const pathItem : path) {
|
||||||
return index;
|
index = this->index(pathItem->row(), column, index);
|
||||||
}
|
if (pathItem == item || !index.isValid()) {
|
||||||
|
return index;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return QModelIndex();
|
return QModelIndex();
|
||||||
|
@ -199,35 +206,32 @@ QModelIndex FileSystemItemModel::index(FileSystemItem *item, int column) const
|
||||||
|
|
||||||
QModelIndex FileSystemItemModel::parent(const QModelIndex &index) const
|
QModelIndex FileSystemItemModel::parent(const QModelIndex &index) const
|
||||||
{
|
{
|
||||||
if (index.isValid()) {
|
const auto *const item = fileSystemItemFromIndex(index);
|
||||||
if (FileSystemItem *item = reinterpret_cast<FileSystemItem *>(index.internalPointer())) {
|
if (!item) {
|
||||||
FileSystemItem *parent = item->parent();
|
return QModelIndex();
|
||||||
if (parent && (index.row() < parent->children().length())) {
|
|
||||||
return createIndex(parent->row(), index.column(), parent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return QModelIndex();
|
auto *const parent = item->parent();
|
||||||
|
if (!parent || index.row() >= parent->children().size()) {
|
||||||
|
return QModelIndex();
|
||||||
|
}
|
||||||
|
return createIndex(parent->row(), index.column(), parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
QModelIndex FileSystemItemModel::counterpart(const QModelIndex &index, int column = -1)
|
QModelIndex FileSystemItemModel::counterpart(const QModelIndex &index, int column = -1)
|
||||||
{
|
{
|
||||||
if (index.isValid()) {
|
const auto *const item = fileSystemItemFromIndex(index);
|
||||||
if (column < 0) {
|
if (!item) {
|
||||||
column = index.column();
|
return QModelIndex();
|
||||||
}
|
|
||||||
if (FileSystemItem *item = reinterpret_cast<FileSystemItem *>(index.internalPointer())) {
|
|
||||||
if (item->counterpart()) {
|
|
||||||
return this->index(item->counterpart(), column);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return QModelIndex();
|
if (column < 0) {
|
||||||
|
column = index.column();
|
||||||
|
}
|
||||||
|
return item->counterpart() ? this->index(item->counterpart(), column) : QModelIndex();
|
||||||
}
|
}
|
||||||
|
|
||||||
int FileSystemItemModel::rowCount(const QModelIndex &parent) const
|
int FileSystemItemModel::rowCount(const QModelIndex &parent) const
|
||||||
{
|
{
|
||||||
if (const FileSystemItem *parentItem = (parent.isValid() ? reinterpret_cast<FileSystemItem *>(parent.internalPointer()) : m_rootItem)) {
|
if (const auto *const parentItem = (parent.isValid() ? reinterpret_cast<FileSystemItem *>(parent.internalPointer()) : m_rootItem)) {
|
||||||
return parentItem->children().size();
|
return parentItem->children().size();
|
||||||
} else {
|
} else {
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -236,7 +240,7 @@ int FileSystemItemModel::rowCount(const QModelIndex &parent) const
|
||||||
|
|
||||||
bool FileSystemItemModel::hasChildren(const QModelIndex &parent) const
|
bool FileSystemItemModel::hasChildren(const QModelIndex &parent) const
|
||||||
{
|
{
|
||||||
if (const FileSystemItem *parentItem = (parent.isValid() ? reinterpret_cast<const FileSystemItem *>(parent.internalPointer()) : m_rootItem)) {
|
if (const auto *const parentItem = (parent.isValid() ? reinterpret_cast<const FileSystemItem *>(parent.internalPointer()) : m_rootItem)) {
|
||||||
return parentItem->children().size() > 0;
|
return parentItem->children().size() > 0;
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -14,9 +14,10 @@ class FileSystemItemModel : public QAbstractItemModel {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit FileSystemItemModel(FileSystemItem *rootItem, QObject *parent = nullptr);
|
explicit FileSystemItemModel(FileSystemItem *rootItem, QObject *parent = nullptr);
|
||||||
~FileSystemItemModel();
|
|
||||||
|
|
||||||
void setRootItem(FileSystemItem *rootItem);
|
void setRootItem(FileSystemItem *rootItem);
|
||||||
|
FileSystemItem *fileSystemItemFromIndex(const QModelIndex &index);
|
||||||
|
const FileSystemItem *fileSystemItemFromIndex(const QModelIndex &index) const;
|
||||||
QVariant data(const QModelIndex &index, int role) const;
|
QVariant data(const QModelIndex &index, int role) const;
|
||||||
bool setData(const QModelIndex &index, const QVariant &value, int role);
|
bool setData(const QModelIndex &index, const QVariant &value, int role);
|
||||||
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
|
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
|
||||||
|
|
|
@ -15,23 +15,28 @@ FilteredFileSystemItemModel::FilteredFileSystemItemModel(ItemStatus statusFilter
|
||||||
|
|
||||||
bool FilteredFileSystemItemModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const
|
bool FilteredFileSystemItemModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const
|
||||||
{
|
{
|
||||||
QModelIndex sourceIndex = sourceModel()->index(sourceRow, 0, sourceParent);
|
const auto sourceIndex = sourceModel()->index(sourceRow, 0, sourceParent);
|
||||||
if (sourceIndex.isValid()) {
|
if (!sourceIndex.isValid()) {
|
||||||
if (FileSystemItem *item = reinterpret_cast<FileSystemItem *>(sourceIndex.internalPointer())) {
|
return false;
|
||||||
if (item->status() == m_statusFilter) {
|
}
|
||||||
return true;
|
const auto *const item = reinterpret_cast<FileSystemItem *>(sourceIndex.internalPointer());
|
||||||
} else if (item->status() == ItemStatus::Current && !item->counterpart() && !item->note().isEmpty()) {
|
if (!item) {
|
||||||
return true;
|
return false;
|
||||||
} else if (item->type() == ItemType::Dir) {
|
}
|
||||||
QModelIndex child = sourceIndex.child(0, 0);
|
|
||||||
while (child.isValid()) {
|
if (item->status() == m_statusFilter || (item->status() == ItemStatus::Current && !item->counterpart() && !item->note().isEmpty())) {
|
||||||
if (filterAcceptsRow(child.row(), sourceIndex)) {
|
return true;
|
||||||
return true;
|
}
|
||||||
}
|
if (item->type() != ItemType::Dir) {
|
||||||
child = sourceIndex.child(child.row() + 1, 0);
|
return false;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
auto child = sourceIndex.child(0, 0);
|
||||||
|
while (child.isValid()) {
|
||||||
|
if (filterAcceptsRow(child.row(), sourceIndex)) {
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
child = sourceIndex.child(child.row() + 1, 0);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -43,9 +48,8 @@ bool FilteredFileSystemItemModel::filterAcceptsColumn(int sourceColumn, const QM
|
||||||
return sourceColumn == 0;
|
return sourceColumn == 0;
|
||||||
case ItemStatus::New:
|
case ItemStatus::New:
|
||||||
return sourceColumn == 1 || sourceColumn == 2;
|
return sourceColumn == 1 || sourceColumn == 2;
|
||||||
default:
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace RenamingUtility
|
} // namespace RenamingUtility
|
||||||
|
|
|
@ -204,7 +204,7 @@ unique_ptr<FileSystemItem> RenamingEngine::generatePreview(const QDir &dir, File
|
||||||
|
|
||||||
void RenamingEngine::applyChangings(FileSystemItem *parentItem)
|
void RenamingEngine::applyChangings(FileSystemItem *parentItem)
|
||||||
{
|
{
|
||||||
for (FileSystemItem *item : parentItem->children()) {
|
for (auto *const item : parentItem->children()) {
|
||||||
if (!item->applied() && !item->errorOccured()) {
|
if (!item->applied() && !item->errorOccured()) {
|
||||||
switch (item->status()) {
|
switch (item->status()) {
|
||||||
case ItemStatus::New: {
|
case ItemStatus::New: {
|
||||||
|
@ -277,7 +277,7 @@ void RenamingEngine::applyChangings(FileSystemItem *parentItem)
|
||||||
|
|
||||||
void RenamingEngine::setError(const QList<FileSystemItem *> items)
|
void RenamingEngine::setError(const QList<FileSystemItem *> items)
|
||||||
{
|
{
|
||||||
for (FileSystemItem *item : items) {
|
for (auto *const 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"));
|
||||||
}
|
}
|
||||||
|
|
|
@ -228,30 +228,29 @@ TAGEDITOR_JS_VALUE TagEditorObject::parseFileName(const QString &fileName)
|
||||||
TAGEDITOR_JS_VALUE TagEditorObject::allFiles(const QString &dirName)
|
TAGEDITOR_JS_VALUE TagEditorObject::allFiles(const QString &dirName)
|
||||||
{
|
{
|
||||||
const QDir dir(dirName);
|
const QDir dir(dirName);
|
||||||
if (dir.exists()) {
|
if (!dir.exists()) {
|
||||||
const auto files(dir.entryList(QDir::Files));
|
|
||||||
auto entriesObj = m_engine->newArray(static_cast<uint>(files.size()));
|
|
||||||
quint32 counter = 0;
|
|
||||||
for (const auto &file : files) {
|
|
||||||
entriesObj.setProperty(counter, file TAGEDITOR_JS_READONLY);
|
|
||||||
++counter;
|
|
||||||
}
|
|
||||||
return entriesObj;
|
|
||||||
} else {
|
|
||||||
return TAGEDITOR_JS_VALUE();
|
return TAGEDITOR_JS_VALUE();
|
||||||
}
|
}
|
||||||
|
const auto files(dir.entryList(QDir::Files));
|
||||||
|
auto entriesObj = m_engine->newArray(static_cast<uint>(files.size()));
|
||||||
|
quint32 counter = 0;
|
||||||
|
for (const auto &file : files) {
|
||||||
|
entriesObj.setProperty(counter++, file TAGEDITOR_JS_READONLY);
|
||||||
|
}
|
||||||
|
return entriesObj;
|
||||||
}
|
}
|
||||||
|
|
||||||
TAGEDITOR_JS_VALUE TagEditorObject::firstFile(const QString &dirName)
|
TAGEDITOR_JS_VALUE TagEditorObject::firstFile(const QString &dirName)
|
||||||
{
|
{
|
||||||
const QDir dir(dirName);
|
const QDir dir(dirName);
|
||||||
if (dir.exists()) {
|
if (!dir.exists()) {
|
||||||
const auto files(dir.entryList(QDir::Files));
|
return TAGEDITOR_JS_VALUE();
|
||||||
if (!files.empty()) {
|
|
||||||
return TAGEDITOR_JS_VALUE(files.first());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return TAGEDITOR_JS_VALUE();
|
const auto files(dir.entryList(QDir::Files));
|
||||||
|
if (files.empty()) {
|
||||||
|
return TAGEDITOR_JS_VALUE();
|
||||||
|
}
|
||||||
|
return TAGEDITOR_JS_VALUE(files.first());
|
||||||
}
|
}
|
||||||
|
|
||||||
void TagEditorObject::writeLog(const QString &message)
|
void TagEditorObject::writeLog(const QString &message)
|
||||||
|
|
|
@ -2,49 +2,47 @@
|
||||||
// This is an example script demonstrating how the renaming tool can be used.
|
// This is an example script demonstrating how the renaming tool can be used.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
//
|
||||||
// script configuration
|
// script configuration
|
||||||
|
//
|
||||||
|
|
||||||
// specifies the separator between artist, album and track number
|
// specifies the separator between artist, album and track number
|
||||||
var separator = ", ";
|
var separator = ", ";
|
||||||
// specifies the separator between title and other fields
|
// specifies the separator between title and other fields
|
||||||
var lastSeparator = " - ";
|
var lastSeparator = " - ";
|
||||||
// specifies whether the artist name should be included
|
// specifies whether the artist name should be included
|
||||||
var includeArtist = false;
|
var includeArtist = true;
|
||||||
// specifies whether the album name should be included
|
// specifies whether the album name should be included
|
||||||
var includeAlbum = false;
|
var includeAlbum = true;
|
||||||
// specifies whether the title should be included
|
// specifies whether the title should be included
|
||||||
var includeTitle = true;
|
var includeTitle = true;
|
||||||
// specifies the distribution directory
|
// specifies the "distribution directory"
|
||||||
// all files will be moved in an appropriate subdirectory in the
|
//var distDir = false; // don't move files around
|
||||||
// distribution directory if one is specified
|
var distDir = "/path/to/my/music-collection"; // move files to an appropriate subdirectory under this path
|
||||||
var distDir = false;
|
// directory used to store collections which contain songs from multiple artists
|
||||||
// string used for "miscellaneous" category
|
|
||||||
var misc = "misc";
|
|
||||||
// directory used to store collections
|
|
||||||
var collectionsDir = "collections";
|
var collectionsDir = "collections";
|
||||||
|
// directory used to store miscellaneous songs by miscellaneous artists
|
||||||
|
var miscDir = "misc";
|
||||||
|
// directory used for miscellaneous songs by specific artist
|
||||||
|
var miscAlbumDir = "misc";
|
||||||
|
// condition to move files to miscDir
|
||||||
|
var isMiscFile = function (tag) { return tag.comment === "misc"; };
|
||||||
|
// condition to consider files part of a collection which contains songs from multiple artists
|
||||||
|
var isPartOfCollection = function (tag) { return tag.comment === "collection"; }
|
||||||
|
|
||||||
// define some helper functions
|
//
|
||||||
|
// helper functions
|
||||||
|
//
|
||||||
|
|
||||||
/*!
|
// 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) {
|
function notEmpty(value) {
|
||||||
return value !== undefined && value !== "";
|
return value !== undefined && value !== "";
|
||||||
}
|
}
|
||||||
|
// 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) {
|
function notNull(value) {
|
||||||
return value !== undefined && value !== 0;
|
return value !== undefined && value !== 0;
|
||||||
}
|
}
|
||||||
|
// 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) {
|
function appropriateDigitCount(pos, total) {
|
||||||
var res = pos + "";
|
var res = pos + "";
|
||||||
var count = (total + "").length;
|
var count = (total + "").length;
|
||||||
|
@ -53,152 +51,147 @@ function appropriateDigitCount(pos, total) {
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
// 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) {
|
function validFileName(name) {
|
||||||
if(name !== undefined) {
|
return name !== undefined ? name.replace(/[\/\\]/gi, " - ").replace(/[<>?!*|:\"\n\f\r]/gi, "") : "";
|
||||||
return name.replace(/[\/\\]/gi, " - ").replace(/[<>?!*|:\"\n\f\r]/gi, "");
|
|
||||||
} else {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
// 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) {
|
function validDirectoryName(name) {
|
||||||
if(name !== undefined) {
|
return name !== undefined ? name.replace(/[\/\\]/gi, " - ").replace(/[<>?!*|:\".\n\f\r]/gi, "") : "";
|
||||||
return name.replace(/[\/\\]/gi, " - ").replace(/[<>?!*|:\".\n\f\r]/gi, "");
|
|
||||||
} else {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// the actual script
|
//
|
||||||
|
// actual script
|
||||||
|
//
|
||||||
|
|
||||||
// check whether we have to deal with a file or a directory
|
// skip directories in this example script
|
||||||
if(tageditor.isFile) {
|
if (!tageditor.isFile) {
|
||||||
// parse file using the built-in parseFileInfo function
|
|
||||||
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 = tageditor.parseFileName(fileInfo.currentBaseName);
|
|
||||||
// read the suffix from the file info object to filter backup and temporary files
|
|
||||||
if(fileInfo.currentName === "desktop.ini") {
|
|
||||||
tageditor.skip(); // skip these files
|
|
||||||
} else if(fileInfo.currentSuffix === "bak") {
|
|
||||||
// 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
|
|
||||||
tageditor.move("temp");
|
|
||||||
} else {
|
|
||||||
// define an array for the fields; will be joined later
|
|
||||||
var fields = [];
|
|
||||||
// get the artist and remove invalid characters
|
|
||||||
var artist = validFileName(tag.artist);
|
|
||||||
// add artist to the fields array
|
|
||||||
// (if configured and present and if it is no collection)
|
|
||||||
if(includeArtist && tag.comment !== "collection") {
|
|
||||||
if(notEmpty(artist)) {
|
|
||||||
fields.push(artist);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// get the album and remove invalid characters
|
|
||||||
var album = validFileName(tag.album);
|
|
||||||
// add album to the fields array (if configure and present)
|
|
||||||
if(includeAlbum) {
|
|
||||||
if(notEmpty(tag.album)) {
|
|
||||||
fields.push(album);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// get the track/disk position; use the value from the tag if possible
|
|
||||||
if(notNull(tag.trackPos)) {
|
|
||||||
// define an array for the track position; will be joined later
|
|
||||||
var pos = [];
|
|
||||||
// push the disk position
|
|
||||||
if(notNull(tag.diskPos)
|
|
||||||
&& notNull(tag.diskTotal)
|
|
||||||
&& tag.diskTotal >= 2) {
|
|
||||||
pos.push(appropriateDigitCount(tag.diskPos, tag.diskTotal));
|
|
||||||
}
|
|
||||||
// push the track count
|
|
||||||
if(notNull(tag.trackTotal)) {
|
|
||||||
pos.push(appropriateDigitCount(tag.trackPos, tag.trackTotal));
|
|
||||||
} else {
|
|
||||||
pos.push(appropriateDigitCount(tag.trackPos, 10));
|
|
||||||
}
|
|
||||||
fields.push(pos.join("-"));
|
|
||||||
} else if(notNull(infoFromFileName.trackPos)) {
|
|
||||||
// get the track position from the file name if the tag has no track position field
|
|
||||||
fields.push(appropriateDigitCount(infoFromFileName.trackPos, 10));
|
|
||||||
}
|
|
||||||
// join the first part of the new name
|
|
||||||
var newName = fields.join(separator);
|
|
||||||
// get the title
|
|
||||||
var title = validFileName(tag.title);
|
|
||||||
// append the title (if configured and present)
|
|
||||||
if(includeTitle) {
|
|
||||||
// use value from file name if the tag has no title information
|
|
||||||
if(!notEmpty(title)) {
|
|
||||||
title = validFileName(infoFromFileName.title);
|
|
||||||
}
|
|
||||||
if(newName.length > 0) {
|
|
||||||
newName = newName.concat(lastSeparator, title);
|
|
||||||
} else {
|
|
||||||
newName = newName.concat(title);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// get an appropriate suffix
|
|
||||||
var suffix = "";
|
|
||||||
if(notEmpty(fileInfo.suitableSuffix)) {
|
|
||||||
// get a suitable suffix from the file info object if available
|
|
||||||
suffix = fileInfo.suitableSuffix;
|
|
||||||
} else if(notEmpty(fileInfo.currentSuffix)) {
|
|
||||||
// or just use the current suffix otherwise
|
|
||||||
suffix = fileInfo.currentSuffix;
|
|
||||||
}
|
|
||||||
// append the suffix
|
|
||||||
if(notEmpty(suffix)) {
|
|
||||||
newName = newName.concat(".", suffix);
|
|
||||||
}
|
|
||||||
// apply new name
|
|
||||||
tageditor.rename(newName);
|
|
||||||
// set the distribution directory
|
|
||||||
if(distDir) {
|
|
||||||
var path = [distDir];
|
|
||||||
var artist = validDirectoryName(tag.artist);
|
|
||||||
if(tag.comment === "collection") {
|
|
||||||
path.push(collectionsDir);
|
|
||||||
} else {
|
|
||||||
if(notEmpty(artist)) {
|
|
||||||
path.push(artist);
|
|
||||||
} else {
|
|
||||||
path.push(misc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var album = validDirectoryName(tag.album);
|
|
||||||
if(notEmpty(album)) {
|
|
||||||
if(notEmpty(tag.year)) {
|
|
||||||
path.push([tag.year.split("-")[0], album].join(" - "));
|
|
||||||
} else {
|
|
||||||
path.push(album);
|
|
||||||
}
|
|
||||||
} else if(notEmpty(artist)) {
|
|
||||||
path.push(misc);
|
|
||||||
}
|
|
||||||
if(tag.diskTotal >= 2) {
|
|
||||||
path.push("Disk " + appropriateDigitCount(tag.diskPos, tag.diskTotal));
|
|
||||||
}
|
|
||||||
// apply new relative directory
|
|
||||||
tageditor.move(path.join("/"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if(tageditor.isDir) {
|
|
||||||
// skip directories in this example script
|
|
||||||
tageditor.skip();
|
tageditor.skip();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// parse file using the built-in parseFileInfo function
|
||||||
|
var fileInfo = tageditor.parseFileInfo(tageditor.currentPath);
|
||||||
|
var tag = fileInfo.tag;
|
||||||
|
|
||||||
|
// deduce title and track number from the file name using the built-in parseFileName function (as fallback if tags missing)
|
||||||
|
var infoFromFileName = tageditor.parseFileName(fileInfo.currentBaseName);
|
||||||
|
|
||||||
|
// skip hidden and "desktop.ini" files
|
||||||
|
if (fileInfo.currentName.indexOf(".") === 0 || fileInfo.currentName === "desktop.ini") {
|
||||||
|
tageditor.skip();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// skip files which don't contain audio or video tracks
|
||||||
|
if (!fileInfo.hasAudioTracks && !fileInfo.hasVideoTracks) {
|
||||||
|
tageditor.skip();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// filter backup and temporary files by putting them in a separate directory
|
||||||
|
if (fileInfo.currentSuffix === "bak") {
|
||||||
|
tageditor.move("backups");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (fileInfo.currentSuffix === "tmp") {
|
||||||
|
tageditor.move("temp");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// define an array for the fields to be joined later
|
||||||
|
var fields = [];
|
||||||
|
|
||||||
|
// get the artist, remove invalid characters and add it to fields array
|
||||||
|
var artist = validFileName(tag.artist);
|
||||||
|
if (includeArtist && !isPartOfCollection(tag) && notEmpty(artist)) {
|
||||||
|
fields.push(artist);
|
||||||
|
}
|
||||||
|
|
||||||
|
// get the album and remove invalid characters and add it to fields array
|
||||||
|
var album = validFileName(tag.album);
|
||||||
|
if (includeAlbum && notEmpty(tag.album)) {
|
||||||
|
fields.push(album);
|
||||||
|
}
|
||||||
|
|
||||||
|
// get the track/disk position and add it to fields array
|
||||||
|
// use the value from the tag if possible; otherwise the value deduced from the filename
|
||||||
|
if (notNull(tag.trackPos)) {
|
||||||
|
var pos = [];
|
||||||
|
// push the disk position
|
||||||
|
if (notNull(tag.diskPos) && notNull(tag.diskTotal) && tag.diskTotal >= 2) {
|
||||||
|
pos.push(appropriateDigitCount(tag.diskPos, tag.diskTotal));
|
||||||
|
}
|
||||||
|
// push the track count
|
||||||
|
if (notNull(tag.trackTotal)) {
|
||||||
|
pos.push(appropriateDigitCount(tag.trackPos, tag.trackTotal));
|
||||||
|
} else {
|
||||||
|
pos.push(appropriateDigitCount(tag.trackPos, 10));
|
||||||
|
}
|
||||||
|
fields.push(pos.join("-"));
|
||||||
|
} else if (notNull(infoFromFileName.trackPos)) {
|
||||||
|
fields.push(appropriateDigitCount(infoFromFileName.trackPos, 10));
|
||||||
|
}
|
||||||
|
|
||||||
|
// join the first part of the new name
|
||||||
|
var newName = fields.join(separator);
|
||||||
|
|
||||||
|
// get the title and append it
|
||||||
|
var title = validFileName(tag.title);
|
||||||
|
if (includeTitle) {
|
||||||
|
// use value from file name if the tag has no title information
|
||||||
|
if (!notEmpty(title)) {
|
||||||
|
title = validFileName(infoFromFileName.title);
|
||||||
|
}
|
||||||
|
if (newName.length > 0) {
|
||||||
|
newName = newName.concat(lastSeparator, title);
|
||||||
|
} else {
|
||||||
|
newName = newName.concat(title);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// append an appropriate suffix
|
||||||
|
var suffix = "";
|
||||||
|
if (notEmpty(fileInfo.suitableSuffix)) {
|
||||||
|
// get a suitable suffix from the file info object if available
|
||||||
|
suffix = fileInfo.suitableSuffix;
|
||||||
|
} else if (notEmpty(fileInfo.currentSuffix)) {
|
||||||
|
// or just use the current suffix otherwise
|
||||||
|
suffix = fileInfo.currentSuffix;
|
||||||
|
}
|
||||||
|
if (notEmpty(suffix)) {
|
||||||
|
newName = newName.concat(".", suffix);
|
||||||
|
}
|
||||||
|
|
||||||
|
// apply new name
|
||||||
|
tageditor.rename(newName);
|
||||||
|
|
||||||
|
// set the distribution directory
|
||||||
|
if (!distDir) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var path = [distDir];
|
||||||
|
var artist = validDirectoryName(tag.artist);
|
||||||
|
if (isPartOfCollection(tag)) {
|
||||||
|
path.push(collectionsDir);
|
||||||
|
} else if (isMiscFile(tag)) {
|
||||||
|
path.push(miscDir);
|
||||||
|
} else if (notEmpty(artist)) {
|
||||||
|
path.push(artist);
|
||||||
|
} else {
|
||||||
|
path.push(misc);
|
||||||
|
}
|
||||||
|
var album = validDirectoryName(tag.album);
|
||||||
|
if (notEmpty(album)) {
|
||||||
|
if (notEmpty(tag.year)) {
|
||||||
|
path.push([tag.year.split("-")[0], album].join(" - "));
|
||||||
|
} else {
|
||||||
|
path.push(album);
|
||||||
|
}
|
||||||
|
} else if (notEmpty(artist) && !isMiscFile(tag)) {
|
||||||
|
path.push(miscAlbumDir);
|
||||||
|
}
|
||||||
|
if (tag.diskTotal >= 2) {
|
||||||
|
path.push("Disk " + appropriateDigitCount(tag.diskPos, tag.diskTotal));
|
||||||
|
}
|
||||||
|
// apply new relative directory
|
||||||
|
tageditor.move(path.join("/"));
|
||||||
|
|
Loading…
Reference in New Issue