#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"
Write
};
- wxFileHandle(const wxString& filename, OpenMode mode)
+ wxFileHandle(const wxString& filename, OpenMode mode, int flags = 0)
{
m_hFile = ::CreateFile
(
FILE_SHARE_WRITE, // (allow everything)
NULL, // no secutity attr
OPEN_EXISTING, // creation disposition
- 0, // no flags
+ flags, // flags
NULL // no template file
);
// !! Fall through !!
case wxPATH_UNIX:
- // the paths of the form "~" or "~username" are absolute
- m_relative = leadingChar != wxT('/') && leadingChar != _T('~');
+ m_relative = leadingChar != wxT('/');
break;
case wxPATH_DOS:
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);
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);
}
return cwd;
}
-bool wxFileName::SetCwd()
+bool wxFileName::SetCwd() const
{
return wxFileName::SetCwd( GetPath() );
}
return dir;
}
-bool wxFileName::Mkdir( int perm, int flags )
+bool wxFileName::Mkdir( int perm, int flags ) const
{
return wxFileName::Mkdir(GetPath(), perm, 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);
}
// ----------------------------------------------------------------------------
}
// handle ~ stuff under Unix only
- if ( (format == wxPATH_UNIX) && (flags & wxPATH_NORM_TILDE) )
+ if ( (format == wxPATH_UNIX) && (flags & wxPATH_NORM_TILDE) && m_relative )
{
if ( !dirs.IsEmpty() )
{
{
// to make the path absolute use the home directory
curDir.AssignDir(wxGetUserHome(dir.c_str() + 1));
-
- // if we are expanding the tilde, then this path
- // *should* be already relative (since we checked for
- // the tilde only in the first char of the first dir);
- // if m_relative==false, it's because it was initialized
- // from a string which started with /~; in that case
- // we reach this point but then need m_relative=true
- // for relative->absolute expansion later
- m_relative = true;
-
dirs.RemoveAt(0u);
}
}
// if we used e.g. tilde expansion previously and wxGetUserHome didn't
// return for some reason an absolute path, then curDir maybe not be absolute!
- if ( curDir.IsAbsolute(format) )
+ if ( !curDir.m_relative )
{
// we have prepended an absolute path and thus we are now an absolute
// file name too
bool wxFileName::GetShortcutTarget(const wxString& shortcutPath,
wxString& targetFilename,
- wxString* arguments)
+ wxString* arguments) const
{
wxString path, file, ext;
- wxSplitPath(shortcutPath, & path, & file, & ext);
+ wxFileName::SplitPath(shortcutPath, & path, & file, & ext);
HRESULT hres;
IShellLink* psl;
bool wxFileName::IsAbsolute(wxPathFormat format) const
{
+ // unix paths beginning with ~ are reported as being absolute
+ if ( format == wxPATH_UNIX )
+ {
+ if ( !m_dirs.IsEmpty() )
+ {
+ wxString dir = m_dirs[0u];
+
+ if (!dir.empty() && dir[0u] == _T('~'))
+ return true;
+ }
+ }
+
// if our path doesn't start with a path separator, it's not an absolute
// path
if ( m_relative )
if ( !GetVolumeSeparator(format).empty() )
{
// this format has volumes and an absolute path must have one, it's not
- // enough to have the full path to bean absolute file under Windows
+ // enough to have the full path to be an absolute file under Windows
if ( GetVolume().empty() )
return false;
}
case wxPATH_UNIX:
if ( !m_relative )
{
- // normally the absolute file names start with a slash
- // with one exception: the ones like "~/foo.bar" don't
- // have it
- if ( m_dirs.IsEmpty() || m_dirs[0u] != _T('~') )
- {
- fullpath += wxFILE_SEP_PATH_UNIX;
- }
+ fullpath += wxFILE_SEP_PATH_UNIX;
}
break;
}
}
+/* static */
+wxString wxFileName::StripExtension(const wxString& fullpath)
+{
+ wxFileName fn(fullpath);
+ fn.SetExt("");
+ return fn.GetFullPath();
+}
+
// ----------------------------------------------------------------------------
// time functions
// ----------------------------------------------------------------------------
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__))
return false;
}
-bool wxFileName::Touch()
+bool wxFileName::Touch() const
{
#if defined(__UNIX_LIKE__)
// under Unix touching file is simple: just pass NULL to utime()
return false ;
}
-bool wxFileName::MacGetTypeAndCreator( wxUint32 *type , wxUint32 *creator )
+bool wxFileName::MacGetTypeAndCreator( wxUint32 *type , wxUint32 *creator ) const
{
FSRef fsRef ;
FSCatalogInfo catInfo;