aboutsummaryrefslogtreecommitdiff
path: root/src/plugins/Input/sid
Commit message (Collapse)AuthorAgeFilesLines
* updated Dutch translation (Heimen Stoffels)trialuser022020-03-291-15/+15
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@9326 90c681e8-e032-0410-971d-27865f9a5e38
* updated copyrighttrialuser022020-02-116-6/+6
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@9224 90c681e8-e032-0410-971d-27865f9a5e38
* sync remaining translationstrialuser022019-01-218-28/+28
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@8642 90c681e8-e032-0410-971d-27865f9a5e38
* updated Polish translation (mrerexx)trialuser022019-01-111-6/+6
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@8629 90c681e8-e032-0410-971d-27865f9a5e38
* using override keywordtrialuser022019-01-067-20/+20
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@8591 90c681e8-e032-0410-971d-27865f9a5e38
* fixed build with -Werror=zero-as-null-pointer-constanttrialuser022019-01-034-7/+7
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@8572 90c681e8-e032-0410-971d-27865f9a5e38
* updated .ts filestrialuser022018-11-1328-28/+28
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@8421 90c681e8-e032-0410-971d-27865f9a5e38
* updated .ts filestrialuser022018-09-1628-112/+112
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@8297 90c681e8-e032-0410-971d-27865f9a5e38
* removed Q_OBJECT from MetaDataModeltrialuser022018-09-142-3/+2
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@8289 90c681e8-e032-0410-971d-27865f9a5e38
* updated .ts filestrialuser022018-08-0528-112/+112
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@8242 90c681e8-e032-0410-971d-27865f9a5e38
* fixed cdaudio, gme, sid and wildmidi pluginstrialuser022018-08-042-2/+3
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@8228 90c681e8-e032-0410-971d-27865f9a5e38
* updated .ts filestrialuser022018-07-2228-168/+168
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@8216 90c681e8-e032-0410-971d-27865f9a5e38
* changed translation api againtrialuser022018-07-212-3/+8
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@8200 90c681e8-e032-0410-971d-27865f9a5e38
* changed translation apitrialuser022018-07-212-10/+1
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@8196 90c681e8-e032-0410-971d-27865f9a5e38
* feature to change application nametrialuser022018-07-011-2/+2
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@8077 90c681e8-e032-0410-971d-27865f9a5e38
* changed plugin path (cmake)trialuser022018-06-231-1/+1
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@8054 90c681e8-e032-0410-971d-27865f9a5e38
* changed plugin path (qmake)trialuser022018-06-231-1/+1
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@8053 90c681e8-e032-0410-971d-27865f9a5e38
* changed Qmmp::configDir() output: do not add slash at the end of pathtrialuser022018-06-112-2/+2
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@8019 90c681e8-e032-0410-971d-27865f9a5e38
* enabled sid plugintrialuser022018-05-305-31/+24
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@7978 90c681e8-e032-0410-971d-27865f9a5e38
* copy 1.2 branch to trunktrialuser022017-11-2531-188/+174
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@7772 90c681e8-e032-0410-971d-27865f9a5e38
* updated .ts filestrialuser022017-11-121-7/+9
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@7721 90c681e8-e032-0410-971d-27865f9a5e38
* added Finnish translation (Jiri Grönroos)trialuser022017-11-122-0/+89
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@7718 90c681e8-e032-0410-971d-27865f9a5e38
* updated Polish translation (Daniel Krawczyk)trialuser022017-11-121-1/+1
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@7717 90c681e8-e032-0410-971d-27865f9a5e38
* updated Chezh translation (Jaroslav Lichtblau)trialuser022017-11-121-2/+2
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@7716 90c681e8-e032-0410-971d-27865f9a5e38
* updated Hebrew translation (Genghis Khan)trialuser022017-11-121-1/+1
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@7715 90c681e8-e032-0410-971d-27865f9a5e38
* updated Brazilian Portuguese translation (Vítor Pereira Barros)trialuser022017-11-121-1/+1
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@7714 90c681e8-e032-0410-971d-27865f9a5e38
* updated Indonesian translation (Wantoyo)trialuser022017-11-121-2/+2
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@7713 90c681e8-e032-0410-971d-27865f9a5e38
* updated Galician translation (Delio Docampo Cordeiro)trialuser022017-11-121-15/+16
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@7712 90c681e8-e032-0410-971d-27865f9a5e38
* updated Chinese Simplified translation (Mingcong Bai)trialuser022017-11-121-1/+1
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@7711 90c681e8-e032-0410-971d-27865f9a5e38
* updated Spanish translation (Joel Barrios and Bohdan Shuba)trialuser022017-10-291-17/+17
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@7677 90c681e8-e032-0410-971d-27865f9a5e38
* updated Portuguese translation (Sérgio Marques)trialuser022017-10-291-1/+1
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@7676 90c681e8-e032-0410-971d-27865f9a5e38
* updated Greek translation (Dimitrios Glentadakis)trialuser022017-10-291-1/+1
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@7675 90c681e8-e032-0410-971d-27865f9a5e38
* sid: fixed memory leaktrialuser022017-10-272-17/+15
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@7652 90c681e8-e032-0410-971d-27865f9a5e38
* fixed memory leaks and other errorstrialuser022017-10-261-0/+1
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@7649 90c681e8-e032-0410-971d-27865f9a5e38
* added extra functions to AudioParameters classtrialuser022017-10-221-3/+2
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@7612 90c681e8-e032-0410-971d-27865f9a5e38
* changed contact informationtrialuser022017-10-0735-59/+59
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@7514 90c681e8-e032-0410-971d-27865f9a5e38
* cmake: removed CMP0003 policytrialuser022017-09-231-5/+0
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@7466 90c681e8-e032-0410-971d-27865f9a5e38
* reformat .pro filestrialuser022017-08-291-6/+5
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@7421 90c681e8-e032-0410-971d-27865f9a5e38
* cleaning qmake filestrialuser022017-08-291-8/+1
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@7419 90c681e8-e032-0410-971d-27865f9a5e38
* optimized qmake filestrialuser022017-02-111-4/+0
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@7030 90c681e8-e032-0410-971d-27865f9a5e38
* added Indonesian translation (Wantoyo)trialuser022017-01-032-0/+91
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@6932 90c681e8-e032-0410-971d-27865f9a5e38
* changed decoder apitrialuser022016-09-142-6/+6
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@6715 90c681e8-e032-0410-971d-27865f9a5e38
* updated Brazilian Portuguese translation (Vitor Pereira)trialuser022016-08-081-16/+16
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@6658 90c681e8-e032-0410-971d-27865f9a5e38
* updated .ts filestrialuser022016-08-0826-156/+156
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@6654 90c681e8-e032-0410-971d-27865f9a5e38
* removed function DecoderFactory::supportstrialuser022016-07-262-20/+1
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@6603 90c681e8-e032-0410-971d-27865f9a5e38
* updated .ts filestrialuser022016-06-2026-156/+156
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@6488 90c681e8-e032-0410-971d-27865f9a5e38
* added wildmidi-0.4.0 supporttrialuser022016-06-201-0/+8
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@6478 90c681e8-e032-0410-971d-27865f9a5e38
* updated .ts filestrialuser022016-06-1926-156/+156
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@6477 90c681e8-e032-0410-971d-27865f9a5e38
* decreased compiling timetrialuser022016-06-131-1/+4
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@6449 90c681e8-e032-0410-971d-27865f9a5e38
* cmake: cleanuptrialuser022016-06-031-1/+0
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@6427 90c681e8-e032-0410-971d-27865f9a5e38
lass="hl opt">() const { return m_pattern; } QString MetaDataFormatter::format(const PlayListTrack *item) const { return evalute(&m_nodes, item, item->trackIndex()); } QString MetaDataFormatter::format(const TrackInfo &info, int trackIndex) const { return evalute(&m_nodes, &info, trackIndex); } QString MetaDataFormatter::format(const TrackInfo *info, int trackIndex) const { return format(*info, trackIndex); } QString MetaDataFormatter::formatDuration(qint64 duration, bool hideZero, bool showMs) { if(duration <= 0) { if(hideZero) return QString(); else return showMs ? QLatin1String("0:00.000") : QLatin1String("0:00"); } QString out; qint64 durationInSeconds = duration / 1000; if(durationInSeconds >= 3600) out = QString("%1:%2").arg(durationInSeconds / 3600).arg(durationInSeconds % 3600 / 60, 2, 10, QChar('0')); else out = QString("%1").arg(durationInSeconds % 3600 / 60); out += QString(":%1").arg(durationInSeconds % 60, 2, 10, QChar('0')); if(showMs) out += QString(".%1").arg(duration % 1000, 3, 10, QChar('0')); return out; } bool MetaDataFormatter::parseField(QList<Node> *nodes, QString::const_iterator *i, QString::const_iterator end) { QString fieldName; int field = Qmmp::UNKNOWN; //try to find field with 2 symbols if((*i) + 1 != end) { fieldName.append((**i)); fieldName.append(*((*i)+1)); field = m_fieldNames.value(fieldName, Qmmp::UNKNOWN); } //try to find field with 1 symbol if(field == Qmmp::UNKNOWN) { fieldName.clear(); fieldName.append((**i)); field = m_fieldNames.value(fieldName, Qmmp::UNKNOWN); } if(field != Qmmp::UNKNOWN) { Node node; node.command = Node::PRINT_TEXT; Param param; param.type = Param::FIELD; param.field = field; node.params.append(param); nodes->append(node); (*i) += fieldName.size() - 1; return true; } return false; } bool MetaDataFormatter::parseProperty(QList<Node> *nodes, QString::const_iterator *i, QString::const_iterator end) { if((*i) + 1 == end || (*i) + 2 == end) return false; if((**i) != QChar('{')) return false; (*i)++; //skip '{' QString propertyName; while((*i) != end && (**i) != QChar('}')) { propertyName.append((**i)); (*i)++; } int field = m_propertyNames.value(propertyName, Qmmp::UNKNOWN); if(field != Qmmp::UNKNOWN) { Node node; node.command = Node::PRINT_TEXT; Param param; param.type = Param::PROPERTY; param.field = field; node.params.append(param); nodes->append(node); return true; } return false; } bool MetaDataFormatter::parseIf(QList<MetaDataFormatter::Node> *nodes, QString::const_iterator *i, QString::const_iterator end) { if((*i) + 1 == end || (*i) + 2 == end) return false; if((**i) != QChar('i') || *((*i)+1) != QChar('f')) return false; (*i)+=2; Node node; node.command = Node::IF_KEYWORD; int brackets_tracker = 0; QString var1, var2, var3; enum { STARTING = 0, READING_VAR1, READING_VAR2, READING_VAR3, FINISHED, } state = STARTING; bool escaped = false; while((*i) != end) { if((**i) == QChar('\\')) { (*i)++; escaped = true; continue; } if(escaped) //ignore escaped brackets { escaped = false; } else { if((**i) == QChar('(')) { brackets_tracker++; if(state == STARTING) { state = READING_VAR1; (*i)++; continue; } } else if((**i) == QChar(')')) brackets_tracker--; } switch (state) { case STARTING: { break; } case READING_VAR1: { if((**i) == QChar(',') && brackets_tracker == 1) { state = READING_VAR2; break; } var1.append((**i)); break; } case READING_VAR2: { if((**i) == QChar(',') && brackets_tracker == 1) { state = READING_VAR3; break; } var2.append((**i)); break; } case READING_VAR3: { if((**i) == QChar(')') && brackets_tracker == 0) { state = FINISHED; break; } var3.append((**i)); break; } default: break; } if(state == FINISHED) break; (*i)++; } if(state != FINISHED) { qWarning("MetaDataFormatter: syntax error"); return false; } Param param1, param2, param3; param1.type = Param::NODES, param2.type = Param::NODES, param3.type = Param::NODES; param1.children = compile(var1); param2.children = compile(var2); param3.children = compile(var3); node.params << param1 << param2 << param3; nodes->append(node); return true; } bool MetaDataFormatter::parseDir(QList<MetaDataFormatter::Node> *nodes, QString::const_iterator *i, QString::const_iterator end) { if((*i) + 1 == end || (*i) + 2 == end) return false; if((**i) != QChar('d') || *((*i)+1) != QChar('i') || *((*i)+2) != QChar('r')) return false; (*i)+=3; Node node; node.command = Node::DIR_FUNCTION; if((*i) == end || (**i) != QChar('(')) // %dir without params { (*i)--; nodes->append(node); return true; } 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; node.command = Node::PRINT_TEXT; Param param; param.type = Param::TEXT; node.params.append(param); forever { if((*i) == end || (**i) == QChar('%')) { (*i)--; break; } node.params[0].text.append(**i); (*i)++; } if(!node.params[0].text.isEmpty()) nodes->append(node); } void MetaDataFormatter::parseEscape(QList<MetaDataFormatter::Node> *nodes, QString::const_iterator *i, QString::const_iterator end) { if((*i) == end) return; Node node; node.command = Node::PRINT_TEXT; Param param; param.type = Param::TEXT; node.params.append(param); node.params[0].text.append(**i); nodes->append(node); } QString MetaDataFormatter::evalute(const QList<Node> *nodes, const TrackInfo *info, int trackIndex) const { QString out; for(int i = 0; i < nodes->count(); ++i) { Node node = nodes->at(i); if(node.command == Node::PRINT_TEXT) { Param p = node.params.first(); out.append(printParam(&p, info, trackIndex)); } else if(node.command == Node::IF_KEYWORD) { QString var1 = printParam(&node.params[0], info, trackIndex); if(var1.isEmpty() || var1 == "0") out.append(printParam(&node.params[2], info, trackIndex)); else out.append(printParam(&node.params[1], info, trackIndex)); } else if(node.command == Node::AND_OPERATOR) { QString var1 = printParam(&node.params[0], info, trackIndex); QString var2 = printParam(&node.params[1], info, trackIndex); if(!var1.isEmpty() && !var2.isEmpty()) out.append("1"); } else if(node.command == Node::OR_OPERATOR) { QString var1 = printParam(&node.params[0], info, trackIndex); if(!var1.isEmpty()) out.append("1"); else { QString var2 = printParam(&node.params[1], info, trackIndex); if(!var2.isEmpty()) out.append("1"); } } else if(node.command == Node::DIR_FUNCTION) { if(node.params.isEmpty()) out.append(info->path().mid(0, info->path().lastIndexOf('/'))); else out.append(info->path().section('/', -node.params[0].number - 2, -node.params[0].number - 2)); } } return out; } QString MetaDataFormatter::printParam(MetaDataFormatter::Param *p, const TrackInfo *info, int trackIndex) const { switch (p->type) { case Param::FIELD: return printField(p->field, info, trackIndex); break; case Param::PROPERTY: return printProperty(p->field, info); break; case Param::TEXT: return p->text; break; case Param::NODES: return evalute(&p->children, info, trackIndex); break; default: break; } return QString(); } QString MetaDataFormatter::printField(int field, const TrackInfo *info, int trackIndex) const { if(field >= Qmmp::TITLE && field <= Qmmp::DISCNUMBER) { if(field == Qmmp::TITLE) { QString title = info->value(Qmmp::TITLE); if(title.isEmpty()) //using file name if title is empty { title = info->path().section('/',-1); title = title.left(title.lastIndexOf('.')); } if(title.isEmpty()) //using full path if file name is empty title = info->path(); return title; } return info->value((Qmmp::MetaData) field); } else if(field == Param::PATH) { return info->path(); } else if(field == Param::TWO_DIGIT_TRACK) { return QString("%1").arg(info->value(Qmmp::TRACK),2,'0'); } else if(field == Param::DURATION) { return formatDuration(info->duration()); } else if(field == Param::FILE_NAME) { return info->path().section('/',-1); } else if(field == Param::TRACK_INDEX) { return QString::number(trackIndex + 1); } return QString(); } QString MetaDataFormatter::printProperty(int field, const TrackInfo *info) const { return info->value((Qmmp::TrackProperty) field); } QString MetaDataFormatter::dumpNode(MetaDataFormatter::Node node) const { QString str; QStringList params; if(node.command == Node::PRINT_TEXT) str += "PRINT_TEXT"; else if(node.command == Node::IF_KEYWORD) str += "IF_KEYWORD"; else if(node.command == Node::AND_OPERATOR) str += "AND_OPERATOR"; else if(node.command == Node::OR_OPERATOR) str += "OR_OPERATOR"; else if(node.command == Node::DIR_FUNCTION) str += "DIR_FUNCTION"; str += "("; for(const Param &p : qAsConst(node.params)) { if(p.type == Param::FIELD) params.append(QString("FIELD:%1").arg(p.field)); else if(p.type == Param::PROPERTY) params.append(QString("PROPERTY:%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; for(const Node &n : qAsConst(p.children)) { nodeStrList.append(dumpNode(n)); } params.append(QString("NODES:%1").arg(nodeStrList.join(","))); } } str.append(params.join(",")); str.append(")"); return str; } QList<MetaDataFormatter::Node> MetaDataFormatter::compile(const QString &expr) { QList <Node> nodes; QString::const_iterator i = expr.constBegin(); while (i != expr.constEnd()) { if((*i) == QChar('%')) { ++i; if(i == expr.constEnd()) continue; if(parseDir(&nodes, &i, expr.constEnd())) { ++i; continue; } if(parseField(&nodes, &i, expr.constEnd())) { ++i; continue; } if(parseProperty(&nodes, &i, expr.constEnd())) { ++i; continue; } if(parseIf(&nodes, &i, expr.constEnd())) { ++i; continue; } continue; } else if((*i) == QChar('&')) { ++i; Node node; node.command = Node::AND_OPERATOR; nodes.append(node); } else if((*i) == QChar('|')) { ++i; Node node; node.command = Node::OR_OPERATOR; nodes.append(node); } else if((*i) == QChar('\\')) { ++i; parseEscape(&nodes, &i, expr.constEnd()); ++i; } else { parseText(&nodes, &i, expr.constEnd()); ++i; } } //wrap operators for(int j = 0; j < nodes.count(); ++j) { if(nodes[j].command == Node::AND_OPERATOR || nodes[j].command == Node::OR_OPERATOR) { if(j == 0 || j == nodes.count() - 1) { nodes.clear(); qDebug("MetaDataFormatter: syntax error"); } Param p1; p1.type = Param::NODES; p1.children << nodes.takeAt(j+1); Param p2; p2.type = Param::NODES; p2.children << nodes.takeAt(j-1); nodes[j-1].params.append(p1); nodes[j-1].params.append(p2); j--; } } return nodes; }