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

@@ -527,6 +527,8 @@ public:
virtual wxSize GetSize() const wxOVERRIDE;
private:
wxString FormatDate() const;
wxDateTime m_date;
};
#else // !wxUSE_DATEPICKCTRL

View File

@@ -430,8 +430,6 @@ private:
void DoSetDigitsAndUpdate(unsigned digits);
wxString m_format;
wxDECLARE_DYNAMIC_CLASS(wxSpinCtrlDouble);
};

View File

@@ -13,19 +13,10 @@
#define _WX_INTL_H_
#include "wx/defs.h"
#include "wx/localedefs.h"
#include "wx/string.h"
#include "wx/translation.h"
// Make wxLayoutDirection enum available without need for wxUSE_INTL so wxWindow, wxApp
// and other classes are not distrubed by wxUSE_INTL
enum wxLayoutDirection
{
wxLayout_Default,
wxLayout_LeftToRight,
wxLayout_RightToLeft
};
#if wxUSE_INTL
#include "wx/fontenc.h"
@@ -50,86 +41,6 @@ class WXDLLIMPEXP_FWD_BASE wxLanguageInfoArray;
// locale support
// ============================================================================
// ----------------------------------------------------------------------------
// wxLanguageInfo: encapsulates wxLanguage to OS native lang.desc.
// translation information
// ----------------------------------------------------------------------------
struct WXDLLIMPEXP_BASE wxLanguageInfo
{
int Language; // wxLanguage id
wxString CanonicalName; // Canonical name, e.g. fr_FR
#ifdef __WINDOWS__
wxUint32 WinLang, // Win32 language identifiers
WinSublang;
#endif // __WINDOWS__
wxString Description; // human-readable name of the language
wxLayoutDirection LayoutDirection;
#ifdef __WINDOWS__
// return the LCID corresponding to this language
wxUint32 GetLCID() const;
#endif // __WINDOWS__
// return the locale name corresponding to this language usable with
// setlocale() on the current system or empty string if this locale is not
// supported
wxString GetLocaleName() const;
// Call setlocale() and return non-null value if it works for this language.
//
// This function is mostly for internal use, as changing locale involves
// more than just calling setlocale() on some platforms, use wxLocale to
// do everything that needs to be done instead of calling this method.
const char* TrySetLocale() const;
};
// ----------------------------------------------------------------------------
// wxLocaleCategory: the category of locale settings
// ----------------------------------------------------------------------------
enum wxLocaleCategory
{
// (any) numbers
wxLOCALE_CAT_NUMBER,
// date/time
wxLOCALE_CAT_DATE,
// monetary value
wxLOCALE_CAT_MONEY,
// default category for wxLocaleInfo values which only apply to a single
// category (e.g. wxLOCALE_SHORT_DATE_FMT)
wxLOCALE_CAT_DEFAULT,
wxLOCALE_CAT_MAX
};
// ----------------------------------------------------------------------------
// wxLocaleInfo: the items understood by wxLocale::GetInfo()
// ----------------------------------------------------------------------------
enum wxLocaleInfo
{
// the thousands separator (for wxLOCALE_CAT_NUMBER or MONEY)
wxLOCALE_THOUSANDS_SEP,
// the character used as decimal point (for wxLOCALE_CAT_NUMBER or MONEY)
wxLOCALE_DECIMAL_POINT,
// the stftime()-formats used for short/long date and time representations
// (under some platforms short and long date formats are the same)
//
// NB: these elements should appear in this order, code in GetInfo() relies
// on it
wxLOCALE_SHORT_DATE_FMT,
wxLOCALE_LONG_DATE_FMT,
wxLOCALE_DATE_TIME_FMT,
wxLOCALE_TIME_FMT
};
// ----------------------------------------------------------------------------
// wxLocale: encapsulates all language dependent settings, including current
// message catalogs, date, time and currency formats (TODO) &c
@@ -145,6 +56,8 @@ enum wxLocaleInitFlags
#endif
};
// NOTE: This class is deprecated, use wxUILocale and wxTranslations instead.
class WXDLLIMPEXP_BASE wxLocale
{
public:

113
include/wx/localedefs.h Normal file
View File

@@ -0,0 +1,113 @@
///////////////////////////////////////////////////////////////////////////////
// Name: wx/localedefs.h
// Purpose: Definitions of common locale-related constants and structs.
// Author: Vadim Zeitlin
// Created: 2021-07-31 (extracted from wx/intl.h)
// Copyright: (c) 2021 Vadim Zeitlin <vadim@wxwidgets.org>
// Licence: wxWindows licence
///////////////////////////////////////////////////////////////////////////////
#ifndef _WX_LOCALEDEFS_H_
#define _WX_LOCALEDEFS_H_
// ----------------------------------------------------------------------------
// wxLayoutDirection: used by wxWindow, wxDC etc
// ----------------------------------------------------------------------------
// Note that this one must be available even when wxUSE_INTL == 0 as it's used
// outside of locale code too.
enum wxLayoutDirection
{
wxLayout_Default,
wxLayout_LeftToRight,
wxLayout_RightToLeft
};
#if wxUSE_INTL
#include "wx/string.h"
// ----------------------------------------------------------------------------
// wxLocaleCategory: the category of locale settings
// ----------------------------------------------------------------------------
enum wxLocaleCategory
{
// (any) numbers
wxLOCALE_CAT_NUMBER,
// date/time
wxLOCALE_CAT_DATE,
// monetary value
wxLOCALE_CAT_MONEY,
// default category for wxLocaleInfo values which only apply to a single
// category (e.g. wxLOCALE_SHORT_DATE_FMT)
wxLOCALE_CAT_DEFAULT,
wxLOCALE_CAT_MAX
};
// ----------------------------------------------------------------------------
// wxLocaleInfo: the items understood by wxLocale::GetInfo()
// ----------------------------------------------------------------------------
enum wxLocaleInfo
{
// the thousands separator (for wxLOCALE_CAT_NUMBER or MONEY)
wxLOCALE_THOUSANDS_SEP,
// the character used as decimal point (for wxLOCALE_CAT_NUMBER or MONEY)
wxLOCALE_DECIMAL_POINT,
// the stftime()-formats used for short/long date and time representations
// (under some platforms short and long date formats are the same)
//
// NB: these elements should appear in this order, code in GetInfo() relies
// on it
wxLOCALE_SHORT_DATE_FMT,
wxLOCALE_LONG_DATE_FMT,
wxLOCALE_DATE_TIME_FMT,
wxLOCALE_TIME_FMT
};
// ----------------------------------------------------------------------------
// wxLanguageInfo: encapsulates wxLanguage to OS native lang.desc.
// translation information
// ----------------------------------------------------------------------------
struct WXDLLIMPEXP_BASE wxLanguageInfo
{
int Language; // wxLanguage id
wxString CanonicalName; // Canonical name, e.g. fr_FR
#ifdef __WINDOWS__
wxUint32 WinLang, // Win32 language identifiers
WinSublang;
#endif // __WINDOWS__
wxString Description; // human-readable name of the language
wxLayoutDirection LayoutDirection;
#ifdef __WINDOWS__
// return the LCID corresponding to this language
wxUint32 GetLCID() const;
#endif // __WINDOWS__
// return the locale name corresponding to this language usable with
// setlocale() on the current system or empty string if this locale is not
// supported
wxString GetLocaleName() const;
// Call setlocale() and return non-null value if it works for this language.
//
// This function is mostly for internal use, as changing locale involves
// more than just calling setlocale() on some platforms, use wxLocale to
// do everything that needs to be done instead of calling this method.
const char* TrySetLocale() const;
};
#endif // wxUSE_INTL
#endif // _WX_LOCALEDEFS_H_

View File

@@ -0,0 +1,28 @@
///////////////////////////////////////////////////////////////////////////////
// Name: wx/msw/private/uilocale.h
// Purpose: MSW-specific locale-related helpers
// Author: Vadim Zeitlin
// Created: 2021-08-14
// Copyright: (c) 2021 Vadim Zeitlin <vadim@wxwidgets.org>
// Licence: wxWindows licence
///////////////////////////////////////////////////////////////////////////////
#ifndef _WX_MSW_PRIVATE_UILOCALE_H_
#define _WX_MSW_PRIVATE_UILOCALE_H_
#include "wx/msw/private.h" // Include <windows.h> to get LCID.
#ifndef LOCALE_SNAME
#define LOCALE_SNAME 0x5c
#endif
#ifndef LOCALE_CUSTOM_UI_DEFAULT
#define LOCALE_CUSTOM_UI_DEFAULT 0x1400
#endif
// Use the specific LCID for the current thread.
void wxUseLCID(LCID lcid);
// This function is defined in src/common/intl.cpp
wxString wxGetInfoFromLCID(LCID lcid, wxLocaleInfo index, wxLocaleCategory cat);
#endif // _WX_MSW_PRIVATE_UILOCALE_H_

View File

@@ -40,6 +40,13 @@ public:
int precision,
int style = 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.
static wxString Format(const wxString& format, double val);
// Parse a string representing a number, possibly with thousands separator.
//
// Return true on success and stores the result in the provided location

View File

@@ -0,0 +1,49 @@
///////////////////////////////////////////////////////////////////////////////
// Name: wx/private/localeset.h
// Purpose: Define helper wxLocaleSetter class.
// Author: Vadim Zeitlin
// Created: 2021-08-03 (extracted from tests/testprec.h)
// Copyright: (c) 2021 Vadim Zeitlin <vadim@wxwidgets.org>
// Licence: wxWindows licence
///////////////////////////////////////////////////////////////////////////////
#ifndef _WX_PRIVATE_LOCALESET_H_
#define _WX_PRIVATE_LOCALESET_H_
#include "wx/crt.h" // wxStrdupA()
#include <locale.h>
// Helper class setting the locale to the given one for its lifetime.
class wxLocaleSetter
{
public:
wxLocaleSetter(const char *loc)
: m_locOld(wxStrdupA(setlocale(LC_ALL, NULL)))
{
setlocale(LC_ALL, loc);
}
~wxLocaleSetter()
{
setlocale(LC_ALL, m_locOld);
free(m_locOld);
}
private:
char * const m_locOld;
wxDECLARE_NO_COPY_CLASS(wxLocaleSetter);
};
// An even simpler helper for setting the locale to "C" one during its lifetime.
class wxCLocaleSetter : private wxLocaleSetter
{
public:
wxCLocaleSetter() : wxLocaleSetter("C") { }
private:
wxDECLARE_NO_COPY_CLASS(wxCLocaleSetter);
};
#endif // _WX_PRIVATE_LOCALESET_H_

View File

@@ -0,0 +1,52 @@
///////////////////////////////////////////////////////////////////////////////
// Name: wx/private/uilocale.h
// Purpose: wxUILocaleImpl class declaration
// Author: Vadim Zeitlin
// Created: 2021-08-01
// Copyright: (c) 2021 Vadim Zeitlin <vadim@wxwidgets.org>
// Licence: wxWindows licence
///////////////////////////////////////////////////////////////////////////////
#ifndef _WX_PRIVATE_UILOCALE_H_
#define _WX_PRIVATE_UILOCALE_H_
#include "wx/localedefs.h"
#include "wx/string.h"
// ----------------------------------------------------------------------------
// wxUILocaleImpl provides the implementation of public wxUILocale functions
// ----------------------------------------------------------------------------
class wxUILocaleImpl
{
public:
// This function is implemented in platform-specific code and returns the
// object used by default, i.e. if wxUILocale::UseDefault() is not called.
// This object corresponds to the traditional "C" locale.
//
// It should never return NULL.
static wxUILocaleImpl* CreateStdC();
// Similarly, this one returns the object corresponding to the default user
// locale settings which is used if wxUILocale::UseDefault() was called.
//
// It may return NULL in case of failure.
static wxUILocaleImpl* CreateUserDefault();
// This function exists only for wxLocale compatibility and sets the locale
// corresponding to the given language.
//
// The language passed to this function is a valid language, i.e. neither
// wxLANGUAGE_UNKNOWN nor wxLANGUAGE_DEFAULT.
//
// It may return NULL in case of failure.
static wxUILocaleImpl* CreateForLanguage(const wxLanguageInfo& info);
// Functions corresponding to wxUILocale ones.
virtual wxString GetName() const = 0;
virtual wxString GetInfo(wxLocaleInfo index, wxLocaleCategory cat) const = 0;
virtual ~wxUILocaleImpl() { }
};
#endif // _WX_PRIVATE_UILOCALE_H_

84
include/wx/uilocale.h Normal file
View File

@@ -0,0 +1,84 @@
///////////////////////////////////////////////////////////////////////////////
// Name: wx/uilocale.h
// Purpose: wxUILocale class declaration.
// Author: Vadim Zeitlin
// Created: 2021-07-31
// Copyright: (c) 2021 Vadim Zeitlin <vadim@wxwidgets.org>
// Licence: wxWindows licence
///////////////////////////////////////////////////////////////////////////////
#ifndef _WX_UILOCALE_H_
#define _WX_UILOCALE_H_
#include "wx/defs.h"
#if wxUSE_INTL
#include "wx/localedefs.h"
#include "wx/string.h"
class wxUILocaleImpl;
// ----------------------------------------------------------------------------
// wxUILocale allows to use the default UI locale and get information about it
// ----------------------------------------------------------------------------
class WXDLLIMPEXP_BASE wxUILocale
{
public:
// Configure the UI to use the default user locale.
static bool UseDefault();
// Use the locale corresponding to the given language.
//
// This is a compatibility function used by wxWidgets itself, don't use it
// in the new code.
static bool UseLanguage(const wxLanguageInfo& info);
// Get the object corresponding to the currently used locale.
static const wxUILocale& GetCurrent();
// Get the platform-dependent name of the current locale.
wxString GetName() const;
// Query the locale for the specified information.
wxString GetInfo(wxLocaleInfo index,
wxLocaleCategory cat = wxLOCALE_CAT_DEFAULT) const;
// Note that this class is not supposed to be used polymorphically, hence
// its dtor is not virtual.
~wxUILocale();
private:
// Ctor is private, use static accessor to get objects of this class.
wxUILocale() : m_impl(NULL) { }
// Used by UseDefault().
//
// Note that this object takes ownership of the provided pointer and will
// delete it in dtor.
void SetImpl(wxUILocaleImpl* impl);
static wxUILocale ms_current;
wxUILocaleImpl* m_impl;
wxDECLARE_NO_COPY_CLASS(wxUILocale);
};
inline wxString wxGetUIDateFormat()
{
return wxUILocale::GetCurrent().GetInfo(wxLOCALE_SHORT_DATE_FMT);
}
#else // !wxUSE_INTL
inline wxString wxGetUIDateFormat()
{
return wxString(wxS("%x"));
}
#endif // wxUSE_INTL/!wxUSE_INTL
#endif // _WX_UILOCALE_H_

View File

@@ -0,0 +1,33 @@
///////////////////////////////////////////////////////////////////////////////
// Name: wx/unix/private/uilocale.h
// Purpose: Various locale-related helpers used under Unix systems only
// Author: Vadim Zeitlin
// Created: 2021-08-14 (extracted from src/common/intl.cpp)
// Copyright: (c) 2021 Vadim Zeitlin <vadim@wxwidgets.org>
// Licence: wxWindows licence
///////////////////////////////////////////////////////////////////////////////
#ifndef _WX_UNIX_PRIVATE_UILOCALE_H_
#define _WX_UNIX_PRIVATE_UILOCALE_H_
#include "wx/string.h"
// get just the language part ("en" in "en_GB")
inline wxString ExtractLang(const wxString& langFull)
{
return langFull.BeforeFirst('_');
}
// get everything else (including the leading '_')
inline wxString ExtractNotLang(const wxString& langFull)
{
size_t pos = langFull.find('_');
if ( pos != wxString::npos )
return langFull.substr(pos);
else
return wxString();
}
const char *wxSetlocaleTryAll(int c, const wxString& lc);
#endif // _WX_UNIX_PRIVATE_UILOCALE_H_