MyGUI: MyGUI_LanguageManager.cpp Source File

MyGUI 3.2.2

MyGUI_LanguageManager.cpp
Go to the documentation of this file.
1 /*
2 * This source file is part of MyGUI. For the latest info, see http://mygui.info/
3 * Distributed under the MIT License
4 * (See accompanying file COPYING.MIT or copy at http://opensource.org/licenses/MIT)
5 */
6
7 #include "MyGUI_Precompiled.h"
8 #include "MyGUI_LanguageManager.h"
9 #include "MyGUI_ResourceManager.h"
10 #include "MyGUI_XmlDocument.h"
11 #include "MyGUI_DataManager.h"
12 #include "MyGUI_FactoryManager.h"
13 #include "MyGUI_DataStreamHolder.h"
14
15 namespace MyGUI
16 {
17
18 template <> LanguageManager* Singleton<LanguageManager>::msInstance = nullptr;
19 template <> const char* Singleton<LanguageManager>::mClassTypeName = "LanguageManager";
20
21 LanguageManager::LanguageManager() :
22 mIsInitialise(false),
23 mXmlLanguageTagName("Language")
24 {
25 }
26
27 void LanguageManager::initialise()
28 {
29 MYGUI_ASSERT(!mIsInitialise, getClassTypeName() << " initialised twice");
30 MYGUI_LOG(Info, "* Initialise: " << getClassTypeName());
31
32 ResourceManager::getInstance().registerLoadXmlDelegate(mXmlLanguageTagName) = newDelegate(this, &LanguageManager::_load);
33
34 MYGUI_LOG(Info, getClassTypeName() << " successfully initialized");
35 mIsInitialise = true;
36 }
37
38 void LanguageManager::shutdown()
39 {
40 MYGUI_ASSERT(mIsInitialise, getClassTypeName() << " is not initialised");
41 MYGUI_LOG(Info, "* Shutdown: " << getClassTypeName());
42
43 ResourceManager::getInstance().unregisterLoadXmlDelegate(mXmlLanguageTagName);
44
45 MYGUI_LOG(Info, getClassTypeName() << " successfully shutdown");
46 mIsInitialise = false;
47 }
48
49 void LanguageManager::_load(xml::ElementPtr _node, const std::string& _file, Version _version)
50 {
51 std::string default_lang;
52 bool event_change = false;
53
54 // берем детей и крутимся, основной цикл
55 xml::ElementEnumerator root = _node->getElementEnumerator();
56 while (root.next(mXmlLanguageTagName))
57 {
58 // парсим атрибуты
59 root->findAttribute("default", default_lang);
60
61 // берем детей и крутимся
62 xml::ElementEnumerator info = root->getElementEnumerator();
63 while (info.next("Info"))
64 {
65 // парсим атрибуты
66 std::string name(info->findAttribute("name"));
67
68 // доюавляем в карту пользователя
69 if (name.empty())
70 {
71 xml::ElementEnumerator source_info = info->getElementEnumerator();
72 while (source_info.next("Source"))
73 {
74 loadLanguage(source_info->getContent(), true);
75 }
76 }
77 // добавляем в карту языков
78 else
79 {
80 xml::ElementEnumerator source_info = info->getElementEnumerator();
81 while (source_info.next("Source"))
82 {
83 std::string file_source = source_info->getContent();
84 // добавляем в карту
85 mMapFile[name].push_back(file_source);
86
87 // если добавляемый файл для текущего языка, то подгружаем и оповещаем
88 if (name == mCurrentLanguageName)
89 {
90 loadLanguage(file_source, false);
91 event_change = true;
92 }
93 }
94 }
95
96 }
97 }
98
99 if (!default_lang.empty())
100 setCurrentLanguage(default_lang);
101 else if (event_change)
102 eventChangeLanguage(mCurrentLanguageName);
103 }
104
105 void LanguageManager::setCurrentLanguage(const std::string& _name)
106 {
107 MapListString::iterator item = mMapFile.find(_name);
108 if (item == mMapFile.end())
109 {
110 MYGUI_LOG(Error, "Language '" << _name << "' is not found");
111 return;
112 }
113
114 mMapLanguage.clear();
115 mCurrentLanguageName = _name;
116
117 for (VectorString::const_iterator iter = item->second.begin(); iter != item->second.end(); ++iter)
118 {
119 loadLanguage(*iter, false);
120 }
121
122 eventChangeLanguage(mCurrentLanguageName);
123 }
124
125 bool LanguageManager::loadLanguage(const std::string& _file, bool _user)
126 {
127 DataStreamHolder data = DataManager::getInstance().getData(_file);
128 if (data.getData() == nullptr)
129 {
130 MYGUI_LOG(Error, "file '" << _file << "' not found");
131 return false;
132 }
133
134 if (_file.find(".xml") != std::string::npos)
135 _loadLanguageXML(data.getData(), _user);
136 else
137 _loadLanguage(data.getData(), _user);
138
139 return true;
140 }
141
142 void LanguageManager::_loadLanguageXML(IDataStream* _stream, bool _user)
143 {
144 xml::Document doc;
145 // формат xml
146 if (doc.open(_stream))
147 {
148 xml::ElementPtr root = doc.getRoot();
149 if (root)
150 {
151 xml::ElementEnumerator tag = root->getElementEnumerator();
152 while (tag.next("Tag"))
153 {
154 if (_user)
155 mUserMapLanguage[tag->findAttribute("name")] = tag->getContent();
156 else
157 mMapLanguage[tag->findAttribute("name")] = tag->getContent();
158 }
159 }
160 }
161 }
162
163 void LanguageManager::_loadLanguage(IDataStream* _stream, bool _user)
164 {
165 // формат txt
166 std::string read;
167 while (!_stream->eof())
168 {
169 _stream->readline(read, '\n');
170 if (read.empty()) continue;
171
172 // заголовок утф
173 if ((uint8)read[0] == 0xEF && read.size() > 2)
174 {
175 read.erase(0, 3);
176 }
177
178 if (read[read.size() - 1] == '\r') read.erase(read.size() - 1, 1);
179 if (read.empty()) continue;
180
181 size_t pos = read.find_first_of(" \t");
182 if (_user)
183 {
184 if (pos == std::string::npos) mUserMapLanguage[read] = "";
185 else mUserMapLanguage[read.substr(0, pos)] = read.substr(pos + 1, std::string::npos);
186 }
187 else
188 {
189 if (pos == std::string::npos) mMapLanguage[read] = "";
190 else mMapLanguage[read.substr(0, pos)] = read.substr(pos + 1, std::string::npos);
191 }
192 }
193 }
194
195 UString LanguageManager::replaceTags(const UString& _line)
196 {
197 UString result(_line);
198
199 bool replace = false;
200 do
201 {
202 result = replaceTagsPass(result, replace);
203 }
204 while (replace);
205
206 return result;
207 }
208
209 UString LanguageManager::getTag(const UString& _tag)
210 {
211 MapLanguageString::iterator iter = mMapLanguage.find(_tag);
212 if (iter != mMapLanguage.end())
213 {
214 return iter->second;
215 }
216
217 MapLanguageString::iterator iterUser = mUserMapLanguage.find(_tag);
218 if (iterUser != mUserMapLanguage.end())
219 {
220 return iterUser->second;
221 }
222
223 return _tag;
224 }
225
226 const std::string& LanguageManager::getCurrentLanguage() const
227 {
228 return mCurrentLanguageName;
229 }
230
231 void LanguageManager::addUserTag(const UString& _tag, const UString& _replace)
232 {
233 mUserMapLanguage[_tag] = _replace;
234 }
235
236 void LanguageManager::clearUserTags()
237 {
238 mUserMapLanguage.clear();
239 }
240
241 bool LanguageManager::loadUserTags(const std::string& _file)
242 {
243 return loadLanguage(_file, true);
244 }
245
246 UString LanguageManager::replaceTagsPass(const UString& _line, bool& _replaceResult)
247 {
248 _replaceResult = false;
249
250 // вот хз, что быстрее, итераторы или математика указателей,
251 // для непонятно какого размера одного символа UTF8
252 UString line(_line);
253
254 UString::iterator end = line.end();
255 for (UString::iterator iter = line.begin(); iter != end; )
256 {
257 if (*iter == '#')
258 {
259 ++iter;
260 if (iter == end)
261 {
262 return line;
263 }
264 else
265 {
266 if (*iter != '{')
267 {
268 ++iter;
269 continue;
270 }
271 UString::iterator iter2 = iter;
272 ++iter2;
273
274 while (true)
275 {
276 if (iter2 == end)
277 return line;
278
279 if (*iter2 == '}')
280 {
281 size_t start = iter - line.begin();
282 size_t len = (iter2 - line.begin()) - start - 1;
283 const UString& tag = line.substr(start + 1, len);
284 UString replacement;
285
286 bool find = true;
287 // try to find in loaded from resources language strings
288 MapLanguageString::iterator replace = mMapLanguage.find(tag);
289 if (replace != mMapLanguage.end())
290 {
291 replacement = replace->second;
292 }
293 else
294 {
295 // try to find in user language strings
296 replace = mUserMapLanguage.find(tag);
297 if (replace != mUserMapLanguage.end())
298 {
299 replacement = replace->second;
300 }
301 else
302 {
303 find = false;
304 }
305 }
306
307 // try to ask user if event assigned or use #{_tag} instead
308 if (!find)
309 {
310 if (!eventRequestTag.empty())
311 {
312 eventRequestTag(tag, replacement);
313 }
314 else
315 {
316 iter = line.insert(iter, '#') + size_t(len + 2);
317 end = line.end();
318 break;
319 }
320 }
321
322 _replaceResult = true;
323
324 iter = line.erase(iter - size_t(1), iter2 + size_t(1));
325 size_t pos = iter - line.begin();
326 line.insert(pos, replacement);
327 iter = line.begin() + pos + replacement.length();
328 end = line.end();
329 if (iter == end)
330 return line;
331 break;
332 }
333 ++iter2;
334 }
335 }
336 }
337 else
338 {
339 ++iter;
340 }
341 }
342
343 return line;
344 }
345
346 } // namespace MyGUI
MyGUI::Singleton< ResourceManager >::getInstance
static ResourceManager & getInstance()
Definition: MyGUI_Singleton.h:38
MyGUI_DataStreamHolder.h
MyGUI::LanguageManager::eventChangeLanguage
delegates::CMultiDelegate1< const std::string & > eventChangeLanguage
Definition: MyGUI_LanguageManager.h:55
MyGUI_DataManager.h
MyGUI::LanguageManager::shutdown
void shutdown()
Definition: MyGUI_LanguageManager.cpp:38
MyGUI::xml::ElementPtr
Element * ElementPtr
Definition: MyGUI_XmlDocument.h:104
MyGUI_XmlDocument.h
MyGUI::ResourceManager::registerLoadXmlDelegate
LoadXmlDelegate & registerLoadXmlDelegate(const std::string &_key)
Definition: MyGUI_ResourceManager.cpp:119
MyGUI_ResourceManager.h
MyGUI::DataStreamHolder::getData
IDataStream * getData()
Definition: MyGUI_DataStreamHolder.h:29
MyGUI::len
float len(float x, float y)
Definition: MyGUI_PolygonalSkin.cpp:35
MyGUI::LanguageManager::setCurrentLanguage
void setCurrentLanguage(const std::string &_name)
Definition: MyGUI_LanguageManager.cpp:105
MyGUI::ResourceManager::unregisterLoadXmlDelegate
void unregisterLoadXmlDelegate(const std::string &_key)
Definition: MyGUI_ResourceManager.cpp:126
MyGUI::Singleton< LanguageManager >::getClassTypeName
static const char * getClassTypeName()
Definition: MyGUI_Singleton.h:49
MyGUI::xml::Element
Definition: MyGUI_XmlDocument.h:158
MyGUI::xml::Element::findAttribute
bool findAttribute(const std::string &_name, std::string &_value)
Definition: MyGUI_XmlDocument.cpp:246
MyGUI::UString
A UTF-16 string with implicit conversion to/from std::string and std::wstring.
Definition: MyGUI_UString.h:168
MyGUI_Precompiled.h
MyGUI::UString::iterator
_fwd_iterator iterator
iterator
Definition: MyGUI_UString.h:432
MyGUI::UString::_fwd_iterator
forward iterator for UString
Definition: MyGUI_UString.h:243
MyGUI::Version
Definition: MyGUI_Version.h:17
MyGUI::LanguageManager::getCurrentLanguage
const std::string & getCurrentLanguage() const
Definition: MyGUI_LanguageManager.cpp:226
MyGUI::xml::ElementEnumerator
Definition: MyGUI_XmlDocument.h:114
MYGUI_ASSERT
#define MYGUI_ASSERT(exp, dest)
Definition: MyGUI_Diagnostic.h:42
MyGUI::LanguageManager::getTag
UString getTag(const UString &_tag)
Definition: MyGUI_LanguageManager.cpp:209
MyGUI_LanguageManager.h
MyGUI::LanguageManager::loadUserTags
bool loadUserTags(const std::string &_file)
Definition: MyGUI_LanguageManager.cpp:241
MyGUI::DataStreamHolder
Definition: MyGUI_DataStreamHolder.h:16
MyGUI::uint8
unsigned char uint8
Definition: MyGUI_Types.h:46
MYGUI_LOG
#define MYGUI_LOG(level, text)
Definition: MyGUI_Diagnostic.h:22
MyGUI::LanguageManager::clearUserTags
void clearUserTags()
Definition: MyGUI_LanguageManager.cpp:236
MyGUI::LanguageManager::initialise
void initialise()
Definition: MyGUI_LanguageManager.cpp:27
MyGUI::LanguageManager::replaceTags
UString replaceTags(const UString &_line)
Definition: MyGUI_LanguageManager.cpp:195
MyGUI::xml::Element::getContent
const std::string & getContent() const
Definition: MyGUI_XmlDocument.cpp:337
MyGUI::LanguageManager::addUserTag
void addUserTag(const UString &_tag, const UString &_replace)
Definition: MyGUI_LanguageManager.cpp:231
MyGUI::LanguageManager::eventRequestTag
delegates::CDelegate2< const UString &, UString & > eventRequestTag
Definition: MyGUI_LanguageManager.h:63
MyGUI::xml::Element::getElementEnumerator
ElementEnumerator getElementEnumerator()
Definition: MyGUI_XmlDocument.cpp:352
MyGUI
Definition: MyGUI_ActionController.h:14
MyGUI::xml::ElementEnumerator::next
bool next()
Definition: MyGUI_XmlDocument.cpp:100
newDelegate
MYGUI_TEMPLATE MYGUI_TEMPLATE_PARAMS delegates::IDelegateMYGUI_SUFFIX MYGUI_TEMPLATE_ARGS * newDelegate(void(*_func)(MYGUI_PARAMS))
Definition: MyGUI_DelegateImplement.h:117
MyGUI::LanguageManager::LanguageManager
LanguageManager()
Definition: MyGUI_LanguageManager.cpp:21
MyGUI::DataManager::getData
virtual IDataStream * getData(const std::string &_name)=0
MyGUI_FactoryManager.h