From ffadd64a56433c43e26912a99e3fcbcf758081b0 Mon Sep 17 00:00:00 2001 From: Paul Licameli Date: Tue, 6 Mar 2018 15:28:05 -0500 Subject: [PATCH 1/6] Define MacroCommandsCatalog to associate friendly and internal names... ... friendly names are still English only. Not yet localized, but ought to be. --- src/BatchCommandDialog.cpp | 35 ++++----- src/BatchCommandDialog.h | 7 +- src/BatchCommands.cpp | 125 ++++++++++++++++++++------------ src/BatchCommands.h | 37 ++++++++-- src/BatchProcessDialog.cpp | 18 ++--- src/BatchProcessDialog.h | 4 +- src/commands/CommandManager.cpp | 4 +- src/commands/CommandManager.h | 4 +- 8 files changed, 142 insertions(+), 92 deletions(-) diff --git a/src/BatchCommandDialog.cpp b/src/BatchCommandDialog.cpp index 8c97e995a..2947903df 100644 --- a/src/BatchCommandDialog.cpp +++ b/src/BatchCommandDialog.cpp @@ -62,6 +62,7 @@ MacroCommandDialog::MacroCommandDialog(wxWindow * parent, wxWindowID id): wxDialogWrapper(parent, id, _("Select Command"), wxDefaultPosition, wxDefaultSize, wxCAPTION | wxRESIZE_BORDER) + , mCatalog( GetActiveProject() ) { SetLabel(_("Select Command")); // Provide visual label SetName(_("Select Command")); // Provide audible label @@ -123,12 +124,11 @@ void MacroCommandDialog::PopulateOrExchange(ShuttleGui &S) void MacroCommandDialog::PopulateCommandList() { - mCommandNames = MacroCommands::GetAllCommands(); - mChoices->DeleteAllItems(); - for (size_t ii = 0, size = mCommandNames.size(); ii < size; ++ii) + long ii = 0; + for ( const auto &entry : mCatalog ) // insert the user-facing string - mChoices->InsertItem( ii, std::get<0>( mCommandNames[ii] ) ); + mChoices->InsertItem( ii++, entry.friendly /* .Translation() */ ); } void MacroCommandDialog::ValidateChoices() @@ -159,21 +159,21 @@ void MacroCommandDialog::OnHelp(wxCommandEvent & WXUNUSED(event)) void MacroCommandDialog::OnItemSelected(wxListEvent &event) { - const auto &command = mCommandNames[ event.GetIndex() ]; + const auto &command = mCatalog[ event.GetIndex() ]; EffectManager & em = EffectManager::Get(); - PluginID ID = em.GetEffectByIdentifier( std::get<1>( command )); + PluginID ID = em.GetEffectByIdentifier( command.internal ); // If ID is empty, then the effect wasn't found, in which case, the user must have // selected one of the "special" commands. mEditParams->Enable(!ID.IsEmpty()); mUsePreset->Enable(em.HasPresets(ID)); - if (std::get<0>( command ) == mCommand->GetValue()) + if ( command.friendly == mCommand->GetValue() ) return; - mCommand->SetValue(std::get<0> (command)); - mInternalCommandName = std::get<1>( command ); + mCommand->SetValue(command.friendly); + mInternalCommandName = command.internal; wxString params = MacroCommands::GetCurrentParamsFor(mInternalCommandName); if (params.IsEmpty()) @@ -183,7 +183,7 @@ void MacroCommandDialog::OnItemSelected(wxListEvent &event) // Cryptic command and category. // Later we can put help information there, perhaps. - mDetails->SetValue( mInternalCommandName + "\r\n" + std::get<2>(command) ); + mDetails->SetValue( mInternalCommandName + "\r\n" + command.category ); mParameters->SetValue(params); } @@ -211,19 +211,20 @@ void MacroCommandDialog::OnUsePreset(wxCommandEvent & WXUNUSED(event)) void MacroCommandDialog::SetCommandAndParams(const wxString &Command, const wxString &Params) { - auto item = make_iterator_range(mCommandNames).index_if( - [&](const CommandName &name){ return Command == std::get<1>( name); } - ); + auto iter = mCatalog.ByCommandId( Command ); mParameters->SetValue( Params ); mInternalCommandName = Command; - if (item < 0) + if (iter == mCatalog.end()) + // Expose an internal name to the user in default of any friendly name + // -- AVOID THIS! mCommand->SetValue( Command ); else { - mCommand->SetValue( std::get<0>( mCommandNames[item]) ); - mDetails->SetValue( std::get<1>(mCommandNames[item]) + "\r\n" + std::get<2>(mCommandNames[item]) ); - mChoices->SetItemState(item, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED); + mCommand->SetValue( iter->friendly /* .Translation() */ ); + mDetails->SetValue( iter->internal + "\r\n" + iter->category ); + mChoices->SetItemState(iter - mCatalog.begin(), + wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED); EffectManager & em = EffectManager::Get(); PluginID ID = em.GetEffectByIdentifier(Command); diff --git a/src/BatchCommandDialog.h b/src/BatchCommandDialog.h index b111a02bf..815e77259 100644 --- a/src/BatchCommandDialog.h +++ b/src/BatchCommandDialog.h @@ -12,7 +12,6 @@ #ifndef __AUDACITY_MACRO_COMMAND_DIALOG__ #define __AUDACITY_MACRO_COMMAND_DIALOG__ -#include "MemoryX.h" #include #include @@ -26,6 +25,8 @@ #include #include +#include "BatchCommands.h" + class wxWindow; class wxCheckBox; class wxChoice; @@ -70,9 +71,7 @@ class MacroCommandDialog final : public wxDialogWrapper { wxString mInternalCommandName; - using CommandName = std::tuple; - using CommandNameVector = std::vector; - CommandNameVector mCommandNames; + const MacroCommandsCatalog mCatalog; DECLARE_EVENT_TABLE() }; diff --git a/src/BatchCommands.cpp b/src/BatchCommands.cpp index a9b5ae004..6096e44ec 100644 --- a/src/BatchCommands.cpp +++ b/src/BatchCommands.cpp @@ -274,19 +274,19 @@ bool MacroCommands::RenameMacro(const wxString & oldchain, const wxString & newc } // Gets all commands that are valid for this mode. -auto MacroCommands::GetAllCommands() -> CommandNameVector +MacroCommandsCatalog::MacroCommandsCatalog( const AudacityProject *project ) { - CommandNameVector commands; - - AudacityProject *project = GetActiveProject(); if (!project) - return commands; + return; // CLEANSPEECH remnant + Entries commands; for( const auto &command : SpecialCommands ) - commands.push_back( - CommandName( command.first, command.second, _("Special Command") ) - ); + commands.push_back( { + command.first /* .Translation() */, + command.second, + _("Special Command") + } ); // end CLEANSPEECH remnant @@ -298,72 +298,103 @@ auto MacroCommands::GetAllCommands() -> CommandNameVector { auto command = em.GetCommandIdentifier(plug->GetID()); if (!command.IsEmpty()) - commands.push_back( - CommandName( - plug->GetUntranslatedName(), // plug->GetTranslatedName(), - command, - plug->GetPluginType() == PluginTypeEffect ? - _("Effect") : _("Menu Command (With Parameters)") - ) - ); + commands.push_back( { + plug->GetUntranslatedName(), // plug->GetTranslatedName(), + command, + plug->GetPluginType() == PluginTypeEffect ? + _("Effect") : _("Menu Command (With Parameters)") + } ); plug = pm.GetNextPlugin(PluginTypeEffect|PluginTypeAudacityCommand); } } - CommandManager * mManager = project->GetCommandManager(); + auto mManager = project->GetCommandManager(); wxArrayString mLabels; wxArrayString mNames; mLabels.Clear(); mNames.Clear(); mManager->GetAllCommandLabels(mLabels, false); mManager->GetAllCommandNames(mNames, false); + + const bool english = wxGetLocale()->GetCanonicalName().StartsWith(wxT("en")); + for(size_t i=0; i(a) < std::get<0>(b); } - ); + // PRL: What exactly should happen if first members of pairs are not unique? + // I'm not sure, but at least I can sort stably for a better defined result, + // keeping specials before effects and menu items, and lastly commands. + auto less = + [](const Entry &a, const Entry &b) { return a.friendly < b.friendly; }; + std::stable_sort(commands.begin(), commands.end(), less); - // JKC: Gave up on trying to use std::unique on this. - CommandNameVector uniqueCommands; - unsigned size = commands.size(); - wxString oldName = ""; - for( unsigned i = 0; i < size; ++i ) - { - if( std::get<0>( commands[i] ) != oldName ) - uniqueCommands.push_back( commands[i] ); - oldName = std::get<0>( commands[i] ); - } - return uniqueCommands; + // Now uniquify by friendly name + auto equal = + [](const Entry &a, const Entry &b) { return a.friendly == b.friendly; }; + std::unique_copy( + commands.begin(), commands.end(), std::back_inserter(mCommands), equal); } +// binary search +auto MacroCommandsCatalog::ByFriendlyName( const wxString &friendlyName ) const + -> Entries::const_iterator +{ + const auto less = [&](const Entry &entryA, const Entry &entryB) + { return entryA.friendly < entryB.friendly; }; + auto range = std::equal_range( + begin(), end(), Entry{ friendlyName }, less); + if (range.first != range.second) { + wxASSERT_MSG( range.first + 1 == range.second, + "Non-unique user-visible command name" ); + return range.first; + } + else + return end(); +} + +// linear search +auto MacroCommandsCatalog::ByCommandId( const wxString &commandId ) const + -> Entries::const_iterator +{ + // Maybe this too should have a uniqueness check? + return std::find_if( begin(), end(), + [&](const Entry &entry){ return entry.internal == commandId; }); +} + + + wxString MacroCommands::GetCurrentParamsFor(const wxString & command) { const PluginID & ID = EffectManager::Get().GetEffectByIdentifier(command); diff --git a/src/BatchCommands.h b/src/BatchCommands.h index 3e0ebcec7..162dda698 100644 --- a/src/BatchCommands.h +++ b/src/BatchCommands.h @@ -12,7 +12,6 @@ #ifndef __AUDACITY_BATCH_COMMANDS_DIALOG__ #define __AUDACITY_BATCH_COMMANDS_DIALOG__ -#include "MemoryX.h" #include #include @@ -20,7 +19,37 @@ class Effect; class CommandContext; +class AudacityProject; +class MacroCommandsCatalog { +public: + // A triple of user-visible name, internal string identifier and type/help string. + struct Entry { + wxString friendly; + wxString internal; + wxString category; + }; + using Entries = std::vector; + + MacroCommandsCatalog( const AudacityProject *project ); + + // binary search + Entries::const_iterator ByFriendlyName( const wxString &friendlyName ) const; + // linear search + Entries::const_iterator ByCommandId( const wxString &commandId ) const; + + // Lookup by position as sorted by friendly name + const Entry &operator[] ( size_t index ) const { return mCommands[index]; } + + Entries::const_iterator begin() const { return mCommands.begin(); } + Entries::const_iterator end() const { return mCommands.end(); } + +private: + // Sorted by friendly name + Entries mCommands; +}; + +// Stores information for one chain class MacroCommands final { public: // constructors and destructors @@ -44,12 +73,6 @@ class MacroCommands final { static wxArrayString GetNames(); static wxArrayString GetNamesOfDefaultMacros(); - // A triple of user-visible name, internal string identifier and type/help string. - using CommandName = std::tuple; - using CommandNameVector = std::vector; - // Result is sorted by user-visible name - static CommandNameVector GetAllCommands(); - static wxString GetCurrentParamsFor(const wxString & command); static wxString PromptForParamsFor(const wxString & command, const wxString & params, wxWindow *parent); static wxString PromptForPresetFor(const wxString & command, const wxString & params, wxWindow *parent); diff --git a/src/BatchProcessDialog.cpp b/src/BatchProcessDialog.cpp index 26349b772..8d67cd46b 100644 --- a/src/BatchProcessDialog.cpp +++ b/src/BatchProcessDialog.cpp @@ -525,6 +525,7 @@ enum { /// Constructor MacrosWindow::MacrosWindow(wxWindow * parent, bool bExpanded): ApplyMacroDialog(parent, true) + , mCatalog( GetActiveProject() ) { mbExpanded = bExpanded; SetLabel(_("Manage Macros")); // Provide visual label @@ -547,8 +548,6 @@ MacrosWindow::~MacrosWindow() /// Creates the dialog and its contents. void MacrosWindow::Populate() { - mCommandNames = MacroCommands::GetAllCommands(); - //------------------------- Main section -------------------- ShuttleGui S(this, eIsCreating); PopulateOrExchange(S); @@ -690,14 +689,13 @@ void MacrosWindow::PopulateList() /// Add one item into mList void MacrosWindow::AddItem(const wxString &Action, const wxString &Params) { - // Translate internal command name to a friendly form - auto item = make_iterator_range(mCommandNames).index_if( - [&](const CommandName &name){ return Action == std::get<1>(name); } - ); - auto friendlyName = item >= 0 - ? // wxGetTranslation - std::get<0>( mCommandNames[item] ) - : Action; + auto entry = mCatalog.ByCommandId(Action); + auto friendlyName = entry != mCatalog.end() + ? entry->friendly /* .Translation() */ + : + // Expose an internal name to the user in default of any friendly name + // -- AVOID THIS! + Action; int i = mList->GetItemCount(); diff --git a/src/BatchProcessDialog.h b/src/BatchProcessDialog.h index 1470957e0..627bad156 100644 --- a/src/BatchProcessDialog.h +++ b/src/BatchProcessDialog.h @@ -142,9 +142,7 @@ private: int mSelectedCommand; bool mChanged; - using CommandName = std::tuple; - using CommandNameVector = std::vector; - CommandNameVector mCommandNames; + const MacroCommandsCatalog mCatalog; DECLARE_EVENT_TABLE() }; diff --git a/src/commands/CommandManager.cpp b/src/commands/CommandManager.cpp index 84195f04a..dbc44dfc3 100644 --- a/src/commands/CommandManager.cpp +++ b/src/commands/CommandManager.cpp @@ -1650,7 +1650,7 @@ void CommandManager::GetCategories(wxArrayString &cats) } void CommandManager::GetAllCommandNames(wxArrayString &names, - bool includeMultis) + bool includeMultis) const { for(const auto &entry : mCommandList) { if ( entry->isEffect ) @@ -1663,7 +1663,7 @@ void CommandManager::GetAllCommandNames(wxArrayString &names, } void CommandManager::GetAllCommandLabels(wxArrayString &names, - bool includeMultis) + bool includeMultis) const { for(const auto &entry : mCommandList) { // This is fetching commands from the menus, for use as batch commands. diff --git a/src/commands/CommandManager.h b/src/commands/CommandManager.h index 2bf98ddd1..7668506f2 100644 --- a/src/commands/CommandManager.h +++ b/src/commands/CommandManager.h @@ -278,8 +278,8 @@ class AUDACITY_DLL_API CommandManager final : public XMLTagHandler // void GetCategories(wxArrayString &cats); - void GetAllCommandNames(wxArrayString &names, bool includeMultis); - void GetAllCommandLabels(wxArrayString &labels, bool includeMultis); + void GetAllCommandNames(wxArrayString &names, bool includeMultis) const; + void GetAllCommandLabels(wxArrayString &labels, bool includeMultis) const; void GetAllCommandData( wxArrayString &names, std::vector &keys, From bc773e02d336cd5d23e4e8eaa2b9896e47a45c5e Mon Sep 17 00:00:00 2001 From: Paul Licameli Date: Wed, 7 Mar 2018 14:48:11 -0500 Subject: [PATCH 2/6] Supply some missing translation in Macros dialogs... ... The "Set" prompt for checkboxes; Strings in Choice controls, which had been declared translatable with XO, but the translations not yet used. This can be tested in Ukrainian locale now, for editing parameters of commands like Select or Drag, but be aware that even uk.po is not up to date for all recent changes in the Manage Macros dialog itself. --- src/Internat.h | 15 +++++++++++++++ src/ShuttleGui.cpp | 3 ++- src/commands/DragCommand.cpp | 2 +- src/commands/GetInfoCommand.cpp | 4 ++-- src/commands/GetTrackInfoCommand.cpp | 2 +- src/commands/ScreenshotCommand.cpp | 4 ++-- src/commands/SelectCommand.cpp | 3 ++- src/commands/SetClipCommand.cpp | 2 +- src/commands/SetTrackInfoCommand.cpp | 8 ++++---- src/effects/nyquist/Nyquist.cpp | 11 +---------- src/effects/nyquist/Nyquist.h | 2 -- 11 files changed, 31 insertions(+), 25 deletions(-) diff --git a/src/Internat.h b/src/Internat.h index 7a57c117f..39d56f744 100644 --- a/src/Internat.h +++ b/src/Internat.h @@ -167,4 +167,19 @@ private: #define UTF8CTOWX(X) wxString((X), wxConvUTF8) #define LAT1CTOWX(X) wxString((X), wxConvISO8859_1) +inline wxArrayString LocalizedStrings(const wxString strings[], size_t nStrings) +{ + wxArrayString results; + std::transform( strings, strings + nStrings, std::back_inserter(results), + GetCustomTranslation ); + return results; +} + +inline wxArrayString LocalizedStrings(const wxArrayString &strings) +{ + if (strings.empty()) + return {}; + return LocalizedStrings( &strings[0], strings.size() ); +} + #endif diff --git a/src/ShuttleGui.cpp b/src/ShuttleGui.cpp index 4ec4aa5f8..43b210f49 100644 --- a/src/ShuttleGui.cpp +++ b/src/ShuttleGui.cpp @@ -2077,7 +2077,8 @@ ShuttleGui & ShuttleGui::Id(int id ) } ShuttleGui & ShuttleGui::Optional( bool &bVar ){ - TieCheckBox( "Set", bVar ); + /* i18n-hint verb, imperative */ + TieCheckBox( _("Set"), bVar ); return *this; }; diff --git a/src/commands/DragCommand.cpp b/src/commands/DragCommand.cpp index 15d223ea1..5b2350d19 100644 --- a/src/commands/DragCommand.cpp +++ b/src/commands/DragCommand.cpp @@ -61,7 +61,7 @@ bool DragCommand::DefineParams( ShuttleParams & S ){ void DragCommand::PopulateOrExchange(ShuttleGui & S) { - wxArrayString coords( nCoordTypes, kCoordTypeStrings ); + auto coords = LocalizedStrings( kCoordTypeStrings, nCoordTypes ); S.AddSpace(0, 5); diff --git a/src/commands/GetInfoCommand.cpp b/src/commands/GetInfoCommand.cpp index 19401616d..935d330c3 100644 --- a/src/commands/GetInfoCommand.cpp +++ b/src/commands/GetInfoCommand.cpp @@ -94,8 +94,8 @@ bool GetInfoCommand::DefineParams( ShuttleParams & S ){ void GetInfoCommand::PopulateOrExchange(ShuttleGui & S) { - wxArrayString types( nTypes, kTypes ); - wxArrayString formats( nFormats, kFormats ); + auto types = LocalizedStrings( kTypes, nTypes ); + auto formats = LocalizedStrings( kFormats, nFormats ); S.AddSpace(0, 5); S.StartMultiColumn(2, wxALIGN_CENTER); diff --git a/src/commands/GetTrackInfoCommand.cpp b/src/commands/GetTrackInfoCommand.cpp index b8eb5e9a6..e0480e313 100644 --- a/src/commands/GetTrackInfoCommand.cpp +++ b/src/commands/GetTrackInfoCommand.cpp @@ -48,7 +48,7 @@ bool GetTrackInfoCommand::DefineParams( ShuttleParams & S ){ void GetTrackInfoCommand::PopulateOrExchange(ShuttleGui & S) { - wxArrayString types( nTypes, kTypes ); + auto types = LocalizedStrings( kTypes, nTypes ); S.AddSpace(0, 5); S.StartMultiColumn(2, wxALIGN_CENTER); diff --git a/src/commands/ScreenshotCommand.cpp b/src/commands/ScreenshotCommand.cpp index f500ee719..2593b6853 100644 --- a/src/commands/ScreenshotCommand.cpp +++ b/src/commands/ScreenshotCommand.cpp @@ -148,8 +148,8 @@ bool ScreenshotCommand::DefineParams( ShuttleParams & S ){ void ScreenshotCommand::PopulateOrExchange(ShuttleGui & S) { - wxArrayString whats(nCaptureWhats, kCaptureWhatStrings); - wxArrayString backs(nBackgrounds, kBackgroundStrings); + auto whats = LocalizedStrings(kCaptureWhatStrings, nCaptureWhats); + auto backs = LocalizedStrings(kBackgroundStrings, nBackgrounds); S.AddSpace(0, 5); S.StartMultiColumn(2, wxALIGN_CENTER); diff --git a/src/commands/SelectCommand.cpp b/src/commands/SelectCommand.cpp index d0ab58331..86c98e08d 100644 --- a/src/commands/SelectCommand.cpp +++ b/src/commands/SelectCommand.cpp @@ -107,6 +107,7 @@ bool SelectFrequenciesCommand::Apply(const CommandContext & context){ const int nModes =3; static const wxString kModes[nModes] = { + /* i18n-hint verb, imperative */ XO("Set"), XO("Add"), XO("Remove") @@ -123,7 +124,7 @@ bool SelectTracksCommand::DefineParams( ShuttleParams & S ){ void SelectTracksCommand::PopulateOrExchange(ShuttleGui & S) { - wxArrayString modes( nModes, kModes ); + auto modes = LocalizedStrings( kModes, nModes ); S.AddSpace(0, 5); S.StartMultiColumn(3, wxALIGN_CENTER); diff --git a/src/commands/SetClipCommand.cpp b/src/commands/SetClipCommand.cpp index 731976edf..e45a71b3a 100644 --- a/src/commands/SetClipCommand.cpp +++ b/src/commands/SetClipCommand.cpp @@ -61,7 +61,7 @@ bool SetClipCommand::DefineParams( ShuttleParams & S ){ void SetClipCommand::PopulateOrExchange(ShuttleGui & S) { - wxArrayString colours( nColours, kColourStrings ); + auto colours = LocalizedStrings( kColourStrings, nColours ); S.AddSpace(0, 5); diff --git a/src/commands/SetTrackInfoCommand.cpp b/src/commands/SetTrackInfoCommand.cpp index d71e1e781..50a2aaed6 100644 --- a/src/commands/SetTrackInfoCommand.cpp +++ b/src/commands/SetTrackInfoCommand.cpp @@ -123,10 +123,10 @@ bool SetTrackCommand::DefineParams( ShuttleParams & S ){ void SetTrackCommand::PopulateOrExchange(ShuttleGui & S) { - wxArrayString colours( nColours, kColourStrings ); - wxArrayString displays( nDisplayTypes, kDisplayTypeStrings ); - wxArrayString scales( nScaleTypes, kScaleTypeStrings ); - wxArrayString vzooms( nZoomTypes, kZoomTypeStrings ); + auto colours = LocalizedStrings( kColourStrings, nColours ); + auto displays = LocalizedStrings( kDisplayTypeStrings, nDisplayTypes ); + auto scales = LocalizedStrings( kScaleTypeStrings, nScaleTypes ); + auto vzooms = LocalizedStrings( kZoomTypeStrings, nZoomTypes ); S.AddSpace(0, 5); diff --git a/src/effects/nyquist/Nyquist.cpp b/src/effects/nyquist/Nyquist.cpp index 97ffb9cae..fc59305de 100644 --- a/src/effects/nyquist/Nyquist.cpp +++ b/src/effects/nyquist/Nyquist.cpp @@ -94,15 +94,6 @@ enum static const wxChar *KEY_Version = wxT("Version"); static const wxChar *KEY_Command = wxT("Command"); -wxArrayString NyqControl::GetTranslatedChoices() const -{ - wxArrayString results; - std::transform( - choices.begin(), choices.end(), std::back_inserter(results), - GetCustomTranslation); - return results; -} - /////////////////////////////////////////////////////////////////////////////// // // NyquistEffect @@ -2405,7 +2396,7 @@ void NyquistEffect::BuildEffectWindow(ShuttleGui & S) { S.AddSpace(10, 10); - const wxArrayString &choices = ctrl.GetTranslatedChoices(); + auto choices = LocalizedStrings(ctrl.choices); S.Id(ID_Choice + i).AddChoice( {}, wxT(""), &choices); } else diff --git a/src/effects/nyquist/Nyquist.h b/src/effects/nyquist/Nyquist.h index d336584ae..dab4c5b12 100644 --- a/src/effects/nyquist/Nyquist.h +++ b/src/effects/nyquist/Nyquist.h @@ -53,8 +53,6 @@ public: //NyqControl( NyqControl && ) = default; //NyqControl &operator = ( NyqControl && ) = default; - wxArrayString GetTranslatedChoices() const; - int type; wxString var; wxString name; From 4cb2ec6fa0a2c7059997a1cd4c6666ef64fcd34c Mon Sep 17 00:00:00 2001 From: Paul Licameli Date: Wed, 7 Mar 2018 17:05:09 -0500 Subject: [PATCH 3/6] Fix missing i18n of some new prompts --- src/BatchProcessDialog.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/BatchProcessDialog.cpp b/src/BatchProcessDialog.cpp index 8d67cd46b..885e27c2d 100644 --- a/src/BatchProcessDialog.cpp +++ b/src/BatchProcessDialog.cpp @@ -633,7 +633,7 @@ void MacrosWindow::PopulateOrExchange(ShuttleGui & S) S.StartVerticalLay(wxALIGN_TOP, 0); { - S.AddPrompt( "Command" ); + S.AddPrompt( _("Command") ); S.Id(InsertButtonID).AddButton(_("&Insert"), wxALIGN_LEFT); S.Id(EditButtonID).AddButton(_("&Edit..."), wxALIGN_LEFT); S.Id(DeleteButtonID).AddButton(_("De&lete"), wxALIGN_LEFT); @@ -642,7 +642,7 @@ void MacrosWindow::PopulateOrExchange(ShuttleGui & S) mDefaults = S.Id(DefaultsButtonID).AddButton(_("De&faults")); S.AddSpace( 30 ); - S.AddPrompt( "Macro" ); + S.AddPrompt( _("Macro") ); S.Id(AddButtonID).AddButton(_("&New")); mRemove = S.Id(RemoveButtonID).AddButton(_("Remo&ve")); mRename = S.Id(RenameButtonID).AddButton(_("&Rename...")); From bf4c8eff639cc3d9e3db34a40548000594ed2f87 Mon Sep 17 00:00:00 2001 From: Paul Licameli Date: Wed, 7 Mar 2018 17:36:45 -0500 Subject: [PATCH 4/6] Fix another neglected i18n --- src/commands/SetProjectCommand.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/commands/SetProjectCommand.cpp b/src/commands/SetProjectCommand.cpp index 0a5181d7f..a8b130bdb 100644 --- a/src/commands/SetProjectCommand.cpp +++ b/src/commands/SetProjectCommand.cpp @@ -46,7 +46,7 @@ void SetProjectCommand::PopulateOrExchange(ShuttleGui & S) S.StartMultiColumn(3, wxALIGN_CENTER); { S.Optional( bHasName ).TieTextBox( _("Name:"), mName ); - S.TieCheckBox( "Resize:", bHasSizing ); + S.TieCheckBox( _("Resize:"), bHasSizing ); } S.EndMultiColumn(); S.StartMultiColumn(2, wxALIGN_CENTER); From 9298ac575d53eeadf2e54f3a949fa3253a7993f0 Mon Sep 17 00:00:00 2001 From: Steve Daulton Date: Thu, 8 Mar 2018 03:46:55 +0000 Subject: [PATCH 5/6] Fix Linux build --- src/Internat.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Internat.h b/src/Internat.h index 39d56f744..732db661d 100644 --- a/src/Internat.h +++ b/src/Internat.h @@ -16,6 +16,8 @@ #include #include +#include + #ifndef IN_RC class wxString; From 77f720b0c8df5b038b9afbc56426efcd7d8ca8f0 Mon Sep 17 00:00:00 2001 From: Paul Licameli Date: Wed, 7 Mar 2018 23:42:57 -0500 Subject: [PATCH 6/6] Show friendly names of commands in message boxes... ... With spaces in the English; maybe later they will localize --- src/BatchCommands.cpp | 58 ++++++++++++++++++++----------- src/BatchCommands.h | 21 +++++++---- src/BatchProcessDialog.cpp | 6 ++-- src/BatchProcessDialog.h | 5 +-- src/commands/BatchEvalCommand.cpp | 12 +++++-- 5 files changed, 69 insertions(+), 33 deletions(-) diff --git a/src/BatchCommands.cpp b/src/BatchCommands.cpp index 6096e44ec..9bce05d3f 100644 --- a/src/BatchCommands.cpp +++ b/src/BatchCommands.cpp @@ -595,9 +595,11 @@ bool MacroCommands::WriteMp3File( const wxString & Name, int bitrate ) // and think again. // ======= IMPORTANT ======== // CLEANSPEECH remnant -bool MacroCommands::ApplySpecialCommand(int WXUNUSED(iCommand), const wxString & command,const wxString & params) +bool MacroCommands::ApplySpecialCommand( + int WXUNUSED(iCommand), const wxString &friendlyCommand, + const wxString & command, const wxString & params) { - if (ReportAndSkip(command, params)) + if (ReportAndSkip(friendlyCommand, params)) return true; AudacityProject *project = GetActiveProject(); @@ -674,15 +676,19 @@ bool MacroCommands::ApplySpecialCommand(int WXUNUSED(iCommand), const wxString & return false; #endif } - AudacityMessageBox(wxString::Format(_("Command %s not implemented yet"),command)); + AudacityMessageBox( + wxString::Format(_("Command %s not implemented yet"), friendlyCommand)); return false; } // end CLEANSPEECH remnant -bool MacroCommands::ApplyEffectCommand(const PluginID & ID, const wxString & command, const wxString & params, const CommandContext & Context) +bool MacroCommands::ApplyEffectCommand( + const PluginID & ID, const wxString &friendlyCommand, + const wxString & command, const wxString & params, + const CommandContext & Context) { //Possibly end processing here, if in batch-debug - if( ReportAndSkip(command, params)) + if( ReportAndSkip(friendlyCommand, params)) return true; const PluginDescriptor *plug = PluginManager::Get().GetPlugin(ID); @@ -723,7 +729,9 @@ bool MacroCommands::ApplyEffectCommand(const PluginID & ID, const wxString & com return res; } -bool MacroCommands::ApplyCommand(const wxString & command, const wxString & params, CommandContext const * pContext) +bool MacroCommands::ApplyCommand( const wxString &friendlyCommand, + const wxString & command, const wxString & params, + CommandContext const * pContext) { unsigned int i; @@ -731,7 +739,7 @@ bool MacroCommands::ApplyCommand(const wxString & command, const wxString & para // CLEANSPEECH remnant for( i = 0; i < sizeof(SpecialCommands)/sizeof(*SpecialCommands); ++i ) { if( command.IsSameAs( SpecialCommands[i].second, false) ) - return ApplySpecialCommand( i, command, params ); + return ApplySpecialCommand( i, friendlyCommand, command, params ); } // end CLEANSPEECH remnant @@ -740,9 +748,11 @@ bool MacroCommands::ApplyCommand(const wxString & command, const wxString & para if (!ID.empty()) { if( pContext ) - return ApplyEffectCommand(ID, command, params, *pContext); + return ApplyEffectCommand( + ID, friendlyCommand, command, params, *pContext); const CommandContext context( *GetActiveProject() ); - return ApplyEffectCommand(ID, command, params, context); + return ApplyEffectCommand( + ID, friendlyCommand, command, params, context); } AudacityProject *project = GetActiveProject(); @@ -751,7 +761,7 @@ bool MacroCommands::ApplyCommand(const wxString & command, const wxString & para if( pManager->HandleTextualCommand( command, *pContext, AlwaysEnabledFlag, AlwaysEnabledFlag ) ) return true; pContext->Status( wxString::Format( - _("Your batch command of %s was not recognized."), command )); + _("Your batch command of %s was not recognized."), friendlyCommand )); return false; } else @@ -763,12 +773,13 @@ bool MacroCommands::ApplyCommand(const wxString & command, const wxString & para AudacityMessageBox( wxString::Format( - _("Your batch command of %s was not recognized."), command )); + _("Your batch command of %s was not recognized."), friendlyCommand )); return false; } -bool MacroCommands::ApplyCommandInBatchMode(const wxString & command, const wxString ¶ms) +bool MacroCommands::ApplyCommandInBatchMode( const wxString &friendlyCommand, + const wxString & command, const wxString ¶ms) { AudacityProject *project = GetActiveProject(); @@ -779,14 +790,15 @@ bool MacroCommands::ApplyCommandInBatchMode(const wxString & command, const wxSt project->SetShowId3Dialog(prevShowMode); } ); - return ApplyCommand( command, params ); + return ApplyCommand( friendlyCommand, command, params ); } static int MacroReentryCount = 0; // ApplyMacro returns true on success, false otherwise. // Any error reporting to the user in setting up the chain // has already been done. -bool MacroCommands::ApplyMacro(const wxString & filename) +bool MacroCommands::ApplyMacro( + const MacroCommandsCatalog &catalog, const wxString & filename) { // Check for reentrant ApplyMacro commands. // We'll allow 1 level of reentry, but not more. @@ -814,12 +826,17 @@ bool MacroCommands::ApplyMacro(const wxString & filename) mAbort = false; size_t i = 0; - for (; i < mCommandMacro.GetCount(); i++) { - if (!ApplyCommandInBatchMode(mCommandMacro[i], mParamsMacro[i]) || mAbort) + for (; i < mCommandMacro.size(); i++) { + const auto &command = mCommandMacro[i]; + auto iter = catalog.ByCommandId(command); + auto friendly = (iter == catalog.end()) + ? command // Expose internal name to user, in default of a better one! + : iter->friendly; + if (!ApplyCommandInBatchMode(friendly, command, mParamsMacro[i]) || mAbort) break; } - res = (i == mCommandMacro.GetCount()); + res = (i == mCommandMacro.size()); if (!res) return false; @@ -887,7 +904,8 @@ void MacroCommands::ResetMacro() // ReportAndSkip() is a diagnostic function that avoids actually // applying the requested effect if in batch-debug mode. -bool MacroCommands::ReportAndSkip(const wxString & command, const wxString & params) +bool MacroCommands::ReportAndSkip( + const wxString & friendlyCommand, const wxString & params) { int bDebug; gPrefs->Read(wxT("/Batch/Debug"), &bDebug, false); @@ -897,12 +915,12 @@ bool MacroCommands::ReportAndSkip(const wxString & command, const wxString & par //TODO: Add a cancel button to these, and add the logic so that we can abort. if( params != wxT("") ) { - AudacityMessageBox( wxString::Format(_("Apply %s with parameter(s)\n\n%s"),command, params), + AudacityMessageBox( wxString::Format(_("Apply %s with parameter(s)\n\n%s"),friendlyCommand, params), _("Test Mode")); } else { - AudacityMessageBox( wxString::Format(_("Apply %s"),command), + AudacityMessageBox( wxString::Format(_("Apply %s"), friendlyCommand), _("Test Mode")); } return true; diff --git a/src/BatchCommands.h b/src/BatchCommands.h index 162dda698..61388df2e 100644 --- a/src/BatchCommands.h +++ b/src/BatchCommands.h @@ -55,12 +55,21 @@ class MacroCommands final { // constructors and destructors MacroCommands(); public: - bool ApplyMacro(const wxString & filename = wxT("")); - bool ApplyCommand( const wxString & command, const wxString & params, CommandContext const * pContext=NULL ); - bool ApplyCommandInBatchMode(const wxString & command, const wxString ¶ms); - bool ApplySpecialCommand(int iCommand, const wxString & command,const wxString & params); - bool ApplyEffectCommand(const PluginID & ID, const wxString & command, const wxString & params, const CommandContext & Context); - bool ReportAndSkip( const wxString & command, const wxString & params ); + bool ApplyMacro( const MacroCommandsCatalog &catalog, + const wxString & filename = wxT("")); + bool ApplyCommand( const wxString &friendlyCommand, + const wxString & command, const wxString & params, + CommandContext const * pContext=NULL ); + bool ApplyCommandInBatchMode( const wxString &friendlyCommand, + const wxString & command, const wxString ¶ms); + bool ApplySpecialCommand( + int iCommand, const wxString &friendlyCommand, + const wxString & command, const wxString & params); + bool ApplyEffectCommand( + const PluginID & ID, const wxString &friendlyCommand, + const wxString & command, + const wxString & params, const CommandContext & Context); + bool ReportAndSkip( const wxString & friendlyCommand, const wxString & params ); void AbortBatch(); // Utility functions for the special commands. diff --git a/src/BatchProcessDialog.cpp b/src/BatchProcessDialog.cpp index 885e27c2d..0441634aa 100644 --- a/src/BatchProcessDialog.cpp +++ b/src/BatchProcessDialog.cpp @@ -73,6 +73,7 @@ ApplyMacroDialog::ApplyMacroDialog(wxWindow * parent, bool bInherited): wxDialogWrapper(parent, wxID_ANY, _("Apply Macro"), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER) + , mCatalog( GetActiveProject() ) { //AudacityProject * p = GetActiveProject(); mAbort = false; @@ -269,7 +270,7 @@ void ApplyMacroDialog::ApplyMacroToProject( int iMacro, bool bHasGui ) { wxWindowDisabler wd(&activityWin); success = GuardedCall< bool >( - [this]{ return mMacroCommands.ApplyMacro(); } ); + [this]{ return mMacroCommands.ApplyMacro(mCatalog); } ); } if( !bHasGui ) @@ -436,7 +437,7 @@ void ApplyMacroDialog::OnApplyToFiles(wxCommandEvent & WXUNUSED(event)) project->Import(files[i]); project->ZoomAfterImport(nullptr); project->OnSelectAll(*project); - if (!mMacroCommands.ApplyMacro()) + if (!mMacroCommands.ApplyMacro(mCatalog)) return false; if (!activityWin.IsShown() || mAbort) @@ -525,7 +526,6 @@ enum { /// Constructor MacrosWindow::MacrosWindow(wxWindow * parent, bool bExpanded): ApplyMacroDialog(parent, true) - , mCatalog( GetActiveProject() ) { mbExpanded = bExpanded; SetLabel(_("Manage Macros")); // Provide visual label diff --git a/src/BatchProcessDialog.h b/src/BatchProcessDialog.h index 627bad156..997f58754 100644 --- a/src/BatchProcessDialog.h +++ b/src/BatchProcessDialog.h @@ -74,6 +74,9 @@ class ApplyMacroDialog : public wxDialogWrapper { bool mbExpanded; wxString mActiveMacro; +protected: + const MacroCommandsCatalog mCatalog; + DECLARE_EVENT_TABLE() }; @@ -142,8 +145,6 @@ private: int mSelectedCommand; bool mChanged; - const MacroCommandsCatalog mCatalog; - DECLARE_EVENT_TABLE() }; diff --git a/src/commands/BatchEvalCommand.cpp b/src/commands/BatchEvalCommand.cpp index ac43cefac..9787619a1 100644 --- a/src/commands/BatchEvalCommand.cpp +++ b/src/commands/BatchEvalCommand.cpp @@ -39,21 +39,29 @@ OldStyleCommandPointer BatchEvalCommandType::Create(std::unique_ptrfriendly; // Create a Batch that will have just one command in it... MacroCommands Batch; - bool bResult = Batch.ApplyCommand(cmdName, cmdParams, &context); + bool bResult = Batch.ApplyCommand(friendly, cmdName, cmdParams, &context); // Relay messages, if any. wxString Message = Batch.GetMessage(); if( !Message.IsEmpty() )