X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/bd365871aadca528e03f3b6bb8382a1fdf5f1817..c753eb9269d1e6c99b80a2d782ce49d9864ac1da:/src/common/filename.cpp diff --git a/src/common/filename.cpp b/src/common/filename.cpp index 508954f955..b0274b5863 100644 --- a/src/common/filename.cpp +++ b/src/common/filename.cpp @@ -83,6 +83,7 @@ #include "wx/tokenzr.h" #include "wx/config.h" // for wxExpandEnvVars #include "wx/dynlib.h" +#include "wx/dir.h" #if defined(__WIN32__) && defined(__MINGW32__) #include "wx/msw/gccpriv.h" @@ -161,7 +162,7 @@ public: Write }; - wxFileHandle(const wxString& filename, OpenMode mode) + wxFileHandle(const wxString& filename, OpenMode mode, int flags = 0) { m_hFile = ::CreateFile ( @@ -172,7 +173,7 @@ public: FILE_SHARE_WRITE, // (allow everything) NULL, // no secutity attr OPEN_EXISTING, // creation disposition - 0, // no flags + flags, // flags NULL // no template file ); @@ -471,9 +472,8 @@ void wxFileName::Assign(const wxString& fullpathOrig, wxString volume, path, name, ext; bool hasExt; - // do some consistency checks in debug mode: the name should be really just - // the filename and the path should be really just a path -#ifdef __WXDEBUG__ + // do some consistency checks: the name should be really just the filename + // and the path should be really just a path wxString volDummy, pathDummy, nameDummy, extDummy; SplitPath(fullname, &volDummy, &pathDummy, &name, &ext, &hasExt, format); @@ -486,12 +486,6 @@ void wxFileName::Assign(const wxString& fullpathOrig, wxASSERT_MSG( nameDummy.empty() && extDummy.empty(), _T("the path shouldn't contain file name nor extension") ); -#else // !__WXDEBUG__ - SplitPath(fullname, NULL /* no volume */, NULL /* no path */, - &name, &ext, &hasExt, format); - SplitPath(fullpath, &volume, &path, NULL, NULL, format); -#endif // __WXDEBUG__/!__WXDEBUG__ - Assign(volume, path, name, ext, hasExt, format); } @@ -598,7 +592,7 @@ wxString wxFileName::GetCwd(const wxString& volume) return cwd; } -bool wxFileName::SetCwd() +bool wxFileName::SetCwd() const { return wxFileName::SetCwd( GetPath() ); } @@ -1079,7 +1073,7 @@ wxString wxFileName::GetTempDir() return dir; } -bool wxFileName::Mkdir( int perm, int flags ) +bool wxFileName::Mkdir( int perm, int flags ) const { return wxFileName::Mkdir(GetPath(), perm, flags); } @@ -1123,14 +1117,83 @@ bool wxFileName::Mkdir( const wxString& dir, int perm, int flags ) return ::wxMkdir( dir, perm ); } -bool wxFileName::Rmdir() +bool wxFileName::Rmdir(int flags) const { - return wxFileName::Rmdir( GetPath() ); + return wxFileName::Rmdir( GetPath(), flags ); } -bool wxFileName::Rmdir( const wxString &dir ) +bool wxFileName::Rmdir(const wxString& dir, int flags) { - return ::wxRmdir( dir ); +#ifdef __WXMSW__ + if ( flags & wxPATH_RMDIR_RECURSIVE ) + { + // SHFileOperation needs double null termination string + // but without separator at the end of the path + wxString path(dir); + if ( path.Last() == wxFILE_SEP_PATH ) + path.RemoveLast(); + path += _T('\0'); + + SHFILEOPSTRUCT fileop; + wxZeroMemory(fileop); + fileop.wFunc = FO_DELETE; + fileop.pFrom = path.fn_str(); + fileop.fFlags = FOF_SILENT | FOF_NOCONFIRMATION; + #ifndef __WXWINCE__ + // FOF_NOERRORUI is not defined in WinCE + fileop.fFlags |= FOF_NOERRORUI; + #endif + + int ret = SHFileOperation(&fileop); + if ( ret != 0 ) + { + // SHFileOperation may return non-Win32 error codes, so the error + // message can be incorrect + wxLogApiError(_T("SHFileOperation"), ret); + return false; + } + + return true; + } + else if ( flags & wxPATH_RMDIR_FULL ) +#else // !__WXMSW__ + if ( flags != 0 ) // wxPATH_RMDIR_FULL or wxPATH_RMDIR_RECURSIVE +#endif // !__WXMSW__ + { + wxString path(dir); + if ( path.Last() != wxFILE_SEP_PATH ) + path += wxFILE_SEP_PATH; + + wxDir d(path); + + if ( !d.IsOpened() ) + return false; + + wxString filename; + + // first delete all subdirectories + bool cont = d.GetFirst(&filename, "", wxDIR_DIRS | wxDIR_HIDDEN); + while ( cont ) + { + wxFileName::Rmdir(path + filename, flags); + cont = d.GetNext(&filename); + } + +#ifndef __WXMSW__ + if ( flags & wxPATH_RMDIR_RECURSIVE ) + { + // delete all files too + cont = d.GetFirst(&filename, "", wxDIR_FILES | wxDIR_HIDDEN); + while ( cont ) + { + ::wxRemoveFile(path + filename); + cont = d.GetNext(&filename); + } + } +#endif // !__WXMSW__ + } + + return ::wxRmdir(dir); } // ---------------------------------------------------------------------------- @@ -1370,7 +1433,7 @@ bool wxFileName::ReplaceHomeDir(wxPathFormat format) bool wxFileName::GetShortcutTarget(const wxString& shortcutPath, wxString& targetFilename, - wxString* arguments) + wxString* arguments) const { wxString path, file, ext; wxFileName::SplitPath(shortcutPath, & path, & file, & ext); @@ -2198,6 +2261,14 @@ void wxFileName::SplitPath(const wxString& fullpath, } } +/* static */ +wxString wxFileName::StripExtension(const wxString& fullpath) +{ + wxFileName fn(fullpath); + fn.SetExt(""); + return fn.GetFullPath(); +} + // ---------------------------------------------------------------------------- // time functions // ---------------------------------------------------------------------------- @@ -2206,35 +2277,47 @@ void wxFileName::SplitPath(const wxString& fullpath, bool wxFileName::SetTimes(const wxDateTime *dtAccess, const wxDateTime *dtMod, - const wxDateTime *dtCreate) + const wxDateTime *dtCreate) const { #if defined(__WIN32__) + FILETIME ftAccess, ftCreate, ftWrite; + + if ( dtCreate ) + ConvertWxToFileTime(&ftCreate, *dtCreate); + if ( dtAccess ) + ConvertWxToFileTime(&ftAccess, *dtAccess); + if ( dtMod ) + ConvertWxToFileTime(&ftWrite, *dtMod); + + wxString path; + int flags; if ( IsDir() ) { - // VZ: please let me know how to do this if you can - wxFAIL_MSG( _T("SetTimes() not implemented for the directories") ); + if ( wxGetOsVersion() == wxOS_WINDOWS_9X ) + { + wxLogError(_("Setting directory access times is not supported " + "under this OS version")); + return false; + } + + path = GetPath(); + flags = FILE_FLAG_BACKUP_SEMANTICS; } else // file { - wxFileHandle fh(GetFullPath(), wxFileHandle::Write); - if ( fh.IsOk() ) - { - FILETIME ftAccess, ftCreate, ftWrite; - - if ( dtCreate ) - ConvertWxToFileTime(&ftCreate, *dtCreate); - if ( dtAccess ) - ConvertWxToFileTime(&ftAccess, *dtAccess); - if ( dtMod ) - ConvertWxToFileTime(&ftWrite, *dtMod); + path = GetFullPath(); + flags = 0; + } - if ( ::SetFileTime(fh, - dtCreate ? &ftCreate : NULL, - dtAccess ? &ftAccess : NULL, - dtMod ? &ftWrite : NULL) ) - { - return true; - } + wxFileHandle fh(path, wxFileHandle::Write, flags); + if ( fh.IsOk() ) + { + if ( ::SetFileTime(fh, + dtCreate ? &ftCreate : NULL, + dtAccess ? &ftAccess : NULL, + dtMod ? &ftWrite : NULL) ) + { + return true; } } #elif defined(__UNIX_LIKE__) || (defined(__DOS__) && defined(__WATCOMC__)) @@ -2267,7 +2350,7 @@ bool wxFileName::SetTimes(const wxDateTime *dtAccess, return false; } -bool wxFileName::Touch() +bool wxFileName::Touch() const { #if defined(__UNIX_LIKE__) // under Unix touching file is simple: just pass NULL to utime() @@ -2525,7 +2608,7 @@ bool wxFileName::MacSetTypeAndCreator( wxUint32 type , wxUint32 creator ) return false ; } -bool wxFileName::MacGetTypeAndCreator( wxUint32 *type , wxUint32 *creator ) +bool wxFileName::MacGetTypeAndCreator( wxUint32 *type , wxUint32 *creator ) const { FSRef fsRef ; FSCatalogInfo catInfo;