18#define wxLOG_COMPONENT "MacroCommands"
24#include <wx/datetime.h>
27#include <wx/textfile.h>
62 for(
size_t i = 0;i<defaults.size();i++){
63 wxString
name = defaults[i];
94 AddToMacro(
wxT(
"Select"),
wxT(
"Start=\"0\" End=\"1\" RelativeTo=\"ProjectEnd\"") );
139 wxFD_OPEN | wxRESIZE_BORDER,
144 return wxEmptyString;
147 wxFileName check(
fn);
148 check.SetPath(
name.GetPath());
149 if (check.FileExists())
152 XO(
"Macro %s already exists. Would you like to replace it?").
Format(check.GetName()),
156 return wxEmptyString;
164 wxTextFile tf(
name.GetFullPath());
168 if (!tf.IsOpened()) {
170 return wxEmptyString;
174 int lines = tf.GetLineCount();
176 for (
int i = 0; i < lines; i++) {
179 int splitAt = tf[i].Find(
wxT(
':'));
185 wxString cmd = tf[i].Left(splitAt).Strip(wxString::both);
186 wxString parm = tf[i].Mid(splitAt + 1).Strip(wxString::trailing);
202 return name.GetName();
218 wxFD_SAVE | wxFD_OVERWRITE_PROMPT | wxRESIZE_BORDER,
223 return wxEmptyString;
230 wxTextFile tf(
name.GetFullPath());
240 if (!tf.IsOpened()) {
242 return wxEmptyString;
250 for (
int i = 0; i < lines; i++) {
261 return name.GetName();
270 wxTextFile tf(
name.GetFullPath());
282 auto result = wxRemoveFile(
name.GetFullPath());
286 wxRemoveFile(oldPath.GetFullPath());
298 return wxRenameFile(oname.GetFullPath(), nname.GetFullPath());
315 if (!command.empty())
316 commands.push_back( {
317 { command, plug.GetSymbol().Msgid() },
319 XO(
"Effect") :
XO(
"Menu Command (With Parameters)")
327 std::vector<bool> vExcludeFromMacros;
330 manager.GetAllCommandLabels(mLabels, vExcludeFromMacros,
true);
331 manager.GetAllCommandNames(mNames,
true);
333 const bool english = wxGetLocale()->GetCanonicalName().StartsWith(
wxT(
"en"));
335 for(
size_t i=0; i<mNames.size(); i++) {
336 if( !vExcludeFromMacros[i] ){
337 auto label = mLabels[i];
351 squashed.Replace(
" ",
"" );
356 suffix = squashed.length() < wxMin( 18, mNames[i].GET().length());
372 if (mNames[i] ==
"Close")
381 XO(
"Menu Command (No Parameters)")
393 b.name.StrippedTranslation(); };
394 std::stable_sort(commands.begin(), commands.end(), less);
400 b.name.StrippedTranslation(); };
402 commands.begin(), commands.end(), std::back_inserter(
mCommands), equal);
407 -> Entries::const_iterator
409 const auto less = [](
const Entry &entryA,
const Entry &entryB)
411 entryB.name.StrippedTranslation(); };
412 auto range = std::equal_range(
415 if (range.first != range.second) {
416 wxASSERT_MSG( range.first + 1 == range.second,
417 "Non-unique user-visible command name" );
426 -> Entries::const_iterator
429 return std::find_if(
begin(),
end(),
431 {
return entry.name.Internal() == commandId; });
440 return wxEmptyString;
452 return wxEmptyString;
468 return wxEmptyString;
488 static_cast<void>(command);
509 XO(
"\"%s\" requires one or more tracks to be selected.").
Format(friendlyCommand));
551 ID, friendlyCommand, command,
params, *pContext);
554 ID, friendlyCommand, command,
params, context);
563 pContext->
Status( wxString::Format(
564 _(
"Your batch command of %s was not recognized."), friendlyCommand.
Translation() ));
576 XO(
"Your batch command of %s was not recognized.")
577 .
Format( friendlyCommand ) );
593 auto cleanup =
finally( [&] {
631 longDesc =
XO(
"Applied Macro");
632 shortDesc =
XO(
"Apply Macro");
636 longDesc =
XO(
"Applied Macro '%s'").Format(
name);
637 shortDesc =
XO(
"Apply '%s'").Format(
name);
652 if (macroReentryCount == 1 && !res && proj) {
657 history.RollbackState();
662 history.PopState( elem.
state ); } );
663 undoManager.AbandonRedo();
675 wxLogLevel prevLevel = wxLog::GetComponentLevel(
"");
677 wxLog::SetComponentLevel(
"", wxLOG_FatalError);
685 const auto friendly = (iter == catalog.
end())
694 before = wxTimeSpan(0, 0, 0, wxGetUTCTimeMillis());
700 auto after = wxTimeSpan(0, 0, 0, wxGetUTCTimeMillis());
701 wxLogMessage(
wxT(
"Macro line #%ld took %s : %s:%s"),
703 (after - before).
Format(
wxT(
"%H:%M:%S.%l")),
714 wxLog::SetComponentLevel(
"", prevLevel);
782 XO(
"Apply %s with parameter(s)\n\n%s")
789 XO(
"Apply %s").
Format( friendlyCommand ),
797 static bool done =
false;
811 wxDir::GetAllFiles(oldDir, &files,
wxT(
"*.txt"), wxDIR_FILES);
816 for (
const auto &file : files) {
817 auto name = wxFileName{file}.GetFullName();
818 newDir.SetFullName(
name);
819 const auto newPath = newDir.GetFullPath();
820 if (!wxFileExists(newPath))
838 for (i = 0; i < files.size(); i++) {
840 names.push_back(ff.GetName());
867 splitAt =
str.Find(
wxT(
':'));
872 command =
str.Mid(0, splitAt);
873 param =
str.Mid(splitAt + 1);
880 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
const TranslatableString name
std::vector< CommandID > CommandIDs
ValueRestorer< T > valueRestorer(T &var)
inline functions provide convenient parameter type deduction
IteratorRange< Iterator > make_iterator_range(const Iterator &i1, const Iterator &i2)
@ PluginTypeAudacityCommand
audacity::BasicSettings * gPrefs
static const AttachedProjectObjects::RegisteredFactory manager
EffectReverbSettings preset
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
static CommandManager & Get(AudacityProject &project)
const wxString StrippedTranslation() const
EffectManager is the class that handles effects and effect categories.
CommandID GetCommandIdentifier(const PluginID &ID)
BatchProcessingScope SetBatchProcessing(const PluginID &ID)
Begin a scope that ends when the returned object is destroyed.
static EffectManager & Get()
wxString GetPreset(const PluginID &ID, const wxString ¶ms, wxWindow *parent)
wxString GetEffectParameters(const PluginID &ID)
const PluginID & GetEffectByIdentifier(const CommandID &strTarget)
FILES_API const FileType TextFiles
Entries::const_iterator ByCommandId(const CommandID &commandId) const
Entries::const_iterator end() const
std::vector< Entry > Entries
MacroCommandsCatalog(const AudacityProject *project)
Entries::const_iterator ByFriendlyName(const TranslatableString &friendlyName) const
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=NULL)
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)
wxString WriteMacro(const wxString ¯o, wxWindow *parent=nullptr)
bool ApplyMacro(const MacroCommandsCatalog &catalog, const wxString &filename={})
static wxString PromptForParamsFor(const CommandID &command, const wxString ¶ms, wxWindow &parent)
bool AddMacro(const wxString ¯o)
MacroCommands(AudacityProject &project)
wxString ReadMacro(const wxString ¯o, wxWindow *parent=nullptr)
void RestoreMacro(const wxString &name)
AudacityProject & mProject
bool ApplyCommandInBatchMode(const TranslatableString &friendlyCommand, const CommandID &command, const wxString ¶ms, CommandContext const *pContext=NULL)
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
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(CommandManager &commandManager, const CommandID &Str, const CommandContext &context, CommandFlag flags, bool alwaysEnabled)
AUDACITY_DLL_API bool DoEffect(const PluginID &ID, const CommandContext &context, unsigned flags)
'Repeat Last Effect'.
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()
auto end(const Ptr< Type, BaseDeleter > &p)
Enables range-for.
auto begin(const Ptr< Type, BaseDeleter > &p)
Enables range-for.
bool SelectAllIfNoneAndAllowed(AudacityProject &project)
ComponentInterfaceSymbol name
Holds one item with description and time range for the UndoManager.