From c4e54b004b31b76a66cdf8db07f68bc0723f29c9 Mon Sep 17 00:00:00 2001 From: Oliver Duis Date: Sat, 16 Jul 2011 13:39:28 +0200 Subject: [PATCH] Automatic language detection (Win Vista/7) see issue 847 --- rtdata/languages/Deutsch | 2 + rtdata/languages/default | 1 + rtgui/multilangmgr.cc | 81 ++++++++++++++++++++++++++++++++++++++++ rtgui/multilangmgr.h | 5 +++ rtgui/options.cc | 5 +++ rtgui/options.h | 1 + rtgui/preferences.cc | 13 ++++++- rtgui/preferences.h | 5 ++- 8 files changed, 111 insertions(+), 2 deletions(-) diff --git a/rtdata/languages/Deutsch b/rtdata/languages/Deutsch index 77f6c3ac3..cdefc8865 100644 --- a/rtdata/languages/Deutsch +++ b/rtdata/languages/Deutsch @@ -15,6 +15,7 @@ #13 Erweiterung (oduis) #14 05.12.2010, 3.0 alpha: Erweiterung und Korrekturen (Metex) #15 Jan-Jun 2011: Erweiterungen und Korrekturen (MaWe). Letzter Stand: 30.06.2011 +#16 Erweiterung (oduis) ABOUT_TAB_BUILD;Version ABOUT_TAB_CREDITS;Danksagungen ABOUT_TAB_LICENSE;Lizenz @@ -611,6 +612,7 @@ PREFERENCES_INTENT_RELATIVE;Relativ farbmetrisch PREFERENCES_INTENT_SATURATION;Sättigung PREFERENCES_INTERNALTHUMBIFUNTOUCHED;Voransicht aus RAW, wenn noch nicht editiert PREFERENCES_LIVETHUMBNAILS;Live Voransichten (langsamer) +PREFERENCES_LANGAUTODETECT;Betriebssystem-Einstellung verwenden PREFERENCES_MENUOPTIONS;Menüoptionen PREFERENCES_MENUGROUPRANK;Untermenü Bewertung PREFERENCES_MENUGROUPLABEL;Untermenü Farbmarkierung diff --git a/rtdata/languages/default b/rtdata/languages/default index 229c5e396..fa35cc43f 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -610,6 +610,7 @@ PREFERENCES_INTENT_PERCEPTUAL;Perceptual PREFERENCES_INTENT_RELATIVE;Relative Colorimetric PREFERENCES_INTENT_SATURATION;Saturation PREFERENCES_INTERNALTHUMBIFUNTOUCHED;Show RAW internal thumbnail if unedited +PREFERENCES_LANGAUTODETECT;Use OS language setting PREFERENCES_LIVETHUMBNAILS;Live Thumbnails (slower) PREFERENCES_MENUOPTIONS;Menu Options PREFERENCES_MENUGROUPRANK;Group Ranking diff --git a/rtgui/multilangmgr.cc b/rtgui/multilangmgr.cc index 15cf4b489..5f3e3c865 100644 --- a/rtgui/multilangmgr.cc +++ b/rtgui/multilangmgr.cc @@ -20,11 +20,19 @@ #include #include #include +#ifdef WIN32 +// Desired auto detect function is Vista+ +#define _WIN32_WINNT 0x0600 +#include +#include +#undef _WIN32_WINNT +#endif MultiLangMgr langMgr; Glib::ustring M (std::string key) { return langMgr.getStr (key); } +// fb is fallback manager if the first could not be loaded bool MultiLangMgr::load (Glib::ustring fname, MultiLangMgr* fb) { FILE *f = safe_g_fopen (fname, "rt"); @@ -85,6 +93,79 @@ bool MultiLangMgr::save (Glib::ustring fname) { return true; } + +bool MultiLangMgr::isOSLanguageDetectSupported() { +#ifdef WIN32 + // Only on Vista or above + return LOBYTE(LOWORD(GetVersion()))>=6; +#else + return false; +#endif +} + + +// returns Language name mapped from the currently selected OS language +Glib::ustring MultiLangMgr::getOSUserLanguage() { + Glib::ustring langName = Glib::ustring("default"); + + if (isOSLanguageDetectSupported()) { + + // TODO: Add support for other OS here +#ifdef WIN32 + WCHAR langRFCU[64] = {0}; + if (GetUserDefaultLocaleName(langRFCU,64)!=0 && lstrlenW(langRFCU)>=2) { + // convert UNICODE16 to GTK + char langRFC[64]; + WideCharToMultiByte(CP_UTF8,0,langRFCU,-1,langRFC,64,0,0); + Glib::ustring localRFC=Glib::ustring(langRFC); + + langName=TranslateRFC2Language(localRFC); + } +#endif + } else printf("Automatic language detection not supported on your OS\n"); + + return langName; +} + +// Translates RFC standard language code to file name, e.g. "de-DE" to "Deutsch" +Glib::ustring MultiLangMgr::TranslateRFC2Language(Glib::ustring rfcName) { + if (rfcName.length()<2) return Glib::ustring("default"); + + Glib::ustring major=rfcName.substr(0,2).lowercase(); + Glib::ustring minor; + if (rfcName.length()>=5) { + minor=rfcName.substr(3,2).uppercase(); + } + + //printf("Lang: %s - %s\n",major.c_str(),minor.c_str()); + + if (major=="cs") return "Czech"; + if (major=="ca") return "Catala"; + if (major=="fr") return "Francais"; + if (major=="de") return "Deutsch"; + if (major=="sr") return "Serbian (Cyrilic Characters)"; + if (major=="zh") + return (minor=="CN" || minor=="SG") ? "Chinese (Simplified)" : "Chinese (Traditional)"; + if (major=="da") return "Dansk"; + if (major=="es") return "Espanol"; + if (major=="el") return "Greek"; + if (major=="he") return "Hebrew"; + if (major=="it") return "Italian"; + if (major=="ja") return "Japanese"; + if (major=="nl") return "Nederlands"; + if (major=="nn" || major=="nb") return "Norsk BM"; + if (major=="pl") return "Polish"; + if (major=="pt") return "Portugues (Brasil)"; + if (major=="ru") return "Russian"; + if (major=="sk") return "Slovak"; + if (major=="fi") return "Suomi"; + if (major=="se") return "Swedish"; + if (major=="tr") return "Turkish"; + + // Don't split en-US, en-GB, etc. since only default english is constantly updated + return "default"; +} + Glib::ustring MultiLangMgr::getStr (std::string key) { std::map::iterator r = transTable.find (key); diff --git a/rtgui/multilangmgr.h b/rtgui/multilangmgr.h index b9475df06..2f2dc500a 100644 --- a/rtgui/multilangmgr.h +++ b/rtgui/multilangmgr.h @@ -28,6 +28,8 @@ class MultiLangMgr { std::map transTable; MultiLangMgr* fallBack; + Glib::ustring TranslateRFC2Language(Glib::ustring rfcName); + public: MultiLangMgr () : fallBack (NULL) {} MultiLangMgr (Glib::ustring fname) : fallBack (NULL) { load (fname); } @@ -36,6 +38,9 @@ class MultiLangMgr { bool load (Glib::ustring fname, MultiLangMgr* fb = NULL); bool save (Glib::ustring fname); + bool isOSLanguageDetectSupported(); + Glib::ustring getOSUserLanguage(); + Glib::ustring getStr (std::string key); }; diff --git a/rtgui/options.cc b/rtgui/options.cc index bc2c64fb6..dfbd2ebf9 100644 --- a/rtgui/options.cc +++ b/rtgui/options.cc @@ -98,6 +98,7 @@ void Options::setDefaults () { bgcolor = 0; blinkClipped = false; // was true language = DefaultLanguage; + languageAutoDetect= langMgr.isOSLanguageDetectSupported(); lastSaveAsPath = ""; overwriteOutputFile = false; // if TRUE, existing output JPGs/PNGs are overwritten, instead of adding ..-1.jpg, -2.jpg etc. theme = "17-Gray-Red"; @@ -268,6 +269,7 @@ if (keyFile.has_group ("General")) { if (keyFile.has_key ("General", "MultiUser")) multiUser = keyFile.get_boolean ("General", "MultiUser"); if (keyFile.has_key ("General", "Version")) version = keyFile.get_string ("General", "Version"); if (keyFile.has_key ("General", "Language")) language = keyFile.get_string ("General", "Language"); + if (keyFile.has_key ("General", "LanguageAutoDetect")) languageAutoDetect = keyFile.get_boolean ("General", "LanguageAutoDetect"); if (keyFile.has_key ("General", "Theme")) theme = keyFile.get_string ("General", "Theme"); if (keyFile.has_key ("General", "SlimUI")) slimUI = keyFile.get_boolean ("General", "SlimUI"); if (keyFile.has_key ("General", "UseSystemTheme")) useSystemTheme = keyFile.get_boolean ("General", "UseSystemTheme"); @@ -433,6 +435,7 @@ int Options::saveToFile (Glib::ustring fname) { keyFile.set_boolean ("General", "DualProcSupport", rtSettings.dualThreadEnabled); keyFile.set_boolean ("General", "MultiUser", multiUser); keyFile.set_string ("General", "Language", language); + keyFile.set_boolean ("General", "LanguageAutoDetect", languageAutoDetect); keyFile.set_string ("General", "Theme", theme); keyFile.set_boolean ("General", "SlimUI", slimUI); keyFile.set_boolean ("General", "UseSystemTheme", useSystemTheme); @@ -661,6 +664,8 @@ void Options::load () { Glib::ustring languageTranslation = ""; Glib::ustring localeTranslation = ""; + if (options.languageAutoDetect) options.language=langMgr.getOSUserLanguage(); + if (!options.language.empty()){ std::vector langPortions = Glib::Regex::split_simple(" ", options.language); if (langPortions.size() >= 1){ diff --git a/rtgui/options.h b/rtgui/options.h index baeb23213..b7a5d778f 100644 --- a/rtgui/options.h +++ b/rtgui/options.h @@ -100,6 +100,7 @@ class Options { bool blinkClipped; int bgcolor; Glib::ustring language; + bool languageAutoDetect; Glib::ustring theme; bool slimUI; bool useSystemTheme; diff --git a/rtgui/preferences.cc b/rtgui/preferences.cc index 2df2a2a3b..4b61426d0 100644 --- a/rtgui/preferences.cc +++ b/rtgui/preferences.cc @@ -454,6 +454,9 @@ Gtk::Widget* Preferences::getGeneralPanel () { Gtk::Frame* flang = Gtk::manage( new Gtk::Frame (M("PREFERENCES_DEFAULTLANG")) ); Gtk::HBox* hblang = Gtk::manage( new Gtk::HBox () ); hblang->set_border_width (4); + + ckbLangAutoDetect = Gtk::manage( new Gtk::CheckButton (M("PREFERENCES_LANGAUTODETECT")) ); + Gtk::Label* langlab = Gtk::manage( new Gtk::Label (M("PREFERENCES_SELECTLANG")+":") ); languages = Gtk::manage( new Gtk::ComboBoxText () ); @@ -466,12 +469,15 @@ Gtk::Widget* Preferences::getGeneralPanel () { } Gtk::Label* langw = Gtk::manage( new Gtk::Label (Glib::ustring(" (") + M("PREFERENCES_APPLNEXTSTARTUP") + ")") ); - hblang->pack_start (*langlab, Gtk::PACK_SHRINK, 4); + hblang->pack_start (*ckbLangAutoDetect, Gtk::PACK_SHRINK, 4); + hblang->pack_start (*langlab, Gtk::PACK_SHRINK, 8); hblang->pack_start (*languages); hblang->pack_end (*langw, Gtk::PACK_SHRINK, 4); flang->add (*hblang); mvbsd->pack_start (*flang, Gtk::PACK_SHRINK, 4); + langAutoDetectConn = ckbLangAutoDetect->signal_toggled().connect (sigc::mem_fun(*this, &Preferences::langAutoDetectToggled)); + Gtk::Frame* ftheme = Gtk::manage( new Gtk::Frame (M("PREFERENCES_DEFAULTTHEME")) ); Gtk::VBox* vbftheme = Gtk::manage( new Gtk::VBox () ); vbftheme->set_border_width(4); @@ -927,6 +933,7 @@ void Preferences::storePreferences () { moptions.highlightThreshold = (int)hlThresh->get_value (); moptions.shadowThreshold = (int)shThresh->get_value (); moptions.language = languages->get_active_text (); + moptions.languageAutoDetect = ckbLangAutoDetect->get_active (); moptions.theme = theme->get_active_text (); moptions.slimUI = slimUI->get_active (); moptions.useSystemTheme = chUseSystemTheme->get_active (); @@ -1046,6 +1053,7 @@ void Preferences::fillPreferences () { iccDir->set_current_folder (moptions.rtSettings.iccDirectory); intent->set_active (moptions.rtSettings.colorimetricIntent); languages->set_active_text (moptions.language); + ckbLangAutoDetect->set_active (moptions.languageAutoDetect); theme->set_active_text (moptions.theme); slimUI->set_active(moptions.slimUI); chUseSystemTheme->set_active(moptions.useSystemTheme); @@ -1191,6 +1199,9 @@ void Preferences::sndEnableToggled () { spbSndLngEditProcDoneSecs->set_sensitive(ckbSndEnable->get_active()); } +void Preferences::langAutoDetectToggled () { + languages->set_sensitive(!ckbLangAutoDetect->get_active()); +} void Preferences::okPressed () { diff --git a/rtgui/preferences.h b/rtgui/preferences.h index 3d582353b..4cff8297d 100644 --- a/rtgui/preferences.h +++ b/rtgui/preferences.h @@ -54,6 +54,7 @@ class Preferences : public Gtk::Dialog { Gtk::ComboBoxText* rprofiles; Gtk::ComboBoxText* iprofiles; Gtk::ComboBoxText* languages; + Gtk::CheckButton* ckbLangAutoDetect; Gtk::Entry* dateformat; Gtk::Entry* startupdir; Gtk::RadioButton* sdcurrent; @@ -132,7 +133,8 @@ class Preferences : public Gtk::Dialog { Options moptions; - sigc::connection tconn, sconn, fconn, usethcon, addc, setc, dfconn, ffconn, autoMonProfileConn, sndEnableConn; + sigc::connection tconn, sconn, fconn, usethcon, addc, setc, dfconn, ffconn; + sigc::connection autoMonProfileConn, sndEnableConn, langAutoDetectConn; Glib::ustring initialTheme; Glib::ustring initialFont; @@ -172,6 +174,7 @@ class Preferences : public Gtk::Dialog { void aboutPressed (); void autoMonProfileToggled (); void sndEnableToggled (); + void langAutoDetectToggled (); void selectStartupDir (); void addExtPressed ();