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
|
|
|
|
|
|
|
*//*******************************************************************/
|
|
|
|
|
|
|
|
#include "Audacity.h"
|
2015-06-18 14:24:36 +00:00
|
|
|
#include "BatchProcessDialog.h"
|
2010-01-23 19:44:49 +00:00
|
|
|
|
|
|
|
#include <wx/defs.h>
|
|
|
|
#include <wx/checkbox.h>
|
|
|
|
#include <wx/choice.h>
|
|
|
|
#include <wx/filedlg.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>
|
|
|
|
|
2016-12-03 19:33:37 +00:00
|
|
|
#include "AudacityException.h"
|
2015-06-18 14:24:36 +00:00
|
|
|
#include "ShuttleGui.h"
|
2010-01-23 19:44:49 +00:00
|
|
|
#include "Prefs.h"
|
|
|
|
#include "Project.h"
|
|
|
|
#include "Internat.h"
|
|
|
|
#include "commands/CommandManager.h"
|
Automation: AudacityCommand
This is a squash of 50 commits.
This merges the capabilities of BatchCommands and Effects using a new
AudacityCommand class. AudacityCommand provides one function to specify the
parameters, and then we leverage that one function in automation, whether by chains,
mod-script-pipe or (future) Nyquist.
- Now have AudacityCommand which is using the same mechanism as Effect
- Has configurable parameters
- Has data-entry GUI (built using shuttle GUI)
- Registers with PluginManager.
- Menu commands now provided in chains, and to python batch.
- Tested with Zoom Toggle.
- ShuttleParams now can set, get, set defaults, validate and specify
the parameters.
- Bugfix: Don't overwrite values with defaults first time out.
- Add DefineParams function for all built-in effects.
- Extend CommandContext to carry output channels for results.
We abuse EffectsManager. It handles both Effects and
AudacityCommands now. In time an Effect should become a special case of
AudacityCommand and we'll split and rename the EffectManager class.
- Don't use 'default' as a parameter name.
- Massive renaming for CommandDefinitionInterface
- EffectIdentInterface becomes EffectDefinitionInterface
- EffectAutomationParameters becomes CommandAutomationParameters
- PluginType is now a bit field.
This way we can search for related types at the same time.
- Most old batch commands made into AudacityCommands.
The ones that weren't are for a reason. They are used by mod-script-pipe
to carry commands and responses across from a non-GUI thread to the GUI
thread.
- Major tidy up of ScreenshotCommand
- Reworking of SelectCommand
- GetPreferenceCommand and SetPreferenceCommand
- GetTrackInfo and SetTrackInfo
- GetInfoCommand
- Help, Open, Save, Import and Export commands.
- Removed obsolete commands ExecMenu, GetProjectInfo and SetProjectInfo
which are now better handled by other commands.
- JSONify "GetInfo: Commands" output, i.e. commas in the right places.
- General work on better Doxygen.
- Lyrics -> LyricsPanel
- Meter -> MeterPanel
- Updated Linux makefile.
- Scripting commands added into Extra menu.
- Distinct names for previously duplicated find-clipping parameters.
- Fixed longstanding error with erroneous status field number which
previously caused an ASSERT in debug.
- Sensible formatting of numbers in Chains, 0.1 not 0.1000000000137
2018-01-14 18:51:41 +00:00
|
|
|
#include "commands/CommandContext.h"
|
2010-01-23 19:44:49 +00:00
|
|
|
#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 "BatchCommands.h"
|
2016-02-24 16:41:26 +00:00
|
|
|
#include "Track.h"
|
2010-01-23 19:44:49 +00:00
|
|
|
#include "UndoManager.h"
|
|
|
|
|
|
|
|
#include "Theme.h"
|
|
|
|
#include "AllThemeResources.h"
|
|
|
|
|
|
|
|
#include "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"
|
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
|
|
|
|
|
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)
|
|
|
|
EVT_BUTTON(wxID_HELP, ApplyMacroDialog::OnHelp)
|
2010-01-23 19:44:49 +00:00
|
|
|
END_EVENT_TABLE()
|
|
|
|
|
2018-03-03 19:08:23 +00:00
|
|
|
ApplyMacroDialog::ApplyMacroDialog(wxWindow * parent, bool bInherited):
|
2018-03-17 15:42:30 +00:00
|
|
|
wxDialogWrapper(parent, wxID_ANY, _("Macros Palette"),
|
2010-01-23 19:44:49 +00:00
|
|
|
wxDefaultPosition, wxDefaultSize,
|
|
|
|
wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)
|
2018-03-08 04:42:57 +00:00
|
|
|
, mCatalog( GetActiveProject() )
|
2010-01-23 19:44:49 +00:00
|
|
|
{
|
2013-08-25 21:51:26 +00:00
|
|
|
//AudacityProject * p = GetActiveProject();
|
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;
|
2018-03-17 15:42:30 +00:00
|
|
|
SetLabel(_("Macros Palette")); // Provide visual label
|
|
|
|
SetName(_("Macros Palette")); // 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.*/
|
2018-07-30 10:34:00 +00:00
|
|
|
S.StartStatic(_("Select Macro"), 1);
|
2010-01-23 19:44:49 +00:00
|
|
|
{
|
2018-03-14 16:37:15 +00:00
|
|
|
S.SetStyle(wxSUNKEN_BORDER | wxLC_REPORT | wxLC_HRULES | wxLC_VRULES |
|
|
|
|
wxLC_SINGLE_SEL);
|
|
|
|
mMacros = S.Id(MacrosListID).Prop(1).AddListControlReportMode();
|
|
|
|
mMacros->InsertColumn(0, _("Macro"), wxLIST_FORMAT_LEFT);
|
|
|
|
}
|
|
|
|
S.EndStatic();
|
2018-03-05 15:00:11 +00:00
|
|
|
|
2018-03-14 16:37:15 +00:00
|
|
|
S.StartHorizontalLay(wxEXPAND, 0);
|
|
|
|
{
|
|
|
|
S.AddPrompt( _("Apply Macro to:") );
|
2018-07-30 10:34:00 +00:00
|
|
|
wxButton* btn = S.Id(ApplyToProjectID).AddButton(_("&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
|
|
|
btn->SetName(_("Apply macro to project"));
|
|
|
|
|
|
|
|
btn = S.Id(ApplyToFilesID).AddButton(_("&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-07-30 10:34:00 +00:00
|
|
|
btn->SetName(_("Apply macro to files..."));
|
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);
|
|
|
|
{
|
|
|
|
mResize = S.Id(ExpandID).AddButton(_("&Expand"));
|
|
|
|
S.Prop(1).AddSpace( 10 );
|
|
|
|
S.AddStandardButtons( eCancelButton | 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
|
|
|
{
|
2018-03-03 19:08:23 +00:00
|
|
|
wxArrayString 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();
|
2018-03-03 18:01:40 +00:00
|
|
|
for (i = 0; i < (int)names.GetCount(); 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-03-03 19:08:23 +00:00
|
|
|
mMacros->SetItemState(item, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED);
|
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
|
|
|
{
|
|
|
|
wxString page = GetHelpPageName();
|
|
|
|
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) {
|
2018-03-03 19:08:23 +00:00
|
|
|
AudacityMessageBox(_("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
|
|
|
}
|
|
|
|
|
2018-03-04 19:02:22 +00:00
|
|
|
wxString ApplyMacroDialog::MacroIdOfName( const wxString & MacroName )
|
|
|
|
{
|
|
|
|
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.
|
|
|
|
void ApplyMacroDialog::ApplyMacroToProject( const wxString & MacroID, bool bHasGui )
|
|
|
|
{
|
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);
|
2018-03-02 21:56:24 +00:00
|
|
|
if( name.IsEmpty() )
|
|
|
|
return;
|
2010-01-23 19:44:49 +00:00
|
|
|
|
2018-03-03 18:01:40 +00:00
|
|
|
wxDialogWrapper activityWin( this, wxID_ANY, GetTitle());
|
|
|
|
activityWin.SetName(activityWin.GetTitle());
|
|
|
|
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);
|
|
|
|
S.AddFixedText(wxString::Format(_("Applying '%s' to current project"),
|
2017-10-09 05:03:14 +00:00
|
|
|
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-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-03-03 18:01:40 +00:00
|
|
|
wxWindowDisabler wd(&activityWin);
|
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) {
|
2018-03-03 19:08:23 +00:00
|
|
|
AudacityMessageBox(_("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
|
|
|
|
|
|
|
AudacityProject *project = GetActiveProject();
|
|
|
|
if (!project->GetIsEmpty()) {
|
2017-09-06 21:39:33 +00:00
|
|
|
AudacityMessageBox(_("Please save and close the current project first."));
|
2010-01-23 19:44:49 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2012-04-26 22:57:04 +00:00
|
|
|
wxString prompt = _("Select file(s) for batch processing...");
|
2014-06-03 20:30:19 +00:00
|
|
|
|
2010-01-23 19:44:49 +00:00
|
|
|
FormatList l;
|
|
|
|
wxString filter;
|
|
|
|
wxString all;
|
|
|
|
|
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
|
|
|
Importer::Get().GetSupportedImportFormats(&l);
|
2016-02-19 15:59:51 +00:00
|
|
|
for (const auto &format : l) {
|
|
|
|
const Format *f = &format;
|
2010-01-23 19:44:49 +00:00
|
|
|
|
|
|
|
wxString newfilter = f->formatName + wxT("|");
|
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
|
|
|
for (size_t i = 0; i < f->formatExtensions.size(); i++) {
|
2010-01-23 19:44:49 +00:00
|
|
|
if (!newfilter.Contains(wxT("*.") + f->formatExtensions[i] + wxT(";")))
|
|
|
|
newfilter += wxT("*.") + f->formatExtensions[i] + wxT(";");
|
|
|
|
if (!all.Contains(wxT("*.") + f->formatExtensions[i] + wxT(";")))
|
|
|
|
all += wxT("*.") + f->formatExtensions[i] + wxT(";");
|
|
|
|
}
|
|
|
|
newfilter.RemoveLast(1);
|
|
|
|
filter += newfilter;
|
|
|
|
filter += wxT("|");
|
|
|
|
}
|
|
|
|
all.RemoveLast(1);
|
|
|
|
filter.RemoveLast(1);
|
|
|
|
|
|
|
|
wxString mask = _("All files|*|All supported files|") +
|
|
|
|
all + wxT("|") +
|
|
|
|
filter;
|
|
|
|
|
|
|
|
wxString type = gPrefs->Read(wxT("/DefaultOpenType"),mask.BeforeFirst(wxT('|')));
|
|
|
|
// Convert the type to the filter index
|
|
|
|
int index = mask.First(type + wxT("|"));
|
|
|
|
if (index == wxNOT_FOUND) {
|
|
|
|
index = 0;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
index = mask.Left(index).Freq(wxT('|')) / 2;
|
|
|
|
if (index < 0) {
|
|
|
|
index = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
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,
|
2013-02-20 23:42:58 +00:00
|
|
|
prompt,
|
|
|
|
path,
|
|
|
|
wxT(""),
|
|
|
|
mask,
|
2010-01-23 19:44:49 +00:00
|
|
|
wxFD_OPEN | wxFD_MULTIPLE | wxRESIZE_BORDER);
|
|
|
|
|
|
|
|
dlog.SetFilterIndex(index);
|
|
|
|
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();
|
|
|
|
|
2018-03-03 18:01:40 +00:00
|
|
|
wxDialogWrapper activityWin(this, wxID_ANY, GetTitle());
|
|
|
|
activityWin.SetName(activityWin.GetTitle());
|
|
|
|
ShuttleGui S(&activityWin, eIsCreating);
|
2010-01-23 19:44:49 +00:00
|
|
|
|
2018-03-23 09:30:25 +00:00
|
|
|
wxListCtrl * fileList = NULL;
|
|
|
|
|
2010-01-23 19:44:49 +00:00
|
|
|
S.StartVerticalLay(false);
|
|
|
|
{
|
|
|
|
S.StartStatic(_("Applying..."), 1);
|
|
|
|
{
|
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));
|
|
|
|
|
|
|
|
S.SetStyle(wxSUNKEN_BORDER | wxLC_REPORT | wxLC_HRULES | wxLC_VRULES |
|
|
|
|
wxLC_SINGLE_SEL);
|
2018-03-23 09:30:25 +00:00
|
|
|
fileList = S.Id(CommandsListID).AddListControlReportMode();
|
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);
|
|
|
|
fileList->InsertColumn(0, _("File"), wxLIST_FORMAT_LEFT);
|
2010-01-23 19:44:49 +00:00
|
|
|
}
|
|
|
|
S.EndStatic();
|
|
|
|
|
|
|
|
S.StartHorizontalLay(wxCENTER, false);
|
|
|
|
{
|
|
|
|
S.Id(wxID_CANCEL).AddButton(_("&Cancel"));
|
|
|
|
}
|
|
|
|
S.EndHorizontalLay();
|
|
|
|
}
|
|
|
|
S.EndVerticalLay();
|
|
|
|
|
|
|
|
int i;
|
|
|
|
for (i = 0; i < (int)files.GetCount(); 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
|
|
|
|
2018-03-23 09:30:25 +00:00
|
|
|
int width = fileList->GetColumnWidth(0);
|
|
|
|
wxSize sz = fileList->GetClientSize();
|
2010-01-23 19:44:49 +00:00
|
|
|
if (width > sz.GetWidth() && width < 500) {
|
|
|
|
sz.SetWidth(width);
|
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();
|
|
|
|
|
2018-03-03 19:08:23 +00:00
|
|
|
mMacroCommands.ReadMacro(name);
|
2010-01-23 19:44:49 +00:00
|
|
|
for (i = 0; i < (int)files.GetCount(); i++) {
|
2018-03-03 18:01:40 +00:00
|
|
|
wxWindowDisabler wd(&activityWin);
|
2010-01-23 19:44:49 +00:00
|
|
|
if (i > 0) {
|
|
|
|
//Clear the arrow in previous item.
|
2018-03-23 09:30:25 +00:00
|
|
|
fileList->SetItemImage(i - 1, 0, 0);
|
2010-01-23 19:44:49 +00:00
|
|
|
}
|
2018-03-23 09:30:25 +00:00
|
|
|
fileList->SetItemImage(i, 1, 1);
|
|
|
|
fileList->EnsureVisible(i);
|
2010-01-23 19:44:49 +00:00
|
|
|
|
2016-12-03 19:33:37 +00:00
|
|
|
auto success = GuardedCall< bool >( [&] {
|
|
|
|
project->Import(files[i]);
|
2017-12-30 19:13:31 +00:00
|
|
|
project->ZoomAfterImport(nullptr);
|
2017-08-19 14:15:32 +00:00
|
|
|
project->OnSelectAll(*project);
|
2018-03-08 04:42:57 +00:00
|
|
|
if (!mMacroCommands.ApplyMacro(mCatalog))
|
2016-12-03 19:33:37 +00:00
|
|
|
return false;
|
2010-01-23 19:44:49 +00:00
|
|
|
|
2018-03-03 18:01:40 +00:00
|
|
|
if (!activityWin.IsShown() || mAbort)
|
2016-12-03 19:33:37 +00:00
|
|
|
return false;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
} );
|
|
|
|
|
|
|
|
if (!success)
|
2010-01-23 19:44:49 +00:00
|
|
|
break;
|
2016-12-03 19:33:37 +00:00
|
|
|
|
2010-01-23 19:44:49 +00:00
|
|
|
UndoManager *um = project->GetUndoManager();
|
|
|
|
um->ClearStates();
|
2017-08-19 14:15:32 +00:00
|
|
|
project->OnSelectAll(*project);
|
|
|
|
project->OnRemoveTracks(*project);
|
2010-01-23 19:44:49 +00:00
|
|
|
}
|
2017-08-19 14:15:32 +00:00
|
|
|
project->OnRemoveTracks(*project);
|
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,
|
|
|
|
ImportButtonID,
|
|
|
|
ExportButtonID,
|
|
|
|
DefaultsButtonID,
|
|
|
|
InsertButtonID,
|
2018-03-01 17:54:08 +00:00
|
|
|
EditButtonID,
|
2010-01-23 19:44:49 +00:00
|
|
|
DeleteButtonID,
|
|
|
|
UpButtonID,
|
|
|
|
DownButtonID,
|
2018-03-01 17:54:08 +00:00
|
|
|
RenameButtonID,
|
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)
|
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(DefaultsButtonID, MacrosWindow::OnDefaults)
|
|
|
|
|
|
|
|
EVT_BUTTON(wxID_OK, MacrosWindow::OnOK)
|
|
|
|
EVT_BUTTON(wxID_CANCEL, MacrosWindow::OnCancel)
|
|
|
|
|
|
|
|
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
|
|
|
BlankColumn,
|
|
|
|
ItemNumberColumn,
|
|
|
|
ActionColumn,
|
2010-01-23 19:44:49 +00:00
|
|
|
ParamsColumn,
|
|
|
|
};
|
|
|
|
|
|
|
|
/// Constructor
|
2018-03-03 19:08:23 +00:00
|
|
|
MacrosWindow::MacrosWindow(wxWindow * parent, bool bExpanded):
|
|
|
|
ApplyMacroDialog(parent, true)
|
2010-01-23 19:44:49 +00:00
|
|
|
{
|
2018-03-03 18:01:40 +00:00
|
|
|
mbExpanded = bExpanded;
|
2018-03-17 15:42:30 +00:00
|
|
|
wxString Title = mbExpanded ? _("Manage Macros") : _("Macros Palette");
|
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);
|
|
|
|
{
|
2018-07-30 10:34:00 +00:00
|
|
|
S.StartStatic(_("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
|
|
|
{
|
|
|
|
S.SetStyle(wxSUNKEN_BORDER | wxLC_REPORT | wxLC_HRULES | wxLC_SINGLE_SEL |
|
2018-03-14 16:37:15 +00:00
|
|
|
wxLC_EDIT_LABELS);
|
2018-03-03 22:20:25 +00:00
|
|
|
mMacros = S.Id(MacrosListID).Prop(1).AddListControlReportMode();
|
|
|
|
// i18n-hint: This is the heading for a column in the edit macros dialog
|
|
|
|
mMacros->InsertColumn(0, _("Macro"), wxLIST_FORMAT_LEFT);
|
2018-03-14 16:37:15 +00:00
|
|
|
S.StartVerticalLay(wxALIGN_TOP, 0);
|
|
|
|
{
|
|
|
|
S.Id(AddButtonID).AddButton(_("&New"));
|
|
|
|
mRemove = S.Id(RemoveButtonID).AddButton(_("Remo&ve"));
|
|
|
|
mRename = S.Id(RenameButtonID).AddButton(_("&Rename..."));
|
|
|
|
S.Id(ImportButtonID).AddButton(_("I&mport..."))->Enable( false);
|
|
|
|
S.Id(ExportButtonID).AddButton(_("E&xport..."))->Enable( false);
|
|
|
|
}
|
|
|
|
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
|
|
|
|
2018-07-30 10:34:00 +00:00
|
|
|
S.StartStatic(_("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-03-01 21:57:44 +00:00
|
|
|
|
2018-03-14 16:37:15 +00:00
|
|
|
S.SetStyle(wxSUNKEN_BORDER | wxLC_REPORT | wxLC_HRULES | wxLC_VRULES |
|
|
|
|
wxLC_SINGLE_SEL);
|
|
|
|
mList = S.Id(CommandsListID).AddListControlReportMode();
|
|
|
|
|
|
|
|
//An empty first column is a workaround - under Win98 the first column
|
|
|
|
//can't be right aligned.
|
|
|
|
mList->InsertColumn(BlankColumn, wxT(""), wxLIST_FORMAT_LEFT);
|
|
|
|
/* i18n-hint: This is the number of the command in the list */
|
|
|
|
mList->InsertColumn(ItemNumberColumn, _("Num"), wxLIST_FORMAT_RIGHT);
|
|
|
|
mList->InsertColumn(ActionColumn, _("Command "), wxLIST_FORMAT_RIGHT);
|
|
|
|
mList->InsertColumn(ParamsColumn, _("Parameters"), wxLIST_FORMAT_LEFT);
|
|
|
|
|
|
|
|
S.StartVerticalLay(wxALIGN_TOP, 0);
|
|
|
|
{
|
|
|
|
S.Id(InsertButtonID).AddButton(_("&Insert"), wxALIGN_LEFT);
|
|
|
|
S.Id(EditButtonID).AddButton(_("&Edit..."), wxALIGN_LEFT);
|
|
|
|
S.Id(DeleteButtonID).AddButton(_("De&lete"), wxALIGN_LEFT);
|
|
|
|
S.Id(UpButtonID).AddButton(_("Move &Up"), wxALIGN_LEFT);
|
|
|
|
S.Id(DownButtonID).AddButton(_("Move &Down"), wxALIGN_LEFT);
|
|
|
|
mDefaults = S.Id(DefaultsButtonID).AddButton(_("De&faults"));
|
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);
|
|
|
|
{
|
|
|
|
mResize = S.Id(ShrinkID).AddButton(_("Shrin&k"));
|
|
|
|
// Using variable text just to get the positioning options.
|
|
|
|
S.Prop(0).AddVariableText( _("Apply Macro to:"), false, wxALL | wxALIGN_CENTRE_VERTICAL );
|
2018-07-30 10:34:00 +00:00
|
|
|
wxButton* btn = S.Id(ApplyToProjectID).AddButton(_("&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
|
|
|
btn->SetName(_("Apply macro to project"));
|
|
|
|
|
|
|
|
btn = S.Id(ApplyToFilesID).AddButton(_("&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-07-30 10:34:00 +00:00
|
|
|
btn->SetName(_("Apply macro to files..."));
|
2018-03-14 16:37:15 +00:00
|
|
|
S.Prop(1).AddSpace( 10 );
|
|
|
|
S.AddStandardButtons( eOkButton | eCancelButton | eHelpButton);
|
|
|
|
}
|
|
|
|
S.EndHorizontalLay();
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
mList->SetItemState(mSelectedCommand, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED);
|
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
|
2018-03-03 19:08:23 +00:00
|
|
|
void MacrosWindow::AddItem(const wxString &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()
|
2018-03-15 23:06:30 +00:00
|
|
|
? entry->name.Translated()
|
2018-03-06 20:28:05 +00:00
|
|
|
:
|
|
|
|
// Expose an internal name to the user in default of any friendly name
|
|
|
|
// -- AVOID THIS!
|
|
|
|
Action;
|
2018-01-10 02:49:49 +00:00
|
|
|
|
2010-01-23 19:44:49 +00:00
|
|
|
int i = mList->GetItemCount();
|
|
|
|
|
|
|
|
mList->InsertItem(i, wxT(""));
|
|
|
|
mList->SetItem(i, ItemNumberColumn, 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.
|
2018-03-02 22:13:41 +00:00
|
|
|
GetActiveProject()->RebuildMenuBar();
|
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
|
|
|
{
|
2018-03-03 22:20:25 +00:00
|
|
|
if( bExpanded == mbExpanded )
|
|
|
|
return;
|
2018-03-04 19:16:30 +00:00
|
|
|
|
|
|
|
if( !SaveChanges() )
|
|
|
|
return;
|
|
|
|
|
2018-03-03 22:20:25 +00:00
|
|
|
mbExpanded = bExpanded;
|
|
|
|
DestroyChildren();
|
|
|
|
SetSizer( nullptr );
|
|
|
|
|
|
|
|
mChanged = false;
|
|
|
|
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
|
|
|
|
2018-03-17 15:42:30 +00:00
|
|
|
wxString Title = mbExpanded ? _("Manage Macros") : _("Macros Palette");
|
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))
|
|
|
|
{ UpdateDisplay( false );}
|
|
|
|
|
|
|
|
|
2018-03-03 19:08:23 +00:00
|
|
|
bool MacrosWindow::ChangeOK()
|
2010-01-23 19:44:49 +00:00
|
|
|
{
|
|
|
|
if (mChanged) {
|
|
|
|
wxString title;
|
|
|
|
wxString msg;
|
|
|
|
int id;
|
|
|
|
|
2018-03-03 19:08:23 +00:00
|
|
|
title.Printf(_("%s changed"), mActiveMacro);
|
2010-01-23 19:44:49 +00:00
|
|
|
msg = _("Do you want to save the changes?");
|
|
|
|
|
2017-09-06 21:39:33 +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;
|
|
|
|
}
|
|
|
|
|
|
|
|
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);
|
|
|
|
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();
|
|
|
|
mDefaults->Enable();
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
mRemove->Enable();
|
|
|
|
mRename->Enable();
|
|
|
|
mDefaults->Disable();
|
|
|
|
}
|
|
|
|
|
|
|
|
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
|
|
|
{
|
|
|
|
// Refrsh the layout and re-fit the columns.
|
|
|
|
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
|
|
|
{
|
|
|
|
mList->SetColumnWidth(0, 0); // First column width is zero, to hide it.
|
|
|
|
|
|
|
|
#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.
|
|
|
|
for (size_t c = 1; c < mList->GetColumnCount(); c++) {
|
|
|
|
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
|
|
|
|
mList->SetColumnWidth(1, wxLIST_AUTOSIZE_USEHEADER);
|
|
|
|
mList->SetColumnWidth(2, wxLIST_AUTOSIZE_USEHEADER);
|
|
|
|
mList->SetColumnWidth(3, wxLIST_AUTOSIZE);
|
2014-06-03 20:30:19 +00:00
|
|
|
#endif
|
2013-03-10 09:05:41 +00:00
|
|
|
|
|
|
|
int bestfit = mList->GetColumnWidth(3);
|
|
|
|
int clientsize = mList->GetClientSize().GetWidth();
|
|
|
|
int col1 = mList->GetColumnWidth(1);
|
|
|
|
int col2 = mList->GetColumnWidth(2);
|
|
|
|
bestfit = (bestfit > clientsize-col1-col2)? bestfit : clientsize-col1-col2;
|
|
|
|
mList->SetColumnWidth(3, 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
|
|
|
|
2018-03-03 19:08:23 +00:00
|
|
|
if (mMacroCommands.IsFixed(mActiveMacro)) {
|
2010-01-23 19:44:49 +00:00
|
|
|
wxBell();
|
|
|
|
event.Veto();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
///
|
2018-03-03 19:08:23 +00:00
|
|
|
void MacrosWindow::OnMacrosEndEdit(wxListEvent &event)
|
2010-01-23 19:44:49 +00:00
|
|
|
{
|
|
|
|
if (event.IsEditCancelled()) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
wxString newname = event.GetLabel();
|
|
|
|
|
2018-03-03 19:08:23 +00:00
|
|
|
mMacroCommands.RenameMacro(mActiveMacro, newname);
|
2010-01-23 19:44:49 +00:00
|
|
|
|
2018-03-03 19:08:23 +00:00
|
|
|
mActiveMacro = newname;
|
2010-01-23 19:44:49 +00:00
|
|
|
|
2018-03-03 19:08:23 +00:00
|
|
|
PopulateMacros();
|
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
|
|
|
{
|
|
|
|
while (true) {
|
2017-10-12 15:49:57 +00:00
|
|
|
AudacityTextEntryDialog d(this,
|
2018-03-03 19:08:23 +00:00
|
|
|
_("Enter name of new macro"),
|
|
|
|
_("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);
|
|
|
|
|
|
|
|
if (name.Length() == 0) {
|
2017-09-06 21:39:33 +00:00
|
|
|
AudacityMessageBox(_("Name must not be blank"),
|
2010-01-23 19:44:49 +00:00
|
|
|
GetTitle(),
|
|
|
|
wxOK | wxICON_ERROR,
|
|
|
|
this);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (name.Contains(wxFILE_SEP_PATH) ||
|
|
|
|
name.Contains(wxFILE_SEP_PATH_UNIX)) {
|
2012-03-20 21:59:30 +00:00
|
|
|
/*i18n-hint: The %c will be replaced with 'forbidden characters', like '/' and '\'.*/
|
2017-09-06 21:39:33 +00:00
|
|
|
AudacityMessageBox(wxString::Format(_("Names may not contain '%c' and '%c'"),
|
2010-01-23 19:44:49 +00:00
|
|
|
wxFILE_SEP_PATH, wxFILE_SEP_PATH_UNIX),
|
|
|
|
GetTitle(),
|
|
|
|
wxOK | wxICON_ERROR,
|
|
|
|
this);
|
|
|
|
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);
|
2017-10-12 16:21:52 +00:00
|
|
|
AudacityMessageDialog m(this,
|
2012-03-20 15:36:02 +00:00
|
|
|
/*i18n-hint: %s will be replaced by the name of a file.*/
|
2017-10-09 05:03:14 +00:00
|
|
|
wxString::Format(_("Are you sure you want to delete %s?"), name),
|
2010-01-23 19:44:49 +00:00
|
|
|
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--;
|
|
|
|
}
|
|
|
|
|
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
|
|
|
}
|
|
|
|
|
|
|
|
/// 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;
|
|
|
|
}
|
|
|
|
|
2018-03-03 19:08:23 +00:00
|
|
|
MacroCommandDialog d(this, wxID_ANY);
|
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
|
|
|
|
2011-08-18 22:53:13 +00:00
|
|
|
if(d.mSelectedCommand != wxT(""))
|
|
|
|
{
|
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;
|
|
|
|
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.
|
2018-03-03 19:08:23 +00:00
|
|
|
wxString command = mMacroCommands.GetCommand(item);
|
|
|
|
wxString params = mMacroCommands.GetParams(item);
|
2018-03-01 17:54:08 +00:00
|
|
|
|
2018-03-03 19:08:23 +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
|
|
|
|
2018-03-03 19:08:23 +00:00
|
|
|
mMacroCommands.DeleteFromMacro(item);
|
|
|
|
mMacroCommands.AddToMacro(command,
|
2018-03-01 17:54:08 +00:00
|
|
|
params,
|
|
|
|
item);
|
|
|
|
mChanged = true;
|
|
|
|
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);
|
2010-01-23 19:44:49 +00:00
|
|
|
mChanged = true;
|
|
|
|
|
|
|
|
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);
|
2010-01-23 19:44:49 +00:00
|
|
|
mChanged = true;
|
|
|
|
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);
|
2010-01-23 19:44:49 +00:00
|
|
|
mChanged = true;
|
|
|
|
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
|
|
|
/// Select the empty Command macro.
|
|
|
|
void MacrosWindow::OnDefaults(wxCommandEvent & WXUNUSED(event))
|
2010-01-23 19:44:49 +00:00
|
|
|
{
|
2018-03-03 19:08:23 +00:00
|
|
|
mMacroCommands.RestoreMacro(mActiveMacro);
|
2010-01-23 19:44:49 +00:00
|
|
|
|
|
|
|
mChanged = true;
|
|
|
|
|
|
|
|
PopulateList();
|
|
|
|
}
|
|
|
|
|
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
|
|
|
}
|
|
|
|
}
|
2018-03-01 17:54:08 +00:00
|
|
|
mChanged = false;
|
|
|
|
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
|
|
|
{
|
|
|
|
if (!ChangeOK()) {
|
|
|
|
return;
|
|
|
|
}
|
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();
|
|
|
|
}
|