Merge branch 'ui-locale'

Add wxUILocale class providing functionality which can be implemented
portably for all major platforms, including macOS, and doesn't force
the change of the global C locale, unlike wxLocale.

See https://github.com/wxWidgets/wxWidgets/pull/2464
This commit is contained in:
Vadim Zeitlin
2021-08-26 15:49:57 +02:00
41 changed files with 1978 additions and 655 deletions

View File

@@ -69,7 +69,7 @@ struct wxLanguageInfo
/**
The category of locale settings.
@see wxLocale::GetInfo()
@see wxLocale::GetInfo(), wxUILocale::GetInfo()
*/
enum wxLocaleCategory
{
@@ -108,6 +108,8 @@ enum wxLocaleCategory
All of these values are used with @c wxLOCALE_CAT_DATE in wxLocale::GetInfo() or,
more typically, with @c wxLOCALE_CAT_DEFAULT as they only apply to a single category.
@see wxUILocale::GetInfo()
*/
enum wxLocaleInfo
{
@@ -116,6 +118,9 @@ enum wxLocaleInfo
This value can be used with either wxLOCALE_CAT_NUMBER or
wxLOCALE_CAT_MONEY categories.
By default, i.e. when wxLOCALE_CAT_DEFAULT is used, the separator for
numbers is returned.
*/
wxLOCALE_THOUSANDS_SEP,
@@ -124,6 +129,9 @@ enum wxLocaleInfo
This value can be used with either wxLOCALE_CAT_NUMBER or
wxLOCALE_CAT_MONEY categories.
By default, i.e. when wxLOCALE_CAT_DEFAULT is used, the decimal point
for numbers is returned.
*/
wxLOCALE_DECIMAL_POINT,
@@ -166,6 +174,13 @@ enum wxLocaleInfo
wxLocale class encapsulates all language-dependent settings and is a
generalization of the C locale concept.
@note While this class can still be used in wxMSW and wxGTK ports, it
doesn't work in wxOSX where it is impossible to change the application
UI locale after launching it. Worse, since macOS 11 (Big Sur), using
wxLocale can break application display due to bugs in C locale support
in macOS itself. Because of this, it is recommended to use wxUILocale
instead of this class for the applications targeting macOS.
In wxWidgets this class manages current locale. It also initializes and
activates wxTranslations object that manages message catalogs.
@@ -435,6 +450,9 @@ public:
/**
Get the values of a locale datum in the OS locale.
This function shouldn't be used in the new code, use
wxUILocale::GetInfo() instead.
This function is similar to GetInfo() and, in fact, identical to it
under non-MSW systems. Under MSW it differs from it when no locale had
been explicitly set: GetInfo() returns the values corresponding to the

View File

@@ -8,11 +8,15 @@
/**
@class wxNumberFormatter
Helper class for formatting and parsing numbers with thousands separators.
Formatting and parsing numbers using the current UI locale conventions,
including support for using the correct decimal point character and
thousands separators.
This class contains only static functions, so users must not create instances
but directly call the member functions.
@see wxUILocale
@since 2.9.2
@library{wxbase}
@@ -32,7 +36,7 @@ public:
/**
If this flag is given, thousands separators will be inserted in the
number string representation as defined by the current locale.
number string representation as defined by the current UI locale.
*/
Style_WithThousandsSep = 0x01,
@@ -56,7 +60,7 @@ public:
Returns string representation of an integer number.
By default, the string will use thousands separators if appropriate for
the current locale. This can be avoided by passing Style_None as @a
the current UI locale. This can be avoided by passing Style_None as @a
flags in which case the call to the function has exactly the same
effect as <code>wxString::Format("%ld", val)</code>.
@@ -89,12 +93,22 @@ public:
static wxString
ToString(double val, int precision, int flags = Style_WithThousandsSep);
/**
Format the given number using one of the floating point formats and
ensure that the result uses the correct decimal separator.
Prefer using ToString() if possible, i.e. if format is "%g" or "%.Nf"
which are supported by it directly.
@since 3.1.6
*/
static wxString Format(const wxString& format, double val);
/**
Parse a string representation of a number possibly including thousands
separators.
These functions parse number representation in the current locale. On
These functions parse number representation in the current UI locale. On
success they return @true and store the result at the location pointed
to by @a val (which can't be @NULL), otherwise @false is returned.
@@ -114,7 +128,7 @@ public:
//@}
/**
Get the decimal separator for the current locale.
Get the decimal separator for the current UI locale.
Decimal separators is always defined and we fall back to returning '.'
in case of an error.
@@ -123,14 +137,14 @@ public:
/**
Get the thousands separator if grouping of the digits is used by the
current locale.
current UI locale.
The value returned in @a sep should be only used if the function
returns @true, otherwise no thousands separator should be used at all.
@param sep
Points to the variable receiving the thousands separator character
if it is used by the current locale. May be @NULL if only the
if it is used by the current UI locale. May be @NULL if only the
function return value is needed.
*/
static bool GetThousandsSeparatorIfUsed(wxChar *sep);

121
interface/wx/uilocale.h Normal file
View File

@@ -0,0 +1,121 @@
///////////////////////////////////////////////////////////////////////////////
// Name: wx/uilocale.h
// Purpose: Interface of wxUILocale
// Author: Vadim Zeitlin
// Created: 2021-08-01
// Copyright: (c) 2021 Vadim Zeitlin <vadim@wxwidgets.org>
// Licence: wxWindows licence
///////////////////////////////////////////////////////////////////////////////
/**
Query and modify locale used for the UI by the current platform.
UI locale determines all culture-dependent conventions used in the user
interface, including numbers, currencies and dates formatting. It also
determines the language used by the native dialogs, such as wxFileDialog,
where different labels use the language corresponding to the current UI
locale.
The UI locale is, in general, different from C locale set by the standard
@c setlocale() function and affecting C standard library functions such as
@c printf(), @c scanf(), @c strftime() and many others. Unfortunately, the
relationship between C and UI locales is not the same depending on the
platform: with wxGTK they must be the same, but under macOS C locale must
not be changed, as doing this exposes bugs in the system. Because of this,
applications can't generally count on C locale being set to any particular
value and it is best to avoid using it, including implicitly via the
standard C functions, in portable code. Instead, consider using
wxNumberFormatter for parsing and formatting numbers according to the
current UI locale or wxString::FromCDouble() and wxString::ToCDouble()
functions for doing it always using period as decimal separator.
Localized applications should call wxUILocale::UseDefault() on startup to
explicitly indicate that they opt-in using the current UI locale, even if
this results in changing the global C locale, as is the case in wxGTK. Note
that some platforms (MSW and macOS) will use default user locale for their
standard dialogs even if this function is not called, but it is still
necessary to call it to use the correct number and date formats and to
avoid mixing messages in the user language with default formats not
corresponding to it.
Please also note that under macOS to really use the user locale, it must be
listed as a supported language in the application @c Info.plist file under
@c CFBundleLocalizations key.
Unlike wxLocale class, this class doesn't affect the translations used by
the application, see wxTranslations for doing this.
@library{wxbase}
@since 3.1.6
*/
class wxUILocale
{
public:
/**
Configure the UI to use the default user locale.
Localized applications should call this functions as early as possible
during the program startup, e.g. in the very beginning of the
overridden wxApp::OnInit().
Note that under most Unix systems (but not macOS) this function changes
the C locale to the locale specified by the environment variables and
so affects the results of calling C functions such as @c sprintf() etc
which can use comma, rather than period, as decimal separator. The
wxString::ToCDouble() and wxString::FromCDouble() functions can be used
for parsing and formatting floating point numbers using period as
decimal separator independently of the current locale.
@return @true on success or @false if the default locale couldn't be set
*/
static bool UseDefault();
/**
Get the object corresponding to the currently used locale.
If UseDefault() had been called, this object corresponds to the default
user locale. Otherwise it corresponds to a generic locale similar to
"C" locale, i.e. always uses period as decimal separator and m/d/y date
format.
*/
static const wxUILocale& GetCurrent();
/**
Get the platform-dependent name of the current locale.
This name can be used in diagnostic messages.
*/
wxString GetName() const;
/**
Query the locale for the specified information.
This function returns the value of the locale-specific option specified
by the given @a index.
@param index
One of the elements of wxLocaleInfo enum.
@param cat
The category to use with the given index or wxLOCALE_CAT_DEFAULT if
the index can only apply to a single category.
@return
The option value or empty string if the function failed.
*/
wxString GetInfo(wxLocaleInfo index,
wxLocaleCategory cat = wxLOCALE_CAT_DEFAULT) const;
};
/**
Return the format to use for formatting user-visible dates.
This is a simple wrapper function normally calling wxUILocale::GetInfo()
with wxLOCALE_SHORT_DATE_FMT argument, but which is also available when @c
wxUSE_INTL==0, i.e. support for internationalization is disabled at
compile-time, in which case it returns @c %x string, i.e. uses the current
C locale formatting rather than UI locale.
@see wxDateTime::Format()
@since 3.1.6
*/
wxString wxGetUIDateFormat();