00001
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "MyGUI_Precompiled.h"
00024 #include "MyGUI_ResourceManager.h"
00025 #include "MyGUI_LanguageManager.h"
00026 #include "MyGUI_XmlDocument.h"
00027 #include "MyGUI_DataManager.h"
00028 #include "MyGUI_FactoryManager.h"
00029
00030 namespace MyGUI
00031 {
00032
00033 const std::string XML_TYPE("Language");
00034
00035 MYGUI_INSTANCE_IMPLEMENT( LanguageManager )
00036
00037 void LanguageManager::initialise()
00038 {
00039 MYGUI_ASSERT(!mIsInitialise, INSTANCE_TYPE_NAME << " initialised twice");
00040 MYGUI_LOG(Info, "* Initialise: " << INSTANCE_TYPE_NAME);
00041
00042 ResourceManager::getInstance().registerLoadXmlDelegate(XML_TYPE) = newDelegate(this, &LanguageManager::_load);
00043
00044 MYGUI_LOG(Info, INSTANCE_TYPE_NAME << " successfully initialized");
00045 mIsInitialise = true;
00046 }
00047
00048 void LanguageManager::shutdown()
00049 {
00050 if (!mIsInitialise) return;
00051 MYGUI_LOG(Info, "* Shutdown: " << INSTANCE_TYPE_NAME);
00052
00053 ResourceManager::getInstance().unregisterLoadXmlDelegate(XML_TYPE);
00054
00055 MYGUI_LOG(Info, INSTANCE_TYPE_NAME << " successfully shutdown");
00056 mIsInitialise = false;
00057 }
00058
00059 bool LanguageManager::load(const std::string& _file)
00060 {
00061 return ResourceManager::getInstance()._loadImplement(_file, true, XML_TYPE, INSTANCE_TYPE_NAME);
00062 }
00063
00064 void LanguageManager::_load(xml::ElementPtr _node, const std::string& _file, Version _version)
00065 {
00066 std::string default_lang;
00067 bool event_change = false;
00068
00069
00070 xml::ElementEnumerator root = _node->getElementEnumerator();
00071 while (root.next(XML_TYPE))
00072 {
00073
00074 root->findAttribute("default", default_lang);
00075
00076
00077 xml::ElementEnumerator info = root->getElementEnumerator();
00078 while (info.next("Info"))
00079 {
00080
00081 std::string name(info->findAttribute("name"));
00082
00083
00084 if (name.empty())
00085 {
00086 xml::ElementEnumerator source_info = info->getElementEnumerator();
00087 while (source_info.next("Source"))
00088 {
00089 loadLanguage(source_info->getContent(), true);
00090 }
00091 }
00092
00093 else
00094 {
00095 xml::ElementEnumerator source_info = info->getElementEnumerator();
00096 while (source_info.next("Source"))
00097 {
00098 std::string file_source = source_info->getContent();
00099
00100 mMapFile[name].push_back(file_source);
00101
00102
00103 if (name == mCurrentLanguageName)
00104 {
00105 loadLanguage(file_source, false);
00106 event_change = true;
00107 }
00108 }
00109 }
00110
00111 }
00112 }
00113
00114 if (!default_lang.empty())
00115 setCurrentLanguage(default_lang);
00116 else if (event_change)
00117 eventChangeLanguage(mCurrentLanguageName);
00118 }
00119
00120 void LanguageManager::setCurrentLanguage(const std::string& _name)
00121 {
00122 mMapLanguage.clear();
00123
00124 mCurrentLanguageName = _name;
00125
00126 MapListString::iterator item = mMapFile.find(_name);
00127 if (item == mMapFile.end())
00128 {
00129 MYGUI_LOG(Error, "Language '" << _name << "' is not found");
00130 return;
00131 }
00132
00133 for (VectorString::const_iterator iter=item->second.begin(); iter!=item->second.end(); ++iter)
00134 {
00135 loadLanguage(*iter, false);
00136 }
00137
00138 eventChangeLanguage(mCurrentLanguageName);
00139 }
00140
00141 bool LanguageManager::loadLanguage(const std::string& _file, bool _user)
00142 {
00143 IDataStream* data = DataManager::getInstance().getData(_file);
00144 if (data == nullptr)
00145 {
00146 MYGUI_LOG(Error, "file '" << _file << "' not found");
00147 return false;
00148 }
00149
00150 if (_file.find(".xml") != std::string::npos)
00151 _loadLanguageXML(data, _user);
00152 else
00153 _loadLanguage(data, _user);
00154
00155 delete data;
00156 return true;
00157 }
00158
00159 void LanguageManager::_loadLanguageXML(IDataStream* _stream, bool _user)
00160 {
00161 xml::Document doc;
00162
00163 if (doc.open(_stream))
00164 {
00165 xml::ElementPtr root = doc.getRoot();
00166 if (root)
00167 {
00168 xml::ElementEnumerator tag = root->getElementEnumerator();
00169 while (tag.next("Tag"))
00170 {
00171 if (_user)
00172 mUserMapLanguage[tag->findAttribute("name")] = tag->getContent();
00173 else
00174 mMapLanguage[tag->findAttribute("name")] = tag->getContent();
00175 }
00176 }
00177 }
00178 }
00179
00180 void LanguageManager::_loadLanguage(IDataStream* _stream, bool _user)
00181 {
00182
00183 std::string read;
00184 while (!_stream->eof())
00185 {
00186 _stream->readline(read, '\n');
00187 if (read.empty()) continue;
00188
00189
00190 if ((uint8)read[0] == 0xEF && read.size() > 2)
00191 {
00192 read.erase(0, 3);
00193 }
00194
00195 if (read[read.size()-1] == '\r') read.erase(read.size()-1, 1);
00196 if (read.empty()) continue;
00197
00198 size_t pos = read.find_first_of(" \t");
00199 if (_user)
00200 {
00201 if (pos == std::string::npos) mUserMapLanguage[read] = "";
00202 else mUserMapLanguage[read.substr(0, pos)] = read.substr(pos+1, std::string::npos);
00203 }
00204 else
00205 {
00206 if (pos == std::string::npos) mMapLanguage[read] = "";
00207 else mMapLanguage[read.substr(0, pos)] = read.substr(pos+1, std::string::npos);
00208 }
00209 }
00210 }
00211
00212 UString LanguageManager::replaceTags(const UString& _line)
00213 {
00214
00215
00216 UString line(_line);
00217
00218 if (mMapLanguage.empty() && mUserMapLanguage.empty())
00219 return _line;
00220
00221 UString::iterator end = line.end();
00222 for (UString::iterator iter=line.begin(); iter!=end; )
00223 {
00224 if (*iter == '#')
00225 {
00226 ++iter;
00227 if (iter == end)
00228 {
00229 return line;
00230 }
00231 else
00232 {
00233 if (*iter != '{')
00234 {
00235 ++iter;
00236 continue;
00237 }
00238 UString::iterator iter2 = iter;
00239 ++iter2;
00240 while (true)
00241 {
00242 if (iter2 == end) return line;
00243 if (*iter2 == '}')
00244 {
00245 size_t start = iter - line.begin();
00246 size_t len = (iter2 - line.begin()) - start - 1;
00247 const UString& tag = line.substr(start + 1, len);
00248
00249 bool find = true;
00250 MapLanguageString::iterator replace = mMapLanguage.find(tag);
00251 if (replace == mMapLanguage.end())
00252 {
00253 replace = mUserMapLanguage.find(tag);
00254 find = replace != mUserMapLanguage.end();
00255 }
00256
00257 if (!find)
00258 {
00259 iter = line.insert(iter, '#') + size_t(len + 2);
00260 end = line.end();
00261 break;
00262 }
00263
00264 iter = line.erase(iter - size_t(1), iter2 + size_t(1));
00265 size_t pos = iter - line.begin();
00266 line.insert(pos, replace->second);
00267 iter = line.begin() + pos + replace->second.length();
00268 end = line.end();
00269 if (iter == end) return line;
00270 break;
00271
00272 }
00273 ++iter2;
00274 }
00275 }
00276 }
00277 else
00278 {
00279 ++iter;
00280 }
00281 }
00282
00283 return line;
00284 }
00285
00286 UString LanguageManager::getTag(const UString& _tag)
00287 {
00288 MapLanguageString::iterator iter = mMapLanguage.find(_tag);
00289 if (iter == mMapLanguage.end())
00290 {
00291 iter = mUserMapLanguage.find(_tag);
00292 if (iter != mUserMapLanguage.end()) return iter->second;
00293 return _tag;
00294 }
00295
00296 return iter->second;
00297 }
00298
00299 const std::string& LanguageManager::getCurrentLanguage()
00300 {
00301 return mCurrentLanguageName;
00302 }
00303
00304 void LanguageManager::addUserTag(const UString& _tag, const UString& _replace)
00305 {
00306 mUserMapLanguage[_tag] = _replace;
00307 }
00308
00309 void LanguageManager::clearUserTags()
00310 {
00311 mUserMapLanguage.clear();
00312 }
00313
00314 bool LanguageManager::loadUserTags(const std::string& _file)
00315 {
00316 return loadLanguage(_file, true);
00317 }
00318
00319 }