diff options
author | Thierry Crozat | 2010-08-23 19:45:14 +0000 |
---|---|---|
committer | Thierry Crozat | 2010-08-23 19:45:14 +0000 |
commit | bc821136fdf2c82c1877c8ae0e607bcbe784dab1 (patch) | |
tree | 848141a4994e5bd13e8a7a9a304777e251927468 /common | |
parent | 45a87ffe3fb76ae4e75d97271c0567809bd088d0 (diff) | |
download | scummvm-rg350-bc821136fdf2c82c1877c8ae0e607bcbe784dab1.tar.gz scummvm-rg350-bc821136fdf2c82c1877c8ae0e607bcbe784dab1.tar.bz2 scummvm-rg350-bc821136fdf2c82c1877c8ae0e607bcbe784dab1.zip |
i18n: Add support for context in translations.
This change means there can now be different translations for the same
english string depending on the context. It is based on gettext msgctxt feature.
There is a new macro _c(msg, ctxt) that should be used instead of _(msg) in
the source code when we want to add a context to the message. For the
moment I have added contexts to only one message ("None") so that I could
test the changes. Context could be added also to get shorter translations when
GUI is in 1x mode.
I have also added back the fuzzy option to msmerge since it is useful when
adding contexts to populate the translations for the new contexts.
svn-id: r52308
Diffstat (limited to 'common')
-rw-r--r-- | common/translation.cpp | 63 | ||||
-rw-r--r-- | common/translation.h | 25 |
2 files changed, 80 insertions, 8 deletions
diff --git a/common/translation.cpp b/common/translation.cpp index 40a89c6497..063e7a1781 100644 --- a/common/translation.cpp +++ b/common/translation.cpp @@ -29,7 +29,7 @@ #undef ARRAYSIZE #endif -#define TRANSLATIONS_DAT_VER 1 +#define TRANSLATIONS_DAT_VER 2 #include "translation.h" @@ -150,6 +150,10 @@ void TranslationManager::setLanguage(const char *lang) { } const char *TranslationManager::getTranslation(const char *message) { + return getTranslation(message, NULL); +} + +const char *TranslationManager::getTranslation(const char *message, const char *context) { // if no language is set or message is empty, return msgid as is if (_currentTranslationMessages.empty() || *message == '\0') return message; @@ -160,13 +164,39 @@ const char *TranslationManager::getTranslation(const char *message) { while (rightIndex >= leftIndex) { const int midIndex = (leftIndex + rightIndex) / 2; - const PoMessageEntry * const m = &_currentTranslationMessages[midIndex]; - - const int compareResult = strcmp(message, _messageIds[m->msgid].c_str()); - - if (compareResult == 0) - return m->msgstr.c_str(); - else if (compareResult < 0) + const PoMessageEntry *const m = &_currentTranslationMessages[midIndex]; + + int compareResult = strcmp(message, _messageIds[m->msgid].c_str()); + + if (compareResult == 0) { + // Get the range of messages with the same ID (but different context) + leftIndex = rightIndex = midIndex; + while ( + leftIndex > 0 && + _currentTranslationMessages[leftIndex - 1].msgid == m->msgid + ) { + --leftIndex; + } + while ( + rightIndex < (int)_currentTranslationMessages.size() - 1 && + _currentTranslationMessages[rightIndex + 1].msgid == m->msgid + ) { + ++rightIndex; + } + // Find the context we want + if (context == NULL || *context == '\0' || leftIndex == rightIndex) + return _currentTranslationMessages[leftIndex].msgstr.c_str(); + // We could use again binary search, but there should be only a small number of contexts. + while (rightIndex > leftIndex) { + compareResult = strcmp(context, _currentTranslationMessages[rightIndex].msgctxt.c_str()); + if (compareResult == 0) + return _currentTranslationMessages[rightIndex].msgstr.c_str(); + else if (compareResult > 0) + break; + --rightIndex; + } + return _currentTranslationMessages[leftIndex].msgstr.c_str(); + } else if (compareResult < 0) rightIndex = midIndex - 1; else leftIndex = midIndex + 1; @@ -185,6 +215,10 @@ String TranslationManager::getTranslation(const String &message) { return getTranslation(message.c_str()); } +String TranslationManager::getTranslation(const String &message, const String &context) { + return getTranslation(message.c_str(), context.c_str()); +} + const TLangArray TranslationManager::getSupportedLanguageNames() const { TLangArray languages; @@ -314,6 +348,11 @@ void TranslationManager::loadLanguageDat(int index) { len = in.readUint16BE(); in.read(buf, len); _currentTranslationMessages[i].msgstr = String(buf, len); + len = in.readUint16BE(); + if (len > 0) { + in.read(buf, len); + _currentTranslationMessages[i].msgctxt = String(buf, len); + } } } @@ -373,6 +412,14 @@ String TranslationManager::getTranslation(const String &message) { return message; } +const char *TranslationManager::getTranslation(const char *message, const char *) { + return message; +} + +String TranslationManager::getTranslation(const String &message, const String &) { + return message; +} + const TLangArray TranslationManager::getSupportedLanguageNames() const { return TLangArray(); } diff --git a/common/translation.h b/common/translation.h index ccd35ce288..af33177559 100644 --- a/common/translation.h +++ b/common/translation.h @@ -50,6 +50,7 @@ typedef Array<TLanguage> TLangArray; struct PoMessageEntry { int msgid; + String msgctxt; String msgstr; }; @@ -114,6 +115,28 @@ public: * it returns the original untranslated message. */ String getTranslation(const String &message); + + /** + * Returns the translation into the current language of the parameter + * message. In case the message isn't found in the translation catalog, + * it returns the original untranslated message. + * + * If a translation is found for the given context it will return that + * translation, otherwise it will look for a translation for the same + * massage without a context or with a different context. + */ + const char *getTranslation(const char *message, const char *context); + + /** + * Returns the translation into the current language of the parameter + * message. In case the message isn't found in the translation catalog, + * it returns the original untranslated message. + * + * If a translation is found for the given context it will return that + * translation, otherwise it will look for a translation for the same + * massage without a context or with a different context. + */ + String getTranslation(const String &message, const String &context); /** * Returns a list of supported languages. @@ -163,8 +186,10 @@ private: #ifdef USE_TRANSLATION #define _(str) TransMan.getTranslation(str) +#define _c(str, context) TransMan.getTranslation(str, context) #else #define _(str) str +#define _c(str, context) str #endif #define _s(str) str |