This patch is an alternative to commit ed1515ef69, which introduced the
installed_translations file. The new approach is to search for the .mo files. I did not want to do that at first because I feared that in some situations the files could be at some place where we do not expect them. But since we force the path with bindtextdomain() there is little/no risk.

commit ed1515ef69 needs to be reverted to test this. And if we go this way, the cmake infrastructure patch shall be reverted too.

One reason why I did not like the other solution is that distribution may package .mo files separately by language and this requires to update the installed _translation file.

Comments welcome.

JMarc

>From f653cbd8e88e906885bc7ab9107f765e9b4922c2 Mon Sep 17 00:00:00 2001
From: Jean-Marc Lasgouttes <lasgout...@lyx.org>
Date: Thu, 23 Aug 2012 15:08:21 +0200
Subject: [PATCH] Tracking correctly available translations (take 2)

The previous scheme of loading all possible translations and checking
whether the work is a bit too much "brute force" and causes problems
on Mac OS X (documents loaded with the wrong language).

Now there is an helper static method in Messages class that checks
whether a readable .mo file exist for the language. There should be an
API in gettext for doing that, but alas it is not possible.

As a consequence the method Language::translated() has been removed,
along with its cache.
---
 src/Language.cpp               |    4 ----
 src/Language.h                 |    6 +-----
 src/frontends/qt4/GuiPrefs.cpp |    9 +++++++--
 src/support/Messages.cpp       |   17 +++++++++++++++--
 src/support/Messages.h         |    4 ++--
 5 files changed, 25 insertions(+), 15 deletions(-)

diff --git a/src/Language.cpp b/src/Language.cpp
index 13e43c2..286dc92 100644
--- a/src/Language.cpp
+++ b/src/Language.cpp
@@ -196,10 +196,6 @@ bool Language::read(Lexer & lex)
 		encoding_ = encodings.fromLyXName("iso8859-1");
 		LYXERR0("Unknown encoding " << encodingStr_);
 	}
-	// cache translation status. Calling getMessages() directly in
-	// PrefLanguage::PrefLanguage() did only work if the gui language
-	// was set to auto (otherwise all languages would be marked as available).
-	translated_ = getMessages(code()).available();
 	return true;
 }
 
diff --git a/src/Language.h b/src/Language.h
index 71b6777..c17c527 100644
--- a/src/Language.h
+++ b/src/Language.h
@@ -31,7 +31,7 @@ class Lexer;
 class Language {
 public:
 	///
-	Language() : rightToLeft_(false), translated_(false) {}
+	Language() : rightToLeft_(false) {}
 	/// LyX language name
 	std::string const & lang() const { return lang_; }
 	/// Babel language name
@@ -48,8 +48,6 @@ public:
 	std::string const & display() const { return display_; }
 	/// is this a RTL language?
 	bool rightToLeft() const { return rightToLeft_; }
-	/// Is an (at least partial) translation of this language available?
-	bool translated() const { return translated_; }
 	/**
 	 * Translate a string from the layout files that appears in the output.
 	 * It takes the translations from lib/layouttranslations instead of
@@ -121,8 +119,6 @@ private:
 	///
 	bool as_babel_options_;
 	///
-	bool translated_;
-	///
 	TranslationMap layoutTranslations_;
 };
 
diff --git a/src/frontends/qt4/GuiPrefs.cpp b/src/frontends/qt4/GuiPrefs.cpp
index 39f6841..1e40aa9 100644
--- a/src/frontends/qt4/GuiPrefs.cpp
+++ b/src/frontends/qt4/GuiPrefs.cpp
@@ -46,6 +46,7 @@
 #include "support/gettext.h"
 #include "support/lassert.h"
 #include "support/lstrings.h"
+#include "support/Messages.h"
 #include "support/os.h"
 #include "support/Package.h"
 
@@ -2301,9 +2302,13 @@ PrefLanguage::PrefLanguage(GuiPreferences * form)
 		// 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 (lang && name != form->rc().gui_language && name != lyxrc.gui_language)
-			if (!lang->translated() || added.find(lang->code()) != added.end())
+		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(),
diff --git a/src/support/Messages.cpp b/src/support/Messages.cpp
index cceec15..a1df980 100644
--- a/src/support/Messages.cpp
+++ b/src/support/Messages.cpp
@@ -112,9 +112,22 @@ string Messages::language() const
 }
 
 
-bool Messages::available() const
+bool Messages::available(string const & c)
 {
-	return !language().empty();
+	static string locale_dir = package().locale_dir().toFilesystemEncoding();
+	string code = c;
+	// this loops at most twice
+	while (true) {
+		string const filen = locale_dir + "/" + code 
+			+ "/LC_MESSAGES/"PACKAGE".mo";
+		if (FileName(filen).isReadableFile())
+			return true;
+		if (contains(code, '_'))
+			code = token(code, '_', 0);
+		else return false;
+	}
+	return false;
+
 }
 
 
diff --git a/src/support/Messages.h b/src/support/Messages.h
index 35a3bea..4ba2737 100644
--- a/src/support/Messages.h
+++ b/src/support/Messages.h
@@ -28,8 +28,8 @@ public:
 	docstring const get(std::string const & msg) const;
 	/// What is the language associated with this translation?
 	std::string language() const;
-	/// Is an (at least partial) translation of this language available?
-	bool available() const;
+	/// Is an (at least partial) translation of language with code \p c available?
+	static bool available(std::string const & c);
 	///
 	static void init();
 
-- 
1.7.0.4

Reply via email to