MyGUI 3.4.1
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"
10#include "MyGUI_XmlDocument.h"
11#include "MyGUI_DataManager.h"
14
15namespace MyGUI
16{
17
19
21 mIsInitialise(false),
22 mXmlLanguageTagName("Language"),
23 mSingletonHolder(this)
24 {
25 }
26
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
39 {
40 MYGUI_ASSERT(mIsInitialise, getClassTypeName() << " is not initialised");
41 MYGUI_LOG(Info, "* Shutdown: " << getClassTypeName());
42
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 // берем детей и крутимся, основной цикл
56 while (root.next(mXmlLanguageTagName))
57 {
58 // парсим атрибуты
59 root->findAttribute("default", default_lang);
60
61 // берем детей и крутимся
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 {
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
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
210 {
211 MapLanguageString::const_iterator iter = mMapLanguage.find(_tag);
212 if (iter != mMapLanguage.end())
213 {
214 return iter->second;
215 }
216
217 MapLanguageString::const_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
233 {
234 VectorString result;
235 for (MapListString::const_iterator iter = mMapFile.begin(); iter != mMapFile.end(); ++iter)
236 {
237 result.push_back(iter->first);
238 }
239 return result;
240 }
241
242 void LanguageManager::addUserTag(const UString& _tag, const UString& _replace)
243 {
244 mUserMapLanguage[_tag] = _replace;
245 }
246
248 {
249 mUserMapLanguage.clear();
250 }
251
252 bool LanguageManager::loadUserTags(const std::string& _file)
253 {
254 return loadLanguage(_file, true);
255 }
256
257 UString LanguageManager::replaceTagsPass(const UString& _line, bool& _replaceResult)
258 {
259 _replaceResult = false;
260
261 UString::utf32string line(_line.asUTF32());
262
263 UString::utf32string::iterator end = line.end();
264 for (UString::utf32string::iterator iter = line.begin(); iter != end; )
265 {
266 if (*iter == '#')
267 {
268 ++iter;
269 if (iter == end)
270 {
271 return UString(line);
272 }
273 else
274 {
275 if (*iter != '{')
276 {
277 ++iter;
278 continue;
279 }
280 UString::utf32string::iterator iter2 = iter;
281 ++iter2;
282
283 while (true)
284 {
285 if (iter2 == end)
286 return UString(line);
287
288 if (*iter2 == '}')
289 {
290 size_t start = iter - line.begin();
291 size_t len = (iter2 - line.begin()) - start - 1;
292 const UString::utf32string & tag = line.substr(start + 1, len);
293 UString replacement;
294
295 bool find = true;
296 // try to find in loaded from resources language strings
297 MapLanguageString::iterator replace = mMapLanguage.find(UString(tag));
298 if (replace != mMapLanguage.end())
299 {
300 replacement = replace->second;
301 }
302 else
303 {
304 // try to find in user language strings
305 replace = mUserMapLanguage.find(UString(tag));
306 if (replace != mUserMapLanguage.end())
307 {
308 replacement = replace->second;
309 }
310 else
311 {
312 find = false;
313 }
314 }
315
316 // try to ask user if event assigned or use #{_tag} instead
317 if (!find)
318 {
319 if (!eventRequestTag.empty())
320 {
321 eventRequestTag(UString(tag), replacement);
322 }
323 else
324 {
325 iter = line.insert(iter, '#') + size_t(len + 2);
326 end = line.end();
327 break;
328 }
329 }
330
331 _replaceResult = true;
332
333 iter = line.erase(iter - size_t(1), iter2 + size_t(1));
334 size_t pos = iter - line.begin();
335 line.insert(pos, replacement.asUTF32());
336 iter = line.begin() + pos + replacement.length();
337 end = line.end();
338 if (iter == end)
339 return UString(line);
340 break;
341 }
342 ++iter2;
343 }
344 }
345 }
346 else
347 {
348 ++iter;
349 }
350 }
351
352 return UString(line);
353 }
354
355} // namespace MyGUI
#define MYGUI_ASSERT(exp, dest)
#define MYGUI_LOG(level, text)
virtual IDataStream * getData(const std::string &_name) const =0
static DataManager & getInstance()
const std::string & getCurrentLanguage() const
delegates::CDelegate2< const UString &, UString & > eventRequestTag
void addUserTag(const UString &_tag, const UString &_replace)
void setCurrentLanguage(const std::string &_name)
static const char * getClassTypeName()
VectorString getLanguages() const
UString getTag(const UString &_tag) const
delegates::CMultiDelegate1< const std::string & > eventChangeLanguage
bool loadUserTags(const std::string &_file)
UString replaceTags(const UString &_line)
void unregisterLoadXmlDelegate(const std::string &_key)
static ResourceManager & getInstance()
LoadXmlDelegate & registerLoadXmlDelegate(const std::string &_key)
A UTF-16 string with implicit conversion to/from std::string and std::wstring.
const utf32string & asUTF32() const
returns the current string in UTF-32 form within a utf32string
std::basic_string< unicode_char > utf32string
string type used for returning UTF-32 formatted data
const std::string & getContent() const
ElementEnumerator getElementEnumerator()
bool findAttribute(const std::string &_name, std::string &_value)
Element * ElementPtr
std::vector< std::string > VectorString
Definition: MyGUI_Types.h:40
uint8_t uint8
Definition: MyGUI_Types.h:45
delegates::DelegateFunction< Args... > * newDelegate(void(*_func)(Args... args))
MYGUI_SINGLETON_DEFINITION(ClipboardManager)
float len(float x, float y)