"{ 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:''
classVariableNames:''
poolDictionaries:''
privateIn:FileOperation
!
FileOperation subclass:#Delete
instanceVariableNames:'fileName errorString'
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'!
copy
^ Copy
!
create
^ Create
!
delete
^ Delete
!
move
^ Move
!
rename
^ 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'!
fileExistDialogFor:aFile
^ self fileExistDialogFor:aFile withCancel:false.
!
fileExistDialogFor:aFile withCancel:aBoolean
| stream string|
aFile exists ifTrue:[
stream := WriteStream on:''.
stream nextPutAll:'overwrite '.
stream nextPutAll:(aFile asString).
stream nextPutAll:' from '.
(aFile modificationTime) printOn:stream format:'%(Day)-%(mon)-%(year) %h:%m:%s'.
stream nextPutAll:' with size of '.
stream nextPutAll:aFile fileSize asString.
stream cr.
stream nextPutAll:' with '.
stream nextPutAll:aFile asString.
stream nextPutAll:' from '.
(aFile modificationTime) printOn:stream format:'%(Day)-%(mon)-%(year) %h:%m:%s'.
stream nextPutAll:' with size of '.
stream nextPutAll:aFile fileSize asString.
string := stream contents.
stream close.
aBoolean ifTrue:[
^ (Dialog confirmWithCancel:(string)).
] ifFalse:[
^ (Dialog confirm:(string)).
].
].
^ true
! !
!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.2 2002-09-04 15:25:44 penk 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:[
DialogBox 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 fileExistDialogFor:newFile) 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.
] do:[
sourceIsDirectory ifTrue:[
OperatingSystem recursiveCopyDirectory:(aSourceFile pathName)
to:newFile.
] ifFalse:[
aSourceFile copyTo:newFile.
].
DirectoryContents flushCachedDirectory:(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:[
DialogBox warn:'cant copy to not existing directory ', aDirectory asString.
result := false.
^ self
].
(aDirectory isDirectory not) ifTrue:[
DialogBox 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 baseName withoutSuffix, self class copyMoveIfExistSuffixString, '.', suffix.
newFile := aDirectory construct:fileString.
].
] ifFalse:[
overWriteWarning ifTrue:[
askResult := (self fileExistDialogFor:newFile withCancel:true).
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 flushCachedDirectory:aDirectory.
result := true.
! !
!FileOperation::Create class methodsFor:'actions'!
createDirectory:newName
|instance|
instance := self new.
instance createDirectory:newName.
^ instance
!
createFile:newName
|instance|
instance := self new.
instance createFile:newName.
^ instance
! !
!FileOperation::Create class methodsFor:'documentation'!
version
^ '$Header: /cvs/stx/stx/libtool/FileOperation.st,v 1.2 2002-09-04 15:25:44 penk Exp $'
! !
!FileOperation::Create methodsFor:'actions'!
createDirectory:newName
|msg|
newName exists ifTrue:[
DialogBox warn:(newName, ' already exists.').
result := false.
^ self
].
newName makeDirectory ifFalse:[
msg := errorString := ('cannot create directory '', newName,'' !!') , '\\(' , (OperatingSystem lastErrorString) , ')'.
errorString := msg withCRs.
DialogBox warn:errorString.
result := false.
^ self
].
result := true.
!
createFile:file
"create an empty file"
|aStream newName msg|
newName := file baseName.
file exists ifTrue:[
(Dialog
confirm:(newName, ' already exists\\truncate ?') withCRs
yesLabel:('Truncate')
noLabel:('Cancel'))
ifFalse:[^ self].
].
FileStream openErrorSignal handle:[:ex|
msg := ('Cannot create file '', newName,'' !!') , '\\(' , (FileStream lastErrorString) , ')'.
errorString := msg withCRs.
^ DialogBox warn:errorString
] do:[
aStream := file newReadWriteStream.
].
aStream notNil ifTrue:[
aStream close.
] ifFalse:[
msg := ('Cannot create file '', newName, '' !!') , '\\(' , (FileStream lastErrorString) , ')'.
errorString := msg withCRs.
^ DialogBox warn:errorString
].
! !
!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
"
|instance|
instance := self new.
instance deleteFiles:aColOfFiles.
^ instance
! !
!FileOperation::Delete class methodsFor:'documentation'!
version
^ '$Header: /cvs/stx/stx/libtool/FileOperation.st,v 1.2 2002-09-04 15:25:44 penk Exp $'
! !
!FileOperation::Delete methodsFor:'actions'!
deleteFile:aFileOrDirectory
| file isDirectory |
aFileOrDirectory notNil ifTrue:[
file := aFileOrDirectory asFilename.
file exists ifTrue:[
isDirectory := file isDirectory.
Error handle:[:ex|
"was not able to remove it"
Smalltalk beep.
self errorString:((ex description, '\', ex signal notifierString) withCRs).
result := false.
] do:[
isDirectory ifTrue:[file recursiveRemove] ifFalse:[file remove].
"/ flush parent directory or directory
DirectoryContents flushCachedDirectory:(file directory).
]
]
].
result := true.
!
deleteFiles:colOfFiles
"delete current selected files/directories
"
| retVal ask size|
ask := true.
size := colOfFiles size.
colOfFiles do:[: filename |
ask ifTrue:[
size = 1 ifTrue:[
retVal := Dialog
confirmWithCancel:('really delete ', filename asString , ' ?')
labels:#('Yes' 'No' 'Cancel')
values:#(#yes #no #cancel)
default:1.
] ifFalse:[
retVal := Dialog
confirmWithCancel:('really delete ', filename asString , ' ?')
labels:#('Yes' 'No' 'Yes to All' 'Cancel')
values:#(#yes #no #yesToAll #cancel)
default:1.
]
].
retVal == #cancel ifTrue:[
^ self.
].
retVal == #yes ifTrue:[
self deleteFile:filename.
].
retVal == #yesToAll ifTrue:[
self deleteFile:filename.
ask := false.
retVal := #yes.
].
].
! !
!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.2 2002-09-04 15:25:44 penk 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:[
DialogBox warn:'cant move to not 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 fileExistDialogFor:newFile) 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.
] do:[
aSourceFile moveTo:newFile.
DirectoryContents flushCachedDirectory:(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:[
DialogBox warn:'cant move to not existing directory ', aDirectory asString.
result := false.
^ self
].
(aDirectory isDirectory not) ifTrue:[
DialogBox warn:'destination ', aDirectory asString, ' is not a directory'.
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 fileExistDialogFor:newFile withCancel:true).
askResult isNil ifTrue:[
result := false.
^ self.
]
]
].
].
askResult ifTrue:[
Error handle:[:ex|
"was not able to copy it"
result := false.
self errorString:('on move file - ', ex description asString).
( Dialog
confirm:('error on move file - ', ex description asString)
title:'Move'
yesLabel:'Continue'
noLabel:'Abort') ifFalse:[
^ self.
].
] do:[
filename moveTo:newFile.
].
self colOfMovedFiles add:filename
]
].
DirectoryContents flushCachedDirectory: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:'defaults'!
goodRenameDefaultFor:oldName lastOld:lastOldName lastNew:lastNewName
|prefix suffix lastNewSize lastOldSize t
lastOldWOSuffix lastNewWOSuffix oldWOSuffix lastOldRest oldRest lastNewRest
lastRemoved lastInserted|
lastNewName isNil ifTrue:[ ^ nil].
lastNewSize := lastNewName size.
lastOldSize := lastOldName size.
"/ intelligent default ...
(lastNewName endsWith:lastOldName) ifTrue:[
prefix := lastNewName copyTo:(lastNewSize - lastOldSize).
^ (prefix , oldName).
].
(lastOldName endsWith:lastNewName) ifTrue:[
prefix := lastOldName copyTo:(lastOldSize - lastNewSize).
^ (oldName copyFrom:prefix size+1).
].
(lastOldName withoutSeparators = lastNewName) ifTrue:[
"/ intelligent default ...
^ oldName withoutSeparators.
].
(lastNewName startsWith:lastOldName) ifTrue:[
"/ intelligent default ...
suffix := lastNewName copyLast:(lastNewSize - lastOldSize).
^ (oldName , suffix).
].
(lastOldName startsWith:lastNewName) ifTrue:[
suffix := lastOldName copyLast:(lastOldSize - lastNewSize).
(oldName endsWith:suffix) ifTrue:[
^ (oldName copyWithoutLast:suffix size).
]
].
lastOldWOSuffix := lastOldName asFilename withoutSuffix name.
lastNewWOSuffix := lastNewName asFilename withoutSuffix name.
oldWOSuffix := oldName asFilename withoutSuffix name.
prefix := lastOldWOSuffix commonPrefixWith:oldWOSuffix.
(lastNewWOSuffix startsWith:prefix) ifTrue:[
lastOldRest := lastOldWOSuffix copyFrom:prefix size + 1.
lastNewRest := lastNewWOSuffix copyFrom:prefix size + 1.
oldRest := oldWOSuffix copyFrom:prefix size + 1.
(lastNewRest endsWith:lastOldRest) ifTrue:[
t := lastNewRest copyWithoutLast:lastOldRest size.
^ ((prefix , t , oldRest) asFilename withSuffix:oldName asFilename suffix) name
].
].
suffix := lastOldWOSuffix commonSuffixWith:lastNewWOSuffix.
suffix size > 0 ifTrue:[
"/ last change changed something at the beginning
prefix := oldWOSuffix commonPrefixWith:lastOldWOSuffix.
prefix size > 0 ifTrue:[
"/ this name starts with the same characters
lastRemoved := lastOldWOSuffix copyWithoutLast:suffix size.
lastInserted := lastNewWOSuffix copyWithoutLast:suffix size.
^ lastInserted , (oldName copyFrom:lastRemoved size + 1)
].
].
^ nil
! !
!FileOperation::Rename class methodsFor:'documentation'!
version
^ '$Header: /cvs/stx/stx/libtool/FileOperation.st,v 1.2 2002-09-04 15:25:44 penk 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)"
|old new msg|
(oldFile isNil or:[newName isNil]) ifTrue:[
result := false
].
(oldFile asString isBlank or:[newName isBlank]) ifTrue:[
result := false
].
(oldFile baseName = newName) ifTrue:[
result := false
].
old := oldFile.
new := oldFile directory construct:newName.
OperatingSystem errorSignal handle:[:ex|
msg := ('Cannot rename file ', old baseName,' to ', newName,' !!'), '\\(' ,(OperatingSystem lastErrorString) , ')'.
DialogBox warn:msg withCRs.
result := false
] do:[
new exists ifTrue:[
(DialogBox confirm:(new baseName allBold, ' already exists - rename (i.e. overwrite) anyway ?'))
ifFalse:[
result := false.
^ self.
]
].
old renameTo:new.
self renamedFiles add:new.
].
result := true.
!
renameFiles:aColOfFiles
"rename the selected file(s)"
|queryBox b lastNewName lastOldName initialText oldName|
queryBox := FilenameEnterBox new.
queryBox okText:'Rename'.
aColOfFiles size > 1 ifTrue:[
b := queryBox addAbortButtonLabelled:'Cancel All'.
b action:[^ self]
].
aColOfFiles do:[:oldFile |
oldName := oldFile baseName asString.
queryBox title:('Rename ' , oldName , ' to:').
lastNewName notNil ifTrue:[
initialText := self class
goodRenameDefaultFor:oldName
lastOld:lastOldName
lastNew:lastNewName
].
initialText notNil ifTrue:[
queryBox initialText:initialText
] ifFalse:[
queryBox initialText:oldName
].
queryBox
action:[:newName |
(self renameFile:oldFile to:newName asString) ifTrue:[
result := true
].
lastOldName := oldName.
lastNewName := newName
].
queryBox showAtPointer
]
! !
!FileOperation class methodsFor:'documentation'!
version
^ '$Header: /cvs/stx/stx/libtool/FileOperation.st,v 1.2 2002-09-04 15:25:44 penk Exp $'
! !