summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrei Karas <akaras@inbox.ru>2012-02-03 15:53:55 +0300
committerAndrei Karas <akaras@inbox.ru>2012-02-05 22:53:59 +0300
commitbf435a79408d89072f5872ab98449949a8a077b0 (patch)
treee50bddcd239de2756780691cabf8779dd5efcc12
parent42990fcd0a9f662eea267097e88b68b9c30da457 (diff)
downloadplus-bf435a79408d89072f5872ab98449949a8a077b0.tar.gz
plus-bf435a79408d89072f5872ab98449949a8a077b0.tar.bz2
plus-bf435a79408d89072f5872ab98449949a8a077b0.tar.xz
plus-bf435a79408d89072f5872ab98449949a8a077b0.zip
Add own translation system.
-rw-r--r--src/CMakeLists.txt6
-rw-r--r--src/Makefile.am6
-rw-r--r--src/client.cpp5
-rw-r--r--src/game.cpp2
-rw-r--r--src/utils/langs.h3
-rw-r--r--src/utils/stringutils.cpp7
-rw-r--r--src/utils/stringutils.h2
-rw-r--r--src/utils/translation/podict.cpp55
-rw-r--r--src/utils/translation/podict.h59
-rw-r--r--src/utils/translation/poparser.cpp221
-rw-r--r--src/utils/translation/poparser.h78
-rw-r--r--src/utils/translation/translationmanager.cpp72
-rw-r--r--src/utils/translation/translationmanager.h39
-rw-r--r--src/utils/xml.cpp12
-rw-r--r--src/utils/xml.h6
15 files changed, 573 insertions, 0 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 96c1eac67..3289aed66 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -443,6 +443,12 @@ SET(SRCS
resources/spritedef.cpp
resources/wallpaper.cpp
resources/wallpaper.h
+ utils/translation/podict.cpp
+ utils/translation/podict.h
+ utils/translation/poparser.cpp
+ utils/translation/poparser.h
+ utils/translation/translationmanager.cpp
+ utils/translation/translationmanager.h
utils/base64.cpp
utils/base64.h
utils/checkutils.cpp
diff --git a/src/Makefile.am b/src/Makefile.am
index e9af09463..204c21bfc 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -448,6 +448,12 @@ manaplus_SOURCES += gui/widgets/avatarlistbox.cpp \
resources/spritedef.cpp \
resources/wallpaper.cpp \
resources/wallpaper.h \
+ utils/translation/podict.cpp \
+ utils/translation/podict.h \
+ utils/translation/poparser.cpp \
+ utils/translation/poparser.h \
+ utils/translation/translationmanager.cpp \
+ utils/translation/translationmanager.h \
utils/base64.cpp \
utils/base64.h \
utils/checkutils.cpp \
diff --git a/src/client.cpp b/src/client.cpp
index c21194834..cb65c3b60 100644
--- a/src/client.cpp
+++ b/src/client.cpp
@@ -101,6 +101,8 @@
#include "utils/paths.h"
#include "utils/stringutils.h"
+#include "utils/translation/translationmanager.h"
+
#include "test/testlauncher.h"
#include "test/testmain.h"
@@ -458,6 +460,8 @@ void Client::gameInit()
//resman->selectSkin();
+ TranslationManager::loadCurrentLang();
+
std::string iconFile = branding.getValue("appIcon", "icons/manaplus");
#ifdef WIN32
iconFile += ".ico";
@@ -1050,6 +1054,7 @@ int Client::gameExec()
logger->log1("State: CONNECT SERVER");
mCurrentDialog = new ConnectionDialog(
_("Connecting to server"), STATE_SWITCH_SERVER);
+ TranslationManager::loadCurrentLang();
break;
case STATE_LOGIN:
diff --git a/src/game.cpp b/src/game.cpp
index 0d5c1113e..cd54f9c98 100644
--- a/src/game.cpp
+++ b/src/game.cpp
@@ -104,6 +104,8 @@
#include "utils/gettext.h"
#include "utils/mkdir.h"
+#include "utils/translation/translationmanager.h"
+
#include <guichan/exception.hpp>
#include <guichan/focushandler.hpp>
diff --git a/src/utils/langs.h b/src/utils/langs.h
index c3f2f1398..3b9f49f71 100644
--- a/src/utils/langs.h
+++ b/src/utils/langs.h
@@ -29,6 +29,9 @@
#include <set>
#include <vector>
+typedef std::vector<std::string> LangVect;
+typedef LangVect::const_iterator LangIter;
+
std::vector<std::string> getLang();
std::string getLangSimple();
diff --git a/src/utils/stringutils.cpp b/src/utils/stringutils.cpp
index 16542526f..becb2124d 100644
--- a/src/utils/stringutils.cpp
+++ b/src/utils/stringutils.cpp
@@ -592,3 +592,10 @@ std::string &removeProtocol(std::string &url)
url = url.substr(i + 3);
return url;
}
+
+bool strStartWith(std::string str1, std::string str2)
+{
+ if (str1.size() < str2.size())
+ return false;
+ return str1.substr(0, str2.size()) == str2;
+}
diff --git a/src/utils/stringutils.h b/src/utils/stringutils.h
index 7b512b081..398737179 100644
--- a/src/utils/stringutils.h
+++ b/src/utils/stringutils.h
@@ -204,4 +204,6 @@ bool findCutFirst(std::string &str1, std::string str2);
std::string &removeProtocol(std::string &url);
+bool strStartWith(std::string str, std::string start);
+
#endif // UTILS_STRINGUTILS_H
diff --git a/src/utils/translation/podict.cpp b/src/utils/translation/podict.cpp
new file mode 100644
index 000000000..0be0b279f
--- /dev/null
+++ b/src/utils/translation/podict.cpp
@@ -0,0 +1,55 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2012 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "utils/translation/podict.h"
+
+#include <string.h>
+
+#include "localconsts.h"
+#include "logger.h"
+
+#include "debug.h"
+
+std::string empty;
+
+PoDict *translator = nullptr;
+
+PoDict::PoDict(std::string lang) :
+ mLang(lang)
+{
+}
+
+PoDict::~PoDict()
+{
+}
+
+const std::string PoDict::getStr(std::string &str)
+{
+ if (mPoLines.find(str) == mPoLines.end())
+ return str;
+ return mPoLines[str];
+}
+
+const char *PoDict::getChar(const char *str)
+{
+ if (mPoLines.find(str) == mPoLines.end())
+ return str;
+ return mPoLines[str].c_str();
+}
diff --git a/src/utils/translation/podict.h b/src/utils/translation/podict.h
new file mode 100644
index 000000000..0b7dd726c
--- /dev/null
+++ b/src/utils/translation/podict.h
@@ -0,0 +1,59 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2012 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef UTILS_TRANSLATION_PODICT_H
+#define UTILS_TRANSLATION_PODICT_H
+
+#include <string>
+#include <map>
+
+typedef std::map <std::string, std::string> PoMap;
+
+class PoDict
+{
+ public:
+ PoDict(std::string lang);
+
+ ~PoDict();
+
+ const std::string getStr(std::string &str);
+
+ const char *getChar(const char *str);
+
+ protected:
+ friend class PoParser;
+
+ PoMap *getMap()
+ { return &mPoLines; }
+
+ void set(std::string key, std::string value)
+ { mPoLines[key] = value; }
+
+ void setLang(std::string lang)
+ { mLang = lang; }
+
+ private:
+ PoMap mPoLines;
+ std::string mLang;
+};
+
+extern PoDict *translator;
+
+#endif // UTILS_TRANSLATION_PODICT_H
diff --git a/src/utils/translation/poparser.cpp b/src/utils/translation/poparser.cpp
new file mode 100644
index 000000000..24d2ee4d4
--- /dev/null
+++ b/src/utils/translation/poparser.cpp
@@ -0,0 +1,221 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2012 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "utils/translation/poparser.h"
+
+#include "resources/resourcemanager.h"
+
+#include "utils/stringutils.h"
+
+#include "localconsts.h"
+#include "logger.h"
+
+#include <string.h>
+#include <stdlib.h>
+
+#include "debug.h"
+
+PoParser::PoParser() :
+ mDict(nullptr),
+ mReadingId(false),
+ mReadingStr(false)
+{
+}
+
+void PoParser::openFile()
+{
+ ResourceManager *resman = ResourceManager::getInstance();
+ int size;
+ char *buf = static_cast<char*>(resman->loadFile(getFileName(mLang), size));
+
+ mFile.str(std::string(buf, size));
+ free(buf);
+}
+
+PoDict *PoParser::load(std::string lang)
+{
+ setLang(lang);
+ mDict = getDict();
+
+ openFile();
+
+ mMsgId = "";
+ mMsgStr = "";
+
+ // cycle by msgid+msgstr
+ while (readLine())
+ {
+ // reading msgid
+ while (readMsgId())
+ {
+ if (!readLine())
+ break;
+ }
+
+ if (!mMsgId.empty())
+ {
+ // if we got msgid then reading msgstr
+ while (readMsgStr())
+ {
+ if (!readLine())
+ break;
+ }
+ }
+
+ if (!mMsgId.empty() && !mMsgStr.empty())
+ {
+// logger->log("add key: " + mMsgId);
+// logger->log("add value: " + mMsgStr);
+
+ // store key and value
+ mDict->set(mMsgId, mMsgStr);
+ }
+
+ mMsgId = "";
+ mMsgStr = "";
+ }
+
+ return mDict;
+}
+
+bool PoParser::readLine()
+{
+ char line[1001];
+ if (!mFile.getline(line, 1000))
+ return false;
+ mLine = line;
+ return true;
+}
+
+bool PoParser::readMsgId()
+{
+ // if we reading msgstr then stop here
+ if (mReadingStr)
+ return false;
+
+ const std::string msgId1 = "msgid \"";
+
+ // check if in reading process
+ if (mReadingId)
+ {
+ // if we get empty line in file then stop reading
+ if (mLine.empty())
+ {
+ mReadingId = false;
+ return false;
+ }
+ else if (checkLine())
+ {
+ // reading text from: "text"
+ mMsgId += mLine.substr(1, mLine.size() - 2);
+ mLine = "";
+ return true;
+ }
+ // stop reading in other case
+ mReadingId = false;
+ return false;
+ }
+ else
+ {
+ // check line start from msgid "
+ if (strStartWith(mLine, msgId1))
+ {
+ mReadingId = true;
+ // reading text from: msgid "text"
+ mMsgId += mLine.substr(msgId1.size(),
+ mLine.size() - 1 - msgId1.size());
+ mLine = "";
+ return true;
+ }
+ // stop reading if we dont read msgid before
+ return mMsgId.empty();
+ }
+}
+
+bool PoParser::readMsgStr()
+{
+ const std::string msgStr1 = "msgstr \"";
+
+ // check if in reading process
+ if (mReadingStr)
+ {
+ // if we get empty line in file then stop reading
+ if (mLine.empty())
+ {
+ mReadingStr = false;
+ return false;
+ }
+ if (checkLine())
+ {
+ // reading text from: "text"
+ mMsgStr += mLine.substr(1, mLine.size() - 2);
+ mLine = "";
+ return true;
+ }
+ // stop reading in other case
+ mReadingStr = false;
+ }
+ else
+ {
+ // check line start from msgstr "
+ if (strStartWith(mLine, msgStr1))
+ {
+ mReadingStr = true;
+ // reading text from: msgid "text"
+ mMsgStr += mLine.substr(msgStr1.size(),
+ mLine.size() - 1 - msgStr1.size());
+ mLine = "";
+ return true;
+ }
+ }
+
+ // stop reading in other case
+ return false;
+}
+
+bool PoParser::checkLine()
+{
+ // check is line in format: "text"
+ return mLine.size() > 2 && mLine[0] == '\"'
+ && mLine[mLine.size() - 1] == '\"';
+}
+
+PoDict *PoParser::getEmptyDict()
+{
+ return new PoDict("");
+}
+
+bool PoParser::checkLang(std::string lang) const
+{
+ // check is po file exists
+ ResourceManager *resman = ResourceManager::getInstance();
+ return resman->exists(getFileName(lang));
+}
+
+std::string PoParser::getFileName(std::string lang) const
+{
+ // get po file name from lang name
+ return strprintf("translations/%s.po", lang.c_str());
+}
+
+PoDict *PoParser::getDict()
+{
+ return new PoDict(mLang);
+}
diff --git a/src/utils/translation/poparser.h b/src/utils/translation/poparser.h
new file mode 100644
index 000000000..799cd2fe7
--- /dev/null
+++ b/src/utils/translation/poparser.h
@@ -0,0 +1,78 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2012 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef UTILS_TRANSLATION_POPARSER_H
+#define UTILS_TRANSLATION_POPARSER_H
+
+#include "utils/translation/podict.h"
+
+#include <sstream>
+#include <string>
+
+class PoParser
+{
+ public:
+ PoParser();
+
+ PoDict *load(std::string fileName);
+
+ bool checkLang(std::string lang) const;
+
+ static PoDict *getEmptyDict();
+
+ private:
+ void setLang(std::string lang)
+ { mLang = lang; }
+
+ void openFile();
+
+ bool readLine();
+
+ bool readMsgId();
+
+ bool readMsgStr();
+
+ bool checkLine();
+
+ std::string getFileName(std::string lang) const;
+
+ PoDict *getDict();
+
+ // current lang
+ std::string mLang;
+
+ // po file object
+ std::istringstream mFile;
+
+ // current line from po file
+ std::string mLine;
+
+ std::string mMsgId;
+
+ std::string mMsgStr;
+
+ PoDict *mDict;
+
+ bool mReadingId;
+
+ bool mReadingStr;
+};
+
+#endif // UTILS_TRANSLATION_POPARSER_H
diff --git a/src/utils/translation/translationmanager.cpp b/src/utils/translation/translationmanager.cpp
new file mode 100644
index 000000000..b4ae0d949
--- /dev/null
+++ b/src/utils/translation/translationmanager.cpp
@@ -0,0 +1,72 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2012 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "utils/translation/translationmanager.h"
+
+#include "utils/langs.h"
+
+#include "utils/translation/podict.h"
+#include "utils/translation/poparser.h"
+
+#include <string.h>
+
+#include "localconsts.h"
+#include "logger.h"
+
+#include "debug.h"
+
+void TranslationManager::init()
+{
+ if (translator)
+ delete translator;
+ translator = PoParser::getEmptyDict();
+}
+
+void TranslationManager::loadCurrentLang()
+{
+ if (translator)
+ delete translator;
+ translator = loadLang(getLang());
+}
+
+PoDict *TranslationManager::loadLang(LangVect lang)
+{
+ std::string name = "";
+ PoParser parser;
+
+ LangIter it = lang.begin();
+ LangIter it_end = lang.end();
+
+ for (; it != it_end; ++ it)
+ {
+ if (*it == "C")
+ continue;
+
+ if (parser.checkLang(*it))
+ {
+ name = *it;
+ break;
+ }
+ }
+ if (!name.empty())
+ return parser.load(name);
+ logger->log("can't find client data translation");
+ return PoParser::getEmptyDict();
+}
diff --git a/src/utils/translation/translationmanager.h b/src/utils/translation/translationmanager.h
new file mode 100644
index 000000000..de3875b0a
--- /dev/null
+++ b/src/utils/translation/translationmanager.h
@@ -0,0 +1,39 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2012 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef UTILS_TRANSLATION_MANAGER_H
+#define UTILS_TRANSLATION_MANAGER_H
+
+#include <string>
+#include <vector>
+
+class PoDict;
+
+class TranslationManager
+{
+ public:
+ static PoDict *loadLang(std::vector<std::string> lang);
+
+ static void init();
+
+ static void loadCurrentLang();
+};
+
+#endif // UTILS_TRANSLATION_MANAGER_H
diff --git a/src/utils/xml.cpp b/src/utils/xml.cpp
index 420915d8f..140da72df 100644
--- a/src/utils/xml.cpp
+++ b/src/utils/xml.cpp
@@ -26,6 +26,8 @@
#include "resources/resourcemanager.h"
+#include "utils/translation/podict.h"
+
#include <iostream>
#include <fstream>
#include <cstring>
@@ -148,6 +150,16 @@ namespace XML
return def;
}
+ std::string langProperty(XmlNodePtr node, const char *name,
+ const std::string &def)
+ {
+ std::string str = getProperty(node, name, def);
+ if (!translator)
+ return str;
+
+ return translator->getStr(str);
+ }
+
bool getBoolProperty(XmlNodePtr node, const char* name, bool def)
{
xmlChar *prop = xmlGetProp(node, BAD_CAST name);
diff --git a/src/utils/xml.h b/src/utils/xml.h
index f623fa618..eb5ee88b0 100644
--- a/src/utils/xml.h
+++ b/src/utils/xml.h
@@ -92,6 +92,12 @@ namespace XML
const std::string &def);
/**
+ * Gets a translated string property from an XmlNodePtr.
+ */
+ std::string langProperty(XmlNodePtr node, const char *name,
+ const std::string &def);
+
+ /**
* Gets a boolean property from an XmlNodePtr.
*/
bool getBoolProperty(XmlNodePtr node, const char *name, bool def);