Le 12/05/2015 15:03, Jean-Marc Lasgouttes a écrit :
    If you do not like my brilliant method based on ordering (!), I can
    propose to add a GuiLanguage=0/1 tag to the language file.

That would make sense.

I'll try that.

Here is a new version that relies on a new tag HasGuiSupport. Now, if we add a new translation, if will be necessary to
(1) update po/LINGUAS
(2) update lib/languages

Is this new iteration more acceptable to everybody?

JMarc



>From 536589c04435b83db4ef44e48fcffc7426eab74a Mon Sep 17 00:00:00 2001
From: Jean-Marc Lasgouttes <lasgout...@lyx.org>
Date: Thu, 7 May 2015 17:20:23 +0200
Subject: [PATCH] Improve list of available languages for UI l10n.

Add a new tag HasGuiSupport to language file. Add it for all l10ns
that we currently ship. The po files that are unused are not currently
tagged as available, but this could be done, since the code checks that the
translation is actually there.

When reading languages, build a list of GUI languages that have the
HasGuiSupport property and for which a translation is actually
available. This avoids duplicates (like "English" and "English (UK)")
and languages for which no translation exists.

Add in GuiApplication a function guiLanguageModel() that creates a
model for the Prefs dialog. Use it in GuiPrefs.
---
 lib/languages                        |   33 +++++++++++++++++++++++++++++++++
 src/Language.cpp                     |   20 +++++++++++++++++++-
 src/Language.h                       |   16 ++++++++++++++--
 src/frontends/qt4/GuiApplication.cpp |   34 ++++++++++++++++++++++++++++++++--
 src/frontends/qt4/GuiApplication.h   |    2 ++
 src/frontends/qt4/GuiPrefs.cpp       |   27 ++-------------------------
 6 files changed, 102 insertions(+), 30 deletions(-)

diff --git a/lib/languages b/lib/languages
index 06d3c0f..b32bc15 100644
--- a/lib/languages
+++ b/lib/languages
@@ -141,6 +141,7 @@ End
 # to switch the language the way of the ArabTeX-package
 Language arabic_arabtex
 	GuiName          "Arabic (ArabTeX)"
+	HasGuiSupport    true
 	BabelName        arabtex
 	QuoteStyle       french
 	Encoding         cp1256
@@ -206,6 +207,7 @@ End
 
 Language bahasa
 	GuiName          "Indonesian"
+	HasGuiSupport    true
 	BabelName        bahasa
 	PolyglossiaName  bahasai
 	QuoteStyle       english
@@ -224,6 +226,7 @@ End
 
 Language basque
 	GuiName          "Basque"
+	HasGuiSupport    true
 	BabelName        basque
 	PolyglossiaName  basque
 	QuoteStyle       french
@@ -246,6 +249,7 @@ End
 
 Language brazilian
 	GuiName          "Portuguese (Brazil)"
+	HasGuiSupport    true
 	BabelName        brazil
 	PolyglossiaName  brazil
 	QuoteStyle       english
@@ -305,6 +309,7 @@ End
 
 Language catalan
 	GuiName          "Catalan"
+	HasGuiSupport    true
 	BabelName        catalan
 	PolyglossiaName  catalan
 	PolyglossiaOpts  "babelshorthands=true"
@@ -316,6 +321,7 @@ End
 # uses CJK package
 Language chinese-simplified
 	GuiName          "Chinese (simplified)"
+	HasGuiSupport    true
 	Encoding         euc-cn
 	QuoteStyle       english
 	LangCode         zh_CN
@@ -325,6 +331,7 @@ End
 # uses CJK package
 Language chinese-traditional
 	GuiName         "Chinese (traditional)"
+	HasGuiSupport    true
 	QuoteStyle       english
 	Encoding        utf8-cjk
 	LangCode        zh_TW
@@ -350,6 +357,7 @@ End
 
 Language czech
 	GuiName          "Czech"
+	HasGuiSupport    true
 	BabelName        czech
 	PolyglossiaName  czech
 	QuoteStyle       german
