gio-0.11.0: System/GIO/File/File.chs
{-# LANGUAGE CPP, DeriveDataTypeable #-}
-- GIMP Toolkit (GTK) Binding for Haskell: binding to gio -*-haskell-*-
--
-- Author : Peter Gavin, Andy Stewart
-- Created: 13-Oct-2008
--
-- Copyright (c) 2008 Peter Gavin
-- Copyright (c) 2010 Andy Stewart
--
-- This library is free software: you can redistribute it and/or
-- modify it under the terms of the GNU Lesser General Public License
-- as published by the Free Software Foundation, either version 3 of
-- the License, or (at your option) any later version.
--
-- This library is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-- Lesser General Public License for more details.
--
-- You should have received a copy of the GNU Lesser General Public
-- License along with this program. If not, see
-- <http://www.gnu.org/licenses/>.
--
-- GIO, the C library which this Haskell library depends on, is
-- available under LGPL Version 2. The documentation included with
-- this library is based on the original GIO documentation.
--
-- | Maintainer : gtk2hs-devel@lists.sourceforge.net
-- Stability : alpha
-- Portability : portable (depends on GHC)
module System.GIO.File.File (
-- * Details
--
-- | GFile is a high level abstraction for manipulating files on a virtual file system. GFiles are
-- lightweight, immutable objects that do no I/O upon creation. It is necessary to understand that
-- GFile objects do not represent files, merely an identifier for a file. All file content I/O is
-- implemented as streaming operations (see GInputStream and GOutputStream).
--
-- To construct a GFile, you can use: 'fileNewForPath' if
-- you have a URI. 'fileNewForCommandlineArg'
-- from a utf8 string gotten from 'fileGetParseName'.
--
-- One way to think of a GFile is as an abstraction of a pathname. For normal files the system pathname
-- is what is stored internally, but as GFiles are extensible it could also be something else that
-- corresponds to a pathname in a userspace implementation of a filesystem.
--
-- GFiles make up hierarchies of directories and files that correspond to the files on a
-- filesystem. You can move through the file system with GFile using 'fileGetParent' to get an
-- identifier for the parent directory, 'fileGetChild' to get a child within a directory,
-- 'fileResolveRelativePath' to resolve a relative path between two GFiles. There can be multiple
-- hierarchies, so you may not end up at the same root if you repeatedly call 'fileGetParent' on
-- two different files.
--
-- All GFiles have a basename (get with 'fileGetBasename'. These names are byte strings that are
-- used to identify the file on the filesystem (relative to its parent directory) and there is no
-- guarantees that they have any particular charset encoding or even make any sense at all. If you want
-- to use filenames in a user interface you should use the display name that you can get by requesting
-- the GFileAttributeStandardDisplayName attribute with 'fileQueryInfo'. This is guaranteed to
-- be in utf8 and can be used in a user interface. But always store the real basename or the GFile to
-- use to actually access the file, because there is no way to go from a display name to the actual
-- name.
--
-- Using GFile as an identifier has the same weaknesses as using a path in that there may be multiple
-- aliases for the same file. For instance, hard or soft links may cause two different GFiles to refer
-- to the same file. Other possible causes for aliases are: case insensitive filesystems, short and
-- long names on Fat/NTFS, or bind mounts in Linux. If you want to check if two GFiles point to the
-- same file you can query for the GFileAttributeIdFile attribute. Note that GFile does some
-- trivial canonicalization of pathnames passed in, so that trivial differences in the path string used
-- at creation (duplicated slashes, slash at end of path, "." or ".." path segments, etc) does not
-- create different GFiles.
--
-- Many GFile operations have both synchronous and asynchronous versions to suit your
-- application. Asynchronous versions of synchronous functions simply have _async() appended to their
-- function names. The asynchronous I/O functions call a GAsyncReadyCallback which is then used to
-- finalize the operation, producing a GAsyncResult which is then passed to the function's matching
-- _finish() operation.
--
-- Some GFile operations do not have synchronous analogs, as they may take a very long time to finish,
-- and blocking may leave an application unusable. Notable cases include: 'fileMountMountable' to
-- mount a mountable file. 'fileUnmountMountableWithOperation' to unmount a mountable
-- file. 'fileEjectMountableWithOperation' to eject a mountable file.
--
-- One notable feature of GFiles are entity tags, or "etags" for short. Entity tags are somewhat like a
-- more abstract version of the traditional mtime, and can be used to quickly determine if the file has
-- been modified from the version on the file system. See the HTTP 1.1 specification for HTTP Etag
-- headers, which are a very similar concept.
-- * Types.
FileProgressCallback,
FileReadMoreCallback,
FileClass,
-- * Enums
File(..),
FileQueryInfoFlags(..),
FileCreateFlags(..),
FileCopyFlags(..),
FileMonitorFlags(..),
FilesystemPreviewType(..),
FileType(..),
-- * Methods
fileFromPath,
fileFromURI,
fileFromCommandlineArg,
fileFromParseName,
fileEqual,
fileBasename,
filePath,
#if GLIB_CHECK_VERSION(2,24,0)
fileHasParent,
#endif
fileURI,
fileParseName,
fileGetChild,
fileGetChildForDisplayName,
fileHasPrefix,
fileGetRelativePath,
fileResolveRelativePath,
fileIsNative,
fileHasURIScheme,
fileURIScheme,
fileRead,
fileReadAsync,
fileReadFinish,
fileAppendTo,
fileCreate,
fileReplace,
fileAppendToAsync,
fileAppendToFinish,
fileCreateAsync,
fileCreateFinish,
fileReplaceAsync,
fileReplaceFinish,
fileQueryInfo,
fileQueryInfoAsync,
fileQueryInfoFinish,
fileQueryExists,
#if GLIB_CHECK_VERSION(2,18,0)
fileQueryFileType,
#endif
fileQueryFilesystemInfo,
fileQueryFilesystemInfoAsync,
fileQueryFilesystemInfoFinish,
fileQueryDefaultHandler,
fileFindEnclosingMount,
fileFindEnclosingMountAsync,
fileFindEnclosingMountFinish,
fileEnumerateChildren,
fileEnumerateChildrenAsync,
fileEnumerateChildrenFinish,
fileSetDisplayName,
fileSetDisplayNameAsync,
fileSetDisplayNameFinish,
fileDelete,
fileTrash,
fileCopy,
fileCopyAsync,
fileCopyFinish,
fileMove,
fileMakeDirectory,
#if GLIB_CHECK_VERSION(2,18,0)
fileMakeDirectoryWithParents,
#endif
fileMakeSymbolicLink,
fileQuerySettableAttributes,
fileQueryWritableNamespaces
) where
import Control.Monad
import qualified Data.ByteString as BS
import Data.Typeable
import System.Glib.FFI
import System.Glib.Flags
import System.Glib.GError
import System.Glib.UTFString
import System.Glib.GObject
{#import System.GIO.Base#}
{#import System.GIO.Types#}
import System.GIO.File.FileAttribute
{# context lib = "gio" prefix = "g" #}
{# enum GFileQueryInfoFlags as FileQueryInfoFlags {underscoreToCase} with prefix = "G" deriving (Eq, Ord, Bounded, Show, Typeable) #}
instance Flags FileQueryInfoFlags
{# enum GFileCreateFlags as FileCreateFlags {underscoreToCase} with prefix = "G" deriving (Eq, Ord, Bounded, Show, Typeable) #}
instance Flags FileCreateFlags
{# enum GFileCopyFlags as FileCopyFlags {underscoreToCase} with prefix = "G" deriving (Eq, Ord, Bounded, Show, Typeable) #}
instance Flags FileCopyFlags
{# enum GFileMonitorFlags as FileMonitorFlags {underscoreToCase} with prefix = "G" deriving (Eq, Ord, Bounded, Show, Typeable) #}
instance Flags FileMonitorFlags
{# enum GFilesystemPreviewType as FilesystemPreviewType {underscoreToCase} with prefix = "G" deriving (Eq, Ord, Bounded, Show, Typeable) #}
{# enum GFileType as FileType {underscoreToCase} with prefix = "G" deriving (Eq, Ord, Bounded, Show, Typeable) #}
type FileProgressCallback = Offset -> Offset -> IO ()
type CFileProgressCallback = {# type goffset #} -> {# type goffset #} -> Ptr () -> IO ()
foreign import ccall "wrapper"
makeFileProgressCallback :: CFileProgressCallback
-> IO {# type GFileProgressCallback #}
marshalFileProgressCallback :: FileProgressCallback -> IO {# type GFileProgressCallback #}
marshalFileProgressCallback fileProgressCallback =
makeFileProgressCallback cFileProgressCallback
where cFileProgressCallback :: CFileProgressCallback
cFileProgressCallback cCurrentNumBytes cTotalNumBytes _ = do
fileProgressCallback (fromIntegral cCurrentNumBytes)
(fromIntegral cTotalNumBytes)
type FileReadMoreCallback = BS.ByteString -> IO Bool
-- | Constructs a GFile for a given path. This operation never fails, but the returned object might not
-- support any I/O operation if path is malformed.
fileFromPath :: FilePath -> File
fileFromPath path =
unsafePerformIO $ withUTFString path $ \cPath -> {# call file_new_for_path #} cPath >>= takeGObject
-- | Constructs a GFile for a given URI. This operation never fails, but the returned object might not
-- support any I/O operation if uri is malformed or if the uri type is not supported.
fileFromURI :: String -> File
fileFromURI uri =
unsafePerformIO $ withUTFString uri $ \cURI -> {# call file_new_for_uri #} cURI >>= takeGObject
-- | Creates a GFile with the given argument from the command line. The value of arg can be either a URI,
-- an absolute path or a relative path resolved relative to the current working directory. This
-- operation never fails, but the returned object might not support any I/O operation if arg points to
-- a malformed path.
fileFromCommandlineArg :: String -> File
fileFromCommandlineArg arg =
unsafePerformIO $ withUTFString arg $ \cArg -> {# call file_new_for_commandline_arg #} cArg >>= takeGObject
-- | Constructs a GFile with the given 'name (i.e. something given by gFileGetParseName'. This
-- operation never fails, but the returned object might not support any I/O operation if the @parseName@
-- cannot be parsed.
fileFromParseName :: String -> File
fileFromParseName parseName =
unsafePerformIO $ withUTFString parseName $ \cParseName -> {# call file_parse_name #} cParseName >>= takeGObject
-- | Compare two file descriptors for equality. This test is also used to
-- implement the '(==)' function, that is, comparing two descriptions
-- will compare their content, not the pointers to the two structures.
--
fileEqual :: (FileClass file1, FileClass file2)
=> file1 -> file2 -> Bool
fileEqual file1 file2 =
unsafePerformIO $ liftM toBool $ {# call file_equal #} (toFile file1) (toFile file2)
instance Eq File where
(==) = fileEqual
-- | Gets the base name (the last component of the path) for a given GFile.
--
-- If called for the top level of a system (such as the filesystem root or a uri like sftp://host/) it
-- will return a single directory separator (and on Windows, possibly a drive letter).
--
-- The base name is a byte string (*not* UTF-8). It has no defined encoding or rules other than it may
-- not contain zero bytes. If you want to use filenames in a user interface you should use the display
-- name that you can get by requesting the GFileAttributeStandardDisplayName attribute with
-- 'fileQueryInfo'.
--
-- This call does no blocking i/o.
fileBasename :: FileClass file => file -> String
fileBasename file =
unsafePerformIO $ {# call file_get_basename #} (toFile file) >>= readUTFString
-- | Gets the local pathname for GFile, if one exists.
--
-- This call does no blocking i/o.
filePath :: FileClass file => file -> FilePath
filePath file =
unsafePerformIO $ {# call file_get_path #} (toFile file) >>= readUTFString
-- | Gets the URI for the file.
--
-- This call does no blocking i/o.
fileURI :: FileClass file => file -> String
fileURI file =
unsafePerformIO $ {# call file_get_uri #} (toFile file) >>= readUTFString
-- | Gets the parse name of the file. A parse name is a UTF-8 string that describes the file such that
-- one can get the GFile back using 'fileParseName'.
--
-- This is generally used to show the GFile as a nice full-pathname kind of string in a user interface,
-- like in a location entry.
--
-- For local files with names that can safely be converted to UTF8 the pathname is used, otherwise the
-- IRI is used (a form of URI that allows UTF8 characters unescaped).
--
-- This call does no blocking i/o.
fileParseName :: FileClass file => file -> String
fileParseName file =
unsafePerformIO $ {# call file_get_parse_name #} (toFile file) >>= readUTFString
-- | Gets the parent directory for the file. If the file represents the root directory of the file
-- system, then 'Nothing' will be returned.
--
-- This call does no blocking i/o.
fileParent :: FileClass file => file -> Maybe File
fileParent file =
unsafePerformIO $ {# call file_get_parent #} (toFile file) >>= maybePeek takeGObject
#if GLIB_CHECK_VERSION(2,24,0)
-- | Checks if file has a parent, and optionally, if it is parent.
--
-- If parent is 'Nothing' then this function returns 'True' if file has any parent at all. If parent is
-- non-'Nothing' then 'True' is only returned if file is a child of parent.
fileHasParent :: FileClass file => file -> Maybe File -> Bool
fileHasParent file parent =
unsafePerformIO $ liftM toBool $
withGObject (toFile file) $ \cFile ->
maybeWith withGObject parent $ \parentPtr ->
g_file_has_parent cFile parentPtr
where _ = {#call file_has_parent #}
#endif
-- | Gets a child of file with basename equal to name.
--
-- Note that the file with that specific name might not exist, but you can still have a GFile that
-- points to it. You can use this for instance to create that file.
--
-- This call does no blocking i/o.
fileGetChild :: FileClass file => file -> String -> File
fileGetChild file name =
unsafePerformIO $
withUTFString name $ \cName ->
{# call file_get_child #} (toFile file) cName >>= takeGObject
-- | Gets the child of file for a given 'name (i.e. a UTF8 version of the name)'. If this function
-- fails, it returns 'Nothing' and error will be set. This is very useful when constructing a GFile for a
-- new file and the user entered the filename in the user interface, for instance when you select a
-- directory and type a filename in the file selector.
--
-- This call does no blocking i/o.
fileGetChildForDisplayName :: FileClass file => file -> String -> Maybe File
fileGetChildForDisplayName file displayName =
unsafePerformIO $
withUTFString displayName $ \cDisplayName ->
propagateGError ({# call file_get_child_for_display_name #} (toFile file) cDisplayName) >>=
maybePeek takeGObject
-- | Checks whether file has the prefix specified by prefix. In other word, if the names of inital
-- elements of files pathname match prefix. Only full pathname elements are matched, so a path like
-- /foo is not considered a prefix of /foobar, only of / foo/bar.
--
-- This call does no i/o, as it works purely on names. As such it can sometimes return 'False' even if
-- file is inside a prefix (from a filesystem point of view), because the prefix of file is an alias of
-- prefix.
fileHasPrefix :: (FileClass file1, FileClass file2) => file1 -> file2 -> Bool
fileHasPrefix file1 file2 =
unsafePerformIO $
liftM toBool $ {# call file_has_prefix #} (toFile file1) (toFile file2)
-- | Gets the path for descendant relative to parent.
--
-- This call does no blocking i/o.
fileGetRelativePath :: (FileClass file1, FileClass file2) => file1 -> file2 -> Maybe FilePath
fileGetRelativePath file1 file2 =
unsafePerformIO $
{# call file_get_relative_path #} (toFile file1) (toFile file2) >>=
maybePeek readUTFString
-- | Resolves a relative path for file to an absolute path.
--
-- This call does no blocking i/o.
fileResolveRelativePath :: FileClass file => file -> FilePath -> Maybe File
fileResolveRelativePath file relativePath =
unsafePerformIO $
withUTFString relativePath $ \cRelativePath ->
{# call file_resolve_relative_path #} (toFile file) cRelativePath >>=
maybePeek takeGObject
-- | Checks to see if a file is native to the platform.
--
-- A native file s one expressed in the platform-native filename format, e.g. \"C:\\Windows\" or
-- \"/usr/bin/\". This does not mean the file is local, as it might be on a locally mounted remote
-- filesystem.
--
-- On some systems non-native files may be available using the native filesystem via a userspace
-- filesystem (FUSE), in these cases this call will return @False@, but 'fileGetPath' will still
-- return a native path.
--
-- This call does no blocking i/o.
fileIsNative :: FileClass file => file -> Bool
fileIsNative =
unsafePerformIO .
liftM toBool . {# call file_is_native #} . toFile
-- | Checks to see if a 'GFile' has a given URI scheme.
--
-- This call does no blocking i/o.
fileHasURIScheme :: FileClass file => file -> String -> Bool
fileHasURIScheme file uriScheme =
unsafePerformIO $
withUTFString uriScheme $ \cURIScheme ->
liftM toBool $ {# call file_has_uri_scheme #} (toFile file) cURIScheme
-- | Gets the URI scheme for a GFile. RFC 3986 decodes the scheme as:
--
-- URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
--
-- Common schemes include "file", "http", "ftp", etc.
--
-- This call does no blocking i/o.
fileURIScheme :: FileClass file => file -> String
fileURIScheme file =
unsafePerformIO $ {# call file_get_uri_scheme #} (toFile file) >>= readUTFString
-- | Opens a file for reading. The result is a GFileInputStream that can be used to read the contents of
-- the file.
--
-- If cancellable is not 'Nothing', then the operation can be cancelled by triggering the cancellable object
-- from another thread. If the operation was cancelled, the error GIoErrorCancelled will be
-- returned.
--
-- If the file does not exist, the GIoErrorNotFound error will be returned. If the file is a
-- directory, the GIoErrorIsDirectory error will be returned. Other errors are possible too, and
-- depend on what kind of filesystem the file is on.
fileRead :: FileClass file => file -> Maybe Cancellable -> IO FileInputStream
fileRead file (Just cancellable) = constructNewGObject mkFileInputStream $
propagateGError $ {# call file_read #} (toFile file) cancellable
fileRead file Nothing = constructNewGObject mkFileInputStream $
propagateGError $ {# call file_read #} (toFile file) (Cancellable nullForeignPtr)
-- | Asynchronously opens file for reading.
--
-- For more details, see 'fileRead' which is the synchronous version of this call.
--
-- When the operation is finished, callback will be called. You can then call 'fileReadFinish' to
-- get the result of the operation.
fileReadAsync :: FileClass file
=> file
-> Int
-> Maybe Cancellable
-> AsyncReadyCallback
-> IO ()
fileReadAsync file ioPriority mbCancellable callback =
withGObject (toFile file) $ \cFile ->
maybeWith withGObject mbCancellable $ \cCancellable -> do
cCallback <- marshalAsyncReadyCallback callback
g_file_read_async cFile
(fromIntegral ioPriority)
cCancellable
cCallback
(castFunPtrToPtr cCallback)
where _ = {# call file_read_async #}
-- | Finishes an asynchronous file read operation started with 'fileReadAsync'.
fileReadFinish :: FileClass file
=> file
-> AsyncResult
-> IO FileInputStream
fileReadFinish file asyncResult =
propagateGError ({# call file_read_finish #} (toFile file) asyncResult) >>= takeGObject
-- | Gets an output stream for appending data to the file. If the file doesn't already exist it is
-- created.
--
-- By default files created are generally readable by everyone, but if you pass GFileCreatePrivate
-- in flags the file will be made readable only to the current user, to the level that is supported on
-- the target filesystem.
--
-- If cancellable is not 'Nothing', then the operation can be cancelled by triggering the cancellable object
-- from another thread. If the operation was cancelled, the error GIoErrorCancelled will be
-- returned.
--
-- Some file systems don't allow all file names, and may return an GIoErrorInvalidFilename
-- error. If the file is a directory the GIoErrorIsDirectory error will be returned. Other errors
-- are possible too, and depend on what kind of filesystem the file is on.
fileAppendTo :: FileClass file
=> file
-> [FileCreateFlags]
-> Maybe Cancellable
-> IO FileOutputStream
fileAppendTo file flags cancellable =
withGObject (toFile file) $ \cFile ->
maybeWith withGObject cancellable $ \cCancellable ->
propagateGError (g_file_append_to cFile (cFromFlags flags) cCancellable) >>=
takeGObject
where _ = {# call file_append_to #}
-- | Creates a new file and returns an output stream for writing to it. The file must not already exist.
--
-- By default files created are generally readable by everyone, but if you pass GFileCreatePrivate
-- in flags the file will be made readable only to the current user, to the level that is supported on
-- the target filesystem.
--
-- If cancellable is not 'Nothing', then the operation can be cancelled by triggering the cancellable object
-- from another thread. If the operation was cancelled, the error GIoErrorCancelled will be
-- returned.
--
-- If a file or directory with this name already exists the GIoErrorExists error will be
-- returned. Some file systems don't allow all file names, and may return an
-- GIoErrorInvalidFilename error, and if the name is to long GIoErrorFilenameTooLong will be
-- returned. Other errors are possible too, and depend on what kind of filesystem the file is on.
fileCreate :: FileClass file
=> file
-> [FileCreateFlags]
-> Maybe Cancellable
-> IO FileOutputStream
fileCreate file flags cancellable =
withGObject (toFile file) $ \cFile ->
maybeWith withGObject cancellable $ \cCancellable ->
propagateGError (g_file_create cFile (cFromFlags flags) cCancellable) >>=
takeGObject
where _ = {# call file_create #}
-- | Returns an output stream for overwriting the file, possibly creating a backup copy of the file
-- first. If the file doesn't exist, it will be created.
--
-- This will try to replace the file in the safest way possible so that any errors during the writing
-- will not affect an already existing copy of the file. For instance, for local files it may write to
-- a temporary file and then atomically rename over the destination when the stream is closed.
--
-- By default files created are generally readable by everyone, but if you pass GFileCreatePrivate
-- in flags the file will be made readable only to the current user, to the level that is supported on
-- the target filesystem.
--
-- If cancellable is not 'Nothing', then the operation can be cancelled by triggering the cancellable object
-- from another thread. If the operation was cancelled, the error GIoErrorCancelled will be
-- returned.
--
-- If you pass in a non-'Nothing' etag value, then this value is compared to the current entity tag of the
-- file, and if they differ an GIoErrorWrongEtag error is returned. This generally means that the
-- file has been changed since you last read it. You can get the new etag from
-- 'fileOutputStreamGetEtag' after you've finished writing and closed the GFileOutputStream.
-- When you load a new file you can use 'fileInputStreamQueryInfo' to get the etag of the file.
--
-- If @makeBackup@ is 'True', this function will attempt to make a backup of the current file before
-- overwriting it. If this fails a GIoErrorCantCreateBackup error will be returned. If you want to
-- replace anyway, try again with @makeBackup@ set to 'False'.
--
-- If the file is a directory the GIoErrorIsDirectory error will be returned, and if the file is
-- some other form of non-regular file then a GIoErrorNotRegularFile error will be returned. Some
-- file systems don't allow all file names, and may return an GIoErrorInvalidFilename error, and if
-- the name is to long GIoErrorFilenameTooLong will be returned. Other errors are possible too,
-- and depend on what kind of filesystem the file is on.
fileReplace :: FileClass file
=> file
-> Maybe String
-> Bool
-> [FileCreateFlags]
-> Maybe Cancellable
-> IO FileOutputStream
fileReplace file etag makeBackup flags cancellable =
withGObject (toFile file) $ \cFile ->
maybeWith withUTFString etag $ \cEtag ->
maybeWith withGObject cancellable $ \cCancellable ->
propagateGError (g_file_replace cFile
cEtag
(fromBool makeBackup)
(cFromFlags flags) cCancellable) >>=
takeGObject
where _ = {# call file_replace #}
-- | Asynchronously opens file for appending.
--
-- For more details, see 'fileAppendTo' which is the synchronous version of this call.
--
-- When the operation is finished, callback will be called. You can then call 'fileAppendToFinish'
-- to get the result of the operation.
fileAppendToAsync :: FileClass file
=> file
-> [FileCreateFlags]
-> Int
-> Maybe Cancellable
-> AsyncReadyCallback
-> IO ()
fileAppendToAsync file flags ioPriority cancellable callback =
withGObject (toFile file) $ \cFile ->
maybeWith withGObject cancellable $ \cCancellable -> do
cCallback <- marshalAsyncReadyCallback callback
g_file_append_to_async cFile
(cFromFlags flags)
(fromIntegral ioPriority)
cCancellable
cCallback
(castFunPtrToPtr cCallback)
where _ = {# call file_append_to_async #}
-- | Finishes an asynchronous file append operation started with 'fileAppendToAsync'.
fileAppendToFinish :: FileClass file
=> file
-> AsyncResult
-> IO FileOutputStream
fileAppendToFinish file asyncResult =
propagateGError ({# call file_append_to_finish #} (toFile file) asyncResult) >>= takeGObject
-- | Asynchronously creates a new file and returns an output stream for writing to it. The file must not
-- already exist.
--
-- For more details, see 'fileCreate' which is the synchronous version of this call.
--
-- When the operation is finished, callback will be called. You can then call 'fileCreateFinish' to
-- get the result of the operation.
fileCreateAsync :: FileClass file
=> file
-> [FileCreateFlags]
-> Int
-> Maybe Cancellable
-> AsyncReadyCallback
-> IO ()
fileCreateAsync file flags ioPriority cancellable callback =
withGObject (toFile file) $ \cFile ->
maybeWith withGObject cancellable $ \cCancellable -> do
cCallback <- marshalAsyncReadyCallback callback
g_file_create_async cFile
(cFromFlags flags)
(fromIntegral ioPriority)
cCancellable
cCallback
(castFunPtrToPtr cCallback)
where _ = {# call file_create_async #}
-- | Finishes an asynchronous file create operation started with 'fileCreateAsync'.
fileCreateFinish :: FileClass file
=> file
-> AsyncResult
-> IO FileOutputStream
fileCreateFinish file asyncResult =
propagateGError ({# call file_create_finish #} (toFile file) asyncResult) >>= takeGObject
-- | Asynchronously overwrites the file, replacing the contents, possibly creating a backup copy of the
-- file first.
--
-- For more details, see 'fileReplace' which is the synchronous version of this call.
--
-- When the operation is finished, callback will be called. You can then call 'fileReplaceFinish'
-- to get the result of the operation.
fileReplaceAsync :: FileClass file
=> file
-> String
-> Bool
-> [FileCreateFlags]
-> Int
-> Maybe Cancellable
-> AsyncReadyCallback
-> IO ()
fileReplaceAsync file etag makeBackup flags ioPriority cancellable callback =
withGObject (toFile file) $ \cFile ->
withUTFString etag $ \cEtag ->
maybeWith withGObject cancellable $ \cCancellable -> do
cCallback <- marshalAsyncReadyCallback callback
g_file_replace_async cFile
cEtag
(fromBool makeBackup)
(cFromFlags flags)
(fromIntegral ioPriority)
cCancellable
cCallback
(castFunPtrToPtr cCallback)
where _ = {# call file_replace_async #}
-- | Finishes an asynchronous file replace operation started with 'fileReplaceAsync'.
fileReplaceFinish :: FileClass file
=> file
-> AsyncResult
-> IO FileOutputStream
fileReplaceFinish file asyncResult =
propagateGError ({# call file_replace_finish #} (toFile file) asyncResult) >>= takeGObject
-- | Gets the requested information about specified file. The result is a 'GFileInfo' object that contains
-- key-value attributes (such as the type or size of the file).
--
-- The attribute value is a string that specifies the file attributes that should be gathered. It is
-- not an error if it's not possible to read a particular requested attribute from a file - it just
-- won't be set. attribute should be a comma-separated list of attribute or attribute wildcards. The
-- wildcard \"*\" means all attributes, and a wildcard like \"standard::*\" means all attributes in the
-- standard namespace. An example attribute query be \"standard::*,'user'\". The standard attributes
-- are available as defines, like 'GFileAttributeStandardName'.
--
-- If cancellable is not 'Nothing', then the operation can be cancelled by triggering the cancellable object
-- from another thread. If the operation was cancelled, the error 'GIoErrorCancelled' will be
-- returned.
--
-- For symlinks, normally the information about the target of the symlink is returned, rather than
-- information about the symlink itself. However if you pass 'GFileQueryInfoNofollowSymlinks' in
-- flags the information about the symlink itself will be returned. Also, for symlinks that point to
-- non-existing files the information about the symlink itself will be returned.
--
-- If the file does not exist, the 'GIoErrorNotFound' error will be returned. Other errors are
-- possible too, and depend on what kind of filesystem the file is on.
fileQueryInfo :: FileClass file
=> file
-> String
-> [FileQueryInfoFlags]
-> Maybe Cancellable
-> IO FileInfo
fileQueryInfo file attributes flags cancellable =
withGObject (toFile file) $ \cFile ->
withUTFString attributes $ \cAttributes ->
maybeWith withGObject cancellable $ \cCancellable ->
propagateGError (g_file_query_info cFile cAttributes (cFromFlags flags) cCancellable) >>=
takeGObject
where _ = {# call file_query_info #}
-- | Asynchronously gets the requested information about specified file. The
-- result is a 'GFileInfo' object that contains key-value attributes (such as
-- type or size for the file).
--
-- For more details, see 'fileQueryInfo' which is the synchronous version of
-- this call.
--
-- When the operation is finished, callback will be called. You can then call
-- 'fileQueryInfoFinish' to get the result of the operation.
fileQueryInfoAsync :: FileClass file
=> file
-> String
-> [FileQueryInfoFlags]
-> Int
-> Maybe Cancellable
-> AsyncReadyCallback
-> IO ()
fileQueryInfoAsync file attributes flags ioPriority cancellable callback =
withGObject (toFile file) $ \cFile ->
withUTFString attributes $ \cAttributes ->
maybeWith withGObject cancellable $ \cCancellable -> do
cCallback <- marshalAsyncReadyCallback callback
g_file_query_info_async cFile
cAttributes
(cFromFlags flags)
(fromIntegral ioPriority)
cCancellable
cCallback
(castFunPtrToPtr cCallback)
where _ = {# call file_query_info_async #}
-- | Finishes an asynchronous file info query. See 'fileQueryInfoAsync'.
fileQueryInfoFinish :: FileClass file
=> file
-> AsyncResult
-> IO FileInfo
fileQueryInfoFinish file asyncResult =
propagateGError ({#call file_query_info_finish #} (toFile file) asyncResult) >>= takeGObject
-- | Utility function to check if a particular file exists. This is implemented using 'fileQueryInfo'
-- and as such does blocking I/O.
--
-- Note that in many cases it is racy to first check for file existence and then execute something
-- based on the outcome of that, because the file might have been created or removed in between the
-- operations. The general approach to handling that is to not check, but just do the operation and
-- handle the errors as they come.
--
-- As an example of race-free checking, take the case of reading a file, and if it doesn't exist,
-- creating it. There are two racy versions: read it, and on error create it; and: check if it exists,
-- if not create it. These can both result in two processes creating the file (with perhaps a partially
-- written file as the result). The correct approach is to always try to create the file with
-- 'fileCreate' which will either atomically create the file or fail with a GIoErrorExists error.
--
-- However, in many cases an existence check is useful in a user interface, for instance to make a menu
-- item sensitive/ insensitive, so that you don't have to fool users that something is possible and
-- then just show and error dialog. If you do this, you should make sure to also handle the errors that
-- can happen due to races when you execute the operation.
fileQueryExists :: FileClass file
=> file
-> Maybe Cancellable
-> IO Bool
fileQueryExists file cancellable =
withGObject (toFile file) $ \cFile ->
maybeWith withGObject cancellable $ \cCancellable ->
liftM toBool $ g_file_query_exists cFile cCancellable
where _ = {# call file_query_exists #}
#if GLIB_CHECK_VERSION(2,18,0)
-- | Utility function to inspect the GFileType of a file. This is implemented using 'fileQueryInfo'
-- and as such does blocking I/O.
--
-- The primary use case of this method is to check if a file is a regular file, directory, or symlink.
fileQueryFileType :: FileClass file
=> file
-> [FileQueryInfoFlags]
-> Maybe Cancellable
-> IO FileType
fileQueryFileType file flags cancellable =
liftM (toEnum . fromIntegral) $
withGObject (toFile file) $ \cFile ->
maybeWith withGObject cancellable $ \cCancellable ->
(g_file_query_file_type cFile (cFromFlags flags) cCancellable)
where _ = {# call file_query_file_type #}
#endif
-- | Similar to 'fileQueryInfo', but obtains information about the filesystem the file is on, rather
-- than the file itself. For instance the amount of space available and the type of the filesystem.
--
-- The attribute value is a string that specifies the file attributes that should be gathered. It is
-- not an error if it's not possible to read a particular requested attribute from a file - it just
-- won't be set. attribute should be a comma-separated list of attribute or attribute wildcards. The
-- wildcard "*" means all attributes, and a wildcard like "fs:*" means all attributes in the fs
-- namespace. The standard namespace for filesystem attributes is "fs". Common attributes of interest
-- are 'FILEAttributeFilesystemSize (The Total Size Of The Filesystem In Bytes)',
-- 'FILEAttributeFilesystemFree (Number Of Bytes Available)', and GFileAttributeFilesystemType
-- (type of the filesystem).
--
-- If cancellable is not 'Nothing', then the operation can be cancelled by triggering the cancellable object
-- from another thread. If the operation was cancelled, the error GIoErrorCancelled will be
-- returned.
--
-- If the file does not exist, the GIoErrorNotFound error will be returned. Other errors are
-- possible too, and depend on what kind of filesystem the file is on.
fileQueryFilesystemInfo :: FileClass file
=> file
-> String
-> Maybe Cancellable
-> IO FileInfo
fileQueryFilesystemInfo file attributes cancellable =
withGObject (toFile file) $ \cFile ->
withUTFString attributes $ \cAttributes ->
maybeWith withGObject cancellable $ \cCancellable ->
propagateGError (g_file_query_filesystem_info cFile cAttributes cCancellable) >>=
takeGObject
where _ = {# call file_query_filesystem_info #}
-- | Asynchronously gets the requested information about the filesystem that the specified file is
-- on. The result is a GFileInfo object that contains key-value attributes (such as type or size for
-- the file).
--
-- For more details, see 'fileQueryFilesystemInfo' which is the synchronous version of this call.
--
-- When the operation is finished, callback will be called. You can then call
-- 'fileQueryInfoFinish' to get the result of the operation.
fileQueryFilesystemInfoAsync :: FileClass file
=> file
-> String
-> Int
-> Maybe Cancellable
-> AsyncReadyCallback
-> IO ()
fileQueryFilesystemInfoAsync file attributes ioPriority cancellable callback =
withGObject (toFile file) $ \cFile ->
withUTFString attributes $ \cAttributes ->
maybeWith withGObject cancellable $ \cCancellable -> do
cCallback <- marshalAsyncReadyCallback callback
g_file_query_filesystem_info_async cFile
cAttributes
(fromIntegral ioPriority)
cCancellable
cCallback
(castFunPtrToPtr cCallback)
where _ = {# call file_query_filesystem_info_async #}
-- | Finishes an asynchronous filesystem info query. See 'fileQueryFilesystemInfoAsync'.
fileQueryFilesystemInfoFinish :: FileClass file
=> file
-> AsyncResult
-> IO FileInfo
fileQueryFilesystemInfoFinish file asyncResult =
propagateGError ({# call file_query_filesystem_info_finish #} (toFile file) asyncResult) >>=
takeGObject
-- | Returns the GAppInfo that is registered as the default application to handle the file specified by
-- file.
--
-- If cancellable is not 'Nothing', then the operation can be cancelled by triggering the cancellable object
-- from another thread. If the operation was cancelled, the error GIoErrorCancelled will be
-- returned.
fileQueryDefaultHandler :: FileClass file
=> file
-> Maybe Cancellable
-> IO AppInfo
fileQueryDefaultHandler file cancellable =
withGObject (toFile file) $ \cFile ->
maybeWith withGObject cancellable $ \cCancellable ->
propagateGError (g_file_query_default_handler cFile cCancellable) >>=
takeGObject
where _ = {# call file_query_default_handler #}
-- | Gets a GMount for the GFile.
--
-- If the GFileIface for file does not have a mount (e.g. possibly a remote share), error will be set
-- to GIoErrorNotFound and 'Nothing' will be returned.
--
-- If cancellable is not 'Nothing', then the operation can be cancelled by triggering the cancellable object
-- from another thread. If the operation was cancelled, the error GIoErrorCancelled will be
-- returned.
fileFindEnclosingMount :: FileClass file
=> file
-> Maybe Cancellable
-> IO Mount
fileFindEnclosingMount file cancellable =
withGObject (toFile file) $ \cFile ->
maybeWith withGObject cancellable $ \cCancellable ->
propagateGError (g_file_find_enclosing_mount cFile cCancellable) >>=
takeGObject
where _ = {# call file_find_enclosing_mount #}
-- | Asynchronously gets the mount for the file.
--
-- For more details, see 'fileFindEnclosingMount' which is the synchronous version of this call.
--
-- When the operation is finished, callback will be called. You can then call
-- 'fileFindEnclosingMountFinish' to get the result of the operation.
fileFindEnclosingMountAsync :: FileClass file
=> file
-> Int
-> Maybe Cancellable
-> AsyncReadyCallback
-> IO ()
fileFindEnclosingMountAsync file ioPriority cancellable callback =
withGObject (toFile file) $ \cFile ->
maybeWith withGObject cancellable $ \cCancellable -> do
cCallback <- marshalAsyncReadyCallback callback
g_file_find_enclosing_mount_async cFile
(fromIntegral ioPriority)
cCancellable
cCallback
(castFunPtrToPtr cCallback)
where _ = {# call file_find_enclosing_mount_async #}
-- | Finishes an asynchronous find mount request. See 'fileFindEnclosingMountAsync'.
fileFindEnclosingMountFinish :: FileClass file
=> file
-> AsyncResult
-> IO Mount
fileFindEnclosingMountFinish file asyncResult =
propagateGError ({# call file_find_enclosing_mount_finish #} (toFile file) asyncResult) >>=
takeGObject
-- | Gets the requested information about the files in a directory. The result is a 'GFileEnumerator'
-- object that will give out 'GFileInfo' objects for all the files in the directory.
--
-- The attribute value is a string that specifies the file attributes that should be gathered. It is
-- not an error if it's not possible to read a particular requested attribute from a file - it just
-- won't be set. attribute should be a comma-separated list of attribute or attribute wildcards. The
-- wildcard \"*\" means all attributes, and a wildcard like \"standard::*\" means all attributes in the
-- standard namespace. An example attribute query be \"standard::*,'user'\". The standard attributes
-- are available as defines, like 'GFileAttributeStandardName'.
--
-- If cancellable is not @Nothing@, then the operation can be cancelled by triggering the cancellable object
-- from another thread. If the operation was cancelled, the error 'GIoErrorCancelled' will be
-- returned.
--
-- If the file does not exist, the 'GIoErrorNotFound' error will be returned. If the file is not a
-- directory, the 'GFileErrorNotdir' error will be returned. Other errors are possible too.
fileEnumerateChildren :: FileClass file
=> file
-> String
-> [FileQueryInfoFlags]
-> Maybe Cancellable
-> IO FileEnumerator
fileEnumerateChildren file attributes flags cancellable =
withGObject (toFile file) $ \cFile ->
withUTFString attributes $ \cAttributes ->
maybeWith withGObject cancellable $ \cCancellable ->
propagateGError (g_file_enumerate_children cFile cAttributes (cFromFlags flags) cCancellable) >>=
takeGObject
where _ = {# call file_enumerate_children #}
-- | Asynchronously gets the requested information about the files in a directory. The result is a
-- GFileEnumerator object that will give out GFileInfo objects for all the files in the directory.
--
-- For more details, see 'fileEnumerateChildren' which is the synchronous version of this call.
--
-- When the operation is finished, callback will be called. You can then call
-- 'fileEnumerateChildrenFinish' to get the result of the operation.
fileEnumerateChildrenAsync :: FileClass file
=> file
-> String
-> [FileQueryInfoFlags]
-> Int
-> Maybe Cancellable
-> AsyncReadyCallback
-> IO ()
fileEnumerateChildrenAsync file attributes flags ioPriority cancellable callback =
withGObject (toFile file) $ \cFile ->
withUTFString attributes $ \cAttributes ->
maybeWith withGObject cancellable $ \cCancellable -> do
cCallback <- marshalAsyncReadyCallback callback
g_file_enumerate_children_async cFile
cAttributes
(cFromFlags flags)
(fromIntegral ioPriority)
cCancellable
cCallback
(castFunPtrToPtr cCallback)
where _ = {# call file_enumerate_children_async #}
-- | Finishes an async enumerate children operation. See 'fileEnumerateChildrenAsync'.
fileEnumerateChildrenFinish :: FileClass file
=> file
-> AsyncResult
-> IO FileEnumerator
fileEnumerateChildrenFinish file asyncResult =
propagateGError ({# call file_enumerate_children_finish #} (toFile file) asyncResult) >>=
takeGObject
-- | Renames file to the specified display name.
--
-- The display name is converted from UTF8 to the correct encoding for the target filesystem if
-- possible and the file is renamed to this.
--
-- If you want to implement a rename operation in the user interface the edit name
-- (GFileAttributeStandardEditName) should be used as the initial value in the rename widget, and
-- then the result after editing should be passed to 'fileSetDisplayName'.
--
-- On success the resulting converted filename is returned.
--
-- If cancellable is not 'Nothing', then the operation can be cancelled by triggering the cancellable object
-- from another thread. If the operation was cancelled, the error GIoErrorCancelled will be
-- returned.
fileSetDisplayName :: FileClass file
=> file
-> String
-> Maybe Cancellable
-> IO File
fileSetDisplayName file displayName cancellable =
withGObject (toFile file) $ \cFile ->
withUTFString displayName $ \cDisplayName ->
maybeWith withGObject cancellable $ \cCancellable ->
propagateGError (g_file_set_display_name cFile cDisplayName cCancellable) >>=
takeGObject
where _ = {# call file_set_display_name #}
-- | Asynchronously sets the display name for a given GFile.
--
-- For more details, see 'fileSetDisplayName' which is the synchronous version of this call.
--
-- When the operation is finished, callback will be called. You can then call
-- 'fileSetDisplayNameFinish' to get the result of the operation.
fileSetDisplayNameAsync :: FileClass file
=> file
-> String
-> Int
-> Maybe Cancellable
-> AsyncReadyCallback
-> IO ()
fileSetDisplayNameAsync file displayName ioPriority cancellable callback =
withGObject (toFile file) $ \cFile ->
withUTFString displayName $ \cDisplayName ->
maybeWith withGObject cancellable $ \cCancellable -> do
cCallback <- marshalAsyncReadyCallback callback
g_file_set_display_name_async cFile
cDisplayName
(fromIntegral ioPriority)
cCancellable
cCallback
(castFunPtrToPtr cCallback)
where _ = {# call file_set_display_name_async #}
-- | Finishes setting a display name started with 'fileSetDisplayNameAsync'.
fileSetDisplayNameFinish :: FileClass file
=> file
-> AsyncResult
-> IO File
fileSetDisplayNameFinish file asyncResult =
propagateGError ({# call file_set_display_name_finish #} (toFile file) asyncResult) >>=
takeGObject
-- | Deletes a file. If the file is a directory, it will only be deleted if it is empty.
--
-- If cancellable is not 'Nothing', then the operation can be cancelled by triggering the cancellable object
-- from another thread. If the operation was cancelled, the error GIoErrorCancelled will be
-- returned.
fileDelete :: FileClass file
=> file
-> Maybe Cancellable
-> IO ()
fileDelete file cancellable =
withGObject (toFile file) $ \cFile ->
maybeWith withGObject cancellable $ \cCancellable ->
propagateGError (g_file_delete cFile cCancellable) >> return ()
where _ = {# call file_delete #}
-- | Sends file to the "Trashcan", if possible. This is similar to deleting it, but the user can recover
-- it before emptying the trashcan. Not all file systems support trashing, so this call can return the
-- GIoErrorNotSupported error.
--
-- If cancellable is not 'Nothing', then the operation can be cancelled by triggering the cancellable object
-- from another thread. If the operation was cancelled, the error GIoErrorCancelled will be
-- returned.
fileTrash :: FileClass file
=> file
-> Maybe Cancellable
-> IO ()
fileTrash file cancellable =
withGObject (toFile file) $ \cFile ->
maybeWith withGObject cancellable $ \cCancellable ->
propagateGError (g_file_trash cFile cCancellable) >> return ()
where _ = {# call file_trash #}
-- | Copies the file source to the location specified by destination. Can not handle recursive copies of
-- directories.
--
-- If the flag GFileCopyOverwrite is specified an already existing destination file is overwritten.
--
-- If the flag GFileCopyNofollowSymlinks is specified then symlinks will be copied as symlinks,
-- otherwise the target of the source symlink will be copied.
--
-- If cancellable is not 'Nothing', then the operation can be cancelled by triggering the cancellable object
-- from another thread. If the operation was cancelled, the error GIoErrorCancelled will be
-- returned.
--
-- If @progressCallback@ is not 'Nothing', then the operation can be monitored by setting this to a
-- GFileProgressCallback function. @progressCallbackData@ will be passed to this function. It is
-- guaranteed that this callback will be called after all data has been transferred with the total
-- number of bytes copied during the operation.
--
-- If the source file does not exist then the GIoErrorNotFound error is returned, independent on
-- the status of the destination.
--
-- If GFileCopyOverwrite is not specified and the target exists, then the error GIoErrorExists is
-- returned.
--
-- If trying to overwrite a file over a directory the GIoErrorIsDirectory error is returned. If
-- trying to overwrite a directory with a directory the GIoErrorWouldMerge error is returned.
--
-- If the source is a directory and the target does not exist, or GFileCopyOverwrite is specified
-- and the target is a file, then the GIoErrorWouldRecurse error is returned.
--
-- If you are interested in copying the GFile object itself (not the on-disk file), see 'fileDup'.
fileCopy :: (FileClass source, FileClass destination)
=> source
-> destination
-> [FileCopyFlags]
-> Maybe Cancellable
-> Maybe FileProgressCallback
-> IO Bool
fileCopy source destination flags cancellable progressCallback =
withGObject (toFile source) $ \cSource ->
withGObject (toFile destination) $ \cDestination ->
maybeWith withGObject cancellable $ \cCancellable -> do
cProgressCallback <- maybe (return nullFunPtr) marshalFileProgressCallback progressCallback
propagateGError $ \cError -> do
ret <- g_file_copy cSource
cDestination
(cFromFlags flags)
cCancellable
cProgressCallback
nullPtr
cError
when (cProgressCallback /= nullFunPtr) $
freeHaskellFunPtr cProgressCallback
return $ toBool ret
where _ = {# call file_copy #}
-- | Copies the file source to the location specified by destination asynchronously. For details of the
-- behaviour, see 'fileCopy'.
--
-- If @progressCallback@ is not 'Nothing', then that function that will be called just like in 'fileCopy',
-- however the callback will run in the main loop, not in the thread that is doing the I/O operation.
--
-- When the operation is finished, callback will be called. You can then call 'fileCopyFinish' to
-- get the result of the operation.
fileCopyAsync :: (FileClass source, FileClass destination)
=> source
-> destination
-> [FileCopyFlags]
-> Int
-> Maybe Cancellable
-> Maybe FileProgressCallback
-> AsyncReadyCallback
-> IO ()
fileCopyAsync source destination flags ioPriority cancellable progressCallback callback =
withGObject (toFile source) $ \cSource ->
withGObject (toFile destination) $ \cDestination ->
maybeWith withGObject cancellable $ \cCancellable -> do
cProgressCallback <- maybe (return nullFunPtr) marshalFileProgressCallback progressCallback
cCallback <- marshalAsyncReadyCallback $ \sourceObject res -> do
when (cProgressCallback /= nullFunPtr) $
freeHaskellFunPtr cProgressCallback
callback sourceObject res
g_file_copy_async cSource
cDestination
(cFromFlags flags)
(fromIntegral ioPriority)
cCancellable
cProgressCallback
nullPtr
cCallback
(castFunPtrToPtr cCallback)
where _ = {# call file_copy_async #}
-- | Finishes copying the file started with 'fileCopyAsync'.
fileCopyFinish :: FileClass file
=> file
-> AsyncResult
-> IO Bool
fileCopyFinish file asyncResult =
liftM toBool $ propagateGError ({# call file_copy_finish #} (toFile file) asyncResult)
-- | Tries to move the file or directory source to the location specified by destination. If native move
-- operations are supported then this is used, otherwise a copy + delete fallback is used. The native
-- implementation may support moving directories (for instance on moves inside the same filesystem),
-- but the fallback code does not.
--
-- If the flag GFileCopyOverwrite is specified an already existing destination file is overwritten.
--
-- If the flag GFileCopyNofollowSymlinks is specified then symlinks will be copied as symlinks,
-- otherwise the target of the source symlink will be copied.
--
-- If cancellable is not 'Nothing', then the operation can be cancelled by triggering the cancellable object
-- from another thread. If the operation was cancelled, the error GIoErrorCancelled will be
-- returned.
--
-- If @progressCallback@ is not 'Nothing', then the operation can be monitored by setting this to a
-- GFileProgressCallback function. @progressCallbackData@ will be passed to this function. It is
-- guaranteed that this callback will be called after all data has been transferred with the total
-- number of bytes copied during the operation.
--
-- If the source file does not exist then the GIoErrorNotFound error is returned, independent on
-- the status of the destination.
--
-- If GFileCopyOverwrite is not specified and the target exists, then the error GIoErrorExists is
-- returned.
--
-- If trying to overwrite a file over a directory the GIoErrorIsDirectory error is returned. If
-- trying to overwrite a directory with a directory the GIoErrorWouldMerge error is returned.
--
-- If the source is a directory and the target does not exist, or GFileCopyOverwrite is specified
-- and the target is a file, then the GIoErrorWouldRecurse error may be returned (if the native
-- move operation isn't available).
fileMove :: (FileClass source, FileClass destination)
=> source
-> destination
-> [FileCopyFlags]
-> Maybe Cancellable
-> Maybe FileProgressCallback
-> IO Bool
fileMove source destination flags cancellable progressCallback =
withGObject (toFile source) $ \cSource ->
withGObject (toFile destination) $ \cDestination ->
maybeWith withGObject cancellable $ \cCancellable -> do
cProgressCallback <- maybe (return nullFunPtr) marshalFileProgressCallback progressCallback
propagateGError $ \cError -> do
ret <- g_file_move cSource
cDestination
(cFromFlags flags)
cCancellable
cProgressCallback
nullPtr
cError
when (cProgressCallback /= nullFunPtr) $
freeHaskellFunPtr cProgressCallback
return $ toBool ret
where _ = {# call file_move #}
-- | Creates a directory. Note that this will only create a child directory of the immediate parent
-- directory of the path or URI given by the GFile. To recursively create directories, see
-- 'fileMakeDirectoryWithParents'. This function will fail if the parent directory does not
-- exist, setting error to GIoErrorNotFound. If the file system doesn't support creating
-- directories, this function will fail, setting error to GIoErrorNotSupported.
--
-- For a local GFile the newly created directory will have the default (current) ownership and
-- permissions of the current process.
--
-- If cancellable is not 'Nothing', then the operation can be cancelled by triggering the cancellable object
-- from another thread. If the operation was cancelled, the error GIoErrorCancelled will be
-- returned.
fileMakeDirectory :: FileClass file
=> file
-> Maybe Cancellable
-> IO ()
fileMakeDirectory file cancellable =
withGObject (toFile file) $ \cFile ->
maybeWith withGObject cancellable $ \cCancellable -> do
propagateGError $ g_file_make_directory cFile cCancellable
return ()
where _ = {# call file_make_directory #}
#if GLIB_CHECK_VERSION(2,18,0)
-- | Creates a directory and any parent directories that may not exist similar to 'mkdir -p'. If the file
-- system does not support creating directories, this function will fail, setting error to
-- GIoErrorNotSupported.
--
-- For a local GFile the newly created directories will have the default (current) ownership and
-- permissions of the current process.
--
-- If cancellable is not 'Nothing', then the operation can be cancelled by triggering the cancellable object
-- from another thread. If the operation was cancelled, the error GIoErrorCancelled will be
-- returned.
fileMakeDirectoryWithParents :: FileClass file
=> file
-> Maybe Cancellable
-> IO ()
fileMakeDirectoryWithParents file cancellable =
withGObject (toFile file) $ \cFile ->
maybeWith withGObject cancellable $ \cCancellable -> do
propagateGError $ g_file_make_directory_with_parents cFile cCancellable
return ()
where _ = {# call file_make_directory_with_parents #}
#endif
-- | Creates a symbolic link.
--
-- If cancellable is not 'Nothing', then the operation can be cancelled by triggering the cancellable object
-- from another thread. If the operation was cancelled, the error GIoErrorCancelled will be
-- returned.
fileMakeSymbolicLink :: FileClass file
=> file
-> String
-> Maybe Cancellable
-> IO ()
fileMakeSymbolicLink file symlinkValue cancellable =
withGObject (toFile file) $ \cFile ->
withUTFString symlinkValue $ \cSymlinkValue ->
maybeWith withGObject cancellable $ \cCancellable -> do
propagateGError $ g_file_make_symbolic_link cFile cSymlinkValue cCancellable
return ()
where _ = {# call file_make_symbolic_link #}
{# pointer *FileAttributeInfoList newtype #}
takeFileAttributeInfoList :: Ptr FileAttributeInfoList
-> IO [FileAttributeInfo]
takeFileAttributeInfoList ptr =
do cInfos <- liftM castPtr $ {# get FileAttributeInfoList->infos #} ptr
cNInfos <- {# get FileAttributeInfoList->n_infos #} ptr
infos <- peekArray (fromIntegral cNInfos) cInfos
g_file_attribute_info_list_unref ptr
return infos
where _ = {# call file_attribute_info_list_unref #}
-- | Obtain the list of settable attributes for the file.
--
-- Returns the type and full attribute name of all the attributes that can be set on this file. This
-- doesn't mean setting it will always succeed though, you might get an access failure, or some
-- specific file may not support a specific attribute.
--
-- If cancellable is not 'Nothing', then the operation can be cancelled by triggering the cancellable object
-- from another thread. If the operation was cancelled, the error GIoErrorCancelled will be
-- returned.
fileQuerySettableAttributes :: FileClass file
=> file
-> Maybe Cancellable
-> IO [FileAttributeInfo]
fileQuerySettableAttributes file cancellable =
withGObject (toFile file) $ \cFile ->
maybeWith withGObject cancellable $ \cCancellable -> do
ptr <- propagateGError $ g_file_query_settable_attributes cFile cCancellable
infos <- takeFileAttributeInfoList ptr
return infos
where _ = {# call file_query_settable_attributes #}
-- | Obtain the list of attribute namespaces where new attributes can be created by a user. An example of
-- this is extended attributes (in the "xattr" namespace).
--
-- If cancellable is not 'Nothing', then the operation can be cancelled by triggering the cancellable object
-- from another thread. If the operation was cancelled, the error GIoErrorCancelled will be
-- returned.
fileQueryWritableNamespaces :: FileClass file
=> file
-> Maybe Cancellable
-> IO [FileAttributeInfo]
fileQueryWritableNamespaces file cancellable =
withGObject (toFile file) $ \cFile ->
maybeWith withGObject cancellable $ \cCancellable -> do
ptr <- propagateGError $ g_file_query_writable_namespaces cFile cCancellable
infos <- takeFileAttributeInfoList ptr
return infos
where _ = {# call file_query_writable_namespaces #}