2010-01-23 19:44:49 +00:00
|
|
|
/**********************************************************************
|
|
|
|
|
|
|
|
Audacity: A Digital Audio Editor
|
|
|
|
|
|
|
|
BatchProcessDialog.cpp
|
|
|
|
|
|
|
|
Dominic Mazzoni
|
|
|
|
James Crook
|
|
|
|
|
|
|
|
*******************************************************************//*!
|
|
|
|
|
|
|
|
\class BatchProcessDialog
|
|
|
|
\brief Shows progress in executing commands in BatchCommands.
|
|
|
|
|
|
|
|
*//*******************************************************************/
|
|
|
|
|
|
|
|
#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"
|
|
|
|
#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"
|
2010-01-23 19:44:49 +00:00
|
|
|
|
|
|
|
#define ChainsListID 7001
|
2013-03-10 09:05:41 +00:00
|
|
|
#define CommandsListID 7002
|
|
|
|
#define ApplyToProjectID 7003
|
|
|
|
#define ApplyToFilesID 7004
|
2010-01-23 19:44:49 +00:00
|
|
|
|
2016-07-10 21:10:50 +00:00
|
|
|
BEGIN_EVENT_TABLE(BatchProcessDialog, wxDialogWrapper)
|
2010-01-23 19:44:49 +00:00
|
|
|
EVT_BUTTON(ApplyToProjectID, BatchProcessDialog::OnApplyToProject)
|
|
|
|
EVT_BUTTON(ApplyToFilesID, BatchProcessDialog::OnApplyToFiles)
|
|
|
|
EVT_BUTTON(wxID_CANCEL, BatchProcessDialog::OnCancel)
|
|
|
|
END_EVENT_TABLE()
|
|
|
|
|
|
|
|
BatchProcessDialog::BatchProcessDialog(wxWindow * parent):
|
2016-07-10 21:10:50 +00:00
|
|
|
wxDialogWrapper(parent, wxID_ANY, _("Apply Chain"),
|
2010-01-23 19:44:49 +00:00
|
|
|
wxDefaultPosition, wxDefaultSize,
|
|
|
|
wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)
|
|
|
|
{
|
2013-08-25 21:51:26 +00:00
|
|
|
//AudacityProject * p = GetActiveProject();
|
2012-04-26 22:57:04 +00:00
|
|
|
|
2010-01-23 19:44:49 +00:00
|
|
|
SetLabel(_("Apply Chain")); // Provide visual label
|
|
|
|
SetName(_("Apply Chain")); // Provide audible label
|
|
|
|
Populate();
|
|
|
|
|
|
|
|
mAbort = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
BatchProcessDialog::~BatchProcessDialog()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
void BatchProcessDialog::Populate()
|
|
|
|
{
|
|
|
|
//------------------------- Main section --------------------
|
|
|
|
ShuttleGui S(this, eIsCreating);
|
|
|
|
PopulateOrExchange(S);
|
|
|
|
// ----------------------- End of main section --------------
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Defines the dialog and does data exchange with it.
|
|
|
|
void BatchProcessDialog::PopulateOrExchange(ShuttleGui &S)
|
|
|
|
{
|
|
|
|
S.StartVerticalLay(true);
|
|
|
|
{
|
2014-06-03 20:30:19 +00:00
|
|
|
/*i18n-hint: A chain is a sequence of commands that can be applied
|
2012-03-20 15:36:02 +00:00
|
|
|
* to one or more audio files.*/
|
2013-02-14 05:51:32 +00:00
|
|
|
S.StartStatic(_("&Select Chain"), true);
|
2010-01-23 19:44:49 +00:00
|
|
|
{
|
|
|
|
S.SetStyle(wxSUNKEN_BORDER | wxLC_REPORT | wxLC_HRULES | wxLC_VRULES |
|
|
|
|
wxLC_SINGLE_SEL);
|
|
|
|
mChains = S.Id(ChainsListID).AddListControlReportMode();
|
|
|
|
mChains->InsertColumn(0, _("Chain"), wxLIST_FORMAT_LEFT);
|
|
|
|
}
|
|
|
|
S.EndStatic();
|
|
|
|
|
|
|
|
S.StartHorizontalLay(wxALIGN_RIGHT, false);
|
|
|
|
{
|
|
|
|
S.SetBorder(10);
|
|
|
|
S.Id(ApplyToProjectID).AddButton(_("Apply to Current &Project"));
|
|
|
|
S.Id(ApplyToFilesID).AddButton(_("Apply to &Files..."));
|
|
|
|
S.Id(wxID_CANCEL).AddButton(_("&Cancel"));
|
|
|
|
}
|
|
|
|
S.EndHorizontalLay();
|
|
|
|
}
|
|
|
|
S.EndVerticalLay();
|
|
|
|
|
|
|
|
wxArrayString names = mBatchCommands.GetNames();
|
|
|
|
for (int i = 0; i < (int)names.GetCount(); i++) {
|
|
|
|
mChains->InsertItem(i, names[i]);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Get and validate the currently active chain
|
2012-04-26 22:57:04 +00:00
|
|
|
wxString name = gPrefs->Read(wxT("/Batch/ActiveChain"), wxT(""));
|
|
|
|
|
2010-01-23 19:44:49 +00:00
|
|
|
int item = mChains->FindItem(-1, name);
|
|
|
|
if (item == -1) {
|
|
|
|
item = 0;
|
|
|
|
name = mChains->GetItemText(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Select the name in the list...this will fire an event.
|
|
|
|
mChains->SetItemState(item, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED);
|
|
|
|
|
|
|
|
Layout();
|
|
|
|
Fit();
|
|
|
|
SetSizeHints(GetSize());
|
|
|
|
Center();
|
|
|
|
|
|
|
|
// Set the column size for the chains list.
|
|
|
|
wxSize sz = mChains->GetClientSize();
|
|
|
|
mChains->SetColumnWidth(0, sz.x);
|
|
|
|
}
|
|
|
|
|
2013-08-25 21:51:26 +00:00
|
|
|
void BatchProcessDialog::OnApplyToProject(wxCommandEvent & WXUNUSED(event))
|
2010-01-23 19:44:49 +00:00
|
|
|
{
|
|
|
|
long item = mChains->GetNextItem(-1,
|
|
|
|
wxLIST_NEXT_ALL,
|
|
|
|
wxLIST_STATE_SELECTED);
|
|
|
|
if (item == -1) {
|
2017-09-06 21:39:33 +00:00
|
|
|
AudacityMessageBox(_("No chain selected"));
|
2010-01-23 19:44:49 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
wxString name = mChains->GetItemText(item);
|
|
|
|
|
2016-07-10 21:10:50 +00:00
|
|
|
wxDialog * pD = safenew wxDialogWrapper(this, wxID_ANY, GetTitle());
|
2015-10-09 22:28:53 +00:00
|
|
|
pD->SetName(pD->GetTitle());
|
|
|
|
ShuttleGui S(pD, eIsCreating);
|
2010-01-23 19:44:49 +00:00
|
|
|
|
|
|
|
S.StartHorizontalLay(wxCENTER, false);
|
|
|
|
{
|
|
|
|
S.StartStatic(wxT(""), false); // deliberately not translated (!)
|
|
|
|
{
|
|
|
|
S.SetBorder(20);
|
|
|
|
S.AddFixedText(wxString::Format(_("Applying '%s' to current project"),
|
|
|
|
name.c_str()));
|
|
|
|
}
|
|
|
|
S.EndStatic();
|
|
|
|
}
|
|
|
|
S.EndHorizontalLay();
|
|
|
|
|
2015-10-09 22:28:53 +00:00
|
|
|
pD->Layout();
|
|
|
|
pD->Fit();
|
|
|
|
pD->CenterOnScreen();
|
|
|
|
pD->Move(-1, 0);
|
|
|
|
pD->Show();
|
|
|
|
|
2015-10-10 14:41:59 +00:00
|
|
|
// The Hide() on the next line seems to tickle a bug in wx3,
|
|
|
|
// giving rise to our Bug #1221. The problem is that on Linux
|
|
|
|
// the 'Hide' converts us from a Modal into a regular dialog,
|
|
|
|
// as far as closing is concerned. On Linux we can't close with
|
|
|
|
// EndModal() anymore after this.
|
|
|
|
Hide();
|
2010-01-23 19:44:49 +00:00
|
|
|
|
|
|
|
gPrefs->Write(wxT("/Batch/ActiveChain"), name);
|
2012-08-02 06:03:19 +00:00
|
|
|
gPrefs->Flush();
|
2010-01-23 19:44:49 +00:00
|
|
|
|
|
|
|
mBatchCommands.ReadChain(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;
|
|
|
|
{
|
|
|
|
wxWindowDisabler wd(pD);
|
2016-12-03 19:33:37 +00:00
|
|
|
success = GuardedCall< bool >(
|
|
|
|
[this]{ return mBatchCommands.ApplyChain(); } );
|
2016-02-01 01:39:24 +00:00
|
|
|
}
|
2015-07-24 05:02:19 +00:00
|
|
|
|
|
|
|
if (!success) {
|
|
|
|
Show();
|
2010-01-23 19:44:49 +00:00
|
|
|
return;
|
|
|
|
}
|
2015-10-09 22:53:49 +00:00
|
|
|
|
2015-10-10 14:41:59 +00:00
|
|
|
#if !defined(__WXMAC__)
|
|
|
|
// Under Linux an EndModal() here crashes (Bug #1221).
|
2015-10-09 22:53:49 +00:00
|
|
|
// But sending a close message instead is OK.
|
2015-10-09 22:28:53 +00:00
|
|
|
wxCloseEvent Evt;
|
2015-10-10 14:27:35 +00:00
|
|
|
Evt.SetId( wxID_OK );
|
2015-10-09 22:28:53 +00:00
|
|
|
Evt.SetEventObject( this);
|
|
|
|
ProcessWindowEvent( Evt );
|
2015-10-10 14:41:59 +00:00
|
|
|
#else
|
|
|
|
EndModal(wxID_OK);
|
|
|
|
#endif
|
2016-01-27 19:58:51 +00:00
|
|
|
|
|
|
|
// Raise myself again, and the parent window with me
|
|
|
|
Show();
|
2010-01-23 19:44:49 +00:00
|
|
|
}
|
|
|
|
|
2013-08-25 21:51:26 +00:00
|
|
|
void BatchProcessDialog::OnApplyToFiles(wxCommandEvent & WXUNUSED(event))
|
2010-01-23 19:44:49 +00:00
|
|
|
{
|
|
|
|
long item = mChains->GetNextItem(-1,
|
|
|
|
wxLIST_NEXT_ALL,
|
|
|
|
wxLIST_STATE_SELECTED);
|
|
|
|
if (item == -1) {
|
2017-09-06 21:39:33 +00:00
|
|
|
AudacityMessageBox(_("No chain selected"));
|
2010-01-23 19:44:49 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
wxString name = mChains->GetItemText(item);
|
|
|
|
gPrefs->Write(wxT("/Batch/ActiveChain"), 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) {
|
|
|
|
return;
|
|
|
|
}
|
2017-08-03 10:41:38 +00:00
|
|
|
|
2010-01-23 19:44:49 +00:00
|
|
|
wxArrayString files;
|
|
|
|
dlog.GetPaths(files);
|
|
|
|
|
|
|
|
files.Sort();
|
|
|
|
|
2016-07-10 21:10:50 +00:00
|
|
|
wxDialog * pD = safenew wxDialogWrapper(this, wxID_ANY, GetTitle());
|
2015-10-09 22:53:49 +00:00
|
|
|
pD->SetName(pD->GetTitle());
|
|
|
|
ShuttleGui S(pD, eIsCreating);
|
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);
|
2013-03-10 09:05:41 +00:00
|
|
|
mList = S.Id(CommandsListID).AddListControlReportMode();
|
2016-08-10 05:34:44 +00:00
|
|
|
// AssignImageList takes ownership
|
|
|
|
mList->AssignImageList(imageList.release(), wxIMAGE_LIST_SMALL);
|
2010-01-23 19:44:49 +00:00
|
|
|
mList->InsertColumn(0, _("File"), wxLIST_FORMAT_LEFT);
|
|
|
|
}
|
|
|
|
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++ ) {
|
|
|
|
mList->InsertItem(i, files[i], i == 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Set the column size for the files list.
|
|
|
|
mList->SetColumnWidth(0, wxLIST_AUTOSIZE);
|
|
|
|
|
|
|
|
int width = mList->GetColumnWidth(0);
|
|
|
|
wxSize sz = mList->GetClientSize();
|
|
|
|
if (width > sz.GetWidth() && width < 500) {
|
|
|
|
sz.SetWidth(width);
|
|
|
|
mList->SetInitialSize(sz);
|
|
|
|
}
|
|
|
|
|
2015-10-09 22:53:49 +00:00
|
|
|
pD->Layout();
|
|
|
|
pD->Fit();
|
|
|
|
pD->SetSizeHints(pD->GetSize());
|
|
|
|
pD->CenterOnScreen();
|
|
|
|
pD->Move(-1, 0);
|
|
|
|
pD->Show();
|
2010-01-23 19:44:49 +00:00
|
|
|
Hide();
|
|
|
|
|
|
|
|
mBatchCommands.ReadChain(name);
|
|
|
|
for (i = 0; i < (int)files.GetCount(); i++) {
|
2015-10-09 22:53:49 +00:00
|
|
|
wxWindowDisabler wd(pD);
|
2010-01-23 19:44:49 +00:00
|
|
|
if (i > 0) {
|
|
|
|
//Clear the arrow in previous item.
|
|
|
|
mList->SetItemImage(i - 1, 0, 0);
|
|
|
|
}
|
|
|
|
mList->SetItemImage(i, 1, 1);
|
|
|
|
mList->EnsureVisible(i);
|
|
|
|
|
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);
|
2016-12-03 19:33:37 +00:00
|
|
|
project->OnSelectAll();
|
|
|
|
if (!mBatchCommands.ApplyChain())
|
|
|
|
return false;
|
2010-01-23 19:44:49 +00:00
|
|
|
|
2016-12-03 19:33:37 +00:00
|
|
|
if (!pD->IsShown() || mAbort)
|
|
|
|
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();
|
2015-05-26 19:05:31 +00:00
|
|
|
project->OnSelectAll();
|
|
|
|
project->OnRemoveTracks();
|
2010-01-23 19:44:49 +00:00
|
|
|
}
|
|
|
|
project->OnRemoveTracks();
|
2015-07-24 05:02:19 +00:00
|
|
|
|
2015-10-10 14:41:59 +00:00
|
|
|
// Under Linux an EndModal() here crashes (Bug #1221).
|
2015-10-09 22:53:49 +00:00
|
|
|
// But sending a close message instead is OK.
|
2015-10-10 14:41:59 +00:00
|
|
|
#if !defined(__WXMAC__)
|
2015-10-09 22:53:49 +00:00
|
|
|
wxCloseEvent Evt;
|
2015-10-10 14:27:35 +00:00
|
|
|
Evt.SetId( wxID_OK );
|
2015-10-09 22:53:49 +00:00
|
|
|
Evt.SetEventObject( this);
|
|
|
|
ProcessWindowEvent( Evt );
|
2015-10-10 14:41:59 +00:00
|
|
|
#else
|
|
|
|
EndModal(wxID_OK);
|
|
|
|
#endif
|
2016-01-27 19:58:51 +00:00
|
|
|
|
|
|
|
// Raise myself again, and the parent window with me
|
|
|
|
Show();
|
2010-01-23 19:44:49 +00:00
|
|
|
}
|
|
|
|
|
2013-08-25 21:51:26 +00:00
|
|
|
void BatchProcessDialog::OnCancel(wxCommandEvent & WXUNUSED(event))
|
2010-01-23 19:44:49 +00:00
|
|
|
{
|
2015-10-10 14:41:59 +00:00
|
|
|
#if !defined(__WXMAC__)
|
|
|
|
// It is possible that we could just do EndModal()
|
|
|
|
// here even on Linux. However, we know the alternative way of
|
|
|
|
// closing works, if we are hidden, so we hide and then do that.
|
2015-10-10 14:27:35 +00:00
|
|
|
Hide();
|
2015-10-10 14:41:59 +00:00
|
|
|
// Under Linux an EndModal() here potentially crashes (Bug #1221).
|
2015-10-09 22:53:49 +00:00
|
|
|
// But sending a close message instead is OK.
|
|
|
|
wxCloseEvent Evt;
|
2015-10-10 14:27:35 +00:00
|
|
|
Evt.SetId( wxID_CANCEL );
|
2015-10-09 22:53:49 +00:00
|
|
|
Evt.SetEventObject( this);
|
|
|
|
ProcessWindowEvent( Evt );
|
2015-10-10 14:27:35 +00:00
|
|
|
#else
|
|
|
|
EndModal(wxID_CANCEL);
|
|
|
|
#endif
|
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 {
|
|
|
|
// ChainsListID 7005
|
|
|
|
AddButtonID = 10000,
|
|
|
|
RemoveButtonID,
|
2013-03-10 09:05:41 +00:00
|
|
|
// CommandsListID, 7002
|
2010-01-23 19:44:49 +00:00
|
|
|
ImportButtonID,
|
|
|
|
ExportButtonID,
|
|
|
|
DefaultsButtonID,
|
|
|
|
InsertButtonID,
|
|
|
|
DeleteButtonID,
|
|
|
|
UpButtonID,
|
|
|
|
DownButtonID,
|
|
|
|
RenameButtonID
|
|
|
|
};
|
|
|
|
|
2016-07-10 21:10:50 +00:00
|
|
|
BEGIN_EVENT_TABLE(EditChainsDialog, wxDialogWrapper)
|
2010-01-23 19:44:49 +00:00
|
|
|
EVT_LIST_ITEM_SELECTED(ChainsListID, EditChainsDialog::OnChainSelected)
|
2013-03-10 09:05:41 +00:00
|
|
|
EVT_LIST_ITEM_SELECTED(CommandsListID, EditChainsDialog::OnListSelected)
|
2010-01-23 19:44:49 +00:00
|
|
|
EVT_LIST_BEGIN_LABEL_EDIT(ChainsListID, EditChainsDialog::OnChainsBeginEdit)
|
|
|
|
EVT_LIST_END_LABEL_EDIT(ChainsListID, EditChainsDialog::OnChainsEndEdit)
|
|
|
|
EVT_BUTTON(AddButtonID, EditChainsDialog::OnAdd)
|
|
|
|
EVT_BUTTON(RemoveButtonID, EditChainsDialog::OnRemove)
|
|
|
|
EVT_BUTTON(RenameButtonID, EditChainsDialog::OnRename)
|
2013-03-10 09:05:41 +00:00
|
|
|
EVT_SIZE(EditChainsDialog::OnSize)
|
2010-01-23 19:44:49 +00:00
|
|
|
|
|
|
|
EVT_LIST_ITEM_ACTIVATED(CommandsListID, EditChainsDialog::OnCommandActivated)
|
|
|
|
EVT_BUTTON(InsertButtonID, EditChainsDialog::OnInsert)
|
|
|
|
EVT_BUTTON(DeleteButtonID, EditChainsDialog::OnDelete)
|
|
|
|
EVT_BUTTON(UpButtonID, EditChainsDialog::OnUp)
|
|
|
|
EVT_BUTTON(DownButtonID, EditChainsDialog::OnDown)
|
|
|
|
EVT_BUTTON(DefaultsButtonID, EditChainsDialog::OnDefaults)
|
|
|
|
|
|
|
|
EVT_BUTTON(wxID_OK, EditChainsDialog::OnOK)
|
|
|
|
EVT_BUTTON(wxID_CANCEL, EditChainsDialog::OnCancel)
|
|
|
|
|
|
|
|
EVT_KEY_DOWN(EditChainsDialog::OnKeyDown)
|
|
|
|
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
|
|
|
|
EditChainsDialog::EditChainsDialog(wxWindow * parent):
|
2016-07-10 21:10:50 +00:00
|
|
|
wxDialogWrapper(parent, wxID_ANY, _("Edit Chains"),
|
2010-01-23 19:44:49 +00:00
|
|
|
wxDefaultPosition, wxDefaultSize,
|
|
|
|
wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)
|
|
|
|
{
|
|
|
|
SetLabel(_("Edit Chains")); // Provide visual label
|
|
|
|
SetName(_("Edit Chains")); // Provide audible label
|
|
|
|
|
|
|
|
mChanged = false;
|
|
|
|
mSelectedCommand = 0;
|
|
|
|
|
|
|
|
Populate();
|
|
|
|
}
|
|
|
|
|
|
|
|
EditChainsDialog::~EditChainsDialog()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Creates the dialog and its contents.
|
|
|
|
void EditChainsDialog::Populate()
|
|
|
|
{
|
|
|
|
//------------------------- Main section --------------------
|
|
|
|
ShuttleGui S(this, eIsCreating);
|
|
|
|
PopulateOrExchange(S);
|
|
|
|
// ----------------------- End of main section --------------
|
|
|
|
|
|
|
|
// Get and validate the currently active chain
|
2012-04-26 22:57:04 +00:00
|
|
|
mActiveChain = gPrefs->Read(wxT("/Batch/ActiveChain"), wxT(""));
|
2010-01-23 19:44:49 +00:00
|
|
|
|
|
|
|
// Go populate the chains list.
|
|
|
|
PopulateChains();
|
|
|
|
|
|
|
|
// 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
|
|
|
|
SetSize(wxSystemSettings::GetMetric(wxSYS_SCREEN_X) * 3 / 4,
|
|
|
|
wxSystemSettings::GetMetric(wxSYS_SCREEN_Y) * 4 / 5);
|
|
|
|
Center();
|
|
|
|
|
|
|
|
// Set the column size for the chains list.
|
|
|
|
wxSize sz = mChains->GetClientSize();
|
|
|
|
mChains->SetColumnWidth(0, sz.x);
|
|
|
|
|
|
|
|
// 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.
|
|
|
|
void EditChainsDialog::PopulateOrExchange(ShuttleGui & S)
|
|
|
|
{
|
|
|
|
S.StartHorizontalLay(wxEXPAND, 1);
|
|
|
|
{
|
|
|
|
S.StartStatic(_("&Chains"));
|
|
|
|
{
|
|
|
|
// JKC: Experimenting with an alternative way to get multiline
|
|
|
|
// translated strings to work correctly without very long lines.
|
|
|
|
// My appologies Alexandre if this way didn't work either.
|
2014-06-03 20:30:19 +00:00
|
|
|
//
|
2010-01-23 19:44:49 +00:00
|
|
|
// With this method:
|
|
|
|
// 1) it compiles fine under windows unicode and normal mode.
|
|
|
|
// 2) xgettext source code has handling for the trailing '\'
|
|
|
|
//
|
2014-06-03 20:30:19 +00:00
|
|
|
// It remains to see if linux and mac can cope and if xgettext
|
2010-01-23 19:44:49 +00:00
|
|
|
// actually does do fine with strings presented like this.
|
|
|
|
// If it doesn't work out, revert to all-on-one-line.
|
|
|
|
S.SetStyle(wxSUNKEN_BORDER | wxLC_REPORT | wxLC_HRULES | wxLC_SINGLE_SEL |
|
|
|
|
wxLC_EDIT_LABELS);
|
|
|
|
mChains = S.Id(ChainsListID).AddListControlReportMode();
|
2017-07-22 10:33:09 +00:00
|
|
|
// i18n-hint: This is the heading for a column in the edit chains dialog
|
|
|
|
mChains->InsertColumn(0, _("Chain"), wxLIST_FORMAT_LEFT);
|
2010-01-23 19:44:49 +00:00
|
|
|
S.StartHorizontalLay(wxCENTER, false);
|
|
|
|
{
|
|
|
|
S.Id(AddButtonID).AddButton(_("&Add"));
|
|
|
|
mRemove = S.Id(RemoveButtonID).AddButton(_("&Remove"));
|
|
|
|
mRename = S.Id(RenameButtonID).AddButton(_("Re&name"));
|
|
|
|
}
|
|
|
|
S.EndHorizontalLay();
|
|
|
|
}
|
|
|
|
S.EndStatic();
|
|
|
|
|
|
|
|
S.StartStatic(_("C&hain (Double-Click or press SPACE to edit)"), true);
|
|
|
|
{
|
|
|
|
S.SetStyle(wxSUNKEN_BORDER | wxLC_REPORT | wxLC_HRULES | wxLC_VRULES |
|
|
|
|
wxLC_SINGLE_SEL);
|
|
|
|
mList = S.Id(CommandsListID).AddListControlReportMode();
|
|
|
|
|
2014-06-03 20:30:19 +00:00
|
|
|
//An empty first column is a workaround - under Win98 the first column
|
2010-01-23 19:44:49 +00:00
|
|
|
//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);
|
2013-03-10 09:05:41 +00:00
|
|
|
mList->InsertColumn(ActionColumn, _("Command "), wxLIST_FORMAT_RIGHT);
|
2010-01-23 19:44:49 +00:00
|
|
|
mList->InsertColumn(ParamsColumn, _("Parameters"), wxLIST_FORMAT_LEFT);
|
|
|
|
|
|
|
|
S.StartHorizontalLay(wxCENTER, false);
|
|
|
|
{
|
|
|
|
S.Id(InsertButtonID).AddButton(_("&Insert"), 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"));
|
|
|
|
}
|
|
|
|
S.EndHorizontalLay();
|
|
|
|
}
|
|
|
|
S.EndStatic();
|
|
|
|
}
|
|
|
|
S.EndHorizontalLay();
|
|
|
|
|
|
|
|
S.AddStandardButtons();
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// This clears and updates the contents of mChains
|
|
|
|
void EditChainsDialog::PopulateChains()
|
|
|
|
{
|
|
|
|
wxArrayString names = mBatchCommands.GetNames();
|
|
|
|
int i;
|
|
|
|
|
|
|
|
mChains->DeleteAllItems();
|
|
|
|
for (i = 0; i < (int)names.GetCount(); i++) {
|
|
|
|
mChains->InsertItem(i, names[i]);
|
|
|
|
}
|
|
|
|
|
|
|
|
int item = mChains->FindItem(-1, mActiveChain);
|
|
|
|
if (item == -1) {
|
|
|
|
item = 0;
|
|
|
|
mActiveChain = mChains->GetItemText(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Select the name in the list...this will fire an event.
|
|
|
|
mChains->SetItemState(item, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED);
|
|
|
|
}
|
|
|
|
|
|
|
|
/// This clears and updates the contents of mList
|
|
|
|
void EditChainsDialog::PopulateList()
|
|
|
|
{
|
|
|
|
mList->DeleteAllItems();
|
|
|
|
|
|
|
|
for (int i = 0; i < mBatchCommands.GetCount(); i++) {
|
|
|
|
AddItem(mBatchCommands.GetCommand(i),
|
|
|
|
mBatchCommands.GetParams(i));
|
|
|
|
}
|
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);
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Add one item into mList
|
|
|
|
void EditChainsDialog::AddItem(const wxString &Action, const wxString &Params)
|
|
|
|
{
|
|
|
|
int i = mList->GetItemCount();
|
|
|
|
|
|
|
|
mList->InsertItem(i, wxT(""));
|
|
|
|
mList->SetItem(i, ItemNumberColumn, wxString::Format(wxT(" %02i"), i + 1));
|
|
|
|
mList->SetItem(i, ActionColumn, Action );
|
|
|
|
mList->SetItem(i, ParamsColumn, Params );
|
|
|
|
}
|
|
|
|
|
|
|
|
bool EditChainsDialog::ChangeOK()
|
|
|
|
{
|
|
|
|
if (mChanged) {
|
|
|
|
wxString title;
|
|
|
|
wxString msg;
|
|
|
|
int id;
|
|
|
|
|
|
|
|
title.Printf(_("%s changed"), mActiveChain.c_str());
|
|
|
|
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) {
|
|
|
|
if (!mBatchCommands.WriteChain(mActiveChain)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
mChanged = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
/// An item in the chains list has been selected.
|
2013-08-25 21:51:26 +00:00
|
|
|
void EditChainsDialog::OnChainSelected(wxListEvent & event)
|
2010-01-23 19:44:49 +00:00
|
|
|
{
|
|
|
|
if (!ChangeOK()) {
|
|
|
|
event.Veto();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
int item = event.GetIndex();
|
|
|
|
|
|
|
|
mActiveChain = mChains->GetItemText(item);
|
|
|
|
mBatchCommands.ReadChain(mActiveChain);
|
|
|
|
|
|
|
|
if (mBatchCommands.IsFixed(mActiveChain)) {
|
|
|
|
mRemove->Disable();
|
|
|
|
mRename->Disable();
|
|
|
|
mDefaults->Enable();
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
mRemove->Enable();
|
|
|
|
mRename->Enable();
|
|
|
|
mDefaults->Disable();
|
|
|
|
}
|
|
|
|
|
|
|
|
PopulateList();
|
2013-03-10 09:05:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// An item in the chains list has been selected.
|
2013-08-25 21:51:26 +00:00
|
|
|
void EditChainsDialog::OnListSelected(wxListEvent & WXUNUSED(event))
|
2013-03-10 09:05:41 +00:00
|
|
|
{
|
|
|
|
FitColumns();
|
|
|
|
}
|
|
|
|
|
|
|
|
/// The window has been resized.
|
2013-08-25 21:51:26 +00:00
|
|
|
void EditChainsDialog::OnSize(wxSizeEvent & WXUNUSED(event))
|
2013-03-10 09:05:41 +00:00
|
|
|
{
|
|
|
|
// Refrsh the layout and re-fit the columns.
|
|
|
|
Layout();
|
|
|
|
FitColumns();
|
|
|
|
}
|
|
|
|
|
|
|
|
void EditChainsDialog::FitColumns()
|
|
|
|
{
|
|
|
|
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
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
///
|
|
|
|
void EditChainsDialog::OnChainsBeginEdit(wxListEvent &event)
|
|
|
|
{
|
|
|
|
int itemNo = event.GetIndex();
|
|
|
|
|
|
|
|
wxString chain = mChains->GetItemText(itemNo);
|
|
|
|
|
|
|
|
if (mBatchCommands.IsFixed(mActiveChain)) {
|
|
|
|
wxBell();
|
|
|
|
event.Veto();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
///
|
|
|
|
void EditChainsDialog::OnChainsEndEdit(wxListEvent &event)
|
|
|
|
{
|
|
|
|
if (event.IsEditCancelled()) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
wxString newname = event.GetLabel();
|
|
|
|
|
|
|
|
mBatchCommands.RenameChain(mActiveChain, newname);
|
|
|
|
|
|
|
|
mActiveChain = newname;
|
|
|
|
|
|
|
|
PopulateChains();
|
|
|
|
}
|
|
|
|
|
2014-06-03 20:30:19 +00:00
|
|
|
///
|
2013-08-25 21:51:26 +00:00
|
|
|
void EditChainsDialog::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,
|
2010-01-23 19:44:49 +00:00
|
|
|
_("Enter name of new chain"),
|
2015-05-12 08:29:55 +00:00
|
|
|
_("Name of new chain"));
|
|
|
|
d.SetName(d.GetTitle());
|
2010-01-23 19:44:49 +00:00
|
|
|
wxString name;
|
|
|
|
|
|
|
|
if (d.ShowModal() == wxID_CANCEL) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
mBatchCommands.AddChain(name);
|
|
|
|
|
|
|
|
mActiveChain = name;
|
|
|
|
|
|
|
|
PopulateChains();
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
///
|
2013-08-25 21:51:26 +00:00
|
|
|
void EditChainsDialog::OnRemove(wxCommandEvent & WXUNUSED(event))
|
2010-01-23 19:44:49 +00:00
|
|
|
{
|
|
|
|
long item = mChains->GetNextItem(-1,
|
|
|
|
wxLIST_NEXT_ALL,
|
|
|
|
wxLIST_STATE_SELECTED);
|
|
|
|
if (item == -1) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
wxString name = mChains->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.*/
|
2010-01-23 19:44:49 +00:00
|
|
|
wxString::Format(_("Are you sure you want to delete %s?"), name.c_str()),
|
|
|
|
GetTitle(),
|
|
|
|
wxYES_NO | wxICON_QUESTION);
|
2012-05-23 18:52:52 +00:00
|
|
|
if (m.ShowModal() == wxID_NO) {
|
2010-01-23 19:44:49 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
mBatchCommands.DeleteChain(name);
|
|
|
|
|
|
|
|
if (item >= (mChains->GetItemCount() - 1) && item >= 0) {
|
|
|
|
item--;
|
|
|
|
}
|
|
|
|
|
|
|
|
mActiveChain = mChains->GetItemText(item);
|
|
|
|
|
|
|
|
PopulateChains();
|
|
|
|
}
|
|
|
|
|
|
|
|
///
|
2013-08-25 21:51:26 +00:00
|
|
|
void EditChainsDialog::OnRename(wxCommandEvent & WXUNUSED(event))
|
2010-01-23 19:44:49 +00:00
|
|
|
{
|
|
|
|
long item = mChains->GetNextItem(-1,
|
|
|
|
wxLIST_NEXT_ALL,
|
|
|
|
wxLIST_STATE_SELECTED);
|
|
|
|
if (item == -1) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
mChains->EditLabel(item);
|
|
|
|
}
|
|
|
|
|
|
|
|
/// An item in the list has been selected.
|
|
|
|
/// Bring up a dialog to allow its parameters to be edited.
|
|
|
|
void EditChainsDialog::OnCommandActivated(wxListEvent &event)
|
|
|
|
{
|
|
|
|
int item = event.GetIndex();
|
|
|
|
|
|
|
|
BatchCommandDialog d(this, wxID_ANY);
|
|
|
|
d.SetCommandAndParams(mBatchCommands.GetCommand(item),
|
|
|
|
mBatchCommands.GetParams(item));
|
|
|
|
|
|
|
|
if (!d.ShowModal()) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
mBatchCommands.DeleteFromChain(item);
|
|
|
|
mBatchCommands.AddToChain(d.mSelectedCommand,
|
|
|
|
d.mSelectedParameters,
|
|
|
|
item);
|
|
|
|
|
|
|
|
mChanged = true;
|
|
|
|
|
|
|
|
mSelectedCommand = item;
|
|
|
|
|
|
|
|
PopulateList();
|
|
|
|
}
|
|
|
|
|
|
|
|
///
|
2013-08-25 21:51:26 +00:00
|
|
|
void EditChainsDialog::OnInsert(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) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
BatchCommandDialog d(this, wxID_ANY);
|
|
|
|
|
|
|
|
if (!d.ShowModal()) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2011-08-18 22:53:13 +00:00
|
|
|
if(d.mSelectedCommand != wxT(""))
|
|
|
|
{
|
|
|
|
mBatchCommands.AddToChain(d.mSelectedCommand,
|
|
|
|
d.mSelectedParameters,
|
|
|
|
item);
|
|
|
|
mChanged = true;
|
2010-01-23 19:44:49 +00:00
|
|
|
|
2011-08-18 22:53:13 +00:00
|
|
|
mSelectedCommand = item + 1;
|
2010-01-23 19:44:49 +00:00
|
|
|
|
2011-08-18 22:53:13 +00:00
|
|
|
PopulateList();
|
|
|
|
}
|
2010-01-23 19:44:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
///
|
2013-08-25 21:51:26 +00:00
|
|
|
void EditChainsDialog::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;
|
|
|
|
}
|
|
|
|
|
|
|
|
mBatchCommands.DeleteFromChain(item);
|
|
|
|
|
|
|
|
mChanged = true;
|
|
|
|
|
|
|
|
if (item >= (mList->GetItemCount() - 2) && item >= 0) {
|
|
|
|
item--;
|
|
|
|
}
|
|
|
|
|
|
|
|
mSelectedCommand = item;
|
|
|
|
|
|
|
|
PopulateList();
|
|
|
|
}
|
|
|
|
|
|
|
|
///
|
2013-08-25 21:51:26 +00:00
|
|
|
void EditChainsDialog::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;
|
|
|
|
}
|
|
|
|
|
|
|
|
mBatchCommands.AddToChain(mBatchCommands.GetCommand(item),
|
|
|
|
mBatchCommands.GetParams(item),
|
|
|
|
item - 1);
|
|
|
|
mBatchCommands.DeleteFromChain(item + 1);
|
|
|
|
|
|
|
|
mChanged = true;
|
|
|
|
|
|
|
|
mSelectedCommand = item - 1;
|
|
|
|
|
|
|
|
PopulateList();
|
|
|
|
}
|
|
|
|
|
|
|
|
///
|
2013-08-25 21:51:26 +00:00
|
|
|
void EditChainsDialog::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;
|
|
|
|
}
|
|
|
|
|
|
|
|
mBatchCommands.AddToChain(mBatchCommands.GetCommand(item),
|
|
|
|
mBatchCommands.GetParams(item),
|
|
|
|
item + 2);
|
|
|
|
mBatchCommands.DeleteFromChain(item);
|
|
|
|
|
|
|
|
mChanged = true;
|
|
|
|
|
|
|
|
mSelectedCommand = item + 1;
|
|
|
|
|
|
|
|
PopulateList();
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Select the empty Command chain.
|
2013-08-25 21:51:26 +00:00
|
|
|
void EditChainsDialog::OnDefaults(wxCommandEvent & WXUNUSED(event))
|
2010-01-23 19:44:49 +00:00
|
|
|
{
|
|
|
|
mBatchCommands.RestoreChain(mActiveChain);
|
|
|
|
|
|
|
|
mChanged = true;
|
|
|
|
|
|
|
|
PopulateList();
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Send changed values back to Prefs, and update Audacity.
|
2013-08-25 21:51:26 +00:00
|
|
|
void EditChainsDialog::OnOK(wxCommandEvent & WXUNUSED(event))
|
2010-01-23 19:44:49 +00:00
|
|
|
{
|
|
|
|
gPrefs->Write(wxT("/Batch/ActiveChain"), mActiveChain);
|
2012-08-02 06:03:19 +00:00
|
|
|
gPrefs->Flush();
|
2010-01-23 19:44:49 +00:00
|
|
|
|
|
|
|
if (mChanged) {
|
|
|
|
if (!mBatchCommands.WriteChain(mActiveChain)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
EndModal(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
///
|
2013-08-25 21:51:26 +00:00
|
|
|
void EditChainsDialog::OnCancel(wxCommandEvent & WXUNUSED(event))
|
2010-01-23 19:44:49 +00:00
|
|
|
{
|
|
|
|
if (!ChangeOK()) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
EndModal(false);
|
|
|
|
}
|
|
|
|
|
|
|
|
///
|
|
|
|
void EditChainsDialog::OnKeyDown(wxKeyEvent &event)
|
|
|
|
{
|
|
|
|
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();
|
|
|
|
}
|