mirror of
https://github.com/cookiengineer/audacity
synced 2025-09-18 17:10:55 +02:00
Merge branch 'master' into temp
This commit is contained in:
commit
2b2183ae63
@ -42,6 +42,8 @@
|
|||||||
#ifndef __AUDACITY_EFFECTAUTOMATIONPARAMETERS_H__
|
#ifndef __AUDACITY_EFFECTAUTOMATIONPARAMETERS_H__
|
||||||
#define __AUDACITY_EFFECTAUTOMATIONPARAMETERS_H__
|
#define __AUDACITY_EFFECTAUTOMATIONPARAMETERS_H__
|
||||||
|
|
||||||
|
#include <locale.h>
|
||||||
|
|
||||||
#include <wx/cmdline.h>
|
#include <wx/cmdline.h>
|
||||||
#include <wx/fileconf.h>
|
#include <wx/fileconf.h>
|
||||||
#include <wx/intl.h>
|
#include <wx/intl.h>
|
||||||
@ -88,7 +90,8 @@ public:
|
|||||||
wxString str;
|
wxString str;
|
||||||
if (Read(key, &str))
|
if (Read(key, &str))
|
||||||
{
|
{
|
||||||
wxString dec = wxLocale::GetInfo(wxLOCALE_DECIMAL_POINT, wxLOCALE_CAT_NUMBER);
|
struct lconv *info = localeconv();
|
||||||
|
wxString dec = info ? wxString::FromUTF8(info->decimal_point) : wxT(".");
|
||||||
|
|
||||||
str.Replace(wxT(","), dec);
|
str.Replace(wxT(","), dec);
|
||||||
str.Replace(wxT("."), dec);
|
str.Replace(wxT("."), dec);
|
||||||
|
@ -971,36 +971,24 @@ wxLanguageInfo userLangs[] =
|
|||||||
|
|
||||||
void AudacityApp::InitLang( const wxString & lang )
|
void AudacityApp::InitLang( const wxString & lang )
|
||||||
{
|
{
|
||||||
if( mLocale )
|
if (mLocale)
|
||||||
delete mLocale;
|
delete mLocale;
|
||||||
|
|
||||||
wxString canon = lang;
|
|
||||||
|
|
||||||
#if defined(__WXMAC__)
|
#if defined(__WXMAC__)
|
||||||
// This should be reviewed again during the wx3 conversion.
|
// This should be reviewed again during the wx3 conversion.
|
||||||
|
|
||||||
// On OSX, the eventual call to setlocale() will fail to completely
|
|
||||||
// set the locale causing printf() and kin to still use the period
|
|
||||||
// as the decimal separator when the locale specifies something
|
|
||||||
// else.
|
|
||||||
const wxLanguageInfo *info = wxLocale::FindLanguageInfo(lang);
|
|
||||||
if (info) {
|
|
||||||
canon = info->CanonicalName;
|
|
||||||
}
|
|
||||||
|
|
||||||
// On OSX, if the LANG environment variable isn't set when
|
// On OSX, if the LANG environment variable isn't set when
|
||||||
// using a language like Japanese, an assertion will trigger
|
// using a language like Japanese, an assertion will trigger
|
||||||
// because conversion to Japanese from "?" doesn't return a
|
// because conversion to Japanese from "?" doesn't return a
|
||||||
// valid length, so make OSX happy by defining/overriding
|
// valid length, so make OSX happy by defining/overriding
|
||||||
// the LANG environment variable with what the user has
|
// the LANG environment variable with U.S. English for now.
|
||||||
// chosen.
|
wxSetEnv(wxT("LANG"), wxT("en_US.UTF-8"));
|
||||||
wxSetEnv(wxT("LANG"), canon);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if wxCHECK_VERSION(3,0,0)
|
#if wxCHECK_VERSION(3,0,0)
|
||||||
mLocale = new wxLocale(wxT(""), canon, wxT(""), true);
|
mLocale = new wxLocale(wxT(""), lang, wxT(""), true);
|
||||||
#else
|
#else
|
||||||
mLocale = new wxLocale(wxT(""), canon, wxT(""), true, true);
|
mLocale = new wxLocale(wxT(""), lang, wxT(""), true, true);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for(unsigned int i=0; i<audacityPathList.GetCount(); i++)
|
for(unsigned int i=0; i<audacityPathList.GetCount(); i++)
|
||||||
|
@ -383,7 +383,7 @@ XMLTagHandler* RecordingRecoveryHandler::HandleXMLChild(const wxChar *tag)
|
|||||||
//
|
//
|
||||||
// It is not intended that the user view or modify the file.
|
// It is not intended that the user view or modify the file.
|
||||||
//
|
//
|
||||||
// It IS intended that as little work be done during auto save, so numbers
|
// It IS intended that very little work be done during auto save, so numbers
|
||||||
// and strings are written in their native format. They will be converted
|
// and strings are written in their native format. They will be converted
|
||||||
// during recovery.
|
// during recovery.
|
||||||
//
|
//
|
||||||
@ -393,8 +393,8 @@ XMLTagHandler* RecordingRecoveryHandler::HandleXMLChild(const wxChar *tag)
|
|||||||
// name dictionary dictionary of all names used in the document
|
// name dictionary dictionary of all names used in the document
|
||||||
// data fields the "encoded" XML document
|
// data fields the "encoded" XML document
|
||||||
//
|
//
|
||||||
// If a subtree is added, it will be preceeded with FT_Push tell the decoder
|
// If a subtree is added, it will be preceeded with FT_Push to tell the decoder
|
||||||
// to preserve the active dictionary. The decoder when then restore the
|
// to preserve the active dictionary. The decoder will then restore the
|
||||||
// dictionary when an FT_Pop is encountered. Nesting is unlimited.
|
// dictionary when an FT_Pop is encountered. Nesting is unlimited.
|
||||||
//
|
//
|
||||||
// To save space, each name (attribute or element) encountered is stored in
|
// To save space, each name (attribute or element) encountered is stored in
|
||||||
@ -402,7 +402,7 @@ XMLTagHandler* RecordingRecoveryHandler::HandleXMLChild(const wxChar *tag)
|
|||||||
//
|
//
|
||||||
// All strings are in native unicode format, 2-byte or 4-byte.
|
// All strings are in native unicode format, 2-byte or 4-byte.
|
||||||
//
|
//
|
||||||
// All "lengths" are 2-byte signed, so are limited to 32767 bytes long/
|
// All "lengths" are 2-byte signed, so are limited to 32767 bytes long.
|
||||||
|
|
||||||
enum FieldTypes
|
enum FieldTypes
|
||||||
{
|
{
|
||||||
|
@ -982,7 +982,7 @@ void AudacityProject::CreateMenusAndCommands()
|
|||||||
c->SetDefaultFlags(AudioIONotBusyFlag, AudioIONotBusyFlag);
|
c->SetDefaultFlags(AudioIONotBusyFlag, AudioIONotBusyFlag);
|
||||||
|
|
||||||
#ifdef EXPERIMENTAL_EFFECT_MANAGEMENT
|
#ifdef EXPERIMENTAL_EFFECT_MANAGEMENT
|
||||||
c->AddItem(wxT("ManageGenerators"), _("Manage Generators..."), FN(OnManageGenerators));
|
c->AddItem(wxT("ManageGenerators"), _("Manage..."), FN(OnManageGenerators));
|
||||||
c->AddSeparator();
|
c->AddSeparator();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -1009,7 +1009,7 @@ void AudacityProject::CreateMenusAndCommands()
|
|||||||
buildMenuLabel.Printf(_("Repeat Last Effect"));
|
buildMenuLabel.Printf(_("Repeat Last Effect"));
|
||||||
|
|
||||||
#ifdef EXPERIMENTAL_EFFECT_MANAGEMENT
|
#ifdef EXPERIMENTAL_EFFECT_MANAGEMENT
|
||||||
c->AddItem(wxT("ManageEffects"), _("Manage Effects..."), FN(OnManageEffects));
|
c->AddItem(wxT("ManageEffects"), _("Manage..."), FN(OnManageEffects));
|
||||||
c->AddSeparator();
|
c->AddSeparator();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -1033,7 +1033,7 @@ void AudacityProject::CreateMenusAndCommands()
|
|||||||
c->BeginMenu(_("&Analyze"));
|
c->BeginMenu(_("&Analyze"));
|
||||||
|
|
||||||
#ifdef EXPERIMENTAL_EFFECT_MANAGEMENT
|
#ifdef EXPERIMENTAL_EFFECT_MANAGEMENT
|
||||||
c->AddItem(wxT("ManageAnalyzers"), _("Manage Analyzers..."), FN(OnManageAnalyzers));
|
c->AddItem(wxT("ManageAnalyzers"), _("Manage..."), FN(OnManageAnalyzers));
|
||||||
c->AddSeparator();
|
c->AddSeparator();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -516,25 +516,42 @@ void PluginRegistrationDialog::PopulateOrExchange(ShuttleGui &S)
|
|||||||
{
|
{
|
||||||
/*i18n-hint: The dialog shows a list of plugins with check-boxes
|
/*i18n-hint: The dialog shows a list of plugins with check-boxes
|
||||||
beside each one.*/
|
beside each one.*/
|
||||||
S.StartStatic(_("Select Plug-ins, click the Enable or Disable button, then click OK."), true);
|
// S.StartStatic(_("Effects"), true);
|
||||||
|
S.StartVerticalLay();
|
||||||
{
|
{
|
||||||
S.StartHorizontalLay(wxALIGN_LEFT,0 );
|
S.StartHorizontalLay(wxEXPAND, 0);
|
||||||
{
|
{
|
||||||
wxRadioButton* rb;
|
S.StartHorizontalLay(wxALIGN_LEFT, 0);
|
||||||
/* i18n-hint: This is before radio buttons selecting which effects to show */
|
{
|
||||||
S.AddPrompt(_("Show:"));
|
S.AddPrompt(_("Select effects, click the Enable or Disable button, then click OK."));
|
||||||
/* i18n-hint: Radio button to show all effects */
|
}
|
||||||
rb = S.Id(ID_ShowAll).AddRadioButton(_("&All"));
|
S.EndHorizontalLay();
|
||||||
rb->SetName(_("Show all"));
|
|
||||||
/* i18n-hint: Radio button to show just the currently disabled effects */
|
S.StartHorizontalLay(wxCENTER, 1);
|
||||||
rb = S.Id(ID_ShowDisabled).AddRadioButtonToGroup(_("D&isabled"));
|
{
|
||||||
rb->SetName(_("Show disabled"));
|
S.AddSpace(1);
|
||||||
/* i18n-hint: Radio button to show just the currently enabled effects */
|
}
|
||||||
rb = S.Id(ID_ShowEnabled).AddRadioButtonToGroup(_("E&nabled"));
|
S.EndHorizontalLay();
|
||||||
rb->SetName(_("Show enabled"));
|
|
||||||
/* i18n-hint: Radio button to show just the newly discovered effects */
|
S.StartHorizontalLay(wxALIGN_RIGHT, 0);
|
||||||
rb = S.Id(ID_ShowNew).AddRadioButtonToGroup(_("Ne&w"));
|
{
|
||||||
rb->SetName(_("Show new"));
|
wxRadioButton* rb;
|
||||||
|
/* i18n-hint: This is before radio buttons selecting which effects to show */
|
||||||
|
S.AddPrompt(_("Show:"));
|
||||||
|
/* i18n-hint: Radio button to show all effects */
|
||||||
|
rb = S.Id(ID_ShowAll).AddRadioButton(_("&All"));
|
||||||
|
rb->SetName(_("Show all"));
|
||||||
|
/* i18n-hint: Radio button to show just the currently disabled effects */
|
||||||
|
rb = S.Id(ID_ShowDisabled).AddRadioButtonToGroup(_("D&isabled"));
|
||||||
|
rb->SetName(_("Show disabled"));
|
||||||
|
/* i18n-hint: Radio button to show just the currently enabled effects */
|
||||||
|
rb = S.Id(ID_ShowEnabled).AddRadioButtonToGroup(_("E&nabled"));
|
||||||
|
rb->SetName(_("Show enabled"));
|
||||||
|
/* i18n-hint: Radio button to show just the newly discovered effects */
|
||||||
|
rb = S.Id(ID_ShowNew).AddRadioButtonToGroup(_("Ne&w"));
|
||||||
|
rb->SetName(_("Show new"));
|
||||||
|
}
|
||||||
|
S.EndHorizontalLay();
|
||||||
}
|
}
|
||||||
S.EndHorizontalLay();
|
S.EndHorizontalLay();
|
||||||
|
|
||||||
@ -568,7 +585,8 @@ void PluginRegistrationDialog::PopulateOrExchange(ShuttleGui &S)
|
|||||||
}
|
}
|
||||||
S.EndHorizontalLay();
|
S.EndHorizontalLay();
|
||||||
}
|
}
|
||||||
S.EndStatic();
|
// S.EndStatic();
|
||||||
|
S.EndVerticalLay();
|
||||||
|
|
||||||
S.AddStandardButtons(eOkButton | eCancelButton);
|
S.AddStandardButtons(eOkButton | eCancelButton);
|
||||||
}
|
}
|
||||||
@ -726,7 +744,7 @@ void PluginRegistrationDialog::RegenerateEffectsList(int filter)
|
|||||||
if (mEffects->GetItemCount() > 0)
|
if (mEffects->GetItemCount() > 0)
|
||||||
{
|
{
|
||||||
// Make sure first item is selected/focused.
|
// Make sure first item is selected/focused.
|
||||||
mEffects->SetFocus();
|
// mEffects->SetFocus();
|
||||||
mEffects->SetItemState(0, wxLIST_STATE_FOCUSED|wxLIST_STATE_SELECTED, wxLIST_STATE_FOCUSED|wxLIST_STATE_SELECTED);
|
mEffects->SetItemState(0, wxLIST_STATE_FOCUSED|wxLIST_STATE_SELECTED, wxLIST_STATE_FOCUSED|wxLIST_STATE_SELECTED);
|
||||||
#if wxUSE_ACCESSIBILITY
|
#if wxUSE_ACCESSIBILITY
|
||||||
mAx->SetSelected(0);
|
mAx->SetSelected(0);
|
||||||
|
@ -4730,7 +4730,7 @@ void AudacityProject::AutoSave()
|
|||||||
wxString projName;
|
wxString projName;
|
||||||
|
|
||||||
if (mFileName.IsEmpty())
|
if (mFileName.IsEmpty())
|
||||||
projName = _("New Project");
|
projName = wxT("New Project");
|
||||||
else
|
else
|
||||||
projName = wxFileName(mFileName).GetName();
|
projName = wxFileName(mFileName).GetName();
|
||||||
|
|
||||||
|
@ -1950,8 +1950,11 @@ void TrackPanel::SetCursorAndTipWhenSelectTool( Track * t,
|
|||||||
|
|
||||||
// If not shift-down and not snapping center, then
|
// If not shift-down and not snapping center, then
|
||||||
// choose boundaries only in snapping tolerance,
|
// choose boundaries only in snapping tolerance,
|
||||||
// and may choose center
|
// and may choose center.
|
||||||
SelectionBoundary boundary = ChooseBoundary(event, t, r, !bShiftDown, !bShiftDown);
|
// But don't change the cursor when scrubbing.
|
||||||
|
SelectionBoundary boundary = IsScrubbing()
|
||||||
|
? SBNone
|
||||||
|
: ChooseBoundary(event, t, r, !bShiftDown, !bShiftDown);
|
||||||
|
|
||||||
#ifdef USE_MIDI
|
#ifdef USE_MIDI
|
||||||
// The MIDI HitTest will only succeed if we are on a midi track, so
|
// The MIDI HitTest will only succeed if we are on a midi track, so
|
||||||
|
@ -282,6 +282,13 @@ bool EffectDtmf::Startup()
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool EffectDtmf::Init()
|
||||||
|
{
|
||||||
|
Recalculate();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void EffectDtmf::PopulateOrExchange(ShuttleGui & S)
|
void EffectDtmf::PopulateOrExchange(ShuttleGui & S)
|
||||||
{
|
{
|
||||||
// dialog will be passed values from effect
|
// dialog will be passed values from effect
|
||||||
|
@ -52,6 +52,7 @@ public:
|
|||||||
// Effect implementation
|
// Effect implementation
|
||||||
|
|
||||||
virtual bool Startup();
|
virtual bool Startup();
|
||||||
|
virtual bool Init();
|
||||||
virtual void PopulateOrExchange(ShuttleGui & S);
|
virtual void PopulateOrExchange(ShuttleGui & S);
|
||||||
virtual bool TransferDataFromWindow();
|
virtual bool TransferDataFromWindow();
|
||||||
virtual bool TransferDataToWindow();
|
virtual bool TransferDataToWindow();
|
||||||
|
@ -129,17 +129,17 @@
|
|||||||
EFFECT( WAHWAH, EffectWahwah() ) \
|
EFFECT( WAHWAH, EffectWahwah() ) \
|
||||||
EFFECT( FINDCLIPPING, EffectFindClipping() ) \
|
EFFECT( FINDCLIPPING, EffectFindClipping() ) \
|
||||||
NOISEREDUCTION_EFFECT \
|
NOISEREDUCTION_EFFECT \
|
||||||
SOUNDTOUCH_EFFECTS
|
SOUNDTOUCH_EFFECTS \
|
||||||
|
EFFECT( AUTODUCK, EffectAutoDuck() ) \
|
||||||
|
EFFECT( LEVELLER, EffectLeveller() ) \
|
||||||
|
EFFECT( PAULSTRETCH, EffectPaulstretch() ) \
|
||||||
|
SBSMS_EFFECTS
|
||||||
|
|
||||||
//
|
//
|
||||||
// Define the list of effects that do not get autoregistered
|
// Define the list of effects that do not get autoregistered
|
||||||
//
|
//
|
||||||
#define EXCLUDE_LIST \
|
#define EXCLUDE_LIST \
|
||||||
EFFECT( AUTODUCK, EffectAutoDuck() ) \
|
CLASSICFILTER_EFFECT
|
||||||
EFFECT( LEVELLER, EffectLeveller() ) \
|
|
||||||
EFFECT( PAULSTRETCH, EffectPaulstretch() ) \
|
|
||||||
CLASSICFILTER_EFFECT \
|
|
||||||
SBSMS_EFFECTS
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Define the EFFECT() macro to generate enum names
|
// Define the EFFECT() macro to generate enum names
|
||||||
|
@ -258,16 +258,16 @@ bool EffectToneGen::GetAutomationParameters(EffectAutomationParameters & parms)
|
|||||||
parms.Write(KEY_Amplitude, mAmplitude[0]);
|
parms.Write(KEY_Amplitude, mAmplitude[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
parms.Write(KEY_Waveform, mWaveforms[mWaveform]);
|
parms.Write(KEY_Waveform, kWaveStrings[mWaveform]);
|
||||||
parms.Write(KEY_Interp, mInterpolations[mInterpolation]);
|
parms.Write(KEY_Interp, kInterStrings[mInterpolation]);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EffectToneGen::SetAutomationParameters(EffectAutomationParameters & parms)
|
bool EffectToneGen::SetAutomationParameters(EffectAutomationParameters & parms)
|
||||||
{
|
{
|
||||||
ReadAndVerifyEnum(Waveform, mWaveforms);
|
ReadAndVerifyEnum(Waveform, wxArrayString(kNumWaveforms, kWaveStrings));
|
||||||
ReadAndVerifyEnum(Interp, mInterpolations);
|
ReadAndVerifyEnum(Interp, wxArrayString(kNumInterpolations, kInterStrings));
|
||||||
if (mChirp)
|
if (mChirp)
|
||||||
{
|
{
|
||||||
ReadAndVerifyDouble(StartFreq);
|
ReadAndVerifyDouble(StartFreq);
|
||||||
|
@ -39,77 +39,6 @@
|
|||||||
// local helpers
|
// local helpers
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
namespace
|
|
||||||
{
|
|
||||||
|
|
||||||
// Contains information about the locale which was used to initialize our
|
|
||||||
// cached values of the decimal and thousands separators. Notice that it isn't
|
|
||||||
// enough to store just wxLocale because the user code may call setlocale()
|
|
||||||
// directly and storing just C locale string is not enough because we can use
|
|
||||||
// the OS API directly instead of the CRT ones on some platforms. So just store
|
|
||||||
// both.
|
|
||||||
class LocaleId
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
LocaleId()
|
|
||||||
{
|
|
||||||
#if wxUSE_INTL
|
|
||||||
m_wxloc = NULL;
|
|
||||||
#endif // wxUSE_INTL
|
|
||||||
m_cloc = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
~LocaleId()
|
|
||||||
{
|
|
||||||
Free();
|
|
||||||
}
|
|
||||||
|
|
||||||
#if wxUSE_INTL
|
|
||||||
// Return true if this is the first time this function is called for this
|
|
||||||
// object or if the program locale has changed since the last time it was
|
|
||||||
// called. Otherwise just return false indicating that updating locale-
|
|
||||||
// dependent information is not necessary.
|
|
||||||
bool NotInitializedOrHasChanged()
|
|
||||||
{
|
|
||||||
wxLocale * const wxloc = wxGetLocale();
|
|
||||||
const char * const cloc = setlocale(LC_ALL, NULL);
|
|
||||||
if ( m_wxloc || m_cloc )
|
|
||||||
{
|
|
||||||
if ( m_wxloc == wxloc && strcmp(m_cloc, cloc) == 0 )
|
|
||||||
return false;
|
|
||||||
|
|
||||||
Free();
|
|
||||||
}
|
|
||||||
//else: Not initialized yet.
|
|
||||||
|
|
||||||
m_wxloc = wxloc;
|
|
||||||
m_cloc = strdup(cloc);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
#endif // wxUSE_INTL
|
|
||||||
|
|
||||||
private:
|
|
||||||
void Free()
|
|
||||||
{
|
|
||||||
#if wxUSE_INTL
|
|
||||||
free(m_cloc);
|
|
||||||
#endif // wxUSE_INTL
|
|
||||||
}
|
|
||||||
|
|
||||||
#if wxUSE_INTL
|
|
||||||
// Non-owned pointer to wxLocale which was used.
|
|
||||||
wxLocale *m_wxloc;
|
|
||||||
#endif // wxUSE_INTL
|
|
||||||
|
|
||||||
// Owned pointer to the C locale string.
|
|
||||||
char *m_cloc;
|
|
||||||
|
|
||||||
// wxDECLARE_NO_COPY_CLASS(LocaleId);
|
|
||||||
};
|
|
||||||
|
|
||||||
} // anonymous namespace
|
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// NumberFormatter implementation
|
// NumberFormatter implementation
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
@ -120,93 +49,35 @@ private:
|
|||||||
|
|
||||||
wxChar NumberFormatter::GetDecimalSeparator()
|
wxChar NumberFormatter::GetDecimalSeparator()
|
||||||
{
|
{
|
||||||
#if wxUSE_INTL
|
#if wxUSE_INTL
|
||||||
// Notice that while using static variable here is not MT-safe, the worst
|
struct lconv *info = localeconv();
|
||||||
// that can happen is that we redo the initialization if we're called
|
wxString s = info ? wxString::FromUTF8(info->decimal_point) : wxT(".");
|
||||||
// concurrently from more than one thread so it's not a real problem.
|
if (s.empty())
|
||||||
static wxChar s_decimalSeparator = 0;
|
{
|
||||||
|
// We really must have something for decimal separator, so fall
|
||||||
|
// back to the C locale default.
|
||||||
|
s = wxT(".");
|
||||||
|
}
|
||||||
|
|
||||||
// Remember the locale which was current when we initialized, we must redo
|
return s[0];
|
||||||
// the initialization if the locale changed.
|
|
||||||
static LocaleId s_localeUsedForInit;
|
|
||||||
|
|
||||||
if ( s_localeUsedForInit.NotInitializedOrHasChanged() )
|
|
||||||
{
|
|
||||||
const wxString
|
|
||||||
s = wxLocale::GetInfo(wxLOCALE_DECIMAL_POINT, wxLOCALE_CAT_NUMBER);
|
|
||||||
if ( s.empty() )
|
|
||||||
{
|
|
||||||
// We really must have something for decimal separator, so fall
|
|
||||||
// back to the C locale default.
|
|
||||||
s_decimalSeparator = '.';
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// To the best of my knowledge there are no locales like this.
|
|
||||||
wxASSERT_MSG( s.length() == 1,
|
|
||||||
wxT("Multi-character decimal separator?") );
|
|
||||||
|
|
||||||
s_decimalSeparator = s[0];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return s_decimalSeparator;
|
|
||||||
#else // !wxUSE_INTL
|
#else // !wxUSE_INTL
|
||||||
return wxT('.');
|
return wxT('.');
|
||||||
#endif // wxUSE_INTL/!wxUSE_INTL
|
#endif // wxUSE_INTL/!wxUSE_INTL
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NumberFormatter::GetThousandsSeparatorIfUsed(wxChar *sep)
|
bool NumberFormatter::GetThousandsSeparatorIfUsed(wxChar *sep)
|
||||||
{
|
{
|
||||||
#if wxUSE_INTL
|
#if wxUSE_INTL
|
||||||
static wxChar s_thousandsSeparator = 0;
|
struct lconv *info = localeconv();
|
||||||
static LocaleId s_localeUsedForInit;
|
wxString s = info ? wxString::FromUTF8(info->thousands_sep) : wxT("");
|
||||||
|
|
||||||
if ( s_localeUsedForInit.NotInitializedOrHasChanged() )
|
if (s.IsEmpty())
|
||||||
{
|
{
|
||||||
#if defined(__WXMSW__)
|
return false;
|
||||||
wxUint32 lcid = LOCALE_USER_DEFAULT;
|
}
|
||||||
|
|
||||||
if (wxGetLocale())
|
*sep = s[0];
|
||||||
{
|
return true;
|
||||||
const wxLanguageInfo *info = wxLocale::GetLanguageInfo(wxGetLocale()->GetLanguage());
|
|
||||||
if (info)
|
|
||||||
{ ;
|
|
||||||
lcid = MAKELCID(MAKELANGID(info->WinLang, info->WinSublang),
|
|
||||||
SORT_DEFAULT);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
wxString s;
|
|
||||||
wxChar buffer[256];
|
|
||||||
buffer[0] = wxT('\0');
|
|
||||||
size_t count = GetLocaleInfo(lcid, LOCALE_STHOUSAND, buffer, 256);
|
|
||||||
if (!count)
|
|
||||||
s << wxT(",");
|
|
||||||
else
|
|
||||||
s << buffer;
|
|
||||||
#else
|
|
||||||
wxString
|
|
||||||
s = wxLocale::GetInfo(wxLOCALE_THOUSANDS_SEP, wxLOCALE_CAT_NUMBER);
|
|
||||||
#endif
|
|
||||||
if ( !s.empty() )
|
|
||||||
{
|
|
||||||
wxASSERT_MSG( s.length() == 1,
|
|
||||||
wxT("Multi-character thousands separator?") );
|
|
||||||
|
|
||||||
s_thousandsSeparator = s[0];
|
|
||||||
}
|
|
||||||
//else: Unlike above it's perfectly fine for the thousands separator to
|
|
||||||
// be empty if grouping is not used, so just leave it as 0.
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( !s_thousandsSeparator )
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if ( sep )
|
|
||||||
*sep = s_thousandsSeparator;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
#else // !wxUSE_INTL
|
#else // !wxUSE_INTL
|
||||||
wxUnusedVar(sep);
|
wxUnusedVar(sep);
|
||||||
return false;
|
return false;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user