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 107 of file Import.cpp.

108{
109}

◆ ~Importer()

Importer::~Importer ( )

Definition at line 111 of file Import.cpp.

112{
113}

◆ 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 470 of file Import.cpp.

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

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 208 of file Import.cpp.

209{
210 // Construct the filter
211 FileNames::FileTypes fileTypes{
213 // Will fill in the list of extensions later:
214 { XO("All supported files"), {} },
216 };
217
218 if ( !extraType.extensions.empty() )
219 fileTypes.push_back( extraType );
220
222 for(const auto &importPlugin : sImportPluginList())
223 {
224 l.emplace_back(importPlugin->GetPluginFormatDescription(),
225 importPlugin->GetSupportedExtensions());
226 }
227
228 FileExtensions extraExtensions = FileNames::AudacityProjects.extensions;
229 extraExtensions.insert(extraExtensions.end(),
230 extraType.extensions.begin(),
231 extraType.extensions.end());
232
233 using ExtensionSet = std::unordered_set< FileExtension >;
234 FileExtensions allList = FileNames::AudacityProjects.extensions, newList;
235 allList.insert(allList.end(), extraType.extensions.begin(), extraType.extensions.end());
236 ExtensionSet allSet{ allList.begin(), allList.end() }, newSet;
237 for ( const auto &format : l ) {
238 newList.clear();
239 newSet.clear();
240 for ( const auto &extension : format.extensions ) {
241 if ( newSet.insert( extension ).second )
242 newList.push_back( extension );
243 if ( allSet.insert( extension ).second )
244 allList.push_back( extension );
245 }
246 fileTypes.push_back( { format.description, newList } );
247 }
248
249 fileTypes[1].extensions = allList;
250 return fileTypes;
251}
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, 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 486 of file Import.cpp.

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

References ImportProgressListener::Cancelled, ExtImportItem::divider, TranslatableString::empty(), PackedArray::end(), ExtImportItem::extensions, ExtImportItem::filter_objects, gPrefs, AudacityProject::mbBusyImporting, mExtImportItems, ExtImportItem::mime_types, project, audacity::BasicSettings::Read(), sImportPluginList(), ImportProgressListener::Stopped, ImportProgressListener::Success, sUnusableImportPluginList(), tracks, valueRestorer(), Verbatim(), wxT(), and XO().

Referenced by ProjectFileManager::Import().

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 166 of file Import.cpp.

167{
168 // build the list of import plugin and/or unusableImporters.
169 // order is significant. If none match, they will all be tried
170 // in the order defined here.
171
172 using namespace Registry;
174 PathStart,
175 // FFmpeg is in default of all other modules that might handle a format
176 // better and specially; including MIDI import
177 { {wxT(""), wxT("AUP,PCM,OGG,FLAC,MP3,LOF,WavPack,portsmf,FFmpeg") } }
178 };
179
180 // Once only, visit the registry to collect the plug-ins properly
181 // sorted
182 static std::once_flag flag;
183 std::call_once(flag, []{
186 [](const ImporterItem &item, auto&) {
187 sImportPluginList().push_back(item.mpPlugin.get()); },
188 &top, &ImporterItem::Registry());
189 });
190
191 // Ordering of the unusable plugin list is not important.
192
194
196
197 return true;
198}
std::vector< std::unique_ptr< ExtImportItem > > ExtImportItems
Definition: Import.h:42
static std::once_flag flag
void ReadImportItems()
Definition: Import.cpp:298
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:122
static Registry::GroupItem< Traits > & Registry()
Definition: Import.cpp:127

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 298 of file Import.cpp.

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

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 273 of file Import.cpp.

274{
275 wxString defaultValue;
276 if ( !fileTypes.empty() )
277 defaultValue = fileTypes[0].description.Translation();
278
279 wxString type = gPrefs->Read(wxT("/DefaultOpenType"), defaultValue);
280 // Convert the type to the filter index
281 auto begin = fileTypes.begin();
282 auto index = std::distance(
283 begin,
284 std::find_if( begin, fileTypes.end(),
285 [&type](const FileNames::FileType &fileType){
286 return fileType.description.Translation() == type; } ) );
287 return (index == fileTypes.size()) ? 0 : index;
288}
auto begin(const Ptr< Type, BaseDeleter > &p)
Enables range-for.
Definition: PackedArray.h:150

References PackedArray::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 263 of file Import.cpp.

264{
265 // PRL: Preference key /DefaultOpenType, unusually, stores a localized
266 // string!
267 // The bad consequences of a change of locale are not severe -- only that
268 // a default choice of file type for an open dialog is not remembered
269 gPrefs->Write(wxT("/DefaultOpenType"), type.description.Translation());
270 gPrefs->Flush();
271}
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 253 of file Import.cpp.

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

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 115 of file Import.cpp.

116{
117 static ImportPluginList theList;
118 return theList;
119}
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 290 of file Import.cpp.

291{
292 wxStringTokenizer toker;
293
294 for (toker.SetString(str, delims, mod);
295 toker.HasMoreTokens(); list.push_back(toker.GetNextToken()));
296}
#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 153 of file Import.cpp.

154{
155 static UnusableImportPluginList theList;
156 return theList;
157}
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 200 of file Import.cpp.

201{
203
204 return true;
205}
void WriteImportItems()
Definition: Import.cpp:409

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 409 of file Import.cpp.

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