Audacity  2.3.1
Public Member Functions | Static Public Member Functions | Private Attributes | Static Private Attributes | List of all members
Importer Class Reference

Class which actulaly imports the auido, using functions defined in ImportPCM.cpp, ImportMP3.cpp, ImportOGG.cpp, ImportRawData.cpp, and ImportLOF.cpp. More...

#include <Import.h>

Public Member Functions

 Importer ()
 
 ~Importer ()
 
bool Initialize ()
 
bool Terminate ()
 
void GetSupportedImportFormats (FormatList *formatList)
 
void ReadImportItems ()
 
void WriteImportItems ()
 
void StringToList (wxString &str, wxString &delims, wxArrayString &list, wxStringTokenizerMode mod=wxTOKEN_RET_EMPTY_ALL)
 
ExtImportItemsGetImportItems ()
 
std::unique_ptr< ExtImportItemCreateDefaultImportItem ()
 
bool Import (const wxString &fName, TrackFactory *trackFactory, TrackHolders &tracks, Tags *tags, wxString &errorMessage)
 

Static Public Member Functions

static ImporterGet ()
 
static bool IsMidi (const wxString &fName)
 

Private Attributes

ExtImportItems mExtImportItems
 
ImportPluginList mImportPluginList
 
UnusableImportPluginList mUnusableImportPluginList
 

Static Private Attributes

static Importer mInstance
 

Detailed Description

Class which actulaly imports the auido, using functions defined in ImportPCM.cpp, ImportMP3.cpp, ImportOGG.cpp, ImportRawData.cpp, and ImportLOF.cpp.

Definition at line 88 of file Import.h.

Constructor & Destructor Documentation

Importer::Importer ( )

Definition at line 77 of file Import.cpp.

78 {
79 }
Importer::~Importer ( )

Definition at line 81 of file Import.cpp.

82 {
83 }

Member Function Documentation

std::unique_ptr< ExtImportItem > Importer::CreateDefaultImportItem ( )

Allocates NEW ExtImportItem, fills it with default data and returns a pointer to it.

Definition at line 311 of file Import.cpp.

References mImportPluginList.

Referenced by ExtImportPrefs::OnAddRule().

312 {
313  auto new_item = std::make_unique<ExtImportItem>();
314  new_item->extensions.Add(wxT("*"));
315  new_item->mime_types.Add(wxT("*"));
316 
317  for (const auto &importPlugin : mImportPluginList)
318  {
319  new_item->filters.Add (importPlugin->GetPluginStringID());
320  new_item->filter_objects.push_back(importPlugin.get());
321  }
322  new_item->divider = -1;
323  return new_item;
324 }
ImportPluginList mImportPluginList
Definition: Import.h:152
Importer & Importer::Get ( )
static
ExtImportItems& Importer::GetImportItems ( )
inline

Returns a pointer to internal items array. External objects are allowed to change the array contents.

Definition at line 131 of file Import.h.

References mExtImportItems.

Referenced by ExtImportPrefs::DoOnPluginKeyDown(), ExtImportPrefs::DoOnRuleTableSelect(), ExtImportPrefs::OnAddRule(), ExtImportPrefs::OnDelRule(), ExtImportPrefs::OnRuleTableEdit(), ExtImportPrefs::PopulateOrExchange(), ExtImportPrefs::SwapPluginRows(), and ExtImportPrefs::SwapRows().

131 { return mExtImportItems; };
ExtImportItems mExtImportItems
Definition: Import.h:151
void Importer::GetSupportedImportFormats ( FormatList formatList)

Fills with a list of supported import formats

Definition at line 124 of file Import.cpp.

References mImportPluginList.

Referenced by ApplyMacroDialog::OnApplyToFiles(), and AudacityProject::ShowOpenDialog().

