]> git.saurik.com Git - wxWidgets.git/blobdiff - src/common/filename.cpp
fixing modal dialog quit after nested message box problem
[wxWidgets.git] / src / common / filename.cpp
index 4373beb7443454986c9f070c5759a515874f671a..f16ae7127bf9ab7af950bd6d2e656d52b2bb1371 100644 (file)
@@ -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);
 }
 
@@ -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)
 {
-    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);
 }
 
 // ----------------------------------------------------------------------------
@@ -1152,7 +1215,6 @@ bool wxFileName::Normalize(int flags,
         }
     }
 
-
     // the existing path components
     wxArrayString dirs = GetDirs();
 
@@ -1302,6 +1364,49 @@ bool wxFileName::Normalize(int flags,
     return true;
 }
 
+#ifndef __WXWINCE__
+bool wxFileName::ReplaceEnvVariable(const wxString& envname,
+                                    const wxString& replacementFmtString,
+                                    wxPathFormat format)
+{
+    // look into stringForm for the contents of the given environment variable
+    wxString val;
+    if (envname.empty() ||
+        !wxGetEnv(envname, &val))
+        return false;
+    if (val.empty())
+        return false;
+
+    wxString stringForm = GetPath(wxPATH_GET_VOLUME, format);
+        // do not touch the file name and the extension
+
+    wxString replacement = wxString::Format(replacementFmtString, envname);
+    stringForm.Replace(val, replacement);
+
+    // Now assign ourselves the modified path:
+    Assign(stringForm, GetFullName(), format);
+
+    return true;
+}
+#endif
+
+bool wxFileName::ReplaceHomeDir(wxPathFormat format)
+{
+    wxString homedir = wxGetHomeDir();
+    if (homedir.empty())
+        return false;
+
+    wxString stringForm = GetPath(wxPATH_GET_VOLUME, format);
+        // do not touch the file name and the extension
+
+    stringForm.Replace(homedir, "~");
+
+    // Now assign ourselves the modified path:
+    Assign(stringForm, GetFullName(), format);
+
+    return true;
+}
+
 // ----------------------------------------------------------------------------
 // get the shortcut target
 // ----------------------------------------------------------------------------
@@ -1331,7 +1436,7 @@ bool wxFileName::GetShortcutTarget(const wxString& shortcutPath,
                                    wxString* arguments)
 {
     wxString path, file, ext;
-    wxSplitPath(shortcutPath, & path, & file, & ext);
+    wxFileName::SplitPath(shortcutPath, & path, & file, & ext);
 
     HRESULT hres;
     IShellLink* psl;
@@ -2156,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
 // ----------------------------------------------------------------------------
@@ -2167,32 +2280,44 @@ bool wxFileName::SetTimes(const wxDateTime *dtAccess,
                           const wxDateTime *dtCreate)
 {
 #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__))