--- a/AbstractFileBrowser.st Sun Jul 10 17:47:24 2011 +0200
+++ b/AbstractFileBrowser.st Mon Jul 11 12:56:34 2011 +0200
@@ -2075,7 +2075,6 @@
translateLabel: true
)
(MenuItem
- "/ enabled: hasXmlFileSelected
label: 'XML Inspector'
itemValue: inspectXmlFile
translateLabel: true
@@ -2270,19 +2269,6 @@
itemValue: fileHexDump
translateLabel: true
)
-"/ something I would like to have...
-"/ (MenuItem
-"/ enabled: hasFileSelection
-"/ label: 'Hex Dump of First n Bytes...'
-"/ itemValue: fileHexDumpOfFirstNBytes
-"/ translateLabel: true
-"/ )
-"/ (MenuItem
-"/ enabled: hasFileSelection
-"/ label: 'Hex Dump of Last n Bytes...'
-"/ itemValue: fileHexDumpOfLastNBytes
-"/ translateLabel: true
-"/ )
)
nil
nil
@@ -2300,6 +2286,11 @@
translateLabel: true
)
(MenuItem
+ label: 'Duplicate File'
+ itemValue: fileFindDuplicateFile
+ translateLabel: true
+ )
+ (MenuItem
label: 'Duplicate Files'
itemValue: fileFindDuplicates
translateLabel: true
@@ -2325,8 +2316,6 @@
nil
nil
)
-
- "Modified: / 17-02-2011 / 13:55:43 / cg"
!
viewDetailsMenuSpec
@@ -5801,6 +5790,188 @@
"Modified: / 25-07-2006 / 09:07:22 / cg"
!
+fileFindDuplicateFile
+ "scan directory for duplicates of the selected files"
+
+ |files filesBySize samePerFile stream textBox|
+
+ files := self currentSelectedFiles.
+ files isEmpty ifTrue:[^ self].
+
+ filesBySize := Dictionary new.
+ files do:[:fn |
+ |sz entry|
+
+ sz := fn asFilename fileSize.
+ (filesBySize at:sz ifAbsentPut:[Set new]) add:fn.
+ ].
+
+ samePerFile := Dictionary new.
+
+ self currentSelectedDirectories do:[:eachDir |
+ eachDir recursiveDirectoryContentsAsFilenamesDo:[:eachFile |
+ eachFile isDirectory ifFalse:[
+ |sz possibleMatches|
+
+ sz := eachFile fileSize.
+ possibleMatches := filesBySize at:sz ifAbsent:nil.
+ possibleMatches notNil ifTrue:[
+ possibleMatches do:[:eachFileWithSameSize |
+ (eachFileWithSameSize sameContentsAs:eachFile) ifTrue:[
+ (samePerFile at:eachFileWithSameSize ifAbsentPut:[Set new]) add:eachFile
+ ]
+ ]
+ ]
+ ]
+ ]
+ ].
+
+ stream := WriteStream on:''.
+ samePerFile keysAndValuesDo:[:origFile :sameFiles|
+ stream nextPutLine:origFile baseName.
+ (sameFiles asOrderedCollection collect:[:each | each baseName]) sort do:[:eachSameName |
+ stream nextPutAll:' '; nextPutLine:eachSameName.
+ ]
+ ].
+
+ textBox := TextBox new.
+ textBox initialText:(stream contents).
+ textBox title:'Files with same contents'.
+ textBox readOnly:true.
+ textBox noCancel.
+ textBox extent:(350@400).
+ textBox maxExtent:Screen current extent.
+ textBox openModeless. "/ showAtPointer.
+
+"/
+"/ self withActivityIndicationDo:[
+"/ result := Dictionary new.
+"/
+"/ infoDir := Dictionary new.
+"/ allFiles do:[:fn |
+"/ infoDir at:fn put:(fn info)
+"/ ].
+"/
+"/ "/ for each, get the files size.
+"/ "/ in a first pass, look for files of the same size and
+"/ "/ compare them ...
+"/
+"/ filesBySize := Dictionary new.
+"/ infoDir keysAndValuesDo:[:fn :info |
+"/ |sz entry|
+"/
+"/ sz := info size.
+"/ entry := filesBySize at:sz ifAbsentPut:[Set new].
+"/ entry add:fn.
+"/ ].
+"/
+"/ "/ any of same size ?
+"/
+"/ filesBySize do:[:entry |
+"/ |files|
+"/
+"/ entry size > 1 ifTrue:[
+"/ files := entry asArray.
+"/ 1 to:files size-1 do:[:idx1 |
+"/ idx1+1 to:files size do:[:idx2 |
+"/ |fn1 fn2|
+"/
+"/ fn1 := files at:idx1.
+"/ fn2 := files at:idx2.
+"/
+"/ (result at:fn2 ifAbsent:nil) ~= fn1 ifTrue:[
+"/ "/ compare the files
+"/ (fn1 sameContentsAs:fn2) ifTrue:[
+"/"/ Transcript show:'Same: '; show:fn1 baseName; show:' and '; showCR:fn2 baseName.
+"/ result at:fn1 put:fn2.
+"/ ]
+"/ ]
+"/ ]
+"/ ]
+"/ ]
+"/ ].
+"/
+"/ result := result associations.
+"/ result := result collect:[:assoc |
+"/ |f1 f2|
+"/
+"/ f1 := assoc key asString.
+"/ f2 := assoc value asString.
+"/ f1 < f2 ifTrue:[
+"/ f2 -> f1
+"/ ] ifFalse:[
+"/ f1 -> f2
+"/ ]
+"/ ].
+"/ "/ result sort:[:f1 :f2 | f1 key > f2 key "f2 value < f1 key value"].
+"/ result sort:[:f1 :f2 | " f1 key > f2 key" f2 value < f1 key value].
+"/
+"/ info := OrderedCollection new.
+"/ size := self getBestDirectory asString size.
+"/ result do:[:assoc |
+"/ |fn1 fn2|
+"/
+"/ fn1 := assoc key.
+"/ fn2 := assoc value.
+"/ size > 1 ifTrue:[
+"/ fn1 := ('..', (fn1 copyFrom:(size + 1))).
+"/ fn2 := ('..', (fn2 copyFrom:(size + 1))).
+"/ ].
+"/ (fn1 includes:Character space) ifTrue:[
+"/ fn1 := '"' , fn1 , '"'
+"/ ].
+"/ (fn2 includes:Character space) ifTrue:[
+"/ fn2 := '"' , fn2 , '"'
+"/ ].
+"/ info add:(fn1 , ' same as ' , fn2)
+"/ ].
+"/ info isEmpty ifTrue:[
+"/ Dialog information:'No duplicate files found.'.
+"/ ^ self.
+"/ ].
+"/ ].
+"/ stream := WriteStream on:''.
+"/ info do:[:el|
+"/ stream nextPutLine:el.
+"/ ].
+"/ titleStream := WriteStream on:''.
+"/ titleStream nextPutAll:'File duplicates in director'.
+"/ directories size == 1 ifTrue:[
+"/ titleStream nextPutAll:'y: ', directories first asString.
+"/ ] ifFalse:[
+"/ titleStream nextPutLine:'ies: '.
+"/ directories do:[:dir|
+"/ size > 1 ifTrue:[
+"/ titleStream nextPutAll:'..'.
+"/ titleStream nextPutLine:((dir asString) copyFrom:(size + 1)).
+"/ ] ifFalse:[
+"/ titleStream nextPutLine:(dir asString).
+"/ ].
+"/ ]
+"/ ].
+"/
+"/ textBox := TextBox new.
+"/ textBox initialText:(stream contents).
+"/ textBox title:(titleStream contents).
+"/ textBox readOnly:true.
+"/ textBox noCancel.
+"/ stream := WriteStream on:'Duplicates in '.
+"/ directories do:[ :aDirectory |
+"/ stream nextPutAll:aDirectory baseName.
+"/ stream space.
+"/ ].
+"/ textBox label:stream contents.
+"/ maxLength := 10.
+"/ info do:[: el |
+"/ maxLength := maxLength max:(el size).
+"/ ].
+"/ textBox extent:((maxLength * 5)@((info size max:40)* 10)).
+"/ textBox maxExtent:Screen current extent.
+"/ textBox openModeless. "/ showAtPointer.
+
+ "Created: / 11-07-2011 / 12:39:44 / cg"
+!
+
fileFindDuplicates
"scan directory for duplicate files"
@@ -7417,7 +7588,6 @@
^ false
! !
-
!AbstractFileBrowser methodsFor:'presentation'!
getModeString:modeBits
@@ -8334,5 +8504,5 @@
!AbstractFileBrowser class methodsFor:'documentation'!
version_CVS
- ^ '$Header: /cvs/stx/stx/libtool/AbstractFileBrowser.st,v 1.461 2011-07-07 14:14:30 vrany Exp $'
+ ^ '$Header: /cvs/stx/stx/libtool/AbstractFileBrowser.st,v 1.462 2011-07-11 10:56:34 cg Exp $'
! !