home *** CD-ROM | disk | FTP | other *** search
- /**
- * File: modules/Language.ycp
- * Module: Language
- * Summary: This module does all language related stuff:
- * Authors: Klaus Kaempf <kkaempf@suse.de>
- * Thomas Roelz <tom@suse.de>
- * Maintainer: Jiri Suchomel <jsuchome@suse.cz>
- *
- * $Id: Language.ycp 32888 2006-09-14 11:33:57Z jsuchome $
- */
-
- {
-
- module "Language";
- textdomain "country";
-
-
- import "AsciiFile";
- import "Directory";
- import "Encoding";
- import "FileUtils";
- import "Linuxrc";
- import "Misc";
- import "Mode";
- import "PackageCallbacksInit";
- import "PackageSystem";
- import "ProductFeatures";
- import "Stage";
-
-
- /**
- * currently selected language
- */
- global string language = "en_US";
-
- /**
- * original language
- */
- global string language_on_entry = "en_US";
-
- /**
- * language preselected in /etc/install.inf
- */
- global string preselected = "en_US";
-
- /**
- * user readable description of language
- */
- string name = "English (US)";
-
- boolean linuxrc_language_set = false;
-
- /**
- * Default language to be restored with MakeProposal.
- */
- string default_language = "en_US";
-
-
- /**
- * Default settings for ROOT_USES_LANG in /etc/sysconfig/language
- */
- string rootlang = "ctype";
-
-
- /**
- * Default settings for INSTALLED_LANGUAGES in /etc/sysconfig/language
- */
- global string languages = "";
-
- /**
- * Original value of INSTALLED_LANGUAGES
- */
- global string languages_on_entry = "";
-
- /**
- * Use utf8 in locale
- */
- boolean use_utf8 = true;
-
- /**
- * ncurses mode
- */
- boolean text_mode = nil;
-
- global boolean ExpertSettingsChanged = false;
-
- /**
- * level of translation completeness
- */
- map<string,integer> translation_status = $[];
-
- // map (locale: 1) of available locales
- map<string,integer> locales = $[];
-
- // map with all languages (cached - needs to be reread for retranslation)
- map<string, list> languages_map = $[];
-
- // mapping of language to its default (proposed) time zone
- map<string,string> lang2timezone = $[];
-
- // mapping of language to its default (proposed) kbd layout
- map<string,string> lang2keyboard = $[];
-
- // directory with languages descriptions
- string languages_directory = nil;
-
- // languages that cannot be correctly shown in text mode
- list cjk_languages = [ "ja", "ko", "zh", "hi", "km", "pa", "bn" ];
-
- /**
- * Check if the language is "CJK"
- * (and thus could not be shown in text mode - see bug #102958)
- */
- global define boolean CJKLanguage (string lang) {
-
- string l = substring (lang, 0, 2);
- return contains (cjk_languages, l);
- }
-
-
- /**
- * return the value of text_mode (true for ncurses)
- */
- global define boolean GetTextMode () {
-
- if (text_mode== nil)
- {
- map display_info = UI::GetDisplayInfo ();
- text_mode = display_info["TextMode"]:false;
- }
- return text_mode;
- }
-
- /**
- * Read language DB: translatable strings will be translated to current language
- */
- define void read_languages_map() {
-
- if (languages_directory == nil)
- {
- languages_directory = Directory::datadir + "/languages";
- }
-
- foreach (string file,
- (list<string>) SCR::Read (.target.dir, languages_directory, []),
- {
- if (!regexpmatch (file, "language_.+\\.ycp$"))
- return;
- map language_map = (map)
- eval (SCR::Read (.target.yast2, "languages/" + file));
- if (language_map == nil) language_map = $[];
- string code = file;
- foreach (string key, any val, (map<string,any>) language_map, {
- if (is (val, list))
- {
- languages_map[key] = (list) val;
- code = key;
- }
- });
- if (!haskey (lang2timezone, code))
- lang2timezone[code] = language_map["timezone"]:"US/Eastern";
- if (!haskey (lang2keyboard, code))
- lang2keyboard[code] = language_map["keyboard"]:"en_US";
- });
-
- if (languages_map == nil) languages_map = $[];
- }
-
- /**
- * Read only the map of one language
- * @param language code
- */
- define map ReadLanguageMap (string lang) {
-
- map ret = $[];
-
- if (languages_directory == nil)
- {
- languages_directory = Directory::datadir + "/languages";
- }
- string file = sformat ("language_%1.ycp", lang);
- if (FileUtils::Exists (languages_directory + "/" + file))
- {
- ret = (map) eval (SCR::Read (.target.yast2, "languages/" + file));
- if (ret == nil)
- ret = $[];
- }
- return ret;
- }
-
- /**
- * Return the whole map with language descriptions
- * @param force force new loading of the map from the files (forces the change
- * of translations to current language)
- */
- global map<string, list> GetLanguagesMap (boolean force) {
-
- if (size (languages_map) == 0 || force)
- read_languages_map();
- return languages_map;
- }
-
- /**
- * return the content of lang2timezone map
- * (mapping of languages to their default (proposed) time zones)
- */
- global define map<string,string> GetLang2TimezoneMap () {
- return lang2timezone;
- }
-
- /**
- * return the content of lang2keyboard map
- * (mapping of languages to their default (proposed) keyboard layouts)
- */
- global define map<string,string> GetLang2KeyboardMap () {
- return lang2keyboard;
- }
-
- /**
- * return the map of all supported countries and language codes
- */
- global define map<string,integer> GetLocales () {
-
- if (locales == nil || locales == $[])
- {
- map out = (map)SCR::Execute (.target.bash_output, "/usr/bin/locale -a");
- foreach (string l, splitstring (out["stdout"]:"", "\n"), {
- integer pos = findfirstof (l, ".@");
-
- if (pos != nil && pos >= 0)
- l = substring (l, 0, pos);
-
- locales [l] = 1;
- });
- }
-
- return locales;
- }
-
-
- /**
- * Set module to selected language.
- * @param lang language string ISO code of language
- */
- global define void Set (string lang) {
-
- y2milestone ("original language: %1; setting to lang:%2", language, lang);
-
- if (language != lang) // Do it only if different
- {
- if (size (languages_map) == 0)
- read_languages_map();
-
- if (size (locales) == 0)
- GetLocales ();
-
- if (locales[lang]:0 != 1 && size(lang) > 0)
- {
- lang = substring (lang, 0, 2);
- boolean found = false;
- foreach (string k, list dummy, languages_map,
- {
- if (!found && substring (k, 0, 2) ==lang)
- {
- found = true;
- lang = k;
- }
- });
- }
- name = languages_map[lang, 0]:lang;
- if (Mode::config ())
- name = languages_map[lang, 4]:lang;
- language = lang;
- Encoding::SetEncLang (language);
- }
-
- if (Stage::initial () && !Mode::test ())
- {
- map yinf = $[];
- AsciiFile::SetDelimiter (yinf, " ");
- AsciiFile::ReadFile (yinf, "/etc/yast.inf");
- list lines = AsciiFile::FindLineField (yinf, 0, "Language:");
- if (size(lines) > 0)
- {
- AsciiFile::ChangeLineField (yinf, lines[0]:-1, 1, language);
- }
- else
- {
- AsciiFile::AppendLine (yinf, ["Language:", language] );
- }
- AsciiFile::RewriteFile (yinf, "/etc/yast.inf");
-
- // update "name" for proposal when it cannot be shown correctly
- if (GetTextMode () && CJKLanguage (lang) && !CJKLanguage (preselected))
- {
- name = languages_map[lang, 1]:lang;
- }
- }
- }
-
-
- /**
- * Set the language that was read from sysconfig,
- * read only one needed language file
- */
- global define void QuickSet (string lang) {
-
- y2milestone ("original language: %1; setting to lang:%2", language, lang);
-
- if (language != lang)
- {
- map lang_map = ReadLanguageMap (lang);
- name = lang_map[lang, 0]:lang;
- language = lang;
- Encoding::SetEncLang (language);
- }
- }
-
- global define boolean LinuxrcLangSet() {
-
- return linuxrc_language_set;
- }
-
- /**
- * generate the whole locale string for given language according to DB
- * (e.g. de_DE -> de_DE.UTF-8)
- */
- global define string GetLocaleString (string lang) {
-
- if (size (languages_map) == 0)
- read_languages_map();
-
- list language_info = languages_map[lang]:[];
- if (!haskey (languages_map, lang))
- language_info = [ lang, lang, ".UTF-8" ];
-
- // full language code
- string val = language;
- if( use_utf8 )
- val = val + language_info[2]:"";
- else
- val = val + language_info[3]:"";
-
- y2milestone( "locale %1", val );
- return val;
- }
-
-
- /**
- * Store current language as default language.
- */
- global define void SetDefault() {
- y2milestone("Setting default language: %1", language);
- default_language = language;
- return;
- }
-
- /**
- * Read the RC_LANG value from sysconfig and exctract language from it
- * @return language
- */
- global define string ReadSysconfigLanguage () {
-
- string local_lang = Misc::SysconfigRead (.sysconfig.language.RC_LANG, language);
-
- integer pos = findfirstof (local_lang, ".@");
-
- if (pos != nil && pos >= 0)
- {
- local_lang = substring (local_lang, 0, pos);
- }
-
- y2milestone ("language from sysconfig: %1", local_lang);
- return local_lang;
- }
-
- /**
- * Read the rest of language values from sysconfig
- */
- global define void ReadSysconfigValues () {
-
- rootlang = Misc::SysconfigRead (.sysconfig.language.ROOT_USES_LANG, rootlang);
- if (!Stage::initial ())
- {
- string val = toupper (Misc::SysconfigRead (.sysconfig.language.RC_LANG, ""));
- use_utf8 = find (val, ".UTF-8") > 0;
- }
- else
- {
- use_utf8 = true;
- }
- languages = Misc::SysconfigRead (.sysconfig.language.INSTALLED_LANGUAGES, "");
- }
-
- /**
- * Constructor
- *
- * Initializes module either from /etc/install.inf
- * or from /etc/sysconfig/language
- */
- global define void Language() {
-
- if (Mode::config ())
- {
- // read the translated name: bug #180633
- read_languages_map();
- name = languages_map[language, 4]:language;
- return;
- }
-
- if (Stage::initial ())
- {
- string lang = (string)SCR::Read (.content.LANGUAGE);
- y2milestone ("content LANGUAGE %1", lang);
-
- preselected = Linuxrc::InstallInf ("Locale");
- y2milestone ("install_inf Locale %1", preselected);
- if (preselected != nil && preselected != "")
- {
- lang = preselected;
- if (lang != "en_US")
- {
- linuxrc_language_set = true;
- }
- }
- else
- preselected = "en_US";
-
- if (lang == nil)
- lang = "";
- y2milestone ("lang after checking /etc/install.inf: %1", lang );
- if (lang == "")
- {
- lang = Pkg::GetLocale();
- y2milestone ("setting lang to default language: %1", lang);
- }
- // Ignore any previous settings and take language from control file.
- string l = ProductFeatures::GetStringFeature ("globals","language");
- if (l != nil && l != "")
- {
- lang = l;
- y2milestone ("setting lang to ProductFeatures::language: %1", lang);
- }
- Set (lang); // coming from /etc/install.inf
- SetDefault (); // also default
- }
- else
- {
- string local_lang = ReadSysconfigLanguage ();
- QuickSet (local_lang);
- SetDefault(); // also default
- }
- if (SCR::Read (.target.size, "/etc/sysconfig/language") > 0)
- {
- ReadSysconfigValues ();
- }
- Encoding::SetUtf8Lang (use_utf8);
- }
-
- /**
- * Store the inital values; in normal mode, read from system was done in constructor
- * @param really: also read the values from the system
- */
- global define boolean Read (boolean really) {
-
- if (really)
- {
- Set (ReadSysconfigLanguage ());
- ReadSysconfigValues ();
- }
-
- language_on_entry = language;
- languages_on_entry = languages;
-
- y2milestone ("language: %1, languages: %2", language_on_entry, languages_on_entry);
-
- ExpertSettingsChanged = false;
-
- return true;
- }
-
- /**
- * was anything modified?
- */
- global define boolean Modified () {
-
- return (language != language_on_entry ||
- ExpertSettingsChanged ||
- sort (splitstring (languages, ",")) !=
- sort (splitstring (languages_on_entry, ","))
- );
- }
-
- /**
- * Does the modification of language(s) require installation of new packages?
- * This test compares the list of original languages (primary+secondary) with
- * the list after user's modifications
- */
- global define boolean PackagesModified () {
-
- return
- sort (union(splitstring(languages, ","), [language])) !=
- sort (union(splitstring(languages_on_entry, ","), [language_on_entry]));
- }
-
- /**
- * GetExpertValues()
- *
- * Return the values for the various expert settings in a map
- *
- * @param -
- *
- * @return map with values filled in
- *
- */
- global define map GetExpertValues () {
-
- return $[
- "rootlang" : rootlang,
- "use_utf8" : use_utf8,
- ];
- }
-
- /**
- * SetExpertValues()
- *
- * Set the values of the various expert setting
- *
- * @param val map with new values of expert settings
- *
- * @return void
- *
- */
- global define void SetExpertValues (map val) {
-
- if (haskey (val,"rootlang") && size (val["rootlang"]:"") >0)
- {
- rootlang = val["rootlang"]:"";
- }
- if (haskey (val,"use_utf8"))
- {
- use_utf8 = val["use_utf8"]:false;
- Encoding::SetUtf8Lang (use_utf8);
- }
- }
-
- /**
- * WfmSetLanguag()
- *
- * Set the given language in WFM and UI
- *
- * @param language (could be different from current in CJK case)
- *
- * @return -
- */
- global define void WfmSetGivenLanguage (string lang) {
-
- if (Mode::config ())
- return;
-
- string encoding = (use_utf8) ? "UTF-8" : Encoding::console;
-
- y2milestone ( "language %1 enc %2 utf8:%3", lang, encoding, use_utf8 );
-
- UI::SetLanguage (lang, encoding);
-
- if (use_utf8)
- {
- WFM::SetLanguage(lang, "UTF-8");
- }
- else
- {
- WFM::SetLanguage(lang);
- }
- if (Stage::initial () && !GetTextMode ())
- {
- // update font for windowmanager windows
- SCR::Write (.FvwmCommand.lang, lang);
- }
- }
-
-
- /**
- * WfmSetLanguag()
- *
- * Set the current language in WFM and UI
- *
- * @param -
- *
- * @return -
- */
- global define void WfmSetLanguage () {
-
- WfmSetGivenLanguage (language);
- }
-
-
- /**
- * Return proposal string.
- *
- * @return string user readable description.
- * If force_reset is true reset the module to the language
- * stored in default_language.
- */
- global define list<string> MakeProposal (boolean force_reset,boolean language_changed)
- {
- y2milestone("force_reset: %1", force_reset);
- y2milestone("language_changed: %1", language_changed);
-
- if (force_reset)
- {
- Set (default_language); // reset
- }
- list<string> ret = [
- // summary label
- sformat (_("Primary Language: %1"), name)
- ];
- if (languages != "" && languages != language)
- {
- if (size (languages_map) == 0 || language_changed)
- {
- read_languages_map();
- }
- list<string> langs = [];
- foreach (string lang, splitstring (languages, ","), {
- if (lang != language)
- {
- string l = languages_map[lang,4]:languages_map[lang,0]:"";
- if (l != "")
- langs = add (langs, l);
- }
- });
- if (size (langs) > 0)
- {
- // summary label
- ret = add (ret, sformat (_("Additional Languages: %1"),
- mergestring (langs,", ")));
- }
- }
- return ret;
- }
-
- /**
- * Return 'simple' proposal string.
- * @return string preformated description.
- */
- global define string MakeSimpleProposal ()
- {
- import "HTML";
-
- list<string> ret = [
- // summary label
- sformat (_("Primary Language: %1"), name)
- ];
- if (languages != "" && languages != language)
- {
- list<string> langs = [];
- foreach (string lang, splitstring (languages, ","), {
- if (lang != language)
- {
- string l = languages_map[lang,4]:languages_map[lang,0]:"";
- if (l != "")
- langs = add (langs, l);
- }
- });
- if (size (langs) > 0)
- {
- // summary label
- ret = add (ret, sformat (_("Additional Languages: %1"),
- HTML::List (langs)));
- }
- }
- return HTML::List (ret);
- }
-
- /**
- * return user readable description of language
- */
- global define string GetName () {
-
- return name;
- }
-
- /**
- * Return a map of ids and names to build up a selection list
- * for the user. The key is used later in the Set function
- * to select this language. The name is a translated string.
- *
- * @return map of $[ language : [ utf8-name, ascii-name] ...]
- * for all known languages
- * 'language' is the (2 or 5 char) ISO language code.
- * 'utf8-name' is a user-readable (UTF-8 encoded !) string.
- * 'ascii-name' is an english (ascii encoded !) string.
- * @see Set
- */
- global define map<string, list> Selection() {
-
- read_languages_map();
-
- return mapmap (string code, list data, languages_map,
- ``($[code: [data[0]:"", data[1]:"", data[4]:data[0]:""]]));
- }
-
-
- /**
- * Save state to target.
- */
- global define void Save() {
-
- string loc = GetLocaleString (language);
-
- SCR::Write (.sysconfig.language.RC_LANG, loc);
-
- if (find (loc, "zh_HK") == 0)
- {
- SCR::Write(.sysconfig.language.RC_LC_MESSAGES,"zh_TW"+substring(loc,5));
- }
- else
- {
- // FIXME ugly hack: see bug #47711
- string lc_mess = (string)SCR::Read(.sysconfig.language.RC_LC_MESSAGES);
- if (find (lc_mess, "zh_TW") == 0)
- {
- SCR::Write (.sysconfig.language.RC_LC_MESSAGES, "");
- }
- }
-
- SCR::Write (.sysconfig.language.ROOT_USES_LANG, rootlang);
- SCR::Write (.sysconfig.language.INSTALLED_LANGUAGES, languages);
- SCR::Write (.sysconfig.language, nil);
-
- y2milestone ("Saved data for language: <%1>", loc);
- }
-
- /**
- * Initializes source and target,
- * computes the packages necessary to install and uninstall,
- * checks for disk space (#50745)
- * @return false when there is not enough disk space for new packages
- */
- global define boolean PackagesInit (list<string> selected_languages) {
-
- PackageSystem::EnsureSourceInit ();
- PackageSystem::EnsureTargetInit ();
-
- Pkg::SetAdditionalLocales (selected_languages);
- Pkg::PkgSolve (true);
-
- boolean ok = true;
- foreach (string mountpoint, list<integer> usage, Pkg::TargetGetDU (), {
- if (usage[2]:0 > usage[0]:0)
- {
- ok = false;
- }
- });
- return ok;;
- }
-
- /**
- * Install and uninstall packages selected by Pkg::SetAdditionalLocales
- */
- global define boolean PackagesCommit () {
-
- PackageCallbacksInit::InitPackageCallbacks ();
- Pkg::PkgCommit (0);
- return true;
- }
-
- /**
- * de_DE@UTF-8 -> "DE"
- * @return country part of language
- */
- global define string GetGivenLanguageCountry (string lang) {
-
- string country = lang;
-
- if (country == nil || country == "")
- country = default_language;
- if (country != nil && country != "")
- {
- if (find (country, "@") != -1)
- country = splitstring (country, "@") [0]:"";
- }
- if (country != nil && country != "")
- {
- if (find(country, "_") != -1)
- country = splitstring (country, "_") [1]:"";
- else
- country = toupper(country);
- }
-
- y2debug("country=%1",country);
- return country;
- }
-
-
- /**
- * de_DE@UTF-8 -> "DE"
- * @return country part of language
- */
- global define string GetLanguageCountry() {
-
- return GetGivenLanguageCountry (language);
- }
-
-
- /**
- * Returns true if translation for given language is not complete
- */
- global define boolean IncompleteTranslation (string lang) {
-
- if (!haskey (translation_status,lang))
- {
- string file = "/usr/lib/YaST2/trans/" + lang + ".status";
- if (!FileUtils::Exists (file))
- {
- string ll = splitstring (lang, "_") [0]:"";
- if (ll != "")
- file = "/usr/lib/YaST2/trans/" + ll + ".status";
- }
-
- string status = (string) SCR::Read (.target.string, file);
-
- if (status != nil && status != "")
- {
- integer to_i = tointeger (status);
- translation_status[lang] = (to_i != nil) ? to_i : 0;
- }
- else
- translation_status[lang] = 100;
- }
- integer treshold = tointeger (ProductFeatures::GetStringFeature (
- "globals", "incomplete_translation_treshold"));
- if (treshold == nil) treshold = 95;
-
- return translation_status[lang]:0 < treshold;
- }
-
- /**
- * AutoYaST interface function: Get the Language configuration from a map.
- * @param settings imported map
- * @return success
- */
- global define boolean Import (map settings) {
-
- if (languages_on_entry == "")
- Read (false); // only save original values
-
- Set (settings["language"]:language);
- languages = settings["languages"]:languages;
-
- list<string> llanguages = splitstring (languages, ",");
- if (!contains (llanguages, language))
- {
- llanguages = add (llanguages, language);
- languages = mergestring (llanguages, ",");
- }
- // set the language dependent packages to install
- if (Mode::autoinst ())
- {
- Pkg::SetLocale (language);
- Pkg::SetAdditionalLocales (splitstring (languages, ","));
- }
-
- return true;
- }
-
- /**
- * AutoYaST interface function: Return the Language configuration as a map.
- * @return map with the settings
- */
- global define map Export () {
-
- map ret = $[
- "language" : language,
- "languages" : languages
- ];
- return ret;
- }
-
- /**
- * AutoYaST interface function: Return the summary of Language configuration as a map.
- * @return summary string
- */
- global define string Summary () {
-
- return MakeSimpleProposal ();
- }
-
-
- /* EOF */
- }
-