125 {
126  for(const auto &importPlugin : mImportPluginList)
127  {
128  formatList->emplace_back(importPlugin->GetPluginFormatDescription(),
129  importPlugin->GetSupportedExtensions());
130  }
131 }
ImportPluginList mImportPluginList
Definition: Import.h:152
bool Importer::Import ( const wxString &  fName,
TrackFactory trackFactory,
TrackHolders tracks,
Tags tags,
wxString &  errorMessage 
)

Definition at line 336 of file Import.cpp.

References _(), Cancelled, ExtImportItem::divider, ExtImportItem::extensions, Failed, ExtImportItem::filter_objects, GetActiveProject(), ImportPlugin::GetPluginStringID(), gPrefs, IsMidi(), AudacityProject::mbBusyImporting, mExtImportItems, ExtImportItem::mime_types, mImportPluginList, mUnusableImportPluginList, Stopped, Success, and valueRestorer().

Referenced by AudacityProject::Import().

341 {
343  auto cleanup = valueRestorer( pProj->mbBusyImporting, true );
344 
345  wxString extension = fName.AfterLast(wxT('.'));
346 
347  // Always refuse to import MIDI, even though the FFmpeg plugin pretends to know how (but makes very bad renderings)
348 #ifdef USE_MIDI
349  // MIDI files must be imported, not opened
350  if (IsMidi(fName)) {
351  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);
352  return false;
353  }
354 #endif
355 
356  using ImportPluginPtrs = std::vector< ImportPlugin* >;
357 
358  // This list is used to call plugins in correct order
359  ImportPluginPtrs importPlugins;
360 
361  // This list is used to remember plugins that should have been compatible with the file.
362  ImportPluginPtrs compatiblePlugins;
363 
364  // If user explicitly selected a filter,
365  // then we should try importing via corresponding plugin first
366  wxString type = gPrefs->Read(wxT("/LastOpenType"),wxT(""));
367 
368  // Not implemented (yet?)
369  wxString mime_type = wxT("*");
370 
371  // First, add user-selected filter
372  bool usersSelectionOverrides;
373  gPrefs->Read(wxT("/ExtendedImport/OverrideExtendedImportByOpenFileDialogChoice"), &usersSelectionOverrides, false);
374 
375  wxLogDebug(wxT("LastOpenType is %s"),type);
376  wxLogDebug(wxT("OverrideExtendedImportByOpenFileDialogChoice is %i"),usersSelectionOverrides);
377 
378  if (usersSelectionOverrides)
379  {
380  for (const auto &plugin : mImportPluginList)
381  {
382  if (plugin->GetPluginFormatDescription().CompareTo(type) == 0)
383  {
384  // This plugin corresponds to user-selected filter, try it first.
385  wxLogDebug(wxT("Inserting %s"),plugin->GetPluginStringID());
386  importPlugins.insert(importPlugins.begin(), plugin.get());
387  }
388  }
389  }
390 
391  wxLogMessage(wxT("File name is %s"), fName);
392  wxLogMessage(wxT("Mime type is %s"), mime_type.Lower());
393 
394  for (const auto &uItem : mExtImportItems)
395  {
396  ExtImportItem *item = uItem.get();
397  bool matches_ext = false, matches_mime = false;
398  wxLogDebug(wxT("Testing extensions"));
399  for (size_t j = 0; j < item->extensions.Count(); j++)
400  {
401  wxLogDebug(wxT("%s"), item->extensions[j].Lower());
402  if (wxMatchWild (item->extensions[j].Lower(),fName.Lower(), false))
403  {
404  wxLogDebug(wxT("Match!"));
405  matches_ext = true;
406  break;
407  }
408  }
409  if (item->extensions.Count() == 0)
410  {
411  wxLogDebug(wxT("Match! (empty list)"));
412  matches_ext = true;
413  }
414  if (matches_ext)
415  wxLogDebug(wxT("Testing mime types"));
416  else
417  wxLogDebug(wxT("Not testing mime types"));
418  for (size_t j = 0; matches_ext && j < item->mime_types.Count(); j++)
419  {
420  if (wxMatchWild (item->mime_types[j].Lower(),mime_type.Lower(), false))
421  {
422  wxLogDebug(wxT("Match!"));
423  matches_mime = true;
424  break;
425  }
426  }
427  if (item->mime_types.Count() == 0)
428  {
429  wxLogDebug(wxT("Match! (empty list)"));
430  matches_mime = true;
431  }
432  if (matches_ext && matches_mime)
433  {
434  wxLogDebug(wxT("Complete match!"));
435  for (size_t j = 0; j < item->filter_objects.size() && (item->divider < 0 || (int) j < item->divider); j++)
436  {
437  // the filter_object can be NULL if a suitable importer was not found
438  // this happens when we recompile with --without-ffmpeg and there
439  // is still ffmpeg in prefs from previous --with-ffmpeg builds
440  if (!(item->filter_objects[j]))
441  continue;
442  wxLogDebug(wxT("Inserting %s"),item->filter_objects[j]->GetPluginStringID());
443  importPlugins.push_back(item->filter_objects[j]);
444  }
445  }
446  }
447 
448  // Add all plugins that support the extension
449 
450  // Here we rely on the fact that the first plugin in mImportPluginList is libsndfile.
451  // We want to save this for later insertion ahead of libmad, if libmad supports the extension.
452  // The order of plugins in mImportPluginList is determined by the Importer constructor alone and
453  // is not changed by user selection overrides or any other mechanism, but we include an assert
454  // in case subsequent code revisions to the constructor should break this assumption that
455  // libsndfile is first.
456  ImportPlugin *libsndfilePlugin = mImportPluginList.begin()->get();
457  wxASSERT(libsndfilePlugin->GetPluginStringID().IsSameAs(wxT("libsndfile")));
458 
459  for (const auto &plugin : mImportPluginList)
460  {
461  // Make sure its not already in the list
462  if (importPlugins.end() ==
463  std::find(importPlugins.begin(), importPlugins.end(), plugin.get()))
464  {
465  if (plugin->SupportsExtension(extension))
466  {
467  // If libmad is accidentally fed a wav file which has been incorrectly
468  // given an .mp3 extension then it can choke on the contents and crash.
469  // To avoid this, put libsndfile ahead of libmad in the lists created for
470  // mp3 files, or for any of the extensions supported by libmad.
471  // A genuine .mp3 file will first fail an attempted import with libsndfile
472  // but then get processed as desired by libmad.
473  // But a wav file which bears an incorrect .mp3 extension will be successfully
474  // processed by libsndfile and thus avoid being submitted to libmad.
475  if (plugin->GetPluginStringID().IsSameAs(wxT("libmad")))
476  {
477  // Make sure libsndfile is not already in the list
478  if (importPlugins.end() ==
479  std::find(importPlugins.begin(), importPlugins.end(), libsndfilePlugin))
480  {
481  wxLogDebug(wxT("Appending %s"),libsndfilePlugin->GetPluginStringID());
482  importPlugins.push_back(libsndfilePlugin);
483  }
484  }
485  wxLogDebug(wxT("Appending %s"),plugin->GetPluginStringID());
486  importPlugins.push_back(plugin.get());
487  }
488  }
489  }
490 
491  // Add remaining plugins, except for libmad, which should not be used as a fallback for anything.
492  // Otherwise, if FFmpeg (libav) has not been installed, libmad will still be there near the
493  // end of the preference list importPlugins, where it will claim success importing FFmpeg file
494  // formats unsuitable for it, and produce distorted results.
495  for (const auto &plugin : mImportPluginList)
496  {
497  if (!(plugin->GetPluginStringID().IsSameAs(wxT("libmad"))))
498  {
499  // Make sure its not already in the list
500  if (importPlugins.end() ==
501  std::find(importPlugins.begin(), importPlugins.end(), plugin.get()))
502  {
503  wxLogDebug(wxT("Appending %s"),plugin->GetPluginStringID());
504  importPlugins.push_back(plugin.get());
505  }
506  }
507  }
508 
509  // Try the import plugins, in the permuted sequences just determined
510  for (const auto plugin : importPlugins)
511  {
512  // Try to open the file with this plugin (probe it)
513  wxLogMessage(wxT("Opening with %s"),plugin->GetPluginStringID());
514  auto inFile = plugin->Open(fName);
515  if ( (inFile != NULL) && (inFile->GetStreamCount() > 0) )
516  {
517  wxLogMessage(wxT("Open(%s) succeeded"), fName);
518  // File has more than one stream - display stream selector
519  if (inFile->GetStreamCount() > 1)
520  {
521  ImportStreamDialog ImportDlg(inFile.get(), NULL, -1, _("Select stream(s) to import"));
522 
523  if (ImportDlg.ShowModal() == wxID_CANCEL)
524  {
525  return false;
526  }
527  }
528  // One stream - import it by default
529  else
530  inFile->SetStreamUsage(0,TRUE);
531 
532  auto res = inFile->Import(trackFactory, tracks, tags);
533 
535  {
536  // LOF ("list-of-files") has different semantics
537  if (extension.IsSameAs(wxT("lof"), false))
538  {
539  return true;
540  }
541 
542  auto end = tracks.end();
543  auto iter = std::remove_if( tracks.begin(), end,
544  std::mem_fn( &NewChannelGroup::empty ) );
545  if ( iter != end ) {
546  // importer shouldn't give us empty groups of channels!
547  wxASSERT(false);
548  // But correct that and proceed anyway
549  tracks.erase( iter, end );
550  }
551  if (tracks.size() > 0)
552  {
553  // success!
554  return true;
555  }
556  }
557 
559  {
560  return false;
561  }
562 
563  // We could exit here since we had a match on the file extension,
564  // but there may be another plug-in that can import the file and
565  // that may recognize the extension, so we allow the loop to
566  // continue.
567  }
568  }
569  wxLogError(wxT("Importer::Import: Opening failed."));
570 
571  // None of our plugins can handle this file. It might be that
572  // Audacity supports this format, but support was not compiled in.
573  // If so, notify the user of this fact
574  for (const auto &unusableImportPlugin : mUnusableImportPluginList)
575  {
576  if( unusableImportPlugin->SupportsExtension(extension) )
577  {
578  errorMessage.Printf(_("This version of Audacity was not compiled with %s support."),
579  unusableImportPlugin->
580  GetPluginFormatDescription());
581  return false;
582  }
583  }
584 
585  /* warnings for unsupported data types */
586 
587  if (compatiblePlugins.empty())
588  {
589  // if someone has sent us a .cda file, send them away
590  if (extension.IsSameAs(wxT("cda"), false)) {
591  /* i18n-hint: %s will be the filename */
592  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);
593  return false;
594  }
595 
596  // playlist type files
597  if ((extension.IsSameAs(wxT("m3u"), false))||(extension.IsSameAs(wxT("ram"), false))||(extension.IsSameAs(wxT("pls"), false))) {
598  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);
599  return false;
600  }
601  //WMA files of various forms
602  if ((extension.IsSameAs(wxT("wma"), false))||(extension.IsSameAs(wxT("asf"), false))) {
603  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);
604  return false;
605  }
606  //AAC files of various forms (probably not encrypted)
607  if ((extension.IsSameAs(wxT("aac"), false))||(extension.IsSameAs(wxT("m4a"), false))||(extension.IsSameAs(wxT("m4r"), false))||(extension.IsSameAs(wxT("mp4"), false))) {
608  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);
609  return false;
610  }
611  // encrypted itunes files
612  if ((extension.IsSameAs(wxT("m4p"), false))) {
613  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);
614  return false;
615  }
616  // Real Inc. files of various sorts
617  if ((extension.IsSameAs(wxT("ra"), false))||(extension.IsSameAs(wxT("rm"), false))||(extension.IsSameAs(wxT("rpm"), false))) {
618  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);
619  return false;
620  }
621 
622  // Other notes-based formats
623  if ((extension.IsSameAs(wxT("kar"), false))||(extension.IsSameAs(wxT("mod"), false))||(extension.IsSameAs(wxT("rmi"), false))) {
624  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);
625  return false;
626  }
627 
628  // MusePack files
629  if ((extension.IsSameAs(wxT("mp+"), false))||(extension.IsSameAs(wxT("mpc"), false))||(extension.IsSameAs(wxT("mpp"), false))) {
630  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);
631  return false;
632  }
633 
634  // WavPack files
635  if ((extension.IsSameAs(wxT("wv"), false))||(extension.IsSameAs(wxT("wvc"), false))) {
636  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);
637  return false;
638  }
639 
640  // AC3 files
641  if ((extension.IsSameAs(wxT("ac3"), false))) {
642  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);
643  return false;
644  }
645 
646  // Speex files
647  if ((extension.IsSameAs(wxT("spx"), false))) {
648  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);
649  return false;
650  }
651 
652  // Video files of various forms
653  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))) {
654  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);
655  return false;
656  }
657 
658  // Audacity project
659  if (extension.IsSameAs(wxT("aup"), false)) {
660  errorMessage.Printf(_("\"%s\" is an Audacity Project file. \nUse the 'File > Open' command to open Audacity Projects."), fName);
661  return false;
662  }
663 
664  // we were not able to recognize the file type
665  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);
666  }
667  else
668  {
669  // We DO have a plugin for this file, but import failed.
670  wxString pluglist;
671 
672  for (const auto &plugin : compatiblePlugins)
673  {
674  if (pluglist.empty())
675  pluglist = plugin->GetPluginFormatDescription();
676  else
677  pluglist = wxString::Format( _("%s, %s"),
678  pluglist, plugin->GetPluginFormatDescription() );
679  }
680 
681  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);
682  }
683 
684  return false;
685 }
AudacityPrefs * gPrefs
Definition: Prefs.cpp:73
ExtImportItems mExtImportItems
Definition: Import.h:151
static bool IsMidi(const wxString &fName)
Definition: Import.cpp:326
bool mbBusyImporting
Definition: Project.h:689
AudacityProject provides the main window, with tools and tracks contained within it.
Definition: Project.h:174
ImportPluginList mImportPluginList
Definition: Import.h:152
wxArrayString mime_types
Definition: Import.h:85
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
ValueRestorer< T > valueRestorer(T &var)
inline functions provide convenient parameter type deduction
Definition: MemoryX.h:426
AUDACITY_DLL_API AudacityProject * GetActiveProject()
Definition: Project.cpp:311
wxArrayString extensions
Definition: Import.h:79
std::vector< ImportPlugin * > filter_objects
Definition: Import.h:73
virtual std::unique_ptr< ImportFileHandle > Open(const wxString &Filename)=0
virtual wxString GetPluginStringID()=0
int divider
Definition: Import.h:68
bool Importer::Initialize ( )

