Audacity 3.2.0
FileNames.cpp
Go to the documentation of this file.
1/**********************************************************************
2
3 Audacity: A Digital Audio Editor
4
5 FileNames.cpp
6
7 James Crook
8
9********************************************************************//********************************************************************/
22
23#include "FileNames.h"
24
25
26
27#include <memory>
28
29#include <wx/defs.h>
30#include <wx/filename.h>
31#include <wx/stdpaths.h>
32#include <wx/utils.h>
33#include "BasicUI.h"
34#include "Prefs.h"
35#include "Internat.h"
36#include "ModuleConstants.h"
38#include "wxFileNameWrapper.h"
39
40#if defined(__WXMAC__) || defined(__WXGTK__)
41#include <dlfcn.h>
42#endif
43
44#if defined(__WXMSW__)
45#include <windows.h>
46#endif
47
49 FileNames::AllFiles{ XO("All files"), { wxT("") } }
50 /* i18n-hint an Audacity project is the state of the program, stored as
51 files that can be reopened to resume the session later */
52 , FileNames::AudacityProjects{ XO("AUP3 project files"), { wxT("aup3") }, true }
54#if defined(__WXMSW__)
55 XO("Dynamically Linked Libraries"), { wxT("dll") }, true
56#elif defined(__WXMAC__)
57 XO("Dynamic Libraries"), { wxT("dylib") }, true
58#else
59 XO("Dynamically Linked Libraries"), { wxT("so*") }, true
60#endif
61 }
62 , FileNames::TextFiles{ XO("Text files"), { wxT("txt") }, true }
63 , FileNames::XMLFiles{ XO("XML files"), { wxT("xml"), wxT("XML") }, true }
64;
65
66wxString FileNames::FormatWildcard( const FileTypes &fileTypes )
67{
68 // |-separated list of:
69 // [ Description,
70 // ( if appendExtensions, then ' (', globs, ')' ),
71 // '|',
72 // globs ]
73 // where globs is a ;-separated list of filename patterns, which are
74 // '*' for an empty extension, else '*.' then the extension
75 // Only the part before | is displayed in the choice drop-down of file
76 // dialogs
77 //
78 // Exceptional case: if there is only one type and its description is empty,
79 // then just give the globs with no |
80 // Another exception: an empty description, when there is more than one
81 // type, is replaced with a default
82 // Another exception: if an extension contains a dot, it is interpreted as
83 // not really an extension, but a literal filename
84
85 const wxString dot{ '.' };
86 const auto makeGlobs = [&dot]( const FileExtensions &extensions ){
87 wxString globs;
88 for ( const auto &extension: extensions ) {
89 if ( !globs.empty() )
90 globs += ';';
91 if ( extension.Contains( dot ) )
92 globs += extension;
93 else {
94 globs += '*';
95 if ( !extension.empty() ) {
96 globs += '.';
97 globs += extension;
98 }
99 }
100 }
101 return globs;
102 };
103
104 const auto defaultDescription = []( const FileExtensions &extensions ){
105 // Assume extensions is not empty
106 wxString exts = extensions[0];
107 for (size_t ii = 1, size = extensions.size(); ii < size; ++ii ) {
108 exts += XO(", ").Translation();
109 exts += extensions[ii];
110 }
111 /* i18n-hint a type or types such as "txt" or "txt, xml" will be
112 substituted for %s */
113 return XO("%s files").Format( exts );
114 };
115
116 if ( fileTypes.size() == 1 && fileTypes[0].description.empty() ) {
117 return makeGlobs( fileTypes[0].extensions );
118 }
119 else {
120 wxString result;
121 for ( const auto &fileType : fileTypes ) {
122 const auto &extensions = fileType.extensions;
123 if (extensions.empty())
124 continue;
125
126 if (!result.empty())
127 result += '|';
128
129 const auto globs = makeGlobs( extensions );
130
131 auto mask = fileType.description;
132 if ( mask.empty() )
133 mask = defaultDescription( extensions );
134 if ( fileType.appendExtensions )
135 mask.Join( XO("(%s)").Format( globs ), " " );
136 result += mask.Translation();
137 result += '|';
138 result += globs;
139 }
140 return result;
141 }
142}
143
145 const FilePath& file1, const FilePath& file2, bool overwrite)
146{
147#ifdef __WXMSW__
148
149 // workaround not needed
150 return wxCopyFile(file1, file2, overwrite);
151
152#else
153 // PRL: Compensate for buggy wxCopyFile that returns false success,
154 // which was a cause of case 4 in comment 10 of
155 // http://bugzilla.audacityteam.org/show_bug.cgi?id=1759
156 // Destination file was created, but was empty
157 // Bug was introduced after wxWidgets 2.8.12 at commit
158 // 0597e7f977c87d107e24bf3e95ebfa3d60efc249 of wxWidgets repo
159
160 bool existed = wxFileExists(file2);
161 bool result = wxCopyFile(file1, file2, overwrite) &&
162 wxFile{ file1 }.Length() == wxFile{ file2 }.Length();
163 if (!result && !existed)
164 wxRemoveFile(file2);
165 return result;
166
167#endif
168}
169
170bool FileNames::HardLinkFile( const FilePath& file1, const FilePath& file2 )
171{
172#ifdef __WXMSW__
173
174 // Fix forced ASCII conversions and wrong argument order - MJB - 29/01/2019
175 //return ::CreateHardLinkA( file1.c_str(), file2.c_str(), NULL );
176 return ( 0 != ::CreateHardLink( file2, file1, NULL ) );
177
178#else
179
180 return 0 == ::link( file1.c_str(), file2.c_str() );
181
182#endif
183}
184
185wxString FileNames::MkDir(const wxString &Str)
186{
187 // Behaviour of wxFileName::DirExists() and wxFileName::MkDir() has
188 // changed between wx2.6 and wx2.8, so we use static functions instead.
189 if (!wxFileName::DirExists(Str))
190 wxFileName::Mkdir(Str, 511, wxPATH_MKDIR_FULL);
191
192 return Str;
193}
194
195// originally an ExportMultipleDialog method. Append suffix if newName appears in otherNames.
196void FileNames::MakeNameUnique(FilePaths &otherNames,
197 wxFileName &newName)
198{
199 if (otherNames.Index(newName.GetFullName(), false) >= 0) {
200 int i=2;
201 wxString orig = newName.GetName();
202 do {
203 newName.SetName(wxString::Format(wxT("%s-%d"), orig, i));
204 i++;
205 } while (otherNames.Index(newName.GetFullName(), false) >= 0);
206 }
207 otherNames.push_back(newName.GetFullName());
208}
209
210// The APP name has upercase first letter (so that Quit Audacity is correctly
211// capitalised on Mac, but we want lower case APP name in paths.
212// This function does that substitution, IF the last component of
213// the path is 'Audacity'.
214wxString FileNames::LowerCaseAppNameInPath( const wxString & dirIn){
215 wxString dir = dirIn;
216 // BUG 1577 Capitalisation of Audacity in path...
217 if( dir.EndsWith( "Audacity" ) )
218 {
219 int nChars = dir.length() - wxString( "Audacity" ).length();
220 dir = dir.Left( nChars ) + "audacity";
221 }
222 return dir;
223}
224
225namespace // Implementation for user directories
226{
227enum class DirTarget
228{
229 Cache,
230 Config,
231 Data,
232 State,
234};
235
236static FilePath gTargetDirs[size_t(DirTarget::_targetCount)] = {};
237
238#if defined(__WXGTK__)
239struct XDGDirConfig final
240{
241 wxString dirEnvVar;
243};
244
246 {wxT("XDG_CACHE_HOME"), wxT("/.cache") },
247 {wxT("XDG_CONFIG_HOME"), wxT("/.config") },
248 {wxT("XDG_DATA_HOME"), wxT("/.local/share")},
249 {wxT("XDG_STATE_HOME"), wxT("/.local/state")}
250};
251
252static_assert(
253 sizeof(gXDGUnixDirs) / sizeof(*gXDGUnixDirs) == size_t(DirTarget::_targetCount),
254 "Not all DirTarget cases were implemented!"
255);
256
258{
259 static const auto oldUnixDataDir = wxFileName::GetHomeDir() + wxT("/.audacity-data");
260 static const auto oldUnixDataDirExists = wxDirExists(oldUnixDataDir);
261 // Compatibility: Use old user data dir folder, if it already exists
262 if (oldUnixDataDirExists)
263 return oldUnixDataDir;
264
265 // see if the XDG_*_HOME env var is defined. if it is, use its value.
266 // if it isn't, use the default XDG-specified value.
267 wxString newDir;
268 const auto [dirEnvVar, dirDefault] = gXDGUnixDirs[size_t(target)];
269 if (!wxGetEnv(dirEnvVar, &newDir) || newDir.empty())
270 newDir = wxFileName::GetHomeDir() + dirDefault;
271
272#ifdef AUDACITY_NAME
273 newDir = newDir + wxT("/" AUDACITY_NAME);
274#else
275 newDir = newDir + wxT("/audacity");
276#endif
277
278 return newDir;
279}
280#endif
281
282FilePath GetUserTargetDir(DirTarget target, bool allowRoaming)
283{
284 auto& dir = gTargetDirs[size_t(target)];
285 if (dir.empty())
286 {
287 // If there is a directory "Portable Settings" relative to the
288 // executable's EXE file, the prefs are stored in there, otherwise
289 // the prefs are stored in the user data dir provided by the OS.
290 wxFileName exePath(PlatformCompatibility::GetExecutablePath());
291#if defined(__WXMAC__)
292 // Path ends for example in "Audacity.app/Contents/MacOSX"
293 //exePath.RemoveLastDir();
294 //exePath.RemoveLastDir();
295 // just remove the MacOSX part.
296 exePath.RemoveLastDir();
297#endif
298 wxFileName portablePrefsPath(exePath.GetPath(), wxT("Portable Settings"));
299
300 if (::wxDirExists(portablePrefsPath.GetFullPath()))
301 {
302 // Use "Portable Settings" folder
303 dir = portablePrefsPath.GetFullPath();
304 } else
305 {
306#if defined(__WXGTK__)
307 // Use XDG Base Directory compliant folders
308 wxString newDir(GetXDGTargetDir(target));
309#else
310 // Use OS-provided user data dir folder
311 wxString newDir(FileNames::LowerCaseAppNameInPath(
314#endif
315 dir = FileNames::MkDir(newDir);
316 }
317 }
318 return dir;
319}
320} // End of implementation for user directories
321
322FilePath FileNames::CacheDir() { return GetUserTargetDir(DirTarget::Cache, false); }
323FilePath FileNames::ConfigDir() { return GetUserTargetDir(DirTarget::Config, true); }
324FilePath FileNames::DataDir() { return GetUserTargetDir(DirTarget::Data, true); }
325FilePath FileNames::StateDir() { return GetUserTargetDir(DirTarget::State, false); }
326
328#if __WXMSW__
329 static auto resourcesDir = wxFileName(PlatformCompatibility::GetExecutablePath()).GetPath();
330#else
332#endif
333 return resourcesDir;
334}
335
337{
338#if defined(__WXMAC__)
339 wxFileName exePath(PlatformCompatibility::GetExecutablePath());
340 // Path ends for example in "Audacity.app/Contents/MacOSX"
341 //exePath.RemoveLastDir();
342 //exePath.RemoveLastDir();
343 // just remove the MacOSX part.
344 exePath.RemoveLastDir();
345
346 //for mac this puts us within the .app: Audacity.app/Contents/SharedSupport/
347 return wxFileName( exePath.GetPath()+wxT("/help/manual"), wxEmptyString ).GetFullPath();
348#else
349 //linux goes into /*prefix*/share/audacity/
350 //windows (probably) goes into the dir containing the .exe
351 wxString dataDir =
353 return wxFileName( dataDir+wxT("/help/manual"), wxEmptyString ).GetFullPath();
354#endif
355}
356
358{
359 // Don't force creation of it
360 return wxFileName{ DataDir(), wxT("Chains") }.GetFullPath();
361}
362
364{
365 return FileNames::MkDir( wxFileName( DataDir(), wxT("Macros") ).GetFullPath() );
366}
367
369{
370 return FileNames::MkDir( wxFileName( DataDir(), wxT("NRP") ).GetFullPath() );
371}
372
374{
375 return wxFileName( NRPDir(), wxT("noisegate.nrp") ).GetFullPath();
376}
377
379{
380 return FileNames::MkDir( wxFileName( DataDir(), wxT("Plug-Ins") ).GetFullPath() );
381}
382
384{
385 return wxFileName( ConfigDir(), wxT("audacity.cfg") ).GetFullPath();
386}
387
389{
390 return wxFileName( ConfigDir(), wxT("pluginregistry.cfg") ).GetFullPath();
391}
392
394{
395 return wxFileName( ConfigDir(), wxT("pluginsettings.cfg") ).GetFullPath();
396}
397
399{
400 wxFileName baseDir;
401
402#if defined(__WXMAC__)
404
405 // Path ends for example in "Audacity.app/Contents/MacOSX"
406 //baseDir.RemoveLastDir();
407 //baseDir.RemoveLastDir();
408 // just remove the MacOSX part.
409 baseDir.RemoveLastDir();
410#elif defined(__WXMSW__)
411 // Don't use PlatformCompatibility::GetDataDir() since it removes
412 // the "Debug" directory in debug builds.
414#else
415 // Linux goes into /*prefix*/share/audacity/
417#endif
418
419 return baseDir.GetPath();
420}
421
423{
424 wxFileName modulesDir(BaseDir(), wxEmptyString);
425
426 modulesDir.AppendDir(wxT("modules"));
427
428 return modulesDir.GetFullPath();
429}
430
431//
432// Returns the full path of program module (.exe, .dll, .so, .dylib) containing address
433//
435{
436 wxFileName name;
437
438#if defined(__WXMAC__) || defined(__WXGTK__)
439#define OSFILENAME(X) ((char *) (const char *)(X).fn_str())
440#define OSINPUT(X) OSFILENAME(X)
441 Dl_info info;
442 if (dladdr(addr, &info)) {
443 char realname[PLATFORM_MAX_PATH + 1];
444 int len;
445 name = LAT1CTOWX(info.dli_fname);
446 len = readlink(OSINPUT(name.GetFullPath()), realname, PLATFORM_MAX_PATH);
447 if (len > 0) {
448 realname[len] = 0;
449 name.SetFullName(LAT1CTOWX(realname));
450 }
451 }
452#elif defined(__WXMSW__) && defined(_UNICODE)
453 // The GetModuleHandlEx() function did not appear until Windows XP and
454 // GetModuleFileName() did appear until Windows 2000, so we have to
455 // check for them at runtime.
456 typedef BOOL (WINAPI *getmodulehandleex)(DWORD dwFlags, LPCWSTR lpModuleName, HMODULE* phModule);
457 typedef DWORD (WINAPI *getmodulefilename)(HMODULE hModule, LPWCH lpFilename, DWORD nSize);
458 getmodulehandleex gmhe =
459 (getmodulehandleex) GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")),
460 "GetModuleHandleExW");
461 getmodulefilename gmfn =
462 (getmodulefilename) GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")),
463 "GetModuleFileNameW");
464
465 if (gmhe != NULL && gmfn != NULL) {
466 HMODULE module;
467 if (gmhe(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
468 (LPTSTR) addr,
469 &module)) {
470 TCHAR path[MAX_PATH];
471 DWORD nSize;
472
473 nSize = gmfn(module, path, MAX_PATH);
474 if (nSize && nSize < MAX_PATH) {
475 name = LAT1CTOWX(path);
476 }
477 }
478 }
479#endif
480
481 return name.GetFullPath();
482}
483
484
486 if( Path.IsEmpty() )
487 return false;
488#ifndef _WIN32
489 return true;
490#else
491 wxFileNameWrapper filePath( Path );
492 return filePath.DirExists() && !filePath.FileExists();
493#endif
494}
495
497{
498 wxFileNameWrapper result;
499
500#ifdef _WIN32
501 wxFileName defaultPath( PlatformCompatibility::GetDocumentsDir(), "" );
502
503 defaultPath.AppendDir( AppName );
504 result.SetPath( gPrefs->Read( preference, defaultPath.GetPath( wxPATH_GET_VOLUME ) ) );
505
506 // MJB: Bug 1899 & Bug 2007. Only create directory if the result is the default path
507 bool bIsDefaultPath = result == defaultPath;
508 if( !bIsDefaultPath )
509 {
510 // IF the prefs directory doesn't exist - (Deleted by our user perhaps?)
511 // or exists as a file
512 // THEN fallback to using the default directory.
513 bIsDefaultPath = !IsPathAvailable( result.GetPath(wxPATH_GET_VOLUME|wxPATH_GET_SEPARATOR ) );
514 if( bIsDefaultPath )
515 {
516 result.SetPath( defaultPath.GetPath( wxPATH_GET_VOLUME ) );
517 // Don't write to gPrefs.
518 // We typically do it later, (if directory actually gets used)
519 }
520 }
521 if ( bIsDefaultPath )
522 {
523 // The default path might not exist since it is a sub-directory of 'Documents'
524 // There is no error if the path could not be created. That's OK.
525 // The dialog that Audacity offers will allow the user to select a valid directory.
526 result.Mkdir(0755, wxPATH_MKDIR_FULL);
527 }
528#else
529 result.AssignHomeDir();
530 result.SetPath(gPrefs->Read( preference, result.GetPath() + "/Documents"));
531#endif
532
533 return result;
534}
535
537{
538 wxString key;
539 switch (op) {
540 case FileNames::Operation::Temp:
541 key = wxT("/Directories/TempDir"); break;
542 case FileNames::Operation::Presets:
543 key = wxT("/Presets/Path"); break;
544 case FileNames::Operation::Open:
545 key = wxT("/Directories/Open"); break;
546 case FileNames::Operation::Save:
547 key = wxT("/Directories/Save"); break;
548 case FileNames::Operation::Import:
549 key = wxT("/Directories/Import"); break;
550 case FileNames::Operation::Export:
551 key = wxT("/Directories/Export"); break;
552 case FileNames::Operation::MacrosOut:
553 key = wxT("/Directories/MacrosOut"); break;
554 case FileNames::Operation::_None:
555 default:
556 break;
557 }
558
559 switch (type) {
560 case FileNames::PathType::User:
561 key += "/Default"; break;
562 case FileNames::PathType::LastUsed:
563 key += "/LastUsed"; break;
564 case FileNames::PathType::_None:
565 default:
566 break;
567 }
568
569 return key;
570}
571
573{
574 auto key = PreferenceKey(op, PathType::User);
575
576 if (key.empty())
577 return wxString{};
578
579 // If the user specified a default path, then use that
580 FilePath path = gPrefs->Read(key, wxT(""));
581 if (!path.empty()) {
582 return path;
583 }
584
585 // Maybe the last used path is available
586 key = PreferenceKey(op, PathType::LastUsed);
587 path = gPrefs->Read(key, wxT(""));
588 if (!path.empty()) {
589 return path;
590 }
591
592 // Last resort is to simply return the default folder
593 return DefaultToDocumentsFolder("").GetPath();
594}
595
596void FileNames::UpdateDefaultPath(Operation op, const FilePath &path)
597{
598 if (path.empty())
599 return;
600 wxString key;
601 if (op == Operation::Temp) {
602 key = PreferenceKey(op, PathType::_None);
603 }
604 else {
605 key = PreferenceKey(op, PathType::LastUsed);
606 }
607 if (!key.empty()) {
608 gPrefs->Write(key, path);
609 gPrefs->Flush();
610 }
611}
612
614
616{
617 return sAudacityPathList;
618}
619
621{
622 sAudacityPathList = std::move( list );
623}
624
625// static
627 FilePaths &pathList)
628{
629 wxFileNameWrapper pathNorm { pathArg };
630 // https://github.com/audacity/audacity/issues/6448 :
631 // Do not seek to expand environment variables here: it is not needed, and
632 // wxWidgets has an issue doing so - See
633 // https://github.com/wxWidgets/wxWidgets/issues/19214
634 const auto flags = wxPATH_NORM_ALL & ~wxPATH_NORM_ENV_VARS;
635 pathNorm.Normalize(flags);
636 const wxString newpath{ pathNorm.GetFullPath() };
637
638 for(const auto &path : pathList) {
639 if (pathNorm == wxFileNameWrapper{ path })
640 return;
641 }
642
643 pathList.push_back(newpath);
644}
645
646// static
647void FileNames::AddMultiPathsToPathList(const wxString &multiPathStringArg,
648 FilePaths &pathList)
649{
650 wxString multiPathString(multiPathStringArg);
651 while (!multiPathString.empty()) {
652 wxString onePath = multiPathString.BeforeFirst(wxPATH_SEP[0]);
653 multiPathString = multiPathString.AfterFirst(wxPATH_SEP[0]);
654 AddUniquePathToPathList(onePath, pathList);
655 }
656}
657
658#include <wx/log.h>
659
660// static
661void FileNames::FindFilesInPathList(const wxString & pattern,
662 const FilePaths & pathList,
663 FilePaths & results,
664 int flags)
665{
666 wxLogNull nolog;
667
668 if (pattern.empty()) {
669 return;
670 }
671
673
674 for(size_t i = 0; i < pathList.size(); i++) {
675 ff = pathList[i] + wxFILE_SEP_PATH + pattern;
676 wxDir::GetAllFiles(ff.GetPath(), &results, ff.GetFullName(), flags);
677 }
678}
679
681 const TranslatableString & message)
682{
683 bool status = wxFileName::IsDirWritable(path);
684
685 if (!status)
686 {
687 using namespace BasicUI;
689 message +
690 XO("\n%s does not have write permissions.").Format(path),
692 .Caption(XO("Error"))
693 .IconStyle(Icon::Error)
694 .ButtonStyle(Button::Ok)
695 );
696 }
697
698 return status;
699}
700
701// Using this with wxStringArray::Sort will give you a list that
702// is alphabetical, without depending on case. If you use the
703// default sort, you will get strings with 'R' before 'a', because it is in caps.
704int FileNames::CompareNoCase(const wxString& first, const wxString& second)
705{
706 return first.CmpNoCase(second);
707}
708
709// Create a unique filename using the passed prefix and suffix
710wxString FileNames::CreateUniqueName(const wxString &prefix,
711 const wxString &suffix /* = wxEmptyString */)
712{
713 static int count = 0;
714
715 return wxString::Format(wxT("%s %s N-%i.%s"),
716 prefix,
717 wxDateTime::Now().Format(wxT("%Y-%m-%d %H-%M-%S")),
718 ++count,
719 suffix);
720}
721
723{
724 return wxT("aup3unsaved");
725}
726
727// How to detect whether the file system of a path is FAT
728// No apparent way to do it with wxWidgets
729#if defined(__DARWIN__)
730#include <sys/mount.h>
732{
733 struct statfs fs;
734 if (statfs(wxPathOnly(path).c_str(), &fs))
735 // Error from statfs
736 return false;
737 return 0 == strcmp(fs.f_fstypename, "msdos");
738}
739#elif defined(__linux__)
740#include <sys/statfs.h>
741#include "/usr/include/linux/magic.h"
743{
744 struct statfs fs;
745 if (statfs(wxPathOnly(path).c_str(), &fs))
746 // Error from statfs
747 return false;
748 return fs.f_type == MSDOS_SUPER_MAGIC;
749}
750#elif defined(_WIN32)
751#include <fileapi.h>
753{
754 wxFileNameWrapper fileName{path};
755 if (!fileName.HasVolume())
756 return false;
757 auto volume = AbbreviatePath(fileName) + wxT("\\");
758 DWORD volumeFlags;
759 wxChar volumeType[64];
760 if (!::GetVolumeInformationW(
761 volume.wc_str(), NULL, 0, NULL, NULL,
762 &volumeFlags,
763 volumeType,
764 WXSIZEOF(volumeType)))
765 return false;
766 wxString type(volumeType);
767 if (type == wxT("FAT") || type == wxT("FAT32"))
768 return true;
769 return false;
770}
771#else
773{
774 return false;
775}
776#endif
777
778wxString FileNames::AbbreviatePath( const wxFileName &fileName )
779{
780 wxString target;
781#ifdef __WXMSW__
782
783 // Drive letter plus colon
784 target = fileName.GetVolume() + wxT(":");
785
786#else
787
788 // Shorten the path, arbitrarily to 3 components
789 auto path = fileName;
790 path.SetFullName(wxString{});
791 while(path.GetDirCount() > 3)
792 path.RemoveLastDir();
793 target = path.GetFullPath();
794
795#endif
796 return target;
797}
wxT("CloseDown"))
Toolkit-neutral facade for basic user interface services.
static FilePaths sAudacityPathList
Definition: FileNames.cpp:613
#define OSINPUT(X)
#define PLATFORM_MAX_PATH
Definition: FileNames.h:42
XO("Cut/Copy/Paste")
static const auto exts
Definition: ImportAUP.cpp:56
#define LAT1CTOWX(X)
Definition: Internat.h:158
const std::wstring AppName
This program's name.
static const AudacityProject::AttachedObjects::RegisteredFactory key
audacity::BasicSettings * gPrefs
Definition: Prefs.cpp:68
wxString FilePath
Definition: Project.h:21
std::vector< FileNames::FileType > FileTypes
Definition: SelectFile.h:23
wxString name
Definition: TagsEditor.cpp:166
FILES_API const FileType XMLFiles
Definition: FileNames.h:73
FILES_API const FileType AllFiles
Definition: FileNames.h:70
FILES_API const FileType DynamicLibraries
Definition: FileNames.h:72
FILES_API const FileType TextFiles
Definition: FileNames.h:73
FILES_API const FileType AudacityProjects
Definition: FileNames.h:71
Abstract base class used in importing a file.
Holds a msgid for the translation catalog; may also bind format arguments.
virtual bool Flush() noexcept=0
virtual bool Write(const wxString &key, bool value)=0
virtual bool Read(const wxString &key, bool *value) const =0
Extend wxArrayString with move operations and construction and insertion fromstd::initializer_list.
MessageBoxResult ShowMessageBox(const TranslatableString &message, MessageBoxOptions options={})
Show a modal message box with either Ok or Yes and No, and optionally Cancel.
Definition: BasicUI.h:287
FILES_API FilePath MacroDir()
FILES_API bool IsOnFATFileSystem(const FilePath &path)
FILES_API FilePath PlugInDir()
The user plug-in directory (not a system one)
FILES_API FilePath Configuration()
FILES_API bool HardLinkFile(const FilePath &file1, const FilePath &file2)
FILES_API FilePath HtmlHelpDir()
FILES_API FilePath NRPFile()
FILES_API bool IsPathAvailable(const FilePath &Path)
FILES_API wxString LowerCaseAppNameInPath(const wxString &dirIn)
FILES_API wxString CreateUniqueName(const wxString &prefix, const wxString &suffix=wxEmptyString)
FILES_API wxString MkDir(const wxString &Str)
FILES_API wxFileNameWrapper DefaultToDocumentsFolder(const wxString &preference)
FILES_API wxString UnsavedProjectExtension()
FILES_API void AddUniquePathToPathList(const FilePath &path, FilePaths &pathList)
FILES_API FilePath ResourcesDir()
FILES_API FilePath ConfigDir()
Audacity user config directory.
FILES_API wxString PreferenceKey(FileNames::Operation op, FileNames::PathType type)
FILES_API FilePath StateDir()
Audacity user state directory.
FILES_API void FindFilesInPathList(const wxString &pattern, const FilePaths &pathList, FilePaths &results, int flags=wxDIR_FILES)
FILES_API bool DoCopyFile(const FilePath &file1, const FilePath &file2, bool overwrite=true)
FILES_API FilePath CacheDir()
Audacity user cache directory.
FILES_API bool WritableLocationCheck(const FilePath &path, const TranslatableString &message)
Check location on writable access and return true if checked successfully.
FILES_API void AddMultiPathsToPathList(const wxString &multiPathString, FilePaths &pathList)
FILES_API FilePath PathFromAddr(void *addr)
FILES_API wxString AbbreviatePath(const wxFileName &fileName)
Give enough of the path to identify the device. (On Windows, drive letter plus ':')
FILES_API wxString FormatWildcard(const FileTypes &fileTypes)
FILES_API FilePath BaseDir()
FILES_API FilePath DataDir()
Audacity user data directory.
FILES_API void UpdateDefaultPath(Operation op, const FilePath &path)
FILES_API FilePath ModulesDir()
FILES_API FilePath PluginRegistry()
FILES_API FilePath LegacyChainDir()
FILES_API FilePath NRPDir()
FILES_API void MakeNameUnique(FilePaths &otherNames, wxFileName &newName)
FILES_API int CompareNoCase(const wxString &first, const wxString &second)
FILES_API FilePath FindDefaultPath(Operation op)
FILES_API FilePath PluginSettings()
FILES_API const FilePaths & AudacityPathList()
A list of directories that should be searched for Audacity files (plug-ins, help files,...
FILES_API void SetAudacityPathList(FilePaths list)
std::string FILES_API GetPluginsDir()
std::string FILES_API GetUserDataDir()
std::string FILES_API GetDocumentsDir()
std::string FILES_API GetDataDir()
std::string FILES_API GetResourcesDir()
std::string FILES_API GetExecutablePath()
std::string FILES_API GetHomeDir()
std::string FILES_API GetUserLocalDataDir()
static FilePath gTargetDirs[size_t(DirTarget::_targetCount)]
Definition: FileNames.cpp:236
FilePath GetXDGTargetDir(DirTarget target)
Definition: FileNames.cpp:257
const XDGDirConfig gXDGUnixDirs[]
Definition: FileNames.cpp:245
FilePath GetUserTargetDir(DirTarget target, bool allowRoaming)
Definition: FileNames.cpp:282
MessageBoxOptions && Caption(TranslatableString caption_) &&
Definition: BasicUI.h:101
Definition: Dither.cpp:67