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

Singleton class which actually imports the audio, using ImportPlugin objects that are registered by modules, which in turn are factories of ImportFileHandle. More...

#include <Import.h>

Collaboration diagram for Importer:
[legend]

Classes

struct  ImporterItem
 
struct  RegisteredImportPlugin
 
struct  RegisteredUnusableImportPlugin
 
struct  Traits
 

Public Member Functions

 Importer ()
 
 ~Importer ()
 
 Importer (const Importer &)=delete
 
Importeroperator= (Importer &)=delete
 
bool Initialize ()
 
bool Terminate ()
 
FileNames::FileTypes GetFileTypes (const FileNames::FileType &extraType={})
 
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 (AudacityProject &project, const FilePath &fName, ImportProgressListener *importProgressListener, WaveTrackFactory *trackFactory, TrackHolders &tracks, Tags *tags, std::optional< LibFileFormats::AcidizerTags > &outAcidTags, TranslatableString &errorMessage)
 

Static Public Member Functions

static ImporterGet ()
 
static void SetLastOpenType (const FileNames::FileType &type)
 
static void SetDefaultOpenType (const FileNames::FileType &type)
 
static size_t SelectDefaultOpenType (const FileNames::FileTypes &fileTypes)
 

Static Private Member Functions

static ImportPluginListsImportPluginList ()
 
static UnusableImportPluginListsUnusableImportPluginList ()
 

Private Attributes

ExtImportItems mExtImportItems
 

Static Private Attributes

static Importer mInstance
 

Detailed Description

Singleton class which actually imports the audio, using ImportPlugin objects that are registered by modules, which in turn are factories of ImportFileHandle.

Definition at line 84 of file Import.h.

Constructor & Destructor Documentation

◆ Importer() [1/2]

Importer::Importer ( )

Definition at line 108 of file Import.cpp.

109{
110}

◆ ~Importer()

Importer::~Importer ( )

Definition at line 112 of file Import.cpp.

113{
114}

◆ Importer() [2/2]

Importer::Importer ( const Importer )
delete

Member Function Documentation

◆ CreateDefaultImportItem()

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

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

Definition at line 471 of file Import.cpp.

472{
473 auto new_item = std::make_unique<ExtImportItem>();
474 new_item->extensions.push_back(wxT("*"));
475 new_item->mime_types.push_back(wxT("*"));
476
477 for (const auto &importPlugin : sImportPluginList())
478 {
479 new_item->filters.push_back(importPlugin->GetPluginStringID());
480 new_item->filter_objects.push_back(importPlugin);
481 }
482 new_item->divider = -1;
483 return new_item;
484}
wxT("CloseDown"))
static ImportPluginList & sImportPluginList()
Definition: Import.cpp:116

References sImportPluginList(), and wxT().

Referenced by ExtImportPrefs::OnAddRule().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ Get()

Importer & Importer::Get ( )
static

◆ GetFileTypes()

FileNames::FileTypes Importer::GetFileTypes ( const FileNames::FileType extraType = {})

Constructs a list of types, for use by file opening dialogs, that includes all supported file types

Definition at line 209 of file Import.cpp.

210{
211 // Construct the filter
212 FileNames::FileTypes fileTypes{
214 // Will fill in the list of extensions later:
215 { XO("All supported files"), {} },
217 };
218
219 if ( !extraType.extensions.empty() )
220 fileTypes.push_back( extraType );
221
223 for(const auto &importPlugin : sImportPluginList())
224 {
225 l.emplace_back(importPlugin->GetPluginFormatDescription(),
226 importPlugin->GetSupportedExtensions());
227 }
228
229 FileExtensions extraExtensions = FileNames::AudacityProjects.extensions;
230 extraExtensions.insert(extraExtensions.end(),
231 extraType.extensions.begin(),
232 extraType.extensions.end());
233
234 using ExtensionSet = std::unordered_set< FileExtension >;
235 FileExtensions allList = FileNames::AudacityProjects.extensions, newList;
236 allList.insert(allList.end(), extraType.extensions.begin(), extraType.extensions.end());
237 ExtensionSet allSet{ allList.begin(), allList.end() }, newSet;
238 for ( const auto &format : l ) {
239 newList.clear();
240 newSet.clear();
241 for ( const auto &extension : format.extensions ) {
242 if ( newSet.insert( extension ).second )
243 newList.push_back( extension );
244 if ( allSet.insert( extension ).second )
245 allList.push_back( extension );
246 }
247 fileTypes.push_back( { format.description, newList } );
248 }
249
250 fileTypes[1].extensions = allList;
251 return fileTypes;
252}
XO("Cut/Copy/Paste")
std::vector< FileType > FileTypes
Definition: FileNames.h:75
FILES_API const FileType AllFiles
Definition: FileNames.h:70
FILES_API const FileType AudacityProjects
Definition: FileNames.h:71
Extend wxArrayString with move operations and construction and insertion fromstd::initializer_list.
iterator insert(const_iterator pos, std::initializer_list< T > items)
FileExtensions extensions
Definition: FileNames.h:61

