Skip to content

Commit

Permalink
Merge pull request #2643 from ace20022/xbmc_getLanguage
Browse files Browse the repository at this point in the history
[Python] Extend xbmc.getLangauge to return various language formats.
  • Loading branch information
MartijnKaijser committed May 1, 2013
2 parents 14e82ac + 0953505 commit db3c818
Show file tree
Hide file tree
Showing 4 changed files with 208 additions and 8 deletions.
54 changes: 52 additions & 2 deletions xbmc/interfaces/legacy/ModuleXbmc.cpp
Expand Up @@ -52,6 +52,7 @@
#include "cores/AudioEngine/AEFactory.h"
#include "storage/MediaManager.h"
#include "utils/FileUtils.h"
#include "utils/LangCodeExpander.h"

#include "CallbackHandler.h"
#include "AddonUtils.h"
Expand Down Expand Up @@ -180,10 +181,54 @@ namespace XBMCAddon
return g_guiSettings.GetString("lookandfeel.skin");
}

String getLanguage()
String getLanguage(int format /* = CLangCodeExpander::ENGLISH_NAME */, bool region /*= false*/)
{
TRACE;
return g_guiSettings.GetString("locale.language");
CStdString lang = g_guiSettings.GetString("locale.language");

switch (format)
{
case CLangCodeExpander::ENGLISH_NAME:
{
if (region)
{
CStdString region = "-" + g_langInfo.GetCurrentRegion();
return (lang += region).c_str();
}
return lang.c_str();
}
case CLangCodeExpander::ISO_639_1:
{
CStdString langCode;
g_LangCodeExpander.ConvertToTwoCharCode(langCode, lang);
if (region)
{
CStdString region = g_langInfo.GetRegionLocale();
CStdString region2Code;
g_LangCodeExpander.ConvertToTwoCharCode(region2Code, region);
region2Code = "-" + region2Code;
return (langCode += region2Code).c_str();
}
return langCode.c_str();
}
case CLangCodeExpander::ISO_639_2:
{
CStdString langCode;
g_LangCodeExpander.ConvertToThreeCharCode(langCode, lang);
if (region)
{
CStdString region = g_langInfo.GetRegionLocale();
CStdString region3Code;
g_LangCodeExpander.ConvertToThreeCharCode(region3Code, region, true);
region3Code = "-" + region3Code;
return (langCode += region3Code).c_str();
}

return langCode.c_str();
}
default:
return "";
}
}

String getIPAddress()
Expand Down Expand Up @@ -482,6 +527,11 @@ namespace XBMCAddon
int getCAPTURE_FLAG_CONTINUOUS() { return (int)CAPTUREFLAG_CONTINUOUS; }
int getCAPTURE_FLAG_IMMEDIATELY() { return (int)CAPTUREFLAG_IMMEDIATELY; }

// language string formats
int getISO_639_1() { return CLangCodeExpander::ISO_639_1; }
int getISO_639_2(){ return CLangCodeExpander::ISO_639_2; }
int getENGLISH_NAME() { return CLangCodeExpander::ENGLISH_NAME; }

const int lLOGNOTICE = LOGNOTICE;
}
}
24 changes: 18 additions & 6 deletions xbmc/interfaces/legacy/ModuleXbmc.h
Expand Up @@ -23,6 +23,7 @@
#include "Tuple.h"
//#include "Monitor.h"

#include "utils/LangCodeExpander.h"
#include "utils/log.h"
#include "utils/StdString.h"

Expand Down Expand Up @@ -150,12 +151,20 @@ namespace XBMCAddon
String getSkinDir();

/**
* getLanguage() -- Returns the active language as a string.
*
* example:
* - language = xbmc.getLanguage()
*/
String getLanguage();
* getLanguage([format], [region]) -- Returns the active language as a string.
*
* format: [opt] format of the returned language string
* xbmc.ISO_639_1: two letter code as defined in ISO 639-1
* xbmc.ISO_639_2: three letter code as defined in ISO 639-2/T or ISO 639-2/B
* xbmc.ENGLISH_NAME: full language name in English (default)
*
* region: [opt] append the region delimited by "-" of the language (setting)
* to the returned language string
*
* example:
* - language = xbmc.getLanguage(xbmc.ENGLISH_NAME)
*/
String getLanguage(int format = CLangCodeExpander::ENGLISH_NAME, bool region = false);

