Rewrite FileDialogWrapper using FileNames::FileTypes...

... also removing some repeated code and using the config keys /DefaultOpenType
and /LastOpenType only in Import.cpp
This commit is contained in:
Paul Licameli 2019-12-20 13:02:31 -05:00
parent fc668f09b0
commit c64b3cb31f
13 changed files with 93 additions and 216 deletions

View File

@ -339,54 +339,17 @@ void ApplyMacroDialog::OnApplyToFiles(wxCommandEvent & WXUNUSED(event))
auto prompt = XO("Select file(s) for batch processing...");
FormatList l;
wxString filter;
wxString all;
Importer::Get().GetSupportedImportFormats(&l);
for (const auto &format : l) {
const Format *f = &format;
wxString newfilter = f->formatName.Translation() + wxT("|");
for (size_t i = 0; i < f->formatExtensions.size(); i++) {
if (!newfilter.Contains(wxT("*.") + f->formatExtensions[i] + wxT(";")))
newfilter += wxT("*.") + f->formatExtensions[i] + wxT(";");
if (!all.Contains(wxT("*.") + f->formatExtensions[i] + wxT(";")))
all += wxT("*.") + f->formatExtensions[i] + wxT(";");
}
newfilter.RemoveLast(1);
filter += newfilter;
filter += wxT("|");
}
all.RemoveLast(1);
filter.RemoveLast(1);
wxString mask = _("All files|*|All supported files|") +
all + wxT("|") +
filter;
wxString type = gPrefs->Read(wxT("/DefaultOpenType"),mask.BeforeFirst(wxT('|')));
// Convert the type to the filter index
int index = mask.First(type + wxT("|"));
if (index == wxNOT_FOUND) {
index = 0;
}
else {
index = mask.Left(index).Freq(wxT('|')) / 2;
if (index < 0) {
index = 0;
}
}
const auto fileTypes = Importer::Get().GetFileTypes();
auto path = FileNames::FindDefaultPath(FileNames::Operation::Open);
FileDialogWrapper dlog(this,
prompt,
path,
wxT(""),
mask,
wxFD_OPEN | wxFD_MULTIPLE | wxRESIZE_BORDER);
prompt,
path,
wxT(""),
fileTypes,
wxFD_OPEN | wxFD_MULTIPLE | wxRESIZE_BORDER);
dlog.SetFilterIndex(index);
dlog.SetFilterIndex( Importer::SelectDefaultOpenType( fileTypes ) );
if (dlog.ShowModal() != wxID_OK) {
Raise();
return;

View File

@ -1028,107 +1028,35 @@ void ProjectFileManager::CloseLock()
}
// static method, can be called outside of a project
wxArrayString ProjectFileManager::ShowOpenDialog(const wxString &extraformat, const wxString &extrafilter)
wxArrayString ProjectFileManager::ShowOpenDialog(
const FileNames::FileType &extraType )
{
FormatList l;
wxString filter; ///< List of file format names and extensions, separated
/// by | characters between _formats_ and extensions for each _format_, i.e.
/// format1name | *.ext | format2name | *.ex1;*.ex2
wxString all; ///< One long list of all supported file extensions,
/// semicolon separated
if (!extraformat.empty())
{ // additional format specified
all = extrafilter + wxT(';');
// add it to the "all supported files" filter string
}
// Construct the filter
Importer::Get().GetSupportedImportFormats(&l);
const auto fileTypes = Importer::Get().GetFileTypes( extraType );
for (const auto &format : l) {
/* this loop runs once per supported _format_ */
const Format *f = &format;
wxString newfilter = f->formatName.Translation() + wxT("|");
// bung format name into string plus | separator
for (size_t i = 0; i < f->formatExtensions.size(); i++) {
/* this loop runs once per valid _file extension_ for file containing
* the current _format_ */
if (!newfilter.Contains(wxT("*.") + f->formatExtensions[i] + wxT(";")))
newfilter += wxT("*.") + f->formatExtensions[i] + wxT(";");
if (!all.Contains(wxT("*.") + f->formatExtensions[i] + wxT(";")))
all += wxT("*.") + f->formatExtensions[i] + wxT(";");
}
newfilter.RemoveLast(1);
filter += newfilter;
filter += wxT("|");
}
all.RemoveLast(1);
filter.RemoveLast(1);
// For testing long filters
#if 0
wxString test = wxT("*.aaa;*.bbb;*.ccc;*.ddd;*.eee");
all = test + wxT(';') + test + wxT(';') + test + wxT(';') +
test + wxT(';') + test + wxT(';') + test + wxT(';') +
test + wxT(';') + test + wxT(';') + test + wxT(';') +
all;
#endif
/* i18n-hint: The vertical bars and * are essential here.*/
wxString mask = _("All files|*|All supported files|") +
all + wxT("|"); // "all" and "all supported" entries
if (!extraformat.empty())
{ // append caller-defined format if supplied
mask += extraformat + wxT("|") + extrafilter + wxT("|");
}
mask += filter; // put the names and extensions of all the importer formats
// we built up earlier into the mask
// Retrieve saved path and type
// Retrieve saved path
auto path = FileNames::FindDefaultPath(FileNames::Operation::Open);
wxString type = gPrefs->Read(wxT("/DefaultOpenType"),mask.BeforeFirst(wxT('|')));
// Convert the type to the filter index
int index = mask.First(type + wxT("|"));
if (index == wxNOT_FOUND) {
index = 0;
}
else {
index = mask.Left(index).Freq(wxT('|')) / 2;
if (index < 0) {
index = 0;
}
}
// Construct and display the file dialog
wxArrayString selected;
FileDialogWrapper dlog(NULL,
FileDialogWrapper dlog(nullptr,
XO("Select one or more files"),
path,
wxT(""),
mask,
fileTypes,
wxFD_OPEN | wxFD_MULTIPLE | wxRESIZE_BORDER);
dlog.SetFilterIndex(index);
dlog.SetFilterIndex( Importer::SelectDefaultOpenType( fileTypes ) );
int dialogResult = dlog.ShowModal();
// Convert the filter index to type and save
index = dlog.GetFilterIndex();
for (int i = 0; i < index; i++) {
mask = mask.AfterFirst(wxT('|')).AfterFirst(wxT('|'));
}
auto index = dlog.GetFilterIndex();
const auto &saveType = fileTypes[ index ];
// PRL: Preference keys /DefaultOpenType and /LastOpenType, unusually,
// store localized strings!
// The bad consequences of a change of locale are not severe -- only that
// a default choice of file type for an open dialog is not remembered
gPrefs->Write(wxT("/DefaultOpenType"), mask.BeforeFirst(wxT('|')));
gPrefs->Write(wxT("/LastOpenType"), mask.BeforeFirst(wxT('|')));
gPrefs->Flush();
Importer::SetDefaultOpenType( saveType );
Importer::SetLastOpenType( saveType );
if (dialogResult == wxID_OK) {
// Return the selected files

View File

@ -16,6 +16,7 @@ Paul Licameli split from AudacityProject.h
#include "ClientData.h" // to inherit
#include "import/ImportRaw.h" // defines TrackHolders
#include "FileNames.h" // for FileType
class wxString;
class wxFileName;
@ -83,20 +84,13 @@ public:
* will be set to the DefaultOpenType from the preferences, failing that
* the first format specified in the dialogue. These two parameters will
* be saved to the preferences once the user has chosen a file to open.
* @param extraformat Specify the name of an additional format to allow
* opening in this dialogue. This string is free-form, but should be short
* enough to fit in the file dialogue filter drop-down. It should be
* translated.
* @param extrafilter Specify the file extension(s) for the additional format
* specified by extraformat. The patterns must include the wildcard (e.g.
* "*.aup" not "aup" or ".aup"), separate multiple patters with a semicolon,
* e.g. "*.aup;*.AUP" because patterns are case-sensitive. Do not add a
* trailing semicolon to the string. This string should not be translated
* @param extraType Specify an additional format to allow opening in this
* dialogue.
* @return Array of file paths which the user selected to open (multiple
* selections allowed).
*/
static wxArrayString ShowOpenDialog(const wxString &extraformat = {},
const wxString &extrafilter = {});
static wxArrayString ShowOpenDialog(
const FileNames::FileType &extraType = {});
static bool IsAlreadyOpen(const FilePath &projPathName);

View File

@ -38,6 +38,7 @@ Paul Licameli split from AudacityProject.cpp
#include "UndoManager.h"
#include "WaveTrack.h"
#include "wxFileNameWrapper.h"
#include "import/Import.h"
#include "import/ImportMIDI.h"
#include "ondemand/ODManager.h"
#include "prefs/QualityPrefs.h"
@ -834,10 +835,9 @@ void ProjectManager::OpenFiles(AudacityProject *proj)
* with Audacity. Do not include pipe symbols or .aup (this extension will
* now be added automatically for the Save Projects dialogues).*/
auto selectedFiles =
ProjectFileManager::ShowOpenDialog(_("Audacity projects"), wxT("*.aup"));
ProjectFileManager::ShowOpenDialog( FileNames::AudacityProjects );
if (selectedFiles.size() == 0) {
gPrefs->Write(wxT("/LastOpenType"),wxT(""));
gPrefs->Flush();
Importer::SetLastOpenType({});
return;
}
@ -848,8 +848,7 @@ void ProjectManager::OpenFiles(AudacityProject *proj)
ODManager::Pauser pauser;
auto cleanup = finally( [] {
gPrefs->Write(wxT("/LastOpenType"),wxT(""));
gPrefs->Flush();
Importer::SetLastOpenType({});
} );
for (size_t ff = 0; ff < selectedFiles.size(); ff++) {

View File

@ -3696,11 +3696,16 @@ void EditCurvesDialog::OnDelete(wxCommandEvent & WXUNUSED(event))
#endif
}
static const auto XMLtypes = FileNames::FileTypes{
FileNames::XMLFiles
};
void EditCurvesDialog::OnImport( wxCommandEvent & WXUNUSED(event))
{
FileDialogWrapper filePicker(this,
FileDialogWrapper filePicker(
this,
XO("Choose an EQ curve file"), FileNames::DataDir(), wxT(""),
_("xml files (*.xml;*.XML)|*.xml;*.XML"));
XMLtypes );
wxString fileName;
if( filePicker.ShowModal() == wxID_CANCEL)
return;
@ -3721,7 +3726,8 @@ void EditCurvesDialog::OnImport( wxCommandEvent & WXUNUSED(event))
void EditCurvesDialog::OnExport( wxCommandEvent & WXUNUSED(event))
{
FileDialogWrapper filePicker(this, XO("Export EQ curves as..."),
FileNames::DataDir(), wxT(""), wxT("*.XML"),
FileNames::DataDir(), wxT(""),
XMLtypes,
wxFD_SAVE | wxFD_OVERWRITE_PROMPT | wxRESIZE_BORDER); // wxFD_CHANGE_DIR?
wxString fileName;
if( filePicker.ShowModal() == wxID_CANCEL)

View File

@ -2818,6 +2818,13 @@ bool NyquistEffect::IsOk()
return mOK;
}
static const FileNames::FileType
/* i18n-hint: Nyquist is the name of a programming language */
NyquistScripts = { XO("Nyquist scripts"), { wxT("ny") }, true }
/* i18n-hint: Lisp is the name of a programming language */
, LispScripts = { XO("Lisp scripts"), { wxT("lsp") }, true }
;
void NyquistEffect::OnLoad(wxCommandEvent & WXUNUSED(evt))
{
if (mCommandText->IsModified())
@ -2835,7 +2842,12 @@ void NyquistEffect::OnLoad(wxCommandEvent & WXUNUSED(evt))
XO("Load Nyquist script"),
mFileName.GetPath(),
wxEmptyString,
_("Nyquist scripts (*.ny)|*.ny|Lisp scripts (*.lsp)|*.lsp|Text files (*.txt)|*.txt|All files|*"),
{
NyquistScripts,
LispScripts,
FileNames::TextFiles,
FileNames::AllFiles
},
wxFD_OPEN | wxRESIZE_BORDER);
if (dlog.ShowModal() != wxID_OK)
@ -2858,7 +2870,11 @@ void NyquistEffect::OnSave(wxCommandEvent & WXUNUSED(evt))
XO("Save Nyquist script"),
mFileName.GetPath(),
mFileName.GetFullName(),
_("Nyquist scripts (*.ny)|*.ny|Lisp scripts (*.lsp)|*.lsp|All files|*"),
{
NyquistScripts,
LispScripts,
FileNames::AllFiles
},
wxFD_SAVE | wxFD_OVERWRITE_PROMPT | wxRESIZE_BORDER);
if (dlog.ShowModal() != wxID_OK)

View File

@ -133,9 +133,9 @@ void ExportPlugin::SetExtensions(FileExtensions extensions, int index)
mFormatInfos[index].mExtensions = std::move(extensions);
}
void ExportPlugin::SetMask(const wxString & mask, int index)
void ExportPlugin::SetMask(FileNames::FileTypes mask, int index)
{
mFormatInfos[index].mMask = mask;
mFormatInfos[index].mMask = std::move( mask );
}
void ExportPlugin::SetMaxChannels(unsigned maxchannels, unsigned index)
@ -173,22 +173,12 @@ FileExtensions ExportPlugin::GetExtensions(int index)
return mFormatInfos[index].mExtensions;
}
wxString ExportPlugin::GetMask(int index)
FileNames::FileTypes ExportPlugin::GetMask(int index)
{
if (!mFormatInfos[index].mMask.empty()) {
if (!mFormatInfos[index].mMask.empty())
return mFormatInfos[index].mMask;
}
wxString mask = GetTranslatedDescription(index) + wxT("|");
// Build the mask
// const auto &ext = GetExtension(index);
const auto &exts = GetExtensions(index);
for (size_t i = 0; i < exts.size(); i++) {
mask += wxT("*.") + exts[i] + wxT(";");
}
return mask;
return { { GetUntranslatedDescription(index), GetExtensions(index) } };
}
unsigned ExportPlugin::GetMaxChannels(int index)
@ -591,7 +581,7 @@ bool Exporter::GetFilename()
{
mFormat = -1;
wxString maskString;
FileNames::FileTypes fileTypes;
auto defaultFormat = mFormatName;
if( defaultFormat.empty() )
defaultFormat = gPrefs->Read(wxT("/Export/Format"),
@ -605,7 +595,8 @@ bool Exporter::GetFilename()
++i;
for (int j = 0; j < pPlugin->GetFormatCount(); j++)
{
maskString += pPlugin->GetMask(j) + wxT("|");
auto mask = pPlugin->GetMask(j);
fileTypes.insert( fileTypes.end(), mask.begin(), mask.end() );
if (mPlugins[i]->GetFormat(j) == defaultFormat) {
mFormat = i;
mSubFormat = j;
@ -620,7 +611,6 @@ bool Exporter::GetFilename()
mFilterIndex = 0;
mSubFormat = 0;
}
maskString.RemoveLast();
wxString defext = mPlugins[mFormat]->GetExtension(mSubFormat).Lower();
//Bug 1304: Set a default path if none was given. For Export.
@ -640,7 +630,7 @@ bool Exporter::GetFilename()
mFileDialogTitle,
mFilename.GetPath(),
useFileName.GetFullName(),
maskString,
fileTypes,
wxFD_SAVE | wxRESIZE_BORDER);
mDialog = &fd;
mDialog->PushEventHandler(this);

View File

@ -17,6 +17,7 @@
#include "audacity/Types.h"
#include "../SampleFormat.h"
#include "../widgets/wxPanelWrapper.h" // to inherit
#include "../FileNames.h" // for FileTypes
class wxArrayString;
class FileDialogWrapper;
@ -51,7 +52,7 @@ class AUDACITY_DLL_API FormatInfo
TranslatableString mDescription;
// wxString mExtension;
FileExtensions mExtensions;
wxString mMask;
FileNames::FileTypes mMask;
unsigned mMaxChannels;
bool mCanMetaData;
};
@ -71,7 +72,7 @@ public:
void SetDescription(const TranslatableString & description, int index);
void AddExtension(const FileExtension &extension, int index);
void SetExtensions(FileExtensions extensions, int index);
void SetMask(const wxString & mask, int index);
void SetMask(FileNames::FileTypes mask, int index);
void SetMaxChannels(unsigned maxchannels, unsigned index);
void SetCanMetaData(bool canmetadata, int index);
@ -85,7 +86,7 @@ public:
/** @brief Return all the file name extensions used for the sub-format.
* @param index the sub-format for which the extension is required */
virtual FileExtensions GetExtensions(int index = 0);
virtual wxString GetMask(int index);
FileNames::FileTypes GetMask(int index);
virtual unsigned GetMaxChannels(int index);
virtual bool GetCanMetaData(int index);

View File

@ -1995,6 +1995,10 @@ void ExportFFmpegOptions::OnLoadPreset(wxCommandEvent& WXUNUSED(event))
DoOnCodecList();
}
static const FileNames::FileTypes FileTypes{
FileNames::XMLFiles, FileNames::AllFiles
};
///
///
void ExportFFmpegOptions::OnImportPresets(wxCommandEvent& WXUNUSED(event))
@ -2004,7 +2008,7 @@ void ExportFFmpegOptions::OnImportPresets(wxCommandEvent& WXUNUSED(event))
XO("Select xml file with presets to import"),
gPrefs->Read(wxT("/FileFormats/FFmpegPresetDir")),
wxEmptyString,
wxString(_("XML files (*.xml)|*.xml|All files|*")),
FileTypes,
wxFD_OPEN);
if (dlg.ShowModal() == wxID_CANCEL) return;
path = dlg.GetPath();
@ -2037,7 +2041,7 @@ void ExportFFmpegOptions::OnExportPresets(wxCommandEvent& WXUNUSED(event))
XO("Select xml file to export presets into"),
gPrefs->Read(wxT("/FileFormats/FFmpegPresetDir")),
wxEmptyString,
wxString(_("XML files (*.xml)|*.xml|All files|*")),
FileTypes,
wxFD_SAVE|wxFD_OVERWRITE_PROMPT);
if (dlg.ShowModal() == wxID_CANCEL) return;
path = dlg.GetPath();

