FileOperation.st
author Claus Gittinger <cg@exept.de>
Thu, 04 Mar 2004 11:08:18 +0100
changeset 5656 8402ac9f6398
parent 5342 4ea3ee096611
child 5673 3ed1092a3c73
permissions -rw-r--r--
internationalization

"{ Encoding: utf8 }"

"{ Package: 'stx:libtool2' }"

Object subclass:#FileOperation
	instanceVariableNames:'errorString result'
	classVariableNames:''
	poolDictionaries:''
	category:'Interface-Support'
!

FileOperation subclass:#Copy
	instanceVariableNames:'colOfCopiedFiles'
	classVariableNames:''
	poolDictionaries:''
	privateIn:FileOperation
!

FileOperation subclass:#Create
	instanceVariableNames:'createdFile'
	classVariableNames:'LastCreatedDirectory LastCreatedFile'
	poolDictionaries:''
	privateIn:FileOperation
!

FileOperation subclass:#Delete
	instanceVariableNames:'fileName'
	classVariableNames:''
	poolDictionaries:''
	privateIn:FileOperation
!

FileOperation subclass:#Move
	instanceVariableNames:'colOfMovedFiles'
	classVariableNames:''
	poolDictionaries:''
	privateIn:FileOperation
!

FileOperation subclass:#Rename
	instanceVariableNames:'renamedFiles'
	classVariableNames:''
	poolDictionaries:''
	privateIn:FileOperation
!


!FileOperation class methodsFor:'defaults'!

copyMoveIfExistSuffixString

    ^ '.copy'
! !

!FileOperation class methodsFor:'private class access'!

getCopyClass
    ^ Copy 
!

getCreateClass
    ^ Create 
!

getDeleteClass
    ^ Delete 
!

getMoveClass
    ^ Move
!

getRenameClass
    ^ Rename
! !

!FileOperation methodsFor:'accessing'!

errorString
    "return the value of the static variable 'ErrorString' (automatically generated)"

    ^ errorString
!

errorString:something
    "set the value of the static variable 'ErrorString' (automatically generated)"

    errorString := something.
!

result
    "return the value of the instance variable 'result' (automatically generated)"

    ^ result
!

result:something
    "set the value of the instance variable 'result' (automatically generated)"

    result := something.
! !

!FileOperation methodsFor:'dialogs'!

fileExistDialogForNewFile:newFile oldFile:oldFile withCancel:aBoolean
    "return true, if the file should be moved/copied.
     Ask user if oldFile exists."

    |msg oldSize newSize sameContents|

    newFile exists ifFalse:[ ^ true ].
    oldSize := oldFile fileSize.
    newSize := newFile fileSize.

    sameContents := oldSize = newSize and:[oldFile sameContentsAs:newFile].

    sameContents ifTrue:[
        msg := 'Overwrite existing file:\\  %1\    size: %3 of %2\\with (same contents):\\  %4\    size: %6 of %5'.
    ] ifFalse:[
        msg := 'Overwrite existing file:\\  %1\    size: %3 of %2\\with:\\  %4\    size: %6 of %5'.
    ].

    msg := AbstractFileBrowser classResources 
            stringWithCRs:msg
            withArgs:(Array
                with:newFile asString allBold
                with:(newFile modificationTime printStringFormat:'%(Day)-%(mon)-%(year) %h:%m:%s')
                with:newSize
                with:oldFile asString allBold 
                with:(oldFile modificationTime printStringFormat:'%(Day)-%(mon)-%(year) %h:%m:%s')
                with:oldSize).

    ^ Dialog confirm:(msg withCRs) withCancel:aBoolean.
! !

!FileOperation::Copy class methodsFor:'actions'!

copyFile:aSourceFile to:aDestFile
    "delete current selected files/directories
    "

    |instance|

    instance := self new.
    instance copyFile:aSourceFile to:aDestFile.
    ^ instance
!

copyFile:aSourceFile to:aDestFile withOverWriteWarning:overWriteWarning
    "delete current selected files/directories
    "

    |instance|

    instance := self new.
    instance copyFile:aSourceFile to:aDestFile withOverWriteWarning:overWriteWarning.
    ^ instance
!

