Page MenuHomePhabricator (Chris)

No OneTemporary

Authored By
Unknown
Size
62 KB
Referenced Files
None
Subscribers
None
diff --git a/src/OptionsMenu.cpp b/src/OptionsMenu.cpp
index 8663e0d..aadeb4b 100644
--- a/src/OptionsMenu.cpp
+++ b/src/OptionsMenu.cpp
@@ -1,574 +1,574 @@
/*
* Copyright (C) 2011-2013 Me and My Shadow
*
* This file is part of Me and My Shadow.
*
* Me and My Shadow is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Me and My Shadow is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Me and My Shadow. If not, see <http://www.gnu.org/licenses/>.
*/
#include "Functions.h"
#include "GameState.h"
#include "OptionsMenu.h"
#include "ThemeManager.h"
#include "GUIListBox.h"
#include "GUISlider.h"
#include "InputManager.h"
#include "LevelPackManager.h"
#include "StatisticsManager.h"
#include "MusicManager.h"
#include "SoundManager.h"
#include <iostream>
#include <sstream>
#include "libs/tinygettext/tinygettext.hpp"
using namespace std;
/////////////////////////OPTIONS_MENU//////////////////////////////////
//Some variables for the options.
static bool fullscreen,internet,fade,quickrec;
static string themeName,languageName;
static int lastLang,lastRes;
static bool useProxy;
static string internetProxy;
static bool restartFlag;
static _res currentRes;
static vector<_res> resolutionList;
Options::Options(ImageManager& imageManager,SDL_Renderer& renderer){
//Render the title.
title = titleTextureFromText(renderer, _("Settings"), objThemes.getTextColor(false), SCREEN_WIDTH);
//Initialize variables.
lastJumpSound=0;
clearIconHower=false;
section = 2;
section2 = 1;
//Load icon image and tooltip text.
clearIcon=imageManager.loadTexture(getDataPath()+"gfx/menu/clear-progress.png",renderer);
/// TRANSLATORS: Used for button which clear any level progress like unlocked levels and highscores.
clearTooltip=textureFromText(renderer, *fontText, _("Clear Progress"), objThemes.getTextColor(true));
//Set some default settings.
fullscreen=getSettings()->getBoolValue("fullscreen");
languageName=getSettings()->getValue("lang");
themeName=processFileName(getSettings()->getValue("theme"));
internet=getSettings()->getBoolValue("internet");
internetProxy=getSettings()->getValue("internet-proxy");
useProxy=!internetProxy.empty();
fade=getSettings()->getBoolValue("fading");
quickrec=getSettings()->getBoolValue("quickrecord");
//Set the restartFlag false.
restartFlag=false;
//Now create the gui.
createGUI(imageManager,renderer);
}
Options::~Options(){
//Delete the GUI.
if(GUIObjectRoot){
delete GUIObjectRoot;
GUIObjectRoot=NULL;
}
}
void Options::createGUI(ImageManager& imageManager,SDL_Renderer& renderer){
//Variables for positioning
const int columnW=SCREEN_WIDTH*0.3;
const int column1X=SCREEN_WIDTH*0.15;
const int column2X=SCREEN_WIDTH*0.55;
const int lineHeight=40;
//Create the root element of the GUI.
if(GUIObjectRoot){
delete GUIObjectRoot;
GUIObjectRoot=NULL;
}
GUIObjectRoot=new GUIObject(imageManager,renderer,0,0,SCREEN_WIDTH,SCREEN_HEIGHT);
//Single line list for different tabs.
GUISingleLineListBox* listBox=new GUISingleLineListBox(imageManager,renderer,(SCREEN_WIDTH-500)/2,104,500,32);
listBox->addItem(_("General"));
listBox->addItem(_("Controls"));
listBox->value=0;
listBox->name="lstTabs";
listBox->eventCallback=this;
GUIObjectRoot->addChild(listBox);
//Create general tab.
tabGeneral=new GUIObject(imageManager,renderer,0,150,SCREEN_WIDTH,SCREEN_HEIGHT);
GUIObjectRoot->addChild(tabGeneral);
//Now we create GUIObjects for every option.
GUIObject* obj=new GUILabel(imageManager,renderer,column1X,0,columnW,36,_("Music"));
tabGeneral->addChild(obj);
musicSlider=new GUISlider(imageManager,renderer,column2X,0,columnW,36,atoi(getSettings()->getValue("music").c_str()),0,128,15);
musicSlider->name="sldMusic";
musicSlider->eventCallback=this;
tabGeneral->addChild(musicSlider);
obj=new GUILabel(imageManager,renderer,column1X,lineHeight,columnW,36,_("Sound"));
tabGeneral->addChild(obj);
soundSlider=new GUISlider(imageManager,renderer,column2X,lineHeight,columnW,36,atoi(getSettings()->getValue("sound").c_str()),0,128,15);
soundSlider->name="sldSound";
soundSlider->eventCallback=this;
tabGeneral->addChild(soundSlider);
obj=new GUILabel(imageManager,renderer,column1X,2*lineHeight,columnW,36,_("Resolution"));
obj->name="lstResolution";
tabGeneral->addChild(obj);
//Create list with many different resolutions.
resolutions = new GUISingleLineListBox(imageManager,renderer,column2X,2*lineHeight,columnW,36);
resolutions->value=-1;
//Only get the resolution list if it hasn't been done before.
if(resolutionList.empty()){
resolutionList=getResolutionList();
}
//Get current resolution from config file. Thus it can be user defined.
currentRes.w=atoi(getSettings()->getValue("width").c_str());
currentRes.h=atoi(getSettings()->getValue("height").c_str());
for(int i=0; i<(int)resolutionList.size();i++){
//Create a string from width and height and then add it to list.
ostringstream out;
out << resolutionList[i].w << "x" << resolutionList[i].h;
resolutions->addItem(out.str());
//Check if current resolution matches, select it.
if(resolutionList[i].w==currentRes.w && resolutionList[i].h==currentRes.h){
resolutions->value=i;
}
}
//Add current resolution if it isn't already in the list.
if(resolutions->value==-1){
ostringstream out;
out << currentRes.w << "x" << currentRes.h;
resolutions->addItem(out.str());
resolutions->value=resolutions->item.size()-1;
}
lastRes=resolutions->value;
tabGeneral->addChild(resolutions);
obj=new GUILabel(imageManager,renderer,column1X,3*lineHeight,columnW,36,_("Language"));
tabGeneral->addChild(obj);
//Create GUI list with available languages.
langs = new GUISingleLineListBox(imageManager,renderer,column2X,3*lineHeight,columnW,36);
langs->name="lstLanguages";
/// TRANSLATORS: as detect user's language automatically
langs->addItem("",_("Auto-Detect"));
langs->addItem("en","English");
//Get a list of every available language.
set<tinygettext::Language> languages = dictionaryManager->get_languages();
for (set<tinygettext::Language>::iterator s0 = languages.begin(); s0 != languages.end(); ++s0){
//If language in loop is the same in config file, then select it
if(getSettings()->getValue("lang")==s0->str()){
lastLang=distance(languages.begin(),s0)+2;
}
//Add language in loop to list and listbox.
- langs->addItem(s0->str(),s0->get_name());
+ langs->addItem(s0->str(),s0->get_localized_name());
}
//If Auto or English are selected.
if(getSettings()->getValue("lang")==""){
lastLang=0;
}else if(getSettings()->getValue("lang")=="en"){
lastLang=1;
}
langs->value=lastLang;
tabGeneral->addChild(langs);
obj=new GUILabel(imageManager,renderer,column1X,4*lineHeight,columnW,36,_("Theme"));
obj->name="theme";
tabGeneral->addChild(obj);
//Create the theme option gui element.
theme=new GUISingleLineListBox(imageManager,renderer,column2X,4*lineHeight,columnW,36);
theme->name="lstTheme";
//Vector containing the theme locations and names.
vector<pair<string,string> > themes;
vector<string> v=enumAllDirs(getUserPath(USER_DATA)+"themes/");
for(vector<string>::iterator i=v.begin(); i!=v.end(); ++i){
string location=getUserPath(USER_DATA)+"themes/"+*i;
themes.push_back(pair<string,string>(location,*i));
}
vector<string> v2=enumAllDirs(getDataPath()+"themes/");
for(vector<string>::iterator i=v2.begin(); i!=v2.end(); ++i){
string location=getDataPath()+"themes/"+*i;
themes.push_back(pair<string,string>(location,*i));
}
//Try to find the configured theme so we can display it.
int value=-1;
for(vector<pair<string,string> >::iterator i=themes.begin(); i!=themes.end(); ++i){
if(i->first==themeName) {
value=i-themes.begin();
}
}
theme->addItems(themes);
if(value==-1)
value=theme->item.size()-1;
theme->value=value;
//NOTE: We call the event handling method to correctly set the themename.
GUIEventCallback_OnEvent(imageManager,renderer,"lstTheme",theme,GUIEventChange);
theme->eventCallback=this;
tabGeneral->addChild(theme);
//Proxy settings.
obj=new GUILabel(imageManager,renderer,column1X,5*lineHeight,columnW,36,_("Internet proxy"));
obj->name="chkProxy";
obj->eventCallback=this;
tabGeneral->addChild(obj);
obj=new GUITextBox(imageManager,renderer,column2X,5*lineHeight,columnW,36,internetProxy.c_str());
obj->name="txtProxy";
obj->eventCallback=this;
tabGeneral->addChild(obj);
obj=new GUICheckBox(imageManager,renderer,column1X,6*lineHeight,columnW,36,_("Fullscreen"),fullscreen?1:0);
obj->name="chkFullscreen";
obj->eventCallback=this;
tabGeneral->addChild(obj);
obj = new GUICheckBox(imageManager, renderer, column1X, 7 * lineHeight, columnW, 36, _("Quick record"), quickrec ? 1 : 0);
obj->name = "chkQuickRec";
obj->eventCallback = this;
tabGeneral->addChild(obj);
obj=new GUICheckBox(imageManager,renderer,column2X,6*lineHeight,columnW,36,_("Internet"),internet?1:0);
obj->name="chkInternet";
obj->eventCallback=this;
tabGeneral->addChild(obj);
obj=new GUICheckBox(imageManager,renderer,column2X,7*lineHeight,columnW,36,_("Fade transition"),fade?1:0);
obj->name="chkFade";
obj->eventCallback=this;
tabGeneral->addChild(obj);
//Create the controls tab.
tabControls=inputMgr.showConfig(imageManager,renderer,SCREEN_HEIGHT-210);
tabControls->top=140;
tabControls->visible=false;
GUIObjectRoot->addChild(tabControls);
//Save original keys.
for(int i=0;i<INPUTMGR_MAX;i++){
tmpKeys[i]=inputMgr.getKeyCode((InputManagerKeys)i,false);
tmpAlternativeKeys[i]=inputMgr.getKeyCode((InputManagerKeys)i,true);
}
//Create buttons.
cmdBack = new GUIButton(imageManager, renderer, SCREEN_WIDTH*0.3, SCREEN_HEIGHT - 60, -1, 36, _("Cancel"), 0, true, true, GUIGravityCenter);
cmdBack->name = "cmdBack";
cmdBack->eventCallback = this;
GUIObjectRoot->addChild(cmdBack);
cmdSave = new GUIButton(imageManager, renderer, SCREEN_WIDTH*0.7, SCREEN_HEIGHT - 60, -1, 36, _("Save Changes"), 0, true, true, GUIGravityCenter);
cmdSave->name = "cmdSave";
cmdSave->eventCallback = this;
GUIObjectRoot->addChild(cmdSave);
}
static string convertInt(int i){
stringstream ss;
ss << i;
return ss.str();
}
void Options::GUIEventCallback_OnEvent(ImageManager& imageManager, SDL_Renderer& renderer, std::string name,GUIObject* obj,int eventType){
//Check what type of event it was.
if(eventType==GUIEventClick){
if(name=="cmdBack"){
//Reset the key changes.
for(int i=0;i<INPUTMGR_MAX;i++){
inputMgr.setKeyCode((InputManagerKeys)i,tmpKeys[i],false);
inputMgr.setKeyCode((InputManagerKeys)i,tmpAlternativeKeys[i],true);
}
//Reset the music volume.
getMusicManager()->setVolume(atoi(getSettings()->getValue("music").c_str()));
Mix_Volume(-1,atoi(getSettings()->getValue("sound").c_str()));
//And goto the main menu.
setNextState(STATE_MENU);
}else if(name=="cmdSave"){
//Save is pressed thus save
char s[64];
sprintf(s,"%d",soundSlider->value);
getSettings()->setValue("sound",s);
sprintf(s,"%d",musicSlider->value);
getSettings()->setValue("music",s);
getMusicManager()->setEnabled(musicSlider->value>0);
Mix_Volume(-1,soundSlider->value);
getSettings()->setValue("fullscreen",fullscreen?"1":"0");
getSettings()->setValue("internet",internet?"1":"0");
getSettings()->setValue("theme",themeName);
getSettings()->setValue("fading",fade?"1":"0");
getSettings()->setValue("quickrecord",quickrec?"1":"0");
//Before loading the theme remove the previous one from the stack.
objThemes.removeTheme();
loadTheme(imageManager,renderer,themeName);
if(!useProxy)
internetProxy.clear();
getSettings()->setValue("internet-proxy",internetProxy);
getSettings()->setValue("lang",langs->getName());
//Is resolution from the list or is it user defined in config file
if(resolutions->value<(int)resolutionList.size()){
getSettings()->setValue("width",convertInt(resolutionList[resolutions->value].w));
getSettings()->setValue("height",convertInt(resolutionList[resolutions->value].h));
}else{
getSettings()->setValue("width",convertInt(currentRes.w));
getSettings()->setValue("height",convertInt(currentRes.h));
}
//Save the key configuration.
inputMgr.saveConfig();
//Save the settings.
saveSettings();
//Before we return check if some .
if(restartFlag || resolutions->value!=lastRes){
//The resolution changed so we need to recreate the screen.
if(!createScreen()){
//Screen creation failed so set to safe settings.
getSettings()->setValue("fullscreen","0");
getSettings()->setValue("width",convertInt(resolutionList[lastRes].w));
getSettings()->setValue("height",convertInt(resolutionList[lastRes].h));
if(!createScreen()){
//Everything fails so quit.
setNextState(STATE_EXIT);
return;
}
}
//The screen is created, now load the (menu) theme.
if(!loadTheme(imageManager,renderer,"")){
//Loading the theme failed so quit.
setNextState(STATE_EXIT);
return;
}
}
if(langs->value!=lastLang){
//We set the language.
language=langs->getName();
dictionaryManager->set_language(tinygettext::Language::from_name(language));
getLevelPackManager()->updateLanguage();
//And reload the font.
if(!loadFonts()){
//Loading failed so quit.
setNextState(STATE_EXIT);
return;
}
}
//Now return to the main menu.
setNextState(STATE_MENU);
}else if(name=="chkFullscreen"){
fullscreen=obj->value?true:false;
//Check if fullscreen changed.
if(fullscreen==getSettings()->getBoolValue("fullscreen")){
//We disable the restart message flag.
restartFlag=false;
}else{
//We set the restart message flag.
restartFlag=true;
}
}else if(name=="chkInternet"){
internet=obj->value?true:false;
}else if(name=="chkProxy"){
useProxy=obj->value?true:false;
}else if(name=="chkFade"){
fade=obj->value?true:false;
}else if(name=="chkQuickRec"){
quickrec=obj->value?true:false;
}
}
if(name=="lstTheme"){
if(theme!=NULL && theme->value>=0 && theme->value<(int)theme->item.size()){
//Convert the themeName to contain %DATA%, etc...
themeName=compressFileName(theme->item[theme->value].first);
}
}else if(name=="txtProxy"){
internetProxy=obj->caption;
//Check if the internetProxy field is empty.
useProxy=!internetProxy.empty();
}else if(name=="sldMusic"){
getMusicManager()->setEnabled(musicSlider->value>0);
getMusicManager()->setVolume(musicSlider->value);
}else if(name=="sldSound"){
Mix_Volume(-1,soundSlider->value);
if(lastJumpSound==0){
getSoundManager()->playSound("jump");
lastJumpSound=15;
}
}
if(name=="lstTabs"){
if(obj->value==0){
tabGeneral->visible=true;
tabControls->visible=false;
}else{
tabGeneral->visible=false;
tabControls->visible=true;
}
}
}
void Options::handleEvents(ImageManager& imageManager, SDL_Renderer& renderer){
//Check keyboard navigation.
if (tabGeneral && tabGeneral->visible) {
if (inputMgr.isKeyDownEvent(INPUTMGR_TAB)) {
isKeyboardOnly = true;
section = (section == 2) ? 3 : 2;
//Update selection.
if (section == 2) {
tabGeneral->selectNextControl(1, -1);
} else {
tabGeneral->setSelectedControl(-1);
}
}
if (section == 2) {
tabGeneral->handleKeyboardNavigationEvents(imageManager, renderer, UpDownFocus | ReturnControls | LeftRightControls);
} else if (section == 3) {
if (inputMgr.isKeyDownEvent(INPUTMGR_DOWN) || inputMgr.isKeyDownEvent(INPUTMGR_RIGHT)) {
isKeyboardOnly = true;
section2++;
if (section2 > 3) section2 = 1;
} else if (inputMgr.isKeyDownEvent(INPUTMGR_UP) || inputMgr.isKeyDownEvent(INPUTMGR_LEFT)) {
isKeyboardOnly = true;
section2--;
if (section2 < 1) section2 = 3;
}
if (isKeyboardOnly && inputMgr.isKeyDownEvent(INPUTMGR_SELECT) && section == 3) {
if (section2 == 1) {
GUIEventCallback_OnEvent(imageManager, renderer, cmdBack->name, cmdBack, GUIEventClick);
} else if (section2 == 2) {
GUIEventCallback_OnEvent(imageManager, renderer, cmdSave->name, cmdSave, GUIEventClick);
}
}
}
}
//Process mouse event only when it's not keyboard only mode.
if (!isKeyboardOnly) {
//Get the x and y location of the mouse.
int x, y;
SDL_GetMouseState(&x, &y);
//Check icon.
if (event.type == SDL_MOUSEMOTION || event.type == SDL_MOUSEBUTTONDOWN){
if (y >= SCREEN_HEIGHT - 56 && y < SCREEN_HEIGHT - 8 && x >= SCREEN_WIDTH - 56)
clearIconHower = true;
else
clearIconHower = false;
}
}
//Update highlight on keyboard only mode.
if (isKeyboardOnly) {
cmdBack->state = (section == 3 && section2 == 1) ? 1 : 0;
cmdSave->state = (section == 3 && section2 == 2) ? 1 : 0;
clearIconHower = (section == 3 && section2 == 3);
}
if ((isKeyboardOnly ? inputMgr.isKeyDownEvent(INPUTMGR_SELECT) :
(event.type == SDL_MOUSEBUTTONUP && event.button.button == SDL_BUTTON_LEFT)) && clearIconHower)
{
if(msgBox(imageManager,renderer,_("Do you really want to reset level progress?"),MsgBoxYesNo,_("Warning"))==MsgBoxYes){
//We delete the progress folder.
#ifdef WIN32
removeDirectory((getUserPath()+"progress").c_str());
createDirectory((getUserPath()+"progress").c_str());
#else
removeDirectory((getUserPath(USER_DATA)+"/progress").c_str());
createDirectory((getUserPath(USER_DATA)+"/progress").c_str());
#endif
//Reset statistics.
statsMgr.reloadCompletedLevelsAndAchievements();
}
}
//Check if we need to quit, if so enter the exit state.
if(event.type==SDL_QUIT){
setNextState(STATE_EXIT);
}
//Check if the escape button is pressed, if so go back to the main menu.
if (inputMgr.isKeyDownEvent(INPUTMGR_ESCAPE) && (tabControls == NULL || !tabControls->visible)) {
setNextState(STATE_MENU);
}
}
void Options::logic(ImageManager&, SDL_Renderer&){
//Increase the lastJumpSound variable if needed.
if(lastJumpSound!=0){
lastJumpSound--;
}
}
void Options::render(ImageManager&, SDL_Renderer& renderer){
//Draw background.
objThemes.getBackground(true)->draw(renderer);
objThemes.getBackground(true)->updateAnimation();
//Now render the title.
drawTitleTexture(SCREEN_WIDTH, *title, renderer);
//Check if an icon is selected/highlighted and draw tooltip
if(clearIconHower){
const SDL_Rect texSize = rectFromTexture(*clearTooltip);
drawGUIBox(-2,SCREEN_HEIGHT-texSize.h-2,texSize.w+4,texSize.h+4,renderer,0xFFFFFFFF);
applyTexture(0,SCREEN_HEIGHT-texSize.h,clearTooltip,renderer);
}
//Draw border of icon if it's keyboard only mode.
if (isKeyboardOnly && clearIconHower) {
drawGUIBox(SCREEN_WIDTH - 52, SCREEN_HEIGHT - 52, 40, 40, renderer, 0xFFFFFF40);
}
//Draw icon.
applyTexture(SCREEN_WIDTH-48,SCREEN_HEIGHT-48,*clearIcon,renderer);
//NOTE: The rendering of the GUI is done in Main.
}
void Options::resize(ImageManager& imageManager, SDL_Renderer& renderer){
//Recreate the gui to fit the new resolution.
createGUI(imageManager,renderer);
}
diff --git a/src/libs/tinygettext/language.cpp b/src/libs/tinygettext/language.cpp
index 8729190..5ee75b8 100644
--- a/src/libs/tinygettext/language.cpp
+++ b/src/libs/tinygettext/language.cpp
@@ -1,574 +1,590 @@
// tinygettext - A gettext replacement that works directly on .po files
// Copyright (c) 2006 Ingo Ruhnke <grumbel@gmail.com>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgement in the product documentation would be
// appreciated but is not required.
// 2. Altered source versions must be plainly marked as such, and must not be
// misrepresented as being the original software.
// 3. This notice may not be removed or altered from any source distribution.
#include "tinygettext/language.hpp"
#include <assert.h>
#include <unordered_map>
#include <vector>
#include <algorithm>
namespace tinygettext {
struct LanguageSpec {
/** Language code: "de", "en", ... */
const char* language;
/** Country code: "BR", "DE", ..., can be 0 */
const char* country;
/** Modifier/Varint: "Latn", "ije", "latin"..., can be 0 */
const char* modifier;
/** Language name: "German", "English", "French", ... */
const char* name;
+
+ /** Localized language name: "Deutsch", "English", "Français", ... */
+ const char* localized_name;
};
+// NOTE: we have to escape some localized name otherwise VC++ will complain about
+// the erroneous 'error C2001: newline in constant' even in UTF-8 mode
+
/** Language Definitions */
//*{
static const LanguageSpec languages[] = {
- { "aa", 0, 0, "Afar" },
- { "af", 0, 0, "Afrikaans" },
- { "af", "ZA", 0, "Afrikaans (South Africa)" },
- { "am", 0, 0, "Amharic" },
- { "ar", 0, 0, "Arabic" },
- { "ar", "AR", 0, "Arabic (Argentina)" },
- { "ar", "OM", 0, "Arabic (Oman)" },
- { "ar", "SA", 0, "Arabic (Saudi Arabia)" },
- { "ar", "SY", 0, "Arabic (Syrian Arab Republic)" },
- { "ar", "TN", 0, "Arabic (Tunisia)" },
- { "as", 0, 0, "Assamese" },
- { "ast",0, 0, "Asturian" },
- { "ay", 0, 0, "Aymara" },
- { "az", 0, 0, "Azerbaijani" },
- { "az", "IR", 0, "Azerbaijani (Iran)" },
- { "be", 0, 0, "Belarusian" },
- { "be", 0, "latin", "Belarusian" },
- { "bg", 0, 0, "Bulgarian" },
- { "bg", "BG", 0, "Bulgarian (Bulgaria)" },
- { "bn", 0, 0, "Bengali" },
- { "bn", "BD", 0, "Bengali (Bangladesh)" },
- { "bn", "IN", 0, "Bengali (India)" },
- { "bo", 0, 0, "Tibetan" },
- { "br", 0, 0, "Breton" },
- { "bs", 0, 0, "Bosnian" },
- { "bs", "BA", 0, "Bosnian (Bosnia/Herzegovina)"},
- { "bs", "BS", 0, "Bosnian (Bahamas)" },
- { "ca", "ES", "valencia", "Catalan (valencia)" },
- { "ca", "ES", 0, "Catalan (Spain)" },
- { "ca", 0, "valencia", "Catalan (valencia)" },
- { "ca", 0, 0, "Catalan" },
- { "cmn", 0, 0, "Mandarin" },
- { "co", 0, 0, "Corsican" },
- { "cs", 0, 0, "Czech" },
- { "cs", "CZ", 0, "Czech (Czech Republic)" },
- { "cy", 0, 0, "Welsh" },
- { "cy", "GB", 0, "Welsh (Great Britain)" },
- { "cz", 0, 0, "Unknown language" },
- { "da", 0, 0, "Danish" },
- { "da", "DK", 0, "Danish (Denmark)" },
- { "de", 0, 0, "German" },
- { "de", "AT", 0, "German (Austria)" },
- { "de", "CH", 0, "German (Switzerland)" },
- { "de", "DE", 0, "German (Germany)" },
- { "dk", 0, 0, "Unknown language" },
- { "dz", 0, 0, "Dzongkha" },
- { "el", 0, 0, "Greek" },
- { "el", "GR", 0, "Greek (Greece)" },
- { "en", 0, 0, "English" },
- { "en", "AU", 0, "English (Australia)" },
- { "en", "CA", 0, "English (Canada)" },
- { "en", "GB", 0, "English (Great Britain)" },
- { "en", "US", 0, "English (United States)" },
- { "en", "ZA", 0, "English (South Africa)" },
- { "en", 0, "boldquot", "English" },
- { "en", 0, "quot", "English" },
- { "en", "US", "piglatin", "English" },
- { "eo", 0, 0, "Esperanto" },
- { "es", 0, 0, "Spanish" },
- { "es", "AR", 0, "Spanish (Argentina)" },
- { "es", "CL", 0, "Spanish (Chile)" },
- { "es", "CO", 0, "Spanish (Colombia)" },
- { "es", "CR", 0, "Spanish (Costa Rica)" },
- { "es", "DO", 0, "Spanish (Dominican Republic)"},
- { "es", "EC", 0, "Spanish (Ecuador)" },
- { "es", "ES", 0, "Spanish (Spain)" },
- { "es", "GT", 0, "Spanish (Guatemala)" },
- { "es", "HN", 0, "Spanish (Honduras)" },
- { "es", "LA", 0, "Spanish (Laos)" },
- { "es", "MX", 0, "Spanish (Mexico)" },
- { "es", "NI", 0, "Spanish (Nicaragua)" },
- { "es", "PA", 0, "Spanish (Panama)" },
- { "es", "PE", 0, "Spanish (Peru)" },
- { "es", "PR", 0, "Spanish (Puerto Rico)" },
- { "es", "SV", 0, "Spanish (El Salvador)" },
- { "es", "UY", 0, "Spanish (Uruguay)" },
- { "es", "VE", 0, "Spanish (Venezuela)" },
- { "et", 0, 0, "Estonian" },
- { "et", "EE", 0, "Estonian (Estonia)" },
- { "et", "ET", 0, "Estonian (Ethiopia)" },
- { "eu", 0, 0, "Basque" },
- { "eu", "ES", 0, "Basque (Spain)" },
- { "fa", 0, 0, "Persian" },
- { "fa", "AF", 0, "Persian (Afghanistan)" },
- { "fa", "IR", 0, "Persian (Iran)" },
- { "fi", 0, 0, "Finnish" },
- { "fi", "FI", 0, "Finnish (Finland)" },
- { "fo", 0, 0, "Faroese" },
- { "fo", "FO", 0, "Faeroese (Faroe Islands)" },
- { "fr", 0, 0, "French" },
- { "fr", "CA", 0, "French (Canada)" },
- { "fr", "CH", 0, "French (Switzerland)" },
- { "fr", "FR", 0, "French (France)" },
- { "fr", "LU", 0, "French (Luxembourg)" },
- { "fy", 0, 0, "Frisian" },
- { "ga", 0, 0, "Irish" },
- { "gd", 0, 0, "Gaelic Scots" },
- { "gl", 0, 0, "Galician" },
- { "gl", "ES", 0, "Galician (Spain)" },
- { "gn", 0, 0, "Guarani" },
- { "gu", 0, 0, "Gujarati" },
- { "gv", 0, 0, "Manx" },
- { "ha", 0, 0, "Hausa" },
- { "he", 0, 0, "Hebrew" },
- { "he", "IL", 0, "Hebrew (Israel)" },
- { "hi", 0, 0, "Hindi" },
- { "hr", 0, 0, "Croatian" },
- { "hr", "HR", 0, "Croatian (Croatia)" },
- { "hu", 0, 0, "Hungarian" },
- { "hu", "HU", 0, "Hungarian (Hungary)" },
- { "hy", 0, 0, "Armenian" },
- { "ia", 0, 0, "Interlingua" },
- { "id", 0, 0, "Indonesian" },
- { "id", "ID", 0, "Indonesian (Indonesia)" },
- { "is", 0, 0, "Icelandic" },
- { "is", "IS", 0, "Icelandic (Iceland)" },
- { "it", 0, 0, "Italian" },
- { "it", "CH", 0, "Italian (Switzerland)" },
- { "it", "IT", 0, "Italian (Italy)" },
- { "iu", 0, 0, "Inuktitut" },
- { "ja", 0, 0, "Japanese" },
- { "ja", "JP", 0, "Japanese (Japan)" },
- { "ka", 0, 0, "Georgian" },
- { "kk", 0, 0, "Kazakh" },
- { "kl", 0, 0, "Kalaallisut" },
- { "km", 0, 0, "Khmer" },
- { "km", "KH", 0, "Khmer (Cambodia)" },
- { "kn", 0, 0, "Kannada" },
- { "ko", 0, 0, "Korean" },
- { "ko", "KR", 0, "Korean (Korea)" },
- { "ku", 0, 0, "Kurdish" },
- { "kw", 0, 0, "Cornish" },
- { "ky", 0, 0, "Kirghiz" },
- { "la", 0, 0, "Latin" },
- { "lo", 0, 0, "Lao" },
- { "lt", 0, 0, "Lithuanian" },
- { "lt", "LT", 0, "Lithuanian (Lithuania)" },
- { "lv", 0, 0, "Latvian" },
- { "lv", "LV", 0, "Latvian (Latvia)" },
- { "jbo", 0, 0, "Lojban" },
- { "mg", 0, 0, "Malagasy" },
- { "mi", 0, 0, "Maori" },
- { "mk", 0, 0, "Macedonian" },
- { "mk", "MK", 0, "Macedonian (Macedonia)" },
- { "ml", 0, 0, "Malayalam" },
- { "mn", 0, 0, "Mongolian" },
- { "mr", 0, 0, "Marathi" },
- { "ms", 0, 0, "Malay" },
- { "ms", "MY", 0, "Malay (Malaysia)" },
- { "mt", 0, 0, "Maltese" },
- { "my", 0, 0, "Burmese" },
- { "my", "MM", 0, "Burmese (Myanmar)" },
- { "nb", 0, 0, "Norwegian Bokmal" },
- { "nb", "NO", 0, "Norwegian Bokmål (Norway)" },
- { "ne", 0, 0, "Nepali" },
- { "nl", 0, 0, "Dutch" },
- { "nl", "BE", 0, "Dutch (Belgium)" },
- { "nl", "NL", 0, "Dutch (Netherlands)" },
- { "nn", 0, 0, "Norwegian Nynorsk" },
- { "nn", "NO", 0, "Norwegian Nynorsk (Norway)" },
- { "no", 0, 0, "Norwegian" },
- { "no", "NO", 0, "Norwegian (Norway)" },
- { "no", "NY", 0, "Norwegian (NY)" },
- { "nr", 0, 0, "Ndebele, South" },
- { "oc", 0, 0, "Occitan post 1500" },
- { "om", 0, 0, "Oromo" },
- { "or", 0, 0, "Oriya" },
- { "pa", 0, 0, "Punjabi" },
- { "pl", 0, 0, "Polish" },
- { "pl", "PL", 0, "Polish (Poland)" },
- { "ps", 0, 0, "Pashto" },
- { "pt", 0, 0, "Portuguese" },
- { "pt", "BR", 0, "Portuguese (Brazil)" },
- { "pt", "PT", 0, "Portuguese (Portugal)" },
- { "qu", 0, 0, "Quechua" },
- { "rm", 0, 0, "Rhaeto-Romance" },
- { "ro", 0, 0, "Romanian" },
- { "ro", "RO", 0, "Romanian (Romania)" },
- { "ru", 0, 0, "Russian" },
- { "ru", "RU", 0, "Russian (Russia" },
- { "rw", 0, 0, "Kinyarwanda" },
- { "sa", 0, 0, "Sanskrit" },
- { "sd", 0, 0, "Sindhi" },
- { "se", 0, 0, "Sami" },
- { "se", "NO", 0, "Sami (Norway)" },
- { "si", 0, 0, "Sinhalese" },
- { "sk", 0, 0, "Slovak" },
- { "sk", "SK", 0, "Slovak (Slovakia)" },
- { "sl", 0, 0, "Slovenian" },
- { "sl", "SI", 0, "Slovenian (Slovenia)" },
- { "sl", "SL", 0, "Slovenian (Sierra Leone)" },
- { "sm", 0, 0, "Samoan" },
- { "so", 0, 0, "Somali" },
- { "sp", 0, 0, "Unknown language" },
- { "sq", 0, 0, "Albanian" },
- { "sq", "AL", 0, "Albanian (Albania)" },
- { "sr", 0, 0, "Serbian" },
- { "sr", "YU", 0, "Serbian (Yugoslavia)" },
- { "sr", 0,"ije", "Serbian" },
- { "sr", 0, "latin", "Serbian" },
- { "sr", 0, "Latn", "Serbian" },
- { "ss", 0, 0, "Swati" },
- { "st", 0, 0, "Sotho" },
- { "sv", 0, 0, "Swedish" },
- { "sv", "SE", 0, "Swedish (Sweden)" },
- { "sv", "SV", 0, "Swedish (El Salvador)" },
- { "sw", 0, 0, "Swahili" },
- { "ta", 0, 0, "Tamil" },
- { "te", 0, 0, "Telugu" },
- { "tg", 0, 0, "Tajik" },
- { "th", 0, 0, "Thai" },
- { "th", "TH", 0, "Thai (Thailand)" },
- { "ti", 0, 0, "Tigrinya" },
- { "tk", 0, 0, "Turkmen" },
- { "tl", 0, 0, "Tagalog" },
- { "to", 0, 0, "Tonga" },
- { "tr", 0, 0, "Turkish" },
- { "tr", "TR", 0, "Turkish (Turkey)" },
- { "ts", 0, 0, "Tsonga" },
- { "tt", 0, 0, "Tatar" },
- { "ug", 0, 0, "Uighur" },
- { "uk", 0, 0, "Ukrainian" },
- { "uk", "UA", 0, "Ukrainian (Ukraine)" },
- { "ur", 0, 0, "Urdu" },
- { "ur", "PK", 0, "Urdu (Pakistan)" },
- { "uz", 0, 0, "Uzbek" },
- { "uz", 0, "cyrillic", "Uzbek" },
- { "vi", 0, 0, "Vietnamese" },
- { "vi", "VN", 0, "Vietnamese (Vietnam)" },
- { "wa", 0, 0, "Walloon" },
- { "wo", 0, 0, "Wolof" },
- { "xh", 0, 0, "Xhosa" },
- { "yi", 0, 0, "Yiddish" },
- { "yo", 0, 0, "Yoruba" },
- { "zh", 0, 0, "Chinese" },
- { "zh", "CN", 0, "Chinese (simplified)" },
- { "zh", "HK", 0, "Chinese (Hong Kong)" },
- { "zh", "TW", 0, "Chinese (traditional)" },
- { "zu", 0, 0, "Zulu" },
- { NULL, 0, 0, NULL }
+ { "aa", 0, 0, "Afar" , "ʿAfár af" },
+ { "af", 0, 0, "Afrikaans" , "Afrikaans" },
+ { "af", "ZA", 0, "Afrikaans (South Africa)" , 0 },
+ { "am", 0, 0, "Amharic" , "ኣማርኛ" },
+ { "ar", 0, 0, "Arabic" , "العربية" },
+ { "ar", "AR", 0, "Arabic (Argentina)" , 0 },
+ { "ar", "OM", 0, "Arabic (Oman)" , 0 },
+ { "ar", "SA", 0, "Arabic (Saudi Arabia)" , 0 },
+ { "ar", "SY", 0, "Arabic (Syrian Arab Republic)" , 0 },
+ { "ar", "TN", 0, "Arabic (Tunisia)" , 0 },
+ { "as", 0, 0, "Assamese" , "\xE0\xA6\x85\xE0\xA6\xB8\xE0\xA6\xAE\xE0\xA7\x80\xE0\xA6\xAF\xE0\xA6\xBC\xE0\xA6\xBE" },
+ { "ast",0, 0, "Asturian" , "Asturianu" },
+ { "ay", 0, 0, "Aymara" , "Aymar aru" },
+ { "az", 0, 0, "Azerbaijani" , "Azərbaycanca" },
+ { "az", "IR", 0, "Azerbaijani (Iran)" , 0 },
+ { "be", 0, 0, "Belarusian" , "Беларуская мова" },
+ { "be", 0, "latin", "Belarusian" , "Беларуская мова" },
+ { "bg", 0, 0, "Bulgarian" , "български" },
+ { "bg", "BG", 0, "Bulgarian (Bulgaria)" , 0 },
+ { "bn", 0, 0, "Bengali" , "\xE0\xA6\xAC\xE0\xA6\xBE\xE0\xA6\x82\xE0\xA6\xB2\xE0\xA6\xBE" },
+ { "bn", "BD", 0, "Bengali (Bangladesh)" , 0 },
+ { "bn", "IN", 0, "Bengali (India)" , 0 },
+ { "bo", 0, 0, "Tibetan" , "བོད་སྐད་" },
+ { "br", 0, 0, "Breton" , "Brezhoneg" },
+ { "bs", 0, 0, "Bosnian" , "Bosanski" },
+ { "bs", "BA", 0, "Bosnian (Bosnia/Herzegovina)", 0 },
+ { "bs", "BS", 0, "Bosnian (Bahamas)" , 0 },
+ { "ca", "ES", "valencia", "Catalan (valencia)" , 0 },
+ { "ca", "ES", 0, "Catalan (Spain)" , 0 },
+ { "ca", 0, "valencia", "Catalan (valencia)" , 0 },
+ { "ca", 0, 0, "Catalan" , 0 },
+ { "cmn", 0, 0, "Mandarin" , 0 },
+ { "co", 0, 0, "Corsican" , "Corsu" },
+ { "cs", 0, 0, "Czech" , "Čeština" },
+ { "cs", "CZ", 0, "Czech (Czech Republic)" , "Čeština (Česká Republika)" },
+ { "cy", 0, 0, "Welsh" , "Welsh" },
+ { "cy", "GB", 0, "Welsh (Great Britain)" , "Welsh (Great Britain)" },
+ { "cz", 0, 0, "Unknown language" , "Unknown language" },
+ { "da", 0, 0, "Danish" , "Dansk" },
+ { "da", "DK", 0, "Danish (Denmark)" , "Dansk (Danmark)" },
+ { "de", 0, 0, "German" , "Deutsch" },
+ { "de", "AT", 0, "German (Austria)" , "Deutsch (Österreich)" },
+ { "de", "CH", 0, "German (Switzerland)" , "Deutsch (Schweiz)" },
+ { "de", "DE", 0, "German (Germany)" , "Deutsch (Deutschland)" },
+ { "dk", 0, 0, "Unknown language" , "Unknown language" },
+ { "dz", 0, 0, "Dzongkha" , "རྫོང་ཁ" },
+ { "el", 0, 0, "Greek" , "ελληνικά" },
+ { "el", "GR", 0, "Greek (Greece)" , 0 },
+ { "en", 0, 0, "English" , "English" },
+ { "en", "AU", 0, "English (Australia)" , "English (Australia)" },
+ { "en", "CA", 0, "English (Canada)" , "English (Canada)" },
+ { "en", "GB", 0, "English (Great Britain)" , "English (Great Britain)" },
+ { "en", "US", 0, "English (United States)" , "English" },
+ { "en", "ZA", 0, "English (South Africa)" , "English (South Africa)" },
+ { "en", 0, "boldquot", "English" , "English" },
+ { "en", 0, "quot", "English" , "English" },
+ { "en", "US", "piglatin", "English" , "English" },
+ { "eo", 0, 0, "Esperanto" , "Esperanto" },
+ { "es", 0, 0, "Spanish" , "Español" },
+ { "es", "AR", 0, "Spanish (Argentina)" , 0 },
+ { "es", "CL", 0, "Spanish (Chile)" , 0 },
+ { "es", "CO", 0, "Spanish (Colombia)" , 0 },
+ { "es", "CR", 0, "Spanish (Costa Rica)" , 0 },
+ { "es", "DO", 0, "Spanish (Dominican Republic)", 0 },
+ { "es", "EC", 0, "Spanish (Ecuador)" , 0 },
+ { "es", "ES", 0, "Spanish (Spain)" , 0 },
+ { "es", "GT", 0, "Spanish (Guatemala)" , 0 },
+ { "es", "HN", 0, "Spanish (Honduras)" , 0 },
+ { "es", "LA", 0, "Spanish (Laos)" , 0 },
+ { "es", "MX", 0, "Spanish (Mexico)" , 0 },
+ { "es", "NI", 0, "Spanish (Nicaragua)" , 0 },
+ { "es", "PA", 0, "Spanish (Panama)" , 0 },
+ { "es", "PE", 0, "Spanish (Peru)" , 0 },
+ { "es", "PR", 0, "Spanish (Puerto Rico)" , 0 },
+ { "es", "SV", 0, "Spanish (El Salvador)" , 0 },
+ { "es", "UY", 0, "Spanish (Uruguay)" , 0 },
+ { "es", "VE", 0, "Spanish (Venezuela)" , 0 },
+ { "et", 0, 0, "Estonian" , "Eesti keel" },
+ { "et", "EE", 0, "Estonian (Estonia)" , 0 },
+ { "et", "ET", 0, "Estonian (Ethiopia)" , 0 },
+ { "eu", 0, 0, "Basque" , "Euskara" },
+ { "eu", "ES", 0, "Basque (Spain)" , 0 },
+ { "fa", 0, 0, "Persian" , "فارسى" },
+ { "fa", "AF", 0, "Persian (Afghanistan)" , 0 },
+ { "fa", "IR", 0, "Persian (Iran)" , 0 },
+ { "fi", 0, 0, "Finnish" , "Suomi" },
+ { "fi", "FI", 0, "Finnish (Finland)" , 0 },
+ { "fo", 0, 0, "Faroese" , "Føroyskt" },
+ { "fo", "FO", 0, "Faeroese (Faroe Islands)" , 0 },
+ { "fr", 0, 0, "French" , "Français" },
+ { "fr", "CA", 0, "French (Canada)" , "Français (Canada)" },
+ { "fr", "CH", 0, "French (Switzerland)" , "Français (Suisse)" },
+ { "fr", "FR", 0, "French (France)" , "Français (France)" },
+ { "fr", "LU", 0, "French (Luxembourg)" , "Français (Luxembourg)" },
+ { "fy", 0, 0, "Frisian" , "Frysk" },
+ { "ga", 0, 0, "Irish" , "Gaeilge" },
+ { "gd", 0, 0, "Gaelic Scots" , "Gàidhlig" },
+ { "gl", 0, 0, "Galician" , "Galego" },
+ { "gl", "ES", 0, "Galician (Spain)" , 0 },
+ { "gn", 0, 0, "Guarani" , "Ava\xC3\xB1" /* here we must separate otherwise VC++ will complain about \xB1E */ "e'\xE1\xBA\xBD" },
+ { "gu", 0, 0, "Gujarati" , "ગુજરાતી" },
+ { "gv", 0, 0, "Manx" , "Gaelg" },
+ { "ha", 0, 0, "Hausa" , "حَوْسَ" },
+ { "he", 0, 0, "Hebrew" , "עברית" },
+ { "he", "IL", 0, "Hebrew (Israel)" , 0 },
+ { "hi", 0, 0, "Hindi" , "हिन्दी" },
+ { "hr", 0, 0, "Croatian" , "Hrvatski" },
+ { "hr", "HR", 0, "Croatian (Croatia)" , 0 },
+ { "hu", 0, 0, "Hungarian" , "Magyar" },
+ { "hu", "HU", 0, "Hungarian (Hungary)" , 0 },
+ { "hy", 0, 0, "Armenian" , "Հայերեն" },
+ { "ia", 0, 0, "Interlingua" , "Interlingua" },
+ { "id", 0, 0, "Indonesian" , "Bahasa Indonesia" },
+ { "id", "ID", 0, "Indonesian (Indonesia)" , 0 },
+ { "is", 0, 0, "Icelandic" , "Íslenska" },
+ { "is", "IS", 0, "Icelandic (Iceland)" , 0 },
+ { "it", 0, 0, "Italian" , "Italiano" },
+ { "it", "CH", 0, "Italian (Switzerland)" , 0 },
+ { "it", "IT", 0, "Italian (Italy)" , 0 },
+ { "iu", 0, 0, "Inuktitut" , "ᐃᓄᒃᑎᑐᑦ/inuktitut" },
+ { "ja", 0, 0, "Japanese" , "\xE6\x97\xA5\xE6\x9C\xAC\xE8\xAA\x9E" },
+ { "ja", "JP", 0, "Japanese (Japan)" , 0 },
+ { "ka", 0, 0, "Georgian" , "\xE1\x83\xA5\xE1\x83\x90\xE1\x83\xA0\xE1\x83\x97\xE1\x83\xA3\xE1\x83\x9A\xE1\x83\x98" },
+ { "kk", 0, 0, "Kazakh" , "Қазақша" },
+ { "kl", 0, 0, "Kalaallisut" , "Kalaallisut" },
+ { "km", 0, 0, "Khmer" , "\xE1\x9E\x97\xE1\x9E\xB6\xE1\x9E\x9F\xE1\x9E\xB6\xE1\x9E\x81\xE1\x9F\x92\xE1\x9E\x98\xE1\x9F\x82\xE1\x9E\x9A" },
+ { "km", "KH", 0, "Khmer (Cambodia)" , 0 },
+ { "kn", 0, 0, "Kannada" , "\xE0\xB2\x95\xE0\xB2\xA8\xE0\xB3\x8D\xE0\xB2\xA8\xE0\xB2\xA1" },
+ { "ko", 0, 0, "Korean" , "\xED\x95\x9C\xEA\xB5\xAD\xEC\x96\xB4" },
+ { "ko", "KR", 0, "Korean (Korea)" , 0 },
+ { "ku", 0, 0, "Kurdish" , "Kurdî" },
+ { "kw", 0, 0, "Cornish" , "Kernowek" },
+ { "ky", 0, 0, "Kirghiz" , "кыргызча" },
+ { "la", 0, 0, "Latin" , "Latina" },
+ { "lo", 0, 0, "Lao" , "\xE0\xBA\xA5\xE0\xBA\xB2\xE0\xBA\xA7" },
+ { "lt", 0, 0, "Lithuanian" , "Lietuvių" },
+ { "lt", "LT", 0, "Lithuanian (Lithuania)" , 0 },
+ { "lv", 0, 0, "Latvian" , "Latviešu" },
+ { "lv", "LV", 0, "Latvian (Latvia)" , 0 },
+ { "jbo", 0, 0, "Lojban" , "La .lojban." },
+ { "mg", 0, 0, "Malagasy" , "Malagasy" },
+ { "mi", 0, 0, "Maori" , "Māori" },
+ { "mk", 0, 0, "Macedonian" , "Македонски" },
+ { "mk", "MK", 0, "Macedonian (Macedonia)" , 0 },
+ { "ml", 0, 0, "Malayalam" , "മലയാളം" },
+ { "mn", 0, 0, "Mongolian" , "Монгол" },
+ { "mr", 0, 0, "Marathi" , "मराठी" },
+ { "ms", 0, 0, "Malay" , "Bahasa Melayu" },
+ { "ms", "MY", 0, "Malay (Malaysia)" , 0 },
+ { "mt", 0, 0, "Maltese" , "Malti" },
+ { "my", 0, 0, "Burmese" , "\xE1\x80\x99\xE1\x80\xBC\xE1\x80\x94\xE1\x80\xBA\xE1\x80\x99\xE1\x80\xAC\xE1\x80\x98\xE1\x80\xAC\xE1\x80\x9E\xE1\x80\xAC" },
+ { "my", "MM", 0, "Burmese (Myanmar)" , 0 },
+ { "nb", 0, 0, "Norwegian Bokmal" , 0 },
+ { "nb", "NO", 0, "Norwegian Bokmål (Norway)" , 0 },
+ { "ne", 0, 0, "Nepali" , 0 },
+ { "nl", 0, 0, "Dutch" , "Nederlands" },
+ { "nl", "BE", 0, "Dutch (Belgium)" , 0 },
+ { "nl", "NL", 0, "Dutch (Netherlands)" , 0 },
+ { "nn", 0, 0, "Norwegian Nynorsk" , "Norsk nynorsk" },
+ { "nn", "NO", 0, "Norwegian Nynorsk (Norway)" , 0 },
+ { "no", 0, 0, "Norwegian" , "Norsk bokmål" },
+ { "no", "NO", 0, "Norwegian (Norway)" , 0 },
+ { "no", "NY", 0, "Norwegian (NY)" , 0 },
+ { "nr", 0, 0, "Ndebele, South" , 0 },
+ { "oc", 0, 0, "Occitan post 1500" , "Occitan" },
+ { "om", 0, 0, "Oromo" , "Oromoo" },
+ { "or", 0, 0, "Oriya" , "\xE0\xAC\x93\xE0\xAC\xA1\xE0\xAC\xBC\xE0\xAC\xBF\xE0\xAC\x86" },
+ { "pa", 0, 0, "Punjabi" , "ਪੰਜਾਬੀ" },
+ { "pl", 0, 0, "Polish" , "Polski" },
+ { "pl", "PL", 0, "Polish (Poland)" , 0 },
+ { "ps", 0, 0, "Pashto" , "پښتو" },
+ { "pt", 0, 0, "Portuguese" , "Português" },
+ { "pt", "BR", 0, "Portuguese (Brazil)" , 0 },
+ { "pt", "PT", 0, "Portuguese (Portugal)" , 0 },
+ { "qu", 0, 0, "Quechua" , "Runa Simi" },
+ { "rm", 0, 0, "Rhaeto-Romance" , "Rumantsch" },
+ { "ro", 0, 0, "Romanian" , "Română" },
+ { "ro", "RO", 0, "Romanian (Romania)" , 0 },
+ { "ru", 0, 0, "Russian" , "Русский" },
+ { "ru", "RU", 0, "Russian (Russia)" , 0 },
+ { "rw", 0, 0, "Kinyarwanda" , "Kinyarwanda" },
+ { "sa", 0, 0, "Sanskrit" , 0 },
+ { "sd", 0, 0, "Sindhi" , 0 },
+ { "se", 0, 0, "Sami" , "Sámegiella" },
+ { "se", "NO", 0, "Sami (Norway)" , 0 },
+ { "si", 0, 0, "Sinhalese" , 0 },
+ { "sk", 0, 0, "Slovak" , "Slovenčina" },
+ { "sk", "SK", 0, "Slovak (Slovakia)" , 0 },
+ { "sl", 0, 0, "Slovenian" , "Slovenščina" },
+ { "sl", "SI", 0, "Slovenian (Slovenia)" , 0 },
+ { "sl", "SL", 0, "Slovenian (Sierra Leone)" , 0 },
+ { "sm", 0, 0, "Samoan" , 0 },
+ { "so", 0, 0, "Somali" , 0 },
+ { "sp", 0, 0, "Unknown language" , 0 },
+ { "sq", 0, 0, "Albanian" , "Shqip" },
+ { "sq", "AL", 0, "Albanian (Albania)" , 0 },
+ { "sr", 0, 0, "Serbian" , "Српски" },
+ { "sr", "YU", 0, "Serbian (Yugoslavia)" , 0 },
+ { "sr", 0,"ije", "Serbian" , "Српски" },
+ { "sr", 0, "latin", "Serbian" , "Српски" },
+ { "sr", 0, "Latn", "Serbian" , "Српски" },
+ { "ss", 0, 0, "Swati" , 0 },
+ { "st", 0, 0, "Sotho" , 0 },
+ { "sv", 0, 0, "Swedish" , "Svenska" },
+ { "sv", "SE", 0, "Swedish (Sweden)" , 0 },
+ { "sv", "SV", 0, "Swedish (El Salvador)" , 0 },
+ { "sw", 0, 0, "Swahili" , 0 },
+ { "ta", 0, 0, "Tamil" , "\xE0\xAE\xA4\xE0\xAE\xAE\xE0\xAE\xBF\xE0\xAE\xB4\xE0\xAF\x8D" },
+ { "te", 0, 0, "Telugu" , 0 },
+ { "tg", 0, 0, "Tajik" , 0 },
+ { "th", 0, 0, "Thai" , "\xE0\xB9\x84\xE0\xB8\x97\xE0\xB8\xA2" },
+ { "th", "TH", 0, "Thai (Thailand)" , 0 },
+ { "ti", 0, 0, "Tigrinya" , 0 },
+ { "tk", 0, 0, "Turkmen" , 0 },
+ { "tl", 0, 0, "Tagalog" , 0 },
+ { "to", 0, 0, "Tonga" , 0 },
+ { "tr", 0, 0, "Turkish" , "Türkçe" },
+ { "tr", "TR", 0, "Turkish (Turkey)" , 0 },
+ { "ts", 0, 0, "Tsonga" , 0 },
+ { "tt", 0, 0, "Tatar" , "Татарча" },
+ { "ug", 0, 0, "Uighur" , 0 },
+ { "uk", 0, 0, "Ukrainian" , "Українська" },
+ { "uk", "UA", 0, "Ukrainian (Ukraine)" , 0 },
+ { "ur", 0, 0, "Urdu" , "اردو" },
+ { "ur", "PK", 0, "Urdu (Pakistan)" , 0 },
+ { "uz", 0, 0, "Uzbek" , 0 },
+ { "uz", 0, "cyrillic", "Uzbek" , 0 },
+ { "vi", 0, 0, "Vietnamese" , "Tiếng Việt" },
+ { "vi", "VN", 0, "Vietnamese (Vietnam)" , 0 },
+ { "wa", 0, 0, "Walloon" , 0 },
+ { "wo", 0, 0, "Wolof" , 0 },
+ { "xh", 0, 0, "Xhosa" , 0 },
+ { "yi", 0, 0, "Yiddish" , "ייִדיש" },
+ { "yo", 0, 0, "Yoruba" , 0 },
+ { "zh", 0, 0, "Chinese" , "中文" },
+ { "zh", "CN", 0, "Chinese (simplified)" , "中文(简体)" },
+ { "zh", "HK", 0, "Chinese (Hong Kong)" , "中文(香港)" },
+ { "zh", "TW", 0, "Chinese (traditional)" , "中文(繁體)" },
+ { "zu", 0, 0, "Zulu" , 0 },
+ { NULL, 0, 0, NULL , 0 }
};
//*}
std::string
resolve_language_alias(const std::string& name)
{
typedef std::unordered_map<std::string, std::string> Aliases;
static Aliases language_aliases;
if (language_aliases.empty())
{
// FIXME: Many of those are not useful for us, since we leave
// encoding to the app, not to the language, we could/should
// also match against all language names, not just aliases from
// locale.alias
// Aliases taken from /etc/locale.alias
language_aliases["bokmal"] = "nb_NO.ISO-8859-1";
language_aliases["bokmål"] = "nb_NO.ISO-8859-1";
language_aliases["catalan"] = "ca_ES.ISO-8859-1";
language_aliases["croatian"] = "hr_HR.ISO-8859-2";
language_aliases["czech"] = "cs_CZ.ISO-8859-2";
language_aliases["danish"] = "da_DK.ISO-8859-1";
language_aliases["dansk"] = "da_DK.ISO-8859-1";
language_aliases["deutsch"] = "de_DE.ISO-8859-1";
language_aliases["dutch"] = "nl_NL.ISO-8859-1";
language_aliases["eesti"] = "et_EE.ISO-8859-1";
language_aliases["estonian"] = "et_EE.ISO-8859-1";
language_aliases["finnish"] = "fi_FI.ISO-8859-1";
language_aliases["français"] = "fr_FR.ISO-8859-1";
language_aliases["french"] = "fr_FR.ISO-8859-1";
language_aliases["galego"] = "gl_ES.ISO-8859-1";
language_aliases["galician"] = "gl_ES.ISO-8859-1";
language_aliases["german"] = "de_DE.ISO-8859-1";
language_aliases["greek"] = "el_GR.ISO-8859-7";
language_aliases["hebrew"] = "he_IL.ISO-8859-8";
language_aliases["hrvatski"] = "hr_HR.ISO-8859-2";
language_aliases["hungarian"] = "hu_HU.ISO-8859-2";
language_aliases["icelandic"] = "is_IS.ISO-8859-1";
language_aliases["italian"] = "it_IT.ISO-8859-1";
language_aliases["japanese"] = "ja_JP.eucJP";
language_aliases["japanese.euc"] = "ja_JP.eucJP";
language_aliases["ja_JP"] = "ja_JP.eucJP";
language_aliases["ja_JP.ujis"] = "ja_JP.eucJP";
language_aliases["japanese.sjis"] = "ja_JP.SJIS";
language_aliases["korean"] = "ko_KR.eucKR";
language_aliases["korean.euc"] = "ko_KR.eucKR";
language_aliases["ko_KR"] = "ko_KR.eucKR";
language_aliases["lithuanian"] = "lt_LT.ISO-8859-13";
language_aliases["no_NO"] = "nb_NO.ISO-8859-1";
language_aliases["no_NO.ISO-8859-1"] = "nb_NO.ISO-8859-1";
language_aliases["norwegian"] = "nb_NO.ISO-8859-1";
language_aliases["nynorsk"] = "nn_NO.ISO-8859-1";
language_aliases["polish"] = "pl_PL.ISO-8859-2";
language_aliases["portuguese"] = "pt_PT.ISO-8859-1";
language_aliases["romanian"] = "ro_RO.ISO-8859-2";
language_aliases["russian"] = "ru_RU.ISO-8859-5";
language_aliases["slovak"] = "sk_SK.ISO-8859-2";
language_aliases["slovene"] = "sl_SI.ISO-8859-2";
language_aliases["slovenian"] = "sl_SI.ISO-8859-2";
language_aliases["spanish"] = "es_ES.ISO-8859-1";
language_aliases["swedish"] = "sv_SE.ISO-8859-1";
language_aliases["thai"] = "th_TH.TIS-620";
language_aliases["turkish"] = "tr_TR.ISO-8859-9";
}
std::string name_lowercase;
name_lowercase.resize(name.size());
for(std::string::size_type i = 0; i < name.size(); ++i)
name_lowercase[i] = static_cast<char>(tolower(name[i]));
Aliases::iterator i = language_aliases.find(name_lowercase);
if (i != language_aliases.end())
{
return i->second;
}
else
{
return name;
}
}
Language
Language::from_spec(const std::string& language, const std::string& country, const std::string& modifier)
{
typedef std::unordered_map<std::string, std::vector<const LanguageSpec*> > LanguageSpecMap;
static LanguageSpecMap language_map;
if (language_map.empty())
{ // Init language_map
for(int i = 0; languages[i].language != NULL; ++i)
language_map[languages[i].language].push_back(&languages[i]);
}
LanguageSpecMap::iterator i = language_map.find(language);
if (i != language_map.end())
{
std::vector<const LanguageSpec*>& lst = i->second;
LanguageSpec tmpspec;
tmpspec.language = language.c_str();
tmpspec.country = country.c_str();
tmpspec.modifier = modifier.c_str();
Language tmplang(&tmpspec);
const LanguageSpec* best_match = 0;
int best_match_score = 0;
for(std::vector<const LanguageSpec*>::iterator j = lst.begin(); j != lst.end(); ++j)
{ // Search for the language that best matches the given spec, value country more then modifier
int score = Language::match(Language(*j), tmplang);
if (score > best_match_score)
{
best_match = *j;
best_match_score = score;
}
}
assert(best_match);
return Language(best_match);
}
else
{
return Language();
}
}
Language
Language::from_name(const std::string& spec_str)
{
return from_env(resolve_language_alias(spec_str));
}
Language
Language::from_env(const std::string& env)
{
// Split LANGUAGE_COUNTRY.CODESET@MODIFIER into parts
std::string::size_type ln = env.find('_');
std::string::size_type dt = env.find('.');
std::string::size_type at = env.find('@');
std::string language;
std::string country;
std::string codeset;
std::string modifier;
//std::cout << ln << " " << dt << " " << at << std::endl;
language = env.substr(0, std::min(std::min(ln, dt), at));
if (ln != std::string::npos && ln+1 < env.size()) // _
{
country = env.substr(ln+1, (std::min(dt, at) == std::string::npos) ? std::string::npos : std::min(dt, at) - (ln+1));
}
if (dt != std::string::npos && dt+1 < env.size()) // .
{
codeset = env.substr(dt+1, (at == std::string::npos) ? std::string::npos : (at - (dt+1)));
}
if (at != std::string::npos && at+1 < env.size()) // @
{
modifier = env.substr(at+1);
}
return from_spec(language, country, modifier);
}
Language::Language(const LanguageSpec* language_spec_)
: language_spec(language_spec_)
{
}
Language::Language()
: language_spec(0)
{
}
int
Language::match(const Language& lhs, const Language& rhs)
{
if (lhs.get_language() != rhs.get_language())
{
return 0;
}
else
{
static int match_tbl[3][3] = {
// modifier match, wildchard, miss
{ 9, 8, 5 }, // country match
{ 7, 6, 3 }, // country wildcard
{ 4, 2, 1 }, // country miss
};
int c;
if (lhs.get_country() == rhs.get_country())
c = 0;
else if (lhs.get_country().empty() || rhs.get_country().empty())
c = 1;
else
c = 2;
int m;
if (lhs.get_modifier() == rhs.get_modifier())
m = 0;
else if (lhs.get_modifier().empty() || rhs.get_modifier().empty())
m = 1;
else
m = 2;
return match_tbl[c][m];
}
}
std::string
Language::get_language() const
{
if (language_spec)
return language_spec->language;
else
return "";
}
std::string
Language::get_country() const
{
if (language_spec && language_spec->country)
return language_spec->country;
else
return "";
}
std::string
Language::get_modifier() const
{
if (language_spec && language_spec->modifier)
return language_spec->modifier;
else
return "";
}
std::string
Language::get_name() const
{
if (language_spec)
return language_spec->name;
else
return "";
}
+std::string
+Language::get_localized_name() const
+{
+ if (language_spec == NULL)
+ return "";
+ if (language_spec->localized_name)
+ return language_spec->localized_name;
+ return language_spec->name;
+}
+
std::string
Language::str() const
{
if (language_spec)
{
std::string var;
var += language_spec->language;
if (language_spec->country)
{
var += "_";
var += language_spec->country;
}
if (language_spec->modifier)
{
var += "@";
var += language_spec->modifier;
}
return var;
}
else
{
return "";
}
}
bool
Language::operator==(const Language& rhs) const
{
return language_spec == rhs.language_spec;
}
bool
Language::operator!=(const Language& rhs) const
{
return language_spec != rhs.language_spec;
}
} // namespace tinygettext
/* EOF */
diff --git a/src/libs/tinygettext/language.hpp b/src/libs/tinygettext/language.hpp
index 205d0db..9df5ce2 100644
--- a/src/libs/tinygettext/language.hpp
+++ b/src/libs/tinygettext/language.hpp
@@ -1,103 +1,106 @@
// tinygettext - A gettext replacement that works directly on .po files
// Copyright (c) 2006 Ingo Ruhnke <grumbel@gmail.com>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgement in the product documentation would be
// appreciated but is not required.
// 2. Altered source versions must be plainly marked as such, and must not be
// misrepresented as being the original software.
// 3. This notice may not be removed or altered from any source distribution.
#ifndef HEADER_TINYGETTEXT_LANGUAGE_HPP
#define HEADER_TINYGETTEXT_LANGUAGE_HPP
#include <string>
#include <unordered_map>
namespace tinygettext {
struct LanguageSpec;
/** Lightweight wrapper around LanguageSpec */
class Language
{
private:
const LanguageSpec* language_spec;
Language(const LanguageSpec* language_spec);
public:
/** Create a language from language and country code:
Example: Languge("de", "DE"); */
static Language from_spec(const std::string& language,
const std::string& country = std::string(),
const std::string& modifier = std::string());
/** Create a language from language and country code:
Example: Languge("deutsch");
Example: Languge("de_DE"); */
static Language from_name(const std::string& str);
/** Create a language from an environment variable style string (e.g de_DE.UTF-8@modifier) */
static Language from_env(const std::string& env);
/** Compares two Languages, returns 0 on missmatch and a score
between 1 and 9 on match, the higher the score the better the
match */
static int match(const Language& lhs, const Language& rhs);
/** Create an undefined Language object */
Language();
explicit operator bool() const { return language_spec != NULL; }
/** Returns the language code (i.e. de, en, fr) */
std::string get_language() const;
/** Returns the country code (i.e. DE, AT, US) */
std::string get_country() const;
/** Returns the modifier of the language (i.e. latn or Latn for
Serbian with non-cyrilic characters) */
std::string get_modifier() const;
- /** Returns the human readable name of the Language */
+ /** Returns the human readable name of the Language, in English */
std::string get_name() const;
+ /** Returns the localized human readable name of the Language */
+ std::string get_localized_name() const;
+
/** Returns the Language as string in the form of an environment
variable: {language}_{country}@{modifier} */
std::string str() const;
bool operator==(const Language& rhs) const;
bool operator!=(const Language& rhs) const;
friend bool operator<(const Language& lhs, const Language& rhs);
friend struct Language_hash;
};
inline bool operator<(const Language& lhs, const Language& rhs) {
return lhs.language_spec < rhs.language_spec;
}
struct Language_hash
{
size_t operator()(const Language& v) const
{
return reinterpret_cast<size_t>(v.language_spec);
}
};
} // namespace tinygettext
#endif
/* EOF */

File Metadata

Mime Type
text/x-diff
Expires
Sat, May 16, 8:24 PM (1 d, 14 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
63537
Default Alt Text
(62 KB)

Event Timeline