@@ -359,6 +367,7 @@ End
 
 Language danish
 	GuiName          "Danish"
+	HasGuiSupport    true
 	BabelName        danish
 	PolyglossiaName  danish
 	QuoteStyle       danish
@@ -376,6 +385,7 @@ End
 
 Language dutch
 	GuiName          "Dutch"
+	HasGuiSupport    true
 	BabelName        dutch
 	PolyglossiaName  dutch
 	PolyglossiaOpts  "babelshorthands=true"
@@ -386,6 +396,7 @@ End
 
 Language english
 	GuiName          "English"
+	HasGuiSupport    true
 	BabelName        english
 	PolyglossiaName  english
 	QuoteStyle       english
@@ -434,6 +445,7 @@ End
 
 Language finnish
 	GuiName          "Finnish"
+	HasGuiSupport    true
 	BabelName        finnish
 	PolyglossiaName  finnish
 	QuoteStyle       swedish
@@ -444,6 +456,7 @@ End
 # We redefine \og and \fg (guillemets) for older french language definitions
 Language french
 	GuiName          "French"
+	HasGuiSupport    true
 	BabelName        french
 	PolyglossiaName  french
 	QuoteStyle       french
@@ -459,6 +472,7 @@ End
 
 Language galician
 	GuiName          "Galician"
+	HasGuiSupport    true
 	BabelName        galician
 	PolyglossiaName  galician
 	QuoteStyle       french
@@ -493,6 +507,7 @@ End
 
 Language ngerman
 	GuiName          "German"
+	HasGuiSupport    true
 	BabelName        ngerman
 	PolyglossiaName  german
 	PolyglossiaOpts  "babelshorthands=true"
@@ -532,6 +547,7 @@ End
 
 Language greek
 	GuiName           "Greek"
+	HasGuiSupport     true
 	BabelName         greek
 	PolyglossiaName   greek
 	QuoteStyle        french
@@ -555,6 +571,7 @@ End
 
 Language hebrew
 	GuiName           "Hebrew"
+	HasGuiSupport     true
 	BabelName         hebrew
 	PolyglossiaName   hebrew
 	Encoding          cp1255
@@ -599,6 +616,7 @@ End
 # language. We therefore the name of its hunspell dictionary.
 Language interlingua
 	GuiName          "Interlingua"
+	HasGuiSupport    true
 	BabelName        interlingua
 	PolyglossiaName  interlingua
 	Encoding         iso8859-15
@@ -616,6 +634,7 @@ End
 
 Language italian
 	GuiName          "Italian"
+	HasGuiSupport    true
 	BabelName        italian
 	PolyglossiaName  italian
 	QuoteStyle       french
@@ -630,6 +649,7 @@ End
 # InternalEncoding to true.
 Language japanese
 	GuiName          "Japanese"
+	HasGuiSupport    true
 	BabelName        japanese
 	Encoding         jis-platex
 	LangCode         ja_JP
@@ -729,6 +749,7 @@ End
 
 Language magyar
 	GuiName          "Hungarian"
+	HasGuiSupport    true
 	BabelName        magyar
 	PolyglossiaName  magyar
 	QuoteStyle       polish
@@ -767,6 +788,7 @@ End
 
 Language norsk
 	GuiName          "Norwegian (Bokmaal)"
+	HasGuiSupport    true
 	BabelName        norsk
 	PolyglossiaName  norsk
 	QuoteStyle       french
@@ -776,6 +798,7 @@ End
 
 Language nynorsk
 	GuiName          "Norwegian (Nynorsk)"
+	HasGuiSupport    true
 	BabelName        nynorsk
 	PolyglossiaName  nynorsk
 	QuoteStyle       french
@@ -804,6 +827,7 @@ End
 
 Language polish
 	GuiName          "Polish"
+	HasGuiSupport    true
 	BabelName        polish
 	PolyglossiaName  polish
 	QuoteStyle       polish
@@ -813,6 +837,7 @@ End
 
 Language portuguese
 	GuiName          "Portuguese"
