Update of /cvsroot/audacity/audacity-src/src
In directory sc8-pr-cvs11.sourceforge.net:/tmp/cvs-serv16857

Modified Files:
        BatchCommands.cpp BatchProcessDialog.cpp BatchCommands.h 
        Menus.h Menus.cpp BatchProcessDialog.h 
Log Message:
Committing rough chain processing to allow other to review.  

Index: BatchProcessDialog.cpp
===================================================================
RCS file: /cvsroot/audacity/audacity-src/src/BatchProcessDialog.cpp,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -d -r1.9 -r1.10
--- BatchProcessDialog.cpp      3 Jul 2006 19:15:47 -0000       1.9
+++ BatchProcessDialog.cpp      29 Sep 2006 05:50:21 -0000      1.10
@@ -19,6 +19,7 @@
 #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>
@@ -30,157 +31,821 @@
 #include <wx/imaglist.h>
 #include <wx/msgdlg.h>
 
+#include "Prefs.h"
 #include "Project.h"
 #include "BatchProcessDialog.h"
 #include "commands/CommandManager.h"
 #include "effects/Effect.h"
-//#include "../images/Arrow.xpm"
+#include "../images/Arrow.xpm"
 #include "BatchCommands.h"
 
 #include "Theme.h"
 #include "AllThemeResources.h"
 
 
-#define FileListID 7001
+#define ChainsListID       7001
+#define ApplyToProjectID   7002
+#define ApplyToFilesID     7003
 
 BEGIN_EVENT_TABLE(BatchProcessDialog, wxDialog)
-   EVT_BUTTON(wxID_OK,            BatchProcessDialog::OnOk)
-   EVT_BUTTON(wxID_CANCEL,        BatchProcessDialog::OnCancel)
+   EVT_BUTTON(ApplyToProjectID, BatchProcessDialog::OnApplyToProject)
+   EVT_BUTTON(ApplyToFilesID, BatchProcessDialog::OnApplyToFiles)
+   EVT_BUTTON(wxID_CANCEL, BatchProcessDialog::OnCancel)
 END_EVENT_TABLE()
 
-BatchProcessDialog::BatchProcessDialog(wxWindow * parent, wxWindowID id):
-   wxDialog(parent, id,
-            _("Batch Processing"),
-            wxPoint(20,20), wxDefaultSize, wxDIALOG_MODAL | wxCAPTION | 
wxTHICK_FRAME)
+BatchProcessDialog::BatchProcessDialog(wxWindow * parent):
+   wxDialog(parent, wxID_ANY, _("Batch Processing"), wxDefaultPosition)
 {
-   mAbort = false;
-
    AudacityProject * p = GetActiveProject();
-   if( p->GetCleanSpeechMode() )
+   if (p->GetCleanSpeechMode())
    {
-      SetTitle( _("CleanSpeech Batch Processing") );
+      SetTitle(_("CleanSpeech Batch Processing"));
    }
-   mBatchCommands = new BatchCommands;
-   mBatchCommands->ReadChain();
 
-   wxBoxSizer *mainSizer = new wxBoxSizer(wxVERTICAL);
-
-   wxControl *item;
+   SetLabel(_("Batch Processing"));         // Provide visual label
+   SetName(_("Batch Processing"));          // Provide audible label
+   Populate();
 
-   item = new wxStaticText(this, -1,
-                     _("Audio files to be processed"),
-                     wxDefaultPosition, wxDefaultSize, 0);
+   CenterOnParent();
 
-   mainSizer->Add(item, 0, wxALIGN_LEFT | wxALL, 5);
+   mAbort = false;
+}
 
-   mList = new wxListCtrl(this, FileListID, wxDefaultPosition, wxSize(350, 
180),
-                          wxLC_REPORT | wxLC_HRULES | wxLC_VRULES | 
wxSUNKEN_BORDER  /* | wxLC_EDIT_LABELS */);
-   mList->SetName(_("Audio files to be processed"));
-   mList->SetSizeHints(350, 180);
+BatchProcessDialog::~BatchProcessDialog()
+{
+}
 
-   wxImageList *imageList = new wxImageList(9, 16);
+void BatchProcessDialog::Populate()
+{
+   // First any pre-processing for constructing the GUI.
+   mBatchCommands.ReadChains();
 
-   wxIcon TempIcon;
-   TempIcon.CopyFromBitmap( wxBitmap(9,16) );
-   imageList->Add(TempIcon);
-   TempIcon.CopyFromBitmap( theTheme.Bitmap( bmpArrow));
-   imageList->Add(TempIcon);
+   //------------------------- Main section --------------------
+   // Now construct the GUI itself.
+   // Use 'eIsCreatingFromPrefs' so that the GUI is 
+   // initialised with values from gPrefs.
+   ShuttleGui S(this, eIsCreating);
+   PopulateOrExchange(S);
+   // ----------------------- End of main section --------------
+}
 
