30#include <wx/filename.h>
31#include <wx/stdpaths.h>
40#if defined(__WXMAC__) || defined(__WXGTK__)
55 XO(
"Dynamically Linked Libraries"), {
wxT(
"dll") },
true
56#elif defined(__WXMAC__)
57 XO(
"Dynamic Libraries"), {
wxT(
"dylib") },
true
59 XO(
"Dynamically Linked Libraries"), {
wxT(
"so*") },
true
85 const wxString dot{
'.' };
88 for (
const auto &
extension: extensions ) {
104 const auto defaultDescription = [](
const FileExtensions &extensions ){
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];
113 return XO(
"%s files").Format(
exts );
116 if ( fileTypes.size() == 1 && fileTypes[0].description.empty() ) {
117 return makeGlobs( fileTypes[0].extensions );
121 for (
const auto &fileType : fileTypes ) {
122 const auto &extensions = fileType.extensions;
123 if (extensions.empty())
129 const auto globs = makeGlobs( extensions );
131 auto mask = fileType.description;
133 mask = defaultDescription( extensions );
134 if ( fileType.appendExtensions )
135 mask.Join(
XO(
"(%s)").
Format( globs ),
" " );
136 result += mask.Translation();
150 return wxCopyFile(file1, file2, overwrite);
160 bool existed = wxFileExists(file2);
161 bool result = wxCopyFile(file1, file2, overwrite) &&
162 wxFile{ file1 }.Length() == wxFile{ file2 }.Length();
163 if (!result && !existed)
176 return ( 0 != ::CreateHardLink( file2, file1, NULL ) );
180 return 0 == ::link( file1.c_str(), file2.c_str() );
189 if (!wxFileName::DirExists(Str))
190 wxFileName::Mkdir(Str, 511, wxPATH_MKDIR_FULL);
199 if (otherNames.Index(newName.GetFullName(),
false) >= 0) {
201 wxString orig = newName.GetName();
203 newName.SetName(wxString::Format(
wxT(
"%s-%d"), orig, i));
205 }
while (otherNames.Index(newName.GetFullName(),
false) >= 0);
207 otherNames.push_back(newName.GetFullName());
215 wxString dir = dirIn;
217 if( dir.EndsWith(
"Audacity" ) )
219 int nChars = dir.length() - wxString(
"Audacity" ).length();
220 dir = dir.Left( nChars ) +
"audacity";
238#if defined(__WXGTK__)
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")}
254 "Not all DirTarget cases were implemented!"
260 static const auto oldUnixDataDirExists = wxDirExists(oldUnixDataDir);
262 if (oldUnixDataDirExists)
263 return oldUnixDataDir;
268 const auto [dirEnvVar, dirDefault] =
gXDGUnixDirs[size_t(target)];
269 if (!wxGetEnv(dirEnvVar, &newDir) || newDir.empty())
273 newDir = newDir +
wxT(
"/" AUDACITY_NAME);
275 newDir = newDir +
wxT(
"/audacity");
291#if defined(__WXMAC__)
296 exePath.RemoveLastDir();
298 wxFileName portablePrefsPath(exePath.GetPath(),
wxT(
"Portable Settings"));
300 if (::wxDirExists(portablePrefsPath.GetFullPath()))
303 dir = portablePrefsPath.GetFullPath();
306#if defined(__WXGTK__)
338#if defined(__WXMAC__)
344 exePath.RemoveLastDir();
347 return wxFileName( exePath.GetPath()+
wxT(
"/help/manual"), wxEmptyString ).GetFullPath();
353 return wxFileName( dataDir+
wxT(
"/help/manual"), wxEmptyString ).GetFullPath();
360 return wxFileName{
DataDir(),
wxT(
"Chains") }.GetFullPath();
375 return wxFileName(
NRPDir(),
wxT(
"noisegate.nrp") ).GetFullPath();
385 return wxFileName(
ConfigDir(),
wxT(
"audacity.cfg") ).GetFullPath();
390 return wxFileName(
ConfigDir(),
wxT(
"pluginregistry.cfg") ).GetFullPath();
395 return wxFileName(
ConfigDir(),
wxT(
"pluginsettings.cfg") ).GetFullPath();
402#if defined(__WXMAC__)
409 baseDir.RemoveLastDir();
410#elif defined(__WXMSW__)
419 return baseDir.GetPath();
424 wxFileName modulesDir(
BaseDir(), wxEmptyString);
426 modulesDir.AppendDir(
wxT(
"modules"));
428 return modulesDir.GetFullPath();
438#if defined(__WXMAC__) || defined(__WXGTK__)
439#define OSFILENAME(X) ((char *) (const char *)(X).fn_str())
440#define OSINPUT(X) OSFILENAME(X)
442 if (dladdr(addr, &info)) {
452#elif defined(__WXMSW__) && defined(_UNICODE)
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");
465 if (gmhe != NULL && gmfn != NULL) {
467 if (gmhe(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
470 TCHAR path[MAX_PATH];
473 nSize = gmfn(module, path, MAX_PATH);
474 if (nSize && nSize < MAX_PATH) {
481 return name.GetFullPath();
492 return filePath.DirExists() && !filePath.FileExists();
503 defaultPath.AppendDir(
AppName );
504 result.SetPath(
gPrefs->
Read( preference, defaultPath.GetPath( wxPATH_GET_VOLUME ) ) );
507 bool bIsDefaultPath = result == defaultPath;
508 if( !bIsDefaultPath )
513 bIsDefaultPath = !
IsPathAvailable( result.GetPath(wxPATH_GET_VOLUME|wxPATH_GET_SEPARATOR ) );
516 result.SetPath( defaultPath.GetPath( wxPATH_GET_VOLUME ) );
521 if ( bIsDefaultPath )
526 result.Mkdir(0755, wxPATH_MKDIR_FULL);
529 result.AssignHomeDir();
530 result.SetPath(
gPrefs->
Read( preference, result.GetPath() +
"/Documents"));
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:
560 case FileNames::PathType::User:
561 key +=
"/Default";
break;
562 case FileNames::PathType::LastUsed:
563 key +=
"/LastUsed";
break;
564 case FileNames::PathType::_None:
601 if (op == Operation::Temp) {
634 const auto flags = wxPATH_NORM_ALL & ~wxPATH_NORM_ENV_VARS;
635 pathNorm.Normalize(flags);
636 const wxString newpath{ pathNorm.GetFullPath() };
638 for(
const auto &path : pathList) {
643 pathList.push_back(newpath);
650 wxString multiPathString(multiPathStringArg);
651 while (!multiPathString.empty()) {
652 wxString onePath = multiPathString.BeforeFirst(wxPATH_SEP[0]);
653 multiPathString = multiPathString.AfterFirst(wxPATH_SEP[0]);
668 if (pattern.empty()) {
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);
683 bool status = wxFileName::IsDirWritable(path);
690 XO(
"\n%s does not have write permissions.").
Format(path),
693 .IconStyle(Icon::Error)
694 .ButtonStyle(Button::Ok)
706 return first.CmpNoCase(second);
711 const wxString &suffix )
713 static int count = 0;
715 return wxString::Format(
wxT(
"%s %s N-%i.%s"),
717 wxDateTime::Now().
Format(
wxT(
"%Y-%m-%d %H-%M-%S")),
724 return wxT(
"aup3unsaved");
729#if defined(__DARWIN__)
730#include <sys/mount.h>
734 if (statfs(wxPathOnly(path).c_str(), &fs))
737 return 0 == strcmp(fs.f_fstypename,
"msdos");
739#elif defined(__linux__)
740#include <sys/statfs.h>
741#include "/usr/include/linux/magic.h"
745 if (statfs(wxPathOnly(path).c_str(), &fs))
748 return fs.f_type == MSDOS_SUPER_MAGIC;
755 if (!fileName.HasVolume())
759 wxChar volumeType[64];
760 if (!::GetVolumeInformationW(
761 volume.wc_str(), NULL, 0, NULL, NULL,
764 WXSIZEOF(volumeType)))
766 wxString type(volumeType);
767 if (type ==
wxT(
"FAT") || type ==
wxT(
"FAT32"))
784 target = fileName.GetVolume() +
wxT(
":");
789 auto path = fileName;
790 path.SetFullName(wxString{});
791 while(path.GetDirCount() > 3)
792 path.RemoveLastDir();
793 target = path.GetFullPath();
Toolkit-neutral facade for basic user interface services.
static FilePaths sAudacityPathList
#define PLATFORM_MAX_PATH
const std::wstring AppName
This program's name.
audacity::BasicSettings * gPrefs
std::vector< FileNames::FileType > FileTypes
FILES_API const FileType XMLFiles
FILES_API const FileType AllFiles
FILES_API const FileType DynamicLibraries
FILES_API const FileType TextFiles
FILES_API const FileType AudacityProjects
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.
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)
ProjectFileIOExtensionRegistry::Extension extension
static FilePath gTargetDirs[size_t(DirTarget::_targetCount)]
FilePath GetXDGTargetDir(DirTarget target)
const XDGDirConfig gXDGUnixDirs[]
FilePath GetUserTargetDir(DirTarget target, bool allowRoaming)
MessageBoxOptions && Caption(TranslatableString caption_) &&