LRESULT CALLBACK CLanguageSelector::LangSelectProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { static HBITMAP hbmpBackgroundTop = NULL; static HFONT hTextFont = NULL; static CLanguageSelector * lngClass; switch (uMsg) { case WM_INITDIALOG: { lngClass = (CLanguageSelector *)lParam; LanguageList LangList = g_Lang->GetLangList(); if (LangList.size() == 0) { EndDialog(hDlg, 0); } for (LanguageList::iterator Language = LangList.begin(); Language != LangList.end(); Language++) { int index = SendMessageW(GetDlgItem(hDlg, IDC_LANG_SEL), CB_ADDSTRING, 0, (WPARAM)stdstr(Language->LanguageName).ToUTF16().c_str()); if (_stricmp(Language->LanguageName.c_str(), "English") == 0) { SendMessage(GetDlgItem(hDlg, IDC_LANG_SEL), CB_SETCURSEL, index, 0); } } int Index = SendMessage(GetDlgItem(hDlg, IDC_LANG_SEL), CB_GETCURSEL, 0, 0); if (Index < 0) { SendMessage(GetDlgItem(hDlg, IDC_LANG_SEL), CB_SETCURSEL, 0, 0); } //Get Windows DPI Scale float DPIScale = CClientDC(hDlg).GetDeviceCaps(LOGPIXELSX) / 96.0f; // Use the size of the image hbmpBackgroundTop = LoadBitmap(GetModuleHandle(NULL), DPIScale <= 1.0f ? MAKEINTRESOURCE(IDB_ABOUT_LOGO) : MAKEINTRESOURCE(IDB_ABOUT_LOGO_HDPI)); BITMAP bmTL; GetObject(hbmpBackgroundTop, sizeof(BITMAP), &bmTL); hTextFont = ::CreateFont(18, 0, 0, 0, FW_NORMAL, 0, 0, 0, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, PROOF_QUALITY, DEFAULT_PITCH | FF_DONTCARE, "Arial"); SendDlgItemMessage(hDlg, IDC_SELECT_LANG, WM_SETFONT, (WPARAM)hTextFont, TRUE); } break; case WM_CTLCOLORSTATIC: { HDC hdcStatic = (HDC)wParam; SetTextColor(hdcStatic, RGB(0, 0, 0)); SetBkMode(hdcStatic, TRANSPARENT); return (LONG)(LRESULT)((HBRUSH)GetStockObject(NULL_BRUSH)); } break; case WM_ERASEBKGND: { HPEN outline; HBRUSH fill; RECT rect; outline = CreatePen(PS_SOLID, 1, 0x00FFFFFF); fill = CreateSolidBrush(0x00FFFFFF); SelectObject((HDC)wParam, outline); SelectObject((HDC)wParam, fill); GetClientRect(hDlg, &rect); Rectangle((HDC)wParam, rect.left, rect.top, rect.right, rect.bottom); } break; case WM_PAINT: { PAINTSTRUCT ps; if (BeginPaint(hDlg, &ps)) { RECT rcClient; GetClientRect(hDlg, &rcClient); BITMAP bmTL_top; GetObject(hbmpBackgroundTop, sizeof(BITMAP), &bmTL_top); HDC memdc = CreateCompatibleDC(ps.hdc); HGDIOBJ save = SelectObject(memdc, hbmpBackgroundTop); SetStretchBltMode(ps.hdc, HALFTONE); StretchBlt(ps.hdc, 0, 0, rcClient.right, (int)(bmTL_top.bmHeight * rcClient.right / bmTL_top.bmWidth), memdc, 0, 0, bmTL_top.bmWidth, bmTL_top.bmHeight, SRCCOPY); SelectObject(memdc, save); DeleteDC(memdc); EndPaint(hDlg, &ps); } } break; case WM_COMMAND: switch (LOWORD(wParam)) { case IDOK: if (hbmpBackgroundTop) { DeleteObject(hbmpBackgroundTop); } if (hTextFont) { ::DeleteObject(hTextFont); } { int Index = SendMessage(GetDlgItem(hDlg, IDC_LANG_SEL), CB_GETCURSEL, 0, 0); if (Index >= 0) { wchar_t String[255]; SendMessageW(GetDlgItem(hDlg, IDC_LANG_SEL), CB_GETLBTEXT, Index, (LPARAM)String); g_Lang->SetLanguage(stdstr().FromUTF16(String).c_str()); } } EndDialog(hDlg, 0); break; } default: return FALSE; } return TRUE; }
// ---------------------------------------------------------------------------- Translations::Translations() //: m_dictionary_manager("UTF-16") { m_dictionary_manager.add_directory( file_manager->getAsset(FileManager::TRANSLATION,"")); if (g_language_list.size() == 0) { std::set<Language> languages = m_dictionary_manager.get_languages(); // English is always there but won't be found on file system g_language_list.push_back("en"); std::set<Language>::iterator it; for (it = languages.begin(); it != languages.end(); it++) { g_language_list.push_back((*it).str()); } } // LC_ALL does not work, sscanf will then not always be able // to scan for example: s=-1.1,-2.3,-3.3 correctly, which is // used in driveline files. #if defined(WIN32) && !defined(__CYGWIN__) // Windows does not have LC_MESSAGES setlocale(LC_CTYPE, ""); #else setlocale(LC_MESSAGES, ""); #endif /* bindtextdomain (PACKAGE, file_manager->getTranslationDir().c_str()); if (sizeof(wchar_t) == 4) { if (IS_LITTLE_ENDIAN) bind_textdomain_codeset(PACKAGE, "UTF-32LE"); else bind_textdomain_codeset(PACKAGE, "UTF-32BE"); } else if (sizeof(wchar_t) == 2) { bind_textdomain_codeset(PACKAGE, "UTF-16LE"); } else { fprintf(stderr, "Your wchar_t is neither 2 byte-long nor 4. What now??\n"); exit(1); } textdomain (PACKAGE); */ /* const std::set<Language>& languages = m_dictionary_manager.get_languages(); Log::info("Translatings", "Number of languages: %d", languages.size()); for (std::set<Language>::const_iterator i = languages.begin(); i != languages.end(); ++i) { const Language& language = *i; Log::info("Translatings", "Env: %s", language.str()); Log::info("Translatings", "Name: %s", language.get_name()); Log::info("Translatings", "Language: %s", language.get_language()); Log::info("Translatings", "Country: %s", language.get_country()); Log::info("Translatings", "Modifier: %s", language.get_modifier()); } */ const char *p_language = getenv("LANGUAGE"); std::string language; if(p_language) { language=p_language; } else { const char *p_lang = getenv("LANG"); if(p_lang) language = p_lang; else { #ifdef WIN32 // Thanks to the frogatto developer for this code snippet: char c[1024]; GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_SISO639LANGNAME, c, 1024); Log::verbose("translation", "GetLocaleInfo langname returns '%s'.", c); if(c[0]) { language = c; GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_SISO3166CTRYNAME, c, 1024); Log::verbose("translation", "GetLocaleInfo tryname returns '%s'.", c); if(c[0]) language += std::string("_")+c; } // if c[0] #endif } // neither LANGUAGE nor LANG defined } if (language != "") { Log::verbose("translation", "Env var LANGUAGE = '%s'.", language.c_str()); if (language.find(":") != std::string::npos) { std::vector<std::string> langs = StringUtils::split(language, ':'); Language l; for (unsigned int curr=0; curr<langs.size(); curr++) { l = Language::from_env(langs[curr]); if (l) { Log::verbose("translation", "Language '%s'.", l.get_name().c_str()); m_dictionary = m_dictionary_manager.get_dictionary(l); break; } } m_current_language_name = l.get_name(); m_current_language_name_code = l.get_language(); if (!l) { m_dictionary = m_dictionary_manager.get_dictionary(); } } else { const Language& tgtLang = Language::from_env(language); if (!tgtLang) { Log::warn("Translation", "Unsupported langage '%s'", language.c_str()); UserConfigParams::m_language = "system"; m_current_language_name = "Default language"; m_current_language_name_code = "en"; m_dictionary = m_dictionary_manager.get_dictionary(); } else { m_current_language_name = tgtLang.get_name(); m_current_language_name_code = tgtLang.get_language(); Log::verbose("translation", "Language '%s'.", m_current_language_name.c_str()); m_dictionary = m_dictionary_manager.get_dictionary(tgtLang); } } } else { m_current_language_name = "Default language"; m_current_language_name_code = "en"; m_dictionary = m_dictionary_manager.get_dictionary(); } // This is a silly but working hack I added to determine whether the // current language is RTL or not, since gettext doesn't seem to provide // this information // This one is just for the xgettext parser to pick up #define ignore(X) //I18N: Do NOT literally translate this string!! Please enter Y as the // translation if your language is a RTL (right-to-left) language, // N (or nothing) otherwise ignore(_(" Is this a RTL language?")); const std::string isRtl = m_dictionary.translate(" Is this a RTL language?"); m_rtl = false; for (unsigned int n=0; n < isRtl.size(); n++) { if (isRtl[n] == 'Y') { m_rtl = true; break; } } #ifdef TEST_BIDI m_rtl = true; #endif } // Translations