Initialization/Termination

Definition at line 85 of file Import.cpp.

References GetFFmpegImportPlugin(), GetFLACImportPlugin(), GetGStreamerImportPlugin(), GetLOFImportPlugin(), GetMP3ImportPlugin(), GetOGGImportPlugin(), GetPCMImportPlugin(), GetQTImportPlugin(), mExtImportItems, mImportPluginList, mUnusableImportPluginList, and ReadImportItems().

Referenced by AudacityApp::OnInit().

86 {
90 
91  // build the list of import plugin and/or unusableImporters.
92  // order is significant. If none match, they will all be tried
93  // in the order defined here.
99 
100  #if defined(USE_FFMPEG)
102  #endif
103  #ifdef USE_QUICKTIME
105  #endif
106  #if defined(USE_GSTREAMER)
108  #endif
109 
110  ReadImportItems();
111 
112  return true;
113 }
ExtImportItems mExtImportItems
Definition: Import.h:151
void GetOGGImportPlugin(ImportPluginList &importPluginList, UnusableImportPluginList &WXUNUSED(unusableImportPluginList))
Definition: ImportOGG.cpp:163
void GetFLACImportPlugin(ImportPluginList &importPluginList, UnusableImportPluginList &WXUNUSED(unusableImportPluginList))
Definition: ImportFLAC.cpp:293
void GetGStreamerImportPlugin(ImportPluginList &importPluginList, UnusableImportPluginList &WXUNUSED(unusableImportPluginList))
void ReadImportItems()
Definition: Import.cpp:141
void GetQTImportPlugin(ImportPluginList &importPluginList, UnusableImportPluginList &unusableImportPluginList)
Definition: ImportQT.cpp:40
ImportPluginList mImportPluginList
Definition: Import.h:152
void GetPCMImportPlugin(ImportPluginList &importPluginList, UnusableImportPluginList &WXUNUSED(unusableImportPluginList))
Definition: ImportPCM.cpp:117
std::vector< std::unique_ptr< ExtImportItem > > ExtImportItems
Definition: Import.h:47
void GetLOFImportPlugin(ImportPluginList &importPluginList, UnusableImportPluginList &WXUNUSED(unusableImportPluginList))
Definition: ImportLOF.cpp:172
void GetFFmpegImportPlugin(ImportPluginList &importPluginList, UnusableImportPluginList &WXUNUSED(unusableImportPluginList))
UnusableImportPluginList mUnusableImportPluginList
Definition: Import.h:153
An UnusableImportPlugin list.
An ImportPlugin list.
void GetMP3ImportPlugin(ImportPluginList &importPluginList, UnusableImportPluginList &WXUNUSED(unusableImportPluginList))
Definition: ImportMP3.cpp:163
bool Importer::IsMidi ( const wxString &  fName)
static

