Skip to content

Commit

Permalink
General Settings/Language: sort items based on descriptions (#8143)
Browse files Browse the repository at this point in the history
* Language handler: allow presentational view of available languages to be obtained. Re #7284.

When going through General settings/Language combo box, users might be puzzled as to why items in there are listed in random order. This is because entries are sorte according to ISO 639-1 code. To improve user experience, sort this alphabetically according to description.
This is done through a new keyword argument in languageHandler.getAvailableLanguages function. Wuth presentational argument set, language tuples will be sorted based on description text.

* Settings dialog/General/Language: enable presentational view of languages. Re #7284.

* GUI/settings dialog: update copyright years

* Docstring: language handler module description

* Language handler: only add language descriptions if this is for presentation purposes. Re #7284.

Reduece confusion further by omitting language codes from language description texts.

* Language handler: clarify module docstring

* Language handler: readability changes for variable namess.

the nanes 'd', 'i', and 'l' are so generic. Thus rename them to 'displayNames', 'entry', and 'locales'.

* Language handler: clarify comment

* Language handler: add ISO 639 codes in order to reduce confusion for users. Re #7284.

Reviewed by Mick Curran (NV Access) and others: suppose a user changes to another language by accident, a language he or she cannot understand, especially changes the Windows display language by accident. So how can they return to a language they know? This cannot be done with absence of ISO 639 language codes.
  • Loading branch information
josephsl authored and michaelDCurran committed Jun 13, 2018
1 parent 89284ef commit 302f2af
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 19 deletions.
2 changes: 1 addition & 1 deletion source/gui/settingsDialogs.py
Expand Up @@ -617,7 +617,7 @@ class GeneralSettingsPanel(SettingsPanel):

def makeSettings(self, settingsSizer):
settingsSizerHelper = guiHelper.BoxSizerHelper(self, sizer=settingsSizer)
self.languageNames = languageHandler.getAvailableLanguages()
self.languageNames = languageHandler.getAvailableLanguages(presentational=True)
languageChoices = [x[1] for x in self.languageNames]
# Translators: The label for a setting in general settings to select NVDA's interface language (once selected, NVDA must be restarted; the option user default means the user's Windows language will be used).
languageLabelText = _("&Language (requires restart to fully take effect):")
Expand Down
45 changes: 27 additions & 18 deletions source/languageHandler.py
@@ -1,9 +1,13 @@
#languageHandler.py
#A part of NonVisual Desktop Access (NVDA)
#Copyright (C) 2007-2016 NV access Limited, Joseph Lee
#Copyright (C) 2007-2018 NV access Limited, Joseph Lee
#This file is covered by the GNU General Public License.
#See the file COPYING for more details.

"""Language and localization support.
This module assists in NVDA going global through language services such as converting Windows locale ID's to friendly names and presenting available languages.
"""

import __builtin__
import os
import sys
Expand Down Expand Up @@ -94,29 +98,34 @@ def getLanguageDescription(language):
}.get(language,None)
return desc

def getAvailableLanguages():
def getAvailableLanguages(presentational=False):
"""generates a list of locale names, plus their full localized language and country names.
@param presentational: whether this is meant to be shown alphabetically by language description
@type presentational: bool
@rtype: list of tuples
"""
#Make a list of all the locales found in NVDA's locale dir
l=[x for x in os.listdir('locale') if not x.startswith('.')]
l=[x for x in l if os.path.isfile('locale/%s/LC_MESSAGES/nvda.mo'%x)]
locales = [x for x in os.listdir('locale') if not x.startswith('.')]
locales = [x for x in locales if os.path.isfile('locale/%s/LC_MESSAGES/nvda.mo'%x)]
#Make sure that en (english) is in the list as it may not have any locale files, but is default
if 'en' not in l:
l.append('en')
l.sort()
if 'en' not in locales:
locales.append('en')
locales.sort()
#For each locale, ask Windows for its human readable display name
d=[]
for i in l:
desc=getLanguageDescription(i)
label="%s, %s"%(desc,i) if desc else i
d.append(label)
displayNames = []
for entry in locales:
desc=getLanguageDescription(entry)
displayNames.append("%s, %s"%(desc,entry) if desc else entry)
#Prepare a zipped view of language codes and descriptions.
# #7284: especially for sorting by description.
langs = zip(locales,displayNames)
if presentational:
langs.sort(key=lambda lang: lang[1])
#include a 'user default, windows' language, which just represents the default language for this user account
l.append("Windows")
# Translators: the label for the Windows default NVDA interface language.
d.append(_("User default"))
#return a zipped up version of both the lists (a list with tuples of locale,label)
return zip(l,d)
langs.append(("Windows",
# Translators: the label for the Windows default NVDA interface language.
_("User default")))
return langs

def makePgettext(translations):
"""Obtaina pgettext function for use with a gettext translations instance.
Expand Down Expand Up @@ -145,7 +154,7 @@ def getWindowsLanguage():
try:
localeName=locale.windows_locale[windowsLCID]
except KeyError:
# #4203: some locale identifiers from Windows 8 don't exist in Python's list.
# #4203: some locale identifiers from Windows 8 do not exist in Python's list.
# Therefore use windows' own function to get the locale name.
# Eventually this should probably be used all the time.
bufSize=32
Expand Down

0 comments on commit 302f2af

Please sign in to comment.