Example #1
0
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