Definition at line 326 of file Import.cpp.

Referenced by Import(), LOFImportFileHandle::lofOpenFiles(), and AudacityProject::OpenFile().

327 {
328  const auto extension = fName.AfterLast(wxT('.'));
329  return
330  extension.IsSameAs(wxT("gro"), false) ||
331  extension.IsSameAs(wxT("midi"), false) ||
332  extension.IsSameAs(wxT("mid"), false);
333 }
void Importer::ReadImportItems ( )

Reads extended import filters from gPrefs into internal list mExtImportItems

Definition at line 141 of file Import.cpp.

References gPrefs, mExtImportItems, mImportPluginList, and StringToList().

Referenced by Initialize().

142 {
143  int item_counter = 0;
144  wxStringTokenizer toker;
145  wxString item_name;
146  wxString item_value;
147 
149  /* Rule string format is:
150  * extension1:extension2:extension3\mime_type1:mime_type2:mime_type3|filter1:filter2:filter3\unusedfilter1:unusedfilter2
151  * backslashes are escaped and unescaped internally
152  */
153  for (item_counter = 0; true; item_counter++)
154  {
155  wxString condition, filters, used_filters, unused_filters = wxEmptyString, extensions, mime_types = wxEmptyString;
156  item_name.Printf (wxT("/ExtImportItems/Item%d"), item_counter);
157  /* Break at first non-existent item */
158  if (!gPrefs->Read(item_name, &item_value))
159  break;
160 
161  toker.SetString(item_value, wxT("|"), wxTOKEN_RET_EMPTY_ALL);
162  /* Break at first broken item */
163  if (toker.CountTokens() != 2)
164  break;
165 
166  auto new_item = std::make_unique<ExtImportItem>();
167 
168  /* First token is the filtering condition, second - the filter list */
169  condition = toker.GetNextToken();
170  filters = toker.GetNextToken();
171 
172  /* Condition token consists of extension list and mime type list
173  * mime type list can be omitted entirely (complete with '\' separator)*/
174  toker.SetString(condition, wxT("\\"), wxTOKEN_RET_EMPTY_ALL);
175  extensions = toker.GetNextToken();
176  if (toker.HasMoreTokens())
177  mime_types = toker.GetNextToken();
178 
179  wxString delims(wxT(":"));
180  StringToList (extensions, delims, new_item->extensions);
181 
182  if (mime_types != wxEmptyString)
183  StringToList (mime_types, delims, new_item->mime_types);
184 
185  /* Filter token consists of used and unused filter lists */
186  toker.SetString(filters, wxT("\\"), wxTOKEN_RET_EMPTY_ALL);
187  used_filters = toker.GetNextToken();
188  if (toker.HasMoreTokens())
189  unused_filters = toker.GetNextToken();
190 
191  StringToList (used_filters, delims, new_item->filters);
192 
193  if (unused_filters != wxEmptyString)
194  {
195  /* Filters are stored in one list, but the position at which
196  * unused filters start is remembered
197  */
198  new_item->divider = new_item->filters.Count();
199  StringToList (unused_filters, delims, new_item->filters);
200  }
201  else
202  new_item->divider = -1;
203 
204  /* Find corresponding filter object for each filter ID */
205  for (size_t i = 0; i < new_item->filters.Count(); i++)
206  {
207  bool found = false;
208  for (const auto &importPlugin : mImportPluginList)
209  {
210  if (importPlugin->GetPluginStringID().Cmp(new_item->filters[i]) == 0)
211  {
212  new_item->filter_objects.push_back(importPlugin.get());
213  found = true;
214  break;
215  }
216  }
217  /* IDs that do not have corresponding filters, will be shown as-is */
218  if (!found)
219  new_item->filter_objects.push_back(nullptr);
220  }
221  /* Find all filter objects that are not present in the filter list */
222  for (const auto &importPlugin : mImportPluginList)
223  {
224  bool found = false;
225  for (size_t i = 0; i < new_item->filter_objects.size(); i++)
226  {
227  if (importPlugin.get() == new_item->filter_objects[i])
228  {
229  found = true;
230  break;
231  }
232  }
233  /* Add these filters at the bottom of used filter list */
234  if (!found)
235  {
236  int index = new_item->divider;
237  if (new_item->divider < 0)
238  index = new_item->filters.Count();
239  new_item->filters.Insert(importPlugin->GetPluginStringID(),index);
240  new_item->filter_objects.insert(
241  new_item->filter_objects.begin() + index, importPlugin.get());
242  if (new_item->divider >= 0)
243  new_item->divider++;
244  }
245  }
246  this->mExtImportItems.push_back( std::move(new_item) );
247  }
248 }
AudacityPrefs * gPrefs
Definition: Prefs.cpp:73
ExtImportItems mExtImportItems
Definition: Import.h:151
void StringToList(wxString &str, wxString &delims, wxArrayString &list, wxStringTokenizerMode mod=wxTOKEN_RET_EMPTY_ALL)
Definition: Import.cpp:133
ImportPluginList mImportPluginList
Definition: Import.h:152
std::vector< std::unique_ptr< ExtImportItem > > ExtImportItems
Definition: Import.h:47
void Importer::StringToList ( wxString &  str,
wxString &  delims,
wxArrayString &  list,
wxStringTokenizerMode  mod = wxTOKEN_RET_EMPTY_ALL 
)

