1
0
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:
Paul Licameli 2015-06-07 17:37:40 -04:00
commit 2b2183ae63
12 changed files with 96 additions and 205 deletions

View File

@ -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);

View File

@ -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++)

View File

@ -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
{ {

View File

@ -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

View File

@ -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);

View File

@ -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();

View File

@ -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

View File

@ -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

View File

@ -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();

View File

@ -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

View File

@ -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);

View File

@ -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;