Don't call setlocale("") on startup by default any longer.

This undoes the changes of r44773 because calling setlocale() resulted in C
locale being set differently from C++ locale which was confusing and led to
huge slowdowns in any code using std::stream with at least MinGW. And setting
the C++ locale to be the same, as r72719 tried to do, doesn't seem to be
practical as it results in immediate crashes under OS X and MinGW when used
under XP.

Do provide wxApp::SetCLocale() helper to explicitly do what was previously
done implicitly, even though currently it is a trivial wrapper for setlocale()
and we don't even need to call gtk_set_locale() as it has never done anything
else and is deprecated since GTK+ 2.24.

Closes #14780.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@72951 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin 2012-11-14 13:46:50 +00:00
parent 40df8a51f2
commit b51014176a
9 changed files with 65 additions and 64 deletions

View File

@ -527,6 +527,13 @@ Major new features in this release
2.9.5: (released ????-??-??)
----------------------------
INCOMPATIBLE CHANGES SINCE 2.9.4:
- The locale is not set automatically on startup any more, unlike in the
previous 2.9 versions (but like in 2.8). Use wxLocale (preferred) or call
wxApp::SetCLocale() from your overridden wxApp::Initialize() to restore the
old behaviour.
All:
- Add wxEvtHandler::CallAfter() method for asynchronous method calls.

View File

@ -236,6 +236,18 @@ public:
wxEventLoopBase* GetMainLoop() const
{ return m_mainLoop; }
// This function sets the C locale to the default locale for the current
// environment. It is advised to call this to ensure that the underlying
// toolkit uses the locale in which the numbers and monetary amounts are
// shown in the format expected by user and so on.
//
// Notice that this does _not_ change the global C++ locale, you need to do
// it explicitly if you want.
//
// Finally, notice that while this function is virtual, it is not supposed
// to be overridden outside of the library itself.
virtual void SetCLocale();
// event processing functions
// --------------------------

View File

@ -77,12 +77,6 @@ public:
// except in the case of wxMac and wxCocoa
virtual wxStandardPaths& GetStandardPaths();
#if wxUSE_INTL
// called during wxApp initialization to set the locale to correspond to
// the user default (i.e. system locale under Windows, LC_ALL under Unix)
virtual void SetLocale();
#endif // wxUSE_INTL
// functions abstracting differences between GUI and console modes
// ------------------------------------------------------------------------

View File