Helper function - uses wxStringTokenizer to tokenize string and appends string-tokens to a list . deifines tokenizer's behaviour.

Definition at line 133 of file Import.cpp.

Referenced by ExtImportPrefs::OnRuleTableEdit(), and ReadImportItems().

134 {
135  wxStringTokenizer toker;
136 
137  for (toker.SetString(str, delims, mod);
138  toker.HasMoreTokens(); list.Add (toker.GetNextToken()));
139 }
bool Importer::Terminate ( )

Definition at line 115 of file Import.cpp.

References mImportPluginList, mUnusableImportPluginList, and WriteImportItems().

Referenced by AudacityApp::OnExit().

116 {
120 
121  return true;
122 }
ImportPluginList mImportPluginList
Definition: Import.h:152
void WriteImportItems()
Definition: Import.cpp:250
UnusableImportPluginList mUnusableImportPluginList
Definition: Import.h:153
An UnusableImportPlugin list.
An ImportPlugin list.
void Importer::WriteImportItems ( )

Writes mExtImportItems into gPrefs

Definition at line 250 of file Import.cpp.

References ExtImportItem::divider, ExtImportItem::extensions, ExtImportItem::filters, gPrefs, mExtImportItems, ExtImportItem::mime_types, and name.

Referenced by Terminate().

