AbstractFileBrowser.st
changeset 10304 ef51c640ee76
parent 10258 7d2454c716de
child 10305 58cfe23bd6cd
--- 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 $'
 ! !