copyFile:aSourceFile to:aDestFile withOverWriteWarning:overWriteWarning copyFileIfSame:copy
    "delete current selected files/directories
    "

    |instance|

    instance := self new.
    instance copyFile:aSourceFile to:aDestFile withOverWriteWarning:overWriteWarning copyFileIfSame:copy.
    ^ instance
!

copyFiles:aColOfSourceFiles to:aDirectory
    "delete current selected files/directories
    "

    |instance|

    instance := self new.
    instance copyFiles:aColOfSourceFiles to:aDirectory.
    ^ instance
!

copyFiles:aColOfSourceFiles to:aDirectory withOverWriteWarning:overWriteWarning
    "delete current selected files/directories
    "

    |instance|

    instance := self new.
    instance copyFiles:aColOfSourceFiles to:aDirectory withOverWriteWarning:overWriteWarning.
    ^ instance
!

copyFiles:aColOfSourceFiles to:aDirectory withOverWriteWarning:overWriteWarning copyFileIfSame:copy
    "delete current selected files/directories
    "

    |instance|

    instance := self new.
    instance copyFiles:aColOfSourceFiles to:aDirectory withOverWriteWarning:overWriteWarning copyFileIfSame:copy.
    ^ instance
! !

!FileOperation::Copy class methodsFor:'documentation'!

version
    ^ '$Header: /cvs/stx/stx/libtool/FileOperation.st,v 1.41 2004-03-04 10:08:18 cg Exp $'
! !

!FileOperation::Copy methodsFor:'accessing'!

colOfCopiedFiles
    "return the value of the instance variable 'colOfCopiedFiles' (automatically generated)"

    colOfCopiedFiles isNil ifTrue:[
        colOfCopiedFiles := OrderedCollection new.
    ].
    ^ colOfCopiedFiles
! !

!FileOperation::Copy methodsFor:'actions'!

copyFile:aSourceFile to:aDestFile
    "defete current selected files/directories
    "

    self copyFile:aSourceFile to:aDestFile withOverWriteWarning:true
!

copyFile:aSourceFile to:aDestFile withOverWriteWarning:overWriteWarning
    "copy to
    "

    self copyFile:aSourceFile to:aDestFile withOverWriteWarning:true copyFileIfSame:true
!

copyFile:aSourceFile to:aDestFile withOverWriteWarning:overWriteWarning copyFileIfSame:copy
    "copy to
    "

    |newFile fileString targetDirectory targetIsDirectory sourceIsDirectory suffix|

    sourceIsDirectory := aSourceFile isDirectory.
    targetIsDirectory := aDestFile isDirectory.
    targetIsDirectory ifTrue:[
        targetDirectory := aDestFile.
        newFile := aDestFile construct:(aSourceFile baseName).
    ] ifFalse:[
        targetDirectory := aDestFile directory.
        newFile := aDestFile.
    ].
    "/ do not copy if destination directory doest exist.
    (targetDirectory exists not) ifTrue:[
        Dialog warn:'cant copy to not existing directory ', targetDirectory asString. 
        result := false.
        ^ self
    ].
    (newFile exists) ifTrue:[
        ((newFile asString = aSourceFile asString) and:[copy]) ifTrue:[
            [newFile exists] whileTrue:[
                suffix := newFile suffix.
                fileString := newFile baseName withoutSuffix, self class copyMoveIfExistSuffixString, '.', suffix.
                newFile := targetDirectory construct:fileString.
            ].
        ] ifFalse:[
            overWriteWarning ifTrue:[
                (self fileExistDialogForNewFile:newFile oldFile:aSourceFile withCancel:false) ifFalse:[ 
                    result := false.
                    ^ self.
                ]
            ] ifFalse:[
                    result := false.
                    ^ self.
            ]
        ].
    ].
    Error handle:[:ex|
        "was not able to copy it"
        WarningBox warn:'on copy file - ', ex errorString.
        self errorString:('on copy file - ', ex description asString).
        result := false.
        ^ self
    ] do:[
        sourceIsDirectory ifTrue:[
            OperatingSystem recursiveCopyDirectory:(aSourceFile pathName) 
                                                to:(newFile pathName).
        ] ifFalse:[
            aSourceFile copyTo:newFile.
        ].
    ].
    DirectoryContents flushCachedDirectoryFor:(aSourceFile directory).
    result := true.
!

copyFiles:aColOfSourceFiles to:aDirectory

    ^ self copyFiles:aColOfSourceFiles to:aDirectory withOverWriteWarning:true. 
!

copyFiles:aColOfSourceFiles to:aDirectory withOverWriteWarning:overWriteWarning 

    ^ self copyFiles:aColOfSourceFiles to:aDirectory withOverWriteWarning:overWriteWarning copyFileIfSame:true.
!

copyFiles:aColOfSourceFiles to:aDirectory withOverWriteWarning:overWriteWarning copyFileIfSame:copy


    |newFile suffix fileString sourceIsDirectory askResult|

    (aDirectory exists not) ifTrue:[
        Dialog warn:'cant copy to not existing directory ', aDirectory asString. 
        result := false.
        ^ self
    ].
    (aDirectory isDirectory not) ifTrue:[
        Dialog warn:'destination ', aDirectory asString, ' is not a directory'. 
        result := false.
        ^ self
    ].
    aColOfSourceFiles do:[: filename |
        newFile := aDirectory construct:(filename baseName).
        sourceIsDirectory := filename isDirectory.
        (newFile exists) ifTrue:[
            askResult := true.
            ((newFile asString = filename asString) and:[copy]) ifTrue:[
                [newFile exists] whileTrue:[
                    suffix := newFile suffix.
                    fileString := newFile withoutSuffix baseName, self class copyMoveIfExistSuffixString.
                    suffix notEmpty ifTrue:[
                        fileString := fileString, '.', suffix.
                    ].
                    newFile := aDirectory construct:fileString.
                ].
            ] ifFalse:[
                overWriteWarning ifTrue:[
                    askResult := (self fileExistDialogForNewFile:newFile oldFile:filename withCancel:(aColOfSourceFiles size > 1)).
                    askResult isNil ifTrue:[
                        result := false.
                        ^ self.
                    ]
                ]
            ].
        ].
        askResult ifTrue:[
            Error handle:[:ex|
                "was not able to copy it"
                result := false.
                self errorString:('on copy file - ', ex description asString).
                ( Dialog 
                    confirm:('error on copy file - ', ex description asString) 
                    title:'Copy'
                    yesLabel:'Continue' 
                    noLabel:'Abort') ifFalse:[
                    ^ self.
                ].
            ] do:[
                sourceIsDirectory ifTrue:[
                    OperatingSystem recursiveCopyDirectory:(filename asString)  
                                                        to:(newFile asString).
                ] ifFalse:[
                    filename copyTo:newFile.
                ].
            ].
            self colOfCopiedFiles add:filename
        ]
    ].
    DirectoryContents flushCachedDirectoryFor:aDirectory.
    result := true.
! !

!FileOperation::Create class methodsFor:'actions'!

createDirectoryIn:aDirectory

    |instance|

    instance := self new.
    instance createDirectoryIn:aDirectory.
    ^ instance
!

createFileIn:aFile

    |instance|

    instance := self new.
    instance createFileIn:aFile.
    ^ instance
!

createHardLinkIn:aFile
    "create an new hard link in a files directory"

    |instance|

    instance := self new.
    instance createHardLinkIn:aFile.
    ^ instance
!

createSoftLinkIn:aFile
    "create an new soft link in a files directory"

    |instance|

    instance := self new.
    instance createSoftLinkIn:aFile.
    ^ instance
! !

!FileOperation::Create class methodsFor:'documentation'!

version
    ^ '$Header: /cvs/stx/stx/libtool/FileOperation.st,v 1.41 2004-03-04 10:08:18 cg Exp $'
! !

!FileOperation::Create methodsFor:'accessing'!

createdFile
    "return the value of the instance variable 'createdFile' (automatically generated)"

    ^ createdFile
!

createdFile:something
    "set the value of the instance variable 'createdFile' (automatically generated)"

    createdFile := something.
! !

!FileOperation::Create methodsFor:'actions'!

createDirectoryIn:startDirectory
    |defaultDirectory|

    "/ stupid - that one already exists
"/    LastCreatedDirectory notNil ifTrue:[
"/        defaultDirectory := LastCreatedDirectory baseName.
"/    ].
    
    ^ self createDirectoryIn:startDirectory initialAnswer:defaultDirectory
!

createDirectoryIn:startDirectory initialAnswer:initialAnswerArg
    |resources initialAnswer msg startBaseName newName newDir|

    resources := AbstractFileBrowser classResources.

    startBaseName := startDirectory baseName.
    initialAnswer := initialAnswerArg.
    (startDirectory construct:initialAnswer) exists ifTrue:[
        initialAnswer := nil.
    ].
    newName := Dialog
                    request:(resources string:'Create New Directory in %1:' with:startBaseName allBold)
                    initialAnswer:initialAnswer
                    okLabel:(resources string:'Create')
                    title:(resources string:'Create Directory')
                    onCancel:[
                        self result:false. 
                        ^ self
                    ].
    newName isEmpty ifTrue:[
        self result:false. 
        ^ self
    ].
    newDir := startDirectory construct:newName.
    newDir exists ifTrue:[
        Dialog warn:(newName, ' already exists.').
        result := false.
        ^ self
    ].

    newDir makeDirectory ifFalse:[
        msg := errorString := ('cannot create directory '', newName,'' !!') , '(', (OperatingSystem lastErrorString) , ')'.
        errorString := msg.
        Dialog warn:errorString.
        result := false.
        ^ self
    ].
    self createdFile:newDir.
    LastCreatedDirectory := newDir.
    result := true.
!

createFileIn:aFile
    "create an empty file"

    |resources aStream msg file directory newName defaultFile|

    resources := AbstractFileBrowser classResources.

    aFile isDirectory ifTrue:[
        directory := aFile
    ] ifFalse:[
        directory := aFile directory.
        file := aFile
    ].
    LastCreatedFile isNil ifTrue:[
        defaultFile := aFile baseName.
    ] ifFalse:[
        defaultFile := LastCreatedFile baseName.
    ].
    newName := Dialog
                    request:(resources string:'Create New File in %1:' with:directory baseName allBold)
                    initialAnswer:defaultFile
                    okLabel:(resources string:'Create')
                    title:(resources string:'Create File')
                    onCancel:[
                        self result:false. 
                        ^ self
                    ].
    newName isEmpty ifTrue:[
        self result:false. 
    ] ifFalse:[
        | newFile |
        newFile := directory construct:newName.
        newFile exists ifTrue:[
            (Dialog 
                confirm:(newName, ' already exists truncate ?')
                yesLabel:('Truncate')
                noLabel:('Cancel'))
            ifFalse:[
                self result:false. 
                ^ self
            ].
        ].
        FileStream openErrorSignal handle:[:ex|
            msg := ('Cannot create file '', newName,'' !!') , '(' , (FileStream lastErrorString) , ')'.
            errorString := msg.
            self result:false. 
            ^ Dialog warn:errorString
        ] do:[    
            aStream := newFile newReadWriteStream.
        ].
        aStream close.
        self createdFile:newFile.
        LastCreatedFile := newFile.
        self result:true. 
    ].
!

createHardLinkIn:aFile
    "create an new hard link in a files directory"

    self createLinkIn:aFile soft:false.
!

createLinkIn:aFile soft:symbolic
    "ask for the link target;
     then, create an new soft or hard link in aFile's directory"

    |resources newPath oldPath box string if1 if2|

    resources := AbstractFileBrowser classResources.

    aFile isDirectory ifTrue:[
        newPath := aFile asValue.
        oldPath := aFile asValue.
    ] ifFalse:[
        newPath := aFile directory asValue.
        oldPath := aFile asValue.
    ].

    box := Dialog new.
    box label:'Create Link'.

    string := 'Create ', (symbolic ifTrue:['Symbolic'] ifFalse:['Hard']) ,' Link from:'.
    (box addTextLabel:(resources string:string)) adjust:#left.
    if1 := box addFilenameInputFieldOn:newPath in:nil tabable:true.
    (box addTextLabel:(resources string:'to:')) adjust:#left.
    if2 := box addFilenameInputFieldOn:oldPath in:nil value tabable:true.

    box addAbortAndOkButtons.

    aFile isDirectory not ifTrue:[
        box focusOnField:if1.
    ].
    box showAtPointer.

    box accepted ifFalse:[
        self result:false.
    ] ifTrue:[
        self doCreateLinkFrom:(oldPath value) to:(newPath value) soft:symbolic.
    ].
!

