Audacity 3.2.0
ExportMIDI.cpp
Go to the documentation of this file.
1/**********************************************************************
2
3 Audacity: A Digital Audio Editor
4
5 @file ExportMIDI.cpp
6
7 Paul Licameli split from FileMenus.cpp
8
9**********************************************************************/
10
11#include <wx/frame.h>
12
13#if defined(USE_MIDI)
14
15
16//#include "strparse.h"
17//#include "mfmidi.h"
18
19#include "FileNames.h"
20#include "NoteTrack.h"
21#include "Project.h"
22#include "ProjectWindows.h"
23#include "SelectFile.h"
24#include "AudacityMessageBox.h"
26
27#include "ShuttleGui.h"
29
30namespace {
32{
33 S.StartStatic(XO("Exported Allegro (.gro) files save time as:"));
34 {
35#if defined(__WXMAC__)
36 // Bug 2692: Place button group in panel so tabbing will work and,
37 // on the Mac, VoiceOver will announce as radio buttons.
38 S.StartPanel();
39#endif
40 {
41 S.StartRadioButtonGroup(NoteTrack::AllegroStyleSetting);
42 {
43 S.TieRadioButton();
44 S.TieRadioButton();
45 }
46 S.EndRadioButtonGroup();
47 }
48#if defined(__WXMAC__)
49 S.EndPanel();
50#endif
51 }
52 S.EndStatic();
53}
54
56 wxT("AllegroTimeOption"), AddControls };
57}
58
59// Insert a menu item
60#include "CommandContext.h"
61#include "MenuRegistry.h"
62#include "CommonCommandFlags.h"
63
64namespace {
67 [](const AudacityProject &project){
68 return !TrackList::Get(project).Any<const NoteTrack>().empty();
69 }
70 }; return flag; } //gsw
71
72using namespace MenuRegistry;
73
74void OnExportMIDI(const CommandContext &context)
75{
76 auto &project = context.project;
77 auto &tracks = TrackList::Get( project );
78 auto &window = GetProjectFrame( project );
79
80 // Make sure that there is
81 // exactly one NoteTrack selected.
82 const auto range = tracks.Selected<const NoteTrack>();
83 const auto numNoteTracksSelected = range.size();
84
85 if(numNoteTracksSelected > 1) {
87 XO("Please select only one Note Track at a time.") );
88 return;
89 }
90 else if(numNoteTracksSelected < 1) {
92 XO("Please select a Note Track.") );
93 return;
94 }
95
96 wxASSERT(numNoteTracksSelected);
97 if (!numNoteTracksSelected)
98 return;
99
100 const auto nt = *range.begin();
101
102 while(true) {
103
104 wxString fName;
105
106 fName = SelectFile(FileNames::Operation::Export,
107 XO("Export MIDI As:"),
108 wxEmptyString,
109 fName,
110 wxT("mid"),
111 {
112 { XO("MIDI file"), { wxT("mid") }, true },
113 { XO("Allegro file"), { wxT("gro") }, true },
114 },
115 wxFD_SAVE | wxFD_OVERWRITE_PROMPT | wxRESIZE_BORDER,
116 &window);
117
118 if (fName.empty())
119 return;
120
121 if(!fName.Contains(wxT("."))) {
122 fName = fName + wxT(".mid");
123 }
124
125 // Move existing files out of the way. Otherwise wxTextFile will
126 // append to (rather than replace) the current file.
127
128 if (wxFileExists(fName)) {
129#ifdef __WXGTK__
130 wxString safetyFileName = fName + wxT("~");
131#else
132 wxString safetyFileName = fName + wxT(".bak");
133#endif
134
135 if (wxFileExists(safetyFileName))
136 wxRemoveFile(safetyFileName);
137
138 wxRename(fName, safetyFileName);
139 }
140
141 if(fName.EndsWith(wxT(".mid")) || fName.EndsWith(wxT(".midi"))) {
142 nt->ExportMIDI(fName);
143 } else if(fName.EndsWith(wxT(".gro"))) {
144 nt->ExportAllegro(fName);
145 } else {
146 auto msg = XO(
147"You have selected a filename with an unrecognized file extension.\nDo you want to continue?");
148 auto title = XO("Export MIDI");
149 int id = AudacityMessageBox( msg, title, wxYES_NO );
150 if (id == wxNO) {
151 continue;
152 } else if (id == wxYES) {
153 nt->ExportMIDI(fName);
154 }
155 }
156 break;
157 }
158}
159
161 Command( wxT("ExportMIDI"), XXO("Export MI&DI..."), OnExportMIDI,
163 { wxT("File/Import-Export/ExportOther"),
164 { OrderingHint::After, {"ExportLabels"} } }
165};
166
167}
168
169#endif
wxT("CloseDown"))
int AudacityMessageBox(const TranslatableString &message, const TranslatableString &caption, long style, wxWindow *parent, int x, int y)
const ReservedCommandFlag & AudioIONotBusyFlag()
XO("Cut/Copy/Paste")
XXO("&Cut/Copy/Paste Toolbar")
static const auto title
AUDACITY_DLL_API wxFrame & GetProjectFrame(AudacityProject &project)
Get the top-level window associated with the project (as a wxFrame only, when you do not need to use ...
accessors for certain important windows associated with each project
FilePath SelectFile(FileNames::Operation op, const TranslatableString &message, const FilePath &default_path, const FilePath &default_filename, const FileExtension &default_extension, const FileTypes &fileTypes, int flags, wxWindow *parent)
Definition: SelectFile.cpp:17
const auto tracks
const auto project
#define S(N)
Definition: ToChars.cpp:64
static std::once_flag flag
The top-level handle to an Audacity project. It serves as a source of events that other objects can b...
Definition: Project.h:90
size_t size() const
How many attachment pointers are in the Site.
Definition: ClientData.h:260
CommandContext provides additional information to an 'Apply()' command. It provides the project,...
AudacityProject & project
A Track that is used for Midi notes. (Somewhat old code).
Definition: NoteTrack.h:78
static EnumSetting< bool > AllegroStyleSetting
Definition: NoteTrack.h:81
Generates classes whose instances register items at construction.
Definition: Registry.h:388
Derived from ShuttleGuiBase, an Audacity specific class for shuttling data to and from GUI.
Definition: ShuttleGui.h:640
auto Any() -> TrackIterRange< TrackType >
Definition: Track.h:950
static TrackList & Get(AudacityProject &project)
Definition: Track.cpp:314
constexpr auto Command
Definition: MenuRegistry.h:456
ImportExportPrefs::RegisteredControls reg
Definition: ExportMIDI.cpp:55
void OnExportMIDI(const CommandContext &context)
Definition: ExportMIDI.cpp:74
const ReservedCommandFlag & NoteTracksExistFlag()
Definition: ExportMIDI.cpp:66