251 {
252  size_t i;
253  wxString val, name;
254  for (i = 0; i < this->mExtImportItems.size(); i++)
255  {
256  ExtImportItem *item = mExtImportItems[i].get();
257  val.Clear();
258 
259  for (size_t j = 0; j < item->extensions.Count(); j++)
260  {
261  val.Append (item->extensions[j]);
262  if (j < item->extensions.Count() - 1)
263  val.Append (wxT(":"));
264  }
265  val.Append (wxT("\\"));
266  for (size_t j = 0; j < item->mime_types.Count(); j++)
267  {
268  val.Append (item->mime_types[j]);
269  if (j < item->mime_types.Count() - 1)
270  val.Append (wxT(":"));
271  }
272  val.Append (wxT("|"));
273  for (size_t j = 0; j < item->filters.Count() && ((int) j < item->divider || item->divider < 0); j++)
274  {
275  val.Append (item->filters[j]);
276  if (j < item->filters.Count() - 1 && ((int) j < item->divider - 1 || item->divider < 0))
277  val.Append (wxT(":"));
278  }
279  if (item->divider >= 0)
280  {
281  val.Append (wxT("\\"));
282  for (size_t j = item->divider; j < item->filters.Count(); j++)
283  {
284  val.Append (item->filters[j]);
285  if (j < item->filters.Count() - 1)
286  val.Append (wxT(":"));
287  }
288  }
289  name.Printf (wxT("/ExtImportItems/Item%d"), (int)i);
290  gPrefs->Write (name, val);
291  gPrefs->Flush();
292  }
293  /* If we used to have more items than we have now, DELETE the excess items.
294  We just keep deleting items and incrementing until we find there aren't any
295  more to DELETE.*/
296  i = this->mExtImportItems.size();
297  do {
298  name.Printf (wxT("/ExtImportItems/Item%d"), (int)i);
299  // No item to DELETE? Then it's time to finish.
300  if (!gPrefs->Read(name, &val))
301  break;
302  // Failure to DELETE probably means a read-only config file.
303  // no point continuing.
304  // TODO: Possibly report (once).
305  if( !gPrefs->DeleteEntry (name, false))
306  break;
307  i++;
308  } while( true );
309 }
AudacityPrefs * gPrefs
Definition: Prefs.cpp:73
wxArrayString filters
Definition: Import.h:59
ExtImportItems mExtImportItems
Definition: Import.h:151
wxArrayString mime_types
Definition: Import.h:85
const wxChar * name
Definition: Distortion.cpp:94
wxArrayString extensions
Definition: Import.h:79
int divider
Definition: Import.h:68

Member Data Documentation

ExtImportItems Importer::mExtImportItems
private

Definition at line 151 of file Import.h.

Referenced by GetImportItems(), Import(), Initialize(), ReadImportItems(), and WriteImportItems().

ImportPluginList Importer::mImportPluginList
private
Importer Importer::mInstance
staticprivate

Definition at line 149 of file Import.h.

Referenced by Get().

UnusableImportPluginList Importer::mUnusableImportPluginList
private

Definition at line 153 of file Import.h.

Referenced by Import(), Initialize(), and Terminate().


The documentation for this class was generated from the following files: