• Main Page
  • Related Pages
  • Namespaces
  • Data Structures
  • Files
  • Examples
  • File List
  • Globals

MyGUI_LanguageManager.cpp

Go to the documentation of this file.
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_ResourceLanguage.h"
00029 #include "MyGUI_FactoryManager.h"
00030 
00031 namespace MyGUI
00032 {
00033 
00034     const std::string XML_TYPE("Language");
00035     const std::string XML_TYPE_TAG("Tag");
00036     const std::string XML_TYPE_RESOURCE("Resource");
00037     const std::string XML_TYPE_PROPERTY("Property");
00038     const std::string XML_TYPE_SOURCE("Source");
00039 
00040     MYGUI_INSTANCE_IMPLEMENT(LanguageManager);
00041 
00042     void LanguageManager::initialise()
00043     {
00044         MYGUI_ASSERT(false == mIsInitialise, INSTANCE_TYPE_NAME << " initialised twice");
00045         MYGUI_LOG(Info, "* Initialise: " << INSTANCE_TYPE_NAME);
00046 
00047         ResourceManager::getInstance().registerLoadXmlDelegate(XML_TYPE) = newDelegate(this, &LanguageManager::_load);
00048         ResourceManager::getInstance().registerLoadXmlDelegate(XML_TYPE_TAG) = newDelegate(this, &LanguageManager::_loadSource);
00049         FactoryManager::getInstance().registryFactory<ResourceLanguage>(XML_TYPE_RESOURCE);
00050 
00051         MYGUI_LOG(Info, INSTANCE_TYPE_NAME << " successfully initialized");
00052         mIsInitialise = true;
00053     }
00054 
00055     void LanguageManager::shutdown()
00056     {
00057         if (false == mIsInitialise) return;
00058         MYGUI_LOG(Info, "* Shutdown: " << INSTANCE_TYPE_NAME);
00059 
00060         ResourceManager::getInstance().unregisterLoadXmlDelegate(XML_TYPE_TAG);
00061         ResourceManager::getInstance().unregisterLoadXmlDelegate(XML_TYPE);
00062         FactoryManager::getInstance().unregistryFactory<ResourceLanguage>(XML_TYPE_RESOURCE);
00063 
00064         MYGUI_LOG(Info, INSTANCE_TYPE_NAME << " successfully shutdown");
00065         mIsInitialise = false;
00066     }
00067 
00068     bool LanguageManager::load(const std::string& _file)
00069     {
00070         return ResourceManager::getInstance()._loadImplement(_file, true, XML_TYPE, INSTANCE_TYPE_NAME);
00071     }
00072 
00073     void LanguageManager::_load(xml::ElementPtr _node, const std::string& _file, Version _version)
00074     {
00075         // берем детей и крутимся, основной цикл
00076         xml::ElementEnumerator root = _node->getElementEnumerator();
00077         while (root.next())
00078         {
00079             /*if (root->getName() == XML_TYPE)
00080             {
00081                 // парсим атрибуты
00082                 std::string def = root->findAttribute("default");
00083                 if (!def.empty())
00084                     mDefaultName = def;
00085 
00086                 // берем детей и крутимся
00087                 xml::ElementEnumerator info = root->getElementEnumerator();
00088                 while (info.next("Info"))
00089                 {
00090                     // парсим атрибуты
00091                     std::string name(info->findAttribute("name"));
00092                     std::string type = ResourceLanguage::getClassTypeName();
00093 
00094                     if (name.empty()) name = "_UserLanguageTags";
00095 
00096                     IObject* object = FactoryManager::getInstance().createObject(XML_TYPE_RESOURCE, type);
00097                     if (object != nullptr)
00098                     {
00099                         ResourceLanguage* data = object->castType<ResourceLanguage>();
00100                         data->deserialization(info.current(), _version);
00101 
00102                         ResourceManager::getInstance().addResource(data);
00103 
00104                         if (name == "_UserLanguageTags")
00105                         {
00106                             Enumerator<VectorString> tag = data->getEnumerator();
00107                             while (tag.next())
00108                             {
00109                                 loadLanguage(tag.current(), true);
00110                             }
00111                         }
00112                     }
00113 
00114                 }
00115             }
00116             else */if (root->getName() == XML_TYPE_PROPERTY)
00117             {
00118                 const std::string& key = root->findAttribute("key");
00119                 const std::string& value = root->findAttribute("value");
00120                 if (key == "Default")
00121                     //mDefaultName = value;
00122                     setCurrentLanguage(value);
00123             }
00124         }
00125 
00126         //if (!mDefaultName.empty())
00127             //setCurrentLanguage(mDefaultName);
00128     }
00129 
00130     void LanguageManager::setCurrentLanguage(const std::string& _name)
00131     {
00132         loadResourceLanguage(_name);
00133         mCurrentLanguageName = _name;
00134         eventChangeLanguage(mCurrentLanguageName);
00135     }
00136 
00137     bool LanguageManager::loadResourceLanguage(const std::string& _name)
00138     {
00139         mMapLanguage.clear();
00140 
00141         IResource* data = ResourceManager::getInstance().getByName(_name, false);
00142         if (data == nullptr)
00143             return false;
00144 
00145         ResourceLanguage* lang = data->castType<ResourceLanguage>(false);
00146         if (lang == nullptr)
00147             return false;
00148 
00149         Enumerator<VectorString> source = lang->getEnumerator();
00150         while (source.next())
00151         {
00152             loadLanguage(source.current());
00153         }
00154 
00155         return true;
00156     }
00157 
00158     bool LanguageManager::loadLanguage(const std::string& _file, bool _user)
00159     {
00160         IDataStream* data = DataManager::getInstance().getData(_file);
00161         if (data == nullptr)
00162         {
00163             MYGUI_LOG(Error, "file '" << _file << "' not found");
00164             return false;
00165         }
00166 
00167         if (_file.find(".xml") != std::string::npos)
00168             _loadLanguageXML(data, _user);
00169         else
00170             _loadLanguage(data, _user);
00171 
00172         delete data;
00173         return true;
00174     }
00175 
00176     void LanguageManager::_loadLanguageXML(IDataStream* _stream, bool _user)
00177     {
00178         xml::Document doc;
00179         // формат xml
00180         if (doc.open(_stream))
00181         {
00182             xml::ElementPtr root = doc.getRoot();
00183             if (root)
00184             {
00185                 xml::ElementEnumerator tag = root->getElementEnumerator();
00186                 while (tag.next("Tag"))
00187                 {
00188                     if (_user)
00189                         mUserMapLanguage[tag->findAttribute("name")] = tag->getContent();
00190                     else
00191                         mMapLanguage[tag->findAttribute("name")] = tag->getContent();
00192                 }
00193             }
00194         }
00195     }
00196 
00197     void LanguageManager::_loadLanguage(IDataStream* _stream, bool _user)
00198     {
00199         // формат txt
00200         std::string read;
00201         while (!_stream->eof())
00202         {
00203             _stream->readline(read, '\n');
00204             if (read.empty()) continue;
00205 
00206             // заголовок утф
00207             if ((uint8)read[0] == 0xEF && read.size() > 2)
00208             {
00209                 read.erase(0, 3);
00210             }
00211 
00212             if (read[read.size()-1] == '\r') read.erase(read.size()-1, 1);
00213             if (read.empty()) continue;
00214 
00215             size_t pos = read.find_first_of(" \t");
00216             if (_user)
00217             {
00218                 if (pos == std::string::npos) mUserMapLanguage[read] = "";
00219                 else mUserMapLanguage[read.substr(0, pos)] = read.substr(pos+1, std::string::npos);
00220             }
00221             else
00222             {
00223                 if (pos == std::string::npos) mMapLanguage[read] = "";
00224                 else mMapLanguage[read.substr(0, pos)] = read.substr(pos+1, std::string::npos);
00225             }
00226         }
00227     }
00228 
00229     UString LanguageManager::replaceTags(const UString& _line)
00230     {
00231         //FIXME для совместимости
00232         /*if (mCurrentLanguageName.empty())
00233         {
00234             mDefaultName = "English";
00235             setCurrentLanguage(mDefaultName);
00236         }*/
00237 
00238         // вот хз, что быстрее, итераторы или математика указателей,
00239         // для непонятно какого размера одного символа UTF8
00240         UString line(_line);
00241 
00242         if (mMapLanguage.empty() && mUserMapLanguage.empty())
00243             return _line;
00244 
00245         UString::iterator end = line.end();
00246         for (UString::iterator iter=line.begin(); iter!=end; )
00247         {
00248             if (*iter == '#')
00249             {
00250                 ++iter;
00251                 if (iter == end)
00252                 {
00253                     return line;
00254                 }
00255                 else
00256                 {
00257                     if (*iter != '{')
00258                     {
00259                         ++iter;
00260                         continue;
00261                     }
00262                     UString::iterator iter2 = iter;
00263                     ++iter2;
00264                     while (true)
00265                     {
00266                         if (iter2 == end) return line;
00267                         if (*iter2 == '}')
00268                         {
00269                             size_t start = iter - line.begin();
00270                             size_t len = (iter2 - line.begin()) - start - 1;
00271                             const UString& tag = line.substr(start + 1, len);
00272 
00273                             bool find = true;
00274                             MapLanguageString::iterator replace = mMapLanguage.find(tag);
00275                             if (replace == mMapLanguage.end())
00276                             {
00277                                 replace = mUserMapLanguage.find(tag);
00278                                 find = replace != mUserMapLanguage.end();
00279                             }
00280 
00281                             if (!find)
00282                             {
00283                                 iter = line.insert(iter, '#') + size_t(len + 2);
00284                                 end = line.end();
00285                                 break;
00286                             }
00287 
00288                             iter = line.erase(iter - size_t(1), iter2 + size_t(1));
00289                             size_t pos = iter - line.begin();
00290                             line.insert(pos, replace->second);
00291                             iter = line.begin() + pos + replace->second.length();
00292                             end = line.end();
00293                             if (iter == end) return line;
00294                             break;
00295 
00296                         }
00297                         ++iter2;
00298                     };
00299                 }
00300             }
00301             else
00302             {
00303                 ++iter;
00304             }
00305         }
00306 
00307         return line;
00308     }
00309 
00310     UString LanguageManager::getTag(const UString& _tag)
00311     {
00312         //FIXME
00313         //if (mCurrentLanguageName.empty()) setCurrentLanguage("English");
00314 
00315         MapLanguageString::iterator iter = mMapLanguage.find(_tag);
00316         if (iter == mMapLanguage.end())
00317         {
00318             iter = mUserMapLanguage.find(_tag);
00319             if (iter != mUserMapLanguage.end()) return iter->second;
00320             return _tag;
00321         }
00322 
00323         return iter->second;
00324     }
00325 
00326     const std::string& LanguageManager::getCurrentLanguage()
00327     {
00328         return mCurrentLanguageName;
00329     }
00330 
00331     void LanguageManager::addUserTag(const UString& _tag, const UString& _replace)
00332     {
00333         mUserMapLanguage[_tag] = _replace;
00334     }
00335 
00336     void LanguageManager::clearUserTags()
00337     {
00338         mUserMapLanguage.clear();
00339     }
00340 
00341     void LanguageManager::_loadSource(xml::ElementPtr _node, const std::string& _file, Version _version)
00342     {
00343         // берем детей и крутимся, основной цикл
00344         xml::ElementEnumerator node = _node->getElementEnumerator();
00345         while (node.next(XML_TYPE_SOURCE))
00346         {
00347             loadLanguage(node->getContent(), true);
00348         }
00349     }
00350 
00351     bool LanguageManager::loadUserTags(const std::string& _file)
00352     {
00353         return loadLanguage(_file, true);
00354     }
00355 
00356 } // namespace MyGUI

Generated on Sun Jan 30 2011 for MyGUI by  doxygen 1.7.1