From b6b71791ed0f3f05ec8b53ddb9fa9c8317d25e93 Mon Sep 17 00:00:00 2001 From: APTX Date: Sun, 26 Dec 2010 04:22:16 +0100 Subject: [PATCH] Introducing FileRenameDelegate --- anidbudpclient.pro | 9 +- anidbudpclient_global.h | 2 +- file.cpp | 33 +++- file.h | 7 + filecommand.h | 13 ++ filerenamedelegate.cpp | 175 ++++++++++++++++++++++ filerenamedelegate.h | 41 +++++ include/AniDBUdpClient/FileRenameDelegate | 1 + renameparser/functions.h | 5 +- renameparser/renameengine.cpp | 10 +- renameparser/renameengine.h | 11 +- 11 files changed, 298 insertions(+), 9 deletions(-) create mode 100644 filerenamedelegate.cpp create mode 100644 filerenamedelegate.h create mode 100644 include/AniDBUdpClient/FileRenameDelegate diff --git a/anidbudpclient.pro b/anidbudpclient.pro index 3985504..cb49877 100644 --- a/anidbudpclient.pro +++ b/anidbudpclient.pro @@ -32,7 +32,8 @@ SOURCES += client.cpp \ hashproducer.cpp \ hashconsumer.cpp \ clientsentcommandsmodel.cpp \ - clientqueuedcommandsmodel.cpp + clientqueuedcommandsmodel.cpp \ + filerenamedelegate.cpp HEADERS += client.h \ anidbudpclient_global.h \ @@ -51,7 +52,8 @@ HEADERS += client.h \ hashconsumer.h \ circularbuffer.h \ clientsentcommandsmodel.h \ - clientqueuedcommandsmodel.h + clientqueuedcommandsmodel.h \ + filerenamedelegate.h CONV_HEADERS += include/AniDBUdpClient/Client \ include/AniDBUdpClient/AbstractCommand \ @@ -64,7 +66,8 @@ CONV_HEADERS += include/AniDBUdpClient/Client \ include/AniDBUdpClient/File \ include/AniDBUdpClient/Hash \ include/AniDBUdpClient/ClientSentCommandsModel \ - include/AniDBUdpClient/ClientQueuedCommandsModel + include/AniDBUdpClient/ClientQueuedCommandsModel \ + include/AniDBUdpClient/FileRenameDelegate # RenameParser Files diff --git a/anidbudpclient_global.h b/anidbudpclient_global.h index 224d266..1a1446e 100644 --- a/anidbudpclient_global.h +++ b/anidbudpclient_global.h @@ -315,7 +315,7 @@ namespace AniDBUdpClient Q_FLAGS(FileAnimeFlag::FileAnimeFlag); Q_DECLARE_FLAGS(FileAnimeFlags, FileAnimeFlag::FileAnimeFlag); Q_DECLARE_OPERATORS_FOR_FLAGS(FileAnimeFlags); - typedef FileAnimeFlag::FileAnimeFlag FileAMask; + typedef FileAnimeFlags FileAMask; namespace AnimeFlag { static const qint64 CategoryWeightList = Q_INT64_C(0x0000000000000001); diff --git a/file.cpp b/file.cpp index 9f810e1..19dbc4e 100644 --- a/file.cpp +++ b/file.cpp @@ -3,6 +3,7 @@ #include #include "client.h" #include "hash.h" +#include "filerenamedelegate.h" #include @@ -91,6 +92,16 @@ File::ActionState File::markingState() const return m_markingState; } +void File::setRenameDelegate(FileRenameDelegate *renameHelper) +{ + m_renameDelegate = renameHelper; +} + +FileRenameDelegate *File::renameDelegate() const +{ + return m_renameDelegate; +} + void File::hash() { @@ -169,14 +180,22 @@ qDebug() << "finishRenaming"; if (name.isEmpty()) name = fileReply->value(FileAnimeFlag::EnglishName).toString(); - QString newFileName = tr("%1 - %2 - %3 - [%4](%5).%6") + QString newFileName, newFilePath; + + if (m_renameDelegate) + { + m_renameDelegate->rename(fileReply, newFileName, newFilePath); + } + else + { + newFileName = tr("%1 - %2 - %3 - [%4](%5).%6") .arg(name) .arg(fileReply->value(FileAnimeFlag::EpNo).toString()) .arg(fileReply->value(FileAnimeFlag::EpName).toString()) .arg(fileReply->value(FileAnimeFlag::GroupShortName).toString()) .arg(fileReply->value(FileFlag::Crc32).toString()) .arg(fileReply->value(FileFlag::FileType).toString()); - + } newFileName.replace('"', "'"); newFileName.replace(QRegExp("[\\/]"), "-"); newFileName.replace(QRegExp("[\\/:*?\"<>|]"), ""); @@ -326,6 +345,14 @@ qDebug() << "startRenaming"; | FileAnimeFlag::EpNo | FileAnimeFlag::EpName | FileAnimeFlag::GroupShortName); + + + if (m_renameDelegate) + { + fileCommand.setAmask(m_renameDelegate->requiredAMask()); + fileCommand.setFmask(m_renameDelegate->requiredFMask()); + } + fileReply = Client::instance()->send(fileCommand); connect(fileReply, SIGNAL(replyReady(bool)), this, SLOT(finishRenaming(bool))); @@ -385,6 +412,8 @@ void File::init() m_hashingState = m_renamingState = m_addingState = m_markingState = NotStarted; notWorking = true; + m_renameDelegate = 0; + connect(this, SIGNAL(statusUpdate(AniDBUdpClient::File::Action,AniDBUdpClient::File::ActionState)), this, SLOT(workOnFinished(AniDBUdpClient::File::Action,AniDBUdpClient::File::ActionState))); } diff --git a/file.h b/file.h index 6428c57..8422ffc 100644 --- a/file.h +++ b/file.h @@ -16,6 +16,8 @@ class FileCommand; class MyListCommand; class HashResult; +class FileRenameDelegate; + class ANIDBUDPCLIENTSHARED_EXPORT File : public QObject { Q_OBJECT @@ -70,6 +72,9 @@ public: ActionState addingState() const; ActionState markingState() const; + void setRenameDelegate(FileRenameDelegate *renameDelegate); + FileRenameDelegate *renameDelegate() const; + public slots: void hash(); bool rename(); @@ -121,6 +126,8 @@ private: MyListAddReply *addReply; MyListAddReply *markReply; + FileRenameDelegate *m_renameDelegate; + }; } // namespace AniDBUdpClient diff --git a/filecommand.h b/filecommand.h index b3e80f4..aa0496d 100644 --- a/filecommand.h +++ b/filecommand.h @@ -90,6 +90,19 @@ class ANIDBUDPCLIENTSHARED_EXPORT FileReply : public AbstractReply Q_PROPERTY(int fid READ fid); public: + + enum State + { + CrcOk = 0x00000001, + CrcErr = 0x00000002, + IsV2 = 0x00000004, + IsV3 = 0x00000008, + IsV4 = 0x00000010, + IsV5 = 0x00000020, + Uncensored = 0x00000040, + Censored = 0x00000080, + }; + int fid() const; QVariant value(FileFlags f) const; diff --git a/filerenamedelegate.cpp b/filerenamedelegate.cpp new file mode 100644 index 0000000..9a54f87 --- /dev/null +++ b/filerenamedelegate.cpp @@ -0,0 +1,175 @@ +#include "filerenamedelegate.h" + +#include "filecommand.h" + +namespace AniDBUdpClient { + +FileRenameDelegate::FileRenameDelegate(RenameParser::RenameEngine *renameEngine, QObject *parent) : + QObject(parent), m_renameEngine(0), fMask(FileFlags()), aMask(FileAnimeFlags()) +{ + setRenameEngine(renameEngine); +} + +FileRenameDelegate::~FileRenameDelegate() +{ + if (m_renameEngine) + delete m_renameEngine; +} + +RenameParser::RenameEngine *FileRenameDelegate::renameEngine() const +{ + return m_renameEngine; +} + +void FileRenameDelegate::setRenameEngine(RenameParser::RenameEngine *renameEngine) +{ + if (m_renameEngine) + { + m_renameEngine->disconnect(this); + m_renameEngine->deleteLater(); + } + + m_renameEngine = renameEngine; + if (!m_renameEngine) + return; + + connect(m_renameEngine, SIGNAL(renameStringChanged()), this, SLOT(updateMasks())); +} + + +FileAMask FileRenameDelegate::requiredAMask() const +{ + return aMask; +} + +FMask FileRenameDelegate::requiredFMask() const +{ + return fMask; +} + +void FileRenameDelegate::rename(const AniDBUdpClient::FileReply *reply, QString &fileName, QString &filePath) +{ + if (!m_renameEngine || !reply) + return; + + RenameParser::Environment env; + + env["ATr"] = reply->value(FileAnimeFlag::RomajiName).toString(); + env["ATe"] = reply->value(FileAnimeFlag::EnglishName).toString(); + env["ATk"] = reply->value(FileAnimeFlag::KanjiName).toString(); + + env["ETr"] = reply->value(FileAnimeFlag::EpRomajiName).toString(); + env["ETe"] = reply->value(FileAnimeFlag::EpName).toString(); + env["ETk"] = reply->value(FileAnimeFlag::EpKanjiName).toString(); + + env["GTs"] = reply->value(FileAnimeFlag::GroupName).toString(); + env["GTl"] = reply->value(FileAnimeFlag::GroupShortName).toString(); + + env["EpNo"] = reply->value( FileAnimeFlag::EpNo).toString(); + env["EpHiNo"] = reply->value(FileAnimeFlag::AnimeTotalEpisodes).toString(); + env["EpCount"] = reply->value(FileAnimeFlag::HighestEpisodeNumber).toString(); + + QString airDate = reply->value(FileFlag::AiredDate).toString(); + if (!airDate.contains('-')) + { + env["AYearBegin"] = airDate; + env["AYearEnd"] = ""; + } + else + { + QStringList years = airDate.split('-'); + env["AYearBegin"] = years[0].trimmed(); + env["AYearEnd"] = years[1].trimmed(); + } + + + env["Type"] = reply->value(FileFlag::FileType).toString(); + env["Depr"] = reply->value(FileFlag::IsDeprecated).toInt() ? "1" : ""; + + const int state = reply->value(FileFlag::State).toInt(); + + env["Cen"] = state & FileReply::Censored ? "1" : "0"; + + int version = 1; + if (state & FileReply::IsV2) + version = 2; + if (state & FileReply::IsV3) + version = 3; + if (state & FileReply::IsV4) + version = 4; + if (state & FileReply::IsV5) + version = 5; + + env["Ver"] = QString::number(version); + env["Source"] = reply->value(FileFlag::Source).toString(); + env["Quality"] = reply->value(FileFlag::Quality).toString(); + env["FCrc"] = reply->value(FileFlag::Crc32).toString(); + env["FVideoRes"] = reply->value(FileFlag::VideoResolution).toString(); + env["FALng"] = reply->value(FileFlag::DubLanguage).toString(); + env["FSLng"] = reply->value(FileFlag::SubLanguage).toString(); + + m_renameEngine->evaluate(env); + + fileName = env.value("FileName", ""); + filePath = env.value("FilePath", ""); +} + +void FileRenameDelegate::updateMasks() +{ + static bool init = true; + static QMap fMaskVars; + static QMap aMaskVars; + + if (init) + { + fMaskVars["Type"] = FileFlag::FileType; + fMaskVars["Depr"] = FileFlag::IsDeprecated; + fMaskVars["Cen"] = FileFlag::State; + fMaskVars["Ver"] = FileFlag::State; + fMaskVars["Source"] = FileFlag::Source; + fMaskVars["Quality"] = FileFlag::Quality; + fMaskVars["AYearBegin"] = FileFlag::AiredDate; + fMaskVars["AYearEnd"] = FileFlag::AiredDate; + fMaskVars["FCrc"] = FileFlag::Crc32; + fMaskVars["FVideoRes"] = FileFlag::VideoResolution; + fMaskVars["FALng"] = FileFlag::DubLanguage; + fMaskVars["FSLng"] = FileFlag::SubLanguage; +// Not implemented in FileCommand. +// fMaskVars["Watched"] = FileFlag::; + + aMaskVars["ATr"] = FileAnimeFlag::RomajiName; + aMaskVars["ATe"] = FileAnimeFlag::EnglishName; + aMaskVars["ATk"] = FileAnimeFlag::KanjiName; + + aMaskVars["ETr"] = FileAnimeFlag::EpRomajiName; + aMaskVars["ETe"] = FileAnimeFlag::EpName; + aMaskVars["ETk"] = FileAnimeFlag::EpKanjiName; + + aMaskVars["GTs"] = FileAnimeFlag::GroupName; + aMaskVars["GTl"] = FileAnimeFlag::GroupShortName; + + aMaskVars["EpNo"] = FileAnimeFlag::EpNo; + aMaskVars["EpHiNo"] = FileAnimeFlag::AnimeTotalEpisodes; + aMaskVars["EpCount"] = FileAnimeFlag::HighestEpisodeNumber; + + init = false; + } + + if (!m_renameEngine) + return; + + QStringList usedVars = m_renameEngine->usedVariables(); + + fMask = 0; + aMask = 0; + + foreach (const QString &var, usedVars) + { + if (fMaskVars.contains(var)) + fMask |= fMaskVars[var]; + if (aMaskVars.contains(var)) + aMask |= aMaskVars[var]; + } +} + +} // namespace AniDBUdpClient diff --git a/filerenamedelegate.h b/filerenamedelegate.h new file mode 100644 index 0000000..6728ad9 --- /dev/null +++ b/filerenamedelegate.h @@ -0,0 +1,41 @@ +#ifndef FILERENAMEDELEGATE_H +#define FILERENAMEDELEGATE_H + +#include "anidbudpclient_global.h" +#include "renameparser/renameengine.h" + +#include +#include + +namespace AniDBUdpClient { + +class FileReply; + +class ANIDBUDPCLIENTSHARED_EXPORT FileRenameDelegate : public QObject +{ + Q_OBJECT +public: + explicit FileRenameDelegate(RenameParser::RenameEngine *renameEngine = 0, QObject *parent = 0); + ~FileRenameDelegate(); + + RenameParser::RenameEngine *renameEngine() const; + void setRenameEngine(RenameParser::RenameEngine *renameEngine); + + FileAMask requiredAMask() const; + FMask requiredFMask() const; + + void rename(const FileReply *reply, QString &fileName, QString &filePath); + +private slots: + void updateMasks(); + +private: + RenameParser::RenameEngine *m_renameEngine; + + FMask fMask; + FileAMask aMask; +}; + +} // namespace AniDBUdpClient + +#endif // FILERENAMEDELEGATE_H diff --git a/include/AniDBUdpClient/FileRenameDelegate b/include/AniDBUdpClient/FileRenameDelegate new file mode 100644 index 0000000..f12e405 --- /dev/null +++ b/include/AniDBUdpClient/FileRenameDelegate @@ -0,0 +1 @@ +#include "../../filerenamedelegate.h" \ No newline at end of file diff --git a/renameparser/functions.h b/renameparser/functions.h index 664562a..7addc02 100644 --- a/renameparser/functions.h +++ b/renameparser/functions.h @@ -8,7 +8,10 @@ namespace RenameParser { namespace RenameFunctions { - QString _max(const QStringList &args); +#ifdef max +#undef max +#endif + QString max(const QStringList &args); QString len(const QStringList &args); QString pad(const QStringList &args); QString repl(const QStringList &args); diff --git a/renameparser/renameengine.cpp b/renameparser/renameengine.cpp index cbbe6ec..af46438 100644 --- a/renameparser/renameengine.cpp +++ b/renameparser/renameengine.cpp @@ -26,6 +26,8 @@ RenameEngine::ParserType RenameEngine::currentParserType() const void RenameEngine::setCurrentParserType(ParserType parserType) { + if (m_parserType == parserType) + return; m_parserType = parserType; delete parser; parser = createParser(parserType); @@ -42,7 +44,8 @@ bool RenameEngine::parse(const QString &string) #ifdef PARSER_DEBUG qDebug() << "-----------------------------------------------------------------"; #endif -return b; + emit renameStringChanged(); + return b; } QString RenameEngine::evaluate(Environment &env) @@ -65,6 +68,11 @@ int RenameEngine::column() const return parser->column(); } +QStringList RenameEngine::usedVariables() const +{ + return parser->usedVariables(); +} + AbstractParser *RenameEngine::createParser(ParserType type) const { switch (type) diff --git a/renameparser/renameengine.h b/renameparser/renameengine.h index 1356033..34128ad 100644 --- a/renameparser/renameengine.h +++ b/renameparser/renameengine.h @@ -12,8 +12,10 @@ namespace RenameParser { typedef QString (*RenameFunction)(const QStringList &args); -class ANIDBUDPCLIENTSHARED_EXPORT RenameEngine +class ANIDBUDPCLIENTSHARED_EXPORT RenameEngine : public QObject { + Q_OBJECT + public: enum ParserType { AniAdd, @@ -36,6 +38,11 @@ public: int line() const; int column() const; + QStringList usedVariables() const; + +signals: + void renameStringChanged(); + private: AbstractParser *createParser(ParserType type) const; @@ -58,4 +65,6 @@ private: } // namespace +Q_DECLARE_METATYPE(RenameParser::RenameEngine::ParserType) + #endif // RENAMEENGINE_H -- 2.52.0