References FileNames::AllFiles, FileNames::AudacityProjects, anonymous_namespace{CloudProjectFileIOExtensions.cpp}::extension, FileNames::FileType::extensions, anonymous_namespace{ExportPCM.cpp}::format, wxArrayStringEx::insert(), sImportPluginList(), and XO().

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

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GetImportItems()

ExtImportItems & Importer::GetImportItems ( )
inline

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

Definition at line 169 of file Import.h.

169{ return mExtImportItems; }
ExtImportItems mExtImportItems
Definition: Import.h:200

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

Here is the caller graph for this function:

◆ Import()

bool Importer::Import ( AudacityProject project,
const FilePath fName,
ImportProgressListener importProgressListener,
WaveTrackFactory trackFactory,
TrackHolders tracks,
Tags tags,
std::optional< LibFileFormats::AcidizerTags > &  outAcidTags,
TranslatableString errorMessage 
)

Definition at line 487 of file Import.cpp.

493{
494 AudacityProject *pProj = &project;
495 auto cleanup = valueRestorer( pProj->mbBusyImporting, true );
496
497 const FileExtension extension{ fName.AfterLast(wxT('.')) };
498
499 // Bug #2647: Peter has a Word 2000 .doc file that is recognized and imported by FFmpeg.
500 if (wxFileName(fName).GetExt() == wxT("doc")) {
501 errorMessage =
502 XO("\"%s\" \nis a not an audio file. \nAudacity cannot open this type of file.")
503 .Format( fName );
504 return false;
505 }
506
507 using ImportPluginPtrs = std::vector< ImportPlugin* >;
508
509 // This list is used to call plugins in correct order
510 ImportPluginPtrs importPlugins;
511
512 // This list is used to remember plugins that should have been compatible with the file.
513 ImportPluginPtrs compatiblePlugins;
514
515 // Not implemented (yet?)
516 wxString mime_type = wxT("*");
517
518 // First, add user-selected filter
519 bool usersSelectionOverrides;
520 gPrefs->Read(wxT("/ExtendedImport/OverrideExtendedImportByOpenFileDialogChoice"), &usersSelectionOverrides, false);
521
522 if (usersSelectionOverrides)
523 {
524 // If user explicitly selected a filter,
525 // then we should try importing via corresponding plugin first
526 wxString type = gPrefs->Read(wxT("/LastOpenType"),wxT(""));
527
528 wxLogDebug(wxT("LastOpenType is %s"),type);
529 wxLogDebug(wxT("OverrideExtendedImportByOpenFileDialogChoice is %i"),usersSelectionOverrides);
530
531 for (const auto &plugin : sImportPluginList())
532 {
533 if (plugin->GetPluginFormatDescription().Translation() == type )
534 {
535 // This plugin corresponds to user-selected filter, try it first.
536 wxLogDebug(wxT("Inserting %s"),plugin->GetPluginStringID());
537 importPlugins.insert(importPlugins.begin(), plugin);
538 }
539 }
540 }
541
542 wxLogMessage(wxT("File name is %s"), fName);
543 wxLogMessage(wxT("Mime type is %s"), mime_type.Lower());
544
545 for (const auto &uItem : mExtImportItems)
546 {
547 ExtImportItem *item = uItem.get();
548 bool matches_ext = false, matches_mime = false;
549 wxLogDebug(wxT("Testing extensions"));
550 for (size_t j = 0; j < item->extensions.size(); j++)
551 {
552 wxLogDebug(wxT("%s"), item->extensions[j].Lower());
553 if (wxMatchWild (item->extensions[j].Lower(),fName.Lower(), false))
554 {
555 wxLogDebug(wxT("Match!"));
556 matches_ext = true;
557 break;
558 }
559 }
560 if (item->extensions.size() == 0)
561 {
562 wxLogDebug(wxT("Match! (empty list)"));
563 matches_ext = true;
564 }
565 if (matches_ext)
566 wxLogDebug(wxT("Testing mime types"));
567 else
568 wxLogDebug(wxT("Not testing mime types"));
569 for (size_t j = 0; matches_ext && j < item->mime_types.size(); j++)
570 {
571 if (wxMatchWild (item->mime_types[j].Lower(),mime_type.Lower(), false))
572 {
573 wxLogDebug(wxT("Match!"));
574 matches_mime = true;
575 break;
576 }
577 }
578 if (item->mime_types.size() == 0)
579 {
580 wxLogDebug(wxT("Match! (empty list)"));
581 matches_mime = true;
582 }
583 if (matches_ext && matches_mime)
584 {
585 wxLogDebug(wxT("Complete match!"));
586 for (size_t j = 0; j < item->filter_objects.size() && (item->divider < 0 || (int) j < item->divider); j++)
587 {
588 // the filter_object can be NULL if a suitable importer was not found
589 // this happens when we recompile with --without-ffmpeg and there
590 // is still ffmpeg in prefs from previous --with-ffmpeg builds
591 if (!(item->filter_objects[j]))
592 continue;
593 wxLogDebug(wxT("Inserting %s"),item->filter_objects[j]->GetPluginStringID());
594 importPlugins.push_back(item->filter_objects[j]);
595 }
596 }
597 }
598
599 // Add all plugins that support the extension
600 for (const auto &plugin : sImportPluginList())
601 {
602 // Make sure its not already in the list
603 if (importPlugins.end() ==
604 std::find(importPlugins.begin(), importPlugins.end(), plugin))
605 {
606 if (plugin->SupportsExtension(extension))
607 {
608 wxLogDebug(wxT("Appending %s"),plugin->GetPluginStringID());
609 importPlugins.push_back(plugin);
610 }
611 }
612 }
613
614 // Add remaining plugins
615 for (const auto &plugin : sImportPluginList())
616 {
617 // Make sure its not already in the list
618 if (importPlugins.end() ==
619 std::find(importPlugins.begin(), importPlugins.end(), plugin))
620 {
621 wxLogDebug(wxT("Appending %s"),plugin->GetPluginStringID());
622 importPlugins.push_back(plugin);
623 }
624 }
625
626 ImportProgressResultProxy importResultProxy(importProgressListener);
627
628 // Try the import plugins, in the permuted sequences just determined
629 for (const auto plugin : importPlugins)
630 {
631 // Try to open the file with this plugin (probe it)
632 wxLogMessage(wxT("Opening with %s"),plugin->GetPluginStringID());
633
634#ifdef __WXMAC__
635 struct stat s;
636 memset(&s, 0, sizeof(struct stat));
637 auto err = stat(fName.data(), &s);
638 if(err != 0 || (S_ISREG(s.st_mode) && s.st_blocks == 0))
639 {
641 auto dialog = BasicUI::MakeGenericProgress({}, XO("Importing files"), XO("Importing %s...").Format(fName.AfterLast(wxFileName::GetPathSeparator())), dialogStyle);
642 while(err != 0 || s.st_blocks == 0)
643 {
645 if(dialog->Pulse() != BasicUI::ProgressResult::Success)
646 {
647 errorMessage = XO("Operation was canceled by user");
648 return false;
649 }
650 memset(&s, 0, sizeof(struct stat));
651 err = stat(fName.data(), &s);
652 }
653 }
654#endif
655 auto inFile = plugin->Open(fName, pProj);
656 if ( (inFile != NULL) && (inFile->GetStreamCount() > 0) )
657 {
658 wxLogMessage(wxT("Open(%s) succeeded"), fName);
659 if(!importResultProxy.OnImportFileOpened(*inFile))
660 return false;
661
662 inFile->Import(
663 importResultProxy, trackFactory, tracks, tags, outAcidTags);
664 const auto importResult = importResultProxy.GetResult();
667 {
668 // LOF ("list-of-files") has different semantics
669 if (extension.IsSameAs(wxT("lof"), false))
670 {
671 return true;
672 }
673
674 // AUP ("legacy projects") have different semantics
675 if (extension.IsSameAs(wxT("aup"), false))
676 {
677 return true;
678 }
679
680 if (tracks.size() > 0)
681 // success!
682 return true;
683 }
684
685 if (importResultProxy.GetResult() == ImportProgressListener::ImportResult::Cancelled)
686 return false;
687
688 // We could exit here since we had a match on the file extension,
689 // but there may be another plug-in that can import the file and
690 // that may recognize the extension, so we allow the loop to
691 // continue.
692 }
693 }
694 wxLogError(wxT("Importer::Import: Opening failed."));
695
696 // None of our plugins can handle this file. It might be that
697 // Audacity supports this format, but support was not compiled in.
698 // If so, notify the user of this fact
699 for (const auto &unusableImportPlugin : sUnusableImportPluginList())
700 {
701 if( unusableImportPlugin->SupportsExtension(extension) )
702 {
703 errorMessage = XO("This version of Audacity was not compiled with %s support.")
704 .Format( unusableImportPlugin->GetPluginFormatDescription() );
705 return false;
706 }
707 }
708
709 /* warnings for unsupported data types */
710
711 if (compatiblePlugins.empty())
712 {
713 // if someone has sent us a .cda file, send them away
714 if (extension.IsSameAs(wxT("cda"), false)) {
715 errorMessage = XO(
716/* i18n-hint: %s will be the filename */
717"\"%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.")
718 .Format( fName );
719 return false;
720 }
721
722 // playlist type files
723 if ((extension.IsSameAs(wxT("m3u"), false))||(extension.IsSameAs(wxT("ram"), false))||(extension.IsSameAs(wxT("pls"), false))) {
724 errorMessage = XO(
725/* i18n-hint: %s will be the filename */
726"\"%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.")
727 .Format( fName );
728 return false;
729 }
730 //WMA files of various forms
731 if ((extension.IsSameAs(wxT("wma"), false))||(extension.IsSameAs(wxT("asf"), false))) {
732 errorMessage = XO(
733/* i18n-hint: %s will be the filename */
734"\"%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.")
735 .Format( fName );
736 return false;
737 }
738 //AAC files of various forms (probably not encrypted)
739 if ((extension.IsSameAs(wxT("aac"), false))||(extension.IsSameAs(wxT("m4a"), false))||(extension.IsSameAs(wxT("m4r"), false))||(extension.IsSameAs(wxT("mp4"), false))) {
740 errorMessage = XO(
741/* i18n-hint: %s will be the filename */
742"\"%s\" is an Advanced Audio Coding file.\nWithout the optional FFmpeg library, Audacity cannot open this type of file.\nOtherwise, you need to convert it to a supported audio format, such as WAV or AIFF.")
743 .Format( fName );
744 return false;
745 }
746 // encrypted itunes files
747 if ((extension.IsSameAs(wxT("m4p"), false))) {
748 errorMessage = XO(
749/* i18n-hint: %s will be the filename */
750"\"%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.")
751 .Format( fName );
752 return false;
753 }
754 // Real Inc. files of various sorts
755 if ((extension.IsSameAs(wxT("ra"), false))||(extension.IsSameAs(wxT("rm"), false))||(extension.IsSameAs(wxT("rpm"), false))) {
756 errorMessage = XO(
757/* i18n-hint: %s will be the filename */
758"\"%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.")
759 .Format( fName );
760 return false;
761 }
762
763 // Other notes-based formats
764 if ((extension.IsSameAs(wxT("kar"), false))||(extension.IsSameAs(wxT("mod"), false))||(extension.IsSameAs(wxT("rmi"), false))) {
765 errorMessage = XO(
766/* i18n-hint: %s will be the filename */
767"\"%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.")
768 .Format( fName );
769 return false;
770 }
771
772 // MusePack files
773 if ((extension.IsSameAs(wxT("mp+"), false))||(extension.IsSameAs(wxT("mpc"), false))||(extension.IsSameAs(wxT("mpp"), false))) {
774 errorMessage = XO(
775/* i18n-hint: %s will be the filename */
776"\"%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.")
777 .Format( fName );
778 return false;
779 }
780
781 // WavPack files
782 if ((extension.IsSameAs(wxT("wv"), false))||(extension.IsSameAs(wxT("wvc"), false))) {
783 errorMessage = XO(
784/* i18n-hint: %s will be the filename */
785"\"%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.")
786 .Format( fName );
787 return false;
788 }
789
790 // AC3 files
791 if ((extension.IsSameAs(wxT("ac3"), false))) {
792 errorMessage = XO(
793/* i18n-hint: %s will be the filename */
794"\"%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.")
795 .Format( fName );
796 return false;
797 }
798
799 // Speex files
800 if ((extension.IsSameAs(wxT("spx"), false))) {
801 errorMessage = XO(
802/* i18n-hint: %s will be the filename */
803"\"%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.")
804 .Format( fName );
805 return false;
806 }
807
808 // Video files of various forms
809 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))) {
810 errorMessage = XO(
811/* i18n-hint: %s will be the filename */
812"\"%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.")
813 .Format( fName );
814 return false;
815 }
816
817 if( !wxFileExists(fName)){
818 errorMessage = XO( "File \"%s\" not found.").Format( fName );
819 return false;
820 }
821
822 // we were not able to recognize the file type
823 TranslatableString extraMessages;
824 for(const auto &importPlugin : sImportPluginList()) {
825 auto message = importPlugin->FailureHint();
826 if (!message.empty()) {
827 extraMessages += message;
828 extraMessages += Verbatim("\n");
829 }
830 }
831
832 errorMessage = XO(
833/* i18n-hint: %s will be the filename */
834"Audacity did not recognize the type of the file '%s'.\n\n%sFor uncompressed files, also try File > Import > Raw Data.")
835 .Format( fName, extraMessages );
836 }
837 else
838 {
839 // We DO have a plugin for this file, but import failed.
840 TranslatableString pluglist;
841
842 for (const auto &plugin : compatiblePlugins)
843 {
844 if (pluglist.empty())
845 pluglist = plugin->GetPluginFormatDescription();
846 else
847 pluglist = XO("%s, %s")
848 .Format( pluglist, plugin->GetPluginFormatDescription() );
849 }
850
851 errorMessage = XO(
852/* i18n-hint: %s will be the filename */
853"Audacity recognized the type of the file '%s'.\nImporters supposedly supporting such files are:\n%s,\nbut none of them understood this file format.")
854 .Format( fName, pluglist );
855 }
856
857 return false;
858}
wxString FileExtension
File extension, not including any leading dot.
Definition: Identifier.h:224
ValueRestorer< T > valueRestorer(T &var)
inline functions provide convenient parameter type deduction
Definition: MemoryX.h:253
audacity::BasicSettings * gPrefs
Definition: Prefs.cpp:68
const auto tracks
const auto project
TranslatableString Verbatim(wxString str)
Require calls to the one-argument constructor to go through this distinct global function name.
The top-level handle to an Audacity project. It serves as a source of events that other objects can b...
Definition: Project.h:90
bool mbBusyImporting
Definition: Project.h:130
int divider
Definition: Import.h:64
wxArrayString extensions
Definition: Import.h:75
wxArrayString mime_types
Definition: Import.h:81
std::vector< ImportPlugin * > filter_objects
Definition: Import.h:69
static UnusableImportPluginList & sUnusableImportPluginList()
Definition: Import.cpp:154
Holds a msgid for the translation catalog; may also bind format arguments.
virtual bool Read(const wxString &key, bool *value) const =0
std::unique_ptr< GenericProgressDialog > MakeGenericProgress(const WindowPlacement &placement, const TranslatableString &title, const TranslatableString &message, int style=(ProgressAppModal|ProgressShowElapsedTime|ProgressSmooth))
Create and display a progress dialog (return nullptr if Services not installed)
Definition: BasicUI.h:320
@ ProgressCanAbort
Definition: BasicUI.h:148
@ ProgressShowElapsedTime
Definition: BasicUI.h:150
@ ProgressSmooth
Definition: BasicUI.h:151
@ ProgressAppModal
Definition: BasicUI.h:149
void Yield()
Dispatch waiting events, including actions enqueued by CallAfter.
Definition: BasicUI.cpp:225

