Repository: nvaccess/nvda

Issue:
Sort items in Language (requires restart to fully take effect) combo box alphabetically by the expanded language names
Currently, the list of languages in the Language (requires restart to fully take effect) combo box present in the General Settings dialog are sorted alphabetically with respect to their two-letter language short codes. The basis of sorting is not too evident, particularly at first look, furthermore by a newbie. In my personal experience, despite being a long-time NVDA user, I never quite understood and admittedly never bothered to understand the structure of the sorting there, until I gave this a quick thought while in General Settings moments ago. I suspect that most new users would not recognize the presence or meaning of the two-letter language identifiers and most probably never figure out that that is the characteristic on which the list of languages has been alphabetically sorted.
To address the above described problem, I would like to propose sorting languages alphabetically by their full names itself as opposed to using their identifiers for sake of clarity. I understand that this issue is very trivial, but I suppose it sounds easy to tackle and thus worth reporting.
P.S. Would you advise me to open separate tickets to tackle other similar item sorting improvements such as the Voice Settings > Variants combo box, or should the scope of this ticket just be broadened to encompass those as well (again, too trivial for another dedicated ticket for each case, therefore asking before proceeding)?



Discussion:
I believe the names of the languages are localised (and therefore the list order could be different when different language settings are enabled) I don't think this is a problem. I assume you intend to sort based on this localised long name? To me this would seem the most logical for a user.

In terms of sorting the voice settings > variants combo box:
I don't think another issue needs to be raised, in fact there is a request for this in #561 The scope of issue #561 is actually a bit larger, and includes a trying to filter the names of the voices.

Please submit the voices variants sorting, and the language items sorting as two pull requests.
I seem to have assumed you were a developer, I'm not sure why I did exactly. So sorry if my comments are a little direct, and developer specific.

The user specific question still stands though, if a person with English locale looks for the German language, they try to find 'G' for 'German'. However a person with German locale tries to find 'D' for 'Deutsch'
No worries about the technical-minded nature of your first comment,
for I did follow it completely for the most part (oxymoron? :P).
I had not forethought of the case of localized long names of different
languages being different and thus the alphabetical sorting varying
accordingly earlier, but your description makes sense and I think I do
agree with said behaviour. If I am understanding correctly however,
wouldn't it be a challenge to make alphabetical sorting work for all
these different languages in which NVDA is translated, or is there
some simple programmatic method making that possible? Just
wondering...

On 6/14/17, Reef Turner <notifications@github.com> wrote:
> I seem to have assumed you were a developer, I'm not sure why I did exactly.
> So sorry if my comments are a little direct, and developer specific.
>
> The user specific question still stands though, if a person with English
> locale looks for the German language, they try to find 'G' for 'German'.
> However a person with German locale tries to find 'D' for 'Deutsch'
>
> --
> You are receiving this because you authored the thread.
> Reply to this email directly or view it on GitHub:
> https://github.com/nvaccess/nvda/issues/7284#issuecomment-308405163


-- 
Best Regards
Bhavya Shah

Blogger at Hiking Across Horizons: https://bhavyashah125.wordpress.com/

Contacting Me
E-mail Address: bhavya.shah125@gmail.com
Follow me on Twitter @BhavyaShah125 or www.twitter.com/BhavyaShah125
Mobile Number: +91 7506221750

They're Unicode strings and Unicode has rules for sorting, so it should be
fine (TM).

Ah right, I think I understand. I hadn't thought about Unicode earlier.

On 6/14/17, James Teh <notifications@github.com> wrote:
> They're Unicode strings and Unicode has rules for sorting, so it should be
> fine (TM).
>
>
> --
> You are receiving this because you authored the thread.
> Reply to this email directly or view it on GitHub:
> https://github.com/nvaccess/nvda/issues/7284#issuecomment-308413715


-- 
Best Regards
Bhavya Shah

Blogger at Hiking Across Horizons: https://bhavyashah125.wordpress.com/

Contacting Me
E-mail Address: bhavya.shah125@gmail.com
Follow me on Twitter @BhavyaShah125 or www.twitter.com/BhavyaShah125
Mobile Number: +91 7506221750

If I might quickly add, something similar also prevails with reference
to the Input and Output Table combo boxes in the Braile Settings
dialog. Something worth tackling alongside/as part of  this ticket.

On 6/14/17, Bhavya shah <bhavya.shah125@gmail.com> wrote:
> Ah right, I think I understand. I hadn't thought about Unicode earlier.
>
> On 6/14/17, James Teh <notifications@github.com> wrote:
>> They're Unicode strings and Unicode has rules for sorting, so it should
>> be
>> fine (TM).
>>
>>
>> --
>> You are receiving this because you authored the thread.
>> Reply to this email directly or view it on GitHub:
>> https://github.com/nvaccess/nvda/issues/7284#issuecomment-308413715
>
>
> --
> Best Regards
> Bhavya Shah
>
> Blogger at Hiking Across Horizons: https://bhavyashah125.wordpress.com/
>
> Contacting Me
> E-mail Address: bhavya.shah125@gmail.com
> Follow me on Twitter @BhavyaShah125 or www.twitter.com/BhavyaShah125
> Mobile Number: +91 7506221750
>


-- 
Best Regards
Bhavya Shah

Blogger at Hiking Across Horizons: https://bhavyashah125.wordpress.com/

Contacting Me
E-mail Address: bhavya.shah125@gmail.com
Follow me on Twitter @BhavyaShah125 or www.twitter.com/BhavyaShah125
Mobile Number: +91 7506221750

Braille tables are getting sorted as part of #6449.


Resolving patch:
diff --git a/source/gui/settingsDialogs.py b/source/gui/settingsDialogs.py
--- a/source/gui/settingsDialogs.py
+++ b/source/gui/settingsDialogs.py
@@ -1,7 +1,7 @@
 # -*- coding: UTF-8 -*-
 #settingsDialogs.py
 #A part of NonVisual Desktop Access (NVDA)
-#Copyright (C) 2006-2017 NV Access Limited, Peter Vágner, Aleksey Sadovoy, Rui Batista, Joseph Lee, Heiko Folkerts, Zahari Yurukov, Leonard de Ruijter, Derek Riemer, Babbage B.V., Davy Kager, Ethan Holliger
+#Copyright (C) 2006-2018 NV Access Limited, Peter Vágner, Aleksey Sadovoy, Rui Batista, Joseph Lee, Heiko Folkerts, Zahari Yurukov, Leonard de Ruijter, Derek Riemer, Babbage B.V., Davy Kager, Ethan Holliger
 #This file is covered by the GNU General Public License.
 #See the file COPYING for more details.
 
@@ -139,7 +139,7 @@ class GeneralSettingsDialog(SettingsDialog):
 
 	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):")
diff --git a/source/languageHandler.py b/source/languageHandler.py
--- a/source/languageHandler.py
+++ b/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
@@ -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.
@@ -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


Test patch: