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

Class which actually imports the auido, using functions defined in ImportPCM.cpp, ImportMP3_*.cpp, ImportOGG.cpp, ImportRawData.cpp, ImportLOF.cpp, and ImportAUP.cpp. More...

#include <Import.h>

Collaboration diagram for Importer:
[legend]

Classes

struct  ImporterItem
 
struct  RegisteredImportPlugin
 
struct  RegisteredUnusableImportPlugin
 

Public Member Functions

 Importer ()
 
 ~Importer ()
 
 Importer (const Importer &) PROHIBITED
 
Importeroperator= (Importer &) PROHIBITED
 
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, WaveTrackFactory *trackFactory, TrackHolders &tracks, Tags *tags, 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

Class which actually imports the auido, using functions defined in ImportPCM.cpp, ImportMP3_*.cpp, ImportOGG.cpp, ImportRawData.cpp, ImportLOF.cpp, and ImportAUP.cpp.

Definition at line 80 of file Import.h.

Constructor & Destructor Documentation

◆ Importer() [1/2]

Importer::Importer ( )

Definition at line 73 of file Import.cpp.

74{
75}

◆ ~Importer()

Importer::~Importer ( )

Definition at line 77 of file Import.cpp.

78{
79}

◆ Importer() [2/2]

Importer::Importer ( const Importer )

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

442{
443 auto new_item = std::make_unique<ExtImportItem>();
444 new_item->extensions.push_back(wxT("*"));
445 new_item->mime_types.push_back(wxT("*"));
446
447 for (const auto &importPlugin : sImportPluginList())
448 {
449 new_item->filters.push_back(importPlugin->GetPluginStringID());
450 new_item->filter_objects.push_back(importPlugin);
451 }
452 new_item->divider = -1;
453 return new_item;
454}
wxT("CloseDown"))
static ImportPluginList & sImportPluginList()
Definition: Import.cpp:81

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

180{
181 // Construct the filter
182 FileNames::FileTypes fileTypes{
184 // Will fill in the list of extensions later:
185 { XO("All supported files"), {} },
187 };
188
189 if ( !extraType.extensions.empty() )
190 fileTypes.push_back( extraType );
191
193 for(const auto &importPlugin : sImportPluginList())
194 {
195 l.emplace_back(importPlugin->GetPluginFormatDescription(),
196 importPlugin->GetSupportedExtensions());
197 }
198
199 FileExtensions extraExtensions = FileNames::AudacityProjects.extensions;
200 extraExtensions.insert(extraExtensions.end(),
201 extraType.extensions.begin(),
202 extraType.extensions.end());
203
204 using ExtensionSet = std::unordered_set< FileExtension >;
205 FileExtensions allList = FileNames::AudacityProjects.extensions, newList;
206 allList.insert(allList.end(), extraType.extensions.begin(), extraType.extensions.end());
207 ExtensionSet allSet{ allList.begin(), allList.end() }, newSet;
208 for ( const auto &format : l ) {
209 newList.clear();
210 newSet.clear();
211 for ( const auto &extension : format.extensions ) {
212 if ( newSet.insert( extension ).second )
213 newList.push_back( extension );
214 if ( allSet.insert( extension ).second )
215 allList.push_back( extension );
216 }
217 fileTypes.push_back( { format.description, newList } );
218 }
219
220 fileTypes[1].extensions = allList;
221 return fileTypes;
222}
int format
Definition: ExportPCM.cpp:53
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, 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 165 of file Import.h.

165{ return mExtImportItems; }
ExtImportItems mExtImportItems
Definition: Import.h:192

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,
WaveTrackFactory trackFactory,
TrackHolders tracks,
Tags tags,
TranslatableString errorMessage 
)

Definition at line 457 of file Import.cpp.

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

References RefreshCode::Cancelled, ExtImportItem::divider, TranslatableString::empty(), PackedArray::end(), ExtImportItem::extensions, ExtImportItem::filter_objects, gPrefs, FileNames::IsMidi(), AudacityProject::mbBusyImporting, mExtImportItems, ExtImportItem::mime_types, sImportPluginList(), BasicUI::Success, sUnusableImportPluginList(), 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 132 of file Import.cpp.

133{
134 // build the list of import plugin and/or unusableImporters.
135 // order is significant. If none match, they will all be tried
136 // in the order defined here.
137
138 using namespace Registry;
140 PathStart,
141 { {wxT(""), wxT("AUP,PCM,OGG,FLAC,MP3,LOF,WavPack,FFmpeg") } }
142 // QT and GStreamer are only conditionally compiled and would get
143 // placed at the end if present
144 };
145
146 static struct MyVisitor final : Visitor {
147 MyVisitor()
148 {
149 // Once only, visit the registry to collect the plug-ins properly
150 // sorted
152 Registry::Visit( *this, &top, &ImporterItem::Registry() );
153 }
154
155 void Visit( SingleItem &item, const Path &path ) override
156 {
157 sImportPluginList().push_back(
158 static_cast<ImporterItem&>( item ).mpPlugin.get() );
159 }
160 } visitor;
161
162 // Ordering of the unusable plugin list is not important.
163
165
167
168 return true;
169}
std::vector< std::unique_ptr< ExtImportItem > > ExtImportItems
Definition: Import.h:38
auto Visit(Visitor &&vis, Variant &&var)
Mimic some of std::visit, for the case of one visitor only.
Definition: MemoryX.h:628
void ReadImportItems()
Definition: Import.cpp:269
Definition: Menus.h:35
void Visit(Visitor &visitor, BaseItem *pTopItem, const GroupItem *pRegistry)
Definition: Registry.cpp:713
static const auto PathStart
Definition: Import.cpp:88
static Registry::GroupItem & Registry()
Definition: Import.cpp:93