References ImportProgressListener::Cancelled, ExtImportItem::divider, TranslatableString::empty(), anonymous_namespace{CloudProjectFileIOExtensions.cpp}::extension, ExtImportItem::extensions, ExtImportItem::filter_objects, gPrefs, BasicUI::MakeGenericProgress(), AudacityProject::mbBusyImporting, mExtImportItems, ExtImportItem::mime_types, BasicUI::ProgressAppModal, BasicUI::ProgressCanAbort, BasicUI::ProgressShowElapsedTime, BasicUI::ProgressSmooth, project, audacity::BasicSettings::Read(), sImportPluginList(), ImportProgressListener::Stopped, BasicUI::Success, ImportProgressListener::Success, sUnusableImportPluginList(), tracks, valueRestorer(), Verbatim(), wxT(), XO(), and BasicUI::Yield().

Referenced by ProjectFileManager::DoImport().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ Initialize()

bool Importer::Initialize ( )

Initialization/Termination

Definition at line 167 of file Import.cpp.

168{
169 // build the list of import plugin and/or unusableImporters.
170 // order is significant. If none match, they will all be tried
171 // in the order defined here.
172
173 using namespace Registry;
175 PathStart,
176 // FFmpeg is in default of all other modules that might handle a format
177 // better and specially; including MIDI import
178 { {wxT(""), wxT("AUP,PCM,OGG,FLAC,MP3,LOF,WavPack,portsmf,FFmpeg") } }
179 };
180
181 // Once only, visit the registry to collect the plug-ins properly
182 // sorted
183 static std::once_flag flag;
184 std::call_once(flag, []{
187 [](const ImporterItem &item, auto&) {
188 sImportPluginList().push_back(item.mpPlugin.get()); },
189 &top, &ImporterItem::Registry());
190 });
191
192 // Ordering of the unusable plugin list is not important.
193
195
197
198 return true;
199}
std::vector< std::unique_ptr< ExtImportItem > > ExtImportItems
Definition: Import.h:42
static std::once_flag flag
void ReadImportItems()
Definition: Import.cpp:299
void Visit(const Visitors &visitors, const GroupItem< RegistryTraits > *pTopItem, const GroupItem< RegistryTraits > *pRegistry={}, typename RegistryTraits::ComputedItemContextType &computedItemContext=RegistryTraits::ComputedItemContextType::Instance)
Definition: Registry.h:609
static const auto PathStart
Definition: Import.cpp:123
static Registry::GroupItem< Traits > & Registry()
Definition: Import.cpp:128

References flag, mExtImportItems, Importer::ImporterItem::mpPlugin, anonymous_namespace{Import.cpp}::PathStart, ReadImportItems(), Importer::ImporterItem::Registry(), sImportPluginList(), Registry::Visit(), and wxT().

Referenced by AudacityApp::InitPart2().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ operator=()

Importer & Importer::operator= ( Importer )
delete

◆ ReadImportItems()

void Importer::ReadImportItems ( )

Reads extended import filters from gPrefs into internal list mExtImportItems

Definition at line 299 of file Import.cpp.

300{
301 int item_counter = 0;
302 wxStringTokenizer toker;
303 wxString item_name;
304 wxString item_value;
305
307 /* Rule string format is:
308 * extension1:extension2:extension3\mime_type1:mime_type2:mime_type3|filter1:filter2:filter3\unusedfilter1:unusedfilter2
309 * backslashes are escaped and unescaped internally
310 */
311 for (item_counter = 0; true; item_counter++)
312 {
313 wxString condition, filters, used_filters, unused_filters, extensions, mime_types;
314 item_name.Printf (wxT("/ExtImportItems/Item%d"), item_counter);
315 /* Break at first non-existent item */
316 if (!gPrefs->Read(item_name, &item_value))
317 break;
318
319 toker.SetString(item_value, wxT("|"), wxTOKEN_RET_EMPTY_ALL);
320 /* Break at first broken item */
321 if (toker.CountTokens() != 2)
322 break;
323
324 auto new_item = std::make_unique<ExtImportItem>();
325
326 /* First token is the filtering condition, second - the filter list */
327 condition = toker.GetNextToken();
328 filters = toker.GetNextToken();
329
330 /* Condition token consists of extension list and mime type list
331 * mime type list can be omitted entirely (complete with '\' separator)*/
332 toker.SetString(condition, wxT("\\"), wxTOKEN_RET_EMPTY_ALL);
333 extensions = toker.GetNextToken();
334 if (toker.HasMoreTokens())
335 mime_types = toker.GetNextToken();
336
337 wxString delims(wxT(":"));
338 StringToList (extensions, delims, new_item->extensions);
339
340 if (!mime_types.empty())
341 StringToList (mime_types, delims, new_item->mime_types);
342
343 /* Filter token consists of used and unused filter lists */
344 toker.SetString(filters, wxT("\\"), wxTOKEN_RET_EMPTY_ALL);
345 used_filters = toker.GetNextToken();
346 if (toker.HasMoreTokens())
347 unused_filters = toker.GetNextToken();
348
349 StringToList (used_filters, delims, new_item->filters);
350
351 if (!unused_filters.empty())
352 {
353 /* Filters are stored in one list, but the position at which
354 * unused filters start is remembered
355 */
356 new_item->divider = new_item->filters.size();
357 StringToList (unused_filters, delims, new_item->filters);
358 }
359 else
360 new_item->divider = -1;
361
362 /* Find corresponding filter object for each filter ID */
363 for (size_t i = 0; i < new_item->filters.size(); i++)
364 {
365 bool found = false;
366 for (const auto &importPlugin : sImportPluginList())
367 {
368 if (importPlugin->GetPluginStringID() == new_item->filters[i])
369 {
370 new_item->filter_objects.push_back(importPlugin);
371 found = true;
372 break;
373 }
374 }
375 /* IDs that do not have corresponding filters, will be shown as-is */
376 if (!found)
377 new_item->filter_objects.push_back(nullptr);
378 }
379 /* Find all filter objects that are not present in the filter list */
380 for (const auto &importPlugin : sImportPluginList())
381 {
382 bool found = false;
383 for (size_t i = 0; i < new_item->filter_objects.size(); i++)
384 {
385 if (importPlugin == new_item->filter_objects[i])
386 {
387 found = true;
388 break;
389 }
390 }
391 /* Add these filters at the bottom of used filter list */
392 if (!found)
393 {
394 int index = new_item->divider;
395 if (new_item->divider < 0)
396 index = new_item->filters.size();
397 new_item->filters.insert(
398 new_item->filters.begin() + index,
399 importPlugin->GetPluginStringID());
400 new_item->filter_objects.insert(
401 new_item->filter_objects.begin() + index, importPlugin);
402 if (new_item->divider >= 0)
403 new_item->divider++;
404 }
405 }
406 this->mExtImportItems.push_back( std::move(new_item) );
407 }
408}
void StringToList(wxString &str, wxString &delims, wxArrayString &list, wxStringTokenizerMode mod=wxTOKEN_RET_EMPTY_ALL)
Definition: Import.cpp:291

References gPrefs, mExtImportItems, audacity::BasicSettings::Read(), sImportPluginList(), StringToList(), and wxT().

Referenced by Initialize(), and ExtImportPrefs::Populate().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ SelectDefaultOpenType()

size_t Importer::SelectDefaultOpenType ( const FileNames::FileTypes fileTypes)
static

Choose index of preferred type

Definition at line 274 of file Import.cpp.

275{
276 wxString defaultValue;
277 if ( !fileTypes.empty() )
278 defaultValue = fileTypes[0].description.Translation();
279
280 wxString type = gPrefs->Read(wxT("/DefaultOpenType"), defaultValue);
281 // Convert the type to the filter index
282 auto begin = fileTypes.begin();
283 auto index = std::distance(
284 begin,
285 std::find_if( begin, fileTypes.end(),
286 [&type](const FileNames::FileType &fileType){
287 return fileType.description.Translation() == type; } ) );
288 return (index == fileTypes.size()) ? 0 : index;
289}
const char * begin(const char *str) noexcept
Definition: StringUtils.h:101

References details::begin(), gPrefs, audacity::BasicSettings::Read(), and wxT().

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

Here is the call graph for this function:
Here is the caller graph for this function:

◆ SetDefaultOpenType()

void Importer::SetDefaultOpenType ( const FileNames::FileType type)
static

Remember a file type in preferences

Definition at line 264 of file Import.cpp.

265{
266 // PRL: Preference key /DefaultOpenType, unusually, stores a localized
267 // string!
268 // The bad consequences of a change of locale are not severe -- only that
269 // a default choice of file type for an open dialog is not remembered
270 gPrefs->Write(wxT("/DefaultOpenType"), type.description.Translation());
271 gPrefs->Flush();
272}
wxString Translation() const
virtual bool Flush() noexcept=0
virtual bool Write(const wxString &key, bool value)=0
TranslatableString description
Definition: FileNames.h:60

References FileNames::FileType::description, audacity::BasicSettings::Flush(), gPrefs, TranslatableString::Translation(), audacity::BasicSettings::Write(), and wxT().

Referenced by ProjectFileManager::ShowOpenDialog().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ SetLastOpenType()

void Importer::SetLastOpenType ( const FileNames::FileType type)
static

Remember a file type in preferences

Definition at line 254 of file Import.cpp.

255{
256 // PRL: Preference key /LastOpenType, unusually, stores a localized
257 // string!
258 // The bad consequences of a change of locale are not severe -- only that
259 // a default choice of file type for an open dialog is not remembered
260 gPrefs->Write(wxT("/LastOpenType"), type.description.Translation());
261 gPrefs->Flush();
262}

References FileNames::FileType::description, audacity::BasicSettings::Flush(), gPrefs, TranslatableString::Translation(), audacity::BasicSettings::Write(), and wxT().

Referenced by anonymous_namespace{FileMenus.cpp}::DoImport(), ProjectManager::OpenFiles(), and ProjectFileManager::ShowOpenDialog().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ sImportPluginList()

ImportPluginList & Importer::sImportPluginList ( )
staticprivate

Definition at line 116 of file Import.cpp.

117{
118 static ImportPluginList theList;
119 return theList;
120}
std::vector< ImportPlugin * > ImportPluginList

Referenced by CreateDefaultImportItem(), GetFileTypes(), Import(), Initialize(), and ReadImportItems().

Here is the caller graph for this function:

◆ StringToList()

void Importer::StringToList ( wxString &  str,
wxString &  delims,
wxArrayString &  list,
wxStringTokenizerMode  mod = wxTOKEN_RET_EMPTY_ALL 
)

Helper function - uses wxStringTokenizer to tokenize @str string and appends string-tokens to a list @list. @mod defines tokenizer's behaviour.

Definition at line 291 of file Import.cpp.

292{
293 wxStringTokenizer toker;
294
295 for (toker.SetString(str, delims, mod);
296 toker.HasMoreTokens(); list.push_back(toker.GetNextToken()));
297}
#define str(a)