createSoftLinkIn:aFile
    "create an new soft link in a files directory"

    self createLinkIn:aFile soft:true.
!

doCreateLinkFrom:oldPath to:newPath soft:symbolic
    "actually create a soft or hard link"

    |resources err newPathFile oldPathFile|

    resources := AbstractFileBrowser classResources.

    (oldPath size == 0) ifTrue:[
        self operationError:'no source entered'.
        ^ self.
    ].
    (newPath size == 0) ifTrue:[
        self operationError:'no link name entered'.
        ^ self.
    ].

    newPathFile := newPath asFilename.
    newPathFile exists ifTrue:[
        self operationError:(resources string:'%1 already exists' with:newPath allBold).
        ^ self.
    ].
    oldPathFile := oldPath asFilename.
    oldPathFile exists not ifTrue:[
        symbolic ifTrue:[
            oldPathFile isAbsolute ifTrue:[
                self operationError:(resources string:'%1 does not exist' with:oldPath allBold).
                ^ self.
            ].
            (newPathFile directory construct:oldPath) exists ifFalse:[
                Dialog warn:(resources string:'%1 does not exist (Warning only)' with:oldPath allBold).
            ].
        ] ifFalse:[
            self operationError:(resources string:'%1 does not exist' with:oldPath allBold).
            ^ self.
        ].
    ].
    ((symbolic not) and:[oldPathFile isDirectory]) ifTrue:[
        self operationError:(resources string:'%1 is a directory' with:oldPath allBold).
        ^ self.
    ].
    ErrorSignal handle:[:ex |
        err := ex errorString.
        self operationError:err.
    ] do:[
        symbolic ifTrue:[
            OperatingSystem createSymbolicLinkFrom:oldPath to:newPath.
        ] ifFalse:[
            OperatingSystem createHardLinkFrom:oldPath to:newPath
        ].
        self createdFile:newPathFile.
        self result:true.
    ].
!

operationError:msg
    self result:false.
    Dialog warn:msg.
    self errorString:msg.
! !

!FileOperation::Delete class methodsFor:'actions'!

deleteFile:aFileOrDirectory
    "delete current selected files/directories
    "

    |instance|

    instance := self new.
    instance deleteFile:aFileOrDirectory.
    ^ instance
!

deleteFiles:aColOfFiles
    "delete current selected files/directories
    "
    ^ self deleteFiles:aColOfFiles confirm:true
!

deleteFiles:aColOfFiles confirm:confirm
    "delete current selected files/directories
    "

    |instance|

    instance := self new.
    instance deleteFiles:aColOfFiles confirm:confirm.
    ^ instance
! !

!FileOperation::Delete class methodsFor:'documentation'!

version
    ^ '$Header: /cvs/stx/stx/libtool/FileOperation.st,v 1.41 2004-03-04 10:08:18 cg Exp $'
! !

!FileOperation::Delete methodsFor:'actions'!

