diff options
-rw-r--r-- | common/translation.cpp | 58 | ||||
-rw-r--r-- | common/translation.h | 14 |
2 files changed, 65 insertions, 7 deletions
diff --git a/common/translation.cpp b/common/translation.cpp index 063e7a1781..1328ed62d2 100644 --- a/common/translation.cpp +++ b/common/translation.cpp @@ -32,6 +32,8 @@ #define TRANSLATIONS_DAT_VER 2 #include "translation.h" +#include "common/archive.h" +#include "common/config-manager.h" DECLARE_SINGLETON(Common::TranslationManager) @@ -258,9 +260,55 @@ const char *TranslationManager::getLangById(int id) { return ""; } +bool TranslationManager::openTranslationsFile(File& inFile) { + // First try to open it directly (i.e. using the SearchMan). + if (inFile.open("translations.dat")) + return true; + + // Then look in the Themepath if we can find the file. + if (ConfMan.hasKey("themepath")) + return openTranslationsFile(FSNode(ConfMan.get("themepath")), inFile); + + return false; +} + +bool TranslationManager::openTranslationsFile(const FSNode &node, File& inFile, int depth) { + if (!node.exists() || !node.isReadable() || !node.isDirectory()) + return false; + + // Check if we can find the file in this directory + // Since File::open(FSNode) makes all the needed tests, it is not really + // necessary to make them here. But it avoid printing warnings. + FSNode fileNode = node.getChild("translations.dat"); + if (fileNode.exists() && fileNode.isReadable() && !fileNode.isDirectory()) { + if (inFile.open(fileNode)) + return true; + } + + // Check if we exceeded the given recursion depth + if (depth - 1 == -1) + return false; + + // Otherwise look for it in sub-directories + FSList fileList; + if (!node.getChildren(fileList, FSNode::kListDirectoriesOnly)) + return false; + + for (FSList::iterator i = fileList.begin(); i != fileList.end(); ++i) { + if (openTranslationsFile(*i, inFile, depth == -1 ? - 1 : depth - 1)) + return true; + } + + // Not found in this directory or its sub-directories + return false; +} + void TranslationManager::loadTranslationsInfoDat() { File in; - in.open("translations.dat"); + if (!openTranslationsFile(in)) { + warning("You are missing the 'translations.dat' file. GUI translation will not be available"); + return; + } if (!checkHeader(in)) return; @@ -308,7 +356,8 @@ void TranslationManager::loadLanguageDat(int index) { } File in; - in.open("translations.dat"); + if (!openTranslationsFile(in)) + return; if (!checkHeader(in)) return; @@ -360,11 +409,6 @@ bool TranslationManager::checkHeader(File &in) { char buf[13]; int ver; - if (!in.isOpen()) { - warning("You are missing the 'translations.dat' file. GUI translation will not be available"); - return false; - } - in.read(buf, 12); buf[12] = '\0'; diff --git a/common/translation.h b/common/translation.h index af33177559..e1951c1330 100644 --- a/common/translation.h +++ b/common/translation.h @@ -28,6 +28,7 @@ #include "common/singleton.h" #include "common/str-array.h" #include "common/file.h" +#include "common/fs.h" namespace Common { @@ -153,6 +154,19 @@ public: private: #ifdef USE_TRANSLATION /** + * Find the translations.dat file. It looks first using the SearchMan and + * then if needed using the Themepath. If found it opens the given File + * to read the translations.dat file. + */ + bool openTranslationsFile(File&); + + /** + * Find the translations.dat file in the given directory node. + * If found it opens the given File to read the translations.dat file. + */ + bool openTranslationsFile(const FSNode &node, File&, int depth = -1); + + /** * Load the list of languages from the translations.dat file */ void loadTranslationsInfoDat(); |