summaryrefslogtreecommitdiff
path: root/shared/localization.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'shared/localization.cpp')
-rw-r--r--shared/localization.cpp435
1 files changed, 0 insertions, 435 deletions
diff --git a/shared/localization.cpp b/shared/localization.cpp
deleted file mode 100644
index 73aa5b72..00000000
--- a/shared/localization.cpp
+++ /dev/null
@@ -1,435 +0,0 @@
-// **************************************************************************
-// * This file is part of the FreeFileSync project. It is distributed under *
-// * GNU General Public License: http://www.gnu.org/licenses/gpl.html *
-// * Copyright (C) 2008-2011 ZenJu (zhnmju123 AT gmx.de) *
-// **************************************************************************
-
-#include "localization.h"
-#include <fstream>
-#include <map>
-#include <list>
-#include <iterator>
-#include <wx/ffile.h>
-#include <wx/intl.h>
-#include <wx/msgdlg.h>
-#include "parse_plural.h"
-#include "parse_lng.h"
-#include "util.h"
-#include "string_tools.h"
-#include "file_traverser.h"
-#include "standard_paths.h"
-#include "string_conv.h"
-#include "zenXml/zenxml_io.h"
-#include "i18n.h"
-
-using namespace zen;
-
-
-namespace
-{
-//global objects
-std::wstring THOUSANDS_SEPARATOR = L",";
-
-
-class FFSLocale : public TranslationHandler
-{
-public:
- FFSLocale(const wxString& filename, wxLanguage languageId); //throw (lngfile::ParsingError, PluralForm::ParsingError)
-
- wxLanguage langId() const { return langId_; }
-
- virtual std::wstring thousandsSeparator() { return THOUSANDS_SEPARATOR; };
-
- virtual std::wstring translate(const std::wstring& text)
- {
- //look for translation in buffer table
- const Translation::const_iterator iter = transMapping.find(text);
- if (iter != transMapping.end())
- return iter->second;
-
- return text; //fallback
- }
-
- virtual std::wstring translate(const std::wstring& singular, const std::wstring& plural, int n)
- {
- TranslationPlural::const_iterator iter = transMappingPl.find(std::make_pair(singular, plural));
- if (iter != transMappingPl.end())
- {
- const int formNo = pluralParser->getForm(n);
- if (0 <= formNo && formNo < static_cast<int>(iter->second.size()))
- return iter->second[formNo];
- }
-
- return n == 1 ? singular : plural; //fallback
- }
-
-private:
- typedef std::map<std::wstring, std::wstring> Translation;
- typedef std::map<std::pair<std::wstring, std::wstring>, std::vector<std::wstring> > TranslationPlural;
-
- Translation transMapping; //map original text |-> translation
- TranslationPlural transMappingPl;
- std::unique_ptr<PluralForm> pluralParser;
- wxLanguage langId_;
-};
-
-
-
-FFSLocale::FFSLocale(const wxString& filename, wxLanguage languageId) : langId_(languageId) //throw (lngfile::ParsingError, PluralForm::ParsingError)
-{
- std::string inputStream;
- try
- {
- inputStream = loadStream(filename);; //throw XmlFileError
- }
- catch (...)
- {
- throw lngfile::ParsingError(0, 0);
- }
-
- lngfile::TransHeader header;
- lngfile::TranslationMap transInput;
- lngfile::TranslationPluralMap transPluralInput;
- lngfile::parseLng(inputStream, header, transInput, transPluralInput); //throw ParsingError
-
- for (lngfile::TranslationMap::const_iterator i = transInput.begin(); i != transInput.end(); ++i)
- {
- const std::wstring original = utf8CvrtTo<std::wstring>(i->first);
- const std::wstring translation = utf8CvrtTo<std::wstring>(i->second);
- assert(!translation.empty());
- transMapping.insert(std::make_pair(original , translation));
- }
-
- for (lngfile::TranslationPluralMap::const_iterator i = transPluralInput.begin(); i != transPluralInput.end(); ++i)
- {
- const std::wstring singular = utf8CvrtTo<std::wstring>(i->first.first);
- const std::wstring plural = utf8CvrtTo<std::wstring>(i->first.second);
- const lngfile::PluralForms& plForms = i->second;
-
- std::vector<std::wstring> plFormsWide;
- for (lngfile::PluralForms::const_iterator j = plForms.begin(); j != plForms.end(); ++j)
- plFormsWide.push_back(utf8CvrtTo<std::wstring>(*j));
-
- assert(!plFormsWide.empty());
-
- transMappingPl.insert(std::make_pair(std::make_pair(singular, plural), plFormsWide));
- }
-
- pluralParser.reset(new PluralForm(header.pluralDefinition.c_str())); //throw PluralForm::ParsingError
-}
-}
-
-
-class FindLngfiles : public zen::TraverseCallback
-{
-public:
- FindLngfiles(std::vector<Zstring>& lngFiles) : lngFiles_(lngFiles) {}
-
- virtual void onFile(const Zchar* shortName, const Zstring& fullName, const FileInfo& details)
- {
- if (endsWith(fullName, Zstr(".lng")))
- lngFiles_.push_back(fullName);
- }
-
- virtual void onSymlink(const Zchar* shortName, const Zstring& fullName, const SymlinkInfo& details) {}
- virtual ReturnValDir onDir(const Zchar* shortName, const Zstring& fullName) { return Loki::Int2Type<ReturnValDir::TRAVERSING_DIR_IGNORE>(); }
- virtual HandleError onError(const std::wstring& errorText) { return TRAV_ERROR_IGNORE; } //errors are not really critical in this context
-
-private:
- std::vector<Zstring>& lngFiles_;
-};
-
-
-struct LessTranslation : public std::binary_function<ExistingTranslations::Entry, ExistingTranslations::Entry, bool>
-{
- bool operator()(const ExistingTranslations::Entry& lhs, const ExistingTranslations::Entry& rhs) const
- {
-#ifdef FFS_WIN
- //use a more "natural" sort, that is ignore case and diacritics
- const int rv = ::CompareString(LOCALE_USER_DEFAULT, //__in LCID Locale,
- NORM_IGNORECASE, //__in DWORD dwCmpFlags,
- lhs.languageName.c_str(), //__in LPCTSTR lpString1,
- static_cast<int>(lhs.languageName.size()), //__in int cchCount1,
- rhs.languageName.c_str(), //__in LPCTSTR lpString2,
- static_cast<int>(rhs.languageName.size())); //__in int cchCount2
- if (rv == 0)
- throw std::runtime_error("Error comparing strings!");
- else
- return rv == CSTR_LESS_THAN; //convert to C-style string compare result
-#else
- return lhs.languageName < rhs.languageName;
-#endif
- }
-};
-
-
-ExistingTranslations::ExistingTranslations()
-{
- {
- //default entry:
- ExistingTranslations::Entry newEntry;
- newEntry.languageID = wxLANGUAGE_ENGLISH_US;
- newEntry.languageName = wxT("English (US)");
- newEntry.languageFile = wxT("");
- newEntry.translatorName = wxT("ZenJu");
- newEntry.languageFlag = wxT("usa.png");
- locMapping.push_back(newEntry);
- }
-
- //search language files available
- std::vector<Zstring> lngFiles;
- FindLngfiles traverseCallback(lngFiles);
-
- traverseFolder(toZ(zen::getResourceDir() + wxT("Languages")), //throw();
- false, //don't follow symlinks
- traverseCallback);
-
- for (auto i = lngFiles.begin(); i != lngFiles.end(); ++i)
- {
- try
- {
- std::string stream = loadStream(*i);; //throw XmlFileError
- try
- {
- lngfile::TransHeader lngHeader;
- lngfile::parseHeader(stream, lngHeader); //throw ParsingError
-
- const wxLanguageInfo* locInfo = wxLocale::FindLanguageInfo(utf8CvrtTo<wxString>(lngHeader.localeName));
- if (locInfo)
- {
- ExistingTranslations::Entry newEntry;
- newEntry.languageID = locInfo->Language;
- newEntry.languageName = utf8CvrtTo<wxString>(lngHeader.languageName);
- newEntry.languageFile = toWx(*i);
- newEntry.translatorName = utf8CvrtTo<wxString>(lngHeader.translatorName);
- newEntry.languageFlag = utf8CvrtTo<wxString>(lngHeader.flagFile);
- locMapping.push_back(newEntry);
- }
- }
- catch (lngfile::ParsingError&) {}
- }
- catch (...) {}
- }
-
- std::sort(locMapping.begin(), locMapping.end(), LessTranslation());
-}
-
-
-namespace
-{
-wxLanguage mapLanguageDialect(wxLanguage language)
-{
- switch (static_cast<int>(language)) //map language dialects
- {
- //variants of wxLANGUAGE_GERMAN
- case wxLANGUAGE_GERMAN_AUSTRIAN:
- case wxLANGUAGE_GERMAN_BELGIUM:
- case wxLANGUAGE_GERMAN_LIECHTENSTEIN:
- case wxLANGUAGE_GERMAN_LUXEMBOURG:
- case wxLANGUAGE_GERMAN_SWISS:
- return wxLANGUAGE_GERMAN;
-
- //variants of wxLANGUAGE_FRENCH
- case wxLANGUAGE_FRENCH_BELGIAN:
- case wxLANGUAGE_FRENCH_CANADIAN:
- case wxLANGUAGE_FRENCH_LUXEMBOURG:
- case wxLANGUAGE_FRENCH_MONACO:
- case wxLANGUAGE_FRENCH_SWISS:
- return wxLANGUAGE_FRENCH;
-
- //variants of wxLANGUAGE_DUTCH
- case wxLANGUAGE_DUTCH_BELGIAN:
- return wxLANGUAGE_DUTCH;
-
- //variants of wxLANGUAGE_ITALIAN
- case wxLANGUAGE_ITALIAN_SWISS:
- return wxLANGUAGE_ITALIAN;
-
- //variants of wxLANGUAGE_CHINESE_SIMPLIFIED
- case wxLANGUAGE_CHINESE:
- case wxLANGUAGE_CHINESE_SINGAPORE:
- return wxLANGUAGE_CHINESE_SIMPLIFIED;
-
- //variants of wxLANGUAGE_CHINESE_TRADITIONAL
- case wxLANGUAGE_CHINESE_TAIWAN:
- case wxLANGUAGE_CHINESE_HONGKONG:
- case wxLANGUAGE_CHINESE_MACAU:
- return wxLANGUAGE_CHINESE_TRADITIONAL;
-
- //variants of wxLANGUAGE_RUSSIAN
- case wxLANGUAGE_RUSSIAN_UKRAINE:
- return wxLANGUAGE_RUSSIAN;
-
- //variants of wxLANGUAGE_SPANISH
- case wxLANGUAGE_SPANISH_ARGENTINA:
- case wxLANGUAGE_SPANISH_BOLIVIA:
- case wxLANGUAGE_SPANISH_CHILE:
- case wxLANGUAGE_SPANISH_COLOMBIA:
- case wxLANGUAGE_SPANISH_COSTA_RICA:
- case wxLANGUAGE_SPANISH_DOMINICAN_REPUBLIC:
- case wxLANGUAGE_SPANISH_ECUADOR:
- case wxLANGUAGE_SPANISH_EL_SALVADOR:
- case wxLANGUAGE_SPANISH_GUATEMALA:
- case wxLANGUAGE_SPANISH_HONDURAS:
- case wxLANGUAGE_SPANISH_MEXICAN:
- case wxLANGUAGE_SPANISH_MODERN:
- case wxLANGUAGE_SPANISH_NICARAGUA:
- case wxLANGUAGE_SPANISH_PANAMA:
- case wxLANGUAGE_SPANISH_PARAGUAY:
- case wxLANGUAGE_SPANISH_PERU:
- case wxLANGUAGE_SPANISH_PUERTO_RICO:
- case wxLANGUAGE_SPANISH_URUGUAY:
- case wxLANGUAGE_SPANISH_US:
- case wxLANGUAGE_SPANISH_VENEZUELA:
- return wxLANGUAGE_SPANISH;
-
- //variants of wxLANGUAGE_SWEDISH
- case wxLANGUAGE_SWEDISH_FINLAND:
- return wxLANGUAGE_SWEDISH;
-
- //case wxLANGUAGE_CZECH:
- //case wxLANGUAGE_DANISH:
- //case wxLANGUAGE_FINNISH:
- //case wxLANGUAGE_GREEK:
- //case wxLANGUAGE_JAPANESE:
- //case wxLANGUAGE_POLISH:
- //case wxLANGUAGE_SLOVENIAN:
- //case wxLANGUAGE_HUNGARIAN:
- //case wxLANGUAGE_PORTUGUESE:
- //case wxLANGUAGE_PORTUGUESE_BRAZILIAN:
- //case wxLANGUAGE_KOREAN:
- //case wxLANGUAGE_UKRAINIAN:
-
- //variants of wxLANGUAGE_ARABIC
- case wxLANGUAGE_ARABIC_ALGERIA:
- case wxLANGUAGE_ARABIC_BAHRAIN:
- case wxLANGUAGE_ARABIC_EGYPT:
- case wxLANGUAGE_ARABIC_IRAQ:
- case wxLANGUAGE_ARABIC_JORDAN:
- case wxLANGUAGE_ARABIC_KUWAIT:
- case wxLANGUAGE_ARABIC_LEBANON:
- case wxLANGUAGE_ARABIC_LIBYA:
- case wxLANGUAGE_ARABIC_MOROCCO:
- case wxLANGUAGE_ARABIC_OMAN:
- case wxLANGUAGE_ARABIC_QATAR:
- case wxLANGUAGE_ARABIC_SAUDI_ARABIA:
- case wxLANGUAGE_ARABIC_SUDAN:
- case wxLANGUAGE_ARABIC_SYRIA:
- case wxLANGUAGE_ARABIC_TUNISIA:
- case wxLANGUAGE_ARABIC_UAE:
- case wxLANGUAGE_ARABIC_YEMEN:
- return wxLANGUAGE_ARABIC;
-
- //variants of wxLANGUAGE_ENGLISH_UK
- case wxLANGUAGE_ENGLISH_AUSTRALIA:
- case wxLANGUAGE_ENGLISH_NEW_ZEALAND:
- case wxLANGUAGE_ENGLISH_TRINIDAD:
- case wxLANGUAGE_ENGLISH_CARIBBEAN:
- case wxLANGUAGE_ENGLISH_JAMAICA:
- case wxLANGUAGE_ENGLISH_BELIZE:
- case wxLANGUAGE_ENGLISH_EIRE:
- case wxLANGUAGE_ENGLISH_SOUTH_AFRICA:
- case wxLANGUAGE_ENGLISH_ZIMBABWE:
- case wxLANGUAGE_ENGLISH_BOTSWANA:
- case wxLANGUAGE_ENGLISH_DENMARK:
- return wxLANGUAGE_ENGLISH_UK;
-
- default:
- return language;
- }
-}
-}
-
-
-class CustomLocale
-{
-public:
- CustomLocale(int selectedLng)
- {
- const wxLanguageInfo* sysLngInfo = wxLocale::GetLanguageInfo(wxLocale::GetSystemLanguage());
- const wxLanguageInfo* selLngInfo = wxLocale::GetLanguageInfo(selectedLng);
-
- bool sysLangIsRTL = sysLngInfo ? sysLngInfo->LayoutDirection == wxLayout_RightToLeft : false;
- bool selectedLangIsRTL = selLngInfo ? selLngInfo->LayoutDirection == wxLayout_RightToLeft : false;
-
- if (sysLangIsRTL == selectedLangIsRTL)
- loc.Init(wxLANGUAGE_DEFAULT); //use sys-lang to preserve sub-language specific rules (e.g. german swiss number punctation)
- else
- loc.Init(selectedLng);
-
- //::setlocale (LC_ALL, ""); -> implicitly called by wxLocale
- const lconv* localInfo = ::localeconv();
-
- //actually these two parameters are language dependent, but we take system setting to handle all kinds of language derivations
- THOUSANDS_SEPARATOR = utf8CvrtTo<wxString>(localInfo->thousands_sep);
-
- // why not working?
- // THOUSANDS_SEPARATOR = std::use_facet<std::numpunct<wchar_t> >(std::locale("")).thousands_sep();
- // DECIMAL_POINT = std::use_facet<std::numpunct<wchar_t> >(std::locale("")).decimal_point();
- }
-private:
- wxLocale loc; //required for RTL language support (and nothing else)
-};
-
-
-void zen::setLanguage(int language)
-{
- //(try to) retrieve language file
- wxString languageFile;
- for (std::vector<ExistingTranslations::Entry>::const_iterator i = ExistingTranslations::get().begin(); i != ExistingTranslations::get().end(); ++i)
- if (i->languageID == language)
- {
- languageFile = i->languageFile;
- break;
- }
-
-
- //handle RTL swapping: we need wxWidgets to do this
- static std::unique_ptr<CustomLocale> dummy;
- dummy.reset(); //avoid global locale lifetime overlap! wxWidgets cannot handle this and will crash!
- dummy.reset(new CustomLocale(languageFile.empty() ? wxLANGUAGE_ENGLISH : language));
-
-
- //reset to english language; in case of error show error message just once
- zen::setTranslator();
-
- //load language file into buffer
- if (!languageFile.empty()) //if languageFile is empty texts will be english per default
- {
- try
- {
- zen::setTranslator(new FFSLocale(languageFile, static_cast<wxLanguage>(language))); //throw (lngfile::ParsingError, PluralForm::ParsingError)
- }
- catch (lngfile::ParsingError& e)
- {
- wxMessageBox(wxString(_("Error reading file:")) + wxT(" \"") + languageFile + wxT("\"") + wxT("\n\n") +
- wxT("Row: ") + zen::toStringSep(e.row) + wxT("\n") +
- wxT("Column: ") + zen::toStringSep(e.col) + wxT("\n"), _("Error"), wxOK | wxICON_ERROR);
- }
- catch (PluralForm::ParsingError&)
- {
- wxMessageBox(wxT("Invalid Plural Form"), _("Error"), wxOK | wxICON_ERROR);
- }
- }
-}
-
-
-
-int zen::getLanguage()
-{
- FFSLocale* loc = dynamic_cast<FFSLocale*>(zen::getTranslator());
- return loc ? loc->langId() : wxLANGUAGE_ENGLISH_US;
-}
-
-
-int zen::retrieveSystemLanguage()
-{
- return mapLanguageDialect(static_cast<wxLanguage>(wxLocale::GetSystemLanguage()));
-}
-
-
-const std::vector<ExistingTranslations::Entry>& ExistingTranslations::get()
-{
- static ExistingTranslations instance;
- return instance.locMapping;
-}
bgstack15