MyGUI
3.0.1
|
00001 00007 /* 00008 This file is part of MyGUI. 00009 00010 MyGUI is free software: you can redistribute it and/or modify 00011 it under the terms of the GNU Lesser General Public License as published by 00012 the Free Software Foundation, either version 3 of the License, or 00013 (at your option) any later version. 00014 00015 MyGUI is distributed in the hope that it will be useful, 00016 but WITHOUT ANY WARRANTY; without even the implied warranty of 00017 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00018 GNU Lesser General Public License for more details. 00019 00020 You should have received a copy of the GNU Lesser General Public License 00021 along with MyGUI. If not, see <http://www.gnu.org/licenses/>. 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 // формат xml 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 // формат txt 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 // для непонятно какого размера одного символа UTF8 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 } // namespace MyGUI