Reimplement ShuttleGui Tie... functions for radios and choices...
... so that in all cases a ChoiceSetting object stores all the details about visible names, internal string codes, default value, and preference path. Repetition of literals for some preference paths and their default values is eliminated
This commit is contained in:
commit
1b5c5a52d2
|
@ -576,12 +576,12 @@ bool MacroCommands::WriteMp3File( const wxString & Name, int bitrate )
|
|||
bool rc;
|
||||
long prevBitRate = gPrefs->Read(wxT("/FileFormats/MP3Bitrate"), 128);
|
||||
gPrefs->Write(wxT("/FileFormats/MP3Bitrate"), bitrate);
|
||||
int prevMode = gPrefs->Read(wxT("/FileFormats/MP3RateMode"), MODE_CBR);
|
||||
gPrefs->Write(wxT("/FileFormats/MP3RateMode"), MODE_CBR);
|
||||
auto prevMode = MP3RateModeSetting.ReadEnum();
|
||||
MP3RateModeSetting.WriteEnum(MODE_CBR);
|
||||
|
||||
auto cleanup = finally( [&] {
|
||||
gPrefs->Write(wxT("/FileFormats/MP3Bitrate"), prevBitRate);
|
||||
gPrefs->Write(wxT("/FileFormats/MP3RateMode"), prevMode);
|
||||
MP3RateModeSetting.WriteEnum(prevMode);
|
||||
gPrefs->Flush();
|
||||
} );
|
||||
|
||||
|
|
|
@ -52,6 +52,7 @@ AliasedFile s.
|
|||
|
||||
#include "blockfile/SimpleBlockFile.h"
|
||||
#include "DirManager.h"
|
||||
#include "FileFormats.h"
|
||||
#include "Prefs.h"
|
||||
#include "Project.h"
|
||||
#include "ProjectSettings.h"
|
||||
|
@ -589,8 +590,7 @@ void DependencyDialog::SaveFutureActionChoice()
|
|||
case 2: savePref = wxT("never"); break;
|
||||
default: savePref = wxT("ask");
|
||||
}
|
||||
gPrefs->Write(wxT("/FileFormats/SaveProjectWithDependencies"),
|
||||
savePref);
|
||||
FileFormatsSaveWithDependenciesSetting.Write( savePref );
|
||||
gPrefs->Flush();
|
||||
}
|
||||
}
|
||||
|
@ -632,9 +632,7 @@ New projects will be self-contained and are less risky.");
|
|||
{
|
||||
#ifdef EXPERIMENTAL_OD_DATA
|
||||
wxString action =
|
||||
gPrefs->Read(
|
||||
wxT("/FileFormats/SaveProjectWithDependencies"),
|
||||
wxT("ask"));
|
||||
FileFormatsSaveWithDependenciesSetting.Read();
|
||||
if (action == wxT("copy"))
|
||||
{
|
||||
// User always wants to remove dependencies
|
||||
|
|
|
@ -397,49 +397,45 @@ inline float Dither::ShapedDither(float sample)
|
|||
return result;
|
||||
}
|
||||
|
||||
static const EnumValueSymbol choicesDither[] = {
|
||||
static const std::initializer_list<EnumValueSymbol> choicesDither{
|
||||
{ XO("None") },
|
||||
{ XO("Rectangle") },
|
||||
{ XO("Triangle") },
|
||||
{ XO("Shaped") },
|
||||
};
|
||||
static const size_t nChoicesDither = WXSIZEOF( choicesDither );
|
||||
static const int intChoicesDither[] = {
|
||||
(int) DitherType::none,
|
||||
(int) DitherType::rectangle,
|
||||
(int) DitherType::triangle,
|
||||
(int) DitherType::shaped,
|
||||
static auto intChoicesDither = {
|
||||
DitherType::none,
|
||||
DitherType::rectangle,
|
||||
DitherType::triangle,
|
||||
DitherType::shaped,
|
||||
};
|
||||
static_assert(
|
||||
nChoicesDither == WXSIZEOF( intChoicesDither ),
|
||||
"size mismatch"
|
||||
);
|
||||
|
||||
static const size_t defaultFastDither = 0; // none
|
||||
|
||||
EnumSetting Dither::FastSetting{
|
||||
EnumSetting< DitherType > Dither::FastSetting{
|
||||
wxT("Quality/DitherAlgorithmChoice"),
|
||||
choicesDither, nChoicesDither, defaultFastDither,
|
||||
choicesDither,
|
||||
0, // none
|
||||
|
||||
// for migrating old preferences:
|
||||
intChoicesDither,
|
||||
wxT("Quality/DitherAlgorithm")
|
||||
};
|
||||
|
||||
static const size_t defaultBestDither = 3; // shaped
|
||||
|
||||
EnumSetting Dither::BestSetting{
|
||||
EnumSetting< DitherType > Dither::BestSetting{
|
||||
wxT("Quality/HQDitherAlgorithmChoice"),
|
||||
choicesDither, nChoicesDither, defaultBestDither,
|
||||
choicesDither,
|
||||
3, // shaped
|
||||
|
||||
// for migrating old preferences:
|
||||
intChoicesDither,
|
||||
wxT("Quality/HQDitherAlgorithm")
|
||||
};
|
||||
|
||||
DitherType Dither::FastDitherChoice()
|
||||
{
|
||||
return (DitherType) FastSetting.ReadInt();
|
||||
return (DitherType) FastSetting.ReadEnum();
|
||||
}
|
||||
|
||||
DitherType Dither::BestDitherChoice()
|
||||
{
|
||||
return (DitherType) BestSetting.ReadInt();
|
||||
return (DitherType) BestSetting.ReadEnum();
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
|
||||
#include "audacity/Types.h" // for samplePtr
|
||||
|
||||
class EnumSetting;
|
||||
template< typename Enum > class EnumSetting;
|
||||
|
||||
|
||||
/// These ditherers are currently available:
|
||||
|
@ -25,7 +25,7 @@ public:
|
|||
static DitherType FastDitherChoice();
|
||||
static DitherType BestDitherChoice();
|
||||
|
||||
static EnumSetting FastSetting, BestSetting;
|
||||
static EnumSetting< DitherType > FastSetting, BestSetting;
|
||||
|
||||
/// Default constructor
|
||||
Dither();
|
||||
|
|
|
@ -23,6 +23,7 @@ information.
|
|||
#include "sndfile.h"
|
||||
#include "Internat.h"
|
||||
#include "widgets/AudacityMessageBox.h"
|
||||
#include "Prefs.h"
|
||||
|
||||
#ifndef SNDFILE_1
|
||||
#error Requires libsndfile 1.0 or higher
|
||||
|
@ -334,3 +335,28 @@ int SFFileCloser::operator() (SNDFILE *sf) const
|
|||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
ChoiceSetting FileFormatsCopyOrEditSetting{
|
||||
wxT("/FileFormats/CopyOrEditUncompressedData"),
|
||||
{
|
||||
EnumValueSymbol{
|
||||
wxT("copy"),
|
||||
XO("&Copy uncompressed files into the project (safer)")
|
||||
},
|
||||
EnumValueSymbol{
|
||||
wxT("edit"),
|
||||
XO("&Read uncompressed files from original location (faster)")
|
||||
},
|
||||
},
|
||||
0 // copy
|
||||
};
|
||||
|
||||
ChoiceSetting FileFormatsSaveWithDependenciesSetting{
|
||||
wxT("/FileFormats/SaveProjectWithDependencies"),
|
||||
{
|
||||
{ wxT("copy"), XO("&Copy all audio into project (safest)") },
|
||||
{ wxT("never"), XO("Do ¬ copy any audio") },
|
||||
{ wxT("ask"), XO("As&k") },
|
||||
},
|
||||
2 // ask
|
||||
};
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
|
||||
#include "sndfile.h"
|
||||
|
||||
class ChoiceSetting;
|
||||
class wxString;
|
||||
|
||||
//
|
||||
|
@ -130,4 +131,7 @@ struct SFFile : public std::unique_ptr<SNDFILE, ::SFFileCloser>
|
|||
}
|
||||
};
|
||||
|
||||
extern ChoiceSetting FileFormatsCopyOrEditSetting;
|
||||
extern ChoiceSetting FileFormatsSaveWithDependenciesSetting;
|
||||
|
||||
#endif
|
||||
|
|
|
@ -360,7 +360,7 @@ void MixerTrackCluster::UpdatePrefs()
|
|||
{
|
||||
this->SetBackgroundColour( theTheme.Colour( clrMedium ) );
|
||||
mStaticText_TrackName->SetForegroundColour(theTheme.Colour(clrTrackPanelText));
|
||||
HandleResize(); // in case prefs "/GUI/Solo" changed
|
||||
HandleResize(); // in case TracksBehaviorsSolo changed
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
#include "DirManager.h"
|
||||
#include "Prefs.h"
|
||||
#include "ProjectFileIORegistry.h"
|
||||
#include "prefs/ImportExportPrefs.h"
|
||||
|
||||
#include "InconsistencyException.h"
|
||||
|
||||
|
@ -847,8 +848,7 @@ bool NoteTrack::ExportMIDI(const wxString &f) const
|
|||
bool NoteTrack::ExportAllegro(const wxString &f) const
|
||||
{
|
||||
double offset = GetOffset();
|
||||
bool in_seconds;
|
||||
gPrefs->Read(wxT("/FileFormats/AllegroStyle"), &in_seconds, true);
|
||||
auto in_seconds = ImportExportPrefs::AllegroStyleSetting.ReadEnum();
|
||||
auto &seq = GetSeq();
|
||||
if (in_seconds) {
|
||||
seq.convert_to_seconds();
|
||||
|
|
138
src/Prefs.cpp
138
src/Prefs.cpp
|
@ -240,9 +240,58 @@ void FinishPreferences()
|
|||
}
|
||||
|
||||
//////////
|
||||
EnumValueSymbols::EnumValueSymbols(
|
||||
ByColumns_t,
|
||||
const wxArrayStringEx &msgids,
|
||||
wxArrayStringEx internals
|
||||
)
|
||||
: mInternals( std::move( internals ) )
|
||||
{
|
||||
auto size = mInternals.size(), size2 = msgids.size();
|
||||
if ( size != size2 ) {
|
||||
wxASSERT( false );
|
||||
size = std::min( size, size2 );
|
||||
}
|
||||
reserve( size );
|
||||
auto iter1 = mInternals.begin();
|
||||
auto iter2 = msgids.begin();
|
||||
while( size-- )
|
||||
emplace_back( *iter1++, *iter2++ );
|
||||
}
|
||||
|
||||
const wxArrayStringEx &EnumValueSymbols::GetTranslations() const
|
||||
{
|
||||
if ( mTranslations.empty() )
|
||||
mTranslations = transform_container<wxArrayStringEx>( *this,
|
||||
std::mem_fn( &EnumValueSymbol::Translation ) );
|
||||
return mTranslations;
|
||||
}
|
||||
|
||||
const wxArrayStringEx &EnumValueSymbols::GetInternals() const
|
||||
{
|
||||
if ( mInternals.empty() )
|
||||
mInternals = transform_container<wxArrayStringEx>( *this,
|
||||
std::mem_fn( &EnumValueSymbol::Internal ) );
|
||||
return mInternals;
|
||||
}
|
||||
|
||||
//////////
|
||||
const EnumValueSymbol &ChoiceSetting::Default() const
|
||||
{
|
||||
if ( mDefaultSymbol >= 0 && mDefaultSymbol < mSymbols.size() )
|
||||
return mSymbols[ mDefaultSymbol ];
|
||||
static EnumValueSymbol empty;
|
||||
return empty;
|
||||
}
|
||||
|
||||
wxString ChoiceSetting::Read() const
|
||||
{
|
||||
const auto &defaultValue = Default().Internal();
|
||||
return ReadWithDefault( defaultValue );
|
||||
}
|
||||
|
||||
wxString ChoiceSetting::ReadWithDefault( const wxString &defaultValue ) const
|
||||
{
|
||||
wxString value;
|
||||
if ( !gPrefs->Read(mKey, &value, defaultValue) )
|
||||
if (!mMigrated) {
|
||||
|
@ -253,16 +302,17 @@ wxString ChoiceSetting::Read() const
|
|||
// Remap to default if the string is not known -- this avoids surprises
|
||||
// in case we try to interpret config files from future versions
|
||||
auto index = Find( value );
|
||||
if ( index >= mnSymbols )
|
||||
if ( index >= mSymbols.size() )
|
||||
value = defaultValue;
|
||||
return value;
|
||||
}
|
||||
|
||||
size_t ChoiceSetting::Find( const wxString &value ) const
|
||||
{
|
||||
auto start = GetSymbols().begin();
|
||||
return size_t(
|
||||
std::find( begin(), end(), EnumValueSymbol{ value, {} } )
|
||||
- mSymbols );
|
||||
std::find( start, GetSymbols().end(), EnumValueSymbol{ value, {} } )
|
||||
- start );
|
||||
}
|
||||
|
||||
void ChoiceSetting::Migrate( wxString &value )
|
||||
|
@ -273,7 +323,7 @@ void ChoiceSetting::Migrate( wxString &value )
|
|||
bool ChoiceSetting::Write( const wxString &value )
|
||||
{
|
||||
auto index = Find( value );
|
||||
if (index >= mnSymbols)
|
||||
if (index >= mSymbols.size())
|
||||
return false;
|
||||
|
||||
auto result = gPrefs->Write( mKey, value );
|
||||
|
@ -281,27 +331,65 @@ bool ChoiceSetting::Write( const wxString &value )
|
|||
return result;
|
||||
}
|
||||
|
||||
int EnumSetting::ReadInt() const
|
||||
{
|
||||
if (!mIntValues)
|
||||
return 0;
|
||||
EnumSettingBase::EnumSettingBase(
|
||||
const wxString &key,
|
||||
EnumValueSymbols symbols,
|
||||
long defaultSymbol,
|
||||
|
||||
std::vector<int> intValues, // must have same size as symbols
|
||||
const wxString &oldKey
|
||||
)
|
||||
: ChoiceSetting{ key, std::move( symbols ), defaultSymbol }
|
||||
, mIntValues{ std::move( intValues ) }
|
||||
, mOldKey{ oldKey }
|
||||
{
|
||||
auto size = mSymbols.size();
|
||||
if( mIntValues.size() != size ) {
|
||||
wxASSERT( false );
|
||||
mIntValues.resize( size );
|
||||
}
|
||||
}
|
||||
|
||||
void ChoiceSetting::SetDefault( long value )
|
||||
{
|
||||
if ( value < (long)mSymbols.size() )
|
||||
mDefaultSymbol = value;
|
||||
else
|
||||
wxASSERT( false );
|
||||
}
|
||||
|
||||
int EnumSettingBase::ReadInt() const
|
||||
{
|
||||
auto index = Find( Read() );
|
||||
wxASSERT( index < mnSymbols );
|
||||
|
||||
wxASSERT( index < mIntValues.size() );
|
||||
return mIntValues[ index ];
|
||||
}
|
||||
|
||||
size_t EnumSetting::FindInt( int code ) const
|
||||
int EnumSettingBase::ReadIntWithDefault( int defaultValue ) const
|
||||
{
|
||||
if (!mIntValues)
|
||||
return mnSymbols;
|
||||
wxString defaultString;
|
||||
auto index0 = FindInt( defaultValue );
|
||||
if ( index0 < mSymbols.size() )
|
||||
defaultString = mSymbols[ index0 ].Internal();
|
||||
else
|
||||
wxASSERT( false );
|
||||
|
||||
return size_t(
|
||||
std::find( mIntValues, mIntValues + mnSymbols, code )
|
||||
- mIntValues );
|
||||
auto index = Find( ReadWithDefault( defaultString ) );
|
||||
|
||||
wxASSERT( index < mSymbols.size() );
|
||||
return mIntValues[ index ];
|
||||
}
|
||||
|
||||
void EnumSetting::Migrate( wxString &value )
|
||||
size_t EnumSettingBase::FindInt( int code ) const
|
||||
{
|
||||
const auto start = mIntValues.begin();
|
||||
return size_t(
|
||||
std::find( start, mIntValues.end(), code )
|
||||
- start );
|
||||
}
|
||||
|
||||
void EnumSettingBase::Migrate( wxString &value )
|
||||
{
|
||||
int intValue = 0;
|
||||
if ( !mOldKey.empty() &&
|
||||
|
@ -310,19 +398,21 @@ void EnumSetting::Migrate( wxString &value )
|
|||
// Do not DELETE the old key -- let that be read if user downgrades
|
||||
// Audacity. But further changes will be stored only to the NEW key
|
||||
// and won't be seen then.
|
||||
auto index = FindInt( intValue );
|
||||
if ( index >= mnSymbols )
|
||||
auto index = (long) FindInt( intValue );
|
||||
if ( index >= mSymbols.size() )
|
||||
index = mDefaultSymbol;
|
||||
value = mSymbols[index].Internal();
|
||||
Write(value);
|
||||
gPrefs->Flush();
|
||||
if ( index >= 0 && index < mSymbols.size() ) {
|
||||
value = mSymbols[index].Internal();
|
||||
Write(value);
|
||||
gPrefs->Flush();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool EnumSetting::WriteInt( int code ) // you flush gPrefs afterward
|
||||
bool EnumSettingBase::WriteInt( int code ) // you flush gPrefs afterward
|
||||
{
|
||||
auto index = FindInt( code );
|
||||
if ( index >= mnSymbols )
|
||||
if ( index >= mSymbols.size() )
|
||||
return false;
|
||||
return Write( mSymbols[index].Internal() );
|
||||
}
|
||||
|
@ -331,3 +421,5 @@ wxString WarningDialogKey(const wxString &internalDialogName)
|
|||
{
|
||||
return wxT("/Warnings/") + internalDialogName;
|
||||
}
|
||||
|
||||
ByColumns_t ByColumns{};
|
||||
|
|
137
src/Prefs.h
137
src/Prefs.h
|
@ -32,6 +32,7 @@
|
|||
#include "Audacity.h"
|
||||
|
||||
#include "../include/audacity/ComponentInterface.h"
|
||||
#include "MemoryX.h" // for wxArrayStringEx
|
||||
|
||||
#include <memory>
|
||||
#include <wx/fileconf.h> // to inherit wxFileConfig
|
||||
|
@ -86,6 +87,38 @@ public:
|
|||
int mVersionMicroKeyInit{};
|
||||
};
|
||||
|
||||
struct ByColumns_t{};
|
||||
extern ByColumns_t ByColumns;
|
||||
|
||||
/// A table of EnumValueSymbol that you can access by "row" with
|
||||
/// operator [] but also allowing access to the "columns" of internal or
|
||||
/// translated strings, and also allowing convenient column-wise construction
|
||||
class EnumValueSymbols : public std::vector< EnumValueSymbol >
|
||||
{
|
||||
public:
|
||||
EnumValueSymbols() = default;
|
||||
EnumValueSymbols( std::initializer_list<EnumValueSymbol> symbols )
|
||||
: vector( symbols )
|
||||
{}
|
||||
|
||||
// columnwise constructor; arguments must have same size
|
||||
// (Implicit constructor takes initial tag argument to avoid unintended
|
||||
// overload resolution to the inherited constructor taking
|
||||
// initializer_list, in the case that each column has exactly two strings)
|
||||
EnumValueSymbols(
|
||||
ByColumns_t,
|
||||
const wxArrayStringEx &msgids, // untranslated!
|
||||
wxArrayStringEx internals
|
||||
);
|
||||
|
||||
const wxArrayStringEx &GetTranslations() const;
|
||||
const wxArrayStringEx &GetInternals() const;
|
||||
|
||||
private:
|
||||
mutable wxArrayStringEx mTranslations;
|
||||
mutable wxArrayStringEx mInternals;
|
||||
};
|
||||
|
||||
/// Packages a table of user-visible choices each with an internal code string,
|
||||
/// a preference key path, and a default choice
|
||||
class ChoiceSetting
|
||||
|
@ -93,78 +126,122 @@ class ChoiceSetting
|
|||
public:
|
||||
ChoiceSetting(
|
||||
const wxString &key,
|
||||
const EnumValueSymbol symbols[], size_t nSymbols,
|
||||
size_t defaultSymbol
|
||||
EnumValueSymbols symbols,
|
||||
long defaultSymbol = -1
|
||||
)
|
||||
: mKey{ key }
|
||||
|
||||
, mSymbols{ symbols }
|
||||
, mnSymbols{ nSymbols }
|
||||
, mSymbols{ std::move( symbols ) }
|
||||
|
||||
, mDefaultSymbol{ defaultSymbol }
|
||||
{
|
||||
wxASSERT( defaultSymbol < nSymbols );
|
||||
wxASSERT( defaultSymbol < (long)mSymbols.size() );
|
||||
}
|
||||
|
||||
const wxString &Key() const { return mKey; }
|
||||
const EnumValueSymbol &Default() const
|
||||
{ return mSymbols[mDefaultSymbol]; }
|
||||
const EnumValueSymbol *begin() const { return mSymbols; }
|
||||
const EnumValueSymbol *end() const { return mSymbols + mnSymbols; }
|
||||
const EnumValueSymbol &Default() const;
|
||||
const EnumValueSymbols &GetSymbols() const { return mSymbols; }
|
||||
|
||||
wxString Read() const;
|
||||
|
||||
// new direct use is discouraged but it may be needed in legacy code:
|
||||
// use a default in case the preference is not defined, which may not be
|
||||
// the default-default stored in this object.
|
||||
wxString ReadWithDefault( const wxString & ) const;
|
||||
|
||||
bool Write( const wxString &value ); // you flush gPrefs afterward
|
||||
|
||||
void SetDefault( long value );
|
||||
|
||||
protected:
|
||||
size_t Find( const wxString &value ) const;
|
||||
virtual void Migrate( wxString& );
|
||||
|
||||
const wxString mKey;
|
||||
|
||||
const EnumValueSymbol *mSymbols;
|
||||
const size_t mnSymbols;
|
||||
const EnumValueSymbols mSymbols;
|
||||
|
||||
// stores an internal value
|
||||
mutable bool mMigrated { false };
|
||||
|
||||
const size_t mDefaultSymbol;
|
||||
long mDefaultSymbol;
|
||||
};
|
||||
|
||||
/// Extends ChoiceSetting with a corresponding table of integer codes
|
||||
/// (generally not equal to their table positions),
|
||||
/// and optionally an old preference key path that stored integer codes, to be
|
||||
/// migrated into one that stores internal string values instead
|
||||
class EnumSetting : public ChoiceSetting
|
||||
class EnumSettingBase : public ChoiceSetting
|
||||
{
|
||||
public:
|
||||
EnumSetting(
|
||||
EnumSettingBase(
|
||||
const wxString &key,
|
||||
const EnumValueSymbol symbols[], size_t nSymbols,
|
||||
size_t defaultSymbol,
|
||||
EnumValueSymbols symbols,
|
||||
long defaultSymbol,
|
||||
|
||||
const int intValues[] = nullptr, // must have same size as symbols
|
||||
const wxString &oldKey = wxString("")
|
||||
)
|
||||
: ChoiceSetting{ key, symbols, nSymbols, defaultSymbol }
|
||||
, mIntValues{ intValues }
|
||||
, mOldKey{ oldKey }
|
||||
{
|
||||
wxASSERT( mIntValues );
|
||||
}
|
||||
|
||||
// Read and write the encoded values
|
||||
virtual int ReadInt() const;
|
||||
bool WriteInt( int code ); // you flush gPrefs afterward
|
||||
std::vector<int> intValues, // must have same size as symbols
|
||||
const wxString &oldKey
|
||||
);
|
||||
|
||||
protected:
|
||||
|
||||
// Read and write the encoded values
|
||||
int ReadInt() const;
|
||||
|
||||
// new direct use is discouraged but it may be needed in legacy code:
|
||||
// use a default in case the preference is not defined, which may not be
|
||||
// the default-default stored in this object.
|
||||
int ReadIntWithDefault( int defaultValue ) const;
|
||||
|
||||
bool WriteInt( int code ); // you flush gPrefs afterward
|
||||
|
||||
size_t FindInt( int code ) const;
|
||||
void Migrate( wxString& ) override;
|
||||
|
||||
private:
|
||||
const int *mIntValues;
|
||||
std::vector<int> mIntValues;
|
||||
const wxString mOldKey;
|
||||
};
|
||||
|
||||
/// Adapts EnumSettingBase to a particular enumeration type
|
||||
template< typename Enum >
|
||||
class EnumSetting : public EnumSettingBase
|
||||
{
|
||||
public:
|
||||
|
||||
EnumSetting(
|
||||
const wxString &key,
|
||||
EnumValueSymbols symbols,
|
||||
long defaultSymbol,
|
||||
|
||||
std::initializer_list< Enum > values, // must have same size as symbols
|
||||
const wxString &oldKey
|
||||
)
|
||||
: EnumSettingBase{
|
||||
key, symbols, defaultSymbol,
|
||||
{ values.begin(), values.end() },
|
||||
oldKey
|
||||
}
|
||||
{}
|
||||
|
||||
// Wrap ReadInt() and ReadIntWithDefault() and WriteInt()
|
||||
Enum ReadEnum() const
|
||||
{ return static_cast<Enum>( ReadInt() ); }
|
||||
|
||||
// new direct use is discouraged but it may be needed in legacy code:
|
||||
// use a default in case the preference is not defined, which may not be
|
||||
// the default-default stored in this object.
|
||||
Enum ReadEnumWithDefault( Enum defaultValue ) const
|
||||
{
|
||||
auto integer = static_cast<int>(defaultValue);
|
||||
return static_cast<Enum>( ReadIntWithDefault( integer ) );
|
||||
}
|
||||
|
||||
bool WriteEnum( Enum value )
|
||||
{ return WriteInt( static_cast<int>( value ) ); }
|
||||
|
||||
};
|
||||
|
||||
// An event emitted by the application when the Preference dialog commits
|
||||
// changes
|
||||
wxDECLARE_EVENT(EVT_PREFS_UPDATE, wxCommandEvent);
|
||||
|
|
|
@ -22,6 +22,7 @@ Paul Licameli split from AudacityProject.cpp
|
|||
#include "AutoRecovery.h"
|
||||
#include "Dependencies.h"
|
||||
#include "DirManager.h"
|
||||
#include "FileFormats.h"
|
||||
#include "FileNames.h"
|
||||
#include "Legacy.h"
|
||||
#include "PlatformCompatibility.h"
|
||||
|
@ -122,13 +123,12 @@ auto ProjectFileManager::ReadProjectFile( const FilePath &fileName )
|
|||
#ifdef EXPERIMENTAL_OD_DATA
|
||||
// 'Lossless copy' projects have dependencies. We need to always copy-in
|
||||
// these dependencies when converting to a normal project.
|
||||
wxString oldAction =
|
||||
gPrefs->Read(wxT("/FileFormats/CopyOrEditUncompressedData"), wxT("copy"));
|
||||
auto oldAction = FileFormatsCopyOrEditSetting.Read();
|
||||
bool oldAsk =
|
||||
gPrefs->ReadBool(wxT("/Warnings/CopyOrEditUncompressedDataAsk"), true);
|
||||
|
||||
if (oldAction != wxT("copy"))
|
||||
gPrefs->Write(wxT("/FileFormats/CopyOrEditUncompressedData"), wxT("copy"));
|
||||
FileFormatsCopyOrEditSetting.Write( wxT("copy") );
|
||||
if (oldAsk)
|
||||
gPrefs->Write(wxT("/Warnings/CopyOrEditUncompressedDataAsk"), (long) false);
|
||||
gPrefs->Flush();
|
||||
|
@ -136,7 +136,7 @@ auto ProjectFileManager::ReadProjectFile( const FilePath &fileName )
|
|||
auto cleanup = finally( [&] {
|
||||
// and restore old settings if necessary.
|
||||
if (oldAction != wxT("copy"))
|
||||
gPrefs->Write(wxT("/FileFormats/CopyOrEditUncompressedData"), oldAction);
|
||||
FileFormatsCopyOrEditSetting.Write( oldAction );
|
||||
if (oldAsk)
|
||||
gPrefs->Write(wxT("/Warnings/CopyOrEditUncompressedDataAsk"), (long) true);
|
||||
gPrefs->Flush();
|
||||
|
|
|
@ -16,6 +16,7 @@ Paul Licameli split from AudacityProject.cpp
|
|||
#include "Project.h"
|
||||
#include "prefs/QualityPrefs.h"
|
||||
#include "widgets/NumericTextCtrl.h"
|
||||
#include "prefs/TracksBehaviorsPrefs.h"
|
||||
|
||||
wxDEFINE_EVENT(EVT_PROJECT_SETTINGS_CHANGE, wxCommandEvent);
|
||||
|
||||
|
@ -91,7 +92,7 @@ void ProjectSettings::UpdatePrefs()
|
|||
gPrefs->Read(wxT("/AudioFiles/ShowId3Dialog"), &mShowId3Dialog, true);
|
||||
gPrefs->Read(wxT("/GUI/EmptyCanBeDirty"), &mEmptyCanBeDirty, true );
|
||||
gPrefs->Read(wxT("/GUI/ShowSplashScreen"), &mShowSplashScreen, true);
|
||||
gPrefs->Read(wxT("/GUI/Solo"), &mSoloPref, wxT("Simple"));
|
||||
mSoloPref = TracksBehaviorsSolo.Read();
|
||||
// Update the old default to the NEW default.
|
||||
if (mSoloPref == wxT("Standard"))
|
||||
mSoloPref = wxT("Simple");
|
||||
|
|
|
@ -52,53 +52,36 @@ Resample::~Resample()
|
|||
}
|
||||
|
||||
//////////
|
||||
static const EnumValueSymbol methodNames[] = {
|
||||
static const std::initializer_list<EnumValueSymbol> methodNames{
|
||||
{ wxT("LowQuality"), XO("Low Quality (Fastest)") },
|
||||
{ wxT("MediumQuality"), XO("Medium Quality") },
|
||||
{ wxT("HighQuality"), XO("High Quality") },
|
||||
{ wxT("BestQuality"), XO("Best Quality (Slowest)") }
|
||||
};
|
||||
|
||||
static const size_t numMethods = WXSIZEOF(methodNames);
|
||||
|
||||
static const wxString fastMethodKey =
|
||||
wxT("/Quality/LibsoxrSampleRateConverterChoice");
|
||||
|
||||
static const wxString bestMethodKey =
|
||||
wxT("/Quality/LibsoxrHQSampleRateConverterChoice");
|
||||
|
||||
static const wxString oldFastMethodKey =
|
||||
wxT("/Quality/LibsoxrSampleRateConverter");
|
||||
|
||||
static const wxString oldBestMethodKey =
|
||||
wxT("/Quality/LibsoxrHQSampleRateConverter");
|
||||
|
||||
static const size_t fastMethodDefault = 1; // Medium Quality
|
||||
static const size_t bestMethodDefault = 3; // Best Quality
|
||||
|
||||
static const int intChoicesMethod[] = {
|
||||
static auto intChoicesMethod = {
|
||||
0, 1, 2, 3
|
||||
};
|
||||
|
||||
static_assert( WXSIZEOF(intChoicesMethod) == numMethods, "size mismatch" );
|
||||
|
||||
EnumSetting Resample::FastMethodSetting{
|
||||
fastMethodKey,
|
||||
methodNames, numMethods,
|
||||
fastMethodDefault,
|
||||
EnumSetting< int > Resample::FastMethodSetting{
|
||||
wxT("/Quality/LibsoxrSampleRateConverterChoice"),
|
||||
methodNames,
|
||||
1, // Medium Quality
|
||||
|
||||
// for migrating old preferences:
|
||||
intChoicesMethod,
|
||||
oldFastMethodKey
|
||||
wxT("/Quality/LibsoxrSampleRateConverter")
|
||||
};
|
||||
|
||||
EnumSetting Resample::BestMethodSetting
|
||||
EnumSetting< int > Resample::BestMethodSetting
|
||||
{
|
||||
bestMethodKey,
|
||||
methodNames, numMethods,
|
||||
bestMethodDefault,
|
||||
wxT("/Quality/LibsoxrHQSampleRateConverterChoice"),
|
||||
methodNames,
|
||||
3, // Best Quality,
|
||||
|
||||
// for migrating old preferences:
|
||||
intChoicesMethod,
|
||||
oldBestMethodKey
|
||||
wxT("/Quality/LibsoxrHQSampleRateConverter")
|
||||
};
|
||||
|
||||
//////////
|
||||
|
@ -132,7 +115,7 @@ std::pair<size_t, size_t>
|
|||
void Resample::SetMethod(const bool useBestMethod)
|
||||
{
|
||||
if (useBestMethod)
|
||||
mMethod = BestMethodSetting.ReadInt();
|
||||
mMethod = BestMethodSetting.ReadEnum();
|
||||
else
|
||||
mMethod = FastMethodSetting.ReadInt();
|
||||
mMethod = FastMethodSetting.ReadEnum();
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
|
||||
#include "SampleFormat.h"
|
||||
|
||||
class EnumSetting;
|
||||
template< typename Enum > class EnumSetting;
|
||||
|
||||
struct soxr;
|
||||
extern "C" void soxr_delete(soxr*);
|
||||
|
@ -41,8 +41,8 @@ class Resample final
|
|||
Resample(const bool useBestMethod, const double dMinFactor, const double dMaxFactor);
|
||||
~Resample();
|
||||
|
||||
static EnumSetting FastMethodSetting;
|
||||
static EnumSetting BestMethodSetting;
|
||||
static EnumSetting< int > FastMethodSetting;
|
||||
static EnumSetting< int > BestMethodSetting;
|
||||
|
||||
/** @brief Main processing function. Resamples from the input buffer to the
|
||||
* output buffer.
|
||||
|
|
|
@ -140,7 +140,7 @@ void ShuttleGuiBase::Init()
|
|||
mpWind = NULL;
|
||||
mpSubSizer = NULL;
|
||||
|
||||
mSettingName = wxT("");
|
||||
mRadioSettingName = wxT("");
|
||||
mRadioCount = -1;
|
||||
|
||||
miBorder = 5;
|
||||
|
@ -483,33 +483,32 @@ wxComboBox * ShuttleGuiBase::AddCombo( const wxString &Prompt, const wxString &S
|
|||
}
|
||||
|
||||
|
||||
wxRadioButton * ShuttleGuiBase::AddRadioButton(const wxString &Prompt)
|
||||
wxRadioButton * ShuttleGuiBase::DoAddRadioButton(
|
||||
const wxString &Prompt, int style)
|
||||
{
|
||||
/// \todo This function and the next one, suitably adapted, could be
|
||||
/// \todo This function and the next two, suitably adapted, could be
|
||||
/// used by TieRadioButton.
|
||||
UseUpId();
|
||||
if( mShuttleMode != eIsCreating )
|
||||
return wxDynamicCast(wxWindow::FindWindowById( miId, mpDlg), wxRadioButton);
|
||||
wxRadioButton * pRad;
|
||||
mpWind = pRad = safenew wxRadioButton(GetParent(), miId, Prompt,
|
||||
wxDefaultPosition, wxDefaultSize, Style( wxRB_GROUP ) );
|
||||
wxDefaultPosition, wxDefaultSize, Style( style ) );
|
||||
mpWind->SetName(wxStripMenuCodes(Prompt));
|
||||
pRad->SetValue(true );
|
||||
if ( style )
|
||||
pRad->SetValue( true );
|
||||
UpdateSizers();
|
||||
return pRad;
|
||||
}
|
||||
|
||||
wxRadioButton * ShuttleGuiBase::AddRadioButton(const wxString &Prompt)
|
||||
{
|
||||
return DoAddRadioButton( Prompt, wxRB_GROUP );
|
||||
}
|
||||
|
||||
wxRadioButton * ShuttleGuiBase::AddRadioButtonToGroup(const wxString &Prompt)
|
||||
{
|
||||
UseUpId();
|
||||
if( mShuttleMode != eIsCreating )
|
||||
return wxDynamicCast(wxWindow::FindWindowById( miId, mpDlg), wxRadioButton);
|
||||
wxRadioButton * pRad;
|
||||
mpWind = pRad = safenew wxRadioButton(GetParent(), miId, Prompt,
|
||||
wxDefaultPosition, wxDefaultSize, Style( 0 ) );
|
||||
mpWind->SetName(wxStripMenuCodes(Prompt));
|
||||
UpdateSizers();
|
||||
return pRad;
|
||||
return DoAddRadioButton( Prompt, 0 );
|
||||
}
|
||||
|
||||
#ifdef __WXMAC__
|
||||
|
@ -1449,10 +1448,27 @@ wxChoice * ShuttleGuiBase::TieChoice(
|
|||
return pChoice;
|
||||
}
|
||||
|
||||
wxRadioButton * ShuttleGuiBase::TieRadioButton(const wxString &Prompt, WrappedType & WrappedRef)
|
||||
/// This function must be within a StartRadioButtonGroup - EndRadioButtonGroup pair.
|
||||
wxRadioButton * ShuttleGuiBase::TieRadioButton()
|
||||
{
|
||||
wxASSERT( mRadioCount >= 0); // Did you remember to use StartRadioButtonGroup() ?
|
||||
|
||||
EnumValueSymbol symbol;
|
||||
if (mpRadioSetting && mRadioCount >= 0) {
|
||||
const auto &symbols = mpRadioSetting->GetSymbols();
|
||||
if ( mRadioCount < symbols.size() )
|
||||
symbol = symbols[ mRadioCount ];
|
||||
}
|
||||
|
||||
// In what follows, WrappedRef is used in read only mode, but we
|
||||
// don't have a 'read-only' version, so we copy to deal with the constness.
|
||||
auto Temp = symbol.Internal();
|
||||
wxASSERT( !Temp.empty() ); // More buttons than values?
|
||||
|
||||
WrappedType WrappedRef( Temp );
|
||||
|
||||
mRadioCount++;
|
||||
|
||||
UseUpId();
|
||||
wxRadioButton * pRadioButton = NULL;
|
||||
|
||||
|
@ -1460,10 +1476,18 @@ wxRadioButton * ShuttleGuiBase::TieRadioButton(const wxString &Prompt, WrappedTy
|
|||
{
|
||||
case eIsCreating:
|
||||
{
|
||||
const auto &Prompt = symbol.Translation();
|
||||
|
||||
mpWind = pRadioButton = safenew wxRadioButton(GetParent(), miId, Prompt,
|
||||
wxDefaultPosition, wxDefaultSize,
|
||||
(mRadioCount==1)?wxRB_GROUP:0);
|
||||
pRadioButton->SetValue(WrappedRef.ValuesMatch( *mRadioValue ));
|
||||
|
||||
wxASSERT( WrappedRef.IsString() );
|
||||
wxASSERT( mRadioValue->IsString() );
|
||||
const bool value =
|
||||
(WrappedRef.ReadAsString() == mRadioValue->ReadAsString() );
|
||||
pRadioButton->SetValue( value );
|
||||
|
||||
pRadioButton->SetName(wxStripMenuCodes(Prompt));
|
||||
UpdateSizers();
|
||||
}
|
||||
|
@ -1476,9 +1500,7 @@ wxRadioButton * ShuttleGuiBase::TieRadioButton(const wxString &Prompt, WrappedTy
|
|||
pRadioButton = wxDynamicCast(pWnd, wxRadioButton);
|
||||
wxASSERT( pRadioButton );
|
||||
if( pRadioButton->GetValue() )
|
||||
{
|
||||
mRadioValue->WriteToAsWrappedType( WrappedRef );
|
||||
}
|
||||
mRadioValue->WriteToAsString( WrappedRef.ReadAsString() );
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
@ -1489,25 +1511,34 @@ wxRadioButton * ShuttleGuiBase::TieRadioButton(const wxString &Prompt, WrappedTy
|
|||
}
|
||||
|
||||
/// Call this before any TieRadioButton calls.
|
||||
/// This is the generic version and requires mRadioValue already initialised.
|
||||
/// Versions for specific types must do that initialisation.
|
||||
void ShuttleGuiBase::StartRadioButtonGroup( const wxString & SettingName )
|
||||
void ShuttleGuiBase::StartRadioButtonGroup( const ChoiceSetting &Setting )
|
||||
{
|
||||
wxASSERT( mRadioValue && mRadioValue->eWrappedType != eWrappedNotSet );
|
||||
mSettingName = SettingName;
|
||||
mpRadioSetting = &Setting;
|
||||
|
||||
// Configure the generic type mechanism to use OUR string.
|
||||
mRadioValueString = Setting.Default().Internal();
|
||||
mRadioValue.create( mRadioValueString );
|
||||
|
||||
// Now actually start the radio button group.
|
||||
mRadioSettingName = Setting.Key();
|
||||
mRadioCount = 0;
|
||||
if( mShuttleMode == eIsCreating )
|
||||
DoDataShuttle( SettingName, *mRadioValue );
|
||||
DoDataShuttle( Setting.Key(), *mRadioValue );
|
||||
}
|
||||
|
||||
/// Call this after any TieRadioButton calls.
|
||||
/// It's generic too. We don't need type-specific ones.
|
||||
void ShuttleGuiBase::EndRadioButtonGroup()
|
||||
{
|
||||
// too few buttons?
|
||||
wxASSERT( mRadioCount == mpRadioSetting->GetSymbols().size() );
|
||||
|
||||
if( mShuttleMode == eIsGettingFromDialog )
|
||||
DoDataShuttle( mSettingName, *mRadioValue );
|
||||
DoDataShuttle( mRadioSettingName, *mRadioValue );
|
||||
mRadioValue.reset();// Clear it out...
|
||||
mRadioSettingName = wxT("");
|
||||
mRadioCount = -1; // So we detect a problem.
|
||||
mpRadioSetting = nullptr;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------//
|
||||
|
@ -1648,30 +1679,6 @@ wxString ShuttleGuiBase::TranslateFromIndex( const int nIn, const wxArrayStringE
|
|||
return wxT("");
|
||||
}
|
||||
|
||||
/// Int-to-Index (choices can be items like e.g 0x400120 )
|
||||
int ShuttleGuiBase::TranslateToIndex( const int Value, const std::vector<int> &Choices )
|
||||
{
|
||||
int n = make_iterator_range(Choices).index( Value );
|
||||
if( n == wxNOT_FOUND )
|
||||
n=miNoMatchSelector;
|
||||
miNoMatchSelector = 0;
|
||||
return n;
|
||||
}
|
||||
|
||||
/// Index-to-int (choices can be items like e.g 0x400120 )
|
||||
int ShuttleGuiBase::TranslateFromIndex( const int nIn, const std::vector<int> &Choices )
|
||||
{
|
||||
int n = nIn;
|
||||
if( n== wxNOT_FOUND )
|
||||
n=miNoMatchSelector;
|
||||
miNoMatchSelector = 0;
|
||||
if( n < (int)Choices.size() )
|
||||
{
|
||||
return Choices[n];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------//
|
||||
|
||||
|
||||
|
@ -1861,35 +1868,17 @@ wxTextCtrl * ShuttleGuiBase::TieNumericTextBox(
|
|||
/// those as default.
|
||||
wxChoice *ShuttleGuiBase::TieChoice(
|
||||
const wxString &Prompt,
|
||||
ChoiceSetting &choiceSetting )
|
||||
const ChoiceSetting &choiceSetting )
|
||||
{
|
||||
// Do this to force any needed migrations first
|
||||
choiceSetting.Read();
|
||||
|
||||
wxArrayStringEx visibleChoices, internalChoices;
|
||||
for (const auto &ident : choiceSetting) {
|
||||
visibleChoices.push_back( ident.Translation() );
|
||||
internalChoices.push_back( ident.Internal() );
|
||||
}
|
||||
return TieChoice(
|
||||
Prompt, choiceSetting.Key(), choiceSetting.Default().Internal(),
|
||||
visibleChoices, internalChoices );
|
||||
}
|
||||
const auto &symbols = choiceSetting.GetSymbols();
|
||||
const auto &SettingName = choiceSetting.Key();
|
||||
const auto &Default = choiceSetting.Default().Internal();
|
||||
const auto &Choices = symbols.GetTranslations();
|
||||
const auto &InternalChoices = symbols.GetInternals();
|
||||
|
||||
/// Variant of the standard TieChoice which does the two step exchange
|
||||
/// between gui and stack variable and stack variable and shuttle.
|
||||
/// @param Prompt The prompt shown beside the control.
|
||||
/// @param SettingName The setting name as stored in gPrefs
|
||||
/// @param Default The default value for this control (translated)
|
||||
/// @param Choices An array of choices that appear on screen.
|
||||
/// @param InternalChoices The corresponding values (as a string array)
|
||||
wxChoice * ShuttleGuiBase::TieChoice(
|
||||
const wxString &Prompt,
|
||||
const wxString &SettingName,
|
||||
const wxString &Default,
|
||||
const wxArrayStringEx & Choices,
|
||||
const wxArrayStringEx & InternalChoices)
|
||||
{
|
||||
wxChoice * pChoice=(wxChoice*)NULL;
|
||||
|
||||
int TempIndex=0;
|
||||
|
@ -1900,43 +1889,14 @@ wxChoice * ShuttleGuiBase::TieChoice(
|
|||
// Put to prefs does 2 and 3.
|
||||
if( DoStep(1) ) DoDataShuttle( SettingName, WrappedRef ); // Get Index from Prefs.
|
||||
if( DoStep(1) ) TempIndex = TranslateToIndex( TempStr, InternalChoices ); // To an index
|
||||
if( DoStep(2) ) pChoice = TieChoice( Prompt, TempIndex, Choices ); // Get/Put index from GUI.
|
||||
if( DoStep(2) )
|
||||
pChoice = TieChoice( Prompt, TempIndex,
|
||||
transform_container<wxArrayStringEx>(Choices, GetCustomTranslation) );
|
||||
if( DoStep(3) ) TempStr = TranslateFromIndex( TempIndex, InternalChoices ); // To a string
|
||||
if( DoStep(3) ) DoDataShuttle( SettingName, WrappedRef ); // Put into Prefs.
|
||||
return pChoice;
|
||||
}
|
||||
|
||||
/// Variant of the standard TieChoice which does the two step exchange
|
||||
/// between gui and stack variable and stack variable and shuttle.
|
||||
/// Difference to previous one is that the Translated choices and default
|
||||
/// are integers, not Strings.
|
||||
/// @param Prompt The prompt shown beside the control.
|
||||
/// @param SettingName The setting name as stored in gPrefs
|
||||
/// @param Default The default value for this control (translated)
|
||||
/// @param Choices An array of choices that appear on screen.
|
||||
/// @param InternalChoices The corresponding values (as an integer array)
|
||||
wxChoice * ShuttleGuiBase::TieChoice(
|
||||
const wxString &Prompt,
|
||||
const wxString &SettingName,
|
||||
const int Default,
|
||||
const wxArrayStringEx & Choices,
|
||||
const std::vector<int> & InternalChoices)
|
||||
{
|
||||
wxChoice * pChoice=(wxChoice*)NULL;
|
||||
|
||||
int TempIndex=0;
|
||||
int TranslatedInt = Default;
|
||||
WrappedType WrappedRef( TranslatedInt );
|
||||
// Get from prefs does 1 and 2.
|
||||
// Put to prefs does 2 and 3.
|
||||
if( DoStep(1) ) DoDataShuttle( SettingName, WrappedRef ); // Get Int from Prefs.
|
||||
if( DoStep(1) ) TempIndex = TranslateToIndex( TranslatedInt, InternalChoices ); // Int to an index.
|
||||
if( DoStep(2) ) pChoice = TieChoice( Prompt, TempIndex, Choices ); // Get/Put index from GUI.
|
||||
if( DoStep(3) ) TranslatedInt = TranslateFromIndex( TempIndex, InternalChoices ); // Index to int
|
||||
if( DoStep(3) ) DoDataShuttle( SettingName, WrappedRef ); // Put into Prefs.
|
||||
return pChoice;
|
||||
}
|
||||
|
||||
/// Variant of the standard TieChoice which does the two step exchange
|
||||
/// between gui and stack variable and stack variable and shuttle.
|
||||
/// The Translated choices and default are integers, not Strings.
|
||||
|
@ -1944,63 +1904,46 @@ wxChoice * ShuttleGuiBase::TieChoice(
|
|||
/// are non-exhaustive and there is a companion control for abitrary entry.
|
||||
/// @param Prompt The prompt shown beside the control.
|
||||
/// @param SettingName The setting name as stored in gPrefs
|
||||
/// @param Default The default value for this control (translated)
|
||||
/// @param Default The default integer value for this control
|
||||
/// @param Choices An array of choices that appear on screen.
|
||||
/// @param InternalChoices The corresponding values (as an integer array)
|
||||
/// @param pInternalChoices The corresponding values (as an integer array)
|
||||
/// if null, then use 0, 1, 2, ...
|
||||
wxChoice * ShuttleGuiBase::TieNumberAsChoice(
|
||||
const wxString &Prompt,
|
||||
const wxString &SettingName,
|
||||
const int Default,
|
||||
const wxArrayStringEx & Choices,
|
||||
const std::vector<int> & InternalChoices)
|
||||
const std::vector<int> * pInternalChoices)
|
||||
{
|
||||
return ShuttleGuiBase::TieChoice(
|
||||
Prompt, SettingName, Default, Choices, InternalChoices );
|
||||
}
|
||||
auto fn = [](int arg){ return wxString::Format( "%d", arg ); };
|
||||
|
||||
/// Integer specific version of StartRadioButtonGroup.
|
||||
/// All 'TieRadioButton()' enclosed must be ints.
|
||||
void ShuttleGuiBase::StartRadioButtonGroup( const wxString & SettingName, const int iDefaultValue )
|
||||
{
|
||||
// Configure the generic type mechanism to use OUR integer.
|
||||
mRadioValueInt = iDefaultValue;
|
||||
mRadioValue.create( mRadioValueInt );
|
||||
// Now actually start the radio button group.
|
||||
StartRadioButtonGroup( SettingName );
|
||||
}
|
||||
wxArrayStringEx InternalChoices;
|
||||
if ( pInternalChoices )
|
||||
InternalChoices =
|
||||
transform_container<wxArrayStringEx>(*pInternalChoices, fn);
|
||||
else
|
||||
for ( int ii = 0; ii < Choices.size(); ++ii )
|
||||
InternalChoices.push_back( fn( ii ) );
|
||||
|
||||
/// String specific version of StartRadioButtonGroup.
|
||||
/// All 'TieRadioButton()' enclosed must be strings.
|
||||
void ShuttleGuiBase::StartRadioButtonGroup( const wxString & SettingName, const wxString & DefaultValue )
|
||||
{
|
||||
// Configure the generic type mechanism to use OUR string.
|
||||
mRadioValueString = DefaultValue;
|
||||
mRadioValue.create( mRadioValueString );
|
||||
// Now actually start the radio button group.
|
||||
StartRadioButtonGroup( SettingName );
|
||||
}
|
||||
long defaultIndex;
|
||||
if ( pInternalChoices )
|
||||
defaultIndex = make_iterator_range( *pInternalChoices ).index( Default );
|
||||
else
|
||||
defaultIndex = Default;
|
||||
if ( defaultIndex < 0 || defaultIndex >= Choices.size() )
|
||||
defaultIndex = -1;
|
||||
|
||||
ChoiceSetting Setting{
|
||||
SettingName,
|
||||
{
|
||||
ByColumns,
|
||||
Choices,
|
||||
InternalChoices,
|
||||
},
|
||||
defaultIndex
|
||||
};
|
||||
|
||||
/// This function must be within a StartRadioButtonGroup - EndRadioButtonGroup pair.
|
||||
wxRadioButton * ShuttleGuiBase::TieRadioButton(
|
||||
const wxString &Prompt,
|
||||
const int iValue)
|
||||
{
|
||||
int iTemp = iValue;
|
||||
WrappedType WrappedRef( iTemp );
|
||||
return TieRadioButton( Prompt, WrappedRef );
|
||||
}
|
||||
|
||||
/// This function must be within a StartRadioButtonGroup - EndRadioButtonGroup pair.
|
||||
wxRadioButton * ShuttleGuiBase::TieRadioButton(
|
||||
const wxString &Prompt,
|
||||
const wxString &Value)
|
||||
{
|
||||
// In what follows, WrappedRef is used in read only mode, but we
|
||||
// don't have a 'read-only' version, so we copy to deal with the constness.
|
||||
wxString Temp = Value;
|
||||
WrappedType WrappedRef( Temp );
|
||||
return TieRadioButton( Prompt, WrappedRef );
|
||||
return ShuttleGuiBase::TieChoice( Prompt, Setting );
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------//
|
||||
|
|
|
@ -175,19 +175,14 @@ public:
|
|||
wxPanel * StartInvisiblePanel();
|
||||
void EndInvisiblePanel();
|
||||
|
||||
void StartRadioButtonGroup( const wxString & SettingName );
|
||||
void StartRadioButtonGroup( const ChoiceSetting &Setting );
|
||||
void EndRadioButtonGroup();
|
||||
|
||||
void StartRadioButtonGroup( const wxString & SettingName, const int iDefaultValue );
|
||||
void StartRadioButtonGroup( const wxString & SettingName, const wxString &DefaultValue );
|
||||
|
||||
void DoDataShuttle( const wxString &Name, WrappedType & WrappedRef );
|
||||
|
||||
bool DoStep( int iStep );
|
||||
int TranslateToIndex( const wxString &Value, const wxArrayStringEx &Choices );
|
||||
wxString TranslateFromIndex( const int nIn, const wxArrayStringEx &Choices );
|
||||
int TranslateToIndex( const int Value, const std::vector<int> &Choices );
|
||||
int TranslateFromIndex( const int nIn, const std::vector<int> &Choices );
|
||||
|
||||
//-- Tie functions both add controls and also read/write to them.
|
||||
// The ones taking a 'WrappedType' are type-generic and are used by the type specific ones.
|
||||
|
@ -216,9 +211,9 @@ public:
|
|||
wxSlider * TieSlider( const wxString &Prompt, float &pos, const float fMin, const float fMax);
|
||||
wxSlider * TieVSlider( const wxString &Prompt, float &pos, const float fMin, const float fMax);
|
||||
|
||||
wxRadioButton * TieRadioButton( const wxString & Prompt, WrappedType &WrappedRef);
|
||||
wxRadioButton * TieRadioButton( const wxString &Prompt, const int iValue);
|
||||
wxRadioButton * TieRadioButton( const wxString &Prompt, const wxString &Value);
|
||||
// Must be called between a StartRadioButtonGroup / EndRadioButtonGroup pair,
|
||||
// and as many times as there are values in the enumeration.
|
||||
wxRadioButton * TieRadioButton();
|
||||
|
||||
wxSpinCtrl * TieSpinCtrl( const wxString &Prompt, WrappedType & WrappedRef, const int max, const int min = 0 );
|
||||
wxSpinCtrl * TieSpinCtrl( const wxString &Prompt, int &Value, const int max, const int min = 0 );
|
||||
|
@ -237,31 +232,12 @@ public:
|
|||
const wxString &SettingName,
|
||||
const bool bDefault);
|
||||
|
||||
// This one is defined in terms of the next and not virtual
|
||||
virtual wxChoice *TieChoice(
|
||||
const wxString &Prompt,
|
||||
ChoiceSetting &choiceSetting );
|
||||
|
||||
virtual wxChoice * TieChoice(
|
||||
const wxString &Prompt,
|
||||
const wxString &SettingName,
|
||||
const wxString &Default,
|
||||
const wxArrayStringEx &Choices,
|
||||
const wxArrayStringEx & InternalChoices );
|
||||
|
||||
// This overload of TieChoice should no longer be used in Preferences!
|
||||
// Some uses do remain in export settings dialogs.
|
||||
virtual wxChoice * TieChoice(
|
||||
const wxString &Prompt,
|
||||
const wxString &SettingName,
|
||||
const int Default,
|
||||
const wxArrayStringEx & Choices,
|
||||
const std::vector<int> & InternalChoices );
|
||||
const ChoiceSetting &choiceSetting );
|
||||
|
||||
// This overload presents what is really a numerical setting as a choice among
|
||||
// commonly used values, but the choice is not exhaustive because there is
|
||||
// also an associated control that allows entry of a user-specified value
|
||||
// that is arbitrary (within some bounds).
|
||||
// commonly used values, but the choice is not necessarily exhaustive.
|
||||
// This behaves just like the previous for building dialogs, but the
|
||||
// behavior is different when the call is intercepted for purposes of
|
||||
// emitting scripting information about Preferences.
|
||||
|
@ -270,7 +246,7 @@ public:
|
|||
const wxString &SettingName,
|
||||
const int Default,
|
||||
const wxArrayStringEx & Choices,
|
||||
const std::vector<int> & InternalChoices );
|
||||
const std::vector<int> * pInternalChoices = nullptr );
|
||||
|
||||
virtual wxTextCtrl * TieTextBox(
|
||||
const wxString &Prompt,
|
||||
|
@ -345,14 +321,6 @@ protected:
|
|||
|
||||
teShuttleMode mShuttleMode;
|
||||
|
||||
// These five are needed to handle radio button groups.
|
||||
wxString mSettingName; /// The setting controlled by a group.
|
||||
int mRadioCount; /// The index of this radio item. -1 for none.
|
||||
|
||||
Maybe<WrappedType> mRadioValue; /// The wrapped value associated with the active radio button.
|
||||
wxString mRadioValueString; /// Unwrapped string value.
|
||||
int mRadioValueInt; /// Unwrapped integer value.
|
||||
|
||||
int miSizerProp;
|
||||
int mSizerDepth;
|
||||
int miBorder;
|
||||
|
@ -374,6 +342,14 @@ protected:
|
|||
wxWindow * mpWind;
|
||||
wxMenuBar * mpMenuBar;
|
||||
wxMenu * mpMenu;
|
||||
|
||||
private:
|
||||
const ChoiceSetting *mpRadioSetting = nullptr;
|
||||
wxString mRadioSettingName; /// The setting controlled by a group.
|
||||
Maybe<WrappedType> mRadioValue; /// The wrapped value associated with the active radio button.
|
||||
int mRadioCount; /// The index of this radio item. -1 for none.
|
||||
wxString mRadioValueString; /// Unwrapped string value.
|
||||
wxRadioButton * DoAddRadioButton(const wxString &Prompt, int style);
|
||||
};
|
||||
|
||||
// A rarely used helper function that sets a pointer
|
||||
|
|
|
@ -77,6 +77,7 @@ can't be.
|
|||
#include "Prefs.h"
|
||||
#include "ImageManipulation.h"
|
||||
#include "Internat.h"
|
||||
#include "prefs/GUIPrefs.h"
|
||||
#include "widgets/AudacityMessageBox.h"
|
||||
|
||||
// JKC: First get the MAC specific images.
|
||||
|
@ -234,11 +235,7 @@ void Theme::EnsureInitialised()
|
|||
bool ThemeBase::LoadPreferredTheme()
|
||||
{
|
||||
// DA: Default themes differ.
|
||||
#ifdef EXPERIMENTAL_DA
|
||||
wxString theme = gPrefs->Read(wxT("/GUI/Theme"), wxT("dark"));
|
||||
#else
|
||||
wxString theme = gPrefs->Read(wxT("/GUI/Theme"), wxT("light"));
|
||||
#endif
|
||||
auto theme = GUITheme.Read();
|
||||
|
||||
theTheme.LoadTheme( theTheme.ThemeTypeOfTypeName( theme ) );
|
||||
return true;
|
||||
|
|
|
@ -40,9 +40,9 @@ Paul Licameli split from TrackPanel.cpp
|
|||
#include "Track.h"
|
||||
#include "TrackPanelDrawingContext.h"
|
||||
#include "ViewInfo.h"
|
||||
#include "prefs/TracksBehaviorsPrefs.h"
|
||||
#include "tracks/ui/TrackView.h"
|
||||
|
||||
|
||||
// Subscribe to preference changes to update static variables
|
||||
struct Settings : PrefsListener {
|
||||
wxString gSoloPref;
|
||||
|
@ -52,7 +52,7 @@ struct Settings : PrefsListener {
|
|||
|
||||
void UpdatePrefs() override
|
||||
{
|
||||
gPrefs->Read(wxT("/GUI/Solo"), &gSoloPref, wxT("Simple"));
|
||||
gSoloPref = TracksBehaviorsSolo.Read();
|
||||
|
||||
// Calculation of best font size depends on language, so it should be redone in case
|
||||
// the language preference changed.
|
||||
|
|
|
@ -37,62 +37,6 @@ bool WrappedType::IsString()
|
|||
return eWrappedType == eWrappedString;
|
||||
}
|
||||
|
||||
/// @param W Wrapped type to compare
|
||||
/// @return true iff types and values are the same.
|
||||
bool WrappedType::ValuesMatch( const WrappedType & W )
|
||||
{
|
||||
if( W.eWrappedType != eWrappedType )
|
||||
return false;
|
||||
switch( eWrappedType )
|
||||
{
|
||||
case eWrappedString:
|
||||
return *W.mpStr == *mpStr;
|
||||
break;
|
||||
case eWrappedInt:
|
||||
return *W.mpInt == *mpInt;
|
||||
break;
|
||||
case eWrappedDouble:
|
||||
return *W.mpDouble == *mpDouble;
|
||||
break;
|
||||
case eWrappedBool:
|
||||
return *W.mpBool == *mpBool;
|
||||
break;
|
||||
case eWrappedEnum:
|
||||
wxASSERT( false );
|
||||
break;
|
||||
default:
|
||||
wxASSERT( false );
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void WrappedType::WriteToAsWrappedType( const WrappedType & W )
|
||||
{
|
||||
wxASSERT( W.eWrappedType == eWrappedType );
|
||||
switch( eWrappedType )
|
||||
{
|
||||
case eWrappedString:
|
||||
*mpStr = *W.mpStr;
|
||||
break;
|
||||
case eWrappedInt:
|
||||
*mpInt = *W.mpInt;
|
||||
break;
|
||||
case eWrappedDouble:
|
||||
*mpDouble = *W.mpDouble;
|
||||
break;
|
||||
case eWrappedBool:
|
||||
*mpBool = *W.mpBool;
|
||||
break;
|
||||
case eWrappedEnum:
|
||||
wxASSERT( false );
|
||||
break;
|
||||
default:
|
||||
wxASSERT( false );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
wxString WrappedType::ReadAsString()
|
||||
|
|
|
@ -59,9 +59,6 @@ public:
|
|||
void WriteToAsDouble( const double InDouble);
|
||||
void WriteToAsBool( const bool InBool);
|
||||
|
||||
bool ValuesMatch( const WrappedType & W );
|
||||
void WriteToAsWrappedType( const WrappedType & W );
|
||||
|
||||
public :
|
||||
|
||||
const teWrappedType eWrappedType;
|
||||
|
|
|
@ -206,27 +206,13 @@ public:
|
|||
const wxString &Prompt,
|
||||
const wxString &SettingName,
|
||||
const bool bDefault) override;
|
||||
wxChoice * TieChoice(
|
||||
const wxString &Prompt,
|
||||
const wxString &SettingName,
|
||||
const wxString &Default,
|
||||
const wxArrayStringEx &Choices,
|
||||
const wxArrayStringEx & InternalChoices ) override;
|
||||
|
||||
// An assertion will be violated if this override is reached!
|
||||
wxChoice * TieChoice(
|
||||
const wxString &Prompt,
|
||||
const wxString &SettingName,
|
||||
const int Default,
|
||||
const wxArrayStringEx & Choices,
|
||||
const std::vector<int> & InternalChoices) override;
|
||||
|
||||
wxChoice * TieNumberAsChoice(
|
||||
const wxString &Prompt,
|
||||
const wxString &SettingName,
|
||||
const int Default,
|
||||
const wxArrayStringEx & Choices,
|
||||
const std::vector<int> & InternalChoices) override;
|
||||
const std::vector<int> * pInternalChoices) override;
|
||||
|
||||
wxTextCtrl * TieTextBox(
|
||||
const wxString &Prompt,
|
||||
|
@ -289,61 +275,12 @@ wxCheckBox * ShuttleGuiGetDefinition::TieCheckBoxOnRight(
|
|||
EndStruct();
|
||||
return ShuttleGui::TieCheckBoxOnRight( Prompt, SettingName, bDefault );
|
||||
}
|
||||
wxChoice * ShuttleGuiGetDefinition::TieChoice(
|
||||
const wxString &Prompt,
|
||||
const wxString &SettingName,
|
||||
const wxString &Default,
|
||||
const wxArrayStringEx &Choices,
|
||||
const wxArrayStringEx & InternalChoices )
|
||||
{
|
||||
StartStruct();
|
||||
AddItem( SettingName, "id" );
|
||||
AddItem( Prompt, "prompt" );
|
||||
AddItem( "enum", "type" );
|
||||
AddItem( Default, "default" );
|
||||
StartField( "enum" );
|
||||
StartArray();
|
||||
for( size_t i=0;i<Choices.size(); i++ )
|
||||
AddItem( InternalChoices[i] );
|
||||
EndArray();
|
||||
EndField();
|
||||
EndStruct();
|
||||
return ShuttleGui::TieChoice( Prompt, SettingName, Default, Choices, InternalChoices );
|
||||
}
|
||||
wxChoice * ShuttleGuiGetDefinition::TieChoice(
|
||||
const wxString &Prompt,
|
||||
const wxString &SettingName,
|
||||
const int Default,
|
||||
const wxArrayStringEx & Choices,
|
||||
const std::vector<int> & InternalChoices)
|
||||
{
|
||||
// Should no longer come here!
|
||||
// Choice controls in Preferences that really are exhaustive choices among
|
||||
// non-numerical options must now encode the internal choices as strings,
|
||||
// not numbers.
|
||||
wxASSERT(false);
|
||||
|
||||
// But if we do get here anyway, proceed sub-optimally as before.
|
||||
StartStruct();
|
||||
AddItem( SettingName, "id" );
|
||||
AddItem( Prompt, "prompt" );
|
||||
AddItem( "enum", "type" );
|
||||
AddItem( Default, "default" );
|
||||
StartField( "enum" );
|
||||
StartArray();
|
||||
for( size_t i=0;i<Choices.size(); i++ )
|
||||
AddItem( Choices[i] );
|
||||
EndArray();
|
||||
EndField();
|
||||
EndStruct();
|
||||
return ShuttleGui::TieChoice( Prompt, SettingName, Default, Choices, InternalChoices );
|
||||
}
|
||||
wxChoice * ShuttleGuiGetDefinition::TieNumberAsChoice(
|
||||
const wxString &Prompt,
|
||||
const wxString &SettingName,
|
||||
const int Default,
|
||||
const wxArrayStringEx & Choices,
|
||||
const std::vector<int> & InternalChoices)
|
||||
const std::vector<int> * pInternalChoices)
|
||||
{
|
||||
// Come here for controls that present non-exhaustive choices among some
|
||||
// numbers, with an associated control that allows arbitrary entry of an
|
||||
|
@ -355,7 +292,7 @@ wxChoice * ShuttleGuiGetDefinition::TieNumberAsChoice(
|
|||
AddItem( Default, "default" );
|
||||
EndStruct();
|
||||
return ShuttleGui::TieNumberAsChoice(
|
||||
Prompt, SettingName, Default, Choices, InternalChoices );
|
||||
Prompt, SettingName, Default, Choices, pInternalChoices );
|
||||
}
|
||||
wxTextCtrl * ShuttleGuiGetDefinition::TieTextBox(
|
||||
const wxString &Prompt,
|
||||
|
|
|
@ -55,6 +55,7 @@
|
|||
#include "../FileFormats.h"
|
||||
#include "../Mix.h"
|
||||
#include "../Prefs.h"
|
||||
#include "../prefs/ImportExportPrefs.h"
|
||||
#include "../Project.h"
|
||||
#include "../ProjectHistory.h"
|
||||
#include "../ProjectSettings.h"
|
||||
|
@ -152,11 +153,16 @@ wxString ExportPlugin::GetFormat(int index)
|
|||
return mFormatInfos[index].mFormat;
|
||||
}
|
||||
|
||||
wxString ExportPlugin::GetDescription(int index)
|
||||
wxString ExportPlugin::GetUntranslatedDescription(int index)
|
||||
{
|
||||
return mFormatInfos[index].mDescription;
|
||||
}
|
||||
|
||||
wxString ExportPlugin::GetTranslatedDescription(int index)
|
||||
{
|
||||
return GetCustomTranslation( GetUntranslatedDescription( index ) );
|
||||
}
|
||||
|
||||
FileExtension ExportPlugin::GetExtension(int index)
|
||||
{
|
||||
return mFormatInfos[index].mExtensions[0];
|
||||
|
@ -173,7 +179,7 @@ wxString ExportPlugin::GetMask(int index)
|
|||
return mFormatInfos[index].mMask;
|
||||
}
|
||||
|
||||
wxString mask = GetDescription(index) + wxT("|");
|
||||
wxString mask = GetTranslatedDescription(index) + wxT("|");
|
||||
|
||||
// Build the mask
|
||||
// const auto &ext = GetExtension(index);
|
||||
|
@ -847,7 +853,7 @@ bool Exporter::CheckMix()
|
|||
// Detemine if exported file will be stereo or mono or multichannel,
|
||||
// and if mixing will occur.
|
||||
|
||||
int downMix = gPrefs->Read(wxT("/FileFormats/ExportDownMix"), true);
|
||||
auto downMix = ImportExportPrefs::ExportDownMixSetting.ReadEnum();
|
||||
int exportedChannels = mPlugins[mFormat]->SetNumExportChannels();
|
||||
|
||||
if (downMix) {
|
||||
|
|
|
@ -45,7 +45,7 @@ class AUDACITY_DLL_API FormatInfo
|
|||
~FormatInfo() {}
|
||||
|
||||
wxString mFormat;
|
||||
wxString mDescription;
|
||||
wxString mDescription; // untranslated
|
||||
// wxString mExtension;
|
||||
FileExtensions mExtensions;
|
||||
wxString mMask;
|
||||
|
@ -65,7 +65,7 @@ public:
|
|||
|
||||
int AddFormat();
|
||||
void SetFormat(const wxString & format, int index);
|
||||
void SetDescription(const wxString & description, int index);
|
||||
void SetDescription(const wxString & description /* untranslated */, int index);
|
||||
void AddExtension(const wxString &extension,int index);
|
||||
void SetExtensions(FileExtensions extensions, int index);
|
||||
void SetMask(const wxString & mask, int index);
|
||||
|
@ -74,7 +74,8 @@ public:
|
|||
|
||||
virtual int GetFormatCount();
|
||||
virtual wxString GetFormat(int index);
|
||||
virtual wxString GetDescription(int index);
|
||||
wxString GetUntranslatedDescription(int index);
|
||||
wxString GetTranslatedDescription(int index);
|
||||
/** @brief Return the (first) file name extension for the sub-format.
|
||||
* @param index The sub-format for which the extension is wanted */
|
||||
virtual FileExtension GetExtension(int index = 0);
|
||||
|
|
|
@ -312,7 +312,7 @@ ExportCL::ExportCL()
|
|||
AddExtension(wxT(""),0);
|
||||
SetMaxChannels(255,0);
|
||||
SetCanMetaData(false,0);
|
||||
SetDescription(_("(external program)"),0);
|
||||
SetDescription(XO("(external program)"),0);
|
||||
}
|
||||
|
||||
ProgressResult ExportCL::Export(AudacityProject *project,
|
||||
|
|
|
@ -225,7 +225,7 @@ ExportFFmpeg::ExportFFmpeg()
|
|||
}
|
||||
|
||||
SetMaxChannels(ExportFFmpegOptions::fmts[newfmt].maxchannels,fmtindex);
|
||||
SetDescription(ExportFFmpegOptions::fmts[newfmt].Description(), fmtindex);
|
||||
SetDescription(ExportFFmpegOptions::fmts[newfmt].description_, fmtindex);
|
||||
|
||||
int canmeta = ExportFFmpegOptions::fmts[newfmt].canmetadata;
|
||||
if (canmeta && (canmeta == AV_CANMETA || canmeta <= avfver))
|
||||
|
|
|
@ -138,20 +138,61 @@ static const wxChar *FFmpegExportCtrlIDNames[] = {
|
|||
// ExportFFmpegAC3Options Class
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
// This initialises content for the static const member variables defined in
|
||||
// ExportFFmpegDialogs.h (note no static keyword - important!)
|
||||
const int ExportFFmpegAC3Options::iAC3BitRates[] = { 32000, 40000, 48000, 56000, 64000, 80000, 96000, 112000, 128000, 160000, 192000, 224000, 256000, 320000, 384000, 448000, 512000, 576000, 640000 };
|
||||
namespace
|
||||
{
|
||||
|
||||
const wxArrayStringEx AC3BitRateNames{
|
||||
// i18n-hint kbps abbreviates "thousands of bits per second"
|
||||
XO("32 kbps"),
|
||||
XO("40 kbps"),
|
||||
XO("48 kbps"),
|
||||
XO("56 kbps"),
|
||||
XO("64 kbps"),
|
||||
XO("80 kbps"),
|
||||
XO("96 kbps"),
|
||||
XO("112 kbps"),
|
||||
XO("128 kbps"),
|
||||
XO("160 kbps"),
|
||||
XO("192 kbps"),
|
||||
XO("224 kbps"),
|
||||
XO("256 kbps"),
|
||||
XO("320 kbps"),
|
||||
XO("384 kbps"),
|
||||
XO("448 kbps"),
|
||||
XO("512 kbps"),
|
||||
XO("576 kbps"),
|
||||
XO("640 kbps"),
|
||||
};
|
||||
|
||||
const std::vector< int > AC3BitRateValues{
|
||||
32000,
|
||||
40000,
|
||||
48000,
|
||||
56000,
|
||||
64000,
|
||||
80000,
|
||||
96000,
|
||||
112000,
|
||||
128000,
|
||||
160000,
|
||||
192000,
|
||||
224000,
|
||||
256000,
|
||||
320000,
|
||||
384000,
|
||||
448000,
|
||||
512000,
|
||||
576000,
|
||||
640000,
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
const int ExportFFmpegAC3Options::iAC3SampleRates[] = { 32000, 44100, 48000, 0 };
|
||||
|
||||
ExportFFmpegAC3Options::ExportFFmpegAC3Options(wxWindow *parent, int WXUNUSED(format))
|
||||
: wxPanelWrapper(parent, wxID_ANY)
|
||||
{
|
||||
for (unsigned int i=0; i < (sizeof(iAC3BitRates)/sizeof(int)); i++)
|
||||
{
|
||||
mBitRateNames.push_back(wxString::Format(_("%i kbps"),iAC3BitRates[i]/1000));
|
||||
mBitRateLabels.push_back(iAC3BitRates[i]);
|
||||
}
|
||||
|
||||
ShuttleGui S(this, eIsCreatingFromPrefs);
|
||||
PopulateOrExchange(S);
|
||||
|
||||
|
@ -173,8 +214,13 @@ void ExportFFmpegAC3Options::PopulateOrExchange(ShuttleGui & S)
|
|||
{
|
||||
S.StartMultiColumn(2, wxCENTER);
|
||||
{
|
||||
S.TieChoice(_("Bit Rate:"), wxT("/FileFormats/AC3BitRate"),
|
||||
160000, mBitRateNames, mBitRateLabels);
|
||||
S.TieNumberAsChoice(
|
||||
_("Bit Rate:"),
|
||||
wxT("/FileFormats/AC3BitRate"),
|
||||
160000,
|
||||
AC3BitRateNames,
|
||||
&AC3BitRateValues
|
||||
);
|
||||
}
|
||||
S.EndMultiColumn();
|
||||
}
|
||||
|
@ -264,20 +310,40 @@ bool ExportFFmpegAACOptions::TransferDataFromWindow()
|
|||
// ExportFFmpegAMRNBOptions Class
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
namespace {
|
||||
|
||||
/// Bit Rates supported by libAMR-NB encoder
|
||||
/// Sample Rate is always 8 kHz
|
||||
int ExportFFmpegAMRNBOptions::iAMRNBBitRate[] =
|
||||
{ 4750, 5150, 5900, 6700, 7400, 7950, 10200, 12200 };
|
||||
const wxArrayStringEx AMRNBBitRateNames
|
||||
{
|
||||
// i18n-hint kbps abbreviates "thousands of bits per second"
|
||||
XO("4.75 kbps"),
|
||||
XO("5.15 kbps"),
|
||||
XO("5.90 kbps"),
|
||||
XO("6.70 kbps"),
|
||||
XO("7.40 kbps"),
|
||||
XO("7.95 kbps"),
|
||||
XO("10.20 kbps"),
|
||||
XO("12.20 kbps"),
|
||||
};
|
||||
|
||||
const std::vector< int > AMRNBBitRateValues
|
||||
{
|
||||
4750,
|
||||
5150,
|
||||
5900,
|
||||
6700,
|
||||
7400,
|
||||
7950,
|
||||
10200,
|
||||
12200,
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
ExportFFmpegAMRNBOptions::ExportFFmpegAMRNBOptions(wxWindow *parent, int WXUNUSED(format))
|
||||
: wxPanelWrapper(parent, wxID_ANY)
|
||||
{
|
||||
for (unsigned int i=0; i < (sizeof(iAMRNBBitRate)/sizeof(int)); i++)
|
||||
{
|
||||
mBitRateNames.push_back(wxString::Format(_("%.2f kbps"),(float)iAMRNBBitRate[i]/1000));
|
||||
mBitRateLabels.push_back(iAMRNBBitRate[i]);
|
||||
}
|
||||
|
||||
ShuttleGui S(this, eIsCreatingFromPrefs);
|
||||
PopulateOrExchange(S);
|
||||
|
||||
|
@ -299,8 +365,13 @@ void ExportFFmpegAMRNBOptions::PopulateOrExchange(ShuttleGui & S)
|
|||
{
|
||||
S.StartMultiColumn(2, wxCENTER);
|
||||
{
|
||||
S.TieChoice(_("Bit Rate:"), wxT("/FileFormats/AMRNBBitRate"),
|
||||
12200, mBitRateNames, mBitRateLabels);
|
||||
S.TieNumberAsChoice(
|
||||
_("Bit Rate:"),
|
||||
wxT("/FileFormats/AMRNBBitRate"),
|
||||
12200,
|
||||
AMRNBBitRateNames,
|
||||
&AMRNBBitRateValues
|
||||
);
|
||||
}
|
||||
S.EndMultiColumn();
|
||||
}
|
||||
|
@ -335,20 +406,46 @@ bool ExportFFmpegAMRNBOptions::TransferDataFromWindow()
|
|||
const int ExportFFmpegWMAOptions::iWMASampleRates[] =
|
||||
{ 8000, 11025, 16000, 22050, 44100, 0};
|
||||
|
||||
namespace {
|
||||
|
||||
/// Bit Rates supported by WMA encoder. Setting bit rate to other values will not result in different file size.
|
||||
const int ExportFFmpegWMAOptions::iWMABitRate[] =
|
||||
{ 24000, 32000, 40000, 48000, 64000, 80000, 96000, 128000, 160000, 192000, 256000, 320000 };
|
||||
const wxArrayStringEx WMABitRateNames
|
||||
{
|
||||
// i18n-hint kbps abbreviates "thousands of bits per second"
|
||||
XO("24 kbps"),
|
||||
XO("32 kbps"),
|
||||
XO("40 kbps"),
|
||||
XO("48 kbps"),
|
||||
XO("64 kbps"),
|
||||
XO("80 kbps"),
|
||||
XO("96 kbps"),
|
||||
XO("128 kbps"),
|
||||
XO("160 kbps"),
|
||||
XO("192 kbps"),
|
||||
XO("256 kbps"),
|
||||
XO("320 kbps"),
|
||||
};
|
||||
|
||||
const std::vector< int > WMABitRateValues{
|
||||
24000,
|
||||
32000,
|
||||
40000,
|
||||
48000,
|
||||
64000,
|
||||
80000,
|
||||
96000,
|
||||
128000,
|
||||
160000,
|
||||
192000,
|
||||
256000,
|
||||
320000,
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
ExportFFmpegWMAOptions::ExportFFmpegWMAOptions(wxWindow *parent, int WXUNUSED(format))
|
||||
: wxPanelWrapper(parent, wxID_ANY)
|
||||
{
|
||||
for (unsigned int i=0; i < (sizeof(iWMABitRate)/sizeof(int)); i++)
|
||||
{
|
||||
/* i18n-hint: abbreviates thousands of bits per second */
|
||||
mBitRateNames.push_back(wxString::Format(_("%i kbps"),iWMABitRate[i]/1000));
|
||||
mBitRateLabels.push_back(iWMABitRate[i]);
|
||||
}
|
||||
|
||||
ShuttleGui S(this, eIsCreatingFromPrefs);
|
||||
PopulateOrExchange(S);
|
||||
|
||||
|
@ -370,8 +467,13 @@ void ExportFFmpegWMAOptions::PopulateOrExchange(ShuttleGui & S)
|
|||
{
|
||||
S.StartMultiColumn(2, wxCENTER);
|
||||
{
|
||||
S.TieChoice(_("Bit Rate:"), wxT("/FileFormats/WMABitRate"),
|
||||
128000, mBitRateNames, mBitRateLabels);
|
||||
S.TieNumberAsChoice(
|
||||
_("Bit Rate:"),
|
||||
wxT("/FileFormats/WMABitRate"),
|
||||
128000,
|
||||
WMABitRateNames,
|
||||
&WMABitRateValues
|
||||
);
|
||||
}
|
||||
S.EndMultiColumn();
|
||||
}
|
||||
|
@ -1215,36 +1317,17 @@ CompatibilityEntry ExportFFmpegOptions::CompatibilityList[] =
|
|||
};
|
||||
|
||||
/// AAC profiles
|
||||
int ExportFFmpegOptions::iAACProfileValues[] = {
|
||||
FF_PROFILE_AAC_LOW,
|
||||
FF_PROFILE_AAC_MAIN,
|
||||
/*FF_PROFILE_AAC_SSR,*/
|
||||
FF_PROFILE_AAC_LTP
|
||||
};
|
||||
|
||||
/// Names of AAC profiles to be displayed
|
||||
static wxString iAACProfileNames(int index)
|
||||
{
|
||||
static const wxString names[] = {
|
||||
XO("LC"),
|
||||
XO("Main"),
|
||||
/*_("SSR"),*/ //SSR is not supported
|
||||
XO("LTP")
|
||||
};
|
||||
|
||||
class NamesArray final : public TranslatableStringArray
|
||||
// The FF_PROFILE_* enumeration is defined in the ffmpeg library
|
||||
// PRL: I cant find where this preference is used!
|
||||
ChoiceSetting AACProfiles { wxT("/FileFormats/FFmpegAACProfile"),
|
||||
{
|
||||
void Populate() override
|
||||
{
|
||||
for (auto &name : names)
|
||||
mContents.push_back( wxGetTranslation( name ) );
|
||||
}
|
||||
};
|
||||
|
||||
static NamesArray theArray;
|
||||
|
||||
return theArray.Get()[ index ];
|
||||
}
|
||||
{wxT("1") /*FF_PROFILE_AAC_LOW*/, XO("LC")},
|
||||
{wxT("0") /*FF_PROFILE_AAC_MAIN*/, XO("Main")},
|
||||
// {wxT("2") /*FF_PROFILE_AAC_SSR*/, XO("SSR")}, //SSR is not supported
|
||||
{wxT("3") /*FF_PROFILE_AAC_LTP*/, XO("LTP")},
|
||||
},
|
||||
0, // "1"
|
||||
};
|
||||
|
||||
/// List of export types
|
||||
ExposedFormat ExportFFmpegOptions::fmts[] =
|
||||
|
@ -1349,30 +1432,18 @@ ApplicableFor ExportFFmpegOptions::apptable[] =
|
|||
{FALSE,FFmpegExportCtrlID(0),AV_CODEC_ID_NONE,NULL}
|
||||
};
|
||||
|
||||
/// Prediction order method - names. Labels are indices of this array.
|
||||
static wxString PredictionOrderMethodNames(int index)
|
||||
{
|
||||
static const wxString names[] = {
|
||||
XO("Estimate"),
|
||||
XO("2-level"),
|
||||
XO("4-level"),
|
||||
XO("8-level"),
|
||||
XO("Full search"),
|
||||
XO("Log search")
|
||||
};
|
||||
namespace {
|
||||
|
||||
class NamesArray final : public TranslatableStringArray
|
||||
{
|
||||
void Populate() override
|
||||
{
|
||||
for (auto &name : names)
|
||||
mContents.push_back( wxGetTranslation( name ) );
|
||||
}
|
||||
};
|
||||
/// Prediction order method - names.
|
||||
const wxArrayStringEx PredictionOrderMethodNames {
|
||||
XO("Estimate"),
|
||||
XO("2-level"),
|
||||
XO("4-level"),
|
||||
XO("8-level"),
|
||||
XO("Full search"),
|
||||
XO("Log search"),
|
||||
};
|
||||
|
||||
static NamesArray theArray;
|
||||
|
||||
return theArray.Get()[ index ];
|
||||
}
|
||||
|
||||
|
||||
|
@ -1399,18 +1470,6 @@ ExportFFmpegOptions::ExportFFmpegOptions(wxWindow *parent)
|
|||
FetchFormatList();
|
||||
FetchCodecList();
|
||||
|
||||
for (unsigned int i = 0; i < 6; i++)
|
||||
{
|
||||
mPredictionOrderMethodLabels.push_back(i);
|
||||
mPredictionOrderMethodNames.push_back(wxString::Format(wxT("%s"),PredictionOrderMethodNames(i)));
|
||||
}
|
||||
|
||||
for (unsigned int i=0; i < (sizeof(iAACProfileValues)/sizeof(int)); i++)
|
||||
{
|
||||
mProfileNames.push_back(wxString::Format(wxT("%s"),iAACProfileNames(i)));
|
||||
mProfileLabels.push_back(iAACProfileValues[i]);
|
||||
}
|
||||
|
||||
PopulateOrExchange(S);
|
||||
|
||||
//Select the format that was selected last time this dialog was closed
|
||||
|
@ -1549,8 +1608,8 @@ void ExportFFmpegOptions::PopulateOrExchange(ShuttleGui & S)
|
|||
mCutoffSpin = S.Id(FECutoffID).TieSpinCtrl(_("Cutoff:"), wxT("/FileFormats/FFmpegCutOff"), 0, 10000000, 0);
|
||||
mCutoffSpin->SetToolTip(_("Audio cutoff bandwidth (Hz)\nOptional\n0 - automatic"));
|
||||
|
||||
mProfileChoice = S.Id(FEProfileID).TieChoice(_("Profile:"), wxT("/FileFormats/FFmpegAACProfile"),
|
||||
mProfileLabels[0], mProfileNames, mProfileLabels);
|
||||
mProfileChoice = S.Id(FEProfileID)
|
||||
.TieChoice(_("Profile:"), AACProfiles);
|
||||
mProfileChoice->SetSizeHints( 100,-1);
|
||||
mProfileChoice->SetToolTip(_("AAC Profile\nLow Complexity - default\nMost players won't play anything other than LC"));
|
||||
|
||||
|
@ -1571,8 +1630,13 @@ void ExportFFmpegOptions::PopulateOrExchange(ShuttleGui & S)
|
|||
mLPCCoeffsPrecisionSpin = S.Id(FELPCCoeffsID).TieSpinCtrl(_("LPC"), wxT("/FileFormats/FFmpegLPCCoefPrec"), 0, 15, 0);
|
||||
mLPCCoeffsPrecisionSpin->SetToolTip(_("LPC coefficients precision\nOptional\n0 - default\nmin - 1\nmax - 15"));
|
||||
|
||||
mPredictionOrderMethodChoice = S.Id(FEPredOrderID).TieChoice(_("PdO Method:"), wxT("/FileFormats/FFmpegPredOrderMethod"),
|
||||
mPredictionOrderMethodLabels[4], mPredictionOrderMethodNames, mPredictionOrderMethodLabels);
|
||||
mPredictionOrderMethodChoice = S.Id(FEPredOrderID)
|
||||
.TieNumberAsChoice(
|
||||
_("PdO Method:"),
|
||||
wxT("/FileFormats/FFmpegPredOrderMethod"),
|
||||
4, // Full search
|
||||
PredictionOrderMethodNames
|
||||
);
|
||||
mPredictionOrderMethodChoice->SetSizeHints( 100,-1);
|
||||
mPredictionOrderMethodChoice->SetToolTip(_("Prediction Order Method\nEstimate - fastest, lower compression\nLog search - slowest, best compression\nFull search - default"));
|
||||
|
||||
|
|
|
@ -81,17 +81,12 @@ public:
|
|||
bool TransferDataToWindow() override;
|
||||
bool TransferDataFromWindow() override;
|
||||
|
||||
/// Bit Rates supported by AC3 encoder
|
||||
static const int iAC3BitRates[];
|
||||
/// Sample Rates supported by AC3 encoder (must end with zero-element)
|
||||
/// It is not used in dialog anymore, but will be required later
|
||||
static const int iAC3SampleRates[];
|
||||
|
||||
private:
|
||||
|
||||
wxArrayStringEx mBitRateNames;
|
||||
std::vector<int> mBitRateLabels;
|
||||
|
||||
wxChoice *mBitRateChoice;
|
||||
int mBitRateFromChoice;
|
||||
};
|
||||
|
@ -123,13 +118,8 @@ public:
|
|||
bool TransferDataToWindow() override;
|
||||
bool TransferDataFromWindow() override;
|
||||
|
||||
static int iAMRNBBitRate[];
|
||||
|
||||
private:
|
||||
|
||||
wxArrayStringEx mBitRateNames;
|
||||
std::vector<int> mBitRateLabels;
|
||||
|
||||
wxChoice *mBitRateChoice;
|
||||
int mBitRateFromChoice;
|
||||
};
|
||||
|
@ -146,13 +136,9 @@ public:
|
|||
bool TransferDataFromWindow() override;
|
||||
|
||||
static const int iWMASampleRates[];
|
||||
static const int iWMABitRate[];
|
||||
|
||||
private:
|
||||
|
||||
wxArrayStringEx mBitRateNames;
|
||||
std::vector<int> mBitRateLabels;
|
||||
|
||||
wxChoice *mBitRateChoice;
|
||||
int mBitRateFromChoice;
|
||||
};
|
||||
|
@ -212,7 +198,6 @@ public:
|
|||
|
||||
// Static tables
|
||||
static CompatibilityEntry CompatibilityList[];
|
||||
static int iAACProfileValues[];
|
||||
static ExposedFormat fmts[];
|
||||
static const int iAACSampleRates[];
|
||||
static ApplicableFor apptable[];
|
||||
|
@ -227,10 +212,6 @@ private:
|
|||
wxArrayString mFormatLongNames;
|
||||
wxArrayStringEx mCodecNames;
|
||||
wxArrayString mCodecLongNames;
|
||||
wxArrayStringEx mProfileNames;
|
||||
std::vector<int> mProfileLabels;
|
||||
wxArrayStringEx mPredictionOrderMethodNames;
|
||||
std::vector<int> mPredictionOrderMethodLabels;
|
||||
|
||||
wxChoice *mFormatChoice;
|
||||
wxChoice *mCodecChoice;
|
||||
|
|
|
@ -76,54 +76,58 @@ ExportFLACOptions::~ExportFLACOptions()
|
|||
TransferDataFromWindow();
|
||||
}
|
||||
|
||||
ChoiceSetting FLACBitDepth{
|
||||
wxT("/FileFormats/FLACBitDepth"),
|
||||
{
|
||||
ByColumns,
|
||||
{ XO("16 bit") , XO("24 bit") , },
|
||||
{ wxT("16") , wxT("24") , }
|
||||
},
|
||||
0 // "16",
|
||||
};
|
||||
|
||||
ChoiceSetting FLACLevel{
|
||||
wxT("/FileFormats/FLACLevel"),
|
||||
{
|
||||
ByColumns,
|
||||
{
|
||||
XO("0 (fastest)") ,
|
||||
XO("1") ,
|
||||
XO("2") ,
|
||||
XO("3") ,
|
||||
XO("4") ,
|
||||
XO("5") ,
|
||||
XO("6") ,
|
||||
XO("7") ,
|
||||
XO("8 (best)") ,
|
||||
},
|
||||
{
|
||||
wxT("0") ,
|
||||
wxT("1") ,
|
||||
wxT("2") ,
|
||||
wxT("3") ,
|
||||
wxT("4") ,
|
||||
wxT("5") ,
|
||||
wxT("6") ,
|
||||
wxT("7") ,
|
||||
wxT("8") ,
|
||||
}
|
||||
},
|
||||
5 //"5"
|
||||
};
|
||||
|
||||
///
|
||||
///
|
||||
void ExportFLACOptions::PopulateOrExchange(ShuttleGui & S)
|
||||
{
|
||||
wxArrayStringEx flacLevelLabels{
|
||||
wxT("0") ,
|
||||
wxT("1") ,
|
||||
wxT("2") ,
|
||||
wxT("3") ,
|
||||
wxT("4") ,
|
||||
wxT("5") ,
|
||||
wxT("6") ,
|
||||
wxT("7") ,
|
||||
wxT("8") ,
|
||||
};
|
||||
|
||||
wxArrayStringEx flacLevelNames{
|
||||
_("0 (fastest)") ,
|
||||
_("1") ,
|
||||
_("2") ,
|
||||
_("3") ,
|
||||
_("4") ,
|
||||
_("5") ,
|
||||
_("6") ,
|
||||
_("7") ,
|
||||
_("8 (best)") ,
|
||||
};
|
||||
|
||||
wxArrayStringEx flacBitDepthLabels{
|
||||
wxT("16") ,
|
||||
wxT("24") ,
|
||||
};
|
||||
|
||||
wxArrayStringEx flacBitDepthNames{
|
||||
_("16 bit") ,
|
||||
_("24 bit") ,
|
||||
};
|
||||
|
||||
S.StartVerticalLay();
|
||||
{
|
||||
S.StartHorizontalLay(wxCENTER);
|
||||
{
|
||||
S.StartMultiColumn(2, wxCENTER);
|
||||
{
|
||||
S.TieChoice(_("Level:"), wxT("/FileFormats/FLACLevel"),
|
||||
wxT("5"), flacLevelNames, flacLevelLabels);
|
||||
S.TieChoice(_("Bit depth:"), wxT("/FileFormats/FLACBitDepth"),
|
||||
wxT("16"), flacBitDepthNames, flacBitDepthLabels);
|
||||
S.TieChoice( _("Level:"), FLACLevel);
|
||||
S.TieChoice( _("Bit depth:"), FLACBitDepth);
|
||||
}
|
||||
S.EndMultiColumn();
|
||||
}
|
||||
|
@ -239,7 +243,7 @@ ExportFLAC::ExportFLAC()
|
|||
AddExtension(wxT("flac"),0);
|
||||
SetMaxChannels(FLAC__MAX_CHANNELS,0);
|
||||
SetCanMetaData(true,0);
|
||||
SetDescription(_("FLAC Files"),0);
|
||||
SetDescription(XO("FLAC Files"),0);
|
||||
}
|
||||
|
||||
ProgressResult ExportFLAC::Export(AudacityProject *project,
|
||||
|
@ -260,11 +264,10 @@ ProgressResult ExportFLAC::Export(AudacityProject *project,
|
|||
wxLogNull logNo; // temporarily disable wxWidgets error messages
|
||||
auto updateResult = ProgressResult::Success;
|
||||
|
||||
int levelPref;
|
||||
gPrefs->Read(wxT("/FileFormats/FLACLevel"), &levelPref, 5);
|
||||
long levelPref;
|
||||
FLACLevel.Read().ToLong( &levelPref );
|
||||
|
||||
wxString bitDepthPref =
|
||||
gPrefs->Read(wxT("/FileFormats/FLACBitDepth"), wxT("16"));
|
||||
auto bitDepthPref = FLACBitDepth.Read();
|
||||
|
||||
FLAC::Encoder::File encoder;
|
||||
|
||||
|
|
|
@ -75,12 +75,51 @@
|
|||
// ExportMP2Options
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
static int iBitrates[] = {
|
||||
16, 24, 32, 40, 48, 56, 64,
|
||||
80, 96, 112, 128, 160,
|
||||
192, 224, 256, 320, 384
|
||||
namespace {
|
||||
|
||||
const wxArrayStringEx BitRateNames {
|
||||
// i18n-hint kbps abbreviates "thousands of bits per second"
|
||||
XO("16 kbps"),
|
||||
XO("24 kbps"),
|
||||
XO("32 kbps"),
|
||||
XO("40 kbps"),
|
||||
XO("48 kbps"),
|
||||
XO("56 kbps"),
|
||||
XO("64 kbps"),
|
||||
XO("80 kbps"),
|
||||
XO("96 kbps"),
|
||||
XO("112 kbps"),
|
||||
XO("128 kbps"),
|
||||
XO("160 kbps"),
|
||||
XO("192 kbps"),
|
||||
XO("224 kbps"),
|
||||
XO("256 kbps"),
|
||||
XO("320 kbps"),
|
||||
XO("384 kbps"),
|
||||
};
|
||||
|
||||
const std::vector< int > BitRateValues {
|
||||
16,
|
||||
24,
|
||||
32,
|
||||
40,
|
||||
48,
|
||||
56,
|
||||
64,
|
||||
80,
|
||||
96,
|
||||
112,
|
||||
128,
|
||||
160,
|
||||
192,
|
||||
224,
|
||||
256,
|
||||
320,
|
||||
384,
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
class ExportMP2Options final : public wxPanelWrapper
|
||||
{
|
||||
public:
|
||||
|
@ -90,10 +129,6 @@ public:
|
|||
void PopulateOrExchange(ShuttleGui & S);
|
||||
bool TransferDataToWindow() override;
|
||||
bool TransferDataFromWindow() override;
|
||||
|
||||
private:
|
||||
wxArrayStringEx mBitRateNames;
|
||||
std::vector<int> mBitRateLabels;
|
||||
};
|
||||
|
||||
///
|
||||
|
@ -101,12 +136,6 @@ private:
|
|||
ExportMP2Options::ExportMP2Options(wxWindow *parent, int WXUNUSED(format))
|
||||
: wxPanelWrapper(parent, wxID_ANY)
|
||||
{
|
||||
for (unsigned int i=0; i < (sizeof(iBitrates)/sizeof(int)); i++)
|
||||
{
|
||||
mBitRateNames.push_back(wxString::Format(_("%i kbps"),iBitrates[i]));
|
||||
mBitRateLabels.push_back(iBitrates[i]);
|
||||
}
|
||||
|
||||
ShuttleGui S(this, eIsCreatingFromPrefs);
|
||||
PopulateOrExchange(S);
|
||||
|
||||
|
@ -130,8 +159,13 @@ void ExportMP2Options::PopulateOrExchange(ShuttleGui & S)
|
|||
{
|
||||
S.StartMultiColumn(2, wxCENTER);
|
||||
{
|
||||
S.TieChoice(_("Bit Rate:"), wxT("/FileFormats/MP2Bitrate"),
|
||||
160, mBitRateNames, mBitRateLabels);
|
||||
S.TieNumberAsChoice(
|
||||
_("Bit Rate:"),
|
||||
wxT("/FileFormats/MP2Bitrate"),
|
||||
160,
|
||||
BitRateNames,
|
||||
&BitRateValues
|
||||
);
|
||||
}
|
||||
S.EndMultiColumn();
|
||||
}
|
||||
|
@ -202,7 +236,7 @@ ExportMP2::ExportMP2()
|
|||
AddExtension(wxT("mp2"),0);
|
||||
SetMaxChannels(2,0);
|
||||
SetCanMetaData(true,0);
|
||||
SetDescription(_("MP2 Files"),0);
|
||||
SetDescription(XO("MP2 Files"),0);
|
||||
}
|
||||
|
||||
ProgressResult ExportMP2::Export(AudacityProject *project,
|
||||
|
|
|
@ -105,118 +105,111 @@
|
|||
// ExportMP3Options
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#define CHANNEL_JOINT 0
|
||||
#define CHANNEL_STEREO 1
|
||||
#define CHANNEL_MONO 2
|
||||
enum MP3ChannelMode : unsigned {
|
||||
CHANNEL_JOINT = 0,
|
||||
CHANNEL_STEREO = 1,
|
||||
CHANNEL_MONO = 2,
|
||||
};
|
||||
|
||||
#define QUALITY_0 0
|
||||
#define QUALITY_1 1
|
||||
#define QUALITY_2 2
|
||||
#define QUALITY_3 3
|
||||
#define QUALITY_4 4
|
||||
#define QUALITY_5 5
|
||||
#define QUALITY_6 6
|
||||
#define QUALITY_7 7
|
||||
#define QUALITY_8 8
|
||||
#define QUALITY_9 9
|
||||
enum : int {
|
||||
QUALITY_2 = 2,
|
||||
|
||||
#define ROUTINE_FAST 0
|
||||
#define ROUTINE_STANDARD 1
|
||||
ROUTINE_FAST = 0,
|
||||
ROUTINE_STANDARD = 1,
|
||||
|
||||
#define PRESET_INSANE 0
|
||||
#define PRESET_EXTREME 1
|
||||
#define PRESET_STANDARD 2
|
||||
#define PRESET_MEDIUM 3
|
||||
PRESET_INSANE = 0,
|
||||
PRESET_EXTREME = 1,
|
||||
PRESET_STANDARD = 2,
|
||||
PRESET_MEDIUM = 3,
|
||||
};
|
||||
|
||||
// Note: The label field is what will be written to preferences and carries
|
||||
// no numerical significance. It is simply a means to look up a value
|
||||
// in a table.
|
||||
//
|
||||
// The entries should be listed in order you want them to appear in the
|
||||
// choice dropdown based on the name field.
|
||||
typedef struct
|
||||
{
|
||||
wxString name;
|
||||
int label;
|
||||
} CHOICES;
|
||||
|
||||
static CHOICES fixRates[] =
|
||||
{
|
||||
static const wxArrayStringEx fixRateNames {
|
||||
/* i18n-hint: kbps is the bitrate of the MP3 file, kilobits per second*/
|
||||
{wxT(""), 320},
|
||||
{wxT(""), 256},
|
||||
{wxT(""), 224},
|
||||
{wxT(""), 192},
|
||||
{wxT(""), 160},
|
||||
{wxT(""), 144},
|
||||
{wxT(""), 128},
|
||||
{wxT(""), 112},
|
||||
{wxT(""), 96},
|
||||
{wxT(""), 80},
|
||||
{wxT(""), 64},
|
||||
{wxT(""), 56},
|
||||
{wxT(""), 48},
|
||||
{wxT(""), 40},
|
||||
{wxT(""), 32},
|
||||
{wxT(""), 24},
|
||||
{wxT(""), 16},
|
||||
{wxT(""), 8}
|
||||
XO("320 kbps"),
|
||||
XO("256 kbps"),
|
||||
XO("224 kbps"),
|
||||
XO("192 kbps"),
|
||||
XO("160 kbps"),
|
||||
XO("144 kbps"),
|
||||
XO("128 kbps"),
|
||||
XO("112 kbps"),
|
||||
XO("96 kbps"),
|
||||
XO("80 kbps"),
|
||||
XO("64 kbps"),
|
||||
XO("56 kbps"),
|
||||
XO("48 kbps"),
|
||||
XO("40 kbps"),
|
||||
XO("32 kbps"),
|
||||
XO("24 kbps"),
|
||||
XO("16 kbps"),
|
||||
XO("8 kbps"),
|
||||
};
|
||||
|
||||
static CHOICES varRates[] =
|
||||
{
|
||||
{wxT(""), QUALITY_0},
|
||||
{wxT(""), QUALITY_1},
|
||||
{wxT(""), QUALITY_2},
|
||||
{wxT(""), QUALITY_3},
|
||||
{wxT(""), QUALITY_4},
|
||||
{wxT(""), QUALITY_5},
|
||||
{wxT(""), QUALITY_6},
|
||||
{wxT(""), QUALITY_7},
|
||||
{wxT(""), QUALITY_8},
|
||||
{wxT(""), QUALITY_9}
|
||||
static const std::vector<int> fixRateValues {
|
||||
320,
|
||||
256,
|
||||
224,
|
||||
192,
|
||||
160,
|
||||
144,
|
||||
128,
|
||||
112,
|
||||
96,
|
||||
80,
|
||||
64,
|
||||
56,
|
||||
48,
|
||||
40,
|
||||
32,
|
||||
24,
|
||||
16,
|
||||
8,
|
||||
};
|
||||
|
||||
static const wxChar *const varRatesNumbers[] = {
|
||||
wxT("220-260"),
|
||||
wxT("200-250"),
|
||||
wxT("170-210"),
|
||||
wxT("155-195"),
|
||||
wxT("145-185"),
|
||||
wxT("110-150"),
|
||||
wxT("95-135"),
|
||||
wxT("80-120"),
|
||||
wxT("65-105"),
|
||||
wxT("45-85")
|
||||
};
|
||||
static_assert( WXSIZEOF(varRates) == WXSIZEOF(varRatesNumbers),
|
||||
"size mismatch" );
|
||||
|
||||
static CHOICES varModes[] =
|
||||
{
|
||||
{wxT(""), ROUTINE_FAST },
|
||||
{wxT(""), ROUTINE_STANDARD}
|
||||
static const wxArrayStringEx varRateNames {
|
||||
XO("220-260 kbps (Best Quality)"),
|
||||
XO("200-250 kbps"),
|
||||
XO("170-210 kbps"),
|
||||
XO("155-195 kbps"),
|
||||
XO("145-185 kbps"),
|
||||
XO("110-150 kbps"),
|
||||
XO("95-135 kbps"),
|
||||
XO("80-120 kbps"),
|
||||
XO("65-105 kbps"),
|
||||
XO("45-85 kbps (Smaller files)"),
|
||||
};
|
||||
|
||||
static CHOICES setRates[] =
|
||||
{
|
||||
{wxT(""), PRESET_INSANE },
|
||||
{wxT(""), PRESET_EXTREME },
|
||||
{wxT(""), PRESET_STANDARD},
|
||||
{wxT(""), PRESET_MEDIUM }
|
||||
static const wxArrayStringEx varModeNames {
|
||||
XO("Fast"),
|
||||
XO("Standard"),
|
||||
};
|
||||
|
||||
static CHOICES sampRates[] =
|
||||
{
|
||||
{wxT(""), 8000 },
|
||||
{wxT(""), 11025 },
|
||||
{wxT(""), 12000 },
|
||||
{wxT(""), 16000 },
|
||||
{wxT(""), 22050 },
|
||||
{wxT(""), 24000 },
|
||||
{wxT(""), 32000 },
|
||||
{wxT(""), 44100 },
|
||||
{wxT(""), 48000 }
|
||||
static const wxArrayStringEx setRateNames {
|
||||
/* i18n-hint: Slightly humorous - as in use an insane precision with MP3.*/
|
||||
XO("Insane, 320 kbps"),
|
||||
XO("Extreme, 220-260 kbps"),
|
||||
XO("Standard, 170-210 kbps"),
|
||||
XO("Medium, 145-185 kbps"),
|
||||
};
|
||||
|
||||
static const wxArrayStringEx setRateNamesShort {
|
||||
/* i18n-hint: Slightly humorous - as in use an insane precision with MP3.*/
|
||||
XO("Insane"),
|
||||
XO("Extreme"),
|
||||
XO("Standard"),
|
||||
XO("Medium"),
|
||||
};
|
||||
|
||||
static const std::vector< int > sampRates {
|
||||
8000,
|
||||
11025,
|
||||
12000,
|
||||
16000,
|
||||
22050,
|
||||
24000,
|
||||
32000,
|
||||
44100,
|
||||
48000,
|
||||
};
|
||||
|
||||
#define ID_SET 7000
|
||||
|
@ -226,33 +219,6 @@ static CHOICES sampRates[] =
|
|||
#define ID_QUALITY 7004
|
||||
#define ID_MONO 7005
|
||||
|
||||
static void InitMP3_Statics()
|
||||
{
|
||||
for (size_t i=0; i < WXSIZEOF(fixRates); i++)
|
||||
fixRates[i].name = wxString::Format(_("%d kbps"), fixRates[i].label);
|
||||
|
||||
varRates[0].name = wxString::Format(
|
||||
_("%s kbps (Best Quality)"), varRatesNumbers[0] );
|
||||
|
||||
for (size_t i = 1; i < WXSIZEOF(varRates) - 1; i++)
|
||||
varRates[i].name = wxString::Format( _("%s kbps"), varRatesNumbers[i] );
|
||||
|
||||
varRates[9].name = wxString::Format(
|
||||
_("%s kbps (Smaller files)"), varRatesNumbers[9] );
|
||||
|
||||
varModes[0].name = _("Fast");
|
||||
varModes[1].name = _("Standard");
|
||||
|
||||
/* i18n-hint: Slightly humorous - as in use an insane precision with MP3.*/
|
||||
setRates[0].name = _("Insane, 320 kbps");
|
||||
setRates[1].name = _("Extreme, 220-260 kbps");
|
||||
setRates[2].name = _("Standard, 170-210 kbps");
|
||||
setRates[3].name = _("Medium, 145-185 kbps");
|
||||
|
||||
for (size_t i=0; i < WXSIZEOF(sampRates); i++)
|
||||
sampRates[i].name = wxString::Format( wxT("%d"), sampRates[i].label );
|
||||
}
|
||||
|
||||
class ExportMP3Options final : public wxPanelWrapper
|
||||
{
|
||||
public:
|
||||
|
@ -271,10 +237,7 @@ public:
|
|||
void OnQuality(wxCommandEvent& evt);
|
||||
void OnMono(wxCommandEvent& evt);
|
||||
|
||||
void LoadNames(CHOICES *choices, int count);
|
||||
wxArrayString GetNames(CHOICES *choices, int count);
|
||||
std::vector<int> GetLabels(CHOICES *choices, int count);
|
||||
int FindIndex(CHOICES *choices, int cnt, int needle, int def);
|
||||
void LoadNames(const wxArrayStringEx &choices);
|
||||
|
||||
private:
|
||||
|
||||
|
@ -310,8 +273,6 @@ END_EVENT_TABLE()
|
|||
ExportMP3Options::ExportMP3Options(wxWindow *parent, int WXUNUSED(format))
|
||||
: wxPanelWrapper(parent, wxID_ANY)
|
||||
{
|
||||
InitMP3_Statics();
|
||||
|
||||
mSetRate = gPrefs->Read(wxT("/FileFormats/MP3SetRate"), PRESET_STANDARD);
|
||||
mVbrRate = gPrefs->Read(wxT("/FileFormats/MP3VbrRate"), QUALITY_2);
|
||||
mAbrRate = gPrefs->Read(wxT("/FileFormats/MP3AbrRate"), 192);
|
||||
|
@ -328,6 +289,38 @@ ExportMP3Options::~ExportMP3Options()
|
|||
TransferDataFromWindow();
|
||||
}
|
||||
|
||||
EnumSetting< MP3RateMode > MP3RateModeSetting{
|
||||
wxT("/FileFormats/MP3RateModeChoice"),
|
||||
{
|
||||
{ wxT("SET"), XO("Preset") },
|
||||
{ wxT("VBR"), XO("Variable") },
|
||||
{ wxT("ABR"), XO("Average") },
|
||||
{ wxT("CBR"), XO("Constant") },
|
||||
},
|
||||
0, // MODE_SET
|
||||
|
||||
// for migrating old preferences:
|
||||
{
|
||||
MODE_SET, MODE_VBR, MODE_ABR, MODE_CBR
|
||||
},
|
||||
wxT("/FileFormats/MP3RateMode"),
|
||||
};
|
||||
|
||||
static EnumSetting< MP3ChannelMode > MP3ChannelModeSetting{
|
||||
wxT("/FileFormats/MP3ChannelModeChoice"),
|
||||
{
|
||||
EnumValueSymbol{ wxT("JOINT"), XO("Joint Stereo") },
|
||||
EnumValueSymbol{ wxT("STEREO"), XO("Stereo") },
|
||||
},
|
||||
0, // CHANNEL_JOINT
|
||||
|
||||
// for migrating old preferences:
|
||||
{
|
||||
CHANNEL_JOINT, CHANNEL_STEREO,
|
||||
},
|
||||
wxT("/FileFormats/MP3ChannelMode"),
|
||||
};
|
||||
|
||||
///
|
||||
///
|
||||
void ExportMP3Options::PopulateOrExchange(ShuttleGui & S)
|
||||
|
@ -344,59 +337,59 @@ void ExportMP3Options::PopulateOrExchange(ShuttleGui & S)
|
|||
S.AddPrompt(_("Bit Rate Mode:"));
|
||||
S.StartHorizontalLay();
|
||||
{
|
||||
S.StartRadioButtonGroup(wxT("/FileFormats/MP3RateMode"), MODE_SET);
|
||||
S.StartRadioButtonGroup(MP3RateModeSetting);
|
||||
{
|
||||
mSET = S.Id(ID_SET).TieRadioButton(_("Preset"), MODE_SET);
|
||||
mVBR = S.Id(ID_VBR).TieRadioButton(_("Variable"), MODE_VBR);
|
||||
mABR = S.Id(ID_ABR).TieRadioButton(_("Average"), MODE_ABR);
|
||||
mCBR = S.Id(ID_CBR).TieRadioButton(_("Constant"), MODE_CBR);
|
||||
mSET = S.Id(ID_SET).TieRadioButton();
|
||||
mVBR = S.Id(ID_VBR).TieRadioButton();
|
||||
mABR = S.Id(ID_ABR).TieRadioButton();
|
||||
mCBR = S.Id(ID_CBR).TieRadioButton();
|
||||
}
|
||||
S.EndRadioButtonGroup();
|
||||
}
|
||||
S.EndHorizontalLay();
|
||||
|
||||
CHOICES *choices;
|
||||
int cnt;
|
||||
const wxArrayStringEx *choices = nullptr;
|
||||
const std::vector< int > *codes = nullptr;
|
||||
bool enable;
|
||||
int defrate;
|
||||
|
||||
if (mSET->GetValue()) {
|
||||
choices = setRates;
|
||||
cnt = WXSIZEOF(setRates);
|
||||
choices = &setRateNames;
|
||||
enable = true;
|
||||
defrate = mSetRate;
|
||||
}
|
||||
else if (mVBR->GetValue()) {
|
||||
choices = varRates;
|
||||
cnt = WXSIZEOF(varRates);
|
||||
choices = &varRateNames;
|
||||
enable = true;
|
||||
defrate = mVbrRate;
|
||||
}
|
||||
else if (mABR->GetValue()) {
|
||||
choices = fixRates;
|
||||
cnt = WXSIZEOF(fixRates);
|
||||
choices = &fixRateNames;
|
||||
codes = &fixRateValues;
|
||||
enable = false;
|
||||
defrate = mAbrRate;
|
||||
}
|
||||
else {
|
||||
mCBR->SetValue(true);
|
||||
choices = fixRates;
|
||||
cnt = WXSIZEOF(fixRates);
|
||||
choices = &fixRateNames;
|
||||
codes = &fixRateValues;
|
||||
enable = false;
|
||||
defrate = mCbrRate;
|
||||
}
|
||||
|
||||
mRate = S.Id(ID_QUALITY).TieChoice(_("Quality"),
|
||||
wxT("/FileFormats/MP3Bitrate"),
|
||||
defrate,
|
||||
GetNames(choices, cnt),
|
||||
GetLabels(choices, cnt));
|
||||
|
||||
mMode = S.TieChoice(_("Variable Speed:"),
|
||||
wxT("/FileFormats/MP3VarMode"),
|
||||
ROUTINE_FAST,
|
||||
GetNames(varModes, WXSIZEOF(varModes)),
|
||||
GetLabels(varModes, WXSIZEOF(varModes)));
|
||||
|
||||
mRate = S.Id(ID_QUALITY).TieNumberAsChoice(
|
||||
_("Quality"),
|
||||
wxT("/FileFormats/MP3Bitrate"),
|
||||
defrate,
|
||||
*choices,
|
||||
codes
|
||||
);
|
||||
|
||||
mMode = S.TieNumberAsChoice(
|
||||
_("Variable Speed:"),
|
||||
wxT("/FileFormats/MP3VarMode"),
|
||||
ROUTINE_FAST,
|
||||
varModeNames );
|
||||
mMode->Enable(enable);
|
||||
|
||||
S.AddPrompt(_("Channel Mode:"));
|
||||
|
@ -405,10 +398,10 @@ void ExportMP3Options::PopulateOrExchange(ShuttleGui & S)
|
|||
bool mono = false;
|
||||
gPrefs->Read(wxT("/FileFormats/MP3ForceMono"), &mono, 0);
|
||||
|
||||
S.StartRadioButtonGroup(wxT("/FileFormats/MP3ChannelMode"), CHANNEL_JOINT);
|
||||
S.StartRadioButtonGroup(MP3ChannelModeSetting);
|
||||
{
|
||||
mJoint = S.TieRadioButton(_("Joint Stereo"), CHANNEL_JOINT);
|
||||
mStereo = S.TieRadioButton(_("Stereo"), CHANNEL_STEREO);
|
||||
mJoint = S.TieRadioButton();
|
||||
mStereo = S.TieRadioButton();
|
||||
mJoint->Enable(!mono);
|
||||
mStereo->Enable(!mono);
|
||||
}
|
||||
|
@ -448,13 +441,28 @@ bool ExportMP3Options::TransferDataFromWindow()
|
|||
return true;
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
int ValidateValue( int nValues, int value, int defaultValue )
|
||||
{
|
||||
return (value >= 0 && value < nValues) ? value : defaultValue;
|
||||
}
|
||||
int ValidateValue( const std::vector<int> &values, int value, int defaultValue )
|
||||
{
|
||||
auto start = values.begin(), finish = values.end(),
|
||||
iter = std::find( start, finish, value );
|
||||
return ( iter != finish ) ? value : defaultValue;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
///
|
||||
///
|
||||
void ExportMP3Options::OnSET(wxCommandEvent& WXUNUSED(event))
|
||||
{
|
||||
LoadNames(setRates, WXSIZEOF(setRates));
|
||||
LoadNames(setRateNames);
|
||||
|
||||
mRate->SetSelection(FindIndex(setRates, WXSIZEOF(setRates), mSetRate, 2));
|
||||
mRate->SetSelection(ValidateValue(setRateNames.size(), mSetRate, 2));
|
||||
mRate->Refresh();
|
||||
mMode->Enable(true);
|
||||
}
|
||||
|
@ -463,9 +471,9 @@ void ExportMP3Options::OnSET(wxCommandEvent& WXUNUSED(event))
|
|||
///
|
||||
void ExportMP3Options::OnVBR(wxCommandEvent& WXUNUSED(event))
|
||||
{
|
||||
LoadNames(varRates, WXSIZEOF(varRates));
|
||||
LoadNames(varRateNames);
|
||||
|
||||
mRate->SetSelection(FindIndex(varRates, WXSIZEOF(varRates), mVbrRate, 2));
|
||||
mRate->SetSelection(ValidateValue(varRateNames.size(), mVbrRate, 2));
|
||||
mRate->Refresh();
|
||||
mMode->Enable(true);
|
||||
}
|
||||
|
@ -474,9 +482,9 @@ void ExportMP3Options::OnVBR(wxCommandEvent& WXUNUSED(event))
|
|||
///
|
||||
void ExportMP3Options::OnABR(wxCommandEvent& WXUNUSED(event))
|
||||
{
|
||||
LoadNames(fixRates, WXSIZEOF(fixRates));
|
||||
LoadNames(fixRateNames);
|
||||
|
||||
mRate->SetSelection(FindIndex(fixRates, WXSIZEOF(fixRates), mAbrRate, 10));
|
||||
mRate->SetSelection(ValidateValue(fixRateValues, mAbrRate, 10));
|
||||
mRate->Refresh();
|
||||
mMode->Enable(false);
|
||||
}
|
||||
|
@ -485,9 +493,9 @@ void ExportMP3Options::OnABR(wxCommandEvent& WXUNUSED(event))
|
|||
///
|
||||
void ExportMP3Options::OnCBR(wxCommandEvent& WXUNUSED(event))
|
||||
{
|
||||
LoadNames(fixRates, WXSIZEOF(fixRates));
|
||||
LoadNames(fixRateNames);
|
||||
|
||||
mRate->SetSelection(FindIndex(fixRates, WXSIZEOF(fixRates), mCbrRate, 10));
|
||||
mRate->SetSelection(ValidateValue(fixRateValues, mCbrRate, 10));
|
||||
mRate->Refresh();
|
||||
mMode->Enable(false);
|
||||
}
|
||||
|
@ -497,16 +505,16 @@ void ExportMP3Options::OnQuality(wxCommandEvent& WXUNUSED(event))
|
|||
int sel = mRate->GetSelection();
|
||||
|
||||
if (mSET->GetValue()) {
|
||||
mSetRate = setRates[sel].label;
|
||||
mSetRate = sel;
|
||||
}
|
||||
else if (mVBR->GetValue()) {
|
||||
mVbrRate = varRates[sel].label;
|
||||
mVbrRate = sel;
|
||||
}
|
||||
else if (mABR->GetValue()) {
|
||||
mAbrRate = fixRates[sel].label;
|
||||
mAbrRate = fixRateValues[ sel ];
|
||||
}
|
||||
else {
|
||||
mCbrRate = fixRates[sel].label;
|
||||
mCbrRate = fixRateValues[ sel ];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -521,47 +529,11 @@ void ExportMP3Options::OnMono(wxCommandEvent& /*evt*/)
|
|||
gPrefs->Flush();
|
||||
}
|
||||
|
||||
void ExportMP3Options::LoadNames(CHOICES *choices, int count)
|
||||
void ExportMP3Options::LoadNames(const wxArrayStringEx &names)
|
||||
{
|
||||
mRate->Clear();
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
mRate->Append(choices[i].name);
|
||||
}
|
||||
}
|
||||
|
||||
wxArrayString ExportMP3Options::GetNames(CHOICES *choices, int count)
|
||||
{
|
||||
wxArrayString names;
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
names.push_back(choices[i].name);
|
||||
}
|
||||
|
||||
return names;
|
||||
}
|
||||
|
||||
std::vector<int> ExportMP3Options::GetLabels(CHOICES *choices, int count)
|
||||
{
|
||||
std::vector<int> labels;
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
labels.push_back(choices[i].label);
|
||||
}
|
||||
|
||||
return labels;
|
||||
}
|
||||
|
||||
int ExportMP3Options::FindIndex(CHOICES *choices, int cnt, int needle, int def)
|
||||
{
|
||||
for (int i = 0; i < cnt; i++) {
|
||||
if (choices[i].label == needle) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return def;
|
||||
for (const auto &name : names)
|
||||
mRate->Append( GetCustomTranslation( name ) );
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
@ -1696,8 +1668,6 @@ public:
|
|||
|
||||
private:
|
||||
|
||||
int FindValue(CHOICES *choices, int cnt, int needle, int def);
|
||||
wxString FindName(CHOICES *choices, int cnt, int needle);
|
||||
int AskResample(int bitrate, int rate, int lowrate, int highrate);
|
||||
unsigned long AddTags(AudacityProject *project, ArrayOf<char> &buffer, bool *endOfFile, const Tags *tags);
|
||||
#ifdef USE_LIBID3TAG
|
||||
|
@ -1709,13 +1679,12 @@ private:
|
|||
ExportMP3::ExportMP3()
|
||||
: ExportPlugin()
|
||||
{
|
||||
InitMP3_Statics();
|
||||
AddFormat();
|
||||
SetFormat(wxT("MP3"),0);
|
||||
AddExtension(wxT("mp3"),0);
|
||||
SetMaxChannels(2,0);
|
||||
SetCanMetaData(true,0);
|
||||
SetDescription(_("MP3 Files"),0);
|
||||
SetDescription(XO("MP3 Files"),0);
|
||||
}
|
||||
|
||||
bool ExportMP3::CheckFileName(wxFileName & WXUNUSED(filename), int WXUNUSED(format))
|
||||
|
@ -1793,32 +1762,30 @@ ProgressResult ExportMP3::Export(AudacityProject *project,
|
|||
int lowrate = 8000;
|
||||
int bitrate = 0;
|
||||
int brate;
|
||||
int rmode;
|
||||
int vmode;
|
||||
int cmode;
|
||||
bool forceMono;
|
||||
|
||||
gPrefs->Read(wxT("/FileFormats/MP3Bitrate"), &brate, 128);
|
||||
gPrefs->Read(wxT("/FileFormats/MP3RateMode"), &rmode, MODE_CBR);
|
||||
auto rmode = MP3RateModeSetting.ReadEnumWithDefault( MODE_CBR );
|
||||
gPrefs->Read(wxT("/FileFormats/MP3VarMode"), &vmode, ROUTINE_FAST);
|
||||
gPrefs->Read(wxT("/FileFormats/MP3ChannelMode"), &cmode, CHANNEL_STEREO);
|
||||
auto cmode = MP3ChannelModeSetting.ReadEnumWithDefault( CHANNEL_STEREO );
|
||||
gPrefs->Read(wxT("/FileFormats/MP3ForceMono"), &forceMono, 0);
|
||||
|
||||
// Set the bitrate/quality and mode
|
||||
if (rmode == MODE_SET) {
|
||||
int q = FindValue(setRates, WXSIZEOF(setRates), brate, PRESET_STANDARD);
|
||||
int r = FindValue(varModes, WXSIZEOF(varModes), vmode, ROUTINE_FAST);
|
||||
brate = ValidateValue(setRateNames.size(), brate, PRESET_STANDARD);
|
||||
int r = ValidateValue( varModeNames.size(), vmode, ROUTINE_FAST );
|
||||
exporter.SetMode(MODE_SET);
|
||||
exporter.SetQuality(q, r);
|
||||
exporter.SetQuality(brate, r);
|
||||
}
|
||||
else if (rmode == MODE_VBR) {
|
||||
int q = FindValue(varRates, WXSIZEOF(varRates), brate, QUALITY_2);
|
||||
int r = FindValue(varModes, WXSIZEOF(varModes), vmode, ROUTINE_FAST);
|
||||
brate = ValidateValue( varRateNames.size(), brate, QUALITY_2 );
|
||||
int r = ValidateValue( varModeNames.size(), vmode, ROUTINE_FAST );
|
||||
exporter.SetMode(MODE_VBR);
|
||||
exporter.SetQuality(q, r);
|
||||
exporter.SetQuality(brate, r);
|
||||
}
|
||||
else if (rmode == MODE_ABR) {
|
||||
bitrate = FindValue(fixRates, WXSIZEOF(fixRates), brate, 128);
|
||||
bitrate = brate = ValidateValue(fixRateValues, brate, 128);
|
||||
exporter.SetMode(MODE_ABR);
|
||||
exporter.SetBitrate(bitrate);
|
||||
|
||||
|
@ -1830,7 +1797,7 @@ ProgressResult ExportMP3::Export(AudacityProject *project,
|
|||
}
|
||||
}
|
||||
else {
|
||||
bitrate = FindValue(fixRates, WXSIZEOF(fixRates), brate, 128);
|
||||
bitrate = brate = ValidateValue(fixRateValues, brate, 128);
|
||||
exporter.SetMode(MODE_CBR);
|
||||
exporter.SetBitrate(bitrate);
|
||||
|
||||
|
@ -1843,7 +1810,7 @@ ProgressResult ExportMP3::Export(AudacityProject *project,
|
|||
}
|
||||
|
||||
// Verify sample rate
|
||||
if (FindName(sampRates, WXSIZEOF(sampRates), rate).empty() ||
|
||||
if (!make_iterator_range( sampRates ).contains( rate ) ||
|
||||
(rate < lowrate) || (rate > highrate)) {
|
||||
rate = AskResample(bitrate, rate, lowrate, highrate);
|
||||
if (rate == 0) {
|
||||
|
@ -1915,13 +1882,13 @@ ProgressResult ExportMP3::Export(AudacityProject *project,
|
|||
title.Printf(selectionOnly ?
|
||||
_("Exporting selected audio with %s preset") :
|
||||
_("Exporting the audio with %s preset"),
|
||||
FindName(setRates, WXSIZEOF(setRates), brate));
|
||||
setRateNamesShort[brate]);
|
||||
}
|
||||
else if (rmode == MODE_VBR) {
|
||||
title.Printf(selectionOnly ?
|
||||
_("Exporting selected audio with VBR quality %s") :
|
||||
_("Exporting the audio with VBR quality %s"),
|
||||
FindName(varRates, WXSIZEOF(varRates), brate));
|
||||
varRateNames[brate]);
|
||||
}
|
||||
else {
|
||||
title.Printf(selectionOnly ?
|
||||
|
@ -2029,28 +1996,6 @@ wxWindow *ExportMP3::OptionsCreate(wxWindow *parent, int format)
|
|||
return safenew ExportMP3Options(parent, format);
|
||||
}
|
||||
|
||||
int ExportMP3::FindValue(CHOICES *choices, int cnt, int needle, int def)
|
||||
{
|
||||
for (int i = 0; i < cnt; i++) {
|
||||
if (choices[i].label == needle) {
|
||||
return needle;
|
||||
}
|
||||
}
|
||||
|
||||
return def;
|
||||
}
|
||||
|
||||
wxString ExportMP3::FindName(CHOICES *choices, int cnt, int needle)
|
||||
{
|
||||
for (int i = 0; i < cnt; i++) {
|
||||
if (choices[i].label == needle) {
|
||||
return choices[i].name.BeforeFirst(wxT(','));
|
||||
}
|
||||
}
|
||||
|
||||
return wxT("");
|
||||
}
|
||||
|
||||
int ExportMP3::AskResample(int bitrate, int rate, int lowrate, int highrate)
|
||||
{
|
||||
wxDialogWrapper d(nullptr, wxID_ANY, wxString(_("Invalid sample rate")));
|
||||
|
@ -2080,12 +2025,12 @@ int ExportMP3::AskResample(int bitrate, int rate, int lowrate, int highrate)
|
|||
|
||||
wxArrayStringEx choices;
|
||||
int selected = -1;
|
||||
for (size_t i = 0; i < WXSIZEOF(sampRates); i++) {
|
||||
int label = sampRates[i].label;
|
||||
for (size_t ii = 0, nn = sampRates.size(); ii < nn; ++ii) {
|
||||
int label = sampRates[ii];
|
||||
if (label >= lowrate && label <= highrate) {
|
||||
choices.push_back(sampRates[i].name);
|
||||
choices.push_back( wxString::Format( "%d", label ) );
|
||||
if (label <= rate) {
|
||||
selected = i;
|
||||
selected = ii;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,10 +15,15 @@
|
|||
|
||||
#include "../MemoryX.h"
|
||||
|
||||
#define MODE_SET 0
|
||||
#define MODE_VBR 1
|
||||
#define MODE_ABR 2
|
||||
#define MODE_CBR 3
|
||||
enum MP3RateMode : unsigned {
|
||||
MODE_SET = 0,
|
||||
MODE_VBR,
|
||||
MODE_ABR,
|
||||
MODE_CBR,
|
||||
};
|
||||
|
||||
template< typename Enum > class EnumSetting;
|
||||
extern EnumSetting< MP3RateMode > MP3RateModeSetting;
|
||||
|
||||
#if defined(__WXMSW__) || defined(__WXMAC__)
|
||||
#define MP3_EXPORT_BUILT_IN 1
|
||||
|
|
|
@ -234,7 +234,7 @@ void ExportMultiple::PopulateOrExchange(ShuttleGui& S)
|
|||
++i;
|
||||
for (int j = 0; j < pPlugin->GetFormatCount(); j++)
|
||||
{
|
||||
formats.push_back(mPlugins[i]->GetDescription(j));
|
||||
formats.push_back(mPlugins[i]->GetUntranslatedDescription(j));
|
||||
if (mPlugins[i]->GetFormat(j) == defaultFormat) {
|
||||
mPluginIndex = i;
|
||||
mSubFormatIndex = j;
|
||||
|
@ -273,11 +273,13 @@ void ExportMultiple::PopulateOrExchange(ShuttleGui& S)
|
|||
S.Id(CreateID).AddButton(_("Create"));
|
||||
|
||||
mFormat = S.Id(FormatID)
|
||||
.TieChoice(_("Format:"),
|
||||
wxT("/Export/MultipleFormat"),
|
||||
formats[mFilterIndex],
|
||||
formats,
|
||||
formats);
|
||||
.TieChoice( _("Format:"),
|
||||
{
|
||||
wxT("/Export/MultipleFormat"),
|
||||
{ ByColumns, formats, formats },
|
||||
mFilterIndex
|
||||
}
|
||||
);
|
||||
S.AddVariableText( {}, false);
|
||||
S.AddVariableText( {}, false);
|
||||
|
||||
|
@ -353,16 +355,21 @@ void ExportMultiple::PopulateOrExchange(ShuttleGui& S)
|
|||
S.StartStatic(_("Name files:"), 1);
|
||||
{
|
||||
S.SetBorder(2);
|
||||
S.StartRadioButtonGroup(wxT("/Export/TrackNameWithOrWithoutNumbers"), wxT("labelTrack"));
|
||||
S.StartRadioButtonGroup({
|
||||
wxT("/Export/TrackNameWithOrWithoutNumbers"),
|
||||
{
|
||||
{ wxT("labelTrack"), XO("Using Label/Track Name") },
|
||||
{ wxT("numberBefore"), XO("Numbering before Label/Track Name") },
|
||||
{ wxT("numberAfter"), XO("Numbering after File name prefix") },
|
||||
},
|
||||
0 // labelTrack
|
||||
});
|
||||
{
|
||||
mByName = S.Id(ByNameID)
|
||||
.TieRadioButton(_("Using Label/Track Name"), wxT("labelTrack"));
|
||||
mByName = S.Id(ByNameID).TieRadioButton();
|
||||
|
||||
mByNumberAndName = S.Id(ByNameAndNumberID)
|
||||
.TieRadioButton(_("Numbering before Label/Track Name"), wxT("numberBefore"));
|
||||
mByNumberAndName = S.Id(ByNameAndNumberID).TieRadioButton();
|
||||
|
||||
mByNumber = S.Id(ByNumberID)
|
||||
.TieRadioButton(_("Numbering after File name prefix"), wxT("numberAfter"));
|
||||
mByNumber = S.Id(ByNumberID).TieRadioButton();
|
||||
}
|
||||
S.EndRadioButtonGroup();
|
||||
|
||||
|
|
|
@ -157,7 +157,7 @@ ExportOGG::ExportOGG()
|
|||
AddExtension(wxT("ogg"),0);
|
||||
SetMaxChannels(255,0);
|
||||
SetCanMetaData(true,0);
|
||||
SetDescription(_("Ogg Vorbis Files"),0);
|
||||
SetDescription(XO("Ogg Vorbis Files"),0);
|
||||
}
|
||||
|
||||
ProgressResult ExportOGG::Export(AudacityProject *project,
|
||||
|
|
|
@ -53,7 +53,7 @@ struct
|
|||
{
|
||||
int format;
|
||||
const wxChar *name;
|
||||
const wxChar *desc;
|
||||
const wxChar *desc; // untranslated
|
||||
}
|
||||
static const kFormats[] =
|
||||
{
|
||||
|
@ -374,7 +374,7 @@ ExportPCM::ExportPCM()
|
|||
|
||||
SetFormat(kFormats[i].name, format);
|
||||
SetCanMetaData(true, format);
|
||||
SetDescription(wxGetTranslation(kFormats[i].desc), format);
|
||||
SetDescription(kFormats[i].desc, format);
|
||||
AddExtension(ext, format);
|
||||
SetMaxChannels(si.channels - 1, format);
|
||||
}
|
||||
|
@ -383,7 +383,7 @@ ExportPCM::ExportPCM()
|
|||
format = AddFormat() - 1; // store the index = 1 less than the count
|
||||
SetFormat(wxT("LIBSNDFILE"), format);
|
||||
SetCanMetaData(true, format);
|
||||
SetDescription(_("Other uncompressed files"), format);
|
||||
SetDescription(XO("Other uncompressed files"), format);
|
||||
auto allext = sf_get_all_extensions();
|
||||
wxString wavext = sf_header_extension(SF_FORMAT_WAV); // get WAV ext.
|
||||
#if defined(wxMSW)
|
||||
|
|
|
@ -236,7 +236,7 @@ auto PCMImportFileHandle::GetFileUncompressedBytes() -> ByteCount
|
|||
static wxString AskCopyOrEdit()
|
||||
{
|
||||
|
||||
wxString oldCopyPref = gPrefs->Read(wxT("/FileFormats/CopyOrEditUncompressedData"), wxT("copy"));
|
||||
auto oldCopyPref = FileFormatsCopyOrEditSetting.Read();
|
||||
|
||||
bool firstTimeAsk = gPrefs->Read(wxT("/Warnings/CopyOrEditUncompressedDataFirstAsk"), true)?true:false;
|
||||
bool oldAskPref = gPrefs->Read(wxT("/Warnings/CopyOrEditUncompressedDataAsk"), true)?true:false;
|
||||
|
@ -245,7 +245,7 @@ static wxString AskCopyOrEdit()
|
|||
// This effectively does a one-time change to the preferences.
|
||||
if (firstTimeAsk) {
|
||||
if (oldCopyPref != wxT("copy")) {
|
||||
gPrefs->Write(wxT("/FileFormats/CopyOrEditUncompressedData"), wxT("copy"));
|
||||
FileFormatsCopyOrEditSetting.Write( wxT("copy") );
|
||||
oldCopyPref = wxT("copy");
|
||||
}
|
||||
gPrefs->Write(wxT("/Warnings/CopyOrEditUncompressedDataFirstAsk"), (long) false);
|
||||
|
@ -338,7 +338,7 @@ static wxString AskCopyOrEdit()
|
|||
|
||||
// if the preference changed, save it.
|
||||
if (newCopyPref != oldCopyPref) {
|
||||
gPrefs->Write(wxT("/FileFormats/CopyOrEditUncompressedData"), newCopyPref);
|
||||
FileFormatsCopyOrEditSetting.Write( newCopyPref );
|
||||
gPrefs->Flush();
|
||||
}
|
||||
oldCopyPref = newCopyPref;
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include "../effects/Contrast.h"
|
||||
#include "../effects/EffectManager.h"
|
||||
#include "../effects/RealtimeEffectManager.h"
|
||||
#include "../prefs/EffectsPrefs.h"
|
||||
|
||||
// private helper classes and functions
|
||||
namespace {
|
||||
|
@ -195,7 +196,7 @@ void AddEffectMenuItems(
|
|||
{
|
||||
size_t pluginCnt = plugs.size();
|
||||
|
||||
wxString groupBy = gPrefs->Read(wxT("/Effects/GroupBy"), wxT("sortby:name"));
|
||||
auto groupBy = EffectsGroupBy.Read();
|
||||
|
||||
bool grouped = false;
|
||||
if (groupBy.StartsWith(wxT("groupby")))
|
||||
|
@ -382,7 +383,7 @@ MenuTable::BaseItemPtrs PopulateEffectsMenu(
|
|||
plug = pm.GetNextPluginForEffectType(type);
|
||||
}
|
||||
|
||||
wxString groupby = gPrefs->Read(wxT("/Effects/GroupBy"), wxT("sortby:name"));
|
||||
wxString groupby = EffectsGroupBy.Read();
|
||||
|
||||
using Comparator = bool(*)(const PluginDescriptor*, const PluginDescriptor*);
|
||||
Comparator comp1, comp2;
|
||||
|
|
|
@ -133,11 +133,12 @@ void DevicePrefs::PopulateOrExchange(ShuttleGui & S)
|
|||
S.StartMultiColumn(2);
|
||||
{
|
||||
S.Id(HostID);
|
||||
mHost = S.TieChoice(_("&Host:"),
|
||||
wxT("/AudioIO/Host"),
|
||||
wxT(""),
|
||||
mHostNames,
|
||||
mHostLabels);
|
||||
mHost = S.TieChoice( _("&Host:"),
|
||||
{
|
||||
wxT("/AudioIO/Host"),
|
||||
{ ByColumns, mHostNames, mHostLabels }
|
||||
}
|
||||
);
|
||||
|
||||
S.AddPrompt(_("Using:"));
|
||||
S.AddFixedText(wxString(wxSafeConvertMB2WX(Pa_GetVersionText())));
|
||||
|
|
|
@ -66,6 +66,28 @@ void EffectsPrefs::Populate()
|
|||
// ----------------------- End of main section --------------
|
||||
}
|
||||
|
||||
ChoiceSetting EffectsGroupBy{
|
||||
wxT("/Effects/GroupBy"),
|
||||
{
|
||||
ByColumns,
|
||||
{
|
||||
XO("Sorted by Effect Name") ,
|
||||
XO("Sorted by Publisher and Effect Name") ,
|
||||
XO("Sorted by Type and Effect Name") ,
|
||||
XO("Grouped by Publisher") ,
|
||||
XO("Grouped by Type") ,
|
||||
},
|
||||
{
|
||||
wxT("sortby:name") ,
|
||||
wxT("sortby:publisher:name") ,
|
||||
wxT("sortby:type:name") ,
|
||||
wxT("groupby:publisher") ,
|
||||
wxT("groupby:type") ,
|
||||
}
|
||||
},
|
||||
0 // "sortby:name"
|
||||
};
|
||||
|
||||
namespace {
|
||||
|
||||
// Rather than hard-code an exhaustive list of effect families in this file,
|
||||
|
@ -177,27 +199,7 @@ void EffectsPrefs::PopulateOrExchange(ShuttleGui & S)
|
|||
{
|
||||
S.StartMultiColumn(2);
|
||||
{
|
||||
wxArrayStringEx visualgroups{
|
||||
_("Sorted by Effect Name") ,
|
||||
_("Sorted by Publisher and Effect Name") ,
|
||||
_("Sorted by Type and Effect Name") ,
|
||||
_("Grouped by Publisher") ,
|
||||
_("Grouped by Type") ,
|
||||
};
|
||||
|
||||
wxArrayStringEx prefsgroups{
|
||||
wxT("sortby:name") ,
|
||||
wxT("sortby:publisher:name") ,
|
||||
wxT("sortby:type:name") ,
|
||||
wxT("groupby:publisher") ,
|
||||
wxT("groupby:type") ,
|
||||
};
|
||||
|
||||
wxChoice *c = S.TieChoice(_("S&ort or Group:"),
|
||||
wxT("/Effects/GroupBy"),
|
||||
wxT("sortby:name"),
|
||||
visualgroups,
|
||||
prefsgroups);
|
||||
wxChoice *c = S.TieChoice( _("S&ort or Group:"), EffectsGroupBy);
|
||||
if( c ) c->SetMinSize(c->GetBestSize());
|
||||
|
||||
S.TieNumericTextBox(_("&Maximum effects per group (0 to disable):"),
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
|
||||
#include "PrefsPanel.h"
|
||||
|
||||
class ChoiceSetting;
|
||||
class ShuttleGui;
|
||||
|
||||
#define EFFECTS_PREFS_PLUGIN_SYMBOL ComponentInterfaceSymbol{ XO("Effects") }
|
||||
|
@ -39,4 +40,7 @@ class EffectsPrefs final : public PrefsPanel
|
|||
|
||||
/// A PrefsPanel::Factory that creates one EffectsPrefs panel.
|
||||
extern PrefsPanel::Factory EffectsPrefsFactory;
|
||||
|
||||
extern ChoiceSetting EffectsGroupBy;
|
||||
|
||||
#endif
|
||||
|
|
|
@ -67,37 +67,45 @@ wxString GUIPrefs::HelpPageName()
|
|||
}
|
||||
|
||||
void GUIPrefs::GetRangeChoices(
|
||||
wxArrayStringEx *pChoices, wxArrayStringEx *pCodes)
|
||||
wxArrayStringEx *pChoicesUntranslated,
|
||||
wxArrayStringEx *pChoicesTranslated,
|
||||
wxArrayStringEx *pCodes,
|
||||
int *pDefaultRangeIndex
|
||||
)
|
||||
{
|
||||
if (pCodes) {
|
||||
auto &codes = *pCodes;
|
||||
codes.clear();
|
||||
codes.insert( codes.end(), {
|
||||
wxT("36") ,
|
||||
wxT("48") ,
|
||||
wxT("60") ,
|
||||
wxT("72") ,
|
||||
wxT("84") ,
|
||||
wxT("96") ,
|
||||
wxT("120") ,
|
||||
wxT("145") ,
|
||||
} );
|
||||
}
|
||||
static const auto sCodes = {
|
||||
wxT("36") ,
|
||||
wxT("48") ,
|
||||
wxT("60") ,
|
||||
wxT("72") ,
|
||||
wxT("84") ,
|
||||
wxT("96") ,
|
||||
wxT("120") ,
|
||||
wxT("145") ,
|
||||
};
|
||||
if (pCodes)
|
||||
*pCodes = sCodes;
|
||||
|
||||
if (pChoices) {
|
||||
auto &choices = *pChoices;
|
||||
choices.clear();
|
||||
choices.insert( choices.end(), {
|
||||
_("-36 dB (shallow range for high-amplitude editing)") ,
|
||||
_("-48 dB (PCM range of 8 bit samples)") ,
|
||||
_("-60 dB (PCM range of 10 bit samples)") ,
|
||||
_("-72 dB (PCM range of 12 bit samples)") ,
|
||||
_("-84 dB (PCM range of 14 bit samples)") ,
|
||||
_("-96 dB (PCM range of 16 bit samples)") ,
|
||||
_("-120 dB (approximate limit of human hearing)") ,
|
||||
_("-145 dB (PCM range of 24 bit samples)") ,
|
||||
} );
|
||||
}
|
||||
static const auto sChoices = {
|
||||
XO("-36 dB (shallow range for high-amplitude editing)") ,
|
||||
XO("-48 dB (PCM range of 8 bit samples)") ,
|
||||
XO("-60 dB (PCM range of 10 bit samples)") ,
|
||||
XO("-72 dB (PCM range of 12 bit samples)") ,
|
||||
XO("-84 dB (PCM range of 14 bit samples)") ,
|
||||
XO("-96 dB (PCM range of 16 bit samples)") ,
|
||||
XO("-120 dB (approximate limit of human hearing)") ,
|
||||
XO("-145 dB (PCM range of 24 bit samples)") ,
|
||||
};
|
||||
|
||||
if (pChoicesUntranslated)
|
||||
*pChoicesUntranslated = sChoices;
|
||||
|
||||
if (pChoicesTranslated)
|
||||
*pChoicesTranslated =
|
||||
transform_container<wxArrayStringEx>( sChoices, GetCustomTranslation );
|
||||
|
||||
if (pDefaultRangeIndex)
|
||||
*pDefaultRangeIndex = 2; // 60 == ENV_DB_RANGE
|
||||
}
|
||||
|
||||
void GUIPrefs::Populate()
|
||||
|
@ -105,43 +113,7 @@ void GUIPrefs::Populate()
|
|||
// First any pre-processing for constructing the GUI.
|
||||
GetLanguages(mLangCodes, mLangNames);
|
||||
|
||||
mHtmlHelpCodes.clear();
|
||||
auto values = {
|
||||
wxT("Local") ,
|
||||
wxT("FromInternet") ,
|
||||
};
|
||||
mHtmlHelpCodes.insert( mHtmlHelpCodes.end(), values );
|
||||
|
||||
mHtmlHelpChoices.clear();
|
||||
auto values2 = {
|
||||
_("Local") ,
|
||||
_("From Internet") ,
|
||||
};
|
||||
mHtmlHelpChoices.insert( mHtmlHelpChoices.end(), values2 );
|
||||
|
||||
mThemeCodes.clear();
|
||||
mThemeCodes.insert( mThemeCodes.end(), {
|
||||
wxT("classic") ,
|
||||
wxT("light") ,
|
||||
wxT("dark") ,
|
||||
wxT("high-contrast") ,
|
||||
wxT("custom") ,
|
||||
} );
|
||||
|
||||
mThemeChoices.clear();
|
||||
mThemeChoices.insert( mThemeChoices.end(), {
|
||||
/* i18n-hint: describing the "classic" or traditional appearance of older versions of Audacity */
|
||||
_("Classic") ,
|
||||
/* i18n-hint: Light meaning opposite of dark */
|
||||
_("Light") ,
|
||||
_("Dark") ,
|
||||
/* i18n-hint: greater difference between foreground and background colors */
|
||||
_("High Contrast") ,
|
||||
/* i18n-hint: user defined */
|
||||
_("Custom") ,
|
||||
} );
|
||||
|
||||
GetRangeChoices(&mRangeChoices, &mRangeCodes);
|
||||
GetRangeChoices(&mRangeChoices, nullptr, &mRangeCodes, &mDefaultRangeIndex);
|
||||
|
||||
#if 0
|
||||
mLangCodes.insert( mLangCodes.end(), {
|
||||
|
@ -165,6 +137,52 @@ void GUIPrefs::Populate()
|
|||
// ----------------------- End of main section --------------
|
||||
}
|
||||
|
||||
ChoiceSetting GUIManualLocation{
|
||||
wxT("/GUI/Help"),
|
||||
{
|
||||
ByColumns,
|
||||
{ XO("Local") , XO("From Internet") , },
|
||||
{ wxT("Local") , wxT("FromInternet") , }
|
||||
},
|
||||
0 // "Local"
|
||||
};
|
||||
|
||||
constexpr int defaultTheme =
|
||||
#ifdef EXPERIMENTAL_DA
|
||||
2 // "dark"
|
||||
#else
|
||||
1 // "light"
|
||||
#endif
|
||||
;
|
||||
|
||||
ChoiceSetting GUITheme{
|
||||
wxT("/GUI/Theme"),
|
||||
{
|
||||
ByColumns,
|
||||
{
|
||||
/* i18n-hint: describing the "classic" or traditional
|
||||
appearance of older versions of Audacity */
|
||||
XO("Classic") ,
|
||||
/* i18n-hint: Light meaning opposite of dark */
|
||||
XO("Light") ,
|
||||
XO("Dark") ,
|
||||
/* i18n-hint: greater difference between foreground and
|
||||
background colors */
|
||||
XO("High Contrast") ,
|
||||
/* i18n-hint: user defined */
|
||||
XO("Custom") ,
|
||||
},
|
||||
{
|
||||
wxT("classic") ,
|
||||
wxT("light") ,
|
||||
wxT("dark") ,
|
||||
wxT("high-contrast") ,
|
||||
wxT("custom") ,
|
||||
}
|
||||
},
|
||||
defaultTheme
|
||||
};
|
||||
|
||||
void GUIPrefs::PopulateOrExchange(ShuttleGui & S)
|
||||
{
|
||||
S.SetBorder(2);
|
||||
|
@ -175,36 +193,24 @@ void GUIPrefs::PopulateOrExchange(ShuttleGui & S)
|
|||
S.StartMultiColumn(2);
|
||||
{
|
||||
|
||||
#ifdef EXPERIMENTAL_DA
|
||||
const wxString defaultTheme = wxT("dark");
|
||||
#else
|
||||
const wxString defaultTheme = wxT("light");
|
||||
#endif
|
||||
const wxString defaultRange = wxString::Format(wxT("%d"), ENV_DB_RANGE);
|
||||
S.TieChoice( _("&Language:"),
|
||||
{
|
||||
wxT("/Locale/Language"),
|
||||
{ ByColumns, mLangNames, mLangCodes }
|
||||
}
|
||||
);
|
||||
|
||||
S.TieChoice(_("&Language:"),
|
||||
wxT("/Locale/Language"),
|
||||
wxT(""),
|
||||
mLangNames,
|
||||
mLangCodes);
|
||||
S.TieChoice( _("Location of &Manual:"), GUIManualLocation);
|
||||
|
||||
S.TieChoice(_("Location of &Manual:"),
|
||||
wxT("/GUI/Help"),
|
||||
wxT("Local"),
|
||||
mHtmlHelpChoices,
|
||||
mHtmlHelpCodes);
|
||||
S.TieChoice( _("Th&eme:"), GUITheme);
|
||||
|
||||
S.TieChoice(_("Th&eme:"),
|
||||
wxT("/GUI/Theme"),
|
||||
defaultTheme,
|
||||
mThemeChoices,
|
||||
mThemeCodes);
|
||||
|
||||
S.TieChoice(_("Meter dB &range:"),
|
||||
ENV_DB_KEY,
|
||||
defaultRange,
|
||||
mRangeChoices,
|
||||
mRangeCodes);
|
||||
S.TieChoice( _("Meter dB &range:"),
|
||||
{
|
||||
ENV_DB_KEY,
|
||||
{ ByColumns, mRangeChoices, mRangeCodes },
|
||||
mDefaultRangeIndex
|
||||
}
|
||||
);
|
||||
}
|
||||
S.EndMultiColumn();
|
||||
// S.AddSpace(10);
|
||||
|
@ -269,7 +275,7 @@ bool GUIPrefs::Commit()
|
|||
gPrefs->Flush();
|
||||
}
|
||||
|
||||
// Reads preference /GUI/Theme
|
||||
// Reads preference GUITheme
|
||||
theTheme.LoadPreferredTheme();
|
||||
ThemePrefs::ApplyUpdatedImages();
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
|
||||
#include "PrefsPanel.h"
|
||||
|
||||
class ChoiceSetting;
|
||||
class ShuttleGui;
|
||||
class wxArrayStringEx;
|
||||
|
||||
|
@ -35,7 +36,11 @@ class GUIPrefs final : public PrefsPanel
|
|||
void PopulateOrExchange(ShuttleGui & S) override;
|
||||
|
||||
static void GetRangeChoices(
|
||||
wxArrayStringEx *pChoices, wxArrayStringEx *pCodes);
|
||||
wxArrayStringEx *pChoicesUntranslated,
|
||||
wxArrayStringEx *pChoicesTranslated,
|
||||
wxArrayStringEx *pCodes,
|
||||
int *pDefaultRangeIndex = nullptr
|
||||
);
|
||||
|
||||
// If no input language given, defaults first to choice in preferences, then
|
||||
// to system language.
|
||||
|
@ -55,14 +60,9 @@ class GUIPrefs final : public PrefsPanel
|
|||
wxArrayStringEx mLangCodes;
|
||||
wxArrayStringEx mLangNames;
|
||||
|
||||
wxArrayStringEx mHtmlHelpCodes;
|
||||
wxArrayStringEx mHtmlHelpChoices;
|
||||
|
||||
wxArrayStringEx mThemeCodes;
|
||||
wxArrayStringEx mThemeChoices;
|
||||
|
||||
wxArrayStringEx mRangeCodes;
|
||||
wxArrayStringEx mRangeChoices;
|
||||
int mDefaultRangeIndex;
|
||||
};
|
||||
|
||||
/// A PrefsPanel::Factory that creates one GUIPrefs panel.
|
||||
|
@ -70,4 +70,9 @@ extern PrefsPanel::Factory GUIPrefsFactory;
|
|||
|
||||
int ShowClippingPrefsID();
|
||||
|
||||
extern ChoiceSetting
|
||||
GUIManualLocation
|
||||
, GUITheme
|
||||
;
|
||||
|
||||
#endif
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
|
||||
#include <wx/defs.h>
|
||||
|
||||
#include "../FileFormats.h"
|
||||
#include "../Prefs.h"
|
||||
#include "../ShuttleGui.h"
|
||||
|
||||
|
@ -60,6 +61,36 @@ void ImportExportPrefs::Populate()
|
|||
// ----------------------- End of main section --------------
|
||||
}
|
||||
|
||||
EnumSetting< bool > ImportExportPrefs::ExportDownMixSetting{
|
||||
wxT("/FileFormats/ExportDownMixChoice"),
|
||||
{
|
||||
EnumValueSymbol{ wxT("MixDown"), XO("&Mix down to Stereo or Mono") },
|
||||
EnumValueSymbol{ wxT("Custom"), XO("&Use Advanced Mixing Options") },
|
||||
},
|
||||
0, // true
|
||||
|
||||
// for migrating old preferences:
|
||||
{
|
||||
true, false,
|
||||
},
|
||||
wxT("/FileFormats/ExportDownMix"),
|
||||
};
|
||||
|
||||
EnumSetting< bool > ImportExportPrefs::AllegroStyleSetting{
|
||||
wxT("/FileFormats/AllegroStyleChoice"),
|
||||
{
|
||||
EnumValueSymbol{ wxT("Seconds"), XO("&Seconds") },
|
||||
EnumValueSymbol{ wxT("Beats"), XO("&Beats") },
|
||||
},
|
||||
0, // true
|
||||
|
||||
// for migrating old preferences:
|
||||
{
|
||||
true, false,
|
||||
},
|
||||
wxT("/FileFormats/AllegroStyle"),
|
||||
};
|
||||
|
||||
void ImportExportPrefs::PopulateOrExchange(ShuttleGui & S)
|
||||
{
|
||||
S.SetBorder(2);
|
||||
|
@ -68,12 +99,10 @@ void ImportExportPrefs::PopulateOrExchange(ShuttleGui & S)
|
|||
#ifdef EXPERIMENTAL_OD_DATA
|
||||
S.StartStatic(_("When importing audio files"));
|
||||
{
|
||||
S.StartRadioButtonGroup(wxT("/FileFormats/CopyOrEditUncompressedData"), wxT("copy"));
|
||||
S.StartRadioButtonGroup(FileFormatsCopyOrEditSetting);
|
||||
{
|
||||
S.TieRadioButton(_("&Copy uncompressed files into the project (safer)"),
|
||||
wxT("copy"));
|
||||
S.TieRadioButton(_("&Read uncompressed files from original location (faster)"),
|
||||
wxT("edit"));
|
||||
S.TieRadioButton();
|
||||
S.TieRadioButton();
|
||||
}
|
||||
S.EndRadioButtonGroup();
|
||||
}
|
||||
|
@ -81,12 +110,10 @@ void ImportExportPrefs::PopulateOrExchange(ShuttleGui & S)
|
|||
#endif
|
||||
S.StartStatic(_("When exporting tracks to an audio file"));
|
||||
{
|
||||
S.StartRadioButtonGroup(wxT("/FileFormats/ExportDownMix"), true);
|
||||
S.StartRadioButtonGroup(ImportExportPrefs::ExportDownMixSetting);
|
||||
{
|
||||
S.TieRadioButton(_("&Mix down to Stereo or Mono"),
|
||||
true);
|
||||
S.TieRadioButton(_("&Use Advanced Mixing Options"),
|
||||
false);
|
||||
S.TieRadioButton();
|
||||
S.TieRadioButton();
|
||||
}
|
||||
S.EndRadioButtonGroup();
|
||||
|
||||
|
@ -102,12 +129,10 @@ void ImportExportPrefs::PopulateOrExchange(ShuttleGui & S)
|
|||
#ifdef USE_MIDI
|
||||
S.StartStatic(_("Exported Allegro (.gro) files save time as:"));
|
||||
{
|
||||
S.StartRadioButtonGroup(wxT("/FileFormats/AllegroStyle"), true);
|
||||
S.StartRadioButtonGroup(ImportExportPrefs::AllegroStyleSetting);
|
||||
{
|
||||
S.TieRadioButton(_("&Seconds"),
|
||||
true);
|
||||
S.TieRadioButton(_("&Beats"),
|
||||
false);
|
||||
S.TieRadioButton();
|
||||
S.TieRadioButton();
|
||||
}
|
||||
S.EndRadioButtonGroup();
|
||||
}
|
||||
|
|
|
@ -21,9 +21,14 @@ class ShuttleGui;
|
|||
|
||||
#define IMPORT_EXPORT_PREFS_PLUGIN_SYMBOL ComponentInterfaceSymbol{ XO("IMPORT EXPORT") }
|
||||
|
||||
template< typename Enum > class EnumSetting;
|
||||
|
||||
class ImportExportPrefs final : public PrefsPanel
|
||||
{
|
||||
public:
|
||||
static EnumSetting< bool > ExportDownMixSetting;
|
||||
static EnumSetting< bool > AllegroStyleSetting;
|
||||
|
||||
ImportExportPrefs(wxWindow * parent, wxWindowID winid);
|
||||
~ImportExportPrefs();
|
||||
ComponentInterfaceSymbol GetSymbol() override;
|
||||
|
@ -39,4 +44,5 @@ class ImportExportPrefs final : public PrefsPanel
|
|||
|
||||
/// A PrefsPanel::Factory that creates one ImportExportPrefs panel.
|
||||
extern PrefsPanel::Factory ImportExportPrefsFactory;
|
||||
|
||||
#endif
|
||||
|
|
|
@ -174,13 +174,21 @@ void KeyConfigPrefs::PopulateOrExchange(ShuttleGui & S)
|
|||
S.StartHorizontalLay(wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL, 0);
|
||||
{
|
||||
S.AddTitle(_("View by:"));
|
||||
S.StartRadioButtonGroup(wxT("/Prefs/KeyConfig/ViewBy"), wxT("tree"));
|
||||
S.StartRadioButtonGroup({
|
||||
wxT("/Prefs/KeyConfig/ViewBy"),
|
||||
{
|
||||
{ wxT("tree"), XO("&Tree") },
|
||||
{ wxT("name"), XO("&Name") },
|
||||
{ wxT("key"), XO("&Key") },
|
||||
},
|
||||
0 // tree
|
||||
});
|
||||
{
|
||||
mViewByTree = S.Id(ViewByTreeID).TieRadioButton(_("&Tree"), wxT("tree"));
|
||||
mViewByTree = S.Id(ViewByTreeID).TieRadioButton();
|
||||
if( mViewByTree ) mViewByTree->SetName(_("View by tree"));
|
||||
mViewByName = S.Id(ViewByNameID).TieRadioButton(_("&Name"), wxT("name"));
|
||||
mViewByName = S.Id(ViewByNameID).TieRadioButton();
|
||||
if( mViewByName ) mViewByName->SetName(_("View by name"));
|
||||
mViewByKey = S.Id(ViewByKeyID).TieRadioButton(_("&Key"), wxT("key"));
|
||||
mViewByKey = S.Id(ViewByKeyID).TieRadioButton();
|
||||
if( mViewByKey ) mViewByKey->SetName(_("View by key"));
|
||||
#if wxUSE_ACCESSIBILITY
|
||||
// so that name can be set on a standard control
|
||||
|
|
|
@ -138,11 +138,12 @@ void MidiIOPrefs::PopulateOrExchange( ShuttleGui & S ) {
|
|||
{
|
||||
S.Id(HostID);
|
||||
/* i18n-hint: (noun) */
|
||||
mHost = S.TieChoice(_("&Host:"),
|
||||
wxT("/MidiIO/Host"),
|
||||
wxT(""),
|
||||
mHostNames,
|
||||
mHostLabels);
|
||||
mHost = S.TieChoice( _("&Host:"),
|
||||
{
|
||||
wxT("/MidiIO/Host"),
|
||||
{ ByColumns, mHostNames, mHostLabels }
|
||||
}
|
||||
);
|
||||
|
||||
S.AddPrompt(_("Using: PortMidi"));
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@ handling.
|
|||
#include <wx/defs.h>
|
||||
#include <wx/textctrl.h>
|
||||
|
||||
#include "../FileFormats.h"
|
||||
#include "../Prefs.h"
|
||||
#include "../ShuttleGui.h"
|
||||
|
||||
|
@ -73,14 +74,11 @@ void ProjectsPrefs::PopulateOrExchange(ShuttleGui & S)
|
|||
|
||||
S.StartStatic(_("When saving a project that depends on other audio files"));
|
||||
{
|
||||
S.StartRadioButtonGroup(wxT("/FileFormats/SaveProjectWithDependencies"), wxT("ask"));
|
||||
S.StartRadioButtonGroup(FileFormatsSaveWithDependenciesSetting);
|
||||
{
|
||||
S.TieRadioButton(_("&Copy all audio into project (safest)"),
|
||||
wxT("copy"));
|
||||
S.TieRadioButton(_("Do ¬ copy any audio"),
|
||||
wxT("never"));
|
||||
S.TieRadioButton(_("As&k"),
|
||||
wxT("ask"));
|
||||
S.TieRadioButton();
|
||||
S.TieRadioButton();
|
||||
S.TieRadioButton();
|
||||
}
|
||||
S.EndRadioButtonGroup();
|
||||
}
|
||||
|
|
|
@ -32,26 +32,21 @@
|
|||
|
||||
//////////
|
||||
|
||||
static const EnumValueSymbol choicesFormat[] = {
|
||||
{ wxT("Format16Bit"), XO("16-bit") },
|
||||
{ wxT("Format24Bit"), XO("24-bit") },
|
||||
{ wxT("Format32BitFloat"), XO("32-bit float") }
|
||||
};
|
||||
static const size_t nChoicesFormat = WXSIZEOF( choicesFormat );
|
||||
static const int intChoicesFormat[] = {
|
||||
int16Sample,
|
||||
int24Sample,
|
||||
floatSample
|
||||
};
|
||||
static_assert( nChoicesFormat == WXSIZEOF(intChoicesFormat), "size mismatch" );
|
||||
|
||||
static const size_t defaultChoiceFormat = 2; // floatSample
|
||||
|
||||
static EnumSetting formatSetting{
|
||||
static EnumSetting< sampleFormat > formatSetting{
|
||||
wxT("/SamplingRate/DefaultProjectSampleFormatChoice"),
|
||||
choicesFormat, nChoicesFormat, defaultChoiceFormat,
|
||||
|
||||
intChoicesFormat,
|
||||
{
|
||||
{ wxT("Format16Bit"), XO("16-bit") },
|
||||
{ wxT("Format24Bit"), XO("24-bit") },
|
||||
{ wxT("Format32BitFloat"), XO("32-bit float") }
|
||||
},
|
||||
2, // floatSample
|
||||
|
||||
// for migrating old preferences:
|
||||
{
|
||||
int16Sample,
|
||||
int24Sample,
|
||||
floatSample
|
||||
},
|
||||
wxT("/SamplingRate/DefaultProjectSampleFormat"),
|
||||
};
|
||||
|
||||
|
@ -132,7 +127,7 @@ void QualityPrefs::GetNamesAndLabels()
|
|||
mSampleRateNames.push_back(wxString::Format(wxT("%i Hz"), iRate));
|
||||
}
|
||||
|
||||
mSampleRateNames.push_back(_("Other..."));
|
||||
mSampleRateNames.push_back(XO("Other..."));
|
||||
|
||||
// The label for the 'Other...' case can be any value at all.
|
||||
mSampleRateLabels.push_back(44100); // If chosen, this value will be overwritten
|
||||
|
@ -162,7 +157,7 @@ void QualityPrefs::PopulateOrExchange(ShuttleGui & S)
|
|||
wxT("/SamplingRate/DefaultProjectSampleRate"),
|
||||
AudioIOBase::GetOptimalSupportedSampleRate(),
|
||||
mSampleRateNames,
|
||||
mSampleRateLabels);
|
||||
&mSampleRateLabels);
|
||||
|
||||
// Now do the edit box...
|
||||
mOtherSampleRate = S.TieNumericTextBox( {},
|
||||
|
@ -246,6 +241,6 @@ QualityPrefsFactory = [](wxWindow *parent, wxWindowID winid)
|
|||
|
||||
sampleFormat QualityPrefs::SampleFormatChoice()
|
||||
{
|
||||
return (sampleFormat)formatSetting.ReadInt();
|
||||
return formatSetting.ReadEnum();
|
||||
}
|
||||
|
||||
|
|
|
@ -56,14 +56,6 @@ const wxChar *TracksBehaviorsPrefs::ScrollingPreferenceKey()
|
|||
|
||||
void TracksBehaviorsPrefs::Populate()
|
||||
{
|
||||
mSoloCodes.push_back(wxT("Simple"));
|
||||
mSoloCodes.push_back(wxT("Multi"));
|
||||
mSoloCodes.push_back(wxT("None"));
|
||||
|
||||
mSoloChoices.push_back(_("Simple"));
|
||||
mSoloChoices.push_back(_("Multi-track"));
|
||||
mSoloChoices.push_back(_("None"));
|
||||
|
||||
//------------------------- Main section --------------------
|
||||
// Now construct the GUI itself.
|
||||
ShuttleGui S(this, eIsCreatingFromPrefs);
|
||||
|
@ -71,6 +63,16 @@ void TracksBehaviorsPrefs::Populate()
|
|||
// ----------------------- End of main section --------------
|
||||
}
|
||||
|
||||
ChoiceSetting TracksBehaviorsSolo{
|
||||
wxT("/GUI/Solo"),
|
||||
{
|
||||
ByColumns,
|
||||
{ XO("Simple"), XO("Multi-track"), XO("None") },
|
||||
{ wxT("Simple"), wxT("Multi"), wxT("None") }
|
||||
},
|
||||
0, // "Simple"
|
||||
};
|
||||
|
||||
void TracksBehaviorsPrefs::PopulateOrExchange(ShuttleGui & S)
|
||||
{
|
||||
S.SetBorder(2);
|
||||
|
@ -113,11 +115,7 @@ void TracksBehaviorsPrefs::PopulateOrExchange(ShuttleGui & S)
|
|||
|
||||
S.StartMultiColumn(2);
|
||||
{
|
||||
S.TieChoice(_("Solo &Button:"),
|
||||
wxT("/GUI/Solo"),
|
||||
wxT("Standard"),
|
||||
mSoloChoices,
|
||||
mSoloCodes);
|
||||
S.TieChoice( _("Solo &Button:"), TracksBehaviorsSolo);
|
||||
}
|
||||
S.EndMultiColumn();
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
#include "PrefsPanel.h"
|
||||
|
||||
class ChoiceSetting;
|
||||
class ShuttleGui;
|
||||
class wxArrayStringEx;
|
||||
|
||||
|
@ -38,11 +39,11 @@ class TracksBehaviorsPrefs final : public PrefsPanel
|
|||
private:
|
||||
void Populate();
|
||||
void PopulateOrExchange(ShuttleGui & S) override;
|
||||
|
||||
wxArrayStringEx mSoloCodes;
|
||||
wxArrayStringEx mSoloChoices;
|
||||
};
|
||||
|
||||
/// A PrefsPanel::Factory that creates one TracksBehaviorsPrefs panel.
|
||||
extern PrefsPanel::Factory TracksBehaviorsPrefsFactory;
|
||||
|
||||
extern ChoiceSetting TracksBehaviorsSolo;
|
||||
|
||||
#endif
|
||||
|
|
|
@ -54,33 +54,21 @@ namespace {
|
|||
|
||||
|
||||
//////////
|
||||
static const EnumValueSymbol choicesView[] = {
|
||||
{ XO("Waveform") },
|
||||
{ wxT("WaveformDB"), XO("Waveform (dB)") },
|
||||
{ XO("Spectrogram") }
|
||||
};
|
||||
static const int intChoicesView[] = {
|
||||
(int)(WaveTrackViewConstants::Waveform),
|
||||
(int)(WaveTrackViewConstants::obsoleteWaveformDBDisplay),
|
||||
(int)(WaveTrackViewConstants::Spectrum)
|
||||
};
|
||||
static const size_t nChoicesView = WXSIZEOF(choicesView);
|
||||
static_assert( nChoicesView == WXSIZEOF(intChoicesView), "size mismatch" );
|
||||
|
||||
static const size_t defaultChoiceView = 0;
|
||||
|
||||
class TracksViewModeSetting : public EnumSetting {
|
||||
class TracksViewModeEnumSetting
|
||||
: public EnumSetting< WaveTrackViewConstants::Display > {
|
||||
public:
|
||||
TracksViewModeSetting(
|
||||
TracksViewModeEnumSetting(
|
||||
const wxString &key,
|
||||
const EnumValueSymbol symbols[], size_t nSymbols,
|
||||
size_t defaultSymbol,
|
||||
EnumValueSymbols symbols,
|
||||
long defaultSymbol,
|
||||
|
||||
const int intValues[],
|
||||
std::initializer_list< WaveTrackViewConstants::Display > intValues,
|
||||
const wxString &oldKey
|
||||
)
|
||||
: EnumSetting{
|
||||
key, symbols, nSymbols, defaultSymbol, intValues, oldKey }
|
||||
key, std::move( symbols ), defaultSymbol,
|
||||
std::move( intValues ), oldKey
|
||||
}
|
||||
{}
|
||||
|
||||
void Migrate( wxString &value ) override
|
||||
|
@ -106,56 +94,61 @@ public:
|
|||
// Now future-proof 2.1.1 against a recurrence of this sort of bug!
|
||||
viewMode = WaveTrackViewConstants::ValidateWaveTrackDisplay(viewMode);
|
||||
|
||||
const_cast<TracksViewModeSetting*>(this)->WriteInt( viewMode );
|
||||
const_cast<TracksViewModeEnumSetting*>(this)->WriteInt( viewMode );
|
||||
gPrefs->Flush();
|
||||
|
||||
value = mSymbols[ FindInt(viewMode) ].Internal();
|
||||
}
|
||||
};
|
||||
|
||||
static TracksViewModeSetting viewModeSetting{
|
||||
static TracksViewModeEnumSetting viewModeSetting{
|
||||
wxT("/GUI/DefaultViewModeChoice"),
|
||||
choicesView, nChoicesView, defaultChoiceView,
|
||||
{
|
||||
{ XO("Waveform") },
|
||||
{ wxT("WaveformDB"), XO("Waveform (dB)") },
|
||||
{ XO("Spectrogram") }
|
||||
},
|
||||
0, // Waveform
|
||||
|
||||
intChoicesView,
|
||||
// for migrating old preferences:
|
||||
{
|
||||
WaveTrackViewConstants::Waveform,
|
||||
WaveTrackViewConstants::obsoleteWaveformDBDisplay,
|
||||
WaveTrackViewConstants::Spectrum
|
||||
},
|
||||
wxT("/GUI/DefaultViewModeNew")
|
||||
};
|
||||
|
||||
WaveTrackViewConstants::Display TracksPrefs::ViewModeChoice()
|
||||
{
|
||||
return (WaveTrackViewConstants::Display) viewModeSetting.ReadInt();
|
||||
return viewModeSetting.ReadEnum();
|
||||
}
|
||||
|
||||
//////////
|
||||
static const EnumValueSymbol choicesSampleDisplay[] = {
|
||||
{ wxT("ConnectDots"), XO("Connect dots") },
|
||||
{ wxT("StemPlot"), XO("Stem plot") }
|
||||
};
|
||||
static const size_t nChoicesSampleDisplay = WXSIZEOF( choicesSampleDisplay );
|
||||
static const int intChoicesSampleDisplay[] = {
|
||||
(int) WaveTrackViewConstants::LinearInterpolate,
|
||||
(int) WaveTrackViewConstants::StemPlot
|
||||
};
|
||||
static_assert(
|
||||
nChoicesSampleDisplay == WXSIZEOF(intChoicesSampleDisplay), "size mismatch" );
|
||||
|
||||
static const size_t defaultChoiceSampleDisplay = 1;
|
||||
|
||||
static EnumSetting sampleDisplaySetting{
|
||||
static EnumSetting< WaveTrackViewConstants::SampleDisplay >
|
||||
sampleDisplaySetting{
|
||||
wxT("/GUI/SampleViewChoice"),
|
||||
choicesSampleDisplay, nChoicesSampleDisplay, defaultChoiceSampleDisplay,
|
||||
{
|
||||
{ wxT("ConnectDots"), XO("Connect dots") },
|
||||
{ wxT("StemPlot"), XO("Stem plot") }
|
||||
},
|
||||
1, // StemPlot
|
||||
|
||||
intChoicesSampleDisplay,
|
||||
// for migrating old preferences:
|
||||
{
|
||||
WaveTrackViewConstants::LinearInterpolate,
|
||||
WaveTrackViewConstants::StemPlot
|
||||
},
|
||||
wxT("/GUI/SampleView")
|
||||
};
|
||||
|
||||
WaveTrackViewConstants::SampleDisplay TracksPrefs::SampleViewChoice()
|
||||
{
|
||||
return (WaveTrackViewConstants::SampleDisplay) sampleDisplaySetting.ReadInt();
|
||||
return sampleDisplaySetting.ReadEnum();
|
||||
}
|
||||
|
||||
//////////
|
||||
static const EnumValueSymbol choicesZoom[] = {
|
||||
static const std::initializer_list<EnumValueSymbol> choicesZoom{
|
||||
{ wxT("FitToWidth"), XO("Fit to Width") },
|
||||
{ wxT("ZoomToSelection"), XO("Zoom to Selection") },
|
||||
{ wxT("ZoomDefault"), XO("Zoom Default") },
|
||||
|
@ -172,8 +165,7 @@ static const EnumValueSymbol choicesZoom[] = {
|
|||
{ wxT("FourPixelsPerSample"), XO("4 Pixels per Sample") },
|
||||
{ wxT("MaxZoom"), XO("Max Zoom") },
|
||||
};
|
||||
static const size_t nChoicesZoom = WXSIZEOF( choicesZoom );
|
||||
static const int intChoicesZoom[] = {
|
||||
static auto enumChoicesZoom = {
|
||||
WaveTrackViewConstants::kZoomToFit,
|
||||
WaveTrackViewConstants::kZoomToSelection,
|
||||
WaveTrackViewConstants::kZoomDefault,
|
||||
|
@ -190,36 +182,35 @@ static const int intChoicesZoom[] = {
|
|||
WaveTrackViewConstants::kZoom4To1,
|
||||
WaveTrackViewConstants::kMaxZoom,
|
||||
};
|
||||
static_assert( nChoicesZoom == WXSIZEOF(intChoicesZoom), "size mismatch" );
|
||||
|
||||
static const size_t defaultChoiceZoom1 = 2; // kZoomDefault
|
||||
|
||||
static EnumSetting zoom1Setting{
|
||||
static EnumSetting< WaveTrackViewConstants::ZoomPresets > zoom1Setting{
|
||||
wxT("/GUI/ZoomPreset1Choice"),
|
||||
choicesZoom, nChoicesZoom, defaultChoiceZoom1,
|
||||
choicesZoom,
|
||||
2, // kZoomDefault
|
||||
|
||||
intChoicesZoom,
|
||||
// for migrating old preferences:
|
||||
enumChoicesZoom,
|
||||
wxT("/GUI/ZoomPreset1")
|
||||
};
|
||||
|
||||
static const size_t defaultChoiceZoom2 = 13; // kZoom4To1
|
||||
|
||||
static EnumSetting zoom2Setting{
|
||||
static EnumSetting< WaveTrackViewConstants::ZoomPresets > zoom2Setting{
|
||||
wxT("/GUI/ZoomPreset2Choice"),
|
||||
choicesZoom, nChoicesZoom, defaultChoiceZoom2,
|
||||
choicesZoom,
|
||||
13, // kZoom4To1
|
||||
|
||||
intChoicesZoom,
|
||||
// for migrating old preferences:
|
||||
enumChoicesZoom,
|
||||
wxT("/GUI/ZoomPreset2")
|
||||
};
|
||||
|
||||
WaveTrackViewConstants::ZoomPresets TracksPrefs::Zoom1Choice()
|
||||
{
|
||||
return (WaveTrackViewConstants::ZoomPresets) zoom1Setting.ReadInt();
|
||||
return zoom1Setting.ReadEnum();
|
||||
}
|
||||
|
||||
WaveTrackViewConstants::ZoomPresets TracksPrefs::Zoom2Choice()
|
||||
{
|
||||
return (WaveTrackViewConstants::ZoomPresets) zoom2Setting.ReadInt();
|
||||
return zoom2Setting.ReadEnum();
|
||||
}
|
||||
|
||||
//////////
|
||||
|
|
|
@ -79,7 +79,7 @@ enum {
|
|||
void WaveformPrefs::Populate()
|
||||
{
|
||||
// Reuse the same choices and codes as for Interface prefs
|
||||
GUIPrefs::GetRangeChoices(&mRangeChoices, &mRangeCodes);
|
||||
GUIPrefs::GetRangeChoices(nullptr, &mRangeChoices, &mRangeCodes);
|
||||
|
||||
//------------------------- Main section --------------------
|
||||
// Now construct the GUI itself.
|
||||
|
|
|
@ -111,7 +111,7 @@ void WaveformSettings::ConvertToEnumeratedDBRange()
|
|||
{
|
||||
// Assumes the codes are in ascending sequence.
|
||||
wxArrayStringEx codes;
|
||||
GUIPrefs::GetRangeChoices(NULL, &codes);
|
||||
GUIPrefs::GetRangeChoices(nullptr, nullptr, &codes);
|
||||
int ii = 0;
|
||||
for (int nn = codes.size(); ii < nn; ++ii) {
|
||||
long value = 0;
|
||||
|
@ -125,7 +125,7 @@ void WaveformSettings::ConvertToEnumeratedDBRange()
|
|||
void WaveformSettings::ConvertToActualDBRange()
|
||||
{
|
||||
wxArrayStringEx codes;
|
||||
GUIPrefs::GetRangeChoices(NULL, &codes);
|
||||
GUIPrefs::GetRangeChoices(nullptr, nullptr, &codes);
|
||||
long value = 0;
|
||||
codes[std::max(0, std::min((int)(codes.size()) - 1, dBRange))]
|
||||
.ToLong(&value);
|
||||
|
|
|
@ -46,6 +46,7 @@
|
|||
#include "../HelpText.h"
|
||||
#include "../Prefs.h"
|
||||
#include "../wxFileNameWrapper.h"
|
||||
#include "../prefs/GUIPrefs.h"
|
||||
|
||||
#ifdef USE_ALPHA_MANUAL
|
||||
const wxString HelpSystem::HelpHostname = wxT("alphamanual.audacityteam.org");
|
||||
|
@ -248,8 +249,8 @@ void HelpSystem::ShowHelp(wxWindow *parent,
|
|||
// these next lines are for legacy cfg files (pre 2.0) where we had different modes
|
||||
if( (HelpMode == wxT("Standard")) || (HelpMode == wxT("InBrowser")) )
|
||||
{
|
||||
HelpMode = wxT("Local");
|
||||
gPrefs->Write(wxT("/GUI/Help"), HelpMode);
|
||||
HelpMode = GUIManualLocation.Default().Internal();
|
||||
GUIManualLocation.Write(HelpMode);
|
||||
gPrefs->Flush();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue