aboutsummaryrefslogtreecommitdiff
path: root/src/qmmpui
diff options
context:
space:
mode:
Diffstat (limited to 'src/qmmpui')
-rw-r--r--src/qmmpui/metadataformatter.cpp93
-rw-r--r--src/qmmpui/metadataformatter.h11
2 files changed, 99 insertions, 5 deletions
diff --git a/src/qmmpui/metadataformatter.cpp b/src/qmmpui/metadataformatter.cpp
index c63938560..c2f52f2b7 100644
--- a/src/qmmpui/metadataformatter.cpp
+++ b/src/qmmpui/metadataformatter.cpp
@@ -1,5 +1,5 @@
/***************************************************************************
- * Copyright (C) 2015 by Ilya Kotov *
+ * Copyright (C) 2015-2017 by Ilya Kotov *
* forkotov02@hotmail.ru *
* *
* This program is free software; you can redistribute it and/or modify *
@@ -37,7 +37,8 @@ Syntax:
%y - year,
%l - duration,
%I - track index,
-%if(A,B,C) or %if(A&B&C,D,E) - condition.
+%if(A,B,C) or %if(A&B&C,D,E) - condition,
+%dir(n) - Name of the directory located on n levels above.
*/
#include <QStringList>
@@ -271,6 +272,82 @@ bool MetaDataFormatter::parseIf(QList<MetaDataFormatter::Node> *nodes, QString::
return true;
}
+bool MetaDataFormatter::parseDir(QList<MetaDataFormatter::Node> *nodes, QString::const_iterator *i, QString::const_iterator end)
+{
+ if((*i) + 1 == end || (*i) + 2 == end || (*i) + 3 == end)
+ return false;
+
+ if((**i) != QChar('d') || *((*i)+1) != QChar('i') || *((*i)+2) != QChar('r'))
+ return false;
+
+ (*i)+=3;
+
+ if((**i) != QChar('('))
+ return false;
+
+ Node node;
+ node.command = Node::DIR_FUNCTION;
+ QString var;
+
+ enum {
+ STARTING = 0,
+ READING_VAR,
+ FINISHED,
+
+ } state = STARTING;
+
+ while((*i) != end)
+ {
+ if((**i) == QChar('(') && state == STARTING)
+ {
+ state = READING_VAR;
+ (*i)++;
+ continue;
+ }
+
+ switch (state)
+ {
+ case STARTING:
+ {
+ break;
+ }
+ case READING_VAR:
+ {
+ if((**i) == QChar(')'))
+ {
+ state = FINISHED;
+ break;
+ }
+ var.append((**i));
+ break;
+ }
+ default:
+ break;
+ }
+
+ if(state == FINISHED)
+ break;
+
+ (*i)++;
+ }
+
+ if(state != FINISHED)
+ {
+ qWarning("MetaDataFormatter: syntax error");
+ return false;
+ }
+
+ Param param;
+ param.type = Param::NUMERIC;
+ bool ok = false;
+ param.number = var.toInt(&ok);
+ if(!ok)
+ param.number = 0;
+ node.params << param;
+ nodes->append(node);
+ return true;
+}
+
void MetaDataFormatter::parseText(QList<MetaDataFormatter::Node> *nodes, QString::const_iterator *i, QString::const_iterator end)
{
Node node;
@@ -346,6 +423,10 @@ QString MetaDataFormatter::evalute(const QList<Node> *nodes, const QMap<Qmmp::Me
out.append("1");
}
}
+ else if(node.command == Node::DIR_FUNCTION)
+ {
+ out.append(metaData->value(Qmmp::URL).section('/', -node.params[0].number - 2, -node.params[0].number - 2));
+ }
}
return out;
}
@@ -427,6 +508,8 @@ QString MetaDataFormatter::dumpNode(MetaDataFormatter::Node node) const
params.append(QString("FIELD:%1").arg(p.field));
else if(p.type == Param::TEXT)
params.append(QString("TEXT:%1").arg(p.text));
+ else if(p.type == Param::NUMERIC)
+ params.append(QString("NUMBER:%1").arg(p.number));
else if(p.type == Param::NODES)
{
QStringList nodeStrList;
@@ -455,6 +538,12 @@ QList<MetaDataFormatter::Node> MetaDataFormatter::compile(const QString &expr)
if(i == expr.constEnd())
continue;
+ if(parseDir(&nodes, &i, expr.constEnd()))
+ {
+ i++;
+ continue;
+ }
+
if(parseField(&nodes, &i, expr.constEnd()))
{
i++;
diff --git a/src/qmmpui/metadataformatter.h b/src/qmmpui/metadataformatter.h
index 967087e4f..e28af2826 100644
--- a/src/qmmpui/metadataformatter.h
+++ b/src/qmmpui/metadataformatter.h
@@ -1,5 +1,5 @@
/***************************************************************************
- * Copyright (C) 2015 by Ilya Kotov *
+ * Copyright (C) 2015-2017 by Ilya Kotov *
* forkotov02@hotmail.ru *
* *
* This program is free software; you can redistribute it and/or modify *
@@ -52,7 +52,8 @@ public:
* %y - year,
* %l - duration,
* %I - track index,
- * %if(A,B,C) or %if(A&B&C,D,E) - condition.
+ * %if(A,B,C) or %if(A&B&C,D,E) - condition,
+ * %dir(n) - Name of the directory located on \b n levels above.
*/
MetaDataFormatter(const QString &pattern = QString());
/*!
@@ -95,7 +96,8 @@ private:
PRINT_TEXT = 0,
IF_KEYWORD,
OR_OPERATOR,
- AND_OPERATOR
+ AND_OPERATOR,
+ DIR_FUNCTION
} command;
QList<Param> params;
@@ -106,6 +108,7 @@ private:
enum {
FIELD = 0,
TEXT,
+ NUMERIC,
NODES
} type;
@@ -120,11 +123,13 @@ private:
int field;
QString text;
+ int number;
QList<Node> children;
};
bool parseField(QList<Node> *nodes, QString::const_iterator *i, QString::const_iterator end);
bool parseIf(QList<Node> *nodes, QString::const_iterator *i, QString::const_iterator end);
+ bool parseDir(QList<Node> *nodes, QString::const_iterator *i, QString::const_iterator end);
void parseText(QList<Node> *nodes, QString::const_iterator *i, QString::const_iterator end);
void parseEscape(QList<Node> *nodes, QString::const_iterator *i, QString::const_iterator end);