Merge pull request #5805 from JosJuice/date-time-locale

Set C++ locale
This commit is contained in:
Léo Lam 2018-04-09 20:03:48 +02:00 committed by GitHub
commit 0e1ca1e17c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 78 additions and 5 deletions

View File

@ -51,10 +51,6 @@ std::string ThousandSeparate(I value, int spaces = 0)
std::ostringstream stream;
#endif
// std::locale("") seems to be broken on many platforms
#if defined _WIN32 || (defined __linux__ && !defined __clang__)
stream.imbue(std::locale(""));
#endif
stream << std::setw(spaces) << value;
#ifdef _WIN32

View File

@ -18,6 +18,7 @@
#include "Common/MsgHandler.h"
#include "Common/StringUtil.h"
#include "Core/ConfigManager.h"
#include "UICommon/UICommon.h"
constexpr u32 MO_MAGIC_NUMBER = 0x950412de;
@ -270,6 +271,10 @@ static bool TryInstallTranslator(const QString& exact_language_code)
if (translator->load(filename))
{
QApplication::instance()->installTranslator(translator);
QLocale::setDefault(QLocale(exact_language_code));
UICommon::SetLocale(exact_language_code.toStdString());
return true;
}
translator->deleteLater();

View File

@ -343,6 +343,9 @@ void DolphinApp::InitLanguageSupport()
_("Error"));
m_locale.reset(new wxLocale(wxLANGUAGE_DEFAULT));
}
// wxWidgets sets the C locale for us, but not the C++ locale, so let's do that ourselves
UICommon::SetLocale(language_code);
}
void DolphinApp::OnEndSession(wxCloseEvent& event)

View File

@ -2,8 +2,13 @@
// Licensed under GPLv2+
// Refer to the license.txt file included.
#include <algorithm>
#include <clocale>
#include <cmath>
#include <iomanip>
#include <locale>
#include <memory>
#include <sstream>
#ifdef _WIN32
#include <shlobj.h> // for SHGetFolderPath
#endif
@ -66,6 +71,63 @@ void Shutdown()
Config::Shutdown();
}
void SetLocale(std::string locale_name)
{
auto set_locale = [](const std::string& locale) {
#ifdef __linux__
std::string adjusted_locale = locale;
if (!locale.empty())
adjusted_locale += ".UTF-8";
#else
const std::string& adjusted_locale = locale;
#endif
// setlocale sets the C locale, and global sets the C and C++ locales, so the call to setlocale
// would be redundant if it wasn't for not having any other good way to check whether
// the locale name is valid. (Constructing a std::locale object for an unsupported
// locale name throws std::runtime_error, and exception handling is disabled in Dolphin.)
if (!std::setlocale(LC_ALL, adjusted_locale.c_str()))
return false;
std::locale::global(std::locale(adjusted_locale));
return true;
};
#ifdef _WIN32
constexpr char PREFERRED_SEPARATOR = '-';
constexpr char OTHER_SEPARATOR = '_';
#else
constexpr char PREFERRED_SEPARATOR = '_';
constexpr char OTHER_SEPARATOR = '-';
#endif
// Users who use a system language other than English are unlikely to prefer American date and
// time formats, so let's explicitly request "en_GB" if Dolphin's language is set to "en".
// (The settings window only allows setting "en", not anything like "en_US" or "en_GB".)
// Users who prefer the American formats are likely to have their system language set to en_US,
// and are thus likely to leave Dolphin's language as the default value "" (<System Language>).
if (locale_name == "en")
locale_name = "en_GB";
std::replace(locale_name.begin(), locale_name.end(), OTHER_SEPARATOR, PREFERRED_SEPARATOR);
// Use the specified locale if supported.
if (set_locale(locale_name))
return;
// Remove subcodes until we get a supported locale. If that doesn't give us a supported locale,
// "" is passed to set_locale in order to get the system default locale.
while (!locale_name.empty())
{
const size_t separator_index = locale_name.rfind(PREFERRED_SEPARATOR);
locale_name.erase(separator_index == std::string::npos ? 0 : separator_index);
if (set_locale(locale_name))
return;
}
// If none of the locales tried above are supported, we just keep using whatever locale is set
// (which is the classic locale by default).
}
void CreateDirectories()
{
// Copy initial Wii NAND data from Sys to User.
@ -346,7 +408,10 @@ std::string FormatSize(u64 bytes)
// Don't need exact values, only 5 most significant digits
const double unit_size = std::pow(2, unit * 10);
return StringFromFormat("%.2f %s", bytes / unit_size, GetStringT(unit_symbols[unit]).c_str());
std::stringstream ss;
ss << std::fixed << std::setprecision(2);
ss << bytes / unit_size << ' ' << GetStringT(unit_symbols[unit]);
return ss.str();
}
} // namespace UICommon

View File

@ -19,6 +19,10 @@ void EnableScreenSaver(Display* display, Window win, bool enable);
void EnableScreenSaver(bool enable);
#endif
// Calls std::locale::global, selecting a fallback locale if the
// requested locale isn't available
void SetLocale(std::string locale_name);
void CreateDirectories();
void SetUserDirectory(const std::string& custom_path);