LIB/GTK: add convenient renaming capabilities on file copy/move

This commit is contained in:
2016-04-09 17:25:14 +02:00
parent 0e226d61ec
commit 44a90574e8
2 changed files with 51 additions and 20 deletions

View File

@@ -139,6 +139,7 @@ data CopyMode = Strict -- ^ fail if the target already exists
-- is the same as Replace
| Replace -- ^ remove targets before copying, this is
-- only useful if the target is a directorty
| Rename (Path Fn)
-- |Run a given FileOperation. If the FileOperation is partial, it will
@@ -147,7 +148,7 @@ runFileOp :: FileOperation -> IO (Maybe FileOperation)
runFileOp (FCopy (CC froms to cm)) = mapM_ (\x -> easyCopy cm x to) froms
>> return Nothing
runFileOp (FCopy fo) = return $ Just $ FCopy fo
runFileOp (FMove (MC froms to cm)) = mapM_ (\x -> moveFile cm x to) froms
runFileOp (FMove (MC froms to cm)) = mapM_ (\x -> easyMove cm x to) froms
>> return Nothing
runFileOp (FMove fo) = return $ Just $ FMove fo
runFileOp (FDelete fp) = mapM_ easyDelete fp >> return Nothing
@@ -162,7 +163,6 @@ runFileOp _ = return Nothing
--------------------
-- TODO: allow renaming
-- |Copies a directory to the given destination with the specified
-- `DirCopyMode`. Excludes symlinks.
copyDir :: CopyMode
@@ -173,6 +173,12 @@ copyDir :: CopyMode
copyDir _ AFileInvFN _ _ = throw InvalidFileName
copyDir _ _ AFileInvFN _ = throw InvalidFileName
copyDir _ _ _ InvFN = throw InvalidFileName
copyDir (Rename fn)
from@(_ :/ Dir {})
to@(_ :/ Dir {})
_
= copyDir Strict from to fn
-- this branch must never get `Rename` as CopyMode
copyDir cm from@(_ :/ Dir _ FileInfo{ fileMode = fmode })
to@(_ :/ Dir {})
fn
@@ -211,6 +217,7 @@ copyDir cm from@(_ :/ Dir _ FileInfo{ fileMode = fmode })
(deleteDirRecursive =<<
HSFM.FileSystem.FileType.readFileWithFileInfo destdir)
createDirectory destdir' fmode'
_ -> throw $ InvalidOperation "Internal error, wrong CopyMode!"
copyDir _ _ _ _ = throw $ InvalidOperation "wrong input type"
@@ -224,6 +231,8 @@ recreateSymlink :: CopyMode
recreateSymlink _ AFileInvFN _ _ = throw InvalidFileName
recreateSymlink _ _ AFileInvFN _ = throw InvalidFileName
recreateSymlink _ _ _ InvFN = throw InvalidFileName
recreateSymlink (Rename pn) symf@(_ :/ SymLink {}) symdest@(_ :/ Dir {}) _
= recreateSymlink Strict symf symdest pn
recreateSymlink cm symf@(_ :/ SymLink {}) symdest@(_ :/ Dir {}) fn
= do
throwCantOpenDirectory $ fullPath symdest
@@ -253,6 +262,8 @@ copyFile :: CopyMode
copyFile _ AFileInvFN _ _ = throw InvalidFileName
copyFile _ _ AFileInvFN _ = throw InvalidFileName
copyFile _ _ _ InvFN = throw InvalidFileName
copyFile (Rename pn) from@(_ :/ RegFile {}) to@(_ :/ Dir {}) _
= copyFile Strict from to pn
copyFile cm from@(_ :/ RegFile {}) to@(_ :/ Dir {}) fn
= do
let from' = fullPath from
@@ -436,18 +447,22 @@ renameFile _ _ = throw $ InvalidOperation "wrong input type"
moveFile :: CopyMode
-> AnchoredFile FileInfo -- ^ file to move
-> AnchoredFile FileInfo -- ^ base target directory
-> Path Fn -- ^ target file name
-> IO ()
moveFile _ AFileInvFN _ = throw InvalidFileName
moveFile _ _ AFileInvFN = throw InvalidFileName
moveFile cm from to@(_ :/ Dir {}) = do
moveFile _ AFileInvFN _ _ = throw InvalidFileName
moveFile _ _ AFileInvFN _ = throw InvalidFileName
moveFile (Rename pn) from to@(_ :/ Dir {}) _ =
moveFile Strict from to pn
moveFile cm from to@(_ :/ Dir {}) fn = do
let from' = fullPath from
froms' = fullPathS from
to' = fullPath to P.</> (name . file $ from)
tos' = P.fromAbs (fullPath to P.</> (name . file $ from))
to' = fullPath to P.</> fn
tos' = P.fromAbs (fullPath to P.</> fn)
case cm of
Strict -> throwFileDoesExist to'
Merge -> delOld to'
Replace -> delOld to'
Strict -> throwFileDoesExist to'
Merge -> delOld to'
Replace -> delOld to'
Rename _ -> throw $ InvalidOperation "Internal error! Wrong CopyMode!"
throwSameFile from' to'
catchErrno eXDEV (rename froms' tos') $ do
easyCopy Strict from to
@@ -456,9 +471,15 @@ moveFile cm from to@(_ :/ Dir {}) = do
delOld fp = do
to' <- HSFM.FileSystem.FileType.readFileWithFileInfo fp
unless (failed . file $ to') (easyDelete to')
moveFile _ _ _ = throw $ InvalidOperation "wrong input type"
moveFile _ _ _ _ = throw $ InvalidOperation "wrong input type"
-- |Like `moveFile` except it uses the filename of the source as target.
easyMove :: CopyMode
-> AnchoredFile FileInfo -- ^ file to move
-> AnchoredFile FileInfo -- ^ base target directory
-> IO ()
easyMove cm from to = moveFile cm from to (name . file $ from)