+	HasGuiSupport    true
 	BabelName        portuges
 	PolyglossiaName  portuges
 	QuoteStyle       english
@@ -822,6 +847,7 @@ End
 
 Language romanian
 	GuiName          "Romanian"
+	HasGuiSupport    true
 	BabelName        romanian
 	PolyglossiaName  romanian
 	QuoteStyle       polish
@@ -831,6 +857,7 @@ End
 
 Language russian
 	GuiName          "Russian"
+	HasGuiSupport    true
 	BabelName        russian
 	PolyglossiaName  russian
 	QuoteStyle       french
@@ -867,6 +894,7 @@ End
 
 Language serbian
 	GuiName          "Serbian"
+	HasGuiSupport    true
 	BabelName        serbianc
 	PolyglossiaName  serbian
 	QuoteStyle       german
@@ -887,6 +915,7 @@ End
 
 Language slovak
 	GuiName          "Slovak"
+	HasGuiSupport    true
 	BabelName        slovak
 	PolyglossiaName  slovak
 	QuoteStyle       german
@@ -905,6 +934,7 @@ End
 
 Language spanish
 	GuiName          "Spanish"
+	HasGuiSupport    true
 	BabelName        spanish
 	PolyglossiaName  spanish
 	QuoteStyle       french
@@ -930,6 +960,7 @@ End
 
 Language swedish
 	GuiName          "Swedish"
+	HasGuiSupport    true
 	BabelName        swedish
 	PolyglossiaName  swedish
 	QuoteStyle       swedish
@@ -984,6 +1015,7 @@ End
 
 Language turkish
 	GuiName          "Turkish"
+	HasGuiSupport    true
 	BabelName        turkish
 	PolyglossiaName  turkish
 	QuoteStyle       french
@@ -1008,6 +1040,7 @@ End
 
 Language ukrainian
 	GuiName          "Ukrainian"
+	HasGuiSupport    true
 	BabelName        ukrainian
 	PolyglossiaName  ukrainian
 	QuoteStyle       french
diff --git a/src/Language.cpp b/src/Language.cpp
index 28ce4e2..b14d140 100644
--- a/src/Language.cpp
+++ b/src/Language.cpp
@@ -74,6 +74,7 @@ bool Language::readLanguage(Lexer & lex)
 		LA_END,
 		LA_FONTENC,
 		LA_GUINAME,
+		LA_HAS_GUI_SUPPORT,
 		LA_INTERNAL_ENC,
 		LA_LANG_CODE,
 		LA_LANG_VARIETY,
@@ -94,6 +95,7 @@ bool Language::readLanguage(Lexer & lex)
 		{ "end",                  LA_END },
 		{ "fontencoding",         LA_FONTENC },
 		{ "guiname",              LA_GUINAME },
+		{ "hasguisupport",        LA_HAS_GUI_SUPPORT },
 		{ "internalencoding",     LA_INTERNAL_ENC },
 		{ "langcode",             LA_LANG_CODE },
 		{ "langvariety",          LA_LANG_VARIETY },
@@ -153,6 +155,9 @@ bool Language::readLanguage(Lexer & lex)
 		case LA_GUINAME:
 			lex >> display_;
 			break;
+		case LA_HAS_GUI_SUPPORT:
+			lex >> has_gui_support_;
+			break;
 		case LA_INTERNAL_ENC:
 			lex >> internal_enc_;
 			break;
@@ -224,6 +229,9 @@ void Language::readLayoutTranslations(Language::TranslationMap const & trans, bo
 
 void Languages::read(FileName const & filename)
 {
+	// This is used to populate the list of GUI languages
+	gui_vector_.clear();
+
 	Lexer lex;
 	lex.setFile(filename);
 	lex.setContext("Languages::read");
@@ -254,8 +262,18 @@ void Languages::read(FileName const & filename)
 			LASSERT(ignore_language == 0, continue);
 			static const Language ignore_lang = l;
 			ignore_language = &ignore_lang;
-		} else
+		} else {
 			languagelist[l.lang()] = l;
+			/** also populate the list of GUI translations. Discard
+			 * (1) the languages that are not annotated as having GUI
+			 * support and (2) the languages without available
+			 * translation. The current GUI language is always
+			 * available in the list.
+			 */
+			if ((l.hasGuiSupport() && Messages::available(l.code()))
+			    || l.lang() == lyxrc.gui_language)
+				gui_vector_.push_back(make_pair(l.lang(), l.display()));
+		}
 	}
 
 	default_language = getLanguage("english");
