Audacity  2.2.2
Import.cpp
Go to the documentation of this file.
1 /**********************************************************************
2 
3  Audacity: A Digital Audio Editor
4 
5  Import.cpp
6 
7  Dominic Mazzoni
8 
9 *******************************************************************//***************************************************************//***************************************************************//******************************************************************/
35 
36 
37 
38 #include "../Audacity.h"
39 #include "Import.h"
40 
41 #include <algorithm>
42 #include "ImportPlugin.h"
43 
44 #include <wx/textctrl.h>
45 #include <wx/string.h>
46 #include <wx/intl.h>
47 #include <wx/log.h>
48 #include <wx/sizer.h> //for wxBoxSizer
49 #include <wx/listimpl.cpp>
50 #include "../ShuttleGui.h"
51 #include "../Project.h"
52 
53 #include "ImportPCM.h"
54 #include "ImportMP3.h"
55 #include "ImportOGG.h"
56 #include "ImportQT.h"
57 #include "ImportRaw.h"
58 #include "ImportLOF.h"
59 #include "ImportFLAC.h"
60 #include "ImportFFmpeg.h"
61 #include "ImportGStreamer.h"
62 #include "../Prefs.h"
63 
64 // ============================================================================
65 //
66 // Return reference to singleton
67 //
68 // (Thread-safe...no active threading during construction or after destruction)
69 // ============================================================================
72 {
73  return mInstance;
74 }
75 
77 {
78 }
79 
81 {
82 }
83 
85 {
89 
90  // build the list of import plugin and/or unusableImporters.
91  // order is significant. If none match, they will all be tried
92  // in the order defined here.
98 
99  #if defined(USE_FFMPEG)
101  #endif
102  #ifdef USE_QUICKTIME
104  #endif
105  #if defined(USE_GSTREAMER)
107  #endif
108 
109  ReadImportItems();
110 
111  return true;
112 }
113 
115 {
119 
120  return true;
121 }
122 
124 {
125  for(const auto &importPlugin : mImportPluginList)
126  {
127  formatList->emplace_back(importPlugin->GetPluginFormatDescription(),
128  importPlugin->GetSupportedExtensions());
129  }
130 }
131 
132 void Importer::StringToList(wxString &str, wxString &delims, wxArrayString &list, wxStringTokenizerMode mod)
133 {
134  wxStringTokenizer toker;
135 
136  for (toker.SetString(str, delims, mod);
137  toker.HasMoreTokens(); list.Add (toker.GetNextToken()));
138 }
139 
141 {
142  int item_counter = 0;
143  wxStringTokenizer toker;
144  wxString item_name;
145  wxString item_value;
146 
148  /* Rule string format is:
149  * extension1:extension2:extension3\mime_type1:mime_type2:mime_type3|filter1:filter2:filter3\unusedfilter1:unusedfilter2
150  * backslashes are escaped and unescaped internally
151  */
152  for (item_counter = 0; true; item_counter++)
153  {
154  wxString condition, filters, used_filters, unused_filters = wxEmptyString, extensions, mime_types = wxEmptyString;
155  item_name.Printf (wxT("/ExtImportItems/Item%d"), item_counter);
156  /* Break at first non-existent item */
157  if (!gPrefs->Read(item_name, &item_value))
158  break;
159 
160  toker.SetString(item_value, wxT("|"), wxTOKEN_RET_EMPTY_ALL);
161  /* Break at first broken item */
162  if (toker.CountTokens() != 2)
163  break;
164 
165  auto new_item = std::make_unique<ExtImportItem>();
166 
167  /* First token is the filtering condition, second - the filter list */
168  condition = toker.GetNextToken();
169  filters = toker.GetNextToken();
170 
171  /* Condition token consists of extension list and mime type list
172  * mime type list can be omitted entirely (complete with '\' separator)*/
173  toker.SetString(condition, wxT("\\"), wxTOKEN_RET_EMPTY_ALL);
174  extensions = toker.GetNextToken();
175  if (toker.HasMoreTokens())
176  mime_types = toker.GetNextToken();
177 
178  wxString delims(wxT(":"));
179  StringToList (extensions, delims, new_item->extensions);
180 
181  if (mime_types != wxEmptyString)
182  StringToList (mime_types, delims, new_item->mime_types);
183 
184  /* Filter token consists of used and unused filter lists */
185  toker.SetString(filters, wxT("\\"), wxTOKEN_RET_EMPTY_ALL);
186  used_filters = toker.GetNextToken();
187  if (toker.HasMoreTokens())
188  unused_filters = toker.GetNextToken();
189 
190  StringToList (used_filters, delims, new_item->filters);
191 
192  if (unused_filters != wxEmptyString)
193  {
194  /* Filters are stored in one list, but the position at which
195  * unused filters start is remembered
196  */
197  new_item->divider = new_item->filters.Count();
198  StringToList (unused_filters, delims, new_item->filters);
199  }
200  else
201  new_item->divider = -1;
202 
203  /* Find corresponding filter object for each filter ID */
204  for (size_t i = 0; i < new_item->filters.Count(); i++)
205  {
206  bool found = false;
207  for (const auto &importPlugin : mImportPluginList)
208  {
209  if (importPlugin->GetPluginStringID().Cmp(new_item->filters[i]) == 0)
210  {
211  new_item->filter_objects.push_back(importPlugin.get());
212  found = true;
213  break;
214  }
215  }
216  /* IDs that do not have corresponding filters, will be shown as-is */
217  if (!found)
218  new_item->filter_objects.push_back(nullptr);
219  }
220  /* Find all filter objects that are not present in the filter list */
221  for (const auto &importPlugin : mImportPluginList)
222  {
223  bool found = false;
224  for (size_t i = 0; i < new_item->filter_objects.size(); i++)
225  {
226  if (importPlugin.get() == new_item->filter_objects[i])
227  {
228  found = true;
229  break;
230  }
231  }
232  /* Add these filters at the bottom of used filter list */
233  if (!found)
234  {
235  int index = new_item->divider;
236  if (new_item->divider < 0)
237  index = new_item->filters.Count();
238  new_item->filters.Insert(importPlugin->GetPluginStringID(),index);
239  new_item->filter_objects.insert(
240  new_item->filter_objects.begin() + index, importPlugin.get());
241  if (new_item->divider >= 0)
242  new_item->divider++;
243  }
244  }
245  this->mExtImportItems.push_back( std::move(new_item) );
246  }
247 }
248 
250 {
251  size_t i;
252  wxString val, name;
253  for (i = 0; i < this->mExtImportItems.size(); i++)
254  {
255  ExtImportItem *item = mExtImportItems[i].get();
256  val.Clear();
257 
258  for (size_t j = 0; j < item->extensions.Count(); j++)
259  {
260  val.Append (item->extensions[j]);
261  if (j < item->extensions.Count() - 1)
262  val.Append (wxT(":"));
263  }
264  val.Append (wxT("\\"));
265  for (size_t j = 0; j < item->mime_types.Count(); j++)
266  {
267  val.Append (item->mime_types[j]);
268  if (j < item->mime_types.Count() - 1)
269  val.Append (wxT(":"));
270  }
271  val.Append (wxT("|"));
272  for (size_t j = 0; j < item->filters.Count() && ((int) j < item->divider || item->divider < 0); j++)
273  {
274  val.Append (item->filters[j]);
275  if (j < item->filters.Count() - 1 && ((int) j < item->divider - 1 || item->divider < 0))
276  val.Append (wxT(":"));
277  }
278  if (item->divider >= 0)
279  {
280  val.Append (wxT("\\"));
281  for (size_t j = item->divider; j < item->filters.Count(); j++)
282  {
283  val.Append (item->filters[j]);
284  if (j < item->filters.Count() - 1)
285  val.Append (wxT(":"));
286  }
287  }
288  name.Printf (wxT("/ExtImportItems/Item%d"), (int)i);
289  gPrefs->Write (name, val);
290  gPrefs->Flush();
291  }
292  /* If we used to have more items than we have now, DELETE the excess items.
293  We just keep deleting items and incrementing until we find there aren't any
294  more to DELETE.*/
295  i = this->mExtImportItems.size();
296  do {
297  name.Printf (wxT("/ExtImportItems/Item%d"), (int)i);
298  // No item to DELETE? Then it's time to finish.
299  if (!gPrefs->Read(name, &val))
300  break;
301  // Failure to DELETE probably means a read-only config file.
302  // no point continuing.
303  // TODO: Possibly report (once).
304  if( !gPrefs->DeleteEntry (name, false))
305  break;
306  i++;
307  } while( true );
308 }
309 
310 std::unique_ptr<ExtImportItem> Importer::CreateDefaultImportItem()
311 {
312  auto new_item = std::make_unique<ExtImportItem>();
313  new_item->extensions.Add(wxT("*"));
314  new_item->mime_types.Add(wxT("*"));
315 
316  for (const auto &importPlugin : mImportPluginList)
317  {
318  new_item->filters.Add (importPlugin->GetPluginStringID());
319  new_item->filter_objects.push_back(importPlugin.get());
320  }
321  new_item->divider = -1;
322  return new_item;
323 }
324 
325 bool Importer::IsMidi(const wxString &fName)
326 {
327  const auto extension = fName.AfterLast(wxT('.'));
328  return
329  extension.IsSameAs(wxT("gro"), false) ||
330  extension.IsSameAs(wxT("midi"), false) ||
331  extension.IsSameAs(wxT("mid"), false);
332 }
333 
334 // returns number of tracks imported
335 bool Importer::Import(const wxString &fName,
336  TrackFactory *trackFactory,
337  TrackHolders &tracks,
338  Tags *tags,
339  wxString &errorMessage)
340 {
342  auto cleanup = valueRestorer( pProj->mbBusyImporting, true );
343 
344  wxString extension = fName.AfterLast(wxT('.'));
345 
346  // Always refuse to import MIDI, even though the FFmpeg plugin pretends to know how (but makes very bad renderings)
347 #ifdef USE_MIDI
348  // MIDI files must be imported, not opened
349  if (IsMidi(fName)) {
350  errorMessage.Printf(_("\"%s\" \nis a MIDI file, not an audio file. \nAudacity cannot open this type of file for playing, but you can\nedit it by clicking File > Import > MIDI."), fName);
351  return false;
352  }
353 #endif
354 
355  using ImportPluginPtrs = std::vector< ImportPlugin* >;
356 
357  // This list is used to call plugins in correct order
358  ImportPluginPtrs importPlugins;
359 
360  // This list is used to remember plugins that should have been compatible with the file.
361  ImportPluginPtrs compatiblePlugins;
362 
363  // If user explicitly selected a filter,
364  // then we should try importing via corresponding plugin first
365  wxString type = gPrefs->Read(wxT("/LastOpenType"),wxT(""));
366 
367  // Not implemented (yet?)
368  wxString mime_type = wxT("*");
369 
370  // First, add user-selected filter
371  bool usersSelectionOverrides;
372  gPrefs->Read(wxT("/ExtendedImport/OverrideExtendedImportByOpenFileDialogChoice"), &usersSelectionOverrides, false);
373 
374  wxLogDebug(wxT("LastOpenType is %s"),type);
375  wxLogDebug(wxT("OverrideExtendedImportByOpenFileDialogChoice is %i"),usersSelectionOverrides);
376 
377  if (usersSelectionOverrides)
378  {
379  for (const auto &plugin : mImportPluginList)
380  {
381  if (plugin->GetPluginFormatDescription().CompareTo(type) == 0)
382  {
383  // This plugin corresponds to user-selected filter, try it first.
384  wxLogDebug(wxT("Inserting %s"),plugin->GetPluginStringID());
385  importPlugins.insert(importPlugins.begin(), plugin.get());
386  }
387  }
388  }
389 
390  wxLogMessage(wxT("File name is %s"), fName);
391  wxLogMessage(wxT("Mime type is %s"), mime_type.Lower());
392 
393  for (const auto &uItem : mExtImportItems)
394  {
395  ExtImportItem *item = uItem.get();
396  bool matches_ext = false, matches_mime = false;
397  wxLogDebug(wxT("Testing extensions"));
398  for (size_t j = 0; j < item->extensions.Count(); j++)
399  {
400  wxLogDebug(wxT("%s"), item->extensions[j].Lower());
401  if (wxMatchWild (item->extensions[j].Lower(),fName.Lower(), false))
402  {
403  wxLogDebug(wxT("Match!"));
404  matches_ext = true;
405  break;
406  }
407  }
408  if (item->extensions.Count() == 0)
409  {
410  wxLogDebug(wxT("Match! (empty list)"));
411  matches_ext = true;
412  }
413  if (matches_ext)
414  wxLogDebug(wxT("Testing mime types"));
415  else
416  wxLogDebug(wxT("Not testing mime types"));
417  for (size_t j = 0; matches_ext && j < item->mime_types.Count(); j++)
418  {
419  if (wxMatchWild (item->mime_types[j].Lower(),mime_type.Lower(), false))
420  {
421  wxLogDebug(wxT("Match!"));
422  matches_mime = true;
423  break;
424  }
425  }
426  if (item->mime_types.Count() == 0)
427  {
428  wxLogDebug(wxT("Match! (empty list)"));
429  matches_mime = true;
430  }
431  if (matches_ext && matches_mime)
432  {
433  wxLogDebug(wxT("Complete match!"));
434  for (size_t j = 0; j < item->filter_objects.size() && (item->divider < 0 || (int) j < item->divider); j++)
435  {
436  // the filter_object can be NULL if a suitable importer was not found
437  // this happens when we recompile with --without-ffmpeg and there
438  // is still ffmpeg in prefs from previous --with-ffmpeg builds
439  if (!(item->filter_objects[j]))
440  continue;
441  wxLogDebug(wxT("Inserting %s"),item->filter_objects[j]->GetPluginStringID());
442  importPlugins.push_back(item->filter_objects[j]);
443  }
444  }
445  }
446 
447  // Add all plugins that support the extension
448 
449  // Here we rely on the fact that the first plugin in mImportPluginList is libsndfile.
450  // We want to save this for later insertion ahead of libmad, if libmad supports the extension.
451  // The order of plugins in mImportPluginList is determined by the Importer constructor alone and
452  // is not changed by user selection overrides or any other mechanism, but we include an assert
453  // in case subsequent code revisions to the constructor should break this assumption that
454  // libsndfile is first.
455  ImportPlugin *libsndfilePlugin = mImportPluginList.begin()->get();
456  wxASSERT(libsndfilePlugin->GetPluginStringID().IsSameAs(wxT("libsndfile")));
457 
458  for (const auto &plugin : mImportPluginList)
459  {
460  // Make sure its not already in the list
461  if (importPlugins.end() ==
462  std::find(importPlugins.begin(), importPlugins.end(), plugin.get()))
463  {
464  if (plugin->SupportsExtension(extension))
465  {
466  // If libmad is accidentally fed a wav file which has been incorrectly
467  // given an .mp3 extension then it can choke on the contents and crash.
468  // To avoid this, put libsndfile ahead of libmad in the lists created for
469  // mp3 files, or for any of the extensions supported by libmad.
470  // A genuine .mp3 file will first fail an attempted import with libsndfile
471  // but then get processed as desired by libmad.
472  // But a wav file which bears an incorrect .mp3 extension will be successfully
473  // processed by libsndfile and thus avoid being submitted to libmad.
474  if (plugin->GetPluginStringID().IsSameAs(wxT("libmad")))
475  {
476  // Make sure libsndfile is not already in the list
477  if (importPlugins.end() ==
478  std::find(importPlugins.begin(), importPlugins.end(), libsndfilePlugin))
479  {
480  wxLogDebug(wxT("Appending %s"),libsndfilePlugin->GetPluginStringID());
481  importPlugins.push_back(libsndfilePlugin);
482  }
483  }
484  wxLogDebug(wxT("Appending %s"),plugin->GetPluginStringID());
485  importPlugins.push_back(plugin.get());
486  }
487  }
488  }
489 
490  // Add remaining plugins, except for libmad, which should not be used as a fallback for anything.
491  // Otherwise, if FFmpeg (libav) has not been installed, libmad will still be there near the
492  // end of the preference list importPlugins, where it will claim success importing FFmpeg file
493  // formats unsuitable for it, and produce distorted results.
494  for (const auto &plugin : mImportPluginList)
495  {
496  if (!(plugin->GetPluginStringID().IsSameAs(wxT("libmad"))))
497  {
498  // Make sure its not already in the list
499  if (importPlugins.end() ==
500  std::find(importPlugins.begin(), importPlugins.end(), plugin.get()))
501  {
502  wxLogDebug(wxT("Appending %s"),plugin->GetPluginStringID());
503  importPlugins.push_back(plugin.get());
504  }
505  }
506  }
507 
508  // Try the import plugins, in the permuted sequences just determined
509  for (const auto plugin : importPlugins)
510  {
511  // Try to open the file with this plugin (probe it)
512  wxLogMessage(wxT("Opening with %s"),plugin->GetPluginStringID());
513  auto inFile = plugin->Open(fName);
514  if ( (inFile != NULL) && (inFile->GetStreamCount() > 0) )
515  {
516  wxLogMessage(wxT("Open(%s) succeeded"), fName);
517  // File has more than one stream - display stream selector
518  if (inFile->GetStreamCount() > 1)
519  {
520  ImportStreamDialog ImportDlg(inFile.get(), NULL, -1, _("Select stream(s) to import"));
521 
522  if (ImportDlg.ShowModal() == wxID_CANCEL)
523  {
524  return false;
525  }
526  }
527  // One stream - import it by default
528  else
529  inFile->SetStreamUsage(0,TRUE);
530 
531  auto res = inFile->Import(trackFactory, tracks, tags);
532 
534  {
535  // LOF ("list-of-files") has different semantics
536  if (extension.IsSameAs(wxT("lof"), false))
537  {
538  return true;
539  }
540 
541  if (tracks.size() > 0)
542  {
543  // success!
544  return true;
545  }
546  }
547 
549  {
550  return false;
551  }
552 
553  // We could exit here since we had a match on the file extension,
554  // but there may be another plug-in that can import the file and
555  // that may recognize the extension, so we allow the loop to
556  // continue.
557  }
558  }
559  wxLogError(wxT("Importer::Import: Opening failed."));
560 
561  // None of our plugins can handle this file. It might be that
562  // Audacity supports this format, but support was not compiled in.
563  // If so, notify the user of this fact
564  for (const auto &unusableImportPlugin : mUnusableImportPluginList)
565  {
566  if( unusableImportPlugin->SupportsExtension(extension) )
567  {
568  errorMessage.Printf(_("This version of Audacity was not compiled with %s support."),
569  unusableImportPlugin->
570  GetPluginFormatDescription());
571  return false;
572  }
573  }
574 
575  /* warnings for unsupported data types */
576 
577  if (compatiblePlugins.empty())
578  {
579  // if someone has sent us a .cda file, send them away
580  if (extension.IsSameAs(wxT("cda"), false)) {
581  /* i18n-hint: %s will be the filename */
582  errorMessage.Printf(_("\"%s\" is an audio CD track. \nAudacity cannot open audio CDs directly. \nExtract (rip) the CD tracks to an audio format that \nAudacity can import, such as WAV or AIFF."), fName);
583  return false;
584  }
585 
586  // playlist type files
587  if ((extension.IsSameAs(wxT("m3u"), false))||(extension.IsSameAs(wxT("ram"), false))||(extension.IsSameAs(wxT("pls"), false))) {
588  errorMessage.Printf(_("\"%s\" is a playlist file. \nAudacity cannot open this file because it only contains links to other files. \nYou may be able to open it in a text editor and download the actual audio files."), fName);
589  return false;
590  }
591  //WMA files of various forms
592  if ((extension.IsSameAs(wxT("wma"), false))||(extension.IsSameAs(wxT("asf"), false))) {
593  errorMessage.Printf(_("\"%s\" is a Windows Media Audio file. \nAudacity cannot open this type of file due to patent restrictions. \nYou need to convert it to a supported audio format, such as WAV or AIFF."), fName);
594  return false;
595  }
596  //AAC files of various forms (probably not encrypted)
597  if ((extension.IsSameAs(wxT("aac"), false))||(extension.IsSameAs(wxT("m4a"), false))||(extension.IsSameAs(wxT("m4r"), false))||(extension.IsSameAs(wxT("mp4"), false))) {
598  errorMessage.Printf(_("\"%s\" is an Advanced Audio Coding file. \nAudacity cannot open this type of file. \nYou need to convert it to a supported audio format, such as WAV or AIFF."), fName);
599  return false;
600  }
601  // encrypted itunes files
602  if ((extension.IsSameAs(wxT("m4p"), false))) {
603  errorMessage.Printf(_("\"%s\" is an encrypted audio file. \nThese typically are from an online music store. \nAudacity cannot open this type of file due to the encryption. \nTry recording the file into Audacity, or burn it to audio CD then \nextract the CD track to a supported audio format such as WAV or AIFF."), fName);
604  return false;
605  }
606  // Real Inc. files of various sorts
607  if ((extension.IsSameAs(wxT("ra"), false))||(extension.IsSameAs(wxT("rm"), false))||(extension.IsSameAs(wxT("rpm"), false))) {
608  errorMessage.Printf(_("\"%s\" is a RealPlayer media file. \nAudacity cannot open this proprietary format. \nYou need to convert it to a supported audio format, such as WAV or AIFF."), fName);
609  return false;
610  }
611 
612  // Other notes-based formats
613  if ((extension.IsSameAs(wxT("kar"), false))||(extension.IsSameAs(wxT("mod"), false))||(extension.IsSameAs(wxT("rmi"), false))) {
614  errorMessage.Printf(_("\"%s\" is a notes-based file, not an audio file. \nAudacity cannot open this type of file. \nTry converting it to an audio file such as WAV or AIFF and \nthen import it, or record it into Audacity."), fName);
615  return false;
616  }
617 
618  // MusePack files
619  if ((extension.IsSameAs(wxT("mp+"), false))||(extension.IsSameAs(wxT("mpc"), false))||(extension.IsSameAs(wxT("mpp"), false))) {
620  errorMessage.Printf(_("\"%s\" is a Musepack audio file. \nAudacity cannot open this type of file. \nIf you think it might be an mp3 file, rename it to end with \".mp3\" \nand try importing it again. Otherwise you need to convert it to a supported audio \nformat, such as WAV or AIFF."), fName);
621  return false;
622  }
623 
624  // WavPack files
625  if ((extension.IsSameAs(wxT("wv"), false))||(extension.IsSameAs(wxT("wvc"), false))) {
626  errorMessage.Printf(_("\"%s\" is a Wavpack audio file. \nAudacity cannot open this type of file. \nYou need to convert it to a supported audio format, such as WAV or AIFF."), fName);
627  return false;
628  }
629 
630  // AC3 files
631  if ((extension.IsSameAs(wxT("ac3"), false))) {
632  errorMessage.Printf(_("\"%s\" is a Dolby Digital audio file. \nAudacity cannot currently open this type of file. \nYou need to convert it to a supported audio format, such as WAV or AIFF."), fName);
633  return false;
634  }
635 
636  // Speex files
637  if ((extension.IsSameAs(wxT("spx"), false))) {
638  errorMessage.Printf(_("\"%s\" is an Ogg Speex audio file. \nAudacity cannot currently open this type of file. \nYou need to convert it to a supported audio format, such as WAV or AIFF."), fName);
639  return false;
640  }
641 
642  // Video files of various forms
643  if ((extension.IsSameAs(wxT("mpg"), false))||(extension.IsSameAs(wxT("mpeg"), false))||(extension.IsSameAs(wxT("avi"), false))||(extension.IsSameAs(wxT("wmv"), false))||(extension.IsSameAs(wxT("rv"), false))) {
644  errorMessage.Printf(_("\"%s\" is a video file. \nAudacity cannot currently open this type of file. \nYou need to extract the audio to a supported format, such as WAV or AIFF."), fName);
645  return false;
646  }
647 
648  // Audacity project
649  if (extension.IsSameAs(wxT("aup"), false)) {
650  errorMessage.Printf(_("\"%s\" is an Audacity Project file. \nUse the 'File > Open' command to open Audacity Projects."), fName);
651  return false;
652  }
653 
654  // we were not able to recognize the file type
655  errorMessage.Printf(_("Audacity did not recognize the type of the file '%s'.\nTry installing FFmpeg. For uncompressed files, also try File > Import > Raw Data."),fName);
656  }
657  else
658  {
659  // We DO have a plugin for this file, but import failed.
660  wxString pluglist;
661 
662  for (const auto &plugin : compatiblePlugins)
663  {
664  if (pluglist.empty())
665  pluglist = plugin->GetPluginFormatDescription();
666  else
667  pluglist = wxString::Format( _("%s, %s"),
668  pluglist, plugin->GetPluginFormatDescription() );
669  }
670 
671  errorMessage.Printf(_("Audacity recognized the type of the file '%s'.\nImporters supposedly supporting such files are:\n%s,\nbut none of them understood this file format."),fName, pluglist);
672  }
673 
674  return false;
675 }
676 
677 //-------------------------------------------------------------------------
678 // ImportStreamDialog
679 //-------------------------------------------------------------------------
680 
681 BEGIN_EVENT_TABLE( ImportStreamDialog, wxDialogWrapper )
682  EVT_BUTTON( wxID_OK, ImportStreamDialog::OnOk )
683  EVT_BUTTON( wxID_CANCEL, ImportStreamDialog::OnCancel )
685 
686 ImportStreamDialog::ImportStreamDialog( ImportFileHandle *_mFile, wxWindow *parent, wxWindowID id, const wxString &title,
687  const wxPoint &position, const wxSize& size, long style ):
688 wxDialogWrapper( parent, id, title, position, size, style | wxRESIZE_BORDER )
689 {
690  SetName(GetTitle());
691 
692  mFile = _mFile;
693  scount = mFile->GetStreamCount();
694  for (wxInt32 i = 0; i < scount; i++)
695  mFile->SetStreamUsage(i, FALSE);
696 
697  wxBoxSizer *vertSizer;
698  {
699  auto uVertSizer = std::make_unique<wxBoxSizer>(wxVERTICAL);
700  vertSizer = uVertSizer.get();
701 
702  auto choices = mFile->GetStreamInfo();
703  StreamList = safenew wxListBox(this, -1, wxDefaultPosition, wxDefaultSize, choices, wxLB_EXTENDED | wxLB_ALWAYS_SB);
704 
705  vertSizer->Add(StreamList, 1, wxEXPAND | wxALIGN_LEFT | wxALL, 5);
706 
707  vertSizer->Add(CreateStdButtonSizer(this, eCancelButton | eOkButton).release(), 0, wxEXPAND);
708 
709  SetAutoLayout(true);
710 
711  SetSizer(uVertSizer.release());
712  }
713 
714  vertSizer->Fit( this );
715 
716  SetSize( 400, 200 );
717 }
718 
720 {
721 
722 }
723 
724 void ImportStreamDialog::OnOk(wxCommandEvent & WXUNUSED(event))
725 {
726  wxArrayInt selitems;
727  int sels = StreamList->GetSelections(selitems);
728  for (wxInt32 i = 0; i < sels; i++)
729  mFile->SetStreamUsage(selitems[i],TRUE);
730  EndModal( wxID_OK );
731 }
732 
733 void ImportStreamDialog::OnCancel(wxCommandEvent & WXUNUSED(event))
734 {
735  EndModal( wxID_CANCEL );
736 }
737 
void OnCancel(wxCommandEvent &event)
Definition: Import.cpp:733
std::unique_ptr< wxSizer > CreateStdButtonSizer(wxWindow *parent, long buttons, wxWindow *extra)
AudacityPrefs * gPrefs
Definition: Prefs.cpp:73
Class which actulaly imports the auido, using functions defined in ImportPCM.cpp, ImportMP3...
Definition: Import.h:88
An ImportFileHandle for data.
Definition: ImportPlugin.h:119
static Importer mInstance
Definition: Import.h:149
void GetFLACImportPlugin(ImportPluginList &importPluginList, UnusableImportPluginList &unusableImportPluginList)
Definition: ImportFLAC.cpp:61
wxArrayString filters
Definition: Import.h:59
virtual void SetStreamUsage(wxInt32 StreamID, bool Use)=0
ExtImportItems mExtImportItems
Definition: Import.h:151
void GetFFmpegImportPlugin(ImportPluginList &importPluginList, UnusableImportPluginList &unusableImportPluginList)
static bool IsMidi(const wxString &fName)
Definition: Import.cpp:325
Importer()
Definition: Import.cpp:76
bool Initialize()
Definition: Import.cpp:84
void StringToList(wxString &str, wxString &delims, wxArrayString &list, wxStringTokenizerMode mod=wxTOKEN_RET_EMPTY_ALL)
Definition: Import.cpp:132
bool Import(const wxString &fName, TrackFactory *trackFactory, TrackHolders &tracks, Tags *tags, wxString &errorMessage)
Definition: Import.cpp:335
void GetGStreamerImportPlugin(ImportPluginList &importPluginList, UnusableImportPluginList &unusableImportPluginList)
#define safenew
Definition: Audacity.h:230
Used to create a WaveTrack, or a LabelTrack.. Implementation of the functions of this class are dispe...
Definition: Track.h:863
void GetSupportedImportFormats(FormatList *formatList)
Definition: Import.cpp:123
bool mbBusyImporting
Definition: Project.h:708
AudacityProject provides the main window, with tools and tracks contained within it.
Definition: Project.h:176
void ReadImportItems()
Definition: Import.cpp:140
void OnOk(wxCommandEvent &event)
Definition: Import.cpp:724
void GetQTImportPlugin(ImportPluginList &importPluginList, UnusableImportPluginList &unusableImportPluginList)
Definition: ImportQT.cpp:40
ImportPluginList mImportPluginList
Definition: Import.h:152
void WriteImportItems()
Definition: Import.cpp:249
virtual ~ImportStreamDialog()
Definition: Import.cpp:719
void GetPCMImportPlugin(ImportPluginList &importPluginList, UnusableImportPluginList &WXUNUSED(unusableImportPluginList))
Definition: ImportPCM.cpp:117
~Importer()
Definition: Import.cpp:80
wxArrayString mime_types
Definition: Import.h:85
The interface that all file import "plugins" (if you want to call them that) must implement...
std::vector< std::unique_ptr< ExtImportItem > > ExtImportItems
Definition: Import.h:47
void GetLOFImportPlugin(ImportPluginList &importPluginList, UnusableImportPluginList &WXUNUSED(unusableImportPluginList))
Definition: ImportLOF.cpp:171
EVT_BUTTON(wxID_NO, DependencyDialog::OnNo) EVT_BUTTON(wxID_YES
ID3 Tags (for MP3)
Definition: Tags.h:70
Base class for FlacImportPlugin, LOFImportPlugin, MP3ImportPlugin, OggImportPlugin and PCMImportPlugi...
Definition: ImportPlugin.h:73
UnusableImportPluginList mUnusableImportPluginList
Definition: Import.h:153
_("Move Track &Down")+wxT("\t")+(GetActiveProject() -> GetCommandManager() ->GetKeyFromName(wxT("TrackMoveDown")).Raw()), OnMoveTrack) POPUP_MENU_ITEM(OnMoveTopID, _("Move Track to &Top")+wxT("\t")+(GetActiveProject() ->GetCommandManager() ->GetKeyFromName(wxT("TrackMoveTop")).Raw()), OnMoveTrack) POPUP_MENU_ITEM(OnMoveBottomID, _("Move Track to &Bottom")+wxT("\t")+(GetActiveProject() ->GetCommandManager() ->GetKeyFromName(wxT("TrackMoveBottom")).Raw()), OnMoveTrack)#define SET_TRACK_NAME_PLUGIN_SYMBOLclass SetTrackNameCommand:public AudacityCommand
void GetOGGImportPlugin(ImportPluginList &importPluginList, UnusableImportPluginList &unusableImportPluginList)
Definition: ImportOGG.cpp:59
ValueRestorer< T > valueRestorer(T &var)
Definition: MemoryX.h:494
void GetMP3ImportPlugin(ImportPluginList &importPluginList, UnusableImportPluginList &unusableImportPluginList)
Definition: ImportMP3.cpp:61
const wxChar * name
Definition: Distortion.cpp:94
AUDACITY_DLL_API AudacityProject * GetActiveProject()
Definition: Project.cpp:308
wxListBox * StreamList
Definition: Import.h:174
An UnusableImportPlugin list.
An ImportPlugin list.
wxArrayString extensions
Definition: Import.h:79
std::vector< ImportPlugin * > filter_objects
Definition: Import.h:73
END_EVENT_TABLE()
virtual wxString GetPluginStringID()=0
static Importer & Get()
Definition: Import.cpp:71
std::vector< std::unique_ptr< WaveTrack >> TrackHolders
Definition: ImportRaw.h:24
int divider
Definition: Import.h:68
std::unique_ptr< ExtImportItem > CreateDefaultImportItem()
Definition: Import.cpp:310
ImportFileHandle * mFile
Definition: Import.h:172
std::vector< Format > FormatList
Definition: Import.h:46
bool Terminate()
Definition: Import.cpp:114