/**
* getIPAddress() -- Returns the current ip address as a string.
Expand Down Expand Up @@ -429,6 +438,9 @@ namespace XBMCAddon

SWIG_CONSTANT_FROM_GETTER(int,CAPTURE_FLAG_CONTINUOUS);
SWIG_CONSTANT_FROM_GETTER(int,CAPTURE_FLAG_IMMEDIATELY);
SWIG_CONSTANT_FROM_GETTER(int,ISO_639_1);
SWIG_CONSTANT_FROM_GETTER(int,ISO_639_2);
SWIG_CONSTANT_FROM_GETTER(int,ENGLISH_NAME);
#if 0
void registerMonitor(Monitor* monitor);
void unregisterMonitor(Monitor* monitor);
Expand Down
108 changes: 108 additions & 0 deletions xbmc/utils/LangCodeExpander.cpp
Expand Up @@ -202,6 +202,14 @@ bool CLangCodeExpander::ConvertToThreeCharCode(CStdString& strThreeCharCode, con
return true;
}
}
for (unsigned int index = 0; index < sizeof(RegionCode2To3) / sizeof(RegionCode2To3[0]); ++index)
{
if (strCharCode.Equals(RegionCode2To3[index].id))
{
strThreeCharCode = strCharCode;
return true;
}
}
}
else if (strCharCode.size() > 3)
{
Expand Down Expand Up @@ -261,6 +269,93 @@ bool CLangCodeExpander::ConvertWindowsToGeneralCharCode(const CStdString& strWin
}
#endif

bool CLangCodeExpander::ConvertToTwoCharCode(CStdString& code, const CStdString& lang)
{
if (lang.length() == 2)
{
CStdString tmp;
if (Lookup(tmp, lang))
{
code = lang;
return true;
}
}
else if (lang.length() == 3)
{
for (unsigned int index = 0; index < sizeof(CharCode2To3) / sizeof(CharCode2To3[0]); ++index)
{
if (lang.Equals(CharCode2To3[index].id) || (CharCode2To3[index].win_id && lang.Equals(CharCode2To3[index].win_id)))
{
code = CharCode2To3[index].old;
return true;
}
}

for (unsigned int index = 0; index < sizeof(RegionCode2To3) / sizeof(RegionCode2To3[0]); ++index)
{
if (lang.Equals(RegionCode2To3[index].id))
{
code = RegionCode2To3[index].old;
return true;
}
}
}

// check if lang is full language name
CStdString tmp;
if (ReverseLookup(lang, tmp))
{
if (tmp.length() == 2)
{
code = tmp;
return true;
}
else if (tmp.length() == 3)
return ConvertToTwoCharCode(code, tmp);
}

// try xbmc specific language names
CStdString strLangInfoPath;
strLangInfoPath.Format("special://xbmc/language/%s/langinfo.xml", lang.c_str());
CLangInfo langInfo;
if (!langInfo.Load(strLangInfoPath))
return false;

return ConvertToTwoCharCode(code, langInfo.GetLanguageCode());
}

bool CLangCodeExpander::ReverseLookup(const CStdString& desc, CStdString& code)
{
CStdString descTmp(desc);
descTmp.Trim();
STRINGLOOKUPTABLE::iterator it;
for (it = m_mapUser.begin(); it != m_mapUser.end() ; it++)
{
if (descTmp.Equals(it->second))
{
code = it->first;
return true;
}
}
for(unsigned int i = 0; i < sizeof(g_iso639_1) / sizeof(LCENTRY); i++)
{
if (descTmp.Equals(g_iso639_1[i].name))
{
CodeToString(g_iso639_1[i].code, code);
return true;
}
}
for(unsigned int i = 0; i < sizeof(g_iso639_2) / sizeof(LCENTRY); i++)
{
if (descTmp.Equals(g_iso639_2[i].name))
{
CodeToString(g_iso639_2[i].code, code);
return true;
}
}
return false;
}

bool CLangCodeExpander::LookupInMap(CStdString& desc, const CStdString& code)
{
STRINGLOOKUPTABLE::iterator it;
Expand Down Expand Up @@ -312,6 +407,19 @@ bool CLangCodeExpander::LookupInDb(CStdString& desc, const CStdString& code)
return false;
}

void CLangCodeExpander::CodeToString(long code, CStdString& ret)
{
ret.Empty();
for (unsigned int j = 0 ; j < 4 ; j++)
{
char c = (char) code & 0xFF;
if (c == '\0')
return;
ret.Insert(0, c);
code >>= 8;
}
}

extern const LCENTRY g_iso639_1[144] =
{
{ MAKECODE('\0','\0','c','c'), "Closed Caption" },
Expand Down
30 changes: 30 additions & 0 deletions xbmc/utils/LangCodeExpander.h
Expand Up @@ -28,11 +28,27 @@ class CLangCodeExpander
{
public:

enum LANGFORMATS
{
ISO_639_1,
ISO_639_2,
ENGLISH_NAME
};

CLangCodeExpander(void);
~CLangCodeExpander(void);

bool Lookup(CStdString& desc, const CStdString& code);
bool Lookup(CStdString& desc, const int code);

/** \brief Converts a language given as 2-Char (ISO 639-1),
* 3-Char (ISO 639-2/T or ISO 639-2/B),
* or full english name string to a 2-Char (ISO 639-1) code.
* \param[out] code The 2-Char language code of the given language lang.
* \param[in] lang The language that should be converted.
* \return true if the conversion succeeded, false otherwise.
*/
bool ConvertToTwoCharCode(CStdString& code, const CStdString& lang);
#ifdef TARGET_WINDOWS
bool ConvertTwoToThreeCharCode(CStdString& strThreeCharCode, const CStdString& strTwoCharCode, bool localeHack = false);
bool ConvertToThreeCharCode(CStdString& strThreeCharCode, const CStdString& strCharCode, bool localeHack = false);
Expand All @@ -50,12 +66,26 @@ class CLangCodeExpander
void Clear();
protected:

/** \brief Converts a language code given as a long, see #MAKECODE(a, b, c, d)
* to its string representation.
* \param[in] code The language code given as a long, see #MAKECODE(a, b, c, d).
* \param[out] ret The string representation of the given language code code.
*/
void CodeToString(long code, CStdString& ret);

typedef std::map<CStdString, CStdString> STRINGLOOKUPTABLE;
STRINGLOOKUPTABLE m_mapUser;

bool LookupInDb(CStdString& desc, const CStdString& code);
bool LookupInMap(CStdString& desc, const CStdString& code);

/** \brief Looks up the ISO 639-1, ISO 639-2/T, or ISO 639-2/B, whichever it finds first,
* code of the given english language name.
* \param[in] desc The english language name for which a code is looked for.
* \param[out] code The ISO 639-1, ISO 639-2/T, or ISO 639-2/B code of the given language desc.
* \return true if the a code was found, false otherwise.
*/
bool ReverseLookup(const CStdString& desc, CStdString& code);
};

extern CLangCodeExpander g_LangCodeExpander;

0 comments on commit db3c818

Please sign in to comment.