AUP3: Update default/lastused path handling

This commit is contained in:
Leland Lucius 2020-07-27 14:11:50 -05:00
parent 757bc0b183
commit e2d6e1cc24
15 changed files with 299 additions and 173 deletions

View File

@ -800,7 +800,7 @@ bool AudacityApp::MRUOpen(const FilePath &fullPathStr) {
// verify that the file exists
if (wxFile::Exists(fullPathStr))
{
FileNames::UpdateDefaultPath(FileNames::Operation::Open, fullPathStr);
FileNames::UpdateDefaultPath(FileNames::Operation::Open, ::wxPathOnly(fullPathStr));
// Make sure it isn't already open.
// Test here even though AudacityProject::OpenFile() also now checks, because
@ -1574,8 +1574,7 @@ void SetToExtantDirectory( wxString & result, const wxString & dir ){
bool AudacityApp::InitTempDir()
{
// We need to find a temp directory location.
wxString tempFromPrefs = gPrefs->Read(wxT("/Directories/TempDir"), wxT(""));
auto tempFromPrefs = FileNames::TempDir();
auto tempDefaultLoc = FileNames::DefaultTempDir();
wxString temp;
@ -1638,13 +1637,13 @@ bool AudacityApp::InitTempDir()
chmod(OSFILENAME(temp), 0755);
#endif
bool bSuccess = gPrefs->Write(wxT("/Directories/TempDir"), temp) && gPrefs->Flush();
FileNames::UpdateDefaultPath(FileNames::Operation::Temp, temp);
// Make sure the temp dir isn't locked by another process.
if (!CreateSingleInstanceChecker(temp))
return false;
return bSuccess;
return true;
}
#if defined(__WXMSW__)

View File

@ -202,7 +202,7 @@ wxString FileNames::MkDir(const wxString &Str)
/// each time.
wxString FileNames::TempDir()
{
return FileNames::MkDir(gPrefs->Read(wxT("/Directories/TempDir"), wxT("")));
return FileNames::MkDir(gPrefs->Read(PreferenceKey(Operation::Temp, PathType::_None), wxT("")));
}
// originally an ExportMultipleDialog method. Append suffix if newName appears in otherNames.
@ -509,44 +509,82 @@ wxFileNameWrapper FileNames::DefaultToDocumentsFolder(const wxString &preference
return result;
}
namespace {
wxString PreferenceKey(FileNames::Operation op)
{
wxString key;
switch (op) {
case FileNames::Operation::Open:
key = wxT("/DefaultOpenPath"); break;
case FileNames::Operation::Export:
key = wxT("/DefaultExportPath"); break;
case FileNames::Operation::_None:
default:
break;
}
return key;
wxString FileNames::PreferenceKey(FileNames::Operation op, FileNames::PathType type)
{
wxString key;
switch (op) {
case FileNames::Operation::Temp:
key = wxT("/Directories/TempDir"); break;
case FileNames::Operation::Presets:
key = wxT("/Presets/Path"); break;
case FileNames::Operation::Open:
key = wxT("/Directories/Open"); break;
case FileNames::Operation::Save:
key = wxT("/Directories/Save"); break;
case FileNames::Operation::Import:
key = wxT("/Directories/Import"); break;
case FileNames::Operation::Export:
key = wxT("/Directories/Export"); break;
case FileNames::Operation::_None:
default:
break;
}
switch (type) {
case FileNames::PathType::User:
key += "/Default"; break;
case FileNames::PathType::LastUsed:
key += "/LastUsed"; break;
case FileNames::PathType::_None:
default:
break;
}
return key;
}
wxString FileNames::FindDefaultPath(Operation op)
FilePath FileNames::FindDefaultPath(Operation op)
{
auto key = PreferenceKey(op);
auto key = PreferenceKey(op, PathType::User);
if (key.empty())
return wxString{};
else
return DefaultToDocumentsFolder(key).GetPath();
// If the user specified a default path, then use that
FilePath path = gPrefs->Read(key, wxT(""));
if (!path.empty()) {
return path;
}
// Maybe the last used path is available
key = PreferenceKey(op, PathType::LastUsed);
path = gPrefs->Read(key, wxT(""));
if (!path.empty()) {
return path;
}
// Last resort is to simply return the default folder
return DefaultToDocumentsFolder("").GetPath();
}
void FileNames::UpdateDefaultPath(Operation op, const FilePath &path)
{
if (path.empty())
return;
auto key = PreferenceKey(op);
if (!key.empty()) {
gPrefs->Write(key, ::wxPathOnly(path));
wxString key;
if (op == Operation::Temp) {
key = PreferenceKey(op, PathType::_None);
}
else {
key = PreferenceKey(op, PathType::LastUsed);
}
if (!key.empty()) {
gPrefs->Write(key, path);
gPrefs->Flush();
}
}
wxString
FilePath
FileNames::SelectFile(Operation op,
const TranslatableString& message,
const FilePath& default_path,

View File

@ -133,27 +133,44 @@ namespace FileNames
enum class Operation {
// _ on None to defeat some macro that is expanding this.
_None,
// These do not have a specific pathtype
Temp,
Presets,
// These have default/lastused pathtypes
Open,
Save,
Import,
Export
};
wxString FindDefaultPath(Operation op);
enum class PathType {
// _ on None to defeat some macro that is expanding this.
_None,
User,
LastUsed
};
wxString PreferenceKey(FileNames::Operation op, FileNames::PathType type);
FilePath FindDefaultPath(Operation op);
void UpdateDefaultPath(Operation op, const FilePath &path);
// F is a function taking a wxString, returning wxString
template<typename F>
wxString WithDefaultPath
FilePath WithDefaultPath
(Operation op, const FilePath &defaultPath, F function)
{
auto path = defaultPath;
auto path = gPrefs->Read(PreferenceKey(op, PathType::User), defaultPath);
if (path.empty())
path = FileNames::FindDefaultPath(op);
auto result = function(path);
FileNames::UpdateDefaultPath(op, result);
FileNames::UpdateDefaultPath(op, ::wxPathOnly(result));
return result;
}
wxString
FilePath
SelectFile(Operation op, // op matters only when default_path is empty
const TranslatableString& message,
const FilePath& default_path,

View File

@ -391,11 +391,11 @@ bool ProjectFileManager::SaveAs()
auto &projectFileIO = ProjectFileIO::Get( project );
auto &window = GetProjectFrame( project );
TitleRestorer Restorer( window, project ); // RAII
bool bHasPath = true;
wxFileName filename;
FilePath defaultSavePath = FileNames::FindDefaultPath(FileNames::Operation::Save);
if (projectFileIO.IsTemporary()) {
filename = FileNames::DefaultToDocumentsFolder(wxT("/SaveAs/Path"));
filename.SetPath(defaultSavePath);
filename.SetName(project.GetProjectName());
}
else {
@ -404,8 +404,7 @@ bool ProjectFileManager::SaveAs()
// Bug 1304: Set a default file path if none was given. For Save/SaveAs/SaveCopy
if( !FileNames::IsPathAvailable( filename.GetPath( wxPATH_GET_VOLUME| wxPATH_GET_SEPARATOR) ) ){
bHasPath = false;
filename.SetPath(FileNames::DefaultToDocumentsFolder(wxT("/SaveAs/Path")).GetPath());
filename.SetPath(defaultSavePath);
}
TranslatableString title = XO("%sSave Project \"%s\" As...")
@ -414,8 +413,7 @@ bool ProjectFileManager::SaveAs()
'Save Project' is for an Audacity project, not an audio file.\n\
For an audio file that will open in other apps, use 'Export'.\n");
if (ShowWarningDialog(&window, wxT("FirstProjectSave"), message, true) != wxID_OK)
{
if (ShowWarningDialog(&window, wxT("FirstProjectSave"), message, true) != wxID_OK) {
return false;
}
@ -427,7 +425,7 @@ For an audio file that will open in other apps, use 'Export'.\n");
if (bPrompt) {
// JKC: I removed 'wxFD_OVERWRITE_PROMPT' because we are checking
// for overwrite ourselves later, and we disallow it.
fName = FileNames::SelectFile(FileNames::Operation::Export,
fName = FileNames::SelectFile(FileNames::Operation::Save,
title,
filename.GetPath(),
filename.GetFullName(),
@ -500,8 +498,7 @@ For an audio file that will open in other apps, use 'Export'.\n");
return false;
}
}
else
{
else {
// Overwrite disallowed. The destination project is open in another window.
AudacityMessageDialog m(
nullptr,
@ -520,11 +517,6 @@ For an audio file that will open in other apps, use 'Export'.\n");
auto success = DoSave(fName, !bOwnsNewName);
if (success) {
FileHistory::Global().Append( projectFileIO.GetFileName() );
if( !bHasPath )
{
gPrefs->Write( wxT("/SaveAs/Path"), filename.GetPath());
gPrefs->Flush();
}
}
return(success);
@ -537,12 +529,13 @@ bool ProjectFileManager::SaveCopy(const FilePath &fileName /* = wxT("") */)
auto &window = GetProjectFrame(project);
TitleRestorer Restorer(window, project); // RAII
wxFileName filename = fileName;
FilePath defaultSavePath = FileNames::FindDefaultPath(FileNames::Operation::Save);
if (fileName.empty())
{
if (projectFileIO.IsTemporary())
{
filename = FileNames::DefaultToDocumentsFolder(wxT("/SaveAs/Path"));
filename.SetPath(defaultSavePath);
}
else
{
@ -553,7 +546,7 @@ bool ProjectFileManager::SaveCopy(const FilePath &fileName /* = wxT("") */)
// Bug 1304: Set a default file path if none was given. For Save/SaveAs/SaveCopy
if (!FileNames::IsPathAvailable(filename.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR)))
{
filename.SetPath(FileNames::DefaultToDocumentsFolder(wxT("/SaveAs/Path")).GetPath());
filename.SetPath(defaultSavePath);
}
TranslatableString title =
@ -728,14 +721,14 @@ void ProjectFileManager::CloseProject()
}
// static method, can be called outside of a project
wxArrayString ProjectFileManager::ShowOpenDialog(
wxArrayString ProjectFileManager::ShowOpenDialog(FileNames::Operation op,
const FileNames::FileType &extraType )
{
// Construct the filter
const auto fileTypes = Importer::Get().GetFileTypes( extraType );
// Retrieve saved path
auto path = FileNames::FindDefaultPath(FileNames::Operation::Open);
auto path = FileNames::FindDefaultPath(op);
// Construct and display the file dialog
wxArrayString selected;
@ -761,7 +754,11 @@ wxArrayString ProjectFileManager::ShowOpenDialog(
if (dialogResult == wxID_OK) {
// Return the selected files
dlog.GetPaths(selected);
// Remember the directory
FileNames::UpdateDefaultPath(op, ::wxPathOnly(dlog.GetPath()));
}
return selected;
}

View File

@ -84,7 +84,7 @@ public:
* @return Array of file paths which the user selected to open (multiple
* selections allowed).
*/
static wxArrayString ShowOpenDialog(
static wxArrayString ShowOpenDialog(FileNames::Operation op,
const FileNames::FileType &extraType = {});
static bool IsAlreadyOpen(const FilePath &projPathName);

View File

@ -840,7 +840,7 @@ void ProjectManager::OnOpenAudioFile(wxCommandEvent & event)
void ProjectManager::OpenFiles(AudacityProject *proj)
{
auto selectedFiles =
ProjectFileManager::ShowOpenDialog();
ProjectFileManager::ShowOpenDialog(FileNames::Operation::Open);
if (selectedFiles.size() == 0) {
Importer::SetLastOpenType({});
return;
@ -860,8 +860,6 @@ void ProjectManager::OpenFiles(AudacityProject *proj)
if (ProjectFileManager::IsAlreadyOpen(fileName))
continue; // Skip ones that are already open.
FileNames::UpdateDefaultPath(FileNames::Operation::Open, fileName);
// DMM: If the project is dirty, that means it's been touched at
// all, and it's not safe to open a NEW project directly in its
// place. Only if the project is brand-NEW clean and the user

View File

@ -54,7 +54,7 @@ bool ImportCommand::Apply(const CommandContext & context){
bool ExportCommand::DefineParams( ShuttleParams & S ){
wxFileName fn = FileNames::DefaultToDocumentsFolder(wxT("/Export/Path"));
wxFileName fn = FileNames::FindDefaultPath(FileNames::Operation::Export);
fn.SetName("exported.wav");
S.Define(mFileName, wxT("Filename"), fn.GetFullPath());
S.Define( mnChannels, wxT("NumChannels"), 1 );

View File

@ -679,28 +679,24 @@ void Effect::ExportPresets()
wxString commandId = GetSquashedName(GetSymbol().Internal()).GET();
params = commandId + ":" + params;
auto path = FileNames::DefaultToDocumentsFolder(wxT("Presets/Path"));
FileDialogWrapper dlog(nullptr,
XO("Export Effect Parameters"),
path.GetFullPath(),
wxEmptyString,
PresetTypes(),
wxFD_SAVE | wxFD_OVERWRITE_PROMPT | wxRESIZE_BORDER);
if (dlog.ShowModal() != wxID_OK) {
auto path = FileNames::SelectFile(FileNames::Operation::Presets,
XO("Export Effect Parameters"),
wxEmptyString,
wxEmptyString,
wxEmptyString,
PresetTypes(),
wxFD_SAVE | wxFD_OVERWRITE_PROMPT | wxRESIZE_BORDER,
nullptr);
if (path.empty()) {
return;
}
path = dlog.GetPath();
gPrefs->Write(wxT("Presets/Path"), path.GetPath());
// Create/Open the file
wxFFile f(path.GetFullPath(), wxT("wb"));
wxFFile f(path, wxT("wb"));
if (!f.IsOpened())
{
AudacityMessageBox(
XO("Could not open file: \"%s\"").Format( path.GetFullPath() ),
XO("Could not open file: \"%s\"").Format( path ),
XO("Error Saving Effect Presets"),
wxICON_EXCLAMATION,
NULL);
@ -711,7 +707,7 @@ void Effect::ExportPresets()
if (f.Error())
{
AudacityMessageBox(
XO("Error writing to file: \"%s\"").Format( path.GetFullPath() ),
XO("Error writing to file: \"%s\"").Format( path ),
XO("Error Saving Effect Presets"),
wxICON_EXCLAMATION,
NULL);
@ -728,26 +724,19 @@ void Effect::ImportPresets()
{
wxString params;
auto path = FileNames::DefaultToDocumentsFolder(wxT("Presets/Path"));
FileDialogWrapper dlog(nullptr,
XO("Import Effect Parameters"),
path.GetPath(),
wxEmptyString,
PresetTypes(),
wxFD_OPEN | wxRESIZE_BORDER);
if (dlog.ShowModal() != wxID_OK) {
auto path = FileNames::SelectFile(FileNames::Operation::Presets,
XO("Import Effect Parameters"),
wxEmptyString,
wxEmptyString,
wxEmptyString,
PresetTypes(),
wxFD_OPEN | wxRESIZE_BORDER,
nullptr);
if (path.empty()) {
return;
}
path = dlog.GetPath();
if( !path.IsOk())
return;
gPrefs->Write(wxT("Presets/Path"), path.GetPath());
wxFFile f(path.GetFullPath());
wxFFile f(path);
if (f.IsOpened()) {
if (f.ReadAll(&params)) {
wxString ident = params.BeforeFirst(':');
@ -763,14 +752,14 @@ void Effect::ImportPresets()
Effect::MessageBox(
/* i18n-hint %s will be replaced by a file name */
XO("%s: is not a valid presets file.\n")
.Format(path.GetFullName()));
.Format(wxFileNameFromPath(path)));
}
else
{
Effect::MessageBox(
/* i18n-hint %s will be replaced by a file name */
XO("%s: is for a different Effect, Generator or Analyzer.\n")
.Format(path.GetFullName()));
.Format(wxFileNameFromPath(path)));
}
return;
}

View File

@ -3211,8 +3211,8 @@ void NyquistEffect::resolveFilePath(wxString& path, FileExtension extension /* e
{"*home*", wxGetHomeDir()},
{"~", wxGetHomeDir()},
{"*default*", FileNames::DefaultToDocumentsFolder("").GetPath()},
{"*export*", FileNames::DefaultToDocumentsFolder(wxT("/Export/Path")).GetPath()},
{"*save*", FileNames::DefaultToDocumentsFolder(wxT("/SaveAs/Path")).GetPath()},
{"*export*", FileNames::FindDefaultPath(FileNames::Operation::Export)},
{"*save*", FileNames::FindDefaultPath(FileNames::Operation::Save)},
{"*config*", FileNames::DataDir()}
};

View File

@ -631,7 +631,7 @@ bool Exporter::GetFilename()
wxString defext = mPlugins[mFormat]->GetExtension(mSubFormat).Lower();
//Bug 1304: Set a default path if none was given. For Export.
mFilename = FileNames::DefaultToDocumentsFolder(wxT("/Export/Path"));
mFilename.SetPath(FileNames::FindDefaultPath(FileNames::Operation::Export));
mFilename.SetName(mProject->GetProjectName());
if (mFilename.GetName().empty())
mFilename.SetName(_("untitled"));
@ -776,8 +776,8 @@ bool Exporter::CheckFilename()
{
if( mFormatName.empty() )
gPrefs->Write(wxT("/Export/Format"), mPlugins[mFormat]->GetFormat(mSubFormat));
gPrefs->Write(wxT("/Export/Path"), mFilename.GetPath());
gPrefs->Flush();
FileNames::UpdateDefaultPath(FileNames::Operation::Export, mFilename.GetPath());
//
// To be even safer, return a temporary file name based

View File

@ -255,8 +255,7 @@ void ExportMultipleDialog::PopulateOrExchange(ShuttleGui& S)
// Bug 1304: Set the default file path. It's used if none stored in config.
auto filename = FileNames::DefaultToDocumentsFolder(wxT("/Export/Path"));
wxString DefaultPath = filename.GetPath();
auto DefaultPath = FileNames::FindDefaultPath(FileNames::Operation::Export);
if (mPluginIndex == -1)
{
@ -274,9 +273,8 @@ void ExportMultipleDialog::PopulateOrExchange(ShuttleGui& S)
S.StartMultiColumn(4, true);
{
mDir = S.Id(DirID)
.TieTextBox(XXO("Folder:"),
{wxT("/Export/MultiplePath"),
DefaultPath},
.AddTextBox(XXO("Folder:"),
DefaultPath,
64);
S.Id(ChooseID).AddButton(XXO("Choose..."));
S.Id(CreateID).AddButton(XXO("Create"));
@ -573,6 +571,8 @@ void ExportMultipleDialog::OnExport(wxCommandEvent& WXUNUSED(event))
gPrefs->Flush();
FileNames::UpdateDefaultPath(FileNames::Operation::Export, mDir->GetValue());
// Make sure the output directory is in good shape
if (!DirOk()) {
return;

View File

@ -399,7 +399,7 @@ void OnImport(const CommandContext &context)
auto &project = context.project;
auto &window = ProjectWindow::Get( project );
auto selectedFiles = ProjectFileManager::ShowOpenDialog();
auto selectedFiles = ProjectFileManager::ShowOpenDialog(FileNames::Operation::Import);
if (selectedFiles.size() == 0) {
Importer::SetLastOpenType({});
return;
@ -420,7 +420,7 @@ void OnImport(const CommandContext &context)
for (size_t ff = 0; ff < selectedFiles.size(); ff++) {
wxString fileName = selectedFiles[ff];
FileNames::UpdateDefaultPath(FileNames::Operation::Open, fileName);
FileNames::UpdateDefaultPath(FileNames::Operation::Import, ::wxPathOnly(fileName));
ProjectFileManager::Get( project ).Import(fileName);
}

View File

@ -375,12 +375,10 @@ struct Handler : CommandHandlerObject {
void OnResetConfig(const CommandContext &context)
{
auto &project = context.project;
//wxString dir = gPrefs->Read("/Directories/TempDir");
gPrefs->DeleteAll();
// Directory will be reset on next restart.
wxString dir = FileNames::DefaultTempDir();
gPrefs->Write("/Directories/TempDir", dir);
FileNames::UpdateDefaultPath(FileNames::Operation::Temp, FileNames::DefaultTempDir());
gPrefs->Write("/GUI/SyncLockTracks", 0);
gPrefs->Write("/SnapTo", 0 );
ProjectSelectionManager::Get( project ).AS_SetSnapTo( 0 );

View File

@ -37,21 +37,39 @@
#include "../ShuttleGui.h"
#include "../widgets/AudacityMessageBox.h"
enum {
TempDirID = 1000,
ChooseButtonID
using namespace FileNames;
enum
{
TempTextID = 1000,
TempButtonID,
TextsStart = 1010,
OpenTextID,
SaveTextID,
ImportTextID,
ExportTextID,
TextsEnd,
ButtonsStart = 1020,
OpenButtonID,
SaveButtonID,
ImportButtonID,
ExportButtonID,
ButtonsEnd
};
BEGIN_EVENT_TABLE(DirectoriesPrefs, PrefsPanel)
EVT_TEXT(TempDirID, DirectoriesPrefs::UpdateFreeSpace)
EVT_BUTTON(ChooseButtonID, DirectoriesPrefs::OnChooseTempDir)
EVT_TEXT(TempTextID, DirectoriesPrefs::OnTempText)
EVT_BUTTON(TempButtonID, DirectoriesPrefs::OnTempBrowse)
EVT_COMMAND_RANGE(ButtonsStart, ButtonsEnd, wxEVT_BUTTON, DirectoriesPrefs::OnBrowse)
END_EVENT_TABLE()
DirectoriesPrefs::DirectoriesPrefs(wxWindow * parent, wxWindowID winid)
/* i18n-hint: Directories, also called folders, in computer file systems */
: PrefsPanel(parent, winid, XO("Directories")),
mFreeSpace(NULL),
mTempDir(NULL)
mTempText(NULL)
{
Populate();
}
@ -60,7 +78,6 @@ DirectoriesPrefs::~DirectoriesPrefs()
{
}
ComponentInterfaceSymbol DirectoriesPrefs::GetSymbol()
{
return DIRECTORIES_PREFS_PLUGIN_SYMBOL;
@ -88,59 +105,96 @@ void DirectoriesPrefs::Populate()
// ----------------------- End of main section --------------
wxCommandEvent e;
UpdateFreeSpace(e);
OnTempText(e);
}
void DirectoriesPrefs::PopulateOrExchange(ShuttleGui & S)
void DirectoriesPrefs::PopulateOrExchange(ShuttleGui &S)
{
S.SetBorder(2);
S.StartScroller();
S.StartStatic(XO("Temporary files directory"));
{
S.StartMultiColumn(2, wxEXPAND);
S.StartMultiColumn(3, wxEXPAND);
{
S.SetStretchyCol(1);
S.Id(TempDirID);
mTempDir = S.TieTextBox(XXO("&Location:"),
{wxT("/Directories/TempDir"),
wxT("")},
30);
S.Id(TempTextID);
mTempText = S.TieTextBox(XXO("&Location:"),
{PreferenceKey(Operation::Temp, PathType::_None),
wxT("")},
30);
S.Id(TempButtonID).AddButton(XXO("B&rowse..."));
S.AddPrompt(XXO("Free Space:"));
mFreeSpace = S.Style(wxTE_READONLY).AddTextBox({}, wxT(""), 30);
mFreeSpace->SetName(XO("Free Space").Translation());
}
S.EndMultiColumn();
S.StartHorizontalLay(wxEXPAND);
{
S.Prop(0).AddFixedText(XO("Free Space:"));
mFreeSpace = S.Prop(0).AddVariableText( {} );
S.Prop(10).AddSpace( 10 );
S.Id(ChooseButtonID).Prop(0).AddButton(XXO("C&hoose..."));
}
}
S.EndStatic();
S.StartStatic(XO("Default folders (\"last used\" if not specified)"));
{
S.StartMultiColumn(3, wxEXPAND);
{
S.SetStretchyCol(1);
S.Id(OpenTextID);
mOpenText = S.TieTextBox(XXO("&Open:"),
{PreferenceKey(Operation::Open, PathType::User),
wxT("")},
30);
S.Id(OpenButtonID).AddButton(XXO("Browse..."));
S.Id(SaveTextID);
mSaveText = S.TieTextBox(XXO("&Save:"),
{PreferenceKey(Operation::Save, PathType::User),
wxT("")},
30);
S.Id(SaveButtonID).AddButton(XXO("Browse..."));
S.Id(ImportTextID);
mImportText = S.TieTextBox(XXO("&Import:"),
{PreferenceKey(Operation::Import, PathType::User),
wxT("")},
30);
S.Id(ImportButtonID).AddButton(XXO("Browse..."));
S.Id(ExportTextID);
mExportText = S.TieTextBox(XXO("&Export:"),
{PreferenceKey(Operation::Export, PathType::User),
wxT("")},
30);
S.Id(ExportButtonID).AddButton(XXO("Browse..."));
}
S.EndMultiColumn();
}
S.EndStatic();
S.EndScroller();
}
void DirectoriesPrefs::OnChooseTempDir(wxCommandEvent & e)
void DirectoriesPrefs::OnTempBrowse(wxCommandEvent &evt)
{
wxString oldTempDir =
gPrefs->Read(wxT("/Directories/TempDir"), FileNames::DefaultTempDir());
wxString oldTemp = gPrefs->Read(PreferenceKey(Operation::Open, PathType::_None),
DefaultTempDir());
// Because we went through InitTempDir() during initialisation,
// Because we went through InitTemp() during initialisation,
// the old temp directory name in prefs should already be OK. Just in case there is
// some way we hadn't thought of for it to be not OK,
// we avoid prompting with it in that case and use the suggested default instead.
if( !FileNames::IsTempDirectoryNameOK( oldTempDir ) )
oldTempDir = FileNames::DefaultTempDir();
if (!IsTempDirectoryNameOK(oldTemp))
{
oldTemp = DefaultTempDir();
}
wxDirDialogWrapper dlog(this,
XO("Choose a location to place the temporary directory"),
oldTempDir );
XO("Choose a location to place the temporary directory"),
oldTemp);
int retval = dlog.ShowModal();
if (retval != wxID_CANCEL && !dlog.GetPath().empty()) {
if (retval != wxID_CANCEL && !dlog.GetPath().empty())
{
wxFileName tmpDirPath;
tmpDirPath.AssignDir(dlog.GetPath());
@ -162,50 +216,74 @@ void DirectoriesPrefs::OnChooseTempDir(wxCommandEvent & e)
// If the default temp dir or user's pref dir don't end in '/' they cause
// wxFileName's == operator to construct a wxFileName representing a file
// (that doesn't exist) -- hence the constructor calls
if (tmpDirPath != wxFileName(FileNames::DefaultTempDir(), wxT("")) &&
tmpDirPath != wxFileName(mTempDir->GetValue(), wxT("")) &&
if (tmpDirPath != wxFileName(DefaultTempDir(), wxT("")) &&
tmpDirPath != wxFileName(mTempText->GetValue(), wxT("")) &&
(dirsInPath.size() == 0 ||
dirsInPath[dirsInPath.size()-1] != newDirName))
{
tmpDirPath.AppendDir(newDirName);
}
mTempDir->SetValue(tmpDirPath.GetPath(wxPATH_GET_VOLUME|wxPATH_GET_SEPARATOR));
UpdateFreeSpace(e);
mTempText->SetValue(tmpDirPath.GetPath(wxPATH_GET_VOLUME|wxPATH_GET_SEPARATOR));
OnTempText(evt);
}
}
void DirectoriesPrefs::UpdateFreeSpace(wxCommandEvent & WXUNUSED(event))
void DirectoriesPrefs::OnTempText(wxCommandEvent & WXUNUSED(evt))
{
wxString tempDir;
wxString Temp;
TranslatableString label;
if (mTempDir != NULL) {
tempDir = mTempDir->GetValue();
if (mTempText != NULL)
{
Temp = mTempText->GetValue();
}
if (wxDirExists(tempDir)) {
if (wxDirExists(Temp))
{
wxLongLong space;
wxGetDiskSpace(tempDir, NULL, &space);
wxGetDiskSpace(Temp, NULL, &space);
label = Internat::FormatSize(space);
}
else {
else
{
label = XO("unavailable - above location doesn't exist");
}
if( mFreeSpace != NULL ) {
if (mFreeSpace != NULL)
{
mFreeSpace->SetLabel(label.Translation());
mFreeSpace->SetName(label.Translation()); // fix for bug 577 (NVDA/Narrator screen readers do not read static text in dialogs)
}
}
void DirectoriesPrefs::OnBrowse(wxCommandEvent &evt)
{
long id = evt.GetId() - ButtonsStart;
wxTextCtrl *tc = (wxTextCtrl *) FindWindow(id + TextsStart);
wxString location = tc->GetValue();
wxDirDialogWrapper dlog(this,
XO("Choose a location"),
location);
int retval = dlog.ShowModal();
if (retval == wxID_CANCEL)
{
return;
}
tc->SetValue(dlog.GetPath());
}
bool DirectoriesPrefs::Validate()
{
wxFileName tempDir;
tempDir.SetPath(mTempDir->GetValue());
wxFileName Temp;
Temp.SetPath(mTempText->GetValue());
wxString path{tempDir.GetPath()};
if( !FileNames::IsTempDirectoryNameOK( path ) ) {
wxString path{Temp.GetPath()};
if( !IsTempDirectoryNameOK( path ) ) {
AudacityMessageBox(
XO("Directory %s is not suitable (at risk of being cleaned out)")
.Format( path ),
@ -213,7 +291,7 @@ bool DirectoriesPrefs::Validate()
wxOK | wxICON_ERROR);
return false;
}
if (!tempDir.DirExists()) {
if (!Temp.DirExists()) {
int ans = AudacityMessageBox(
XO("Directory %s does not exist. Create it?")
.Format( path ),
@ -224,7 +302,7 @@ bool DirectoriesPrefs::Validate()
return false;
}
if (!tempDir.Mkdir(0755, wxPATH_MKDIR_FULL)) {
if (!Temp.Mkdir(0755, wxPATH_MKDIR_FULL)) {
/* wxWidgets throws up a decent looking dialog */
return false;
}
@ -232,9 +310,9 @@ bool DirectoriesPrefs::Validate()
else {
/* If the directory already exists, make sure it is writable */
wxLogNull logNo;
tempDir.AppendDir(wxT("canicreate"));
path = tempDir.GetPath();
if (!tempDir.Mkdir(0755)) {
Temp.AppendDir(wxT("canicreate"));
path = Temp.GetPath();
if (!Temp.Mkdir(0755)) {
AudacityMessageBox(
XO("Directory %s is not writable")
.Format( path ),
@ -242,13 +320,13 @@ bool DirectoriesPrefs::Validate()
wxOK | wxICON_ERROR);
return false;
}
tempDir.Rmdir();
tempDir.RemoveLastDir();
Temp.Rmdir();
Temp.RemoveLastDir();
}
wxFileName oldDir;
oldDir.SetPath(gPrefs->Read(wxT("/Directories/TempDir")));
if (tempDir != oldDir) {
oldDir.SetPath(FileNames::TempDir());
if (Temp != oldDir) {
AudacityMessageBox(
XO(
"Changes to temporary directory will not take effect until Audacity is restarted"),
@ -268,7 +346,8 @@ bool DirectoriesPrefs::Commit()
}
PrefsPanel::Factory
DirectoriesPrefsFactory() {
DirectoriesPrefsFactory()
{
return [](wxWindow *parent, wxWindowID winid, AudacityProject *)
{
wxASSERT(parent); // to justify safenew
@ -276,8 +355,12 @@ DirectoriesPrefsFactory() {
};
}
namespace{
PrefsPanel::Registration sAttachment{ "Directories",
DirectoriesPrefsFactory() };
namespace
{
PrefsPanel::Registration sAttachment
{
"Directories",
DirectoriesPrefsFactory()
};
};

View File

@ -31,15 +31,22 @@ class DirectoriesPrefs final : public PrefsPanel
bool Commit() override;
bool Validate() override;
wxString HelpPageName() override;
void PopulateOrExchange(ShuttleGui & S) override;
void PopulateOrExchange(ShuttleGui &S) override;
private:
void Populate();
void UpdateFreeSpace(wxCommandEvent & e);
void OnChooseTempDir(wxCommandEvent & e);
wxStaticText *mFreeSpace;
wxTextCtrl *mTempDir;
void OnTempText(wxCommandEvent &evt);
void OnTempBrowse(wxCommandEvent &evt);
void OnBrowse(wxCommandEvent &evt);
wxTextCtrl *mFreeSpace;
wxTextCtrl *mTempText;
wxTextCtrl *mOpenText;
wxTextCtrl *mSaveText;
wxTextCtrl *mImportText;
wxTextCtrl *mExportText;
DECLARE_EVENT_TABLE()
};