-   mList->AssignImageList(imageList, wxIMAGE_LIST_SMALL);
-   mList->InsertColumn(0, _("File"), wxLIST_FORMAT_LEFT, 280);
-//   mList->InsertColumn(1, _("Size"), wxLIST_FORMAT_LEFT, 66);
-//   mList->InsertColumn(2, _("Time"), wxLIST_FORMAT_LEFT, 66);
+/// Defines the dialog and does data exchange with it.
+void BatchProcessDialog::PopulateOrExchange( ShuttleGui & S )
+{
+   S.StartVerticalLay(true);
+   {
+      
+      S.StartStatic(_("Select chain"), true);
+      {
+         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();
 
-   mainSizer->Add(mList, 1, wxEXPAND | wxALL, 5);
+      S.StartHorizontalLay(wxALIGN_RIGHT, false);
+      {
+         S.Id(ApplyToProjectID).AddButton(_("Apply to Current Project"));
+         S.Id(ApplyToFilesID).AddButton(_("Apply to Files..."));
+         S.Id(wxID_CANCEL).AddButton(_("Cancel"));
+      }
+      S.StartHorizontalLay();
+   }
+   S.EndVerticalLay();
 
-   wxBoxSizer *okSizer = new wxBoxSizer(wxHORIZONTAL);
+   wxArrayString names = mBatchCommands.GetChainNames();
+   for (int i = 0; i < names.GetCount(); i++)
+   {
+      mChains->InsertItem(i, names[i]);
+   }
 
-   mCancel =
-       new wxButton(this, wxID_CANCEL, _("&Cancel"), wxDefaultPosition,
-                    wxDefaultSize, 0);
-   okSizer->Add(mCancel, 0, wxALIGN_CENTRE | wxALL, 5);
+   // Get and validate the currently active chain
+   wxString name = gPrefs->Read(wxT("/Batch/ActiveChain"), wxT("CleanSpeech"));
+   int item = mChains->FindItem(-1, name);
+   if (mChains->FindItem(-1, name) == -1) {
+      item = 0;
+      name = mChains->GetItemText(0);
+   }
 
-   mOK = 
-       new wxButton(this, wxID_OK, _("&OK"), wxDefaultPosition,
-                    wxDefaultSize, 0);
-   mOK->SetDefault();
-   mOK->SetFocus();
-   okSizer->Add(mOK, 0, wxALIGN_CENTRE | wxALL, 5);
+   // Select the name in the list...this will fire an event.
+   mChains->SetItemState(item, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED);
 
-   mainSizer->Add(okSizer,0 , wxALIGN_CENTRE | wxALL, 5);
+   Layout();
+   Fit();
+   SetSizeHints(GetSize());
 
-   SetAutoLayout(TRUE);
-   SetSizer(mainSizer);
-   SetSize(320, 400);
+   // Set the column size for the chains list.
+   wxSize sz = mChains->GetClientSize();
+   mChains->SetColumnWidth(0, sz.x);
 }
 
-BatchProcessDialog::~BatchProcessDialog()
+void BatchProcessDialog::OnApplyToProject(wxCommandEvent & event)
 {
-   if( mBatchCommands )
-      delete mBatchCommands;
+   long item = mChains->GetNextItem(-1,
+                                    wxLIST_NEXT_ALL,
+                                    wxLIST_STATE_SELECTED);
+   if (item == -1) {
+      wxMessageBox(_("No chain selected"));
+      return;
+   }
+
+   wxDialog d(this, wxID_ANY, wxString(_("Batch Processing")));
+   ShuttleGui S(&d, eIsCreating);
+
+   S.StartHorizontalLay(wxCENTER, false);
+   {
+      S.StartStatic(_(""), 0);
+         S.AddFixedText(wxT(""));
+         S.AddFixedText(_("Applying chain to current project"), true);
+         S.AddFixedText(wxT(""));
+      S.EndStatic();
+   }
+   S.EndHorizontalLay();
+
+   d.Layout();
+   d.Fit();
+   d.CenterOnParent();
+   d.Move(-1, 0);
+   d.Show();
+   Hide();
+
+   wxWindowDisabler wd;
+
+   wxString name = mChains->GetItemText(item);
+
+   gPrefs->Write(wxT("/Batch/ActiveChain"), name);
+
+   if (!mBatchCommands.ApplyChain(name, wxT(""))) {
+      return;
+   }
+
+   EndModal(true);
 }
-void BatchProcessDialog::PopulateList(wxArrayString fileList)
+
+void BatchProcessDialog::OnApplyToFiles(wxCommandEvent & event)
 {
-   unsigned int i;
-   mList->DeleteAllItems(); // Delete contents.
-   for(i=0;i<fileList.GetCount();i++)
+   long item = mChains->GetNextItem(-1,
+                                    wxLIST_NEXT_ALL,
+                                    wxLIST_STATE_SELECTED);
+   if (item == -1) {
+      wxMessageBox(_("No chain selected"));
+      return;
+   }
+
+   wxString name = mChains->GetItemText(item);
+   gPrefs->Write(wxT("/Batch/ActiveChain"), name);
+
+   AudacityProject *project = GetActiveProject();
+   if (!project->GetIsEmpty())
    {
-      mList->InsertItem( i, fileList[i], i==0 );
+      wxMessageBox(_("Please save and close the current project first."));
+      return;
+   }
+
+   wxString path = gPrefs->Read(wxT("/DefaultOpenPath"), ::wxGetCwd());
+   wxString prompt =  project->GetCleanSpeechMode() ? 
+      _("Select vocal file(s) for batch CleanSpeech Chain...") :
+      _("Select file(s) for batch processing...");
+   wxString fileSelector = project->GetCleanSpeechMode() ? 
+      _("Vocal files (*.wav;*.mp3)|*.wav;*.mp3|WAV files (*.wav)|*.wav|MP3 
files (*.mp3)|*.mp3") :
+      _("All files (*.*)|*.*|WAV files (*.wav)|*.wav|AIFF files 
(*.aif)|*.aif|AU files (*.au)|*.au|MP3 files (*.mp3)|*.mp3|Ogg Vorbis files 
(*.ogg)|*.ogg|FLAC files (*.flac)|*.flac"
+       );
+
+   wxFileDialog dlog(this, prompt,
+                     path, wxT(""), fileSelector,
+                     wxOPEN | wxMULTIPLE);
+
+   if (dlog.ShowModal() != wxID_OK) {
+      return;
    }
+
+   wxArrayString files;
+   dlog.GetPaths(files);
+
+   files.Sort();
+
+   wxDialog d(this, wxID_ANY, wxString(_("Batch Processing")));
+   ShuttleGui S(&d, eIsCreating);
+
+   S.StartVerticalLay(false);
+   {
+      S.StartStatic(_("Applying..."), 1);
+      {
+         wxImageList *imageList = new wxImageList(9, 16);
+         imageList->Add(wxIcon(empty_9x16_xpm));
+         imageList->Add(wxIcon(arrow_xpm));
+
+         S.SetStyle(wxSUNKEN_BORDER | wxLC_REPORT | wxLC_HRULES | wxLC_VRULES |
+                    wxLC_SINGLE_SEL);
+         mList = S.AddListControlReportMode();
+         mList->AssignImageList(imageList, wxIMAGE_LIST_SMALL);
+         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 < 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->SetBestFittingSize(sz);
+   }
+
+   d.Layout();
+   d.Fit();
+   d.SetSizeHints(d.GetSize());
+   d.CenterOnParent();
+   d.Move(-1, 0);
+   d.Show();
+   Hide();
+
+   for (i = 0; i < files.GetCount(); i++)
+   {
+      wxWindowDisabler wd(&d);
+      if (i > 0)
+      {
+         //Clear the arrow in previous item.
+         mList->SetItemImage(i - 1, 0, 0);
+      }
+      mList->SetItemImage(i, 1, 1);
+      mList->EnsureVisible(i);
+
+      if (!mBatchCommands.ApplyChain(name, files[i])) {
+         break;
+      }
+
+      if (!d.IsShown() || mAbort) {
+         break;
+      }
+   }
+
+   EndModal(true);
 }
 
-void BatchProcessDialog::ValidateChoices()
+void BatchProcessDialog::OnCancel(wxCommandEvent & event)
 {
-   mOK->Enable(false);
+   EndModal(false);
 }
 
-void BatchProcessDialog::OnChoice(wxCommandEvent & event)
+/////////////////////////////////////////////////////////////////////
+#include <wx/textdlg.h>
+#include "../BatchCommandDialog.h"
+//#define ChainsListID             7005
+#define AddButtonID              7006
+#define RemoveButtonID           7007
+#define CommandsListID           7008
+#define ImportButtonID           7009
+#define ExportButtonID           7010
+#define DefaultsButtonID         7011
+#define UpButtonID               7012
+#define DownButtonID             7013
+#define RenameButtonID           7014
+
+BEGIN_EVENT_TABLE(EditChainsDialog, wxDialog)
+   EVT_BUTTON(wxID_OK, EditChainsDialog::OnOK)
+   EVT_BUTTON(wxID_CANCEL, EditChainsDialog::OnCancel)
+   EVT_BUTTON(AddButtonID, EditChainsDialog::OnAdd)
+   EVT_BUTTON(RemoveButtonID, EditChainsDialog::OnRemove)
+   EVT_BUTTON(RenameButtonID, EditChainsDialog::OnRename)
+   EVT_BUTTON(UpButtonID, EditChainsDialog::OnUp)
+   EVT_BUTTON(DownButtonID, EditChainsDialog::OnDown)
+   EVT_BUTTON(ImportButtonID, EditChainsDialog::OnImport)
+   EVT_BUTTON(ExportButtonID, EditChainsDialog::OnExport)
+   EVT_BUTTON(DefaultsButtonID, EditChainsDialog::OnDefaults)
+   EVT_LIST_ITEM_SELECTED(ChainsListID, EditChainsDialog::OnChainSelected)
+   EVT_LIST_BEGIN_LABEL_EDIT(ChainsListID, EditChainsDialog::OnChainsBeginEdit)
+   EVT_LIST_END_LABEL_EDIT(ChainsListID, EditChainsDialog::OnChainsEndEdit)
+   EVT_LIST_ITEM_ACTIVATED(CommandsListID, EditChainsDialog::OnItemSelected)
+END_EVENT_TABLE()
+
+enum {
+   BlankColumn,   
+   ItemNumberColumn,    
+   ActionColumn, 
+   ParamsColumn,
+};
+
+/// Constructor
+EditChainsDialog::EditChainsDialog(wxWindow * parent):
+   wxDialog(parent, wxID_ANY, wxString(_("Edit Chains")))
 {
-   ValidateChoices();
+   SetLabel(_("Batch"));         // Provide visual label
+   SetName(_("Batch"));          // Provide audible label
+   Populate();
 }
 
-void BatchProcessDialog::OnOk(wxCommandEvent & event)
+EditChainsDialog::~EditChainsDialog()
 {
-   mOK->Enable(false);
-   DoProcessing();
-   EndModal(true);
 }
 
-void BatchProcessDialog::OnCancel(wxCommandEvent & event)
+/// Creates the dialog and its contents.
+void EditChainsDialog::Populate( )
 {
-   // Can happen if user clicks Cancel before clicking Ok
-   if( mOK->IsEnabled() )
-   {
-      EndModal(false);
-      return;
+   // First any pre-processing for constructing the GUI.
+   mBatchCommands.ReadChains();
+
+   //------------------------- Main section --------------------
+   // Now construct the GUI itself.
+   // Use 'eIsCreatingFromPrefs' so that the GUI is 
+   // initialised with values from gPrefs.
+   ShuttleGui S(this, eIsCreating);
+   PopulateOrExchange(S);
+   // ----------------------- End of main section --------------
+
+   // Set the column size for the chains list.
+   PopulateChains();
+
+   // Set the column size for the chains list.
+   wxSize sz = mChains->GetClientSize();
+   mChains->SetColumnWidth(0, sz.x);
+
+   // Get and validate the currently active chain
+   mActiveChain = gPrefs->Read(wxT("/Batch/ActiveChain"), wxT("CleanSpeech"));
+   int item = mChains->FindItem(-1, mActiveChain);
+   if (mChains->FindItem(-1, mActiveChain) == -1) {
+      item = 0;
+      mActiveChain = mChains->GetItemText(0);
    }
 
-   mCancel->Enable(false);
+   // Load it
+   mChain = mBatchCommands.GetChain(mActiveChain);
 
-   mAbort = true;
-   mBatchCommands->AbortBatch();
+   // Select the name in the list...this will fire an event.
+   mChains->SetItemState(item, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED);
+
+   // We have a bare list.  We need to add columns and content.
+   PopulateList();
+
+   // Size columns properly
+   mList->SetColumnWidth( BlankColumn,  0 ); // First column width is zero, to 
hide it.
+   mList->SetColumnWidth( ItemNumberColumn,  wxLIST_AUTOSIZE );
+   mList->SetColumnWidth( ActionColumn, 110 );
+   mList->SetColumnWidth( ParamsColumn, 220 );
+
+   Layout();
+   Fit();
+   CenterOnParent();
 }
 
-void BatchProcessDialog::DoProcessing()
+/// Defines the dialog and does data exchange with it.
+void EditChainsDialog::PopulateOrExchange( ShuttleGui & S )
 {
-   int i;
-   wxString Temp;
-   for(i=0;i<mList->GetItemCount();i++)
+   S.StartHorizontalLay( wxEXPAND, 1 );
    {
-      if( i>0 )
+      S.StartStatic( _("Chains"));
       {
-         //Clear the arrow in previous item.
-         mList->SetItemImage( i-1,0,0);
+         // 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.
+         // 
+         // With this method:
+         //   1) it compiles fine under windows unicode and normal mode.
+         //   2) xgettext source code has handling for the trailing '\'
+         //
+         // It remains to see if linux and mac can cope and if xgettext 
+         // 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();
+         mChains->InsertColumn( 0, wxT("Chain"), wxLIST_FORMAT_LEFT );
+         S.StartHorizontalLay(wxCENTER, false);
+         {
+            S.Id( AddButtonID ).AddButton( _("&Add") );
+            mRemove = S.Id( RemoveButtonID ).AddButton( _("&Remove") );
+            mRename = S.Id( RenameButtonID ).AddButton( _("Rena&me") );
+         }
+         S.EndHorizontalLay();
       }
-      mList->SetItemImage( i, 1,1);
-      if( !ProcessOne( mList->GetItemText( i )) || mAbort )
+      S.EndStatic();
+
+      S.StartStatic( _("Chain Sequence (Double-Click or press SPACE to 
edit)"),1);
+      {
+         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 );
+         mList->InsertColumn(ItemNumberColumn,    _("No"),   
wxLIST_FORMAT_RIGHT );
+         mList->InsertColumn(ActionColumn,  _("Command"),    
wxLIST_FORMAT_RIGHT );
+         mList->InsertColumn(ParamsColumn,  _("Parameters"), 
wxLIST_FORMAT_LEFT );
+         mList->SetSizeHints(300, 200);
+
+         S.StartHorizontalLay(wxCENTER, false);
+         {
+            S.Id( UpButtonID ).AddButton( _("Move &Up"), wxALIGN_LEFT );
+            S.Id( DownButtonID ).AddButton( _("Move &Down"), wxALIGN_LEFT );
+            mDefaults = S.Id( DefaultsButtonID ).AddButton( _("De&faults") );
+//            S.Id( ImportButtonID ).AddButton( _("&Import"), wxALIGN_LEFT );
+//            S.Id( ExportButtonID ).AddButton( _("E&xport"), wxALIGN_LEFT );
+         }
+         S.EndHorizontalLay();
+      }
+      S.EndStatic();
+   }
+   S.EndHorizontalLay();
+
+   GetSizer()->Add(CreateButtonSizer(wxOK | wxCANCEL), 0, wxALIGN_RIGHT | 
wxBOTTOM, 10);
+
+   return;
+}
+
+/// This clears and updates the contents of mChains
+void EditChainsDialog::PopulateChains()
+{
+   wxArrayString names = mBatchCommands.GetChainNames();
+   int i;
+
+   mChains->DeleteAllItems();
+   for (i = 0; i < names.GetCount(); i++)
+   {
+      mChains->InsertItem(i, names[i]);
+   }
+
+   mChains->Refresh(false);
+}
+
+/// This clears and updates the contents of mList
+void EditChainsDialog::PopulateList()
+{
+   wxString command;
+   wxString params;
+   int i;
+
+   mList->DeleteAllItems();
+
+   for (i = 0; i < mChain->GetCount(); i++) {
+      mBatchCommands.Split( (*mChain)[i], command, params );
+      AddItem( command, params );
+   }
+
+   AddItem( _("- END -"), wxT(""));
+   mList->Refresh(false);
+}
+
+/// 
+void EditChainsDialog::OnAdd(wxCommandEvent &event)
+{
+   while (true) {
+      wxTextEntryDialog d(this,
+                          _("Enter name of new chain"),
+                          _("Batch Chain"));
+      wxString name;
+
+      if (d.ShowModal() == wxID_CANCEL) {
          return;
+      }
+
+      name = d.GetValue().Strip(wxString::both);
+
+      if (name.Length() == 0) {
+         wxMessageBox(_("Name must not be blank"),
+                      _("Batch Chain"),
+                      wxOK | wxICON_ERROR,
+                      this);
+         continue;
+      }
+
+      if (name.Contains(wxT("[")) ||
+          name.Contains(wxT("]")) ||
+          name.Contains(wxCONFIG_PATH_SEPARATOR)) {
+         wxMessageBox(wxString::Format(_("Names may not contain brackets and 
'%c'"), wxCONFIG_PATH_SEPARATOR),
+                      _("Batch Chain"),
+                      wxOK | wxICON_ERROR,
+                      this);
+         continue;
+      }
+
+      if (mChains->FindItem(-1, name) != -1) {
+         wxMessageBox(_("Chain already exists"),
+                      _("Batch Chain"),
+                      wxOK | wxICON_ERROR,
+                      this);
+         continue;
+      }
+
+      mBatchCommands.GetChain(name);
+      
+      long item = mChains->InsertItem(mChains->GetItemCount(), name);
+      mChains->SetItemState(item, wxLIST_STATE_SELECTED, 
wxLIST_STATE_SELECTED);
+
+      break;
    }
 }
 
-bool BatchProcessDialog::ProcessOne(const wxString Filename)
+///
+void EditChainsDialog::OnRemove(wxCommandEvent &event)
 {
-   return mBatchCommands->ApplyBatchToNamedFile( Filename );
+   long item = mChains->GetNextItem(-1,
+                                    wxLIST_NEXT_ALL,
+                                    wxLIST_STATE_SELECTED);
+   if (item == -1) {
+      return;
+   }
+
+   wxString name = mChains->GetItemText(item);
+   wxMessageDialog m(this,
+                     wxString::Format(_("Are you sure you want to delete 
%s?"), name.c_str()),
+                     _("Batch Chain"),
+                     wxYES_NO | wxICON_QUESTION);
+   if (m.ShowModal() == wxID_NO) {
+      return;
+   }
+}
+
+///
+void EditChainsDialog::OnRename(wxCommandEvent &event)
+{
+   long item = mChains->GetNextItem(-1,
+                                    wxLIST_NEXT_ALL,
+                                    wxLIST_STATE_SELECTED);
+   if (item == -1) {
+      return;
+   }
+
+   mChains->EditLabel(item);
+}
+
+///
+void EditChainsDialog::OnUp(wxCommandEvent &event)
+{
+   long item = mList->GetNextItem(-1,
+                                  wxLIST_NEXT_ALL,
+                                  wxLIST_STATE_SELECTED);
+   if (item == -1 || item == 0 || item + 1 == mList->GetItemCount()) {
+      return;
+   }
+
+   wxString commandP, paramsP, commandC, paramsC;
+   wxListItem info;
+
+   info.SetMask(wxLIST_MASK_TEXT);
+   info.SetId(item - 1);
+
+   info.SetColumn(ActionColumn);
+   mList->GetItem(info);
+   commandP = info.GetText();
+
+   info.SetColumn(ParamsColumn);
+   mList->GetItem(info);
+   paramsP = info.GetText();
+
+   info.SetId(item);
+
+   info.SetColumn(ActionColumn);
+   mList->GetItem(info);
+   commandC = info.GetText();
+
+   info.SetColumn(ParamsColumn);
+   mList->GetItem(info);
+   paramsC = info.GetText();
+
+   SetItem(item - 1, commandC, paramsC);
+   SetItem(item, commandP, paramsP);
+
+   mList->SetItemState(item - 1, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED);
+}
+
+///
+void EditChainsDialog::OnDown(wxCommandEvent &event)
+{
+   long item = mList->GetNextItem(-1,
+                                  wxLIST_NEXT_ALL,
+                                  wxLIST_STATE_SELECTED);
+   if (item == -1 || item + 2 >= mList->GetItemCount()) {
+      return;
+   }
+
+   wxString commandN, paramsN, commandC, paramsC;
+   wxListItem info;
+
+   info.SetMask(wxLIST_MASK_TEXT);
+   info.SetId(item + 1);
+
+   info.SetColumn(ActionColumn);
+   mList->GetItem(info);
+   commandN = info.GetText();
+
+   info.SetColumn(ParamsColumn);
+   mList->GetItem(info);
+   paramsN = info.GetText();
+
+   info.SetId(item);
+
+   info.SetColumn(ActionColumn);
+   mList->GetItem(info);
+   commandC = info.GetText();
+
+   info.SetColumn(ParamsColumn);
+   mList->GetItem(info);
+   paramsC = info.GetText();
+
+   SetItem(item, commandN, paramsN);
+   SetItem(item + 1, commandC, paramsC);
+
+   mList->SetItemState(item + 1, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED);
+}
+
+/// Loads a command chain from a file.
+void EditChainsDialog::OnImport(wxCommandEvent &event)
+{
+   mBatchCommands.ImportChain(this, mActiveChain);
+   PopulateList();
+}
+
+/// Saves the current command chain to a file.
+void EditChainsDialog::OnExport(wxCommandEvent &event)
+{
+   mBatchCommands.ExportChain(this, mActiveChain);
+   PopulateList();
+}
+
+/// Select the empty Command chain.
+void EditChainsDialog::OnDefaults(wxCommandEvent &event)
+{
+   mChain = mBatchCommands.RestoreChain(mActiveChain);
+   PopulateList();
+}
+
+/// An item in the chains list has been selected.
+void EditChainsDialog::OnChainSelected(wxListEvent &event)
+{
+   int itemNo = event.GetIndex();
+
+   mActiveChain = mChains->GetItemText(itemNo);
+   mChain = mBatchCommands.GetChain(mActiveChain);
+
+   if (mBatchCommands.IsFixed(mActiveChain)) {
+      mRemove->Disable();
+      mRename->Disable();
+      mDefaults->Enable();
+   }
+   else {
+      mRemove->Enable();
+      mRename->Enable();
+      mDefaults->Disable();
+   }
+
+   PopulateList();
+}
+
+///
+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();
+
+   mChain = mBatchCommands.RenameChain(mActiveChain, newname);
+   mActiveChain = newname;
+}
+
+/// An item in the list has been selected.
+/// Bring up a dialog to allow its parameters to be edited.
+void EditChainsDialog::OnItemSelected(wxListEvent &event)
+{
+   int itemNo = event.GetIndex();
+   // Keep chain short.
+   // We currently only store shortish chains in the prefs.
+   if( itemNo > 20 )
+      return;
+
+   wxString command, params;
+   BatchCommandDialog Dlg( this, -1);
+
+   wxListItem info;
+   info.SetId( itemNo );
+   info.SetMask( wxLIST_MASK_TEXT );
+
+   info.SetColumn( ActionColumn );
+   mList->GetItem( info );
+   command = info.GetText();
+
+   info.SetColumn( ParamsColumn );
+   mList->GetItem( info );
+   params = info.GetText();
+   
+   Dlg.SetCommandAndParams( command, params );
+
+   if( Dlg.ShowModal())
+   {
+      SetItem( 
+         itemNo, 
+         Dlg.mSelectedCommand,
+         Dlg.mSelectedParameters);
+   }
+}
+
+// This commented out code might be useful as a first step if we want an 
immediate response to 
+// switching in and out of CleanSpeech mode.
+// As things currently stand, the batch commands available will NOT reflect 
changes in
+// CleanSpeech mode until we close and reopen the preferences dialog.
+#if 0
+   int mode;
+   AudacityProject *proj = GetActiveProject();
+   mode = gPrefs->Read(wxT("/Batch/CleanSpeechMode"), 1L);
+   proj->GetControlToolBar()->SetCleanSpeechMode(mode == 1);
+#endif
+
+/// Send changed values back to Prefs, and update Audacity.
+void EditChainsDialog::OnOK(wxCommandEvent &event)
+{
+   gPrefs->Write(wxT("/Batch/ActiveChain"), mActiveChain);
+   mBatchCommands.WriteChains();
+   mBatchCommands.FlushChains();
+   EndModal(true);
+}
+
+///
+void EditChainsDialog::OnCancel(wxCommandEvent &event)
+{
+   mBatchCommands.FlushChains();
+   EndModal(false);
+}
+
+/// Add one item into mList
+void EditChainsDialog::AddItem( wxString const & Action, wxString const & 
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 );
+}
+
+/// Sets one item in mList to a command/parameter pair.
+void EditChainsDialog::SetItem(int itemNo, const wxString command, const 
wxString params)
+{
+   // There is a 'rogue' entry of "- END -" at the end of the list
+   // which users can click on to add an entry to the end.
+
+   // There is a special entry of "No Action" in the effects list,
+   // which can be used to delete an entry.
+
+   // special case - deleting an item.
+   if( command.IsSameAs(wxT("No Action")))
+   {
+      //Attempt to delete the 'rogue' entry at the end.
+      if( (itemNo+1) >= mList->GetItemCount() )
+         return;
+
+      mChain->RemoveAt( itemNo );
+      PopulateList();
+      return;
+   }
+
+   // Set the item in the list.
+   mList->SetItem( itemNo ,ActionColumn, command ); 
+   mList->SetItem( itemNo ,ParamsColumn, params );
+
+   // IF at end of list THEN extend list
+   // else replace item.
+   if( (itemNo+1) >= mList->GetItemCount() )
+   {
+      // Add new rogue
+      AddItem( _("- END -"),wxT(""));
+      mChain->Add( mBatchCommands.Join( command, params ) );
+   }
+   else
+   {
+      (*mChain)[itemNo] = mBatchCommands.Join( command, params );
+   }
+
+   mList->Refresh(false);
 }
 
 // Indentation settings for Vim and Emacs and unique identifier for Arch, a

Index: BatchCommands.h
===================================================================
RCS file: /cvsroot/audacity/audacity-src/src/BatchCommands.h,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -d -r1.5 -r1.6
--- BatchCommands.h     4 Jan 2006 19:08:48 -0000       1.5
+++ BatchCommands.h     29 Sep 2006 05:50:21 -0000      1.6
@@ -17,6 +17,8 @@
 
 class Effect;
 
+WX_DECLARE_STRING_HASH_MAP(wxArrayString, CommandChains);
+
 class BatchCommands {
  public:
    // constructors and destructors
@@ -25,6 +27,7 @@
        bool ReportAndSkip( const wxString command, const wxString params );
    bool ApplyCommand( const wxString command, const wxString params );
    bool ApplyCommandInBatchMode(const wxString & command, const wxString 
&params);
+   bool ApplyChain(const wxString & name, const wxString & filename);
    bool ApplySpecialCommand(int iCommand, const wxString command,const 
wxString params);
    bool ApplyEffectCommand(Effect * f, const wxString command, const wxString 
params);
    bool ApplyMenuCommand(const wxString command, const wxString params);
@@ -46,7 +49,6 @@
        wxString GetChainWarnings();
        void ResetChain();
        void AddToChain( const wxString & command );
-   bool ApplyBatchToNamedFile( const wxString & filename );
    void AbortBatch();
        void ReadChain();
        void WriteChain();
@@ -54,10 +56,33 @@
        void SaveChain( wxWindow * parent );
        void SetWavToMp3Chain();
        void SetCleanSpeechChain();
+
+   void ReadChains();
+   void WriteChains();
+   void FlushChains();
+   wxArrayString GetChainNames();
+   int GetChainCount();
+
+   wxArrayString * GetChain(const wxString & name);
+   wxArrayString * RenameChain(const wxString & oldname, const wxString & 
newname);
+   void DeleteChain(const wxString & name);
+
+   bool IsFixed(const wxString & name);
+
+   wxArrayString * RestoreChain(const wxString & name);
+
+   void ImportChain(wxWindow *parent, const wxString & name);
+   void ExportChain(wxWindow *parent, const wxString & name);
+
+   void Split(const wxString & str, wxString & command, wxString & param);
+   wxString Join(const wxString & command, const wxString & param);
+       wxString Defaults(const wxString & command);
+
    wxArrayString mCommandChain;
    wxArrayString mParamsChain;
    bool mAbort;
 
+   CommandChains mCommandChains;
 };
 
 

Index: BatchCommands.cpp
===================================================================
RCS file: /cvsroot/audacity/audacity-src/src/BatchCommands.cpp,v
retrieving revision 1.20
retrieving revision 1.21
diff -u -d -r1.20 -r1.21
--- BatchCommands.cpp   23 Sep 2006 02:28:03 -0000      1.20
+++ BatchCommands.cpp   29 Sep 2006 05:50:21 -0000      1.21
@@ -55,6 +55,7 @@
    wxT("Save Hq Master2"),
    wxT("Stereo To Mono"),
    wxT("ExportMp3"),
+   wxT("ExportOgg"),
    wxT("ExportWav")
 };
 
@@ -167,7 +168,7 @@
 void BatchCommands::SaveChain( wxWindow *parent )
 {
    // Get the initial path
-   wxString pName = gPrefs->Read( wxT("/DefaultExportPath"),
+   wxString pName = gPrefs->Read( wxT("/DefaultChainPath"),
                                   ::wxGetCwd() );
 
    // Get last used filename
@@ -441,24 +442,30 @@
 bool BatchCommands::ApplySpecialCommand(int iCommand, const wxString 
command,const wxString params)
 {
    AudacityProject *project = GetActiveProject();
-   wxString filename = project->BuildCleanFileName(mFileName);
+   wxString filename;
    int numChannels = 1;                //used to switch between mono and 
stereo export
    if (IsMono()) {
-       numChannels = 1;        //export in mono
+      numChannels = 1; //export in mono
    } else {
-       numChannels = 2;        //export in stereo
+      numChannels = 2; //export in stereo
    }
 
-
    if( ReportAndSkip(command, params))
       return true;
 
+   if (mFileName.IsEmpty()) {   
+      filename = project->BuildCleanFileName(project->GetFileName());
+   }
+   else {
+      filename = project->BuildCleanFileName(mFileName);
+   }
+
    // We have a command index, but we don't use it!
    // TODO: Make this special-batch-command code use the menu item code....
    // FIX-ME: No error reporting on write file failure in batch mode.
    if( command == wxT("No Action")){
       return true;
-   } else if (command == wxT("Import") ){
+   } else if (!mFileName.IsEmpty() && command == wxT("Import") ){
       project->OnRemoveTracks();
       project->Import(mFileName);
       project->OnSelectAll();
@@ -586,22 +593,31 @@
    return rc;
 }
 
-
-// ApplyBatchToNamedFile returns true on success, false otherwise.
+// ApplyChain returns true on success, false otherwise.
 // Any error reporting to the user has already been done.
-bool BatchCommands::ApplyBatchToNamedFile(const wxString & filename)
+bool BatchCommands::ApplyChain(const wxString & name, const wxString & 
filename)
 {
+   wxArrayString *chain = GetChain(name);
    mFileName = filename;
    unsigned int i;
+   bool res = true;
 
    mAbort = false;
 
-   for(i=0;i<mCommandChain.GetCount();i++)
-   {
-      if(!ApplyCommandInBatchMode( mCommandChain[i], mParamsChain[i]) || 
mAbort)
-         return false;
+   for (i = 0; i < chain->GetCount(); i++) {
+      wxString command;
+      wxString params;
+
+      Split((*chain)[i], command, params);
+      if (!ApplyCommandInBatchMode(command, params) || mAbort) {
+         res = false;
+         break;
+      }
    }
-   return true;
+
+   mFileName.Empty();
+
+   return res;
 }
 
 // AbortBatch() allows a premature terminatation of a batch.
@@ -658,6 +674,293 @@
    return true;
 }
 
+void BatchCommands::ReadChains()
+{
+   wxString groupName;
+   long groupNdx;
+
+   mCommandChains.empty();
+   RestoreChain(wxT("CleanSpeech"));
+   RestoreChain(wxT("MP3 Conversion"));
+
+   wxString oldPath = gPrefs->GetPath();
+
+   gPrefs->SetPath(wxT("/Batch/Chains"));
+
+   if (gPrefs->GetFirstGroup(groupName, groupNdx)) {
+      do {
+         gPrefs->SetPath(groupName);
+
+         wxArrayString chain;
+         wxString entryName;
+         long entryNdx;
+         if (gPrefs->GetFirstEntry(entryName, entryNdx)) {
+            do {
+               wxString cmd = gPrefs->Read(entryName, wxT(""));
+               if (cmd.Length()) {
+                  chain.Add(cmd);
+               }
+            } while (gPrefs->GetNextEntry(entryName, entryNdx));
+         }
+         mCommandChains[groupName] = chain;
+
+         gPrefs->SetPath(wxT(".."));
+      } while (gPrefs->GetNextGroup(groupName, groupNdx));
+   }
+
+   gPrefs->SetPath(oldPath);
+}
+
+void BatchCommands::WriteChains()
+{
+   wxString groupName;
+
+   wxString oldPath = gPrefs->GetPath();
+
+   gPrefs->DeleteGroup(wxT("/Batch/Chains"));
+   gPrefs->SetPath(wxT("/Batch/Chains"));
+
+   CommandChains::iterator it;
+   for (it = mCommandChains.begin(); it != mCommandChains.end(); it++)
+   {
+      wxString groupName = it->first;
+      wxArrayString chain = it->second;
+
+      gPrefs->SetPath(groupName);
+
+      for (int i = 0; i < chain.GetCount(); i++) {
+         gPrefs->Write(wxString::Format(wxT("%d"), i), chain[i]);
+      }
+
+      gPrefs->SetPath(wxT(".."));
+   } 
+
+   gPrefs->SetPath(oldPath);
+}
+
+void BatchCommands::FlushChains()
+{
+   mCommandChains.clear();
+}
+
+wxArrayString * BatchCommands::GetChain(const wxString & name)
+{
+   return &mCommandChains[name];
+}
+
+wxArrayString * BatchCommands::RenameChain(const wxString & oldname, const 
wxString & newname)
+{
+   wxArrayString chain = *(GetChain(oldname));
+   mCommandChains.erase(oldname);
+   mCommandChains[newname] = chain;
+
+   return GetChain(newname);
+}
+
+void BatchCommands::DeleteChain(const wxString & name)
+{
+   mCommandChains.erase(name);
+}
+
+bool BatchCommands::IsFixed(const wxString & name)
+{
+   if (name == wxT("CleanSpeech") || name == wxT("MP3 Conversion")) {
+      return true;
+   }
+
+   return false;
+}
+
+int BatchCommands::GetChainCount()
+{
+   return (int) mCommandChains.size();
+}
+
+wxArrayString BatchCommands::GetChainNames()
+{
+   wxArrayString names;
+
+   CommandChains::iterator it;
+   for (it = mCommandChains.begin(); it != mCommandChains.end(); it++)
+   {
+      names.Add(it->first);
+   } 
+
+   return names;
+}
+
+
+wxArrayString * BatchCommands::RestoreChain(const wxString & name)
+{
+
+// TIDY-ME: Effects change their name with localisation.
+// Commands (at least currently) don't.  Messy.
+
+/* i18n-hint: Effect name translations must agree with those used elsewhere, 
or batch won't find them */
+
+   wxArrayString *chain = GetChain(name);
+   chain->Empty();
+
+   if (name == wxT("CleanSpeech")) {
+      chain->Add(Defaults(wxT("Import")));
+      chain->Add(Defaults(  _("Stereo To Mono")));
+      chain->Add(Defaults(  _("Normalize")));
+      chain->Add(Defaults(wxT("Save Hq Master1")));
+      chain->Add(Defaults(  _("Noise Removal")));
+      chain->Add(Defaults(  _("Truncate Silence")));
+      chain->Add(Defaults(  _("Leveller")));
+      chain->Add(Defaults(  _("Normalize")));
+      chain->Add(Defaults(wxT("ExportMp3")));
+   }
+   else if (name == wxT("MP3 Conversion")) {
+      chain->Add(Defaults(wxT("Import")));
+      chain->Add(Defaults(  _("Normalize")));
+      chain->Add(Defaults(wxT("ExportMp3")));
+   }
+
+   return chain;
+}
+
+void BatchCommands::ImportChain( wxWindow *parent, const wxString & name )
+{
+   // Get the initial path
+   wxString pName = gPrefs->Read( wxT("/Batch/DefaultChainPath"),
+                                  ::wxGetCwd() );
+
+   // Prompt user for a file name
+   wxString fName = wxFileSelector( _("Select a command chain file..."),
+                                    pName,                     // Path
+                                    name + wxT(".txt"),        // Name
+                                    wxT("txt"),                // Extension
+                                    _("Text files (*.txt)|*.txt|All files 
(*.*)|*.*"),
+                                    0,                         // Flags
+                                    parent);                   // Parent
+
+   // Nothing to do
+   if( !fName )
+      return;
+
+   // Remember path
+   gPrefs->Write( wxT("/Batch/DefaultChainPath"), wxPathOnly( fName ) );
+
+   // Set the file name
+   wxTextFile tf( fName );
+
+   // Open and check
+   tf.Open();
+   if( !tf.IsOpened() )
+   {
+      // wxTextFile will display any errors
+      return;
+   }
+
+   // Clear any previous chain
+   wxArrayString *chain = GetChain( name );
+   chain->Clear();
+
+   // Load commands from the file
+   int i;
+   int lines = tf.GetLineCount();
+   for( i = 0; i < lines; i++ )
+   {
+      chain->Add( tf[ i ] );
+   }
+
+   // Done with the file
+   tf.Close();
+}
+
+void BatchCommands::ExportChain( wxWindow *parent, const wxString & name )
+{
+   // Get the initial path
+   wxString pName = gPrefs->Read( wxT("/DefaultChainPath"),
+                                  ::wxGetCwd() );
+
+   // Prompt user for a file name
+   wxString fName = wxFileSelector( _("Save command chain As:"),
+                                    pName,                        // Path
+                                    name + wxT(".txt"),           // Name
+                                    wxT("txt"),                   // Extension
+                                    _("Text files (*.txt)|*.txt|All files 
(*.*)|*.*"),
+                                    wxSAVE | wxOVERWRITE_PROMPT,  // Flags
+                                    parent );                     // Parent
+
+   // Nothing to do
+   if( !fName )
+      return;
+
+   // Remember path
+   gPrefs->Write( wxT("/DefaultChainPath"), wxPathOnly( fName ) );
+
+   // Set the file name
+   wxTextFile tf( fName );
+
+   // (Possibly) create new file
+   if( !tf.Exists() )
+   {
+      tf.Create();
+   }
+
+   // Open and check
+   tf.Open();
+   if( !tf.IsOpened() )
+   {
+      // wxTextFile will display any errors
+      return;
+   }
+
+   // Start with a clean slate
+   tf.Clear();
+
+   // Copy over the commands
+   wxArrayString *chain = GetChain( name );
+   int i;
+   int lines = chain->GetCount();
+   for( i = 0; i < lines; i++ )
+   {
+      tf.AddLine( (*chain)[i] );
+   }
+
+   // Write the chain
+   tf.Write();
+
+   // Done with the file
+   tf.Close();
+}
+
+void BatchCommands::Split(const wxString & str, wxString & command, wxString & 
param)
+{
+   int splitAt;
+   int i;
+
+   command.Empty();
+   param.Empty();
+
+   if (str.IsEmpty()) {
+      return;
+   }
+
+   splitAt = str.Find(wxT(':'));
+   if (splitAt < 0) {
+      return;
+   }
+
+   command = str.Mid(0, splitAt);
+   param = str.Mid(splitAt + 1);
+
+   return;
+}
+
+wxString BatchCommands::Join(const wxString & command, const wxString & param)
+{
+   return command + wxT(": ") + param;
+}
+
+wxString BatchCommands::Defaults(const wxString & command)
+{
+   return Join(command, GetCurrentParamsFor(command));
+}
+
 // Indentation settings for Vim and Emacs and unique identifier for Arch, a
 // version control system. Please do not modify past this point.
 //

Index: Menus.cpp
===================================================================
RCS file: /cvsroot/audacity/audacity-src/src/Menus.cpp,v
retrieving revision 1.281
retrieving revision 1.282
diff -u -d -r1.281 -r1.282
--- Menus.cpp   24 Sep 2006 18:10:41 -0000      1.281
+++ Menus.cpp   29 Sep 2006 05:50:21 -0000      1.282
@@ -76,6 +76,7 @@
 #include "Resample.h"
 #include "BatchProcessDialog.h"
 #include "BatchCommands.h"
+#include "prefs/BatchPrefs.h"
 
 #include "toolbars/ToolManager.h"
 #include "toolbars/ControlToolBar.h"
@@ -325,6 +326,7 @@
    {
       c->AddItem(wxT("BatchProcess"),     _("Process &Batch..."),   
FN(OnBatch));
       c->SetCommandFlags(wxT("BatchProcess"), AudioIONotBusyFlag, 
AudioIONotBusyFlag);
+      c->AddItem(wxT("EditChains"),       _("Edit Chains..."),   
FN(OnEditChains));
    }
 
    c->AddSeparator();
@@ -4153,58 +4155,25 @@
 
 void AudacityProject::OnBatch()
 {
-   wxUint32 flags = GetTrackFlags();
-   size_t numProjects = gAudacityProjects.Count();
-   if (numProjects != 1) 
-   {
-      wxMessageBox(_("Please close all Audacity projects first."));
-      return;
-   }
-   if( (flags & TracksExistFlag) != 0)
-   {
-      wxMessageBox(_("Please save and close the current project first."));
-      return;
-   }
-
-   // Create (hidden) batch processing dialog, so that we can 
-   // query the batch command list and see if there is a sensible
-   // set of batch commands.
-   BatchProcessDialog batchProcessDlg( this, -1 );
-   wxString batchWarnings = batchProcessDlg.mBatchCommands->GetChainWarnings();
-   if( !batchWarnings.IsEmpty() )
-   {
-      wxMessageBox( batchWarnings + 
-         _("\n\nPlease edit the batch chain in preferences."));
-      return;
-   }
-   
-   wxString path = gPrefs->Read(wxT("/DefaultOpenPath"), ::wxGetCwd());
-   wxString prompt =  mCleanSpeechMode ? 
-      _("Select vocal file(s) for batch CleanSpeech Chain...") :
-      _("Select file(s) for batch processing...");
-   wxString fileSelector = mCleanSpeechMode ? 
-      _("Vocal files (*.wav;*.mp3)|*.wav;*.mp3|WAV files (*.wav)|*.wav|MP3 
files (*.mp3)|*.mp3") :
-      _("All files (*.*)|*.*|WAV files (*.wav)|*.wav|AIFF files 
(*.aif)|*.aif|AU files (*.au)|*.au|MP3 files (*.mp3)|*.mp3|Ogg Vorbis files 
(*.ogg)|*.ogg|FLAC files (*.flac)|*.flac"
-//      "|List of Files (*.lof)|*.lof"
-       );
-
-   wxFileDialog dlog(NULL, prompt,
-                     path, wxT(""),fileSelector,
-                     wxOPEN | wxMULTIPLE);
-
-   if (dlog.ShowModal() != wxID_OK) {
-      return;
-   }
-
-   wxArrayString selectedFiles;
-   dlog.GetPaths(selectedFiles);
-
-   selectedFiles.Sort();
+   BatchProcessDialog d(this);
+   d.ShowModal();
+}
 
-   batchProcessDlg.PopulateList( selectedFiles );
-   // ShowModal() gives a progress screen and also applies the chain.
-   batchProcessDlg.ShowModal();
-   return;
+void AudacityProject::OnEditChains()
+{
+   EditChainsDialog d(this);
+   d.ShowModal();
+#if 0
+   wxDialog d(this, wxID_ANY, _("Edit Chains"), wxDefaultPosition, wxSize(500, 
500));
+   wxBoxSizer *s = new wxBoxSizer(wxVERTICAL);
+   BatchPrefs *b = new BatchPrefs(&d);
+   s->Add(b);
+   s->Add(d.CreateButtonSizer(wxOK | wxCANCEL));
+   d.SetSizerAndFit(s);
+   d.Layout();
+   d.ShowModal();
+   b->Destroy();
+#endif
 }
 
 wxString AudacityProject::BuildCleanFileName(wxString fileName)

Index: Menus.h
===================================================================
RCS file: /cvsroot/audacity/audacity-src/src/Menus.h,v
retrieving revision 1.89
retrieving revision 1.90
diff -u -d -r1.89 -r1.90
--- Menus.h     24 Sep 2006 18:10:41 -0000      1.89
+++ Menus.h     29 Sep 2006 05:50:21 -0000      1.90
@@ -264,6 +264,7 @@
         //lda CleanSpeech Menu
 
 void OnBatch();
+void OnEditChains();
 void OnImportCleanSpeechPresets();
 void OnExportCleanSpeechPresets();
 void OnStereoToMono(int index);

Index: BatchProcessDialog.h
===================================================================
RCS file: /cvsroot/audacity/audacity-src/src/BatchProcessDialog.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- BatchProcessDialog.h        25 Nov 2005 05:51:50 -0000      1.2
+++ BatchProcessDialog.h        29 Sep 2006 05:50:21 -0000      1.3
@@ -25,6 +25,9 @@
 #include  <wx/menuitem.h>
 #include  <wx/checklst.h>
 
+#include "ShuttleGui.h"
+#include "BatchCommands.h"
+
 class wxWindow;
 class wxCheckBox;
 class wxChoice;
@@ -34,33 +37,72 @@
 class wxListCtrl;
 class wxListEvent;
 class wxButton;
-class BatchCommands;
 
 class BatchProcessDialog:public wxDialog {
  public:
    // constructors and destructors
-   BatchProcessDialog(wxWindow * parent, wxWindowID id);
+   BatchProcessDialog(wxWindow * parent);
    virtual ~BatchProcessDialog();
  public:
-       bool ProcessOne( const wxString Filename );
-       void DoProcessing();
-   void OnChoice(wxCommandEvent & event);
-   void OnOk(wxCommandEvent & event);
-   void OnCancel(wxCommandEvent & event);
+   void Populate();
+   void PopulateOrExchange( ShuttleGui & S );
 
-   void ValidateChoices();
-   void PopulateList(wxArrayString fileList);
+   void OnApplyToProject(wxCommandEvent & event);
+   void OnApplyToFiles(wxCommandEvent & event);
+   void OnCancel(wxCommandEvent & event);
 
-   wxButton   *mOK;
-   wxButton   *mCancel;
+   wxButton *mOK;
+   wxButton *mCancel;
+   wxListCtrl *mChains;
    wxListCtrl *mList;
-   BatchCommands * mBatchCommands;
+   BatchCommands mBatchCommands;
 
    bool mAbort;
 
    DECLARE_EVENT_TABLE()
 };
 
+class EditChainsDialog:public wxDialog
+{
+public:
+   EditChainsDialog(wxWindow * parent);
+   ~EditChainsDialog();
+
+private:
+   void Populate();
+   void PopulateOrExchange( ShuttleGui & S );
+   void PopulateChains();
+       void PopulateList();
+   void AddItem( wxString const & Action, wxString const & Params);
+       void SetItem( int ItemNo, const wxString command, const wxString params 
);
+
+   void OnOK(wxCommandEvent &event);
+   void OnCancel(wxCommandEvent &event);
+   void OnAdd(wxCommandEvent &event);
+   void OnRemove(wxCommandEvent &event);
+   void OnRename(wxCommandEvent &event);
+   void OnUp(wxCommandEvent &event);
+   void OnDown(wxCommandEvent &event);
+   void OnImport(wxCommandEvent &event);
+   void OnExport(wxCommandEvent &event);
+   void OnDefaults(wxCommandEvent &event);
+   void OnChainSelected(wxListEvent &event);
+   void OnChainsBeginEdit(wxListEvent &event);
+   void OnChainsEndEdit(wxListEvent &event);
+   void OnItemSelected(wxListEvent &event);
+
+   wxListCtrl * mChains; /// List of chains.
+   wxListCtrl * mList;   /// List of commands in current command chain.
+   wxButton * mRemove;
+   wxButton * mRename;
+   wxButton * mDefaults;
+
+   BatchCommands mBatchCommands;  /// Provides list of available commands.
+   wxString mActiveChain;
+   wxArrayString *mChain;
+
+   DECLARE_EVENT_TABLE();
+};
 
 #endif
 


-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys -- and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
Audacity-cvs mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/audacity-cvs

Reply via email to