deleteFile:aFileOrDirectory

    | file isDirectory |

    aFileOrDirectory notNil ifTrue:[
        file := aFileOrDirectory asFilename.

        isDirectory := file isDirectory.

        Error handle:[:ex|
            "was not able to remove it"
            Dialog warn:(ex description, '\', ex signal notifierString) withCRs.
"/                Smalltalk beep.
            self errorString:((ex description, ' - ', ex signal notifierString) withCRs).
            result := false.
            ^ self.
        ] do:[
            isDirectory ifTrue:[file recursiveRemove] ifFalse:[file remove].

        ].
        "/ flush parent directory or directory
    ].
    DirectoryContents flushCachedDirectoryFor:(file directory).
    result := true.
!

deleteFiles:colOfFiles
    "delete current selected files/directories
    "
    ^ self deleteFiles:colOfFiles confirm:true.
!

deleteFiles:colOfFiles confirm:confirm
    "delete current selected files/directories
    "
    |resources retVal nFilesToDelete ask labels values fileTypeString|

    ask := confirm.
    resources := AbstractFileBrowser classResources.

    nFilesToDelete := colOfFiles size.
    colOfFiles do:[:filenameOrString |
        |filename askForNonEmptyDirectory|

        filename := filenameOrString asFilename.

        fileTypeString := ''.
        filename isSymbolicLink ifTrue:[
            fileTypeString := 'symbolic link '.
        ] ifFalse:[        
            filename exists not ifTrue:[ 
                self warn:('%1 does not exist' bindWith:filename asString allBold).
                ^ self.
            ]
        ].
        ask ifTrue:[
            nFilesToDelete = 1 ifTrue:[
                labels := #('No' 'Yes').
                values := #(#no #yes).
            ] ifFalse:[
                labels := #('Cancel' 'No' 'Yes' 'Yes to All' ).
                values := #(#cancel #no #yes #yesToAll).
            ].
            retVal := Dialog 
                confirmWithCancel:(resources 
                                    stringWithCRs:'Really delete\\  %1%2%3 ?' 
                                    with:fileTypeString
                                    with:(filename asString allBold)
                                    with:(nFilesToDelete = 1 ifTrue:'' ifFalse:['\\(' , nFilesToDelete printString , ' files alltogether)']) withCRs )
                labels:(resources array:labels)
                values:values
                default:(values indexOf:#yes).
        ] ifFalse:[
            retVal := #yesToAll.
        ].
        retVal == #cancel ifTrue:[
            ^ self.
        ].

        retVal == #yesToAll ifTrue:[
            ask := false.
            retVal := #yes.
        ].
        retVal == #yes ifTrue:[
            askForNonEmptyDirectory := true.
            filename isSymbolicLink ifFalse:[
                filename isNonEmptyDirectory ifTrue:[
                    askForNonEmptyDirectory := Dialog
                                confirmWithCancel:(('Directory ''%1'' is not empty', Character cr asString, 'remove anyway ?') 
                                                    bindWith:filename pathName allBold) 
                                labels:( #('Cancel' 'Keep' 'Remove') )
                                values:#(nil false true) 
                                default:3.
                    askForNonEmptyDirectory == nil ifTrue:[
                        ^ self
                    ].
                ].
            ].
            askForNonEmptyDirectory ifTrue:[
                self deleteFile:filename.
            ]
        ].
    ].
! !

!FileOperation::Move class methodsFor:'actions'!

moveFile:aSourceFile to:aDestFile
    "delete current selected files/directories
    "

    |instance|

    instance := self new.
    instance moveFile:aSourceFile to:aDestFile.
    ^ instance
!

moveFile:aSourceFile to:aDestFile withOverWriteWarning:overWriteWarning
    "delete current selected files/directories
    "

    |instance|

    instance := self new.
    instance moveFile:aSourceFile to:aDestFile withOverWriteWarning:overWriteWarning.
    ^ instance
!

moveFile:aSourceFile to:aDestFile withOverWriteWarning:overWriteWarning moveFileIfSame:move
    "delete current selected files/directories
    "

    |instance|

    instance := self new.
    instance moveFile:aSourceFile to:aDestFile withOverWriteWarning:overWriteWarning moveFileIfSame:move.
    ^ instance
!

moveFiles:aColOfSourceFiles to:aDirectory
    "delete current selected files/directories
    "

    |instance|

    instance := self new.
    instance moveFiles:aColOfSourceFiles to:aDirectory.
    ^ instance
!

moveFiles:aColOfSourceFiles to:aDirectory withOverWriteWarning:overWriteWarning
    "delete current selected files/directories
    "

    |instance|

    instance := self new.
    instance moveFiles:aColOfSourceFiles to:aDirectory withOverWriteWarning:overWriteWarning.
    ^ instance
!

moveFiles:aColOfSourceFiles to:aDirectory withOverWriteWarning:overWriteWarning moveFileIfSame:move
    "delete current selected files/directories
    "

    |instance|

    instance := self new.
    instance moveFiles:aColOfSourceFiles to:aDirectory withOverWriteWarning:overWriteWarning moveFileIfSame:move.
    ^ instance
! !

!FileOperation::Move class methodsFor:'documentation'!

version
    ^ '$Header: /cvs/stx/stx/libtool/FileOperation.st,v 1.41 2004-03-04 10:08:18 cg Exp $'
! !

!FileOperation::Move methodsFor:'accessing'!

colOfMovedFiles
    "return the value of the instance variable 'colOfMovedFiles' (automatically generated)"

    colOfMovedFiles isNil ifTrue:[
        colOfMovedFiles := OrderedCollection new.
    ].
    ^ colOfMovedFiles