@ -67,10 +67,6 @@ public:
#endif
virtual wxPortId GetToolkitVersion(int *majVer = NULL, int *minVer = NULL) const;
#if defined(__WXGTK__) && wxUSE_INTL
virtual void SetLocale();
#endif // __WXGTK__
#ifdef __WXGTK20__
virtual wxString GetDesktopEnvironment() const;
virtual wxString GetStandardCmdLineOptions(wxArrayString& names,

View File

@ -561,6 +561,33 @@ public:
//@}
/**
Sets the C locale to the default locale for the current environment.
It is advised to call this to ensure that the underlying toolkit uses
the locale in which the numbers and monetary amounts are shown in the
format expected by user and so on.
Calling this function is roughly equivalent to calling
@code
setlocale(LC_ALL, "");
@endcode
but performs additional toolkit-specific tasks under some platforms and
so should be used instead of @c setlocale() itself. Alternatively, you
can use wxLocale to change the locale with more control.
Notice that this does @em not change the global C++ locale, you need to
do it explicitly if you want, e.g.
@code
std::locale::global(std::locale(""));
@endcode
but be warned that locale support in C++ standard library can be poor
or worse under some platforms, e.g. the above line results in an
immediate crash under OS X up to the version 10.8.2.
@since 2.9.5
*/
void SetCLocale();
/**
Number of command line arguments (after environment-specific processing).

View File

@ -174,10 +174,6 @@ wxAppConsoleBase::~wxAppConsoleBase()
bool wxAppConsoleBase::Initialize(int& WXUNUSED(argc), wxChar **WXUNUSED(argv))
{
#if wxUSE_INTL
GetTraits()->SetLocale();
#endif // wxUSE_INTL
return true;
}
@ -784,6 +780,18 @@ void wxAppConsoleBase::OnAssert(const wxChar *file,
OnAssertFailure(file, line, NULL, cond, msg);
}
// ----------------------------------------------------------------------------
// Miscellaneous other methods
// ----------------------------------------------------------------------------
void wxAppConsoleBase::SetCLocale()
{
// We want to use the user locale by default in GUI applications in order
// to show the numbers, dates &c in the familiar format -- and also accept
// this format on input (especially important for decimal comma/dot).
wxSetlocale(LC_ALL, "");
}
// ============================================================================
// other classes implementations
// ============================================================================
@ -836,26 +844,6 @@ bool wxConsoleAppTraitsBase::HasStderr()
// wxAppTraits
// ----------------------------------------------------------------------------
#if wxUSE_INTL
void wxAppTraitsBase::SetLocale()
{
// We want to use the user locale by default in GUI applications in order
// to show the numbers, dates &c in the familiar format -- and also accept
// this format on input (especially important for decimal comma/dot).
wxSetlocale(LC_ALL, "");
#if wxUSE_STL
// At least in some environments, e.g. MinGW-64, if the global C++ locale
// is different from the global C locale, all stream operations temporarily
// change the locale resulting in a huge slowdown (3 times slower in some
// real-life applications), so change the C++ locale to match.
std::locale::global(std::locale(""));
#endif //wxUSE_STL
wxUpdateLocaleIsUtf8();
}
#endif
#if wxUSE_THREADS
void wxMutexGuiEnterImpl();
void wxMutexGuiLeaveImpl();

View File

@ -309,9 +309,9 @@ bool wxApp::Initialize(int& argc_, wxChar **argv_)
if (encName.CmpNoCase(wxT("@locale")) == 0)
encName.clear();
encName.MakeUpper();
#if wxUSE_INTL
if (encName.empty())
{
#if wxUSE_INTL
// (2) if a non default locale is set, assume that the user wants his
// filenames in this locale too
encName = wxLocale::GetSystemEncodingName().Upper();
@ -330,22 +330,14 @@ bool wxApp::Initialize(int& argc_, wxChar **argv_)
encName.clear();
}
}
#endif // wxUSE_INTL
// (3) finally use UTF-8 by default
if ( encName.empty() )
encName = wxT("UTF-8");
wxSetEnv(wxT("G_FILENAME_ENCODING"), encName);
}
#else
if (encName.empty())
encName = wxT("UTF-8");
// if wxUSE_INTL==0 it probably indicates that only "C" locale is supported
// by the program anyhow so prevent GTK+ from calling setlocale(LC_ALL, "")
// from gtk_init_check() as it does by default
gtk_disable_setlocale();
#endif // wxUSE_INTL
static wxConvBrokenFileNames fileconv(encName);
wxConvFileName = &fileconv;
#endif // __UNIX__
@ -366,13 +358,17 @@ bool wxApp::Initialize(int& argc_, wxChar **argv_)
int argcGTK = argc_;
// Prevent gtk_init_check() from changing the locale automatically for
// consistency with the other ports that don't do it. If necessary,
// wxApp::SetCLocale() may be explicitly called.
gtk_disable_setlocale();
#ifdef __WXGPE__
init_result = true; // is there a _check() version of this?
gpe_application_init( &argcGTK, &argvGTK );
#else
init_result = gtk_init_check( &argcGTK, &argvGTK ) != 0;
#endif
wxUpdateLocaleIsUtf8();
if ( argcGTK != argc_ )
{

View File

@ -290,18 +290,6 @@ wxEventLoopBase *wxGUIAppTraits::CreateEventLoop()
}
#if wxUSE_INTL && defined(__UNIX__)
void wxGUIAppTraits::SetLocale()
{
#ifdef __WXGTK3__
setlocale(LC_ALL, "");
#else
gtk_set_locale();
#endif
wxUpdateLocaleIsUtf8();
}
#endif
#ifdef __UNIX__
#if wxDEBUG_LEVEL && wxUSE_STACKWALKER

View File

@ -182,10 +182,3 @@ wxEventLoopBase* wxGUIAppTraits::CreateEventLoop()
return new wxEventLoop;
}
#if wxUSE_INTL
void wxGUIAppTraits::SetLocale()
{
gtk_set_locale();
}
#endif