diff --git a/src/Language.h b/src/Language.h
index b532d9c..e0ac10f 100644
--- a/src/Language.h
+++ b/src/Language.h
@@ -19,6 +19,7 @@
 #include "support/trivstring.h"
 
 #include <map>
+#include <vector>
 
 
 namespace lyx {
@@ -33,7 +34,7 @@ class Language {
 public:
 	///
 	Language() : rightToLeft_(false), encoding_(0), internal_enc_(false),
-				 as_babel_options_(false) {}
+				 as_babel_options_(false), has_gui_support_(false) {}
 	/// LyX language name
 	std::string const lang() const { return lang_; }
 	/// Babel language name
@@ -81,6 +82,8 @@ public:
 	std::string const fontenc() const { return fontenc_; }
 	/// This language needs to be passed to babel itself (not the class)
 	bool asBabelOptions() const { return as_babel_options_; }
+	/// This language correspongs to a translation of the GUI
+	bool hasGuiSupport() const { return has_gui_support_; }
 	///
 	bool read(Lexer & lex);
 	///
@@ -127,6 +130,8 @@ private:
 	///
 	bool as_babel_options_;
 	///
+	bool has_gui_support_;
+	///
 	TranslationMap layoutTranslations_;
 };
 
@@ -147,6 +152,8 @@ public:
 	///
 	typedef LanguageList::size_type size_type;
 	///
+	typedef std::vector< std::pair<trivstring, std::string> > DescVector;
+	///
 	void read(support::FileName const & filename);
 	///
 	void readLayoutTranslations(support::FileName const & filename);
@@ -158,11 +165,16 @@ public:
 	const_iterator begin() const { return languagelist.begin(); }
 	///
 	const_iterator end() const { return languagelist.end(); }
-	///
+	/// Return a vector of pairs (name, display) of languages that
+	/// correspond to available UI translations.
+	DescVector const & getGuiLanguages() const { return gui_vector_; }
+
 
 private:
 	///
 	LanguageList languagelist;
+	///
+	DescVector gui_vector_;
 };
 
 /// Global singleton instance.