! !

!FileOperation::Move methodsFor:'actions'!

moveFile:aSourceFile to:aDestFile

    ^ self moveFile:aSourceFile to:aDestFile withOverWriteWarning:true.
!

moveFile:aSourceFile to:aDestFile withOverWriteWarning:overWriteWarning

    ^ self moveFile:aSourceFile to:aDestFile withOverWriteWarning:overWriteWarning moveFileIfSame:true
!

moveFile:aSourceFile to:aDestFile withOverWriteWarning:overWriteWarning moveFileIfSame:move

    |newFile fileString targetDirectory targetIsDirectory suffix|

    targetIsDirectory := aDestFile isDirectory.
    targetIsDirectory ifTrue:[
        targetDirectory := aDestFile.
        newFile := aDestFile construct:(aSourceFile baseName).
    ] ifFalse:[
        targetDirectory := aDestFile directory.
        newFile := aDestFile.
    ].
    "/ do not copy if destination directory doest exist.
    (targetDirectory exists not) ifTrue:[
        Dialog warn:'Cannot move to non-existing directory ', targetDirectory asString. 
        result := false.
        ^ self
    ].
    (newFile exists) ifTrue:[
        ((newFile asString = aSourceFile asString) and:[move]) ifTrue:[
            [newFile exists] whileTrue:[
                suffix := newFile suffix.
                fileString := newFile baseName withoutSuffix, self class copyMoveIfExistSuffixString, '.', suffix.
                newFile := targetDirectory construct:fileString.
            ].
        ] ifFalse:[
            overWriteWarning ifTrue:[
                (self fileExistDialogForNewFile:newFile oldFile:aSourceFile withCancel:false) ifFalse:[ 
                    result := false.
                    ^ self.
                ]
            ] ifFalse:[
                    result := false.
                    ^ self.
            ]
        ].
    ].
    Error handle:[:ex|
        "was not able to copy it"
        WarningBox warn:'Error in copy file Operation: ', ex errorString.
        self errorString:('Error in copy file Operation- ', ex description asString).
        result := false.
        ^ self
    ] do:[
        aSourceFile moveTo:newFile.
    ].
    DirectoryContents flushCachedDirectoryFor:(aSourceFile directory).
    result := true.
!

moveFiles:aColOfSourceFiles to:aDirectory

    ^ self moveFiles:aColOfSourceFiles to:aDirectory withOverWriteWarning:true
!

moveFiles:aColOfSourceFiles to:aDirectory withOverWriteWarning:overWriteWarning

    ^ self moveFiles:aColOfSourceFiles to:aDirectory withOverWriteWarning:overWriteWarning moveFileIfSame:true
!

moveFiles:aColOfSourceFiles to:aDirectory withOverWriteWarning:overWriteWarning moveFileIfSame:move

    |newFile suffix fileString askResult|

    (aDirectory exists not) ifTrue:[
        Dialog warn:('Cannot move to non-existing directory %1.' bindWith:aDirectory asString allBold).
        result := false.
        ^ self
    ].
    (aDirectory isDirectory not) ifTrue:[
        Dialog warn:('Destination %1 is not a directory.' bindWith:aDirectory asString allBold).
        result := false.
        ^ self
    ].
    aColOfSourceFiles do:[: filename |
        newFile := aDirectory construct:filename baseName.
        (newFile exists) ifTrue:[
            askResult := true.
            ((newFile asString = filename asString) and:[move]) ifTrue:[
                [newFile exists] whileTrue:[
                    suffix := newFile suffix.
                    fileString := newFile baseName withoutSuffix, self class copyMoveIfExistSuffixString, '.', suffix.
                    newFile := aDirectory construct:fileString.
                ].
            ] ifFalse:[
                overWriteWarning ifTrue:[
                    askResult := self fileExistDialogForNewFile:newFile oldFile:filename withCancel:(aColOfSourceFiles size > 1).
                    askResult isNil ifTrue:[
                        result := false.
                        ^ self.
                    ]
                ]
            ].
        ].

        askResult ifTrue:[
            Error handle:[:ex|
                "was not able to copy it"
                result := false.
                self errorString:(' Error in Move-File Operation:', ex description asString).
                ( Dialog 
                    confirm:(' Error in Move-File Operation: ', ex description asString) 
                    title:'Move'
                    yesLabel:'Continue' 
                    noLabel:'Abort') ifFalse:[
                    ^ self.
                ].
            ] do:[
                filename moveTo:newFile.
            ].
            self colOfMovedFiles add:filename
        ]
    ].
    DirectoryContents flushCachedDirectoryFor:aDirectory.
    result := true.