References mExtImportItems, anonymous_namespace{Import.cpp}::PathStart, ReadImportItems(), Importer::ImporterItem::Registry(), sImportPluginList(), Visit(), 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 )

◆ ReadImportItems()

void Importer::ReadImportItems ( )

Reads extended import filters from gPrefs into internal list mExtImportItems

Definition at line 269 of file Import.cpp.

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

References gPrefs, mExtImportItems, 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 244 of file Import.cpp.

245{
246 wxString defaultValue;
247 if ( !fileTypes.empty() )
248 defaultValue = fileTypes[0].description.Translation();
249
250 wxString type = gPrefs->Read(wxT("/DefaultOpenType"), defaultValue);
251 // Convert the type to the filter index
252 auto begin = fileTypes.begin();
253 auto index = std::distance(
254 begin,
255 std::find_if( begin, fileTypes.end(),
256 [&type](const FileNames::FileType &fileType){
257 return fileType.description.Translation() == type; } ) );
258 return (index == fileTypes.size()) ? 0 : index;
259}
auto begin(const Ptr< Type, BaseDeleter > &p)
Enables range-for.
Definition: PackedArray.h:150

References PackedArray::begin(), gPrefs, 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 234 of file Import.cpp.

235{
236 // PRL: Preference key /DefaultOpenType, unusually, stores a localized
237 // string!
238 // The bad consequences of a change of locale are not severe -- only that
239 // a default choice of file type for an open dialog is not remembered
240 gPrefs->Write(wxT("/DefaultOpenType"), type.description.Translation());
241 gPrefs->Flush();
242}
virtual bool Flush(bool bCurrentOnly=false) wxOVERRIDE
Definition: FileConfig.cpp:143
wxString Translation() const
TranslatableString description
Definition: FileNames.h:60

References FileNames::FileType::description, FileConfig::Flush(), gPrefs, TranslatableString::Translation(), 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 224 of file Import.cpp.

225{
226 // PRL: Preference key /LastOpenType, unusually, stores a localized
227 // string!
228 // The bad consequences of a change of locale are not severe -- only that
229 // a default choice of file type for an open dialog is not remembered
230 gPrefs->Write(wxT("/LastOpenType"), type.description.Translation());
231 gPrefs->Flush();
232}

References FileNames::FileType::description, FileConfig::Flush(), gPrefs, TranslatableString::Translation(), 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 81 of file Import.cpp.

82{
83 static ImportPluginList theList;
84 return theList;
85}
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 261 of file Import.cpp.

262{
263 wxStringTokenizer toker;
264
265 for (toker.SetString(str, delims, mod);
266 toker.HasMoreTokens(); list.push_back(toker.GetNextToken()));
267}
#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 119 of file Import.cpp.

120{
121 static UnusableImportPluginList theList;
122 return theList;
123}
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 171 of file Import.cpp.

172{
174
175 return true;
176}
void WriteImportItems()
Definition: Import.cpp:380

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

381{
382 size_t i;
383 wxString val, name;
384 for (i = 0; i < this->mExtImportItems.size(); i++)
385 {
386 ExtImportItem *item = mExtImportItems[i].get();
387 val.clear();
388
389 for (size_t j = 0; j < item->extensions.size(); j++)
390 {
391 val.Append (item->extensions[j]);
392 if (j < item->extensions.size() - 1)
393 val.Append (wxT(":"));
394 }
395 val.Append (wxT("\\"));
396 for (size_t j = 0; j < item->mime_types.size(); j++)
397 {
398 val.Append (item->mime_types[j]);
399 if (j < item->mime_types.size() - 1)
400 val.Append (wxT(":"));
401 }
402 val.Append (wxT("|"));
403 for (size_t j = 0; j < item->filters.size() && ((int) j < item->divider || item->divider < 0); j++)
404 {
405 val.Append (item->filters[j]);
406 if (j < item->filters.size() - 1 && ((int) j < item->divider - 1 || item->divider < 0))
407 val.Append (wxT(":"));
408 }
409 if (item->divider >= 0)
410 {
411 val.Append (wxT("\\"));
412 for (size_t j = item->divider; j < item->filters.size(); j++)
413 {
414 val.Append (item->filters[j]);
415 if (j < item->filters.size() - 1)
416 val.Append (wxT(":"));
417 }
418 }
419 name.Printf (wxT("/ExtImportItems/Item%d"), (int)i);
420 gPrefs->Write (name, val);
421 gPrefs->Flush();
422 }
423 /* If we used to have more items than we have now, DELETE the excess items.
424 We just keep deleting items and incrementing until we find there aren't any
425 more to DELETE.*/
426 i = this->mExtImportItems.size();
427 do {
428 name.Printf (wxT("/ExtImportItems/Item%d"), (int)i);
429 // No item to DELETE? Then it's time to finish.
430 if (!gPrefs->Read(name, &val))
431 break;
432 // Failure to DELETE probably means a read-only config file.
433 // no point continuing.
434 // TODO: Possibly report (once).
435 if( !gPrefs->DeleteEntry (name, false))
436 break;
437 i++;
438 } while( true );
439}
const TranslatableString name
Definition: Distortion.cpp:76
wxArrayString filters
Definition: Import.h:51
virtual bool DeleteEntry(const wxString &key, bool bDeleteGroupIfEmpty=true) wxOVERRIDE
Definition: FileConfig.cpp:209

References FileConfig::DeleteEntry(), ExtImportItem::divider, ExtImportItem::extensions, ExtImportItem::filters, FileConfig::Flush(), gPrefs, mExtImportItems, ExtImportItem::mime_types, name, 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 192 of file Import.h.

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

◆ mInstance

Importer Importer::mInstance
staticprivate

Definition at line 190 of file Import.h.

Referenced by Get().


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