Skip to content
Permalink
Browse files
Merge pull request #5805 from JosJuice/date-time-locale
Set C++ locale
  • Loading branch information
leoetlino committed Apr 9, 2018
2 parents 7aaaf44 + a66d56a commit 0e1ca1e
Show file tree
Hide file tree
Showing 5 changed files with 78 additions and 5 deletions.
@@ -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
@@ -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();
@@ -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)
@@ -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
@@ -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);

0 comments on commit 0e1ca1e

Please sign in to comment.