mirror of
https://github.com/cookiengineer/audacity
synced 2025-09-14 07:20:35 +02:00
File Menus
This commit is contained in:
parent
3308054170
commit
4d6cad8ebc
665
src/Menus.cpp
665
src/Menus.cpp
@ -68,13 +68,7 @@ menu items.
|
||||
#include "Dependencies.h"
|
||||
#include "float_cast.h"
|
||||
#include "LabelTrack.h"
|
||||
#include "commands/CommandManager.h"
|
||||
#ifdef USE_MIDI
|
||||
#include "import/ImportMIDI.h"
|
||||
#endif // USE_MIDI
|
||||
#include "import/ImportRaw.h"
|
||||
#include "export/Export.h"
|
||||
#include "export/ExportMultiple.h"
|
||||
#include "prefs/PrefsDialog.h"
|
||||
#include "prefs/PlaybackPrefs.h"
|
||||
#include "ShuttleGui.h"
|
||||
@ -87,7 +81,6 @@ menu items.
|
||||
#include "ModuleManager.h"
|
||||
#include "PluginManager.h"
|
||||
#include "Prefs.h"
|
||||
#include "Printing.h"
|
||||
#ifdef USE_MIDI
|
||||
#include "NoteTrack.h"
|
||||
#endif // USE_MIDI
|
||||
@ -100,7 +93,6 @@ menu items.
|
||||
#include "ondemand/ODManager.h"
|
||||
|
||||
#include "BatchProcessDialog.h"
|
||||
#include "BatchCommands.h"
|
||||
#include "prefs/BatchPrefs.h"
|
||||
|
||||
#include "toolbars/ToolManager.h"
|
||||
@ -128,7 +120,6 @@ menu items.
|
||||
#include "DeviceManager.h"
|
||||
|
||||
#include "UndoManager.h"
|
||||
#include "WaveTrack.h"
|
||||
|
||||
#if defined(EXPERIMENTAL_CRASH_REPORT)
|
||||
#include <wx/debugrpt.h>
|
||||
@ -147,7 +138,6 @@ menu items.
|
||||
#include "widgets/Meter.h"
|
||||
#include "widgets/ErrorDialog.h"
|
||||
#include "./commands/AudacityCommand.h"
|
||||
#include "commands/CommandContext.h"
|
||||
|
||||
static MenuTable::BaseItemPtrs PopulateMacrosMenu(
|
||||
CommandFlag flags );
|
||||
@ -232,11 +222,8 @@ enum {
|
||||
POST_TIMER_RECORD_SHUTDOWN
|
||||
};
|
||||
|
||||
#include "commands/CommandContext.h"
|
||||
#include "commands/ScreenshotCommand.h"
|
||||
|
||||
#include "BatchCommands.h"
|
||||
|
||||
|
||||
//
|
||||
// Effects menu arrays
|
||||
@ -541,8 +528,9 @@ static CommandHandlerObject &findMenuCommandHandler(AudacityProject &project)
|
||||
static_cast<CommandFunctorPointer>(& MenuCommandHandler :: X)
|
||||
#define XXO(X) _(X), wxString{X}.Contains("...")
|
||||
|
||||
namespace {
|
||||
MenuTable::BaseItemPtr FileMenu( AudacityProject& );
|
||||
|
||||
namespace {
|
||||
MenuTable::BaseItemPtr EditMenu( AudacityProject& );
|
||||
MenuTable::BaseItemPtr SelectMenu( AudacityProject& );
|
||||
MenuTable::BaseItemPtr ToolbarsMenu( AudacityProject& );
|
||||
@ -617,151 +605,6 @@ static const auto menuTree = MenuTable::Items(
|
||||
|
||||
namespace {
|
||||
|
||||
MenuTable::BaseItemPtr FileMenu( AudacityProject& )
|
||||
{
|
||||
using namespace MenuTable;
|
||||
|
||||
return Menu( _("&File"),
|
||||
/*i18n-hint: "New" is an action (verb) to create a NEW project*/
|
||||
Command( wxT("New"), XXO("&New"), FN(OnNew),
|
||||
AudioIONotBusyFlag, wxT("Ctrl+N") ),
|
||||
|
||||
/*i18n-hint: (verb)*/
|
||||
Command( wxT("Open"), XXO("&Open..."), FN(OnOpen),
|
||||
AudioIONotBusyFlag, wxT("Ctrl+O") ),
|
||||
|
||||
#ifdef EXPERIMENTAL_RESET
|
||||
// Empty the current project and forget its name and path. DANGEROUS
|
||||
// It's just for developers.
|
||||
// Do not translate this menu item (no XXO).
|
||||
// It MUST not be shown to regular users.
|
||||
Command( wxT("Reset"), XXO("&Dangerous Reset..."), FN(OnProjectReset),
|
||||
AudioIONotBusyFlag ),
|
||||
#endif
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Menu(
|
||||
#ifdef __WXMAC__
|
||||
/* i18n-hint: This is the name of the menu item on Mac OS X only */
|
||||
_("Open Recent")
|
||||
#else
|
||||
/* i18n-hint: This is the name of the menu item on Windows and Linux */
|
||||
_("Recent &Files")
|
||||
#endif
|
||||
,
|
||||
Special( [](AudacityProject &, wxMenu &theMenu){
|
||||
// Recent Files and Recent Projects menus
|
||||
wxGetApp().GetRecentFiles()->UseMenu( &theMenu );
|
||||
wxGetApp().GetRecentFiles()->AddFilesToMenu( &theMenu );
|
||||
|
||||
wxWeakRef<wxMenu> recentFilesMenu{ &theMenu };
|
||||
wxTheApp->CallAfter( [=] {
|
||||
// Bug 143 workaround.
|
||||
// The bug is in wxWidgets. For a menu that has scrollers,
|
||||
// the scrollers have an ID of 0 (not wxID_NONE which is -3).
|
||||
// Therefore wxWidgets attempts to find a help string. See
|
||||
// wxFrameBase::ShowMenuHelp(int menuId)
|
||||
// It finds a bogus automatic help string of "Recent &Files"
|
||||
// from that submenu.
|
||||
// So we set the help string for command with Id 0 to empty.
|
||||
if ( recentFilesMenu )
|
||||
recentFilesMenu->GetParent()->SetHelpString( 0, "" );
|
||||
} );
|
||||
} )
|
||||
),
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Command( wxT("Close"), XXO("&Close"), FN(OnClose),
|
||||
AudioIONotBusyFlag, wxT("Ctrl+W") ),
|
||||
|
||||
Separator(),
|
||||
|
||||
Menu( _("&Save Project"),
|
||||
Command( wxT("Save"), XXO("&Save Project"), FN(OnSave),
|
||||
AudioIONotBusyFlag | UnsavedChangesFlag, wxT("Ctrl+S") ),
|
||||
Command( wxT("SaveAs"), XXO("Save Project &As..."), FN(OnSaveAs),
|
||||
AudioIONotBusyFlag ),
|
||||
// TODO: The next two items should be disabled if project is empty
|
||||
Command( wxT("SaveCopy"), XXO("Save Lossless Copy of Project..."),
|
||||
FN(OnSaveCopy), AudioIONotBusyFlag )
|
||||
#ifdef USE_LIBVORBIS
|
||||
,
|
||||
Command( wxT("SaveCompressed"),
|
||||
XXO("&Save Compressed Copy of Project..."),
|
||||
FN(OnSaveCompressed), AudioIONotBusyFlag )
|
||||
#endif
|
||||
),
|
||||
|
||||
Separator(),
|
||||
|
||||
Menu( _("&Export"),
|
||||
// Enable Export audio commands only when there are audio tracks.
|
||||
Command( wxT("ExportMp3"), XXO("Export as MP&3"), FN(OnExportMp3),
|
||||
AudioIONotBusyFlag | WaveTracksExistFlag ),
|
||||
|
||||
Command( wxT("ExportWav"), XXO("Export as &WAV"), FN(OnExportWav),
|
||||
AudioIONotBusyFlag | WaveTracksExistFlag ),
|
||||
|
||||
Command( wxT("ExportOgg"), XXO("Export as &OGG"), FN(OnExportOgg),
|
||||
AudioIONotBusyFlag | WaveTracksExistFlag ),
|
||||
|
||||
Command( wxT("Export"), XXO("&Export Audio..."), FN(OnExportAudio),
|
||||
AudioIONotBusyFlag | WaveTracksExistFlag, wxT("Ctrl+Shift+E") ),
|
||||
|
||||
// Enable Export Selection commands only when there's a selection.
|
||||
Command( wxT("ExportSel"), XXO("Expo&rt Selected Audio..."),
|
||||
FN(OnExportSelection),
|
||||
AudioIONotBusyFlag | TimeSelectedFlag | WaveTracksSelectedFlag ),
|
||||
|
||||
Command( wxT("ExportLabels"), XXO("Export &Labels..."),
|
||||
FN(OnExportLabels),
|
||||
AudioIONotBusyFlag | LabelTracksExistFlag ),
|
||||
// Enable Export audio commands only when there are audio tracks.
|
||||
Command( wxT("ExportMultiple"), XXO("Export &Multiple..."),
|
||||
FN(OnExportMultiple),
|
||||
AudioIONotBusyFlag | WaveTracksExistFlag, wxT("Ctrl+Shift+L") )
|
||||
#if defined(USE_MIDI)
|
||||
,
|
||||
Command( wxT("ExportMIDI"), XXO("Export MI&DI..."), FN(OnExportMIDI),
|
||||
AudioIONotBusyFlag | NoteTracksExistFlag )
|
||||
#endif
|
||||
),
|
||||
|
||||
Menu( _("&Import"),
|
||||
Command( wxT("ImportAudio"), XXO("&Audio..."), FN(OnImport),
|
||||
AudioIONotBusyFlag, wxT("Ctrl+Shift+I") ),
|
||||
Command( wxT("ImportLabels"), XXO("&Labels..."), FN(OnImportLabels),
|
||||
AudioIONotBusyFlag ),
|
||||
#ifdef USE_MIDI
|
||||
Command( wxT("ImportMIDI"), XXO("&MIDI..."), FN(OnImportMIDI),
|
||||
AudioIONotBusyFlag ),
|
||||
#endif // USE_MIDI
|
||||
Command( wxT("ImportRaw"), XXO("&Raw Data..."), FN(OnImportRaw),
|
||||
AudioIONotBusyFlag )
|
||||
),
|
||||
|
||||
Separator(),
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Command( wxT("PageSetup"), XXO("Pa&ge Setup..."), FN(OnPageSetup),
|
||||
AudioIONotBusyFlag | TracksExistFlag ),
|
||||
/* i18n-hint: (verb) It's item on a menu. */
|
||||
Command( wxT("Print"), XXO("&Print..."), FN(OnPrint),
|
||||
AudioIONotBusyFlag | TracksExistFlag ),
|
||||
|
||||
Separator(),
|
||||
|
||||
// On the Mac, the Exit item doesn't actually go here...wxMac will pull it out
|
||||
// and put it in the Audacity menu for us based on its ID.
|
||||
/* i18n-hint: (verb) It's item on a menu. */
|
||||
Command( wxT("Exit"), XXO("E&xit"), FN(OnExit),
|
||||
AlwaysEnabledFlag, wxT("Ctrl+Q") )
|
||||
);
|
||||
}
|
||||
|
||||
MenuTable::BaseItemPtr LabelEditMenus( AudacityProject &project )
|
||||
{
|
||||
using namespace MenuTable;
|
||||
@ -5567,333 +5410,12 @@ void MenuCommandHandler::OnAudacityCommand(const CommandContext & ctx)
|
||||
// File Menu
|
||||
//
|
||||
|
||||
void MenuCommandHandler::OnNew(const CommandContext &WXUNUSED(context) )
|
||||
{
|
||||
CreateNewAudacityProject();
|
||||
}
|
||||
|
||||
void MenuCommandHandler::OnOpen(const CommandContext &context)
|
||||
{
|
||||
auto &project = context.project;
|
||||
AudacityProject::OpenFiles(&project);
|
||||
}
|
||||
|
||||
// JKC: This is like OnClose, except it emptys the project in place,
|
||||
// rather than createing a new empty project (with new toolbars etc).
|
||||
// It does not test for unsaved changes.
|
||||
// It is not in the menus by default. Its main purpose is/was for
|
||||
// developers checking functionality of ResetProjectToEmpty().
|
||||
void MenuCommandHandler::OnProjectReset(const CommandContext &context)
|
||||
{
|
||||
auto &project = context.project;
|
||||
project.ResetProjectToEmpty();
|
||||
}
|
||||
|
||||
void MenuCommandHandler::OnClose(const CommandContext &context)
|
||||
{
|
||||
auto &project = context.project;
|
||||
project.SetMenuClose(true);
|
||||
project.Close();
|
||||
}
|
||||
|
||||
void MenuCommandHandler::OnSave(const CommandContext &context)
|
||||
{
|
||||
auto &project = context.project;
|
||||
project.Save();
|
||||
}
|
||||
|
||||
void MenuCommandHandler::OnSaveAs(const CommandContext &context)
|
||||
{
|
||||
auto &project = context.project;
|
||||
project.SaveAs();
|
||||
}
|
||||
|
||||
void MenuCommandHandler::OnSaveCopy(const CommandContext &context)
|
||||
{
|
||||
auto &project = context.project;
|
||||
project.SaveAs(true, true);
|
||||
}
|
||||
|
||||
#ifdef USE_LIBVORBIS
|
||||
void MenuCommandHandler::OnSaveCompressed(const CommandContext &context)
|
||||
{
|
||||
auto &project = context.project;
|
||||
project.SaveAs(true);
|
||||
}
|
||||
#endif
|
||||
|
||||
void MenuCommandHandler::OnCheckDependencies(const CommandContext &context)
|
||||
{
|
||||
auto &project = context.project;
|
||||
::ShowDependencyDialogIfNeeded(&project, false);
|
||||
}
|
||||
|
||||
void MenuCommandHandler::OnExit(const CommandContext &WXUNUSED(context) )
|
||||
{
|
||||
QuitAudacity();
|
||||
}
|
||||
|
||||
void MenuCommandHandler::OnExportLabels(const CommandContext &context)
|
||||
{
|
||||
auto &project = context.project;
|
||||
auto tracks = project.GetTracks();
|
||||
|
||||
/* i18n-hint: filename containing exported text from label tracks */
|
||||
wxString fName = _("labels.txt");
|
||||
auto trackRange = tracks->Any<const LabelTrack>();
|
||||
auto numLabelTracks = trackRange.size();
|
||||
|
||||
if (numLabelTracks == 0) {
|
||||
AudacityMessageBox(_("There are no label tracks to export."));
|
||||
return;
|
||||
}
|
||||
else
|
||||
fName = (*trackRange.rbegin())->GetName();
|
||||
|
||||
fName = FileNames::SelectFile(FileNames::Operation::Export,
|
||||
_("Export Labels As:"),
|
||||
wxEmptyString,
|
||||
fName,
|
||||
wxT("txt"),
|
||||
wxT("*.txt"),
|
||||
wxFD_SAVE | wxFD_OVERWRITE_PROMPT | wxRESIZE_BORDER,
|
||||
&project);
|
||||
|
||||
if (fName == wxT(""))
|
||||
return;
|
||||
|
||||
// Move existing files out of the way. Otherwise wxTextFile will
|
||||
// append to (rather than replace) the current file.
|
||||
|
||||
if (wxFileExists(fName)) {
|
||||
#ifdef __WXGTK__
|
||||
wxString safetyFileName = fName + wxT("~");
|
||||
#else
|
||||
wxString safetyFileName = fName + wxT(".bak");
|
||||
#endif
|
||||
|
||||
if (wxFileExists(safetyFileName))
|
||||
wxRemoveFile(safetyFileName);
|
||||
|
||||
wxRename(fName, safetyFileName);
|
||||
}
|
||||
|
||||
wxTextFile f(fName);
|
||||
f.Create();
|
||||
f.Open();
|
||||
if (!f.IsOpened()) {
|
||||
AudacityMessageBox( wxString::Format(
|
||||
_("Couldn't write to file: %s"), fName ) );
|
||||
return;
|
||||
}
|
||||
|
||||
for (auto lt : trackRange)
|
||||
lt->Export(f);
|
||||
|
||||
f.Write();
|
||||
f.Close();
|
||||
}
|
||||
|
||||
|
||||
#ifdef USE_MIDI
|
||||
void MenuCommandHandler::OnExportMIDI(const CommandContext &context)
|
||||
{
|
||||
auto &project = context.project;
|
||||
auto tracks = project.GetTracks();
|
||||
|
||||
// Make sure that there is
|
||||
// exactly one NoteTrack selected.
|
||||
const auto range = tracks->Selected< const NoteTrack >();
|
||||
const auto numNoteTracksSelected = range.size();
|
||||
|
||||
if(numNoteTracksSelected > 1) {
|
||||
AudacityMessageBox(_(
|
||||
"Please select only one Note Track at a time."));
|
||||
return;
|
||||
}
|
||||
else if(numNoteTracksSelected < 1) {
|
||||
AudacityMessageBox(_(
|
||||
"Please select a Note Track."));
|
||||
return;
|
||||
}
|
||||
|
||||
wxASSERT(numNoteTracksSelected);
|
||||
if (!numNoteTracksSelected)
|
||||
return;
|
||||
|
||||
const auto nt = *range.begin();
|
||||
|
||||
while(true) {
|
||||
|
||||
wxString fName = wxT("");
|
||||
|
||||
fName = FileNames::SelectFile(FileNames::Operation::Export,
|
||||
_("Export MIDI As:"),
|
||||
wxEmptyString,
|
||||
fName,
|
||||
wxT(".mid|.gro"),
|
||||
_("MIDI file (*.mid)|*.mid|Allegro file (*.gro)|*.gro"),
|
||||
wxFD_SAVE | wxFD_OVERWRITE_PROMPT | wxRESIZE_BORDER,
|
||||
&project);
|
||||
|
||||
if (fName == wxT(""))
|
||||
return;
|
||||
|
||||
if(!fName.Contains(wxT("."))) {
|
||||
fName = fName + wxT(".mid");
|
||||
}
|
||||
|
||||
// Move existing files out of the way. Otherwise wxTextFile will
|
||||
// append to (rather than replace) the current file.
|
||||
|
||||
if (wxFileExists(fName)) {
|
||||
#ifdef __WXGTK__
|
||||
wxString safetyFileName = fName + wxT("~");
|
||||
#else
|
||||
wxString safetyFileName = fName + wxT(".bak");
|
||||
#endif
|
||||
|
||||
if (wxFileExists(safetyFileName))
|
||||
wxRemoveFile(safetyFileName);
|
||||
|
||||
wxRename(fName, safetyFileName);
|
||||
}
|
||||
|
||||
if(fName.EndsWith(wxT(".mid")) || fName.EndsWith(wxT(".midi"))) {
|
||||
nt->ExportMIDI(fName);
|
||||
} else if(fName.EndsWith(wxT(".gro"))) {
|
||||
nt->ExportAllegro(fName);
|
||||
} else {
|
||||
wxString msg = _("You have selected a filename with an unrecognized file extension.\nDo you want to continue?");
|
||||
wxString title = _("Export MIDI");
|
||||
int id = AudacityMessageBox(msg, title, wxYES_NO);
|
||||
if (id == wxNO) {
|
||||
continue;
|
||||
} else if (id == wxYES) {
|
||||
nt->ExportMIDI(fName);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif // USE_MIDI
|
||||
|
||||
|
||||
void MenuCommandHandler::DoExport
|
||||
(AudacityProject &project, const wxString & Format )
|
||||
{
|
||||
auto tracks = project.GetTracks();
|
||||
|
||||
Exporter e;
|
||||
|
||||
wxGetApp().SetMissingAliasedFileWarningShouldShow(true);
|
||||
double t0 = 0.0;
|
||||
double t1 = tracks->GetEndTime();
|
||||
|
||||
// Prompt for file name and/or extension?
|
||||
bool bPromptingRequired =
|
||||
(project.mBatchMode == 0) || project.GetFileName().IsEmpty() ||
|
||||
Format.IsEmpty();
|
||||
wxString filename;
|
||||
|
||||
if (!bPromptingRequired) {
|
||||
|
||||
// We're in batch mode, and we have an mFileName and Format.
|
||||
wxString extension = ".";
|
||||
extension += Format;
|
||||
extension.MakeLower();
|
||||
|
||||
filename = MacroCommands::BuildCleanFileName(project.GetFileName(), extension);
|
||||
|
||||
// Bug 1854, No warning of file overwrite (when export is called from Macros).
|
||||
int counter = 0;
|
||||
bPromptingRequired = wxFileExists(filename);
|
||||
|
||||
// We'll try alternative names to avoid overwriting.
|
||||
while ( bPromptingRequired && counter < 100 ) {
|
||||
counter++;
|
||||
wxString number;
|
||||
number.Printf("%03i", counter);
|
||||
// So now the name has a number in it too.
|
||||
filename =
|
||||
MacroCommands::BuildCleanFileName(project.GetFileName(), number + extension);
|
||||
bPromptingRequired = wxFileExists(filename);
|
||||
}
|
||||
// If we've run out of alternative names, we will fall back to prompting - even if in a macro.
|
||||
}
|
||||
|
||||
|
||||
if (bPromptingRequired)
|
||||
{
|
||||
// Do export with prompting.
|
||||
e.SetDefaultFormat(Format);
|
||||
e.Process(&project, false, t0, t1);
|
||||
}
|
||||
else
|
||||
{
|
||||
wxGetApp().AddFileToHistory(filename);
|
||||
// We're in batch mode, the file does not exist already.
|
||||
// We really can proceed without prompting.
|
||||
int nChannels = MacroCommands::IsMono() ? 1 : 2;
|
||||
e.Process(
|
||||
&project, // AudacityProject
|
||||
nChannels, // numChannels,
|
||||
Format, // type,
|
||||
filename, // filename,
|
||||
false, // selectedOnly,
|
||||
t0, // t0
|
||||
t1 // t1
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void MenuCommandHandler::OnExportAudio(const CommandContext &context)
|
||||
{
|
||||
auto &project = context.project;
|
||||
DoExport(project, "");
|
||||
}
|
||||
|
||||
void MenuCommandHandler::OnExportMp3(const CommandContext &context)
|
||||
{
|
||||
auto &project = context.project;
|
||||
DoExport(project, "MP3");
|
||||
}
|
||||
|
||||
void MenuCommandHandler::OnExportWav(const CommandContext &context)
|
||||
{
|
||||
auto &project = context.project;
|
||||
DoExport(project, "WAV");
|
||||
}
|
||||
|
||||
void MenuCommandHandler::OnExportOgg(const CommandContext &context)
|
||||
{
|
||||
auto &project = context.project;
|
||||
DoExport(project, "OGG");
|
||||
}
|
||||
|
||||
|
||||
void MenuCommandHandler::OnExportSelection(const CommandContext &context)
|
||||
{
|
||||
auto &project = context.project;
|
||||
auto &selectedRegion = project.GetViewInfo().selectedRegion;
|
||||
Exporter e;
|
||||
|
||||
wxGetApp().SetMissingAliasedFileWarningShouldShow(true);
|
||||
e.SetFileDialogTitle( _("Export Selected Audio") );
|
||||
e.Process(&project, true, selectedRegion.t0(),
|
||||
selectedRegion.t1());
|
||||
}
|
||||
|
||||
void MenuCommandHandler::OnExportMultiple(const CommandContext &context)
|
||||
{
|
||||
auto &project = context.project;
|
||||
ExportMultiple em(&project);
|
||||
|
||||
wxGetApp().SetMissingAliasedFileWarningShouldShow(true);
|
||||
em.ShowModal();
|
||||
}
|
||||
|
||||
void MenuCommandHandler::OnPreferences(const CommandContext &context)
|
||||
{
|
||||
auto &project = context.project;
|
||||
@ -5968,20 +5490,6 @@ void MenuCommandHandler::OnReloadPreferences(const CommandContext &context )
|
||||
}
|
||||
}
|
||||
|
||||
void MenuCommandHandler::OnPageSetup(const CommandContext &context)
|
||||
{
|
||||
auto &project = context.project;
|
||||
HandlePageSetup(&project);
|
||||
}
|
||||
|
||||
void MenuCommandHandler::OnPrint(const CommandContext &context)
|
||||
{
|
||||
auto &project = context.project;
|
||||
auto name = project.GetName();
|
||||
auto tracks = project.GetTracks();
|
||||
HandlePrint(&project, name, tracks);
|
||||
}
|
||||
|
||||
//
|
||||
// Edit Menu
|
||||
//
|
||||
@ -8199,175 +7707,6 @@ void MenuCommandHandler::OnShowEffectsRack(const &WXUNUSED(context) )
|
||||
// Project Menu
|
||||
//
|
||||
|
||||
void MenuCommandHandler::OnImport(const CommandContext &context)
|
||||
{
|
||||
auto &project = context.project;
|
||||
|
||||
// An import trigger for the alias missing dialog might not be intuitive, but
|
||||
// this serves to track the file if the users zooms in and such.
|
||||
wxGetApp().SetMissingAliasedFileWarningShouldShow(true);
|
||||
|
||||
wxArrayString selectedFiles = project.ShowOpenDialog(wxT(""));
|
||||
if (selectedFiles.GetCount() == 0) {
|
||||
gPrefs->Write(wxT("/LastOpenType"),wxT(""));
|
||||
gPrefs->Flush();
|
||||
return;
|
||||
}
|
||||
|
||||
// PRL: This affects FFmpegImportPlugin::Open which resets the preference
|
||||
// to false. Should it also be set to true on other paths that reach
|
||||
// AudacityProject::Import ?
|
||||
gPrefs->Write(wxT("/NewImportingSession"), true);
|
||||
|
||||
//sort selected files by OD status. Load non OD first so user can edit asap.
|
||||
//first sort selectedFiles.
|
||||
selectedFiles.Sort(CompareNoCaseFileName);
|
||||
ODManager::Pauser pauser;
|
||||
|
||||
auto cleanup = finally( [&] {
|
||||
gPrefs->Write(wxT("/LastOpenType"),wxT(""));
|
||||
|
||||
gPrefs->Flush();
|
||||
|
||||
project.HandleResize(); // Adjust scrollers for NEW track sizes.
|
||||
} );
|
||||
|
||||
for (size_t ff = 0; ff < selectedFiles.GetCount(); ff++) {
|
||||
wxString fileName = selectedFiles[ff];
|
||||
|
||||
FileNames::UpdateDefaultPath(FileNames::Operation::Open, fileName);
|
||||
|
||||
project.Import(fileName);
|
||||
}
|
||||
|
||||
project.ZoomAfterImport(nullptr);
|
||||
}
|
||||
|
||||
void MenuCommandHandler::OnImportLabels(const CommandContext &context)
|
||||
{
|
||||
auto &project = context.project;
|
||||
auto trackFactory = project.GetTrackFactory();
|
||||
auto tracks = project.GetTracks();
|
||||
|
||||
wxString fileName =
|
||||
FileNames::SelectFile(FileNames::Operation::Open,
|
||||
_("Select a text file containing labels"),
|
||||
wxEmptyString, // Path
|
||||
wxT(""), // Name
|
||||
wxT(".txt"), // Extension
|
||||
_("Text files (*.txt)|*.txt|All files|*"),
|
||||
wxRESIZE_BORDER, // Flags
|
||||
&project); // Parent
|
||||
|
||||
if (fileName != wxT("")) {
|
||||
wxTextFile f;
|
||||
|
||||
f.Open(fileName);
|
||||
if (!f.IsOpened()) {
|
||||
AudacityMessageBox(
|
||||
wxString::Format( _("Could not open file: %s"), fileName ) );
|
||||
return;
|
||||
}
|
||||
|
||||
auto newTrack = trackFactory->NewLabelTrack();
|
||||
wxString sTrackName;
|
||||
wxFileName::SplitPath(fileName, NULL, NULL, &sTrackName, NULL);
|
||||
newTrack->SetName(sTrackName);
|
||||
|
||||
newTrack->Import(f);
|
||||
|
||||
project.SelectNone();
|
||||
newTrack->SetSelected(true);
|
||||
tracks->Add(std::move(newTrack));
|
||||
|
||||
project.PushState(wxString::
|
||||
Format(_("Imported labels from '%s'"), fileName),
|
||||
_("Import Labels"));
|
||||
|
||||
project.ZoomAfterImport(nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef USE_MIDI
|
||||
void MenuCommandHandler::OnImportMIDI(const CommandContext &context)
|
||||
{
|
||||
auto &project = context.project;
|
||||
|
||||
wxString fileName = FileNames::SelectFile(FileNames::Operation::Open,
|
||||
_("Select a MIDI file"),
|
||||
wxEmptyString, // Path
|
||||
wxT(""), // Name
|
||||
wxT(""), // Extension
|
||||
_("MIDI and Allegro files (*.mid;*.midi;*.gro)|*.mid;*.midi;*.gro|MIDI files (*.mid;*.midi)|*.mid;*.midi|Allegro files (*.gro)|*.gro|All files|*"),
|
||||
wxRESIZE_BORDER, // Flags
|
||||
&project); // Parent
|
||||
|
||||
if (fileName != wxT(""))
|
||||
DoImportMIDI(&project, fileName);
|
||||
}
|
||||
|
||||
AudacityProject *MenuCommandHandler::DoImportMIDI(
|
||||
AudacityProject *pProject, const wxString &fileName)
|
||||
{
|
||||
auto tracks = pProject->GetTracks();
|
||||
|
||||
AudacityProject *pNewProject {};
|
||||
if ( !pProject )
|
||||
pProject = pNewProject = CreateNewAudacityProject();
|
||||
auto cleanup = finally( [&] { if ( pNewProject ) pNewProject->Close(true); } );
|
||||
|
||||
auto newTrack = pProject->GetTrackFactory()->NewNoteTrack();
|
||||
|
||||
if (::ImportMIDI(fileName, newTrack.get())) {
|
||||
|
||||
pProject->SelectNone();
|
||||
auto pTrack = tracks->Add(std::move(newTrack));
|
||||
pTrack->SetSelected(true);
|
||||
|
||||
pProject->PushState(wxString::Format(_("Imported MIDI from '%s'"),
|
||||
fileName), _("Import MIDI"));
|
||||
|
||||
pProject->ZoomAfterImport(pTrack);
|
||||
pNewProject = nullptr;
|
||||
|
||||
wxGetApp().AddFileToHistory(fileName);
|
||||
|
||||
return pProject;
|
||||
}
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
#endif // USE_MIDI
|
||||
|
||||
void MenuCommandHandler::OnImportRaw(const CommandContext &context)
|
||||
{
|
||||
auto &project = context.project;
|
||||
auto trackFactory = project.GetTrackFactory();
|
||||
|
||||
wxString fileName =
|
||||
FileNames::SelectFile(FileNames::Operation::Open,
|
||||
_("Select any uncompressed audio file"),
|
||||
wxEmptyString, // Path
|
||||
wxT(""), // Name
|
||||
wxT(""), // Extension
|
||||
_("All files|*"),
|
||||
wxRESIZE_BORDER, // Flags
|
||||
&project); // Parent
|
||||
|
||||
if (fileName == wxT(""))
|
||||
return;
|
||||
|
||||
TrackHolders newTracks;
|
||||
|
||||
::ImportRaw(&project, fileName, trackFactory, newTracks);
|
||||
|
||||
if (newTracks.size() <= 0)
|
||||
return;
|
||||
|
||||
project.AddImportedTracks(fileName, std::move(newTracks));
|
||||
project.HandleResize(); // Adjust scrollers for NEW track sizes.
|
||||
}
|
||||
|
||||
void MenuCommandHandler::OnEditMetadata(const CommandContext &context)
|
||||
{
|
||||
auto &project = context.project;
|
||||
|
42
src/Menus.h
42
src/Menus.h
@ -218,37 +218,11 @@ void OnMacBringAllToFront(const CommandContext &context );
|
||||
|
||||
// File Menu
|
||||
|
||||
void OnNew(const CommandContext &context );
|
||||
void OnOpen(const CommandContext &context );
|
||||
void OnProjectReset(const CommandContext &context);
|
||||
void OnClose(const CommandContext &context );
|
||||
void OnSave(const CommandContext &context );
|
||||
void OnSaveAs(const CommandContext &context );
|
||||
void OnSaveCopy(const CommandContext &context );
|
||||
#ifdef USE_LIBVORBIS
|
||||
void OnSaveCompressed(const CommandContext &context );
|
||||
#endif
|
||||
|
||||
void OnCheckDependencies(const CommandContext &context );
|
||||
|
||||
void DoExport(AudacityProject &project, const wxString & Format);
|
||||
void OnExportAudio(const CommandContext &context );
|
||||
void OnExportMp3(const CommandContext &context );
|
||||
void OnExportWav(const CommandContext &context );
|
||||
void OnExportOgg(const CommandContext &context );
|
||||
void OnExportSelection(const CommandContext &context );
|
||||
void OnExportMultiple(const CommandContext &context );
|
||||
void OnExportLabels(const CommandContext &context );
|
||||
void OnExportMIDI(const CommandContext &context );
|
||||
|
||||
void OnPreferences(const CommandContext &context );
|
||||
void OnReloadPreferences(const CommandContext &context );
|
||||
|
||||
void OnPageSetup(const CommandContext &context );
|
||||
void OnPrint(const CommandContext &context );
|
||||
|
||||
void OnExit(const CommandContext &context );
|
||||
|
||||
// Edit Menu
|
||||
|
||||
void OnUndo(const CommandContext &context );
|
||||
@ -416,16 +390,6 @@ void OnPunchAndRoll(const CommandContext &context);
|
||||
#endif
|
||||
|
||||
// Import Submenu
|
||||
void OnImport(const CommandContext &context );
|
||||
void OnImportLabels(const CommandContext &context );
|
||||
void OnImportMIDI(const CommandContext &context );
|
||||
|
||||
// return null on failure; if success, return the given project, or a NEW
|
||||
// one, if the given was null; create no NEW project if failure
|
||||
static AudacityProject *DoImportMIDI(
|
||||
AudacityProject *pProject, const wxString &fileName);
|
||||
|
||||
void OnImportRaw(const CommandContext &context );
|
||||
|
||||
void OnEditMetadata(const CommandContext &context );
|
||||
bool DoEditMetadata(AudacityProject &project,
|
||||
@ -656,6 +620,12 @@ private:
|
||||
MenuCommandHandler &GetMenuCommandHandler(AudacityProject &project);
|
||||
MenuManager &GetMenuManager(AudacityProject &project);
|
||||
|
||||
// Exported helper functions from various menu handling source files
|
||||
namespace FileActions {
|
||||
AudacityProject *DoImportMIDI(
|
||||
AudacityProject *pProject, const wxString &fileName );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -473,7 +473,7 @@ public:
|
||||
for (const auto &name : sortednames) {
|
||||
#ifdef USE_MIDI
|
||||
if (Importer::IsMidi(name))
|
||||
MenuCommandHandler::DoImportMIDI(mProject, name);
|
||||
FileActions::DoImportMIDI(mProject, name);
|
||||
else
|
||||
#endif
|
||||
mProject->Import(name);
|
||||
@ -3133,7 +3133,7 @@ void AudacityProject::OpenFile(const wxString &fileNameArg, bool addtohistory)
|
||||
{
|
||||
#ifdef USE_MIDI
|
||||
if (Importer::IsMidi(fileName))
|
||||
MenuCommandHandler::DoImportMIDI(this, fileName);
|
||||
FileActions::DoImportMIDI(this, fileName);
|
||||
else
|
||||
#endif
|
||||
Import(fileName);
|
||||
|
@ -375,7 +375,7 @@ void LOFImportFileHandle::lofOpenFiles(wxString* ln)
|
||||
// If file is a midi
|
||||
if (Importer::IsMidi(targetfile))
|
||||
{
|
||||
mProject = MenuCommandHandler::DoImportMIDI(mProject, targetfile);
|
||||
mProject = FileActions::DoImportMIDI(mProject, targetfile);
|
||||
}
|
||||
|
||||
// If not a midi, open audio file
|
||||
|
@ -0,0 +1,707 @@
|
||||
#include "../AudacityApp.h"
|
||||
#include "../BatchCommands.h"
|
||||
#include "../Experimental.h"
|
||||
#include "../FileNames.h"
|
||||
#include "../LabelTrack.h"
|
||||
#include "../NoteTrack.h"
|
||||
#include "../Prefs.h"
|
||||
#include "../Printing.h"
|
||||
#include "../Project.h"
|
||||
#include "../WaveTrack.h"
|
||||
#include "../commands/CommandContext.h"
|
||||
#include "../commands/CommandManager.h"
|
||||
#include "../export/Export.h"
|
||||
#include "../export/ExportMultiple.h"
|
||||
|
||||
#ifdef USE_MIDI
|
||||
#include "../import/ImportMIDI.h"
|
||||
#endif // USE_MIDI
|
||||
|
||||
#include "../ondemand/ODManager.h"
|
||||
|
||||
// private helper classes and functions
|
||||
namespace {
|
||||
void DoExport
|
||||
(AudacityProject &project, const wxString & Format )
|
||||
{
|
||||
auto tracks = project.GetTracks();
|
||||
|
||||
Exporter e;
|
||||
|
||||
wxGetApp().SetMissingAliasedFileWarningShouldShow(true);
|
||||
double t0 = 0.0;
|
||||
double t1 = tracks->GetEndTime();
|
||||
|
||||
// Prompt for file name and/or extension?
|
||||
bool bPromptingRequired =
|
||||
(project.mBatchMode == 0) || project.GetFileName().IsEmpty() ||
|
||||
Format.IsEmpty();
|
||||
wxString filename;
|
||||
|
||||
if (!bPromptingRequired) {
|
||||
|
||||
// We're in batch mode, and we have an mFileName and Format.
|
||||
wxString extension = ".";
|
||||
extension += Format;
|
||||
extension.MakeLower();
|
||||
|
||||
filename =
|
||||
MacroCommands::BuildCleanFileName(project.GetFileName(), extension);
|
||||
|
||||
// Bug 1854, No warning of file overwrite
|
||||
// (when export is called from Macros).
|
||||
int counter = 0;
|
||||
bPromptingRequired = wxFileExists(filename);
|
||||
|
||||
// We'll try alternative names to avoid overwriting.
|
||||
while ( bPromptingRequired && counter < 100 ) {
|
||||
counter++;
|
||||
wxString number;
|
||||
number.Printf("%03i", counter);
|
||||
// So now the name has a number in it too.
|
||||
filename = MacroCommands::BuildCleanFileName(
|
||||
project.GetFileName(), number + extension);
|
||||
bPromptingRequired = wxFileExists(filename);
|
||||
}
|
||||
// If we've run out of alternative names, we will fall back to prompting
|
||||
// - even if in a macro.
|
||||
}
|
||||
|
||||
|
||||
if (bPromptingRequired)
|
||||
{
|
||||
// Do export with prompting.
|
||||
e.SetDefaultFormat(Format);
|
||||
e.Process(&project, false, t0, t1);
|
||||
}
|
||||
else
|
||||
{
|
||||
wxGetApp().AddFileToHistory(filename);
|
||||
// We're in batch mode, the file does not exist already.
|
||||
// We really can proceed without prompting.
|
||||
int nChannels = MacroCommands::IsMono() ? 1 : 2;
|
||||
e.Process(
|
||||
&project, // AudacityProject
|
||||
nChannels, // numChannels,
|
||||
Format, // type,
|
||||
filename, // filename,
|
||||
false, // selectedOnly,
|
||||
t0, // t0
|
||||
t1 // t1
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
namespace FileActions {
|
||||
|
||||
// exported helper functions
|
||||
|
||||
#ifdef USE_MIDI
|
||||
// return null on failure; if success, return the given project, or a NEW
|
||||
// one, if the given was null; create no NEW project if failure
|
||||
AudacityProject *DoImportMIDI(
|
||||
AudacityProject *pProject, const wxString &fileName)
|
||||
{
|
||||
auto tracks = pProject->GetTracks();
|
||||
|
||||
AudacityProject *pNewProject {};
|
||||
if ( !pProject )
|
||||
pProject = pNewProject = CreateNewAudacityProject();
|
||||
auto cleanup = finally( [&]
|
||||
{ if ( pNewProject ) pNewProject->Close(true); } );
|
||||
|
||||
auto newTrack = pProject->GetTrackFactory()->NewNoteTrack();
|
||||
|
||||
if (::ImportMIDI(fileName, newTrack.get())) {
|
||||
|
||||
pProject->SelectNone();
|
||||
auto pTrack = tracks->Add(std::move(newTrack));
|
||||
pTrack->SetSelected(true);
|
||||
|
||||
pProject->PushState(wxString::Format(_("Imported MIDI from '%s'"),
|
||||
fileName), _("Import MIDI"));
|
||||
|
||||
pProject->ZoomAfterImport(pTrack);
|
||||
pNewProject = nullptr;
|
||||
|
||||
wxGetApp().AddFileToHistory(fileName);
|
||||
|
||||
return pProject;
|
||||
}
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_MIDI
|
||||
|
||||
// Menu handler functions
|
||||
|
||||
struct Handler : CommandHandlerObject {
|
||||
|
||||
void OnNew(const CommandContext &context )
|
||||
{
|
||||
CreateNewAudacityProject();
|
||||
}
|
||||
|
||||
void OnOpen(const CommandContext &context )
|
||||
{
|
||||
auto &project = context.project;
|
||||
AudacityProject::OpenFiles(&project);
|
||||
}
|
||||
|
||||
// JKC: This is like OnClose, except it emptys the project in place,
|
||||
// rather than createing a new empty project (with new toolbars etc).
|
||||
// It does not test for unsaved changes.
|
||||
// It is not in the menus by default. Its main purpose is/was for
|
||||
// developers checking functionality of ResetProjectToEmpty().
|
||||
void OnProjectReset(const CommandContext &context)
|
||||
{
|
||||
auto &project = context.project;
|
||||
project.ResetProjectToEmpty();
|
||||
}
|
||||
|
||||
void OnClose(const CommandContext &context )
|
||||
{
|
||||
auto &project = context.project;
|
||||
project.SetMenuClose(true);
|
||||
project.Close();
|
||||
}
|
||||
|
||||
void OnSave(const CommandContext &context )
|
||||
{
|
||||
auto &project = context.project;
|
||||
project.Save();
|
||||
}
|
||||
|
||||
void OnSaveAs(const CommandContext &context )
|
||||
{
|
||||
auto &project = context.project;
|
||||
project.SaveAs();
|
||||
}
|
||||
|
||||
void OnSaveCopy(const CommandContext &context )
|
||||
{
|
||||
auto &project = context.project;
|
||||
project.SaveAs(true, true);
|
||||
}
|
||||
|
||||
#ifdef USE_LIBVORBIS
|
||||
void OnSaveCompressed(const CommandContext &context)
|
||||
{
|
||||
auto &project = context.project;
|
||||
project.SaveAs(true);
|
||||
}
|
||||
#endif
|
||||
|
||||
void OnExportMp3(const CommandContext &context)
|
||||
{
|
||||
auto &project = context.project;
|
||||
DoExport(project, "MP3");
|
||||
}
|
||||
|
||||
void OnExportWav(const CommandContext &context)
|
||||
{
|
||||
auto &project = context.project;
|
||||
DoExport(project, "WAV");
|
||||
}
|
||||
|
||||
void OnExportOgg(const CommandContext &context)
|
||||
{
|
||||
auto &project = context.project;
|
||||
DoExport(project, "OGG");
|
||||
}
|
||||
|
||||
void OnExportAudio(const CommandContext &context)
|
||||
{
|
||||
auto &project = context.project;
|
||||
DoExport(project, "");
|
||||
}
|
||||
|
||||
void OnExportSelection(const CommandContext &context)
|
||||
{
|
||||
auto &project = context.project;
|
||||
auto &selectedRegion = project.GetViewInfo().selectedRegion;
|
||||
Exporter e;
|
||||
|
||||
wxGetApp().SetMissingAliasedFileWarningShouldShow(true);
|
||||
e.SetFileDialogTitle( _("Export Selected Audio") );
|
||||
e.Process(&project, true, selectedRegion.t0(),
|
||||
selectedRegion.t1());
|
||||
}
|
||||
|
||||
void OnExportLabels(const CommandContext &context)
|
||||
{
|
||||
auto &project = context.project;
|
||||
auto tracks = project.GetTracks();
|
||||
|
||||
/* i18n-hint: filename containing exported text from label tracks */
|
||||
wxString fName = _("labels.txt");
|
||||
auto trackRange = tracks->Any<const LabelTrack>();
|
||||
auto numLabelTracks = trackRange.size();
|
||||
|
||||
if (numLabelTracks == 0) {
|
||||
AudacityMessageBox(_("There are no label tracks to export."));
|
||||
return;
|
||||
}
|
||||
else
|
||||
fName = (*trackRange.rbegin())->GetName();
|
||||
|
||||
fName = FileNames::SelectFile(FileNames::Operation::Export,
|
||||
_("Export Labels As:"),
|
||||
wxEmptyString,
|
||||
fName,
|
||||
wxT("txt"),
|
||||
wxT("*.txt"),
|
||||
wxFD_SAVE | wxFD_OVERWRITE_PROMPT | wxRESIZE_BORDER,
|
||||
&project);
|
||||
|
||||
if (fName == wxT(""))
|
||||
return;
|
||||
|
||||
// Move existing files out of the way. Otherwise wxTextFile will
|
||||
// append to (rather than replace) the current file.
|
||||
|
||||
if (wxFileExists(fName)) {
|
||||
#ifdef __WXGTK__
|
||||
wxString safetyFileName = fName + wxT("~");
|
||||
#else
|
||||
wxString safetyFileName = fName + wxT(".bak");
|
||||
#endif
|
||||
|
||||
if (wxFileExists(safetyFileName))
|
||||
wxRemoveFile(safetyFileName);
|
||||
|
||||
wxRename(fName, safetyFileName);
|
||||
}
|
||||
|
||||
wxTextFile f(fName);
|
||||
f.Create();
|
||||
f.Open();
|
||||
if (!f.IsOpened()) {
|
||||
AudacityMessageBox( wxString::Format(
|
||||
_("Couldn't write to file: %s"), fName ) );
|
||||
return;
|
||||
}
|
||||
|
||||
for (auto lt : trackRange)
|
||||
lt->Export(f);
|
||||
|
||||
f.Write();
|
||||
f.Close();
|
||||
}
|
||||
|
||||
void OnExportMultiple(const CommandContext &context)
|
||||
{
|
||||
auto &project = context.project;
|
||||
ExportMultiple em(&project);
|
||||
|
||||
wxGetApp().SetMissingAliasedFileWarningShouldShow(true);
|
||||
em.ShowModal();
|
||||
}
|
||||
|
||||
#ifdef USE_MIDI
|
||||
void OnExportMIDI(const CommandContext &context)
|
||||
{
|
||||
auto &project = context.project;
|
||||
auto tracks = project.GetTracks();
|
||||
|
||||
// Make sure that there is
|
||||
// exactly one NoteTrack selected.
|
||||
const auto range = tracks->Selected< const NoteTrack >();
|
||||
const auto numNoteTracksSelected = range.size();
|
||||
|
||||
if(numNoteTracksSelected > 1) {
|
||||
AudacityMessageBox(_(
|
||||
"Please select only one Note Track at a time."));
|
||||
return;
|
||||
}
|
||||
else if(numNoteTracksSelected < 1) {
|
||||
AudacityMessageBox(_(
|
||||
"Please select a Note Track."));
|
||||
return;
|
||||
}
|
||||
|
||||
wxASSERT(numNoteTracksSelected);
|
||||
if (!numNoteTracksSelected)
|
||||
return;
|
||||
|
||||
const auto nt = *range.begin();
|
||||
|
||||
while(true) {
|
||||
|
||||
wxString fName = wxT("");
|
||||
|
||||
fName = FileNames::SelectFile(FileNames::Operation::Export,
|
||||
_("Export MIDI As:"),
|
||||
wxEmptyString,
|
||||
fName,
|
||||
wxT(".mid|.gro"),
|
||||
_("MIDI file (*.mid)|*.mid|Allegro file (*.gro)|*.gro"),
|
||||
wxFD_SAVE | wxFD_OVERWRITE_PROMPT | wxRESIZE_BORDER,
|
||||
&project);
|
||||
|
||||
if (fName == wxT(""))
|
||||
return;
|
||||
|
||||
if(!fName.Contains(wxT("."))) {
|
||||
fName = fName + wxT(".mid");
|
||||
}
|
||||
|
||||
// Move existing files out of the way. Otherwise wxTextFile will
|
||||
// append to (rather than replace) the current file.
|
||||
|
||||
if (wxFileExists(fName)) {
|
||||
#ifdef __WXGTK__
|
||||
wxString safetyFileName = fName + wxT("~");
|
||||
#else
|
||||
wxString safetyFileName = fName + wxT(".bak");
|
||||
#endif
|
||||
|
||||
if (wxFileExists(safetyFileName))
|
||||
wxRemoveFile(safetyFileName);
|
||||
|
||||
wxRename(fName, safetyFileName);
|
||||
}
|
||||
|
||||
if(fName.EndsWith(wxT(".mid")) || fName.EndsWith(wxT(".midi"))) {
|
||||
nt->ExportMIDI(fName);
|
||||
} else if(fName.EndsWith(wxT(".gro"))) {
|
||||
nt->ExportAllegro(fName);
|
||||
} else {
|
||||
wxString msg = _("You have selected a filename with an unrecognized file extension.\nDo you want to continue?");
|
||||
wxString title = _("Export MIDI");
|
||||
int id = AudacityMessageBox(msg, title, wxYES_NO);
|
||||
if (id == wxNO) {
|
||||
continue;
|
||||
} else if (id == wxYES) {
|
||||
nt->ExportMIDI(fName);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif // USE_MIDI
|
||||
|
||||
void OnImport(const CommandContext &context)
|
||||
{
|
||||
auto &project = context.project;
|
||||
|
||||
// An import trigger for the alias missing dialog might not be intuitive, but
|
||||
// this serves to track the file if the users zooms in and such.
|
||||
wxGetApp().SetMissingAliasedFileWarningShouldShow(true);
|
||||
|
||||
wxArrayString selectedFiles = project.ShowOpenDialog(wxT(""));
|
||||
if (selectedFiles.GetCount() == 0) {
|
||||
gPrefs->Write(wxT("/LastOpenType"),wxT(""));
|
||||
gPrefs->Flush();
|
||||
return;
|
||||
}
|
||||
|
||||
// PRL: This affects FFmpegImportPlugin::Open which resets the preference
|
||||
// to false. Should it also be set to true on other paths that reach
|
||||
// AudacityProject::Import ?
|
||||
gPrefs->Write(wxT("/NewImportingSession"), true);
|
||||
|
||||
//sort selected files by OD status. Load non OD first so user can edit asap.
|
||||
//first sort selectedFiles.
|
||||
selectedFiles.Sort(CompareNoCaseFileName);
|
||||
ODManager::Pauser pauser;
|
||||
|
||||
auto cleanup = finally( [&] {
|
||||
gPrefs->Write(wxT("/LastOpenType"),wxT(""));
|
||||
|
||||
gPrefs->Flush();
|
||||
|
||||
project.HandleResize(); // Adjust scrollers for NEW track sizes.
|
||||
} );
|
||||
|
||||
for (size_t ff = 0; ff < selectedFiles.GetCount(); ff++) {
|
||||
wxString fileName = selectedFiles[ff];
|
||||
|
||||
FileNames::UpdateDefaultPath(FileNames::Operation::Open, fileName);
|
||||
|
||||
project.Import(fileName);
|
||||
}
|
||||
|
||||
project.ZoomAfterImport(nullptr);
|
||||
}
|
||||
|
||||
void OnImportLabels(const CommandContext &context)
|
||||
{
|
||||
auto &project = context.project;
|
||||
auto trackFactory = project.GetTrackFactory();
|
||||
auto tracks = project.GetTracks();
|
||||
|
||||
wxString fileName =
|
||||
FileNames::SelectFile(FileNames::Operation::Open,
|
||||
_("Select a text file containing labels"),
|
||||
wxEmptyString, // Path
|
||||
wxT(""), // Name
|
||||
wxT(".txt"), // Extension
|
||||
_("Text files (*.txt)|*.txt|All files|*"),
|
||||
wxRESIZE_BORDER, // Flags
|
||||
&project); // Parent
|
||||
|
||||
if (fileName != wxT("")) {
|
||||
wxTextFile f;
|
||||
|
||||
f.Open(fileName);
|
||||
if (!f.IsOpened()) {
|
||||
AudacityMessageBox(
|
||||
wxString::Format( _("Could not open file: %s"), fileName ) );
|
||||
return;
|
||||
}
|
||||
|
||||
auto newTrack = trackFactory->NewLabelTrack();
|
||||
wxString sTrackName;
|
||||
wxFileName::SplitPath(fileName, NULL, NULL, &sTrackName, NULL);
|
||||
newTrack->SetName(sTrackName);
|
||||
|
||||
newTrack->Import(f);
|
||||
|
||||
project.SelectNone();
|
||||
newTrack->SetSelected(true);
|
||||
tracks->Add(std::move(newTrack));
|
||||
|
||||
project.PushState(wxString::
|
||||
Format(_("Imported labels from '%s'"), fileName),
|
||||
_("Import Labels"));
|
||||
|
||||
project.ZoomAfterImport(nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
void OnImportMIDI(const CommandContext &context)
|
||||
{
|
||||
auto &project = context.project;
|
||||
|
||||
wxString fileName = FileNames::SelectFile(FileNames::Operation::Open,
|
||||
_("Select a MIDI file"),
|
||||
wxEmptyString, // Path
|
||||
wxT(""), // Name
|
||||
wxT(""), // Extension
|
||||
_("MIDI and Allegro files (*.mid;*.midi;*.gro)|*.mid;*.midi;*.gro|MIDI files (*.mid;*.midi)|*.mid;*.midi|Allegro files (*.gro)|*.gro|All files|*"),
|
||||
wxRESIZE_BORDER, // Flags
|
||||
&project); // Parent
|
||||
|
||||
if (fileName != wxT(""))
|
||||
DoImportMIDI(&project, fileName);
|
||||
}
|
||||
#endif
|
||||
|
||||
void OnImportRaw(const CommandContext &context)
|
||||
{
|
||||
auto &project = context.project;
|
||||
auto trackFactory = project.GetTrackFactory();
|
||||
|
||||
wxString fileName =
|
||||
FileNames::SelectFile(FileNames::Operation::Open,
|
||||
_("Select any uncompressed audio file"),
|
||||
wxEmptyString, // Path
|
||||
wxT(""), // Name
|
||||
wxT(""), // Extension
|
||||
_("All files|*"),
|
||||
wxRESIZE_BORDER, // Flags
|
||||
&project); // Parent
|
||||
|
||||
if (fileName == wxT(""))
|
||||
return;
|
||||
|
||||
TrackHolders newTracks;
|
||||
|
||||
::ImportRaw(&project, fileName, trackFactory, newTracks);
|
||||
|
||||
if (newTracks.size() <= 0)
|
||||
return;
|
||||
|
||||
project.AddImportedTracks(fileName, std::move(newTracks));
|
||||
project.HandleResize(); // Adjust scrollers for NEW track sizes.
|
||||
}
|
||||
|
||||
void OnPageSetup(const CommandContext &context)
|
||||
{
|
||||
auto &project = context.project;
|
||||
HandlePageSetup(&project);
|
||||
}
|
||||
|
||||
void OnPrint(const CommandContext &context)
|
||||
{
|
||||
auto &project = context.project;
|
||||
auto name = project.GetName();
|
||||
auto tracks = project.GetTracks();
|
||||
HandlePrint(&project, name, tracks);
|
||||
}
|
||||
|
||||
void OnExit(const CommandContext &WXUNUSED(context) )
|
||||
{
|
||||
QuitAudacity();
|
||||
}
|
||||
|
||||
}; // struct Handler
|
||||
|
||||
} // namespace
|
||||
|
||||
static CommandHandlerObject &findCommandHandler(AudacityProject &) {
|
||||
// Handler is not stateful. Doesn't need a factory registered with
|
||||
// AudacityProject.
|
||||
static FileActions::Handler instance;
|
||||
return instance;
|
||||
};
|
||||
|
||||
// Menu definitions
|
||||
|
||||
#define FN(X) findCommandHandler, \
|
||||
static_cast<CommandFunctorPointer>(& FileActions::Handler :: X)
|
||||
#define XXO(X) _(X), wxString{X}.Contains("...")
|
||||
|
||||
MenuTable::BaseItemPtr FileMenu( AudacityProject& )
|
||||
{
|
||||
using namespace MenuTable;
|
||||
|
||||
return Menu( _("&File"),
|
||||
/*i18n-hint: "New" is an action (verb) to create a NEW project*/
|
||||
Command( wxT("New"), XXO("&New"), FN(OnNew),
|
||||
AudioIONotBusyFlag, wxT("Ctrl+N") ),
|
||||
|
||||
/*i18n-hint: (verb)*/
|
||||
Command( wxT("Open"), XXO("&Open..."), FN(OnOpen),
|
||||
AudioIONotBusyFlag, wxT("Ctrl+O") ),
|
||||
|
||||
#ifdef EXPERIMENTAL_RESET
|
||||
// Empty the current project and forget its name and path. DANGEROUS
|
||||
// It's just for developers.
|
||||
// Do not translate this menu item (no XXO).
|
||||
// It MUST not be shown to regular users.
|
||||
Command( wxT("Reset"), XXO("&Dangerous Reset..."), FN(OnProjectReset),
|
||||
AudioIONotBusyFlag ),
|
||||
#endif
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Menu(
|
||||
#ifdef __WXMAC__
|
||||
/* i18n-hint: This is the name of the menu item on Mac OS X only */
|
||||
_("Open Recent")
|
||||
#else
|
||||
/* i18n-hint: This is the name of the menu item on Windows and Linux */
|
||||
_("Recent &Files")
|
||||
#endif
|
||||
,
|
||||
Special( [](AudacityProject &, wxMenu &theMenu){
|
||||
// Recent Files and Recent Projects menus
|
||||
wxGetApp().GetRecentFiles()->UseMenu( &theMenu );
|
||||
wxGetApp().GetRecentFiles()->AddFilesToMenu( &theMenu );
|
||||
|
||||
wxWeakRef<wxMenu> recentFilesMenu{ &theMenu };
|
||||
wxTheApp->CallAfter( [=] {
|
||||
// Bug 143 workaround.
|
||||
// The bug is in wxWidgets. For a menu that has scrollers,
|
||||
// the scrollers have an ID of 0 (not wxID_NONE which is -3).
|
||||
// Therefore wxWidgets attempts to find a help string. See
|
||||
// wxFrameBase::ShowMenuHelp(int menuId)
|
||||
// It finds a bogus automatic help string of "Recent &Files"
|
||||
// from that submenu.
|
||||
// So we set the help string for command with Id 0 to empty.
|
||||
if ( recentFilesMenu )
|
||||
recentFilesMenu->GetParent()->SetHelpString( 0, "" );
|
||||
} );
|
||||
} )
|
||||
),
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Command( wxT("Close"), XXO("&Close"), FN(OnClose),
|
||||
AudioIONotBusyFlag, wxT("Ctrl+W") ),
|
||||
|
||||
Separator(),
|
||||
|
||||
Menu( _("&Save Project"),
|
||||
Command( wxT("Save"), XXO("&Save Project"), FN(OnSave),
|
||||
AudioIONotBusyFlag | UnsavedChangesFlag, wxT("Ctrl+S") ),
|
||||
Command( wxT("SaveAs"), XXO("Save Project &As..."), FN(OnSaveAs),
|
||||
AudioIONotBusyFlag ),
|
||||
// TODO: The next two items should be disabled if project is empty
|
||||
Command( wxT("SaveCopy"), XXO("Save Lossless Copy of Project..."),
|
||||
FN(OnSaveCopy), AudioIONotBusyFlag )
|
||||
#ifdef USE_LIBVORBIS
|
||||
,
|
||||
Command( wxT("SaveCompressed"),
|
||||
XXO("&Save Compressed Copy of Project..."),
|
||||
FN(OnSaveCompressed), AudioIONotBusyFlag )
|
||||
#endif
|
||||
),
|
||||
|
||||
Separator(),
|
||||
|
||||
Menu( _("&Export"),
|
||||
// Enable Export audio commands only when there are audio tracks.
|
||||
Command( wxT("ExportMp3"), XXO("Export as MP&3"), FN(OnExportMp3),
|
||||
AudioIONotBusyFlag | WaveTracksExistFlag ),
|
||||
|
||||
Command( wxT("ExportWav"), XXO("Export as &WAV"), FN(OnExportWav),
|
||||
AudioIONotBusyFlag | WaveTracksExistFlag ),
|
||||
|
||||
Command( wxT("ExportOgg"), XXO("Export as &OGG"), FN(OnExportOgg),
|
||||
AudioIONotBusyFlag | WaveTracksExistFlag ),
|
||||
|
||||
Command( wxT("Export"), XXO("&Export Audio..."), FN(OnExportAudio),
|
||||
AudioIONotBusyFlag | WaveTracksExistFlag, wxT("Ctrl+Shift+E") ),
|
||||
|
||||
// Enable Export Selection commands only when there's a selection.
|
||||
Command( wxT("ExportSel"), XXO("Expo&rt Selected Audio..."),
|
||||
FN(OnExportSelection),
|
||||
AudioIONotBusyFlag | TimeSelectedFlag | WaveTracksSelectedFlag ),
|
||||
|
||||
Command( wxT("ExportLabels"), XXO("Export &Labels..."),
|
||||
FN(OnExportLabels),
|
||||
AudioIONotBusyFlag | LabelTracksExistFlag ),
|
||||
// Enable Export audio commands only when there are audio tracks.
|
||||
Command( wxT("ExportMultiple"), XXO("Export &Multiple..."),
|
||||
FN(OnExportMultiple),
|
||||
AudioIONotBusyFlag | WaveTracksExistFlag, wxT("Ctrl+Shift+L") )
|
||||
#if defined(USE_MIDI)
|
||||
,
|
||||
Command( wxT("ExportMIDI"), XXO("Export MI&DI..."), FN(OnExportMIDI),
|
||||
AudioIONotBusyFlag | NoteTracksExistFlag )
|
||||
#endif
|
||||
),
|
||||
|
||||
Menu( _("&Import"),
|
||||
Command( wxT("ImportAudio"), XXO("&Audio..."), FN(OnImport),
|
||||
AudioIONotBusyFlag, wxT("Ctrl+Shift+I") ),
|
||||
Command( wxT("ImportLabels"), XXO("&Labels..."), FN(OnImportLabels),
|
||||
AudioIONotBusyFlag ),
|
||||
#ifdef USE_MIDI
|
||||
Command( wxT("ImportMIDI"), XXO("&MIDI..."), FN(OnImportMIDI),
|
||||
AudioIONotBusyFlag ),
|
||||
#endif // USE_MIDI
|
||||
Command( wxT("ImportRaw"), XXO("&Raw Data..."), FN(OnImportRaw),
|
||||
AudioIONotBusyFlag )
|
||||
),
|
||||
|
||||
Separator(),
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Command( wxT("PageSetup"), XXO("Pa&ge Setup..."), FN(OnPageSetup),
|
||||
AudioIONotBusyFlag | TracksExistFlag ),
|
||||
/* i18n-hint: (verb) It's item on a menu. */
|
||||
Command( wxT("Print"), XXO("&Print..."), FN(OnPrint),
|
||||
AudioIONotBusyFlag | TracksExistFlag ),
|
||||
|
||||
Separator(),
|
||||
|
||||
// On the Mac, the Exit item doesn't actually go here...wxMac will
|
||||
// pull it out
|
||||
// and put it in the Audacity menu for us based on its ID.
|
||||
/* i18n-hint: (verb) It's item on a menu. */
|
||||
Command( wxT("Exit"), XXO("E&xit"), FN(OnExit),
|
||||
AlwaysEnabledFlag, wxT("Ctrl+Q") )
|
||||
);
|
||||
}
|
||||
|
||||
#undef XXO
|
||||
#undef FN
|
Loading…
x
Reference in New Issue
Block a user