References str.

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

Here is the caller graph for this function:

◆ sUnusableImportPluginList()

UnusableImportPluginList & Importer::sUnusableImportPluginList ( )
staticprivate

Definition at line 154 of file Import.cpp.

155{
156 static UnusableImportPluginList theList;
157 return theList;
158}
std::vector< std::unique_ptr< UnusableImportPlugin > > UnusableImportPluginList

Referenced by Import(), and Importer::RegisteredUnusableImportPlugin::RegisteredUnusableImportPlugin().

Here is the caller graph for this function:

◆ Terminate()

bool Importer::Terminate ( )

Definition at line 201 of file Import.cpp.

202{
204
205 return true;
206}
void WriteImportItems()
Definition: Import.cpp:410

References WriteImportItems().

Referenced by AudacityApp::OnExit().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ WriteImportItems()

void Importer::WriteImportItems ( )

Writes mExtImportItems into gPrefs

Definition at line 410 of file Import.cpp.

411{
412 size_t i;
413 wxString val, name;
414 for (i = 0; i < this->mExtImportItems.size(); i++)
415 {
416 ExtImportItem *item = mExtImportItems[i].get();
417 val.clear();
418
419 for (size_t j = 0; j < item->extensions.size(); j++)
420 {
421 val.Append (item->extensions[j]);
422 if (j < item->extensions.size() - 1)
423 val.Append (wxT(":"));
424 }
425 val.Append (wxT("\\"));
426 for (size_t j = 0; j < item->mime_types.size(); j++)
427 {
428 val.Append (item->mime_types[j]);
429 if (j < item->mime_types.size() - 1)
430 val.Append (wxT(":"));
431 }
432 val.Append (wxT("|"));
433 for (size_t j = 0; j < item->filters.size() && ((int) j < item->divider || item->divider < 0); j++)
434 {
435 val.Append (item->filters[j]);
436 if (j < item->filters.size() - 1 && ((int) j < item->divider - 1 || item->divider < 0))
437 val.Append (wxT(":"));
438 }
439 if (item->divider >= 0)
440 {
441 val.Append (wxT("\\"));
442 for (size_t j = item->divider; j < item->filters.size(); j++)
443 {
444 val.Append (item->filters[j]);
445 if (j < item->filters.size() - 1)
446 val.Append (wxT(":"));
447 }
448 }
449 name.Printf (wxT("/ExtImportItems/Item%d"), (int)i);
450 gPrefs->Write (name, val);
451 gPrefs->Flush();
452 }
453 /* If we used to have more items than we have now, DELETE the excess items.
454 We just keep deleting items and incrementing until we find there aren't any
455 more to DELETE.*/
456 i = this->mExtImportItems.size();
457 do {
458 name.Printf (wxT("/ExtImportItems/Item%d"), (int)i);
459 // No item to DELETE? Then it's time to finish.
460 if (!gPrefs->Read(name, &val))
461 break;
462 // Failure to DELETE probably means a read-only config file.
463 // no point continuing.
464 // TODO: Possibly report (once).
465 if( !gPrefs->DeleteEntry (name))
466 break;
467 i++;
468 } while( true );
469}
wxString name
Definition: TagsEditor.cpp:166
wxArrayString filters
Definition: Import.h:55
bool DeleteEntry(const wxString &key)
Deletes specified entry if exists.

References audacity::BasicSettings::DeleteEntry(), ExtImportItem::divider, ExtImportItem::extensions, ExtImportItem::filters, audacity::BasicSettings::Flush(), gPrefs, mExtImportItems, ExtImportItem::mime_types, name, audacity::BasicSettings::Read(), audacity::BasicSettings::Write(), and wxT().

Referenced by ExtImportPrefs::Commit(), and Terminate().

Here is the call graph for this function:
Here is the caller graph for this function:

Member Data Documentation

◆ mExtImportItems

ExtImportItems Importer::mExtImportItems
private

Definition at line 200 of file Import.h.

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

◆ mInstance

Importer Importer::mInstance
staticprivate

Definition at line 198 of file Import.h.

Referenced by Get().


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