MyGUI_LanguageManager.cpp
Go to the documentation of this file.
/*
* This source file is part of MyGUI. For the latest info, see http://mygui.info/
* Distributed under the MIT License
* (See accompanying file COPYING.MIT or copy at http://opensource.org/licenses/MIT)
*/
#include "MyGUI_Precompiled.h"
#include "MyGUI_LanguageManager.h"
#include "MyGUI_ResourceManager.h"
#include "MyGUI_XmlDocument.h"
#include "MyGUI_DataManager.h"
#include "MyGUI_FactoryManager.h"
#include "MyGUI_DataStreamHolder.h"
namespace MyGUI
{
MYGUI_SINGLETON_DEFINITION(LanguageManager);
LanguageManager::LanguageManager() :
mXmlLanguageTagName("Language"),
mSingletonHolder(this)
{
}
void LanguageManager::initialise()
{
MYGUI_ASSERT(!mIsInitialise, getClassTypeName() << " initialised twice");
MYGUI_LOG(Info, "* Initialise: " << getClassTypeName());
ResourceManager::getInstance().registerLoadXmlDelegate(mXmlLanguageTagName) =
newDelegate(this, &LanguageManager::_load);
MYGUI_LOG(Info, getClassTypeName() << " successfully initialized");
mIsInitialise = true;
}
void LanguageManager::shutdown()
{
MYGUI_ASSERT(mIsInitialise, getClassTypeName() << " is not initialised");
MYGUI_LOG(Info, "* Shutdown: " << getClassTypeName());
ResourceManager::getInstance().unregisterLoadXmlDelegate(mXmlLanguageTagName);
MYGUI_LOG(Info, getClassTypeName() << " successfully shutdown");
mIsInitialise = false;
}
void LanguageManager::_load(xml::ElementPtr _node, std::string_view /*_file*/, Version _version)
{
std::string default_lang;
bool event_change = false;
// берем детей и крутимся, основной цикл
xml::ElementEnumerator root = _node->getElementEnumerator();
while (root.next(mXmlLanguageTagName))
{
// парсим атрибуты
root->findAttribute("default", default_lang);
// берем детей и крутимся
xml::ElementEnumerator info = root->getElementEnumerator();
while (info.next("Info"))
{
// парсим атрибуты
std::string name(info->findAttribute("name"));
// доюавляем в карту пользователя
if (name.empty())
{
xml::ElementEnumerator source_info = info->getElementEnumerator();
while (source_info.next("Source"))
{
loadLanguage(source_info->getContent(), true);
}
}
// добавляем в карту языков
else
{
xml::ElementEnumerator source_info = info->getElementEnumerator();
while (source_info.next("Source"))
{
const std::string& file_source = source_info->getContent();
// добавляем в карту
mMapFile[name].push_back(file_source);
// если добавляемый файл для текущего языка, то подгружаем и оповещаем
if (name == mCurrentLanguageName)
{
loadLanguage(file_source, false);
event_change = true;
}
}
}
}
}
if (!default_lang.empty())
setCurrentLanguage(default_lang);
else if (event_change)
eventChangeLanguage(mCurrentLanguageName);
}
void LanguageManager::setCurrentLanguage(std::string_view _name)
{
MapListString::iterator item = mMapFile.find(_name);
if (item == mMapFile.end())
{
MYGUI_LOG(Error, "Language '" << _name << "' is not found");
return;
}
mMapLanguage.clear();
mCurrentLanguageName = _name;
for (const auto& file : item->second)
{
loadLanguage(file, false);
}
eventChangeLanguage(mCurrentLanguageName);
}
bool LanguageManager::loadLanguage(const std::string& _file, bool _user)
{
DataStreamHolder data = DataManager::getInstance().getData(_file);
if (data.getData() == nullptr)
{
MYGUI_LOG(Error, "file '" << _file << "' not found");
return false;
}
if (_file.find(".xml") != std::string::npos)
_loadLanguageXML(data.getData(), _user);
else
_loadLanguage(data.getData(), _user);
return true;
}
void LanguageManager::_loadLanguageXML(IDataStream* _stream, bool _user)
{
xml::Document doc;
// формат xml
if (doc.open(_stream))
{
xml::ElementPtr root = doc.getRoot();
if (root)
{
xml::ElementEnumerator tag = root->getElementEnumerator();
while (tag.next("Tag"))
{
auto& map = _user ? mUserMapLanguage : mMapLanguage;
mapSet(map, tag->findAttribute("name"), tag->getContent());
}
}
}
}
void LanguageManager::_loadLanguage(IDataStream* _stream, bool _user)
{
// формат txt
std::string read;
while (!_stream->eof())
{
_stream->readline(read, '\n');
if (read.empty())
continue;
// заголовок утф
if ((uint8)read[0] == 0xEF && read.size() > 2)
{
read.erase(0, 3);
}
if (read[read.size() - 1] == '\r')
read.erase(read.size() - 1, 1);
if (read.empty())
continue;
size_t pos = read.find_first_of(" \t");
if (_user)
{
if (pos == std::string::npos)
mUserMapLanguage[read].clear();
else
mUserMapLanguage[read.substr(0, pos)] = read.substr(pos + 1, std::string::npos);
}
else
{
if (pos == std::string::npos)
mMapLanguage[read].clear();
else
mMapLanguage[read.substr(0, pos)] = read.substr(pos + 1, std::string::npos);
}
}
}
UString LanguageManager::replaceTags(const UString& _line)
{
UString result(_line);
bool replace = false;
do
{
result = replaceTagsPass(result, replace);
} while (replace);
return result;
}
UString LanguageManager::getTag(const UString& _tag) const
{
MapLanguageString::const_iterator iter = mMapLanguage.find(_tag);
if (iter != mMapLanguage.end())
{
return iter->second;
}
MapLanguageString::const_iterator iterUser = mUserMapLanguage.find(_tag);
if (iterUser != mUserMapLanguage.end())
{
return iterUser->second;
}
return _tag;
}
const std::string& LanguageManager::getCurrentLanguage() const
{
return mCurrentLanguageName;
}
VectorString LanguageManager::getLanguages() const
{
VectorString result;
for (const auto& iter : mMapFile)
{
result.push_back(iter.first);
}
return result;
}
void LanguageManager::addUserTag(const UString& _tag, const UString& _replace)
{
mUserMapLanguage[_tag] = _replace;
}
void LanguageManager::clearUserTags()
{
mUserMapLanguage.clear();
}
bool LanguageManager::loadUserTags(const std::string& _file)
{
return loadLanguage(_file, true);
}
UString LanguageManager::replaceTagsPass(const UString& _line, bool& _replaceResult)
{
_replaceResult = false;
UString::utf32string line(_line.asUTF32());
UString::utf32string::iterator end = line.end();
for (UString::utf32string::iterator iter = line.begin(); iter != end;)
{
if (*iter == '#')
{
++iter;
if (iter == end)
{
return UString(line);
}
if (*iter != '{')
{
++iter;
continue;
}
UString::utf32string::iterator iter2 = iter;
++iter2;
while (true)
{
if (iter2 == end)
return UString(line);
if (*iter2 == '}')
{
size_t start = iter - line.begin();
size_t len = (iter2 - line.begin()) - start - 1;
const UString::utf32string& tag = line.substr(start + 1, len);
UString replacement;
bool find = true;
// try to find in loaded from resources language strings
MapLanguageString::iterator replace = mMapLanguage.find(UString(tag));
if (replace != mMapLanguage.end())
{
replacement = replace->second;
}
else
{
// try to find in user language strings
replace = mUserMapLanguage.find(UString(tag));
if (replace != mUserMapLanguage.end())
{
replacement = replace->second;
}
else
{
find = false;
}
}
// try to ask user if event assigned or use #{_tag} instead
if (!find)
{
if (!eventRequestTag.empty())
{
eventRequestTag(UString(tag), replacement);
}
else
{
iter = line.insert(iter, '#') + size_t(len + 2);
end = line.end();
break;
}
}
_replaceResult = true;
iter = line.erase(iter - size_t(1), iter2 + size_t(1));
size_t pos = iter - line.begin();
line.insert(pos, replacement.asUTF32());
iter = line.begin() + pos + replacement.length();
end = line.end();
if (iter == end)
return UString(line);
break;
}
++iter2;
}
}
else
{
++iter;
}
}
return UString(line);
}
} // namespace MyGUI
MyGUI_DataManager.h
MyGUI_DataStreamHolder.h
MYGUI_ASSERT
#define MYGUI_ASSERT(exp, dest)
Definition MyGUI_Diagnostic.h:31
MYGUI_LOG
#define MYGUI_LOG(level, text)
Definition MyGUI_Diagnostic.h:17
MyGUI_FactoryManager.h
MyGUI_LanguageManager.h
MyGUI_Precompiled.h
MyGUI_ResourceManager.h
MYGUI_SINGLETON_DEFINITION
#define MYGUI_SINGLETON_DEFINITION(ClassName)
Definition MyGUI_Singleton.h:126
MyGUI_XmlDocument.h
MyGUI::DataManager::getData
virtual IDataStream * getData(const std::string &_name) const =0
MyGUI::DataManager::getInstance
static DataManager & getInstance()
MyGUI::DataStreamHolder
Definition MyGUI_DataStreamHolder.h:17
MyGUI::DataStreamHolder::getData
IDataStream * getData()
Definition MyGUI_DataStreamHolder.h:31
MyGUI::IDataStream
Definition MyGUI_IDataStream.h:17
MyGUI::LanguageManager::LanguageManager
LanguageManager(const LanguageManager &)=delete
MyGUI::LanguageManager::eventChangeLanguage
delegates::MultiDelegate< const std::string & > eventChangeLanguage
Definition MyGUI_LanguageManager.h:57
MyGUI::LanguageManager::setCurrentLanguage
void setCurrentLanguage(std::string_view _name)
Definition MyGUI_LanguageManager.cpp:104
MyGUI::LanguageManager::LanguageManager
LanguageManager()
Definition MyGUI_LanguageManager.cpp:20
MyGUI::LanguageManager::clearUserTags
void clearUserTags()
Definition MyGUI_LanguageManager.cpp:250
MyGUI::LanguageManager::initialise
void initialise()
Definition MyGUI_LanguageManager.cpp:26
MyGUI::LanguageManager::getCurrentLanguage
const std::string & getCurrentLanguage() const
Definition MyGUI_LanguageManager.cpp:229
MyGUI::LanguageManager::eventRequestTag
delegates::Delegate< const UString &, UString & > eventRequestTag
Definition MyGUI_LanguageManager.h:65
MyGUI::LanguageManager::addUserTag
void addUserTag(const UString &_tag, const UString &_replace)
Definition MyGUI_LanguageManager.cpp:245
MyGUI::LanguageManager::getClassTypeName
static std::string_view getClassTypeName()
Definition MyGUI_LanguageManager.cpp:18
MyGUI::LanguageManager::getLanguages
VectorString getLanguages() const
Definition MyGUI_LanguageManager.cpp:235
MyGUI::LanguageManager::getTag
UString getTag(const UString &_tag) const
Definition MyGUI_LanguageManager.cpp:212
MyGUI::LanguageManager::shutdown
void shutdown()
Definition MyGUI_LanguageManager.cpp:38
MyGUI::LanguageManager::loadUserTags
bool loadUserTags(const std::string &_file)
Definition MyGUI_LanguageManager.cpp:255
MyGUI::LanguageManager::replaceTags
UString replaceTags(const UString &_line)
Definition MyGUI_LanguageManager.cpp:199
MyGUI::ResourceManager::unregisterLoadXmlDelegate
void unregisterLoadXmlDelegate(std::string_view _key)
Definition MyGUI_ResourceManager.cpp:127
MyGUI::ResourceManager::registerLoadXmlDelegate
LoadXmlDelegate & registerLoadXmlDelegate(std::string_view _key)
Definition MyGUI_ResourceManager.cpp:120
MyGUI::ResourceManager::getInstance
static ResourceManager & getInstance()
MyGUI::UString
A UTF-16 string with implicit conversion to/from std::string and std::wstring.
Definition MyGUI_UString.h:144
MyGUI::UString::find
size_type find(const UString &str, size_type index=0) const
returns the index of the first occurrence of str within the current string, starting at index; return...
Definition MyGUI_UString.cpp:1268
MyGUI::UString::asUTF32
const utf32string & asUTF32() const
returns the current string in UTF-32 form within a utf32string
Definition MyGUI_UString.cpp:685
MyGUI::UString::clear
void clear()
deletes all of the elements in the string
Definition MyGUI_UString.cpp:619
MyGUI::UString::utf32string
std::basic_string< unicode_char > utf32string
string type used for returning UTF-32 formatted data
Definition MyGUI_UString.h:177
MyGUI::Version
Definition MyGUI_Version.h:18
MyGUI::xml::ElementEnumerator
Definition MyGUI_XmlDocument.h:121
MyGUI::xml::ElementEnumerator::next
bool next()
Definition MyGUI_XmlDocument.cpp:107
MyGUI::xml::Element::getContent
const std::string & getContent() const
Definition MyGUI_XmlDocument.cpp:333
MyGUI::xml::Element::findAttribute
bool findAttribute(std::string_view _name, std::string &_value)
Definition MyGUI_XmlDocument.cpp:242
MyGUI::xml::Element::getElementEnumerator
ElementEnumerator getElementEnumerator()
Definition MyGUI_XmlDocument.cpp:348
MyGUI::xml::ElementPtr
Element * ElementPtr
Definition MyGUI_XmlDocument.h:112
MyGUI
Definition MyGUI_ActionController.h:15
MyGUI::uint8
uint8_t uint8
Definition MyGUI_Types.h:46
MyGUI::VectorString
std::vector< std::string > VectorString
Definition MyGUI_Types.h:41
MyGUI::mapSet
void mapSet(Map &map, std::string_view key, const Value &value)
Definition MyGUI_Macros.h:36
MyGUI::newDelegate
delegates::DelegateFunction< Args... > * newDelegate(void(*_func)(Args... args))
Definition MyGUI_Delegate.h:100
MyGUI::len
float len(float x, float y)
Definition MyGUI_PolygonalSkin.cpp:22