! !

!FileOperation::Rename class methodsFor:'actions'!

renameFile:oldFile to:newName
    "move from to
    "

    |instance|

    instance := self new.
    instance renameFile:oldFile to:newName.
    ^ instance
!

renameFiles:aColOfFiles 
    "move from to
    "

    |instance|

    instance := self new.
    instance renameFiles:aColOfFiles.
    ^ instance
! !

!FileOperation::Rename class methodsFor:'documentation'!

version
    ^ '$Header: /cvs/stx/stx/libtool/FileOperation.st,v 1.41 2004-03-04 10:08:18 cg Exp $'
! !

!FileOperation::Rename methodsFor:'accessing'!

renamedFiles
    "return the value of the instance variable 'lastRenamedFile' (automatically generated)"

    renamedFiles isNil ifTrue:[
        renamedFiles := OrderedCollection new.
    ].
    ^ renamedFiles
! !

!FileOperation::Rename methodsFor:'actions'!

renameFile:oldFile to:newName
    "rename a file (or directory)"

    |newFile msg resources|

    (oldFile isNil or:[newName isNil]) ifTrue:[
        result := false.
        ^ self.
    ].
    (oldFile asString isBlank or:[newName isBlank]) ifTrue:[
        result := false.
        ^ self.
    ].
    newName asFilename isAbsolute ifTrue:[
        newFile := newName asFilename.
    ] ifFalse:[
        (oldFile baseName = newName) ifTrue:[
            result := false
        ].
        newFile := oldFile directory construct:newName.
    ].

    oldFile pathName = newFile pathName ifTrue:[
        ^ self.
    ].

    resources := Dialog classResources.

    OperatingSystem errorSignal handle:[:ex|
        msg := resources 
                stringWithCRs:'Cannot rename file %1 to %2 !!\\(%3)' 
                with:oldFile baseName 
                with:newName 
                with:(OperatingSystem lastErrorString).
        Dialog warn:msg withCRs.
        result := false.
        ^ self.
    ] do:[
        newFile exists ifTrue:[
            (newFile sameContentsAs:oldFile) ifTrue:[
                msg := '%1 exists [with same contents] - rename (i.e. overwrite) anyway ?'
            ] ifFalse:[
                msg := '%1 exists - rename (i.e. overwrite) anyway ?'
            ].
            (Dialog confirmWithCancel:(resources string:msg with:newName allBold) default:false) ifFalse:[
                result := false.
                ^ self.
            ]
        ].
        oldFile renameTo:newFile.
        self renamedFiles add:newFile.
    ].
    result := true.
!

renameFiles:aColOfFiles 
    "rename the selected file(s)"

    |resources queryBox b lastNewName lastOldName initialText oldName|

    resources := AbstractFileBrowser classResources.

    queryBox := FilenameEnterBox new.
    queryBox okText:(resources string:'Rename').
    aColOfFiles size > 1 ifTrue:[
        b := queryBox addAbortButtonLabelled:(resources string:'Cancel All').
        b action:[^ self]
    ].
    aColOfFiles do:[:oldFile | 
        oldName := oldFile baseName asString.
        queryBox title:(resources string:'Rename %1 to:' with:(oldName allBold)).
        lastNewName notNil ifTrue:[
            initialText := FileBrowser goodRenameDefaultForFile:oldName lastOld:lastOldName lastNew:lastNewName
        ].
        queryBox initialText:(initialText ? oldName).
        queryBox 
            action:[:newName | 
                (self renameFile:oldFile to:newName asString) ifTrue:[
                    result := true
                ].
                lastOldName := oldName.
                lastNewName := newName.
            ].
        queryBox show "showAtPointer".
    ]
! !

!FileOperation class methodsFor:'documentation'!

version
    ^ '$Header: /cvs/stx/stx/libtool/FileOperation.st,v 1.41 2004-03-04 10:08:18 cg Exp $'
! !