diff --git a/src/frontends/qt4/GuiApplication.cpp b/src/frontends/qt4/GuiApplication.cpp
index 8bd22c8..abfee37 100644
--- a/src/frontends/qt4/GuiApplication.cpp
+++ b/src/frontends/qt4/GuiApplication.cpp
@@ -912,8 +912,8 @@ public:
 
 struct GuiApplication::Private
 {
-	Private(): language_model_(0), meta_fake_bit(NoModifier),
-		global_menubar_(0)
+	Private(): language_model_(0), gui_language_model_(0),
+	           meta_fake_bit(NoModifier), global_menubar_(0)
 	{
 	#if (QT_VERSION < 0x050000) || (QT_VERSION >= 0x050400)
 	#if defined(Q_OS_WIN) || defined(Q_CYGWIN_WIN)
@@ -933,6 +933,8 @@ struct GuiApplication::Private
 	///
 	QSortFilterProxyModel * language_model_;
 	///
+	QAbstractItemModel * gui_language_model_;
+	///
 	GuiClipboard clipboard_;
 	///
 	GuiSelection selection_;
@@ -2494,6 +2496,34 @@ QAbstractItemModel * GuiApplication::languageModel()
 }
 
 
+QAbstractItemModel * GuiApplication::guiLanguageModel()
+{
+	if (d->gui_language_model_)
+		return d->gui_language_model_;
+
+	QAbstractItemModel * lang_model = new QStandardItemModel(this);
+	lang_model->insertColumn(0);
+
+	Languages::DescVector const & guivec = lyx::languages.getGuiLanguages();
+	Languages::DescVector::const_iterator it = guivec.begin();
+	Languages::DescVector::const_iterator end = guivec.end();
+	for (; it != end; ++it) {
+		int const current_row = lang_model->rowCount();
+		lang_model->insertRow(current_row);
+		QModelIndex item = lang_model->index(current_row, 0);
+		lang_model->setData(item, qt_(it->second), Qt::DisplayRole);
+		lang_model->setData(item, toqstr(it->first), Qt::UserRole);
+	}
+	lang_model->sort(0);
+	lang_model->insertRow(0);
+	QModelIndex item = lang_model->index(0, 0);
+	lang_model->setData(item, qt_("Default"), Qt::DisplayRole);
+	lang_model->setData(item, toqstr("auto"), Qt::UserRole);
+	d->gui_language_model_ = lang_model;
+	return d->gui_language_model_;
+}
+
+
 void GuiApplication::restoreGuiSession()
 {
 	if (!lyxrc.load_session)
diff --git a/src/frontends/qt4/GuiApplication.h b/src/frontends/qt4/GuiApplication.h
index bfc242c..99746f6 100644
--- a/src/frontends/qt4/GuiApplication.h
+++ b/src/frontends/qt4/GuiApplication.h
@@ -135,6 +135,8 @@ public:
 	ColorCache & colorCache();
 	///
 	QAbstractItemModel * languageModel();
+	///
+	QAbstractItemModel * guiLanguageModel();
 
 	/// return a suitable serif font name.
 	QString const romanFontName();
diff --git a/src/frontends/qt4/GuiPrefs.cpp b/src/frontends/qt4/GuiPrefs.cpp
index 1836501..280bab6 100644
--- a/src/frontends/qt4/GuiPrefs.cpp
+++ b/src/frontends/qt4/GuiPrefs.cpp
@@ -2309,38 +2309,15 @@ PrefLanguage::PrefLanguage(GuiPreferences * form)
 	startCommandED->setValidator(new NoNewLineValidator(startCommandED));
 	endCommandED->setValidator(new NoNewLineValidator(endCommandED));
 
-	uiLanguageCO->clear();
-
-	QAbstractItemModel * language_model = guiApp->languageModel();
-	// FIXME: it would be nice if sorting was enabled/disabled via a checkbox.
-	language_model->sort(0);
 	defaultDecimalPointLE->setInputMask("X; ");
 	defaultDecimalPointLE->setMaxLength(1);
 
 	defaultLengthUnitCO->addItem(lyx::qt_(unit_name_gui[Length::CM]), Length::CM);
 	defaultLengthUnitCO->addItem(lyx::qt_(unit_name_gui[Length::IN]), Length::IN);
 
-	set<string> added;
+	QAbstractItemModel * gui_language_model = guiApp->guiLanguageModel();
 	uiLanguageCO->blockSignals(true);
-	uiLanguageCO->addItem(qt_("Default"), toqstr("auto"));
-	for (int i = 0; i != language_model->rowCount(); ++i) {
-		QModelIndex index = language_model->index(i, 0);
-		// Filter the list based on the available translation and add
-		// each language code only once
-		string const name = fromqstr(index.data(Qt::UserRole).toString());
-		Language const * lang = languages.getLanguage(name);
-		if (!lang)
-			continue;
-		// never remove the currently selected language
-		if (name != form->rc().gui_language
-		    && name != lyxrc.gui_language
-		    && (!Messages::available(lang->code())
-			|| added.find(lang->code()) != added.end()))
-				continue;
-		added.insert(lang->code());
-		uiLanguageCO->addItem(index.data(Qt::DisplayRole).toString(),
-			index.data(Qt::UserRole).toString());
-	}
+	uiLanguageCO->setModel(gui_language_model);
 	uiLanguageCO->blockSignals(false);
 }
 
-- 
1.7.9.5

Reply via email to