View File

@ -137,15 +137,6 @@ bool Importer::Terminate()
return true;
}
void Importer::GetSupportedImportFormats(FormatList *formatList)
{
for(const auto &importPlugin : sImportPluginList())
{
formatList->emplace_back(importPlugin->GetPluginFormatDescription(),
importPlugin->GetSupportedExtensions());
}
}
FileNames::FileTypes
Importer::GetFileTypes( const FileNames::FileType &extraType )
{
@ -159,8 +150,12 @@ Importer::GetFileTypes( const FileNames::FileType &extraType )
if ( !extraType.extensions.empty() )
fileTypes.push_back( extraType );
FormatList l;
GetSupportedImportFormats(&l);
FileNames::FileTypes l;
for(const auto &importPlugin : sImportPluginList())
{
l.emplace_back(importPlugin->GetPluginFormatDescription(),
importPlugin->GetSupportedExtensions());
}
using ExtensionSet = std::unordered_set< FileExtension >;
FileExtensions allList = extraType.extensions, newList;
@ -168,13 +163,13 @@ Importer::GetFileTypes( const FileNames::FileType &extraType )
for ( const auto &format : l ) {
newList.clear();
newSet.clear();
for ( const auto &extension : format.formatExtensions ) {
for ( const auto &extension : format.extensions ) {
if ( newSet.insert( extension ).second )
newList.push_back( extension );
if ( allSet.insert( extension ).second )
allList.push_back( extension );
}
fileTypes.push_back( { format.formatName, newList } );
fileTypes.push_back( { format.description, newList } );
}
fileTypes[1].extensions = allList;

View File

@ -30,22 +30,8 @@ class ImportFileHandle;
class UnusableImportPlugin;
typedef bool (*progress_callback_t)( void *userData, float percent );
class Format {
public:
TranslatableString formatName;
FileExtensions formatExtensions;
Format(const TranslatableString &_formatName,
FileExtensions _formatExtensions):
formatName(_formatName),
formatExtensions( std::move( _formatExtensions ) )
{
}
};
class ExtImportItem;
using FormatList = std::vector<Format> ;
using ExtImportItems = std::vector< std::unique_ptr<ExtImportItem> >;
class ExtImportItem
@ -116,11 +102,6 @@ public:
bool Initialize();
bool Terminate();
/**
* Fills @formatList with a list of supported import formats
*/
void GetSupportedImportFormats(FormatList *formatList);
/**
* Constructs a list of types, for use by file opening dialogs, that includes
* all supported file types

View File

@ -21,6 +21,7 @@
#include "../commands/CommandContext.h"
#include "../commands/CommandManager.h"
#include "../export/ExportMultiple.h"
#include "../import/Import.h"
#include "../import/ImportMIDI.h"
#include "../widgets/AudacityMessageBox.h"
#include "../widgets/FileHistory.h"
@ -373,10 +374,9 @@ void OnImport(const CommandContext &context)
// this serves to track the file if the users zooms in and such.
MissingAliasFilesDialog::SetShouldShow(true);
wxArrayString selectedFiles = ProjectFileManager::ShowOpenDialog(wxT(""));
auto selectedFiles = ProjectFileManager::ShowOpenDialog();
if (selectedFiles.size() == 0) {
gPrefs->Write(wxT("/LastOpenType"),wxT(""));
gPrefs->Flush();
Importer::SetLastOpenType({});
return;
}
@ -391,10 +391,7 @@ void OnImport(const CommandContext &context)
ODManager::Pauser pauser;
auto cleanup = finally( [&] {
gPrefs->Write(wxT("/LastOpenType"),wxT(""));
gPrefs->Flush();
Importer::SetLastOpenType({});
window.HandleResize(); // Adjust scrollers for NEW track sizes.
} );

View File

@ -158,6 +158,7 @@ public:
};
#include "../lib-src/FileDialog/FileDialog.h"
#include "../FileNames.h" // for FileTypes
class AUDACITY_DLL_API FileDialogWrapper
: public wxTabTraversalWrapper<FileDialog>
@ -171,15 +172,16 @@ public:
const TranslatableString& message,
const FilePath& defaultDir,
const FilePath& defaultFile,
const wxString& wildCard,
const FileNames::FileTypes& fileTypes,
long style = wxFD_DEFAULT_STYLE,
const wxPoint& pos = wxDefaultPosition,
const wxSize& sz = wxDefaultSize,
// Important: default window name localizes!
const TranslatableString& name = XO("File Dialog"))
: wxTabTraversalWrapper<FileDialog>(
parent, message.Translation(), defaultDir, defaultFile, wildCard, style,
pos, sz, name.Translation() )
parent, message.Translation(), defaultDir, defaultFile,
FileNames::FormatWildcard( fileTypes ),
style, pos, sz, name.Translation() )
{}
// Pseudo ctor
@ -188,7 +190,7 @@ public:
const TranslatableString& message,
const FilePath& defaultDir,
const FilePath& defaultFile,
const wxString& wildCard,
const FileNames::FileTypes& fileTypes,
long style = wxFD_DEFAULT_STYLE,
const wxPoint& pos = wxDefaultPosition,
const wxSize& sz = wxDefaultSize,
@ -196,7 +198,8 @@ public:
const TranslatableString& name = XO("File Dialog"))
{
wxTabTraversalWrapper<FileDialog>::Create(
parent, message.Translation(), defaultDir, defaultFile, wildCard,
parent, message.Translation(), defaultDir, defaultFile,
FileNames::FormatWildcard( fileTypes ),
style, pos, sz, name.Translation()
);
}