17#define wxLOG_COMPONENT "MacroCommands"
23#include <wx/datetime.h>
28#include <wx/textfile.h>
65 for(
size_t i = 0;i<defaults.size();i++){
66 wxString
name = defaults[i];
97 AddToMacro(
wxT(
"Select"),
wxT(
"Start=\"0\" End=\"1\" RelativeTo=\"ProjectEnd\"") );
142 wxFD_OPEN | wxRESIZE_BORDER,
147 return wxEmptyString;
150 wxFileName check(
fn);
151 check.SetPath(
name.GetPath());
152 if (check.FileExists())
155 XO(
"Macro %s already exists. Would you like to replace it?").
Format(check.GetName()),
159 return wxEmptyString;
167 wxTextFile tf(
name.GetFullPath());
171 if (!tf.IsOpened()) {
173 return wxEmptyString;
177 int lines = tf.GetLineCount();
179 for (
int i = 0; i < lines; i++) {
182 int splitAt = tf[i].Find(
wxT(
':'));
188 wxString cmd = tf[i].Left(splitAt).Strip(wxString::both);
189 wxString parm = tf[i].Mid(splitAt + 1).Strip(wxString::trailing);
205 return name.GetName();
221 wxFD_SAVE | wxFD_OVERWRITE_PROMPT | wxRESIZE_BORDER,
226 return wxEmptyString;
233 wxTextFile tf(
name.GetFullPath());
243 if (!tf.IsOpened()) {
245 return wxEmptyString;
253 for (
int i = 0; i < lines; i++) {
264 return name.GetName();
273 wxTextFile tf(
name.GetFullPath());
285 auto result = wxRemoveFile(
name.GetFullPath());
289 wxRemoveFile(oldPath.GetFullPath());
301 return wxRenameFile(oname.GetFullPath(), nname.GetFullPath());
318 if (!command.empty())
319 commands.push_back( {
320 { command, plug.GetSymbol().Msgid() },
322 XO(
"Effect") :
XO(
"Menu Command (With Parameters)")
330 std::vector<bool> vExcludeFromMacros;
333 manager.GetAllCommandLabels(mLabels, vExcludeFromMacros,
true);
334 manager.GetAllCommandNames(mNames,
true);
336 const bool english = wxGetLocale()->GetCanonicalName().StartsWith(
wxT(
"en"));
338 for(
size_t i=0; i<mNames.size(); i++) {
339 if( !vExcludeFromMacros[i] ){
340 auto label = mLabels[i];
354 squashed.Replace(
" ",
"" );
359 suffix = squashed.length() < wxMin( 18, mNames[i].GET().length());
375 if (mNames[i] ==
"Close")
384 XO(
"Menu Command (No Parameters)")
396 b.name.StrippedTranslation(); };
397 std::stable_sort(commands.begin(), commands.end(), less);
403 b.name.StrippedTranslation(); };
405 commands.begin(), commands.end(), std::back_inserter(
mCommands), equal);
410 -> Entries::const_iterator
412 const auto less = [](
const Entry &entryA,
const Entry &entryB)
414 entryB.name.StrippedTranslation(); };
415 auto range = std::equal_range(
418 if (range.first != range.second) {
419 wxASSERT_MSG( range.first + 1 == range.second,
420 "Non-unique user-visible command name" );
429 -> Entries::const_iterator
432 return std::find_if(
begin(),
end(),
434 {
return entry.name.Internal() == commandId; });
439 -> Entries::const_iterator
443 {
return entry.name.Translation() == translation; });
451 return wxEmptyString;
462 return wxEmptyString;
471 std::shared_ptr<EffectInstance>& pInstance) ->
bool {
476 *std::make_shared<SimpleEffectSettingsAccess>(
settings),
480 ID,
project, std::move(dialogInvoker)))
491 return wxEmptyString;
497 const wxString&
preset) -> std::optional<wxString> {
501 dlg.SetSize(dlg.GetMinSize());
502 dlg.CenterOnParent();
528 static_cast<void>(command);
549 XO(
"\"%s\" requires one or more tracks to be selected.").
Format(friendlyCommand));
589 ID, friendlyCommand, command,
params, *pContext);
592 ID, friendlyCommand, command,
params, context);
600 pContext->
Status( wxString::Format(
601 _(
"Your batch command of %s was not recognized."), friendlyCommand.
Translation() ));
613 XO(
"Your batch command of %s was not recognized.")
614 .
Format( friendlyCommand ) );
631 auto cleanup =
finally( [&] {
669 longDesc =
XO(
"Applied Macro");
670 shortDesc =
XO(
"Apply Macro");
674 longDesc =
XO(
"Applied Macro '%s'").Format(
name);
675 shortDesc =
XO(
"Apply '%s'").Format(
name);
690 if (macroReentryCount == 1 && !res && proj) {
695 history.RollbackState();
700 history.PopState( elem.
state ); } );
701 undoManager.AbandonRedo();
713 wxLogLevel prevLevel = wxLog::GetComponentLevel(
"");
715 wxLog::SetComponentLevel(
"", wxLOG_FatalError);
723 const auto friendly = (iter == catalog.
end())
732 before = wxTimeSpan(0, 0, 0, wxGetUTCTimeMillis());
738 auto after = wxTimeSpan(0, 0, 0, wxGetUTCTimeMillis());
739 wxLogMessage(
wxT(
"Macro line #%ld took %s : %s:%s"),
741 (after - before).
Format(
wxT(
"%H:%M:%S.%l")),
752 wxLog::SetComponentLevel(
"", prevLevel);
820 XO(
"Apply %s with parameter(s)\n\n%s")
827 XO(
"Apply %s").
Format( friendlyCommand ),
835 static bool done =
false;
849 wxDir::GetAllFiles(oldDir, &files,
wxT(
"*.txt"), wxDIR_FILES);
854 for (
const auto &file : files) {
855 auto name = wxFileName{file}.GetFullName();
856 newDir.SetFullName(
name);
857 const auto newPath = newDir.GetFullPath();
858 if (!wxFileExists(newPath))
876 for (i = 0; i < files.size(); i++) {
878 names.push_back(ff.GetName());
905 splitAt =
str.Find(
wxT(
':'));
910 command =
str.Mid(0, splitAt);
911 param =
str.Mid(splitAt + 1);
918 return command +
wxT(
": ") + param;
R GuardedCall(const F1 &body, const F2 &handler=F2::Default(), F3 delayedHandler=DefaultDelayedHandlerAction) noexcept(noexcept(handler(std::declval< AudacityException * >())) &&noexcept(handler(nullptr)) &&noexcept(std::function< void(AudacityException *)>{std::move(delayedHandler)}))
Execute some code on any thread; catch any AudacityException; enqueue error report on the main thread...
int AudacityMessageBox(const TranslatableString &message, const TranslatableString &caption, long style, wxWindow *parent, int x, int y)
static const auto MP3Conversion
static const auto FadeEnds
static int MacroReentryCount
constexpr CommandFlag AlwaysEnabledFlag
EffectDistortionSettings params
std::vector< CommandID > CommandIDs
static ProjectFileIORegistry::AttributeWriterEntry entry
IteratorRange< Iterator > make_iterator_range(const Iterator &i1, const Iterator &i2)
ValueRestorer< T > valueRestorer(T &var)
inline functions provide convenient parameter type deduction
@ PluginTypeAudacityCommand
audacity::BasicSettings * gPrefs
AUDACITY_DLL_API wxFrame & GetProjectFrame(AudacityProject &project)
Get the top-level window associated with the project (as a wxFrame only, when you do not need to use ...
accessors for certain important windows associated with each project
static const AttachedProjectObjects::RegisteredFactory manager
FilePath SelectFile(FileNames::Operation op, const TranslatableString &message, const FilePath &default_path, const FilePath &default_filename, const FileExtension &default_extension, const FileTypes &fileTypes, int flags, wxWindow *parent)
declares abstract base class Track, TrackList, and iterators over TrackList
static Settings & settings()
TranslatableString Verbatim(wxString str)
Require calls to the one-argument constructor to go through this distinct global function name.
std::vector< TranslatableString > TranslatableStrings
The top-level handle to an Audacity project. It serves as a source of events that other objects can b...
CommandContext provides additional information to an 'Apply()' command. It provides the project,...
virtual void Status(const wxString &message, bool bFlush=false) const
AudacityProject & project
static CommandManager & Get(AudacityProject &project)
void UpdateMenus(bool checkActive=true)
const wxString StrippedTranslation() const
bool PromptUser(const PluginID &ID, AudacityProject &project, DialogInvoker dialogInvoker)
Shows an effect or command dialog so the user can specify settings for later.
wxString GetEffectParameters(const PluginID &ID)
static EffectAndCommandPluginManager & Get()
BatchProcessingScope SetBatchProcessing(const PluginID &ID)
Begin a scope that ends when the returned object is destroyed.
Base class for many of the effects in Audacity.
bool IsBatchProcessing() const override
EffectManager is the class that handles effects and effect categories.
std::function< std::optional< wxString >(EffectPlugin &, const wxString &preset)> EffectPresetDialog
wxString GetPreset(const PluginID &ID, const wxString ¶ms, EffectPresetDialog)
static EffectManager & Get()
Factory of instances of an effect.
wxString GetSelected() const
void SetSelected(const wxString &parms)
virtual int ShowHostInterface(EffectBase &plugin, wxWindow &parent, const EffectDialogFactory &factory, std::shared_ptr< EffectInstance > &pInstance, EffectSettingsAccess &access, bool forceModal=false)
FILES_API const FileType TextFiles
Entries::const_iterator ByCommandId(const CommandID &commandId) const
Entries::const_iterator end() const
Entries::const_iterator ByTranslation(const wxString &translation) const
std::vector< Entry > Entries
MacroCommandsCatalog(const AudacityProject *project)
Entries::const_iterator ByFriendlyName(const TranslatableString &friendlyName) const
static wxString PromptForParamsFor(const CommandID &command, const wxString ¶ms, AudacityProject &project)
static wxArrayStringEx GetNamesOfDefaultMacros()
static wxString PromptForPresetFor(const CommandID &command, const wxString ¶ms, wxWindow *parent)
bool IsFixed(const wxString &name)
void AddToMacro(const CommandID &command, int before=-1)
bool ApplyEffectCommand(const PluginID &ID, const TranslatableString &friendlyCommand, const CommandID &command, const wxString ¶ms, const CommandContext &Context)
bool ApplyCommand(const TranslatableString &friendlyCommand, const CommandID &command, const wxString ¶ms, CommandContext const *pContext=nullptr)
wxString GetParams(int index)
void DeleteFromMacro(int index)
wxArrayString mParamsMacro
wxString Join(const wxString &command, const wxString ¶m)
static wxString GetCurrentParamsFor(const CommandID &command)
static void MigrateLegacyChains()
bool RenameMacro(const wxString &oldmacro, const wxString &newmacro)
CommandID GetCommand(int index)
static wxArrayString GetNames()
bool DeleteMacro(const wxString &name)
bool ReportAndSkip(const TranslatableString &friendlyCommand, const wxString ¶ms)
void Split(const wxString &str, wxString &command, wxString ¶m)
bool ApplyCommandInBatchMode(const TranslatableString &friendlyCommand, const CommandID &command, const wxString ¶ms, CommandContext const *pContext=nullptr)
AudacityProject & GetProject()
wxString WriteMacro(const wxString ¯o, wxWindow *parent=nullptr)
bool ApplyMacro(const MacroCommandsCatalog &catalog, const wxString &filename={})
bool AddMacro(const wxString ¯o)
MacroCommands(AudacityProject &project)
wxString ReadMacro(const wxString ¯o, wxWindow *parent=nullptr)
void RestoreMacro(const wxString &name)
AudacityProject & mProject
PluginType GetPluginType() const
PluginManager maintains a list of all plug ins. That covers modules, effects, generators,...
Range PluginsOfType(int type)
const PluginDescriptor * GetPlugin(const PluginID &ID) const
const PluginID & GetByCommandIdentifier(const CommandID &strTarget)
CommandID GetCommandIdentifier(const PluginID &ID) const
static PluginManager & Get()
void PushState(const TranslatableString &desc, const TranslatableString &shortDesc)
void ModifyState(bool bWantsAutoSave)
static ProjectHistory & Get(AudacityProject &project)
static ProjectSettings & Get(AudacityProject &project)
Holds a msgid for the translation catalog; may also bind format arguments.
TranslatableString & Strip(unsigned options=MenuCodes) &
TranslatableString & Join(TranslatableString arg, const wxString &separator={}) &
Append another translatable string.
wxString Translation() const
TranslatableString Stripped(unsigned options=MenuCodes) const
non-mutating, constructs another TranslatableString object
static UndoManager & Get(AudacityProject &project)
virtual bool Read(const wxString &key, bool *value) const =0
Extend wxArrayString with move operations and construction and insertion fromstd::initializer_list.
AUDACITY_DLL_API bool DoAudacityCommand(const PluginID &ID, const CommandContext &context, unsigned flags)
AUDACITY_DLL_API bool HandleTextualCommand(const CommandID &Str, const CommandContext &context, CommandFlag flags, bool alwaysEnabled)
bool DoEffect(const PluginID &ID, AudacityProject &project, unsigned flags)
AUDACITY_DLL_API DialogFactoryResults DialogFactory(wxWindow &parent, EffectBase &host, EffectUIServices &client, EffectSettingsAccess &access)
FILES_API FilePath MacroDir()
FILES_API bool DoCopyFile(const FilePath &file1, const FilePath &file2, bool overwrite=true)
FILES_API FilePath LegacyChainDir()
bool SelectAllIfNoneAndAllowed(AudacityProject &project)
const char * end(const char *str) noexcept
const char * begin(const char *str) noexcept
Externalized state of a plug-in.
ComponentInterfaceSymbol name
Holds one item with description and time range for the UndoManager.