2010-01-23 19:44:49 +00:00
|
|
|
/**********************************************************************
|
|
|
|
|
|
|
|
Audacity: A Digital Audio Editor
|
|
|
|
|
2018-03-03 19:08:23 +00:00
|
|
|
ApplyMacroDialog.cpp
|
2010-01-23 19:44:49 +00:00
|
|
|
|
|
|
|
Dominic Mazzoni
|
|
|
|
James Crook
|
|
|
|
|
|
|
|
*******************************************************************//*!
|
|
|
|
|
2018-03-03 19:08:23 +00:00
|
|
|
\class ApplyMacroDialog
|
|
|
|
\brief Shows progress in executing commands in MacroCommands.
|
2010-01-23 19:44:49 +00:00
|
|
|
|
|
|
|
*//*******************************************************************/
|
|
|
|
|
2021-05-09 15:16:56 +00:00
|
|
|
|
2015-06-18 14:24:36 +00:00
|
|
|
#include "BatchProcessDialog.h"
|
2010-01-23 19:44:49 +00:00
|
|
|
|
2019-03-23 18:28:37 +00:00
|
|
|
#include <wx/setup.h> // for wxUSE_* macros
|
2018-11-14 21:30:11 +00:00
|
|
|
|
|
|
|
#ifdef __WXMSW__
|
|
|
|
#include <wx/ownerdrw.h>
|
|
|
|
#endif
|
|
|
|
|
2010-01-23 19:44:49 +00:00
|
|
|
#include <wx/defs.h>
|
|
|
|
#include <wx/checkbox.h>
|
|
|
|
#include <wx/choice.h>
|
|
|
|
#include <wx/intl.h>
|
|
|
|
#include <wx/sizer.h>
|
|
|
|
#include <wx/statbox.h>
|
|
|
|
#include <wx/stattext.h>
|
|
|
|
#include <wx/textctrl.h>
|
|
|
|
#include <wx/listctrl.h>
|
|
|
|
#include <wx/radiobut.h>
|
|
|
|
#include <wx/button.h>
|
|
|
|
#include <wx/imaglist.h>
|
|
|
|
#include <wx/settings.h>
|
|
|
|
|
2020-12-02 04:03:23 +00:00
|
|
|
#include "Clipboard.h"
|
2015-06-18 14:24:36 +00:00
|
|
|
#include "ShuttleGui.h"
|
2018-10-16 20:45:26 +00:00
|
|
|
#include "Menus.h"
|
2010-01-23 19:44:49 +00:00
|
|
|
#include "Prefs.h"
|
|
|
|
#include "Project.h"
|
2019-06-08 20:05:22 +00:00
|
|
|
#include "ProjectFileManager.h"
|
2019-06-06 13:55:34 +00:00
|
|
|
#include "ProjectHistory.h"
|
2019-05-29 15:42:31 +00:00
|
|
|
#include "ProjectManager.h"
|
2019-05-29 16:05:22 +00:00
|
|
|
#include "ProjectWindow.h"
|
2019-06-21 23:38:38 +00:00
|
|
|
#include "SelectUtilities.h"
|
2010-01-23 19:44:49 +00:00
|
|
|
#include "commands/CommandManager.h"
|
|
|
|
#include "effects/Effect.h"
|
|
|
|
#include "../images/Arrow.xpm"
|
The fabled realtime effects...
I've made it where you can enable and disable via experimentals:
EXPERIMENTAL_REALTIME_EFFECTS
EXPERIMENTAL_EFFECTS_RACK
You will notice that, as of now, the only effects currently set up for
realtime are VSTs. Now that this is in, I will start converting the
rest.
As I start to convert the effects, the astute of you may notice that
they no longer directly access tracks or any "internal" Audacity
objects. This isolates the effects from changes in Audacity and makes
it much easier to add new ones.
Anyway, all 3 platforms can now display VST effects in graphical mode.
Yes, that means Linux too. There are quite a few VSTs for Linux if
you search for them.
The so-called "rack" definitely needs some discussion, work, and attention
from someone much better at graphics than me. I'm not really sure it should
stay in as-is. I'd originally planned for it to be simply a utility window
where you can store your (preconfigured) favorite effects. It should probably
revert back to that idea.
You may notice that this DOES include the API work I did. The realtime effects
were too tied to it and I didn't want to redo the whole thing. As I mentioned
elsewhere, the API stuff may or may not be very future proof.
So, let the critter complaints commence. I absolute KNOW there will be some.
(I know I'll be hearing from the Linux peeps pretty darn quickly. ;-))
2014-10-26 03:24:10 +00:00
|
|
|
#include "../images/Empty9x16.xpm"
|
2010-01-23 19:44:49 +00:00
|
|
|
#include "UndoManager.h"
|
|
|
|
|
|
|
|
#include "AllThemeResources.h"
|
|
|
|
|
2020-05-25 15:51:28 +00:00
|
|
|
#include "widgets/FileDialog/FileDialog.h"
|
2017-08-03 10:41:38 +00:00
|
|
|
#include "FileNames.h"
|
2010-01-23 19:44:49 +00:00
|
|
|
#include "import/Import.h"
|
2017-09-06 21:39:33 +00:00
|
|
|
#include "widgets/ErrorDialog.h"
|
2019-05-20 18:27:11 +00:00
|
|
|
#include "widgets/AudacityMessageBox.h"
|
2018-03-03 10:15:09 +00:00
|
|
|
#include "widgets/HelpSystem.h"
|
2010-01-23 19:44:49 +00:00
|
|
|
|
2018-07-30 10:34:00 +00:00
|
|
|
#if wxUSE_ACCESSIBILITY
|
|
|
|
#include "widgets/WindowAccessible.h"
|
|
|
|
#endif
|
|
|
|
|
2021-02-14 07:25:52 +00:00
|
|
|
#define MacrosPaletteTitle XO("Macros Palette")
|
|
|
|
#define ManageMacrosTitle XO("Manage Macros")
|
|
|
|
|
2021-03-22 17:45:54 +00:00
|
|
|
|
|
|
|
// Separate numerical range from the additional buttons
|
|
|
|
// in the expanded view (which start at 10,000).
|
2018-03-03 19:08:23 +00:00
|
|
|
#define MacrosListID 7001
|
2013-03-10 09:05:41 +00:00
|
|
|
#define CommandsListID 7002
|
|
|
|
#define ApplyToProjectID 7003
|
|
|
|
#define ApplyToFilesID 7004
|
2018-03-03 22:20:25 +00:00
|
|
|
#define ExpandID 7005
|
|
|
|
#define ShrinkID 7006
|
2010-01-23 19:44:49 +00:00
|
|
|
|
2018-03-03 19:08:23 +00:00
|
|
|
BEGIN_EVENT_TABLE(ApplyMacroDialog, wxDialogWrapper)
|
|
|
|
EVT_BUTTON(ApplyToProjectID, ApplyMacroDialog::OnApplyToProject)
|
|
|
|
EVT_BUTTON(ApplyToFilesID, ApplyMacroDialog::OnApplyToFiles)
|
|
|
|
EVT_BUTTON(wxID_CANCEL, ApplyMacroDialog::OnCancel)
|
2021-03-22 17:45:54 +00:00
|
|
|
EVT_BUTTON(wxID_CLOSE, ApplyMacroDialog::OnCancel)
|
2018-03-03 19:08:23 +00:00
|
|
|
EVT_BUTTON(wxID_HELP, ApplyMacroDialog::OnHelp)
|
2010-01-23 19:44:49 +00:00
|
|
|
END_EVENT_TABLE()
|
|
|
|
|
2019-05-22 00:16:20 +00:00
|
|
|
ApplyMacroDialog::ApplyMacroDialog(
|
|
|
|
wxWindow * parent, AudacityProject &project, bool bInherited):
|
2021-02-14 07:25:52 +00:00
|
|
|
wxDialogWrapper(parent, wxID_ANY, MacrosPaletteTitle,
|
2010-01-23 19:44:49 +00:00
|
|
|
wxDefaultPosition, wxDefaultSize,
|
|
|
|
wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)
|
2019-05-22 00:16:20 +00:00
|
|
|
, mMacroCommands{ project }
|
2019-05-22 11:07:57 +00:00
|
|
|
, mProject{ project }
|
|
|
|
, mCatalog( &project )
|
2010-01-23 19:44:49 +00:00
|
|
|
{
|
2018-03-01 17:54:08 +00:00
|
|
|
mAbort = false;
|
2018-03-03 22:20:25 +00:00
|
|
|
mbExpanded = false;
|
2018-03-01 17:54:08 +00:00
|
|
|
if( bInherited )
|
|
|
|
return;
|
2021-02-14 07:25:52 +00:00
|
|
|
SetLabel(MacrosPaletteTitle); // Provide visual label
|
|
|
|
SetName(MacrosPaletteTitle); // Provide audible label
|
2010-01-23 19:44:49 +00:00
|
|
|
Populate();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2018-03-03 19:08:23 +00:00
|
|
|
ApplyMacroDialog::~ApplyMacroDialog()
|
2010-01-23 19:44:49 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2018-03-03 19:08:23 +00:00
|
|
|
void ApplyMacroDialog::Populate()
|
2010-01-23 19:44:49 +00:00
|
|
|
{
|
|
|
|
//------------------------- Main section --------------------
|
|
|
|
ShuttleGui S(this, eIsCreating);
|
|
|
|
PopulateOrExchange(S);
|
|
|
|
// ----------------------- End of main section --------------
|
2018-03-03 19:08:23 +00:00
|
|
|
// Get and validate the currently active macro
|
|
|
|
mActiveMacro = gPrefs->Read(wxT("/Batch/ActiveMacro"), wxT(""));
|
|
|
|
// Go populate the macros list.
|
|
|
|
PopulateMacros();
|
2018-03-03 18:01:40 +00:00
|
|
|
|
|
|
|
Layout();
|
|
|
|
Fit();
|
2018-03-14 16:37:15 +00:00
|
|
|
wxSize sz = GetSize();
|
|
|
|
SetSizeHints( sz );
|
|
|
|
|
|
|
|
// Size and place window
|
|
|
|
SetSize(std::min(wxSystemSettings::GetMetric(wxSYS_SCREEN_X) * 3 / 4, sz.GetWidth()),
|
|
|
|
std::min(wxSystemSettings::GetMetric(wxSYS_SCREEN_Y) * 4 / 5, 400));
|
|
|
|
|
2018-03-03 18:01:40 +00:00
|
|
|
Center();
|
|
|
|
|
2018-03-03 19:08:23 +00:00
|
|
|
// Set the column size for the macros list.
|
2018-03-14 16:37:15 +00:00
|
|
|
sz = mMacros->GetClientSize();
|
2018-03-03 19:08:23 +00:00
|
|
|
mMacros->SetColumnWidth(0, sz.x);
|
2010-01-23 19:44:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Defines the dialog and does data exchange with it.
|
2018-03-03 19:08:23 +00:00
|
|
|
void ApplyMacroDialog::PopulateOrExchange(ShuttleGui &S)
|
2010-01-23 19:44:49 +00:00
|
|
|
{
|
2018-03-14 16:37:15 +00:00
|
|
|
/*i18n-hint: A macro is a sequence of commands that can be applied
|
|
|
|
* to one or more audio files.*/
|
2019-12-22 19:58:36 +00:00
|
|
|
S.StartStatic(XO("Select Macro"), 1);
|
2010-01-23 19:44:49 +00:00
|
|
|
{
|
2018-02-03 00:22:07 +00:00
|
|
|
mMacros = S.Id(MacrosListID).Prop(1)
|
2017-10-31 18:52:01 +00:00
|
|
|
.Style(wxSUNKEN_BORDER | wxLC_REPORT | wxLC_HRULES | wxLC_VRULES |
|
|
|
|
wxLC_SINGLE_SEL)
|
|
|
|
// i18n-hint: This is the heading for a column in the edit macros dialog
|
2019-12-23 22:57:45 +00:00
|
|
|
.AddListControlReportMode( { XO("Macro") } );
|
2018-03-14 16:37:15 +00:00
|
|
|
}
|
|
|
|
S.EndStatic();
|
2018-03-05 15:00:11 +00:00
|
|
|
|
2018-03-14 16:37:15 +00:00
|
|
|
S.StartHorizontalLay(wxEXPAND, 0);
|
|
|
|
{
|
2020-05-11 15:28:14 +00:00
|
|
|
S.AddPrompt( XXO("Apply Macro to:") );
|
2017-10-29 14:27:23 +00:00
|
|
|
wxButton* btn = S.Id(ApplyToProjectID)
|
|
|
|
.Name(XO("Apply macro to project"))
|
2020-05-11 15:28:14 +00:00
|
|
|
.AddButton(XXO("&Project"));
|
2018-07-30 10:58:16 +00:00
|
|
|
#if wxUSE_ACCESSIBILITY
|
2018-07-30 10:34:00 +00:00
|
|
|
// so that name can be set on a standard control
|
|
|
|
btn->SetAccessible(safenew WindowAccessible(btn));
|
2018-07-30 10:58:16 +00:00
|
|
|
#endif
|
2018-07-30 10:34:00 +00:00
|
|
|
|
2017-10-29 14:27:23 +00:00
|
|
|
btn = S.Id(ApplyToFilesID)
|
|
|
|
.Name(XO("Apply macro to files..."))
|
2020-05-11 15:28:14 +00:00
|
|
|
.AddButton(XXO("&Files..."));
|
2018-07-30 10:58:16 +00:00
|
|
|
#if wxUSE_ACCESSIBILITY
|
2018-07-30 10:34:00 +00:00
|
|
|
// so that name can be set on a standard control
|
|
|
|
btn->SetAccessible(safenew WindowAccessible(btn));
|
2018-07-30 10:58:16 +00:00
|
|
|
#endif
|
2018-03-14 16:37:15 +00:00
|
|
|
}
|
|
|
|
S.EndHorizontalLay();
|
2018-03-05 15:00:11 +00:00
|
|
|
|
2018-03-14 16:37:15 +00:00
|
|
|
S.StartHorizontalLay(wxEXPAND, 0);
|
|
|
|
{
|
2018-08-28 15:35:06 +00:00
|
|
|
/* i18n-hint: The Expand button makes the dialog bigger, with more in it */
|
2020-05-11 15:28:14 +00:00
|
|
|
mResize = S.Id(ExpandID).AddButton(XXO("&Expand"));
|
2020-08-22 12:41:18 +00:00
|
|
|
S.AddSpace( 10,10,1 );
|
2021-03-22 17:45:54 +00:00
|
|
|
S.AddStandardButtons( eCloseButton | eHelpButton);
|
2010-01-23 19:44:49 +00:00
|
|
|
}
|
2018-03-14 16:37:15 +00:00
|
|
|
S.EndHorizontalLay();
|
2018-03-03 18:01:40 +00:00
|
|
|
}
|
2010-01-23 19:44:49 +00:00
|
|
|
|
2018-03-03 19:08:23 +00:00
|
|
|
/// This clears and updates the contents of mMacros, the list of macros.
|
2018-03-17 15:38:09 +00:00
|
|
|
/// It has cut-and-paste code from PopulateList, and both should call
|
|
|
|
/// a shared function.
|
2018-03-03 19:08:23 +00:00
|
|
|
void ApplyMacroDialog::PopulateMacros()
|
2018-03-03 18:01:40 +00:00
|
|
|
{
|
2019-02-12 19:00:23 +00:00
|
|
|
auto names = mMacroCommands.GetNames();
|
2018-03-03 18:01:40 +00:00
|
|
|
int i;
|
|
|
|
|
2018-03-17 15:38:09 +00:00
|
|
|
int topItem = mMacros->GetTopItem();
|
2018-03-03 19:08:23 +00:00
|
|
|
mMacros->DeleteAllItems();
|
2019-02-12 00:10:48 +00:00
|
|
|
for (i = 0; i < (int)names.size(); i++) {
|
2018-03-03 19:08:23 +00:00
|
|
|
mMacros->InsertItem(i, names[i]);
|
2010-01-23 19:44:49 +00:00
|
|
|
}
|
|
|
|
|
2018-03-03 19:08:23 +00:00
|
|
|
int item = mMacros->FindItem(-1, mActiveMacro);
|
2018-03-17 15:38:09 +00:00
|
|
|
bool bFound = item >=0;
|
2010-01-23 19:44:49 +00:00
|
|
|
if (item == -1) {
|
|
|
|
item = 0;
|
2018-03-03 19:08:23 +00:00
|
|
|
mActiveMacro = mMacros->GetItemText(0);
|
2010-01-23 19:44:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Select the name in the list...this will fire an event.
|
2018-08-10 15:43:27 +00:00
|
|
|
mMacros->SetItemState(item, wxLIST_STATE_SELECTED | wxLIST_STATE_FOCUSED,
|
|
|
|
wxLIST_STATE_SELECTED | wxLIST_STATE_FOCUSED);
|
2010-01-23 19:44:49 +00:00
|
|
|
|
2018-03-17 15:38:09 +00:00
|
|
|
if( 0 <= topItem && topItem < (int)mMacros->GetItemCount())
|
|
|
|
{
|
|
|
|
// Workaround for scrolling being windows only.
|
|
|
|
// Try to scroll back to where we once were...
|
|
|
|
mMacros->EnsureVisible( (int)mMacros->GetItemCount() -1 );
|
|
|
|
mMacros->EnsureVisible( topItem );
|
|
|
|
// And then make sure whatever is selected is still visible...
|
|
|
|
if( bFound )
|
|
|
|
mMacros->EnsureVisible( item );
|
|
|
|
}
|
|
|
|
}
|
2010-01-23 19:44:49 +00:00
|
|
|
|
2018-03-03 19:08:23 +00:00
|
|
|
void ApplyMacroDialog::OnHelp(wxCommandEvent & WXUNUSED(event))
|
2018-03-03 10:15:09 +00:00
|
|
|
{
|
2021-06-06 16:18:35 +00:00
|
|
|
const auto &page = GetHelpPageName();
|
2018-03-03 10:15:09 +00:00
|
|
|
HelpSystem::ShowHelp(this, page, true);
|
|
|
|
}
|
|
|
|
|
2018-03-03 19:08:23 +00:00
|
|
|
void ApplyMacroDialog::OnApplyToProject(wxCommandEvent & WXUNUSED(event))
|
2010-01-23 19:44:49 +00:00
|
|
|
{
|
2018-03-03 19:08:23 +00:00
|
|
|
long item = mMacros->GetNextItem(-1,
|
2010-01-23 19:44:49 +00:00
|
|
|
wxLIST_NEXT_ALL,
|
|
|
|
wxLIST_STATE_SELECTED);
|
2018-03-02 21:56:24 +00:00
|
|
|
|
2010-01-23 19:44:49 +00:00
|
|
|
if (item == -1) {
|
2019-12-07 19:30:07 +00:00
|
|
|
AudacityMessageBox(XO("No macro selected"));
|
2010-01-23 19:44:49 +00:00
|
|
|
return;
|
|
|
|
}
|
2018-03-03 19:08:23 +00:00
|
|
|
ApplyMacroToProject( item );
|
2018-03-02 21:56:24 +00:00
|
|
|
}
|
|
|
|
|
2019-03-11 02:05:37 +00:00
|
|
|
CommandID ApplyMacroDialog::MacroIdOfName( const wxString & MacroName )
|
2018-03-04 19:02:22 +00:00
|
|
|
{
|
|
|
|
wxString Temp = MacroName;
|
|
|
|
Temp.Replace(" ","");
|
|
|
|
Temp = wxString( "Macro_" ) + Temp;
|
|
|
|
return Temp;
|
|
|
|
}
|
|
|
|
|
2018-03-04 19:16:30 +00:00
|
|
|
// Apply macro, given its ID.
|
2018-03-04 19:02:22 +00:00
|
|
|
// Does nothing if not found, rather than returning an error.
|
2019-03-11 02:05:37 +00:00
|
|
|
void ApplyMacroDialog::ApplyMacroToProject( const CommandID & MacroID, bool bHasGui )
|
2018-03-04 19:02:22 +00:00
|
|
|
{
|
2018-03-06 09:06:17 +00:00
|
|
|
for( int i=0;i<mMacros->GetItemCount();i++){
|
2018-03-04 19:02:22 +00:00
|
|
|
wxString name = mMacros->GetItemText(i);
|
|
|
|
if( MacroIdOfName( name ) == MacroID ){
|
|
|
|
ApplyMacroToProject( i, bHasGui );
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-03-04 19:16:30 +00:00
|
|
|
// Apply macro, given its number in the list.
|
2018-03-03 19:08:23 +00:00
|
|
|
void ApplyMacroDialog::ApplyMacroToProject( int iMacro, bool bHasGui )
|
2018-03-02 21:56:24 +00:00
|
|
|
{
|
2018-03-03 19:08:23 +00:00
|
|
|
wxString name = mMacros->GetItemText(iMacro);
|
2019-02-12 00:10:48 +00:00
|
|
|
if( name.empty() )
|
2018-03-02 21:56:24 +00:00
|
|
|
return;
|
2010-01-23 19:44:49 +00:00
|
|
|
|
2018-08-10 11:23:30 +00:00
|
|
|
#ifdef OPTIONAL_ACTIVITY_WINDOW
|
2018-03-03 18:01:40 +00:00
|
|
|
wxDialogWrapper activityWin( this, wxID_ANY, GetTitle());
|
2019-12-08 05:25:47 +00:00
|
|
|
activityWin.SetName();
|
2018-03-03 18:01:40 +00:00
|
|
|
ShuttleGui S(&activityWin, eIsCreating);
|
2010-01-23 19:44:49 +00:00
|
|
|
|
|
|
|
S.StartHorizontalLay(wxCENTER, false);
|
|
|
|
{
|
2017-09-28 01:20:14 +00:00
|
|
|
S.StartStatic( {}, false); // deliberately not translated (!)
|
2010-01-23 19:44:49 +00:00
|
|
|
{
|
|
|
|
S.SetBorder(20);
|
2019-12-23 00:55:59 +00:00
|
|
|
S.AddFixedText(XO("Applying '%s' to current project")
|
|
|
|
.Format( name ) );
|
2010-01-23 19:44:49 +00:00
|
|
|
}
|
|
|
|
S.EndStatic();
|
|
|
|
}
|
|
|
|
S.EndHorizontalLay();
|
|
|
|
|
2018-03-03 18:01:40 +00:00
|
|
|
activityWin.Layout();
|
|
|
|
activityWin.Fit();
|
|
|
|
activityWin.CenterOnScreen();
|
2018-03-03 12:53:41 +00:00
|
|
|
// Avoid overlap with progress.
|
|
|
|
int x,y;
|
2018-03-03 18:01:40 +00:00
|
|
|
activityWin.GetPosition( &x, &y );
|
|
|
|
activityWin.Move(wxMax(0,x-300), 0);
|
|
|
|
activityWin.Show();
|
2015-10-09 22:28:53 +00:00
|
|
|
|
2018-03-02 22:24:27 +00:00
|
|
|
// Without this the newly created dialog may not show completely.
|
|
|
|
wxYield();
|
2018-08-10 11:23:30 +00:00
|
|
|
#endif
|
2018-03-02 22:24:27 +00:00
|
|
|
|
2018-03-19 17:38:18 +00:00
|
|
|
//Since we intend to keep this dialog open, there is no reason to hide it
|
|
|
|
//and then show it again.
|
|
|
|
//if( bHasGui )
|
|
|
|
// Hide();
|
2010-01-23 19:44:49 +00:00
|
|
|
|
2018-03-03 19:08:23 +00:00
|
|
|
gPrefs->Write(wxT("/Batch/ActiveMacro"), name);
|
2012-08-02 06:03:19 +00:00
|
|
|
gPrefs->Flush();
|
2010-01-23 19:44:49 +00:00
|
|
|
|
2018-03-03 19:08:23 +00:00
|
|
|
mMacroCommands.ReadMacro(name);
|
2015-07-24 05:02:19 +00:00
|
|
|
|
|
|
|
// The disabler must get deleted before the EndModal() call. Otherwise,
|
|
|
|
// the menus on OSX will remain disabled.
|
2016-02-01 01:39:24 +00:00
|
|
|
bool success;
|
|
|
|
{
|
2018-08-10 11:23:30 +00:00
|
|
|
#ifdef OPTIONAL_ACTIVITY_WINDOW
|
2018-03-03 18:01:40 +00:00
|
|
|
wxWindowDisabler wd(&activityWin);
|
2018-08-10 11:23:30 +00:00
|
|
|
#endif
|
2016-12-03 19:33:37 +00:00
|
|
|
success = GuardedCall< bool >(
|
2018-03-08 04:42:57 +00:00
|
|
|
[this]{ return mMacroCommands.ApplyMacro(mCatalog); } );
|
2016-02-01 01:39:24 +00:00
|
|
|
}
|
2015-07-24 05:02:19 +00:00
|
|
|
|
2018-03-02 21:56:24 +00:00
|
|
|
if( !bHasGui )
|
|
|
|
return;
|
|
|
|
|
2018-03-17 14:49:35 +00:00
|
|
|
Show();
|
|
|
|
Raise();
|
2010-01-23 19:44:49 +00:00
|
|
|
}
|
|
|
|
|
2018-03-03 19:08:23 +00:00
|
|
|
void ApplyMacroDialog::OnApplyToFiles(wxCommandEvent & WXUNUSED(event))
|
2010-01-23 19:44:49 +00:00
|
|
|
{
|
2018-03-03 19:08:23 +00:00
|
|
|
long item = mMacros->GetNextItem(-1,
|
2010-01-23 19:44:49 +00:00
|
|
|
wxLIST_NEXT_ALL,
|
|
|
|
wxLIST_STATE_SELECTED);
|
|
|
|
if (item == -1) {
|
2019-12-07 19:30:07 +00:00
|
|
|
AudacityMessageBox( XO("No macro selected") );
|
2010-01-23 19:44:49 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2018-03-03 19:08:23 +00:00
|
|
|
wxString name = mMacros->GetItemText(item);
|
|
|
|
gPrefs->Write(wxT("/Batch/ActiveMacro"), name);
|
2012-08-02 06:03:19 +00:00
|
|
|
gPrefs->Flush();
|
2010-01-23 19:44:49 +00:00
|
|
|
|
2019-05-22 11:07:57 +00:00
|
|
|
AudacityProject *project = &mProject;
|
2019-05-06 23:00:10 +00:00
|
|
|
if (!TrackList::Get( *project ).empty()) {
|
2019-12-07 19:30:07 +00:00
|
|
|
AudacityMessageBox(
|
|
|
|
XO("Please save and close the current project first.") );
|
2010-01-23 19:44:49 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2020-08-26 05:06:19 +00:00
|
|
|
// This insures that we start with an empty and temporary project
|
|
|
|
ProjectFileManager::Get(*project).CloseProject();
|
|
|
|
ProjectFileManager::Get(*project).OpenProject();
|
|
|
|
|
2019-12-20 17:13:39 +00:00
|
|
|
auto prompt = XO("Select file(s) for batch processing...");
|
2014-06-03 20:30:19 +00:00
|
|
|
|
2019-12-20 18:02:31 +00:00
|
|
|
const auto fileTypes = Importer::Get().GetFileTypes();
|
2010-01-23 19:44:49 +00:00
|
|
|
|
2017-08-03 10:41:38 +00:00
|
|
|
auto path = FileNames::FindDefaultPath(FileNames::Operation::Open);
|
2017-10-12 19:41:52 +00:00
|
|
|
FileDialogWrapper dlog(this,
|
2019-12-20 18:02:31 +00:00
|
|
|
prompt,
|
|
|
|
path,
|
|
|
|
wxT(""),
|
|
|
|
fileTypes,
|
|
|
|
wxFD_OPEN | wxFD_MULTIPLE | wxRESIZE_BORDER);
|
2010-01-23 19:44:49 +00:00
|
|
|
|
2019-12-20 18:02:31 +00:00
|
|
|
dlog.SetFilterIndex( Importer::SelectDefaultOpenType( fileTypes ) );
|
2010-01-23 19:44:49 +00:00
|
|
|
if (dlog.ShowModal() != wxID_OK) {
|
2018-03-14 16:57:33 +00:00
|
|
|
Raise();
|
2010-01-23 19:44:49 +00:00
|
|
|
return;
|
|
|
|
}
|
2018-03-14 16:57:33 +00:00
|
|
|
Raise();
|
2017-08-03 10:41:38 +00:00
|
|
|
|
2010-01-23 19:44:49 +00:00
|
|
|
wxArrayString files;
|
|
|
|
dlog.GetPaths(files);
|
|
|
|
|
|
|
|
files.Sort();
|
|
|
|
|
2020-05-25 10:20:21 +00:00
|
|
|
wxDialogWrapper activityWin(this, wxID_ANY, Verbatim( GetTitle() ),
|
|
|
|
wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER
|
|
|
|
);
|
2019-12-08 05:25:47 +00:00
|
|
|
activityWin.SetName();
|
2018-03-03 18:01:40 +00:00
|
|
|
ShuttleGui S(&activityWin, eIsCreating);
|
2010-01-23 19:44:49 +00:00
|
|
|
|
2018-03-23 09:30:25 +00:00
|
|
|
wxListCtrl * fileList = NULL;
|
|
|
|
|
2020-05-25 10:20:21 +00:00
|
|
|
S.StartVerticalLay(1);
|
2010-01-23 19:44:49 +00:00
|
|
|
{
|
2019-12-22 19:58:36 +00:00
|
|
|
S.StartStatic(XO("Applying..."), 1);
|
2010-01-23 19:44:49 +00:00
|
|
|
{
|
2016-08-10 05:34:44 +00:00
|
|
|
auto imageList = std::make_unique<wxImageList>(9, 16);
|
The fabled realtime effects...
I've made it where you can enable and disable via experimentals:
EXPERIMENTAL_REALTIME_EFFECTS
EXPERIMENTAL_EFFECTS_RACK
You will notice that, as of now, the only effects currently set up for
realtime are VSTs. Now that this is in, I will start converting the
rest.
As I start to convert the effects, the astute of you may notice that
they no longer directly access tracks or any "internal" Audacity
objects. This isolates the effects from changes in Audacity and makes
it much easier to add new ones.
Anyway, all 3 platforms can now display VST effects in graphical mode.
Yes, that means Linux too. There are quite a few VSTs for Linux if
you search for them.
The so-called "rack" definitely needs some discussion, work, and attention
from someone much better at graphics than me. I'm not really sure it should
stay in as-is. I'd originally planned for it to be simply a utility window
where you can store your (preconfigured) favorite effects. It should probably
revert back to that idea.
You may notice that this DOES include the API work I did. The realtime effects
were too tied to it and I didn't want to redo the whole thing. As I mentioned
elsewhere, the API stuff may or may not be very future proof.
So, let the critter complaints commence. I absolute KNOW there will be some.
(I know I'll be hearing from the Linux peeps pretty darn quickly. ;-))
2014-10-26 03:24:10 +00:00
|
|
|
imageList->Add(wxIcon(empty9x16_xpm));
|
2010-01-23 19:44:49 +00:00
|
|
|
imageList->Add(wxIcon(arrow_xpm));
|
|
|
|
|
2018-02-03 00:22:07 +00:00
|
|
|
fileList = S.Id(CommandsListID)
|
2017-10-31 18:52:01 +00:00
|
|
|
.Style(wxSUNKEN_BORDER | wxLC_REPORT | wxLC_HRULES | wxLC_VRULES |
|
|
|
|
wxLC_SINGLE_SEL)
|
2019-12-23 22:57:45 +00:00
|
|
|
.AddListControlReportMode( { XO("File") } );
|
2016-08-10 05:34:44 +00:00
|
|
|
// AssignImageList takes ownership
|
2018-03-23 09:30:25 +00:00
|
|
|
fileList->AssignImageList(imageList.release(), wxIMAGE_LIST_SMALL);
|
2010-01-23 19:44:49 +00:00
|
|
|
}
|
|
|
|
S.EndStatic();
|
|
|
|
|
2020-05-25 10:20:21 +00:00
|
|
|
S.StartHorizontalLay(wxCENTER, 0);
|
2010-01-23 19:44:49 +00:00
|
|
|
{
|
2020-05-11 15:28:14 +00:00
|
|
|
S.Id(wxID_CANCEL).AddButton(XXO("&Cancel"));
|
2010-01-23 19:44:49 +00:00
|
|
|
}
|
|
|
|
S.EndHorizontalLay();
|
|
|
|
}
|
|
|
|
S.EndVerticalLay();
|
|
|
|
|
|
|
|
int i;
|
2019-02-12 00:10:48 +00:00
|
|
|
for (i = 0; i < (int)files.size(); i++ ) {
|
2018-03-23 09:30:25 +00:00
|
|
|
fileList->InsertItem(i, files[i], i == 0);
|
2010-01-23 19:44:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Set the column size for the files list.
|
2018-03-23 09:30:25 +00:00
|
|
|
fileList->SetColumnWidth(0, wxLIST_AUTOSIZE);
|
2010-01-23 19:44:49 +00:00
|
|
|
|
2020-05-25 10:20:21 +00:00
|
|
|
int width = wxMin( fileList->GetColumnWidth(0), 1000);
|
2018-03-23 09:30:25 +00:00
|
|
|
wxSize sz = fileList->GetClientSize();
|
2020-05-25 10:20:21 +00:00
|
|
|
if (sz.GetWidth() < width ) {
|
2010-01-23 19:44:49 +00:00
|
|
|
sz.SetWidth(width);
|
2020-05-25 10:20:21 +00:00
|
|
|
if (sz.GetHeight() < width *0.7)
|
|
|
|
sz.SetHeight(width * 0.7);
|
2018-03-23 09:30:25 +00:00
|
|
|
fileList->SetInitialSize(sz);
|
2010-01-23 19:44:49 +00:00
|
|
|
}
|
|
|
|
|
2018-03-03 18:01:40 +00:00
|
|
|
activityWin.Layout();
|
|
|
|
activityWin.Fit();
|
|
|
|
activityWin.CenterOnScreen();
|
2018-03-03 12:53:41 +00:00
|
|
|
// Avoid overlap with progress.
|
|
|
|
int x,y;
|
2018-03-03 18:01:40 +00:00
|
|
|
activityWin.GetPosition( &x, &y );
|
|
|
|
activityWin.Move(wxMax(0,x-300), 0);
|
|
|
|
activityWin.Show();
|
|
|
|
|
|
|
|
// Without this the newly created dialog may not show completely.
|
2018-03-03 12:53:41 +00:00
|
|
|
wxYield();
|
2018-03-19 17:38:18 +00:00
|
|
|
// We could avoid hiding, but there are many dialogs on screen,
|
|
|
|
// and hiding this one temporarily has some advantages.
|
2010-01-23 19:44:49 +00:00
|
|
|
Hide();
|
|
|
|
|
2020-05-25 10:20:21 +00:00
|
|
|
mMacroCommands.ReadMacro(name);
|
|
|
|
{
|
2020-12-02 04:03:23 +00:00
|
|
|
// Move global clipboard contents aside temporarily
|
|
|
|
Clipboard tempClipboard;
|
|
|
|
auto &globalClipboard = Clipboard::Get();
|
|
|
|
globalClipboard.Swap(tempClipboard);
|
|
|
|
auto cleanup = finally([&]{
|
|
|
|
globalClipboard.Swap(tempClipboard);
|
|
|
|
});
|
|
|
|
|
2018-03-03 18:01:40 +00:00
|
|
|
wxWindowDisabler wd(&activityWin);
|
2020-05-25 10:20:21 +00:00
|
|
|
for (i = 0; i < (int)files.size(); i++) {
|
|
|
|
if (i > 0) {
|
|
|
|
//Clear the arrow in previous item.
|
|
|
|
fileList->SetItemImage(i - 1, 0, 0);
|
|
|
|
}
|
|
|
|
fileList->SetItemImage(i, 1, 1);
|
|
|
|
fileList->EnsureVisible(i);
|
|
|
|
|
|
|
|
auto success = GuardedCall< bool >([&] {
|
|
|
|
ProjectFileManager::Get(*project).Import(files[i]);
|
|
|
|
ProjectWindow::Get(*project).ZoomAfterImport(nullptr);
|
|
|
|
SelectUtilities::DoSelectAll(*project);
|
|
|
|
if (!mMacroCommands.ApplyMacro(mCatalog))
|
|
|
|
return false;
|
|
|
|
|
|
|
|
if (!activityWin.IsShown() || mAbort)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
});
|
|
|
|
|
2020-08-26 05:06:19 +00:00
|
|
|
// Ensure project is completely reset
|
|
|
|
ProjectManager::Get(*project).ResetProjectToEmpty();
|
2020-12-02 04:03:23 +00:00
|
|
|
// Bug2567:
|
|
|
|
// Must also destroy the clipboard, to be sure sample blocks are
|
|
|
|
// all freed and their ids can be reused safely in the next pass
|
|
|
|
globalClipboard.Clear();
|
2020-08-26 05:06:19 +00:00
|
|
|
|
2020-05-25 10:20:21 +00:00
|
|
|
if (!success)
|
|
|
|
break;
|
2010-01-23 19:44:49 +00:00
|
|
|
}
|
|
|
|
}
|
2017-08-20 04:16:22 +00:00
|
|
|
|
2018-03-17 14:49:35 +00:00
|
|
|
Show();
|
|
|
|
Raise();
|
2010-01-23 19:44:49 +00:00
|
|
|
}
|
|
|
|
|
2018-03-03 19:08:23 +00:00
|
|
|
void ApplyMacroDialog::OnCancel(wxCommandEvent & WXUNUSED(event))
|
2010-01-23 19:44:49 +00:00
|
|
|
{
|
2015-10-10 14:27:35 +00:00
|
|
|
Hide();
|
2010-01-23 19:44:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
|
|
#include <wx/textdlg.h>
|
2013-11-01 12:15:01 +00:00
|
|
|
#include "BatchCommandDialog.h"
|
2010-01-23 19:44:49 +00:00
|
|
|
|
|
|
|
enum {
|
|
|
|
AddButtonID = 10000,
|
|
|
|
RemoveButtonID,
|
2021-03-22 17:45:54 +00:00
|
|
|
RenameButtonID,
|
|
|
|
RestoreButtonID,
|
2010-01-23 19:44:49 +00:00
|
|
|
ImportButtonID,
|
|
|
|
ExportButtonID,
|
2021-03-22 17:45:54 +00:00
|
|
|
SaveButtonID,
|
|
|
|
|
2010-01-23 19:44:49 +00:00
|
|
|
DefaultsButtonID,
|
2021-03-22 17:45:54 +00:00
|
|
|
|
2010-01-23 19:44:49 +00:00
|
|
|
InsertButtonID,
|
2018-03-01 17:54:08 +00:00
|
|
|
EditButtonID,
|
2010-01-23 19:44:49 +00:00
|
|
|
DeleteButtonID,
|
|
|
|
UpButtonID,
|
|
|
|
DownButtonID,
|
2021-03-22 17:45:54 +00:00
|
|
|
|
2018-03-03 19:08:23 +00:00
|
|
|
// MacrosListID 7005
|
2018-03-01 17:54:08 +00:00
|
|
|
// CommandsListID, 7002
|
2018-03-03 19:08:23 +00:00
|
|
|
// Re-Use IDs from ApplyMacroDialog.
|
2018-03-01 17:54:08 +00:00
|
|
|
ApplyToProjectButtonID = ApplyToProjectID,
|
|
|
|
ApplyToFilesButtonID = ApplyToFilesID,
|
2010-01-23 19:44:49 +00:00
|
|
|
};
|
|
|
|
|
2018-03-03 19:08:23 +00:00
|
|
|
BEGIN_EVENT_TABLE(MacrosWindow, ApplyMacroDialog)
|
|
|
|
EVT_LIST_ITEM_SELECTED(MacrosListID, MacrosWindow::OnMacroSelected)
|
|
|
|
EVT_LIST_ITEM_SELECTED(CommandsListID, MacrosWindow::OnListSelected)
|
|
|
|
EVT_LIST_BEGIN_LABEL_EDIT(MacrosListID, MacrosWindow::OnMacrosBeginEdit)
|
|
|
|
EVT_LIST_END_LABEL_EDIT(MacrosListID, MacrosWindow::OnMacrosEndEdit)
|
|
|
|
EVT_BUTTON(AddButtonID, MacrosWindow::OnAdd)
|
|
|
|
EVT_BUTTON(RemoveButtonID, MacrosWindow::OnRemove)
|
|
|
|
EVT_BUTTON(RenameButtonID, MacrosWindow::OnRename)
|
2019-07-16 06:37:07 +00:00
|
|
|
EVT_BUTTON(RestoreButtonID, MacrosWindow::OnRestore)
|
2020-08-09 02:17:14 +00:00
|
|
|
EVT_BUTTON(ImportButtonID, MacrosWindow::OnImport)
|
|
|
|
EVT_BUTTON(ExportButtonID, MacrosWindow::OnExport)
|
2021-03-22 17:45:54 +00:00
|
|
|
EVT_BUTTON(SaveButtonID, MacrosWindow::OnSave)
|
|
|
|
|
2018-03-03 22:20:25 +00:00
|
|
|
EVT_BUTTON(ExpandID, MacrosWindow::OnExpand)
|
|
|
|
EVT_BUTTON(ShrinkID, MacrosWindow::OnShrink)
|
2018-03-03 19:08:23 +00:00
|
|
|
EVT_SIZE(MacrosWindow::OnSize)
|
|
|
|
|
|
|
|
EVT_LIST_ITEM_ACTIVATED(CommandsListID, MacrosWindow::OnCommandActivated)
|
|
|
|
EVT_BUTTON(InsertButtonID, MacrosWindow::OnInsert)
|
|
|
|
EVT_BUTTON(EditButtonID, MacrosWindow::OnEditCommandParams)
|
|
|
|
EVT_BUTTON(DeleteButtonID, MacrosWindow::OnDelete)
|
|
|
|
EVT_BUTTON(UpButtonID, MacrosWindow::OnUp)
|
|
|
|
EVT_BUTTON(DownButtonID, MacrosWindow::OnDown)
|
|
|
|
|
|
|
|
EVT_BUTTON(wxID_OK, MacrosWindow::OnOK)
|
|
|
|
EVT_BUTTON(wxID_CANCEL, MacrosWindow::OnCancel)
|
2021-03-22 17:45:54 +00:00
|
|
|
EVT_BUTTON(wxID_CLOSE, MacrosWindow::OnCancel)
|
2018-03-03 19:08:23 +00:00
|
|
|
|
|
|
|
EVT_KEY_DOWN(MacrosWindow::OnKeyDown)
|
2010-01-23 19:44:49 +00:00
|
|
|
END_EVENT_TABLE()
|
|
|
|
|
|
|
|
enum {
|
2014-06-03 20:30:19 +00:00
|
|
|
ItemNumberColumn,
|
|
|
|
ActionColumn,
|
2010-01-23 19:44:49 +00:00
|
|
|
ParamsColumn,
|
|
|
|
};
|
|
|
|
|
|
|
|
/// Constructor
|
2019-05-22 00:16:20 +00:00
|
|
|
MacrosWindow::MacrosWindow(
|
|
|
|
wxWindow * parent, AudacityProject &project, bool bExpanded):
|
|
|
|
ApplyMacroDialog(parent, project, true)
|
2019-05-22 01:04:18 +00:00
|
|
|
, mProject{ project }
|
2010-01-23 19:44:49 +00:00
|
|
|
{
|
2018-03-03 18:01:40 +00:00
|
|
|
mbExpanded = bExpanded;
|
2019-12-07 19:30:07 +00:00
|
|
|
auto Title = WindowTitle();
|
2018-03-16 18:38:06 +00:00
|
|
|
SetLabel( Title ); // Provide visual label
|
|
|
|
SetName( Title ); // Provide audible label
|
|
|
|
SetTitle( Title );
|
2010-01-23 19:44:49 +00:00
|
|
|
|
|
|
|
mChanged = false;
|
|
|
|
mSelectedCommand = 0;
|
|
|
|
|
2018-03-03 18:01:40 +00:00
|
|
|
if( mbExpanded )
|
|
|
|
Populate();
|
|
|
|
else
|
2018-03-03 19:08:23 +00:00
|
|
|
ApplyMacroDialog::Populate();
|
2010-01-23 19:44:49 +00:00
|
|
|
}
|
|
|
|
|
2018-03-03 19:08:23 +00:00
|
|
|
MacrosWindow::~MacrosWindow()
|
2010-01-23 19:44:49 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Creates the dialog and its contents.
|
2018-03-03 19:08:23 +00:00
|
|
|
void MacrosWindow::Populate()
|
2010-01-23 19:44:49 +00:00
|
|
|
{
|
|
|
|
//------------------------- Main section --------------------
|
|
|
|
ShuttleGui S(this, eIsCreating);
|
|
|
|
PopulateOrExchange(S);
|
|
|
|
// ----------------------- End of main section --------------
|
|
|
|
|
2018-03-03 19:08:23 +00:00
|
|
|
// Get and validate the currently active macro
|
|
|
|
mActiveMacro = gPrefs->Read(wxT("/Batch/ActiveMacro"), wxT(""));
|
|
|
|
// Go populate the macros list.
|
|
|
|
PopulateMacros();
|
2010-01-23 19:44:49 +00:00
|
|
|
|
|
|
|
// We have a bare list. We need to add columns and content.
|
|
|
|
PopulateList();
|
|
|
|
|
|
|
|
// Layout and set minimum size of window
|
|
|
|
Layout();
|
|
|
|
Fit();
|
|
|
|
SetSizeHints(GetSize());
|
|
|
|
|
|
|
|
// Size and place window
|
2018-03-14 16:37:15 +00:00
|
|
|
SetSize(std::min(wxSystemSettings::GetMetric(wxSYS_SCREEN_X) * 3 / 4, 800),
|
|
|
|
std::min(wxSystemSettings::GetMetric(wxSYS_SCREEN_Y) * 4 / 5, 400));
|
2010-01-23 19:44:49 +00:00
|
|
|
Center();
|
|
|
|
|
2018-03-03 19:08:23 +00:00
|
|
|
// Set the column size for the macros list.
|
|
|
|
wxSize sz = mMacros->GetClientSize();
|
|
|
|
mMacros->SetColumnWidth(0, sz.x);
|
2010-01-23 19:44:49 +00:00
|
|
|
|
|
|
|
// Size columns properly
|
2013-03-10 09:05:41 +00:00
|
|
|
FitColumns();
|
2010-01-23 19:44:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Defines the dialog and does data exchange with it.
|
2018-03-03 19:08:23 +00:00
|
|
|
void MacrosWindow::PopulateOrExchange(ShuttleGui & S)
|
2010-01-23 19:44:49 +00:00
|
|
|
{
|
|
|
|
S.StartHorizontalLay(wxEXPAND, 1);
|
|
|
|
{
|
2019-12-22 19:58:36 +00:00
|
|
|
S.StartStatic(XO("Select Macro"),0);
|
2010-01-23 19:44:49 +00:00
|
|
|
{
|
2018-03-14 16:37:15 +00:00
|
|
|
S.StartHorizontalLay(wxEXPAND,1);
|
2018-03-03 22:20:25 +00:00
|
|
|
{
|
2018-02-03 00:22:07 +00:00
|
|
|
mMacros = S.Id(MacrosListID).Prop(1)
|
2017-10-31 18:52:01 +00:00
|
|
|
.Style(wxSUNKEN_BORDER | wxLC_REPORT | wxLC_HRULES
|
|
|
|
| wxLC_SINGLE_SEL | wxLC_EDIT_LABELS)
|
|
|
|
// i18n-hint: This is the heading for a column in the edit macros dialog
|
2019-12-23 22:57:45 +00:00
|
|
|
.AddListControlReportMode( { XO("Macro") } );
|
2018-03-14 16:37:15 +00:00
|
|
|
S.StartVerticalLay(wxALIGN_TOP, 0);
|
|
|
|
{
|
2021-03-23 12:15:09 +00:00
|
|
|
S.Id(AddButtonID).AddButton(XXO("&New"), wxALIGN_LEFT);
|
|
|
|
mRemove = S.Id(RemoveButtonID).AddButton(XXO("Remo&ve"), wxALIGN_LEFT);
|
|
|
|
mRename = S.Id(RenameButtonID).AddButton(XXO("&Rename..."), wxALIGN_LEFT);
|
|
|
|
mRestore = S.Id(RestoreButtonID).AddButton(XXO("Re&store"), wxALIGN_LEFT);
|
|
|
|
mImport = S.Id(ImportButtonID).AddButton(XO("I&mport..."), wxALIGN_LEFT);
|
|
|
|
mExport = S.Id(ExportButtonID).AddButton(XO("E&xport..."), wxALIGN_LEFT);
|
2018-03-14 16:37:15 +00:00
|
|
|
}
|
|
|
|
S.EndVerticalLay();
|
2018-03-05 15:00:11 +00:00
|
|
|
}
|
|
|
|
S.EndHorizontalLay();
|
2010-01-23 19:44:49 +00:00
|
|
|
}
|
2018-03-14 16:37:15 +00:00
|
|
|
S.EndStatic();
|
2010-01-23 19:44:49 +00:00
|
|
|
|
2019-12-22 19:58:36 +00:00
|
|
|
S.StartStatic(XO("Edit Steps"), true);
|
2010-01-23 19:44:49 +00:00
|
|
|
{
|
2018-03-14 16:37:15 +00:00
|
|
|
S.StartHorizontalLay(wxEXPAND,1);
|
2010-01-23 19:44:49 +00:00
|
|
|
{
|
2018-02-03 00:22:07 +00:00
|
|
|
mList = S.Id(CommandsListID)
|
2017-10-31 18:52:01 +00:00
|
|
|
.Style(wxSUNKEN_BORDER | wxLC_REPORT | wxLC_HRULES | wxLC_VRULES |
|
|
|
|
wxLC_SINGLE_SEL)
|
2018-02-03 00:22:07 +00:00
|
|
|
.AddListControlReportMode({
|
|
|
|
/* i18n-hint: This is the number of the command in the list */
|
2019-12-23 22:57:45 +00:00
|
|
|
{ XO("Num"), wxLIST_FORMAT_RIGHT },
|
|
|
|
{ XO("Command "), wxLIST_FORMAT_RIGHT },
|
|
|
|
{ XO("Parameters"), wxLIST_FORMAT_LEFT }
|
2018-02-03 00:22:07 +00:00
|
|
|
});
|
2018-03-14 16:37:15 +00:00
|
|
|
|
|
|
|
S.StartVerticalLay(wxALIGN_TOP, 0);
|
|
|
|
{
|
2020-05-11 15:28:14 +00:00
|
|
|
S.Id(InsertButtonID).AddButton(XXO("&Insert"), wxALIGN_LEFT);
|
|
|
|
S.Id(EditButtonID).AddButton(XXO("&Edit..."), wxALIGN_LEFT);
|
|
|
|
S.Id(DeleteButtonID).AddButton(XXO("De&lete"), wxALIGN_LEFT);
|
|
|
|
S.Id(UpButtonID).AddButton(XXO("Move &Up"), wxALIGN_LEFT);
|
|
|
|
S.Id(DownButtonID).AddButton(XXO("Move &Down"), wxALIGN_LEFT);
|
2021-03-23 12:15:09 +00:00
|
|
|
mSave = S.Id(SaveButtonID).AddButton(XO("&Save"), wxALIGN_LEFT);
|
|
|
|
mSave->Enable( mChanged );
|
2018-03-01 17:54:08 +00:00
|
|
|
}
|
2018-03-14 16:37:15 +00:00
|
|
|
S.EndVerticalLay();
|
2010-01-23 19:44:49 +00:00
|
|
|
}
|
|
|
|
S.EndHorizontalLay();
|
|
|
|
}
|
2018-03-14 16:37:15 +00:00
|
|
|
S.EndStatic();
|
2010-01-23 19:44:49 +00:00
|
|
|
}
|
|
|
|
S.EndHorizontalLay();
|
|
|
|
|
2018-03-14 16:37:15 +00:00
|
|
|
S.StartHorizontalLay(wxEXPAND, 0);
|
|
|
|
{
|
2018-08-28 15:35:06 +00:00
|
|
|
/* i18n-hint: The Shrink button makes the dialog smaller, with less in it */
|
2020-05-11 15:28:14 +00:00
|
|
|
mResize = S.Id(ShrinkID).AddButton(XXO("Shrin&k"));
|
2018-03-14 16:37:15 +00:00
|
|
|
// Using variable text just to get the positioning options.
|
2019-12-22 22:01:20 +00:00
|
|
|
S.Prop(0).AddVariableText(
|
|
|
|
XO("Apply Macro to:"), false, wxALL | wxALIGN_CENTRE_VERTICAL );
|
2017-10-29 14:27:23 +00:00
|
|
|
wxButton* btn = S.Id(ApplyToProjectID)
|
|
|
|
.Name(XO("Apply macro to project"))
|
2020-05-11 15:28:14 +00:00
|
|
|
.AddButton(XXO("&Project"));
|
2018-07-30 10:58:16 +00:00
|
|
|
#if wxUSE_ACCESSIBILITY
|
2018-07-30 10:34:00 +00:00
|
|
|
// so that name can be set on a standard control
|
|
|
|
btn->SetAccessible(safenew WindowAccessible(btn));
|
2018-07-30 10:58:16 +00:00
|
|
|
#endif
|
2018-07-30 10:34:00 +00:00
|
|
|
|
2017-10-29 14:27:23 +00:00
|
|
|
btn = S.Id(ApplyToFilesID)
|
|
|
|
.Name(XO("Apply macro to files..."))
|
2020-05-11 15:28:14 +00:00
|
|
|
.AddButton(XXO("&Files..."));
|
2018-07-30 10:58:16 +00:00
|
|
|
#if wxUSE_ACCESSIBILITY
|
2018-07-30 10:34:00 +00:00
|
|
|
// so that name can be set on a standard control
|
|
|
|
btn->SetAccessible(safenew WindowAccessible(btn));
|
2018-07-30 10:58:16 +00:00
|
|
|
#endif
|
2020-08-22 12:41:18 +00:00
|
|
|
S.AddSpace( 10,10,1 );
|
|
|
|
// Bug 2524 OK button does much the same as cancel, so remove it.
|
|
|
|
// OnCancel prompts you if there has been a change.
|
|
|
|
// OnOK saves without prompting.
|
|
|
|
// That difference is too slight to merit a button, and with the OK
|
|
|
|
// button, people might expect the dialog to apply the macro too.
|
2021-03-22 17:45:54 +00:00
|
|
|
S.AddStandardButtons( /*eOkButton |*/ eCloseButton | eHelpButton);
|
2018-03-14 16:37:15 +00:00
|
|
|
}
|
|
|
|
|
2021-03-22 17:45:54 +00:00
|
|
|
S.EndHorizontalLay();
|
2018-03-14 16:37:15 +00:00
|
|
|
|
2021-03-22 17:45:54 +00:00
|
|
|
|
2010-01-23 19:44:49 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2018-03-03 19:08:23 +00:00
|
|
|
/// This clears and updates the contents of mList, the commands for the current macro.
|
|
|
|
void MacrosWindow::PopulateList()
|
2010-01-23 19:44:49 +00:00
|
|
|
{
|
2018-03-17 15:38:09 +00:00
|
|
|
int topItem = mList->GetTopItem();
|
2010-01-23 19:44:49 +00:00
|
|
|
mList->DeleteAllItems();
|
|
|
|
|
2018-03-03 19:08:23 +00:00
|
|
|
for (int i = 0; i < mMacroCommands.GetCount(); i++) {
|
|
|
|
AddItem(mMacroCommands.GetCommand(i),
|
|
|
|
mMacroCommands.GetParams(i));
|
2010-01-23 19:44:49 +00:00
|
|
|
}
|
2012-03-20 15:36:02 +00:00
|
|
|
/*i18n-hint: This is the last item in a list.*/
|
2010-01-23 19:44:49 +00:00
|
|
|
AddItem(_("- END -"), wxT(""));
|
|
|
|
|
|
|
|
// Select the name in the list...this will fire an event.
|
|
|
|
if (mSelectedCommand >= (int)mList->GetItemCount()) {
|
|
|
|
mSelectedCommand = 0;
|
|
|
|
}
|
2018-08-10 15:43:27 +00:00
|
|
|
mList->SetItemState(mSelectedCommand,
|
|
|
|
wxLIST_STATE_SELECTED | wxLIST_STATE_FOCUSED,
|
|
|
|
wxLIST_STATE_SELECTED | wxLIST_STATE_FOCUSED);
|
2018-03-17 15:38:09 +00:00
|
|
|
if( 0 <= topItem && topItem < (int)mList->GetItemCount())
|
|
|
|
{
|
|
|
|
// Workaround for scrolling being windows only.
|
|
|
|
// Try to scroll back to where we once were...
|
|
|
|
mList->EnsureVisible( (int)mList->GetItemCount() -1 );
|
|
|
|
mList->EnsureVisible( topItem );
|
|
|
|
// And then make sure whatever is selected is still visible...
|
2018-03-19 14:42:06 +00:00
|
|
|
if (mSelectedCommand >= 0) {
|
|
|
|
mList->EnsureVisible( mSelectedCommand );
|
|
|
|
}
|
2018-03-17 15:38:09 +00:00
|
|
|
}
|
2010-01-23 19:44:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Add one item into mList
|
2019-03-11 02:05:37 +00:00
|
|
|
void MacrosWindow::AddItem(const CommandID &Action, const wxString &Params)
|
2010-01-23 19:44:49 +00:00
|
|
|
{
|
2018-03-06 20:28:05 +00:00
|
|
|
auto entry = mCatalog.ByCommandId(Action);
|
|
|
|
auto friendlyName = entry != mCatalog.end()
|
2019-12-15 15:58:19 +00:00
|
|
|
? entry->name.StrippedTranslation()
|
2018-03-06 20:28:05 +00:00
|
|
|
:
|
2019-02-27 18:14:25 +00:00
|
|
|
// uh oh, using GET to expose an internal name to the user!
|
|
|
|
// in default of any better friendly name
|
|
|
|
Action.GET();
|
2018-01-10 02:49:49 +00:00
|
|
|
|
2010-01-23 19:44:49 +00:00
|
|
|
int i = mList->GetItemCount();
|
|
|
|
|
2019-04-01 10:37:00 +00:00
|
|
|
mList->InsertItem(i, wxString::Format(wxT(" %02i"), i + 1));
|
2018-01-10 02:49:49 +00:00
|
|
|
mList->SetItem(i, ActionColumn, friendlyName );
|
2010-01-23 19:44:49 +00:00
|
|
|
mList->SetItem(i, ParamsColumn, Params );
|
|
|
|
}
|
|
|
|
|
2018-03-03 19:08:23 +00:00
|
|
|
void MacrosWindow::UpdateMenus()
|
2018-03-02 22:13:41 +00:00
|
|
|
{
|
2018-03-03 18:01:40 +00:00
|
|
|
// OK even on mac, as dialog is modal.
|
2019-05-22 11:07:57 +00:00
|
|
|
auto p = &mProject;
|
2019-05-01 17:20:52 +00:00
|
|
|
MenuManager::Get(*p).RebuildMenuBar(*p);
|
2018-03-03 18:01:40 +00:00
|
|
|
}
|
|
|
|
|
2018-03-03 22:20:25 +00:00
|
|
|
void MacrosWindow::UpdateDisplay( bool bExpanded )
|
2018-03-03 18:01:40 +00:00
|
|
|
{
|
2021-03-22 17:45:54 +00:00
|
|
|
// If we failed to save changes, we abandon the attempt to
|
|
|
|
// change the expand/shrink state of the GUI.
|
2018-03-04 19:16:30 +00:00
|
|
|
if( !SaveChanges() )
|
|
|
|
return;
|
|
|
|
|
2018-03-03 22:20:25 +00:00
|
|
|
mbExpanded = bExpanded;
|
2021-03-22 17:45:54 +00:00
|
|
|
|
|
|
|
mChanged = false;
|
|
|
|
// if we try to access the about to be destroyed mSave button
|
|
|
|
// inappropriately, we need to crash rather than (sometimes) silently
|
|
|
|
// succeed.
|
|
|
|
mSave = nullptr;
|
|
|
|
|
2018-03-03 22:20:25 +00:00
|
|
|
DestroyChildren();
|
|
|
|
SetSizer( nullptr );
|
2021-03-22 17:45:54 +00:00
|
|
|
|
2018-03-03 22:20:25 +00:00
|
|
|
mSelectedCommand = 0;
|
|
|
|
SetMinSize( wxSize( 200,200 ));
|
|
|
|
|
2018-03-04 10:24:14 +00:00
|
|
|
// Get and set position for optical stability.
|
|
|
|
// Expanded and shrunk dialogs 'stay where they were'.
|
|
|
|
// That's OK , and what we want, even if we exapnd off-screen.
|
|
|
|
// We won't shrink to being off-screen, since the shrink button
|
|
|
|
// was clicked, so must have been on screen.
|
|
|
|
wxPoint p = GetPosition( );
|
2018-03-03 22:20:25 +00:00
|
|
|
if( mbExpanded )
|
|
|
|
Populate();
|
|
|
|
else
|
|
|
|
ApplyMacroDialog::Populate();
|
2018-03-04 10:24:14 +00:00
|
|
|
SetPosition( p );
|
2018-03-05 15:13:42 +00:00
|
|
|
mResize->SetFocus();
|
2018-03-04 10:24:14 +00:00
|
|
|
|
2019-12-07 19:30:07 +00:00
|
|
|
auto Title = WindowTitle();
|
2018-03-04 10:24:14 +00:00
|
|
|
SetLabel( Title ); // Provide visual label
|
|
|
|
SetName( Title ); // Provide audible label
|
|
|
|
SetTitle( Title );
|
2018-03-02 22:13:41 +00:00
|
|
|
}
|
|
|
|
|
2018-03-03 22:20:25 +00:00
|
|
|
void MacrosWindow::OnExpand(wxCommandEvent &WXUNUSED(event))
|
|
|
|
{ UpdateDisplay( true );}
|
|
|
|
|
|
|
|
void MacrosWindow::OnShrink(wxCommandEvent &WXUNUSED(event))
|
2021-03-22 17:45:54 +00:00
|
|
|
{
|
|
|
|
if( ChangeOK() )
|
|
|
|
UpdateDisplay( false );
|
|
|
|
}
|
2018-03-03 22:20:25 +00:00
|
|
|
|
|
|
|
|
2018-03-03 19:08:23 +00:00
|
|
|
bool MacrosWindow::ChangeOK()
|
2010-01-23 19:44:49 +00:00
|
|
|
{
|
|
|
|
if (mChanged) {
|
|
|
|
int id;
|
|
|
|
|
2019-12-07 19:30:07 +00:00
|
|
|
auto title = XO("%s changed").Format( mActiveMacro );
|
|
|
|
auto msg = XO("Do you want to save the changes?");
|
2010-01-23 19:44:49 +00:00
|
|
|
|
2019-12-07 19:30:07 +00:00
|
|
|
id = AudacityMessageBox(
|
|
|
|
msg,
|
|
|
|
title,
|
|
|
|
wxYES_NO | wxCANCEL);
|
2010-01-23 19:44:49 +00:00
|
|
|
if (id == wxCANCEL) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (id == wxYES) {
|
2018-03-03 19:08:23 +00:00
|
|
|
if (!mMacroCommands.WriteMacro(mActiveMacro)) {
|
2010-01-23 19:44:49 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
mChanged = false;
|
2021-03-22 17:45:54 +00:00
|
|
|
mSave->Enable( mChanged );
|
2010-01-23 19:44:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
2018-03-03 19:08:23 +00:00
|
|
|
/// An item in the macros list has been selected.
|
|
|
|
void MacrosWindow::OnMacroSelected(wxListEvent & event)
|
2010-01-23 19:44:49 +00:00
|
|
|
{
|
|
|
|
if (!ChangeOK()) {
|
|
|
|
event.Veto();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
int item = event.GetIndex();
|
|
|
|
|
2018-03-03 19:08:23 +00:00
|
|
|
mActiveMacro = mMacros->GetItemText(item);
|
2020-08-22 12:41:18 +00:00
|
|
|
ShowActiveMacro();
|
|
|
|
}
|
|
|
|
|
|
|
|
void MacrosWindow::ShowActiveMacro()
|
|
|
|
{
|
2018-03-03 19:08:23 +00:00
|
|
|
mMacroCommands.ReadMacro(mActiveMacro);
|
2018-03-03 18:01:40 +00:00
|
|
|
if( !mbExpanded )
|
|
|
|
return;
|
|
|
|
|
2018-03-03 19:08:23 +00:00
|
|
|
if (mMacroCommands.IsFixed(mActiveMacro)) {
|
2010-01-23 19:44:49 +00:00
|
|
|
mRemove->Disable();
|
|
|
|
mRename->Disable();
|
2019-07-16 06:37:07 +00:00
|
|
|
mRestore->Enable();
|
2010-01-23 19:44:49 +00:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
mRemove->Enable();
|
|
|
|
mRename->Enable();
|
2019-07-16 06:37:07 +00:00
|
|
|
mRestore->Disable();
|
2010-01-23 19:44:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
PopulateList();
|
2013-03-10 09:05:41 +00:00
|
|
|
}
|
|
|
|
|
2018-03-03 19:08:23 +00:00
|
|
|
/// An item in the macros list has been selected.
|
|
|
|
void MacrosWindow::OnListSelected(wxListEvent & WXUNUSED(event))
|
2013-03-10 09:05:41 +00:00
|
|
|
{
|
|
|
|
FitColumns();
|
|
|
|
}
|
|
|
|
|
|
|
|
/// The window has been resized.
|
2018-03-03 19:08:23 +00:00
|
|
|
void MacrosWindow::OnSize(wxSizeEvent & WXUNUSED(event))
|
2013-03-10 09:05:41 +00:00
|
|
|
{
|
2020-03-31 13:52:12 +00:00
|
|
|
// Refresh the layout and re-fit the columns.
|
2013-03-10 09:05:41 +00:00
|
|
|
Layout();
|
2018-03-03 18:01:40 +00:00
|
|
|
if( !mbExpanded )
|
|
|
|
return;
|
2013-03-10 09:05:41 +00:00
|
|
|
FitColumns();
|
|
|
|
}
|
|
|
|
|
2018-03-03 19:08:23 +00:00
|
|
|
void MacrosWindow::FitColumns()
|
2013-03-10 09:05:41 +00:00
|
|
|
{
|
|
|
|
|
|
|
|
#if defined(__WXMAC__)
|
|
|
|
// wxMac uses a hard coded width of 150 when wxLIST_AUTOSIZE_USEHEADER
|
|
|
|
// is specified, so we calculate the width ourselves. This method may
|
|
|
|
// work equally well on other platforms.
|
2019-04-01 10:37:00 +00:00
|
|
|
for (size_t c = 0; c < mList->GetColumnCount(); c++) {
|
2013-03-10 09:05:41 +00:00
|
|
|
wxListItem info;
|
|
|
|
int width;
|
|
|
|
|
|
|
|
mList->SetColumnWidth(c, wxLIST_AUTOSIZE);
|
|
|
|
info.Clear();
|
|
|
|
info.SetId(c);
|
|
|
|
info.SetMask(wxLIST_MASK_TEXT | wxLIST_MASK_WIDTH);
|
|
|
|
mList->GetColumn(c, info);
|
|
|
|
|
|
|
|
mList->GetTextExtent(info.GetText(), &width, NULL);
|
|
|
|
width += 2 * 4; // 2 * kItemPadding - see listctrl_mac.cpp
|
|
|
|
width += 16; // kIconWidth - see listctrl_mac.cpp
|
|
|
|
|
|
|
|
mList->SetColumnWidth(c, wxMax(width, mList->GetColumnWidth(c)));
|
|
|
|
}
|
|
|
|
|
|
|
|
// Looks strange, but it forces the horizontal scrollbar to get
|
|
|
|
// drawn. If not done, strange column sizing can occur if the
|
|
|
|
// user attempts to resize the columns.
|
|
|
|
mList->SetClientSize(mList->GetClientSize());
|
|
|
|
#else
|
2019-04-01 10:37:00 +00:00
|
|
|
mList->SetColumnWidth(0, wxLIST_AUTOSIZE_USEHEADER);
|
2013-03-10 09:05:41 +00:00
|
|
|
mList->SetColumnWidth(1, wxLIST_AUTOSIZE_USEHEADER);
|
2019-04-01 10:37:00 +00:00
|
|
|
mList->SetColumnWidth(2, wxLIST_AUTOSIZE);
|
2014-06-03 20:30:19 +00:00
|
|
|
#endif
|
2013-03-10 09:05:41 +00:00
|
|
|
|
2019-04-01 10:37:00 +00:00
|
|
|
int bestfit = mList->GetColumnWidth(2);
|
2013-03-10 09:05:41 +00:00
|
|
|
int clientsize = mList->GetClientSize().GetWidth();
|
2019-04-01 10:37:00 +00:00
|
|
|
int col0 = mList->GetColumnWidth(0);
|
2013-03-10 09:05:41 +00:00
|
|
|
int col1 = mList->GetColumnWidth(1);
|
2019-04-01 10:37:00 +00:00
|
|
|
bestfit = (bestfit > clientsize-col0-col1)? bestfit : clientsize-col0-col1;
|
|
|
|
mList->SetColumnWidth(2, bestfit);
|
2010-01-23 19:44:49 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
///
|
2018-03-03 19:08:23 +00:00
|
|
|
void MacrosWindow::OnMacrosBeginEdit(wxListEvent &event)
|
2010-01-23 19:44:49 +00:00
|
|
|
{
|
|
|
|
int itemNo = event.GetIndex();
|
|
|
|
|
2018-03-03 19:08:23 +00:00
|
|
|
wxString macro = mMacros->GetItemText(itemNo);
|
2010-01-23 19:44:49 +00:00
|
|
|
|
2019-07-16 09:17:55 +00:00
|
|
|
if (mMacroCommands.IsFixed(macro)) {
|
2010-01-23 19:44:49 +00:00
|
|
|
wxBell();
|
|
|
|
event.Veto();
|
|
|
|
}
|
2019-07-16 09:17:55 +00:00
|
|
|
if( mMacroBeingRenamed.IsEmpty())
|
|
|
|
mMacroBeingRenamed = macro;
|
2010-01-23 19:44:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
///
|
2018-03-03 19:08:23 +00:00
|
|
|
void MacrosWindow::OnMacrosEndEdit(wxListEvent &event)
|
2010-01-23 19:44:49 +00:00
|
|
|
{
|
|
|
|
if (event.IsEditCancelled()) {
|
2019-07-16 09:17:55 +00:00
|
|
|
mMacroBeingRenamed = "";
|
2010-01-23 19:44:49 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2019-07-16 09:17:55 +00:00
|
|
|
if( mMacroBeingRenamed.IsEmpty())
|
|
|
|
return;
|
2010-01-23 19:44:49 +00:00
|
|
|
|
2019-07-16 09:17:55 +00:00
|
|
|
wxString newname = event.GetLabel();
|
2010-01-23 19:44:49 +00:00
|
|
|
|
2019-07-16 09:17:55 +00:00
|
|
|
mMacroCommands.RenameMacro(mMacroBeingRenamed, newname);
|
|
|
|
if( mMacroBeingRenamed == mActiveMacro )
|
|
|
|
mActiveMacro = newname;
|
|
|
|
mMacroBeingRenamed="";
|
2018-03-03 19:08:23 +00:00
|
|
|
PopulateMacros();
|
2019-07-16 09:17:55 +00:00
|
|
|
UpdateMenus();
|
|
|
|
event.Veto();
|
2010-01-23 19:44:49 +00:00
|
|
|
}
|
|
|
|
|
2014-06-03 20:30:19 +00:00
|
|
|
///
|
2018-03-03 19:08:23 +00:00
|
|
|
void MacrosWindow::OnAdd(wxCommandEvent & WXUNUSED(event))
|
2010-01-23 19:44:49 +00:00
|
|
|
{
|
2020-02-26 10:30:48 +00:00
|
|
|
// Similar to Bug 2284 we may need to save a changed macro.
|
|
|
|
if (!ChangeOK()) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2010-01-23 19:44:49 +00:00
|
|
|
while (true) {
|
2017-10-12 15:49:57 +00:00
|
|
|
AudacityTextEntryDialog d(this,
|
2019-12-18 05:07:58 +00:00
|
|
|
XO("Enter name of new macro"),
|
|
|
|
XO("Name of new macro"));
|
2015-05-12 08:29:55 +00:00
|
|
|
d.SetName(d.GetTitle());
|
2010-01-23 19:44:49 +00:00
|
|
|
wxString name;
|
|
|
|
|
|
|
|
if (d.ShowModal() == wxID_CANCEL) {
|
2018-03-14 16:57:33 +00:00
|
|
|
Raise();
|
2010-01-23 19:44:49 +00:00
|
|
|
return;
|
|
|
|
}
|
2018-03-14 16:57:33 +00:00
|
|
|
Raise();
|
2010-01-23 19:44:49 +00:00
|
|
|
|
|
|
|
name = d.GetValue().Strip(wxString::both);
|
|
|
|
|
2019-03-06 19:53:39 +00:00
|
|
|
if (name.length() == 0) {
|
2019-12-07 19:30:07 +00:00
|
|
|
AudacityMessageBox(
|
|
|
|
XO("Name must not be blank"),
|
|
|
|
WindowTitle(),
|
|
|
|
wxOK | wxICON_ERROR,
|
|
|
|
this);
|
2010-01-23 19:44:49 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (name.Contains(wxFILE_SEP_PATH) ||
|
|
|
|
name.Contains(wxFILE_SEP_PATH_UNIX)) {
|
2019-12-07 19:30:07 +00:00
|
|
|
AudacityMessageBox(
|
2020-04-05 12:40:15 +00:00
|
|
|
/*i18n-hint: The %c will be replaced with 'forbidden characters', like '/' and '\'.*/
|
2019-12-07 19:30:07 +00:00
|
|
|
XO("Names may not contain '%c' and '%c'")
|
|
|
|
.Format(wxFILE_SEP_PATH, wxFILE_SEP_PATH_UNIX),
|
|
|
|
WindowTitle(),
|
|
|
|
wxOK | wxICON_ERROR,
|
|
|
|
this);
|
2010-01-23 19:44:49 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2018-03-03 19:08:23 +00:00
|
|
|
mMacroCommands.AddMacro(name);
|
2010-01-23 19:44:49 +00:00
|
|
|
|
2018-03-03 19:08:23 +00:00
|
|
|
mActiveMacro = name;
|
2010-01-23 19:44:49 +00:00
|
|
|
|
2018-03-03 19:08:23 +00:00
|
|
|
PopulateMacros();
|
2018-03-02 22:13:41 +00:00
|
|
|
UpdateMenus();
|
2010-01-23 19:44:49 +00:00
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
///
|
2018-03-03 19:08:23 +00:00
|
|
|
void MacrosWindow::OnRemove(wxCommandEvent & WXUNUSED(event))
|
2010-01-23 19:44:49 +00:00
|
|
|
{
|
2018-03-03 19:08:23 +00:00
|
|
|
long item = mMacros->GetNextItem(-1,
|
2010-01-23 19:44:49 +00:00
|
|
|
wxLIST_NEXT_ALL,
|
|
|
|
wxLIST_STATE_SELECTED);
|
|
|
|
if (item == -1) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2018-03-03 19:08:23 +00:00
|
|
|
wxString name = mMacros->GetItemText(item);
|
2019-12-18 00:40:32 +00:00
|
|
|
AudacityMessageDialog m(
|
|
|
|
this,
|
|
|
|
/*i18n-hint: %s will be replaced by the name of a file.*/
|
|
|
|
XO("Are you sure you want to delete %s?").Format( name ),
|
|
|
|
Verbatim( GetTitle() ),
|
|
|
|
wxYES_NO | wxICON_QUESTION );
|
2012-05-23 18:52:52 +00:00
|
|
|
if (m.ShowModal() == wxID_NO) {
|
2018-03-14 16:57:33 +00:00
|
|
|
Raise();
|
2010-01-23 19:44:49 +00:00
|
|
|
return;
|
|
|
|
}
|
2018-03-14 16:57:33 +00:00
|
|
|
Raise();
|
2010-01-23 19:44:49 +00:00
|
|
|
|
2018-03-03 19:08:23 +00:00
|
|
|
mMacroCommands.DeleteMacro(name);
|
2010-01-23 19:44:49 +00:00
|
|
|
|
2018-03-17 15:38:09 +00:00
|
|
|
item++;
|
2018-03-03 19:08:23 +00:00
|
|
|
if (item >= (mMacros->GetItemCount() - 1) && item >= 0) {
|
2010-01-23 19:44:49 +00:00
|
|
|
item--;
|
|
|
|
}
|
|
|
|
|
2020-02-17 17:42:17 +00:00
|
|
|
// Bug 2284. The macro we have just removed might have been
|
|
|
|
// changed. Since we've just deleted the macro, we should
|
|
|
|
// forget about that change.
|
|
|
|
mChanged = false;
|
2021-03-22 17:45:54 +00:00
|
|
|
mSave->Enable( mChanged );
|
2018-03-03 19:08:23 +00:00
|
|
|
mActiveMacro = mMacros->GetItemText(item);
|
2010-01-23 19:44:49 +00:00
|
|
|
|
2018-03-03 19:08:23 +00:00
|
|
|
PopulateMacros();
|
2018-03-02 22:13:41 +00:00
|
|
|
UpdateMenus();
|
2010-01-23 19:44:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
///
|
2018-03-03 19:08:23 +00:00
|
|
|
void MacrosWindow::OnRename(wxCommandEvent & WXUNUSED(event))
|
2010-01-23 19:44:49 +00:00
|
|
|
{
|
2018-03-03 19:08:23 +00:00
|
|
|
long item = mMacros->GetNextItem(-1,
|
2010-01-23 19:44:49 +00:00
|
|
|
wxLIST_NEXT_ALL,
|
|
|
|
wxLIST_STATE_SELECTED);
|
|
|
|
if (item == -1) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2018-03-03 19:08:23 +00:00
|
|
|
mMacros->EditLabel(item);
|
2018-03-02 22:13:41 +00:00
|
|
|
UpdateMenus();
|
2010-01-23 19:44:49 +00:00
|
|
|
}
|
|
|
|
|
2019-07-16 06:37:07 +00:00
|
|
|
/// Reset a built in macro.
|
|
|
|
void MacrosWindow::OnRestore(wxCommandEvent & WXUNUSED(event))
|
|
|
|
{
|
|
|
|
mMacroCommands.RestoreMacro(mActiveMacro);
|
|
|
|
|
|
|
|
mChanged = true;
|
2021-03-22 17:45:54 +00:00
|
|
|
mSave->Enable( mChanged );
|
2019-07-16 06:37:07 +00:00
|
|
|
|
|
|
|
PopulateList();
|
|
|
|
}
|
|
|
|
|
2020-08-09 02:17:14 +00:00
|
|
|
///
|
|
|
|
void MacrosWindow::OnImport(wxCommandEvent & WXUNUSED(event))
|
|
|
|
{
|
|
|
|
if (!ChangeOK()) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
long item = mMacros->GetNextItem(-1,
|
|
|
|
wxLIST_NEXT_ALL,
|
|
|
|
wxLIST_STATE_SELECTED);
|
|
|
|
if (item == -1) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
wxString name = mMacros->GetItemText(item);
|
|
|
|
|
|
|
|
name = mMacroCommands.ReadMacro({}, this);
|
|
|
|
if (name == wxEmptyString) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
mActiveMacro = name;
|
|
|
|
|
|
|
|
PopulateMacros();
|
|
|
|
UpdateMenus();
|
|
|
|
}
|
|
|
|
|
|
|
|
///
|
|
|
|
void MacrosWindow::OnExport(wxCommandEvent & WXUNUSED(event))
|
|
|
|
{
|
|
|
|
long item = mMacros->GetNextItem(-1,
|
|
|
|
wxLIST_NEXT_ALL,
|
|
|
|
wxLIST_STATE_SELECTED);
|
|
|
|
if (item == -1) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
mMacroCommands.WriteMacro(mMacros->GetItemText(item), this);
|
|
|
|
}
|
|
|
|
|
2021-03-22 17:45:54 +00:00
|
|
|
void MacrosWindow::OnSave(wxCommandEvent & WXUNUSED(event))
|
|
|
|
{
|
|
|
|
SaveChanges();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-01-23 19:44:49 +00:00
|
|
|
/// An item in the list has been selected.
|
|
|
|
/// Bring up a dialog to allow its parameters to be edited.
|
2018-03-03 19:08:23 +00:00
|
|
|
void MacrosWindow::OnCommandActivated(wxListEvent & WXUNUSED(event))
|
2010-01-23 19:44:49 +00:00
|
|
|
{
|
2018-03-01 17:54:08 +00:00
|
|
|
wxCommandEvent dummy;
|
|
|
|
OnEditCommandParams( dummy );
|
2010-01-23 19:44:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
///
|
2018-03-03 19:08:23 +00:00
|
|
|
void MacrosWindow::OnInsert(wxCommandEvent & WXUNUSED(event))
|
2010-01-23 19:44:49 +00:00
|
|
|
{
|
|
|
|
long item = mList->GetNextItem(-1,
|
|
|
|
wxLIST_NEXT_ALL,
|
|
|
|
wxLIST_STATE_SELECTED);
|
2018-03-01 17:54:08 +00:00
|
|
|
if (item == -1) {
|
|
|
|
item = mList->GetItemCount()-1;
|
|
|
|
}
|
|
|
|
InsertCommandAt( item );
|
|
|
|
}
|
|
|
|
|
2018-03-03 19:08:23 +00:00
|
|
|
void MacrosWindow::InsertCommandAt(int item)
|
2018-03-01 17:54:08 +00:00
|
|
|
{
|
2010-01-23 19:44:49 +00:00
|
|
|
if (item == -1) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2019-05-22 01:04:18 +00:00
|
|
|
MacroCommandDialog d(this, wxID_ANY, mProject);
|
2010-01-23 19:44:49 +00:00
|
|
|
|
|
|
|
if (!d.ShowModal()) {
|
2018-03-14 16:57:33 +00:00
|
|
|
Raise();
|
2010-01-23 19:44:49 +00:00
|
|
|
return;
|
|
|
|
}
|
2018-03-14 16:57:33 +00:00
|
|
|
Raise();
|
2010-01-23 19:44:49 +00:00
|
|
|
|
2019-03-14 17:04:37 +00:00
|
|
|
if(!d.mSelectedCommand.empty())
|
2011-08-18 22:53:13 +00:00
|
|
|
{
|
2018-03-03 19:08:23 +00:00
|
|
|
mMacroCommands.AddToMacro(d.mSelectedCommand,
|
2011-08-18 22:53:13 +00:00
|
|
|
d.mSelectedParameters,
|
|
|
|
item);
|
|
|
|
mChanged = true;
|
2021-03-22 17:45:54 +00:00
|
|
|
mSave->Enable( mChanged );
|
|
|
|
|
2011-08-18 22:53:13 +00:00
|
|
|
mSelectedCommand = item + 1;
|
|
|
|
PopulateList();
|
|
|
|
}
|
2018-03-14 16:57:33 +00:00
|
|
|
|
2010-01-23 19:44:49 +00:00
|
|
|
}
|
|
|
|
|
2018-03-03 19:08:23 +00:00
|
|
|
void MacrosWindow::OnEditCommandParams(wxCommandEvent & WXUNUSED(event))
|
2018-03-01 17:54:08 +00:00
|
|
|
{
|
|
|
|
int item = mList->GetNextItem( -1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED );
|
|
|
|
|
|
|
|
// LAST command in list is END.
|
|
|
|
// If nothing selected, add at END.
|
|
|
|
// If END selected, add at END.
|
|
|
|
// When adding at end we use InsertCommandAt, so that a new command
|
|
|
|
// can be chosen.
|
|
|
|
int lastItem = mList->GetItemCount()-1;
|
|
|
|
if( (item<0) || (item+1) == mList->GetItemCount() )
|
|
|
|
{
|
|
|
|
InsertCommandAt( lastItem );
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Just edit the parameters, and not the command.
|
2019-03-11 02:05:37 +00:00
|
|
|
auto command = mMacroCommands.GetCommand(item);
|
2018-03-03 19:08:23 +00:00
|
|
|
wxString params = mMacroCommands.GetParams(item);
|
2020-02-26 10:50:26 +00:00
|
|
|
wxString oldParams = params;
|
2018-03-01 17:54:08 +00:00
|
|
|
|
2020-01-06 15:09:18 +00:00
|
|
|
params = MacroCommands::PromptForParamsFor(command, params, *this).Trim();
|
2018-03-14 16:57:33 +00:00
|
|
|
Raise();
|
2018-03-01 17:54:08 +00:00
|
|
|
|
2020-02-26 10:50:26 +00:00
|
|
|
if (oldParams == params)
|
|
|
|
return; // They did not actually make any changes..
|
|
|
|
|
2018-03-03 19:08:23 +00:00
|
|
|
mMacroCommands.DeleteFromMacro(item);
|
|
|
|
mMacroCommands.AddToMacro(command,
|
2020-02-26 10:50:26 +00:00
|
|
|
params,
|
|
|
|
item);
|
2021-03-22 17:45:54 +00:00
|
|
|
|
2018-03-01 17:54:08 +00:00
|
|
|
mChanged = true;
|
2021-03-22 17:45:54 +00:00
|
|
|
mSave->Enable( mChanged );
|
|
|
|
|
2018-03-01 17:54:08 +00:00
|
|
|
mSelectedCommand = item;
|
|
|
|
PopulateList();
|
|
|
|
}
|
|
|
|
|
2010-01-23 19:44:49 +00:00
|
|
|
///
|
2018-03-03 19:08:23 +00:00
|
|
|
void MacrosWindow::OnDelete(wxCommandEvent & WXUNUSED(event))
|
2010-01-23 19:44:49 +00:00
|
|
|
{
|
|
|
|
long item = mList->GetNextItem(-1,
|
|
|
|
wxLIST_NEXT_ALL,
|
|
|
|
wxLIST_STATE_SELECTED);
|
|
|
|
if (item == -1 || item + 1 == mList->GetItemCount()) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2018-03-03 19:08:23 +00:00
|
|
|
mMacroCommands.DeleteFromMacro(item);
|
2021-03-22 17:45:54 +00:00
|
|
|
|
2010-01-23 19:44:49 +00:00
|
|
|
mChanged = true;
|
2021-03-22 17:45:54 +00:00
|
|
|
mSave->Enable( mChanged );
|
2010-01-23 19:44:49 +00:00
|
|
|
|
|
|
|
if (item >= (mList->GetItemCount() - 2) && item >= 0) {
|
|
|
|
item--;
|
|
|
|
}
|
|
|
|
mSelectedCommand = item;
|
|
|
|
PopulateList();
|
|
|
|
}
|
|
|
|
|
|
|
|
///
|
2018-03-03 19:08:23 +00:00
|
|
|
void MacrosWindow::OnUp(wxCommandEvent & WXUNUSED(event))
|
2010-01-23 19:44:49 +00:00
|
|
|
{
|
|
|
|
long item = mList->GetNextItem(-1,
|
|
|
|
wxLIST_NEXT_ALL,
|
|
|
|
wxLIST_STATE_SELECTED);
|
|
|
|
if (item == -1 || item == 0 || item + 1 == mList->GetItemCount()) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2018-03-03 19:08:23 +00:00
|
|
|
mMacroCommands.AddToMacro(mMacroCommands.GetCommand(item),
|
|
|
|
mMacroCommands.GetParams(item),
|
2010-01-23 19:44:49 +00:00
|
|
|
item - 1);
|
2018-03-03 19:08:23 +00:00
|
|
|
mMacroCommands.DeleteFromMacro(item + 1);
|
2021-03-22 17:45:54 +00:00
|
|
|
|
2010-01-23 19:44:49 +00:00
|
|
|
mChanged = true;
|
2021-03-22 17:45:54 +00:00
|
|
|
mSave->Enable( mChanged );
|
|
|
|
|
2010-01-23 19:44:49 +00:00
|
|
|
mSelectedCommand = item - 1;
|
|
|
|
PopulateList();
|
|
|
|
}
|
|
|
|
|
|
|
|
///
|
2018-03-03 19:08:23 +00:00
|
|
|
void MacrosWindow::OnDown(wxCommandEvent & WXUNUSED(event))
|
2010-01-23 19:44:49 +00:00
|
|
|
{
|
|
|
|
long item = mList->GetNextItem(-1,
|
|
|
|
wxLIST_NEXT_ALL,
|
|
|
|
wxLIST_STATE_SELECTED);
|
|
|
|
if (item == -1 || item + 2 >= mList->GetItemCount()) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2018-03-03 19:08:23 +00:00
|
|
|
mMacroCommands.AddToMacro(mMacroCommands.GetCommand(item),
|
|
|
|
mMacroCommands.GetParams(item),
|
2010-01-23 19:44:49 +00:00
|
|
|
item + 2);
|
2018-03-03 19:08:23 +00:00
|
|
|
mMacroCommands.DeleteFromMacro(item);
|
2021-03-22 17:45:54 +00:00
|
|
|
|
2010-01-23 19:44:49 +00:00
|
|
|
mChanged = true;
|
2021-03-22 17:45:54 +00:00
|
|
|
mSave->Enable( mChanged );
|
|
|
|
|
2010-01-23 19:44:49 +00:00
|
|
|
mSelectedCommand = item + 1;
|
|
|
|
PopulateList();
|
|
|
|
}
|
|
|
|
|
2018-03-03 19:08:23 +00:00
|
|
|
void MacrosWindow::OnApplyToProject(wxCommandEvent & event)
|
2018-03-01 17:54:08 +00:00
|
|
|
{
|
|
|
|
if( !SaveChanges() )
|
|
|
|
return;
|
2018-03-03 19:08:23 +00:00
|
|
|
ApplyMacroDialog::OnApplyToProject( event );
|
2018-03-01 17:54:08 +00:00
|
|
|
}
|
|
|
|
|
2018-03-03 19:08:23 +00:00
|
|
|
void MacrosWindow::OnApplyToFiles(wxCommandEvent & event)
|
2018-03-01 17:54:08 +00:00
|
|
|
{
|
|
|
|
if( !SaveChanges() )
|
|
|
|
return;
|
2018-03-03 19:08:23 +00:00
|
|
|
ApplyMacroDialog::OnApplyToFiles( event );
|
2018-03-01 17:54:08 +00:00
|
|
|
}
|
|
|
|
|
2018-03-03 19:08:23 +00:00
|
|
|
bool MacrosWindow::SaveChanges(){
|
|
|
|
gPrefs->Write(wxT("/Batch/ActiveMacro"), mActiveMacro);
|
2012-08-02 06:03:19 +00:00
|
|
|
gPrefs->Flush();
|
2010-01-23 19:44:49 +00:00
|
|
|
|
|
|
|
if (mChanged) {
|
2018-03-03 19:08:23 +00:00
|
|
|
if (!mMacroCommands.WriteMacro(mActiveMacro)) {
|
2018-03-01 17:54:08 +00:00
|
|
|
return false;
|
2010-01-23 19:44:49 +00:00
|
|
|
}
|
|
|
|
}
|
2021-03-22 17:45:54 +00:00
|
|
|
|
2018-03-01 17:54:08 +00:00
|
|
|
mChanged = false;
|
2021-03-22 17:45:54 +00:00
|
|
|
if( mSave )
|
|
|
|
mSave->Enable( mChanged );
|
|
|
|
|
2018-03-01 17:54:08 +00:00
|
|
|
return true;
|
|
|
|
}
|
2010-01-23 19:44:49 +00:00
|
|
|
|
2018-03-01 17:54:08 +00:00
|
|
|
/// Send changed values back to Prefs, and update Audacity.
|
2018-03-03 19:08:23 +00:00
|
|
|
void MacrosWindow::OnOK(wxCommandEvent & WXUNUSED(event))
|
2018-03-01 17:54:08 +00:00
|
|
|
{
|
|
|
|
if( !SaveChanges() )
|
|
|
|
return;
|
2018-03-03 18:01:40 +00:00
|
|
|
Hide();
|
|
|
|
//EndModal(true);
|
2010-01-23 19:44:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
///
|
2018-03-03 22:20:25 +00:00
|
|
|
void MacrosWindow::OnCancel(wxCommandEvent &WXUNUSED(event))
|
2010-01-23 19:44:49 +00:00
|
|
|
{
|
2020-08-22 12:41:18 +00:00
|
|
|
bool bWasChanged = mChanged;
|
2010-01-23 19:44:49 +00:00
|
|
|
if (!ChangeOK()) {
|
|
|
|
return;
|
|
|
|
}
|
2020-08-22 12:41:18 +00:00
|
|
|
// If we've rejected a change, we need to restore the display
|
|
|
|
// of the active macro.
|
|
|
|
// That's because next time we open this dialog we want to see the
|
|
|
|
// unedited macro.
|
|
|
|
if( bWasChanged )
|
|
|
|
ShowActiveMacro();
|
2018-03-03 18:01:40 +00:00
|
|
|
Hide();
|
2010-01-23 19:44:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
///
|
2018-03-03 19:08:23 +00:00
|
|
|
void MacrosWindow::OnKeyDown(wxKeyEvent &event)
|
2010-01-23 19:44:49 +00:00
|
|
|
{
|
|
|
|
if (event.GetKeyCode() == WXK_DELETE) {
|
2013-03-10 09:05:41 +00:00
|
|
|
wxLogDebug(wxT("wxKeyEvent"));
|
2010-01-23 19:44:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
event.Skip();
|
|
|
|
}
|
2019-12-07 19:30:07 +00:00
|
|
|
|
|
|
|
TranslatableString MacrosWindow::WindowTitle() const
|
|
|
|
{
|
2021-02-14 07:25:52 +00:00
|
|
|
return mbExpanded ? ManageMacrosTitle : MacrosPaletteTitle;
|
|
|
|
}
|
|
|
|
|
|
|
|
// PrefsListener implementation
|
|
|
|
void MacrosWindow::UpdatePrefs()
|
|
|
|
{
|
|
|
|
UpdateDisplay(mbExpanded);
|
2019-12-07 19:30:07 +00:00
|
|
|
}
|