DirectoryDifferenceViewApplication.st
branchjv
changeset 12125 0c49a3b13e43
child 12128 a7ff7d66ee85
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DirectoryDifferenceViewApplication.st	Sun Jan 29 15:33:37 2012 +0000
@@ -0,0 +1,520 @@
+"{ Package: 'stx:libtool' }"
+
+AbstractFileFinderApplicationComponent subclass:#DirectoryDifferenceViewApplication
+	instanceVariableNames:'directory1Holder directory2Holder directory1 directory2
+		filesOnlyInDirectory1 filesOnlyInDirectory2
+		filesWhichAreDifferent directoriesOnlyInDirectory1
+		directoriesOnlyInDirectory2 namePatternHolder
+		excludedNamePatternHolder'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Interface-Tools-File'
+!
+
+
+!DirectoryDifferenceViewApplication class methodsFor:'help specs'!
+
+flyByHelpSpec
+    "This resource specification was automatically generated
+     by the UIHelpTool of ST/X."
+
+    "Do not manually edit this!! If it is corrupted,
+     the UIHelpTool may not be able to read the specification."
+
+    "
+     UIHelpTool openOnClass:FindFileApplication    
+    "
+
+    <resource: #help>
+
+    ^ super flyByHelpSpec addPairsFrom:#(
+
+#namePattern
+'Filename(s) to search for. Can be matchPatterns, separated by ";"'
+
+#excludedNamePattern
+'Filename(s) to skip. Can be matchPatterns, separated by ";"'
+
+#searchDirectory1
+'The first folder, to be compared against folder2'
+
+#searchDirectory2
+'The second folder, to be compared against folder1'
+
+)
+
+    "Modified: / 13-01-2012 / 14:41:36 / cg"
+! !
+
+!DirectoryDifferenceViewApplication class methodsFor:'interface specs'!
+
+windowSpec
+    "This resource specification was automatically generated
+     by the UIPainter of ST/X."
+
+    "Do not manually edit this!! If it is corrupted,
+     the UIPainter may not be able to read the specification."
+
+    "
+     UIPainter new openOnClass:DirectoryDifferenceViewApplication andSelector:#windowSpec
+     DirectoryDifferenceViewApplication new openInterface:#windowSpec
+     DirectoryDifferenceViewApplication open
+    "
+
+    <resource: #canvas>
+
+    ^ 
+     #(FullSpec
+        name: windowSpec
+        window: 
+       (WindowSpec
+          label: 'Directory Diff'
+          name: 'Directory Diff'
+          min: (Point 377 131)
+          bounds: (Rectangle 0 0 758 512)
+        )
+        component: 
+       (SpecCollection
+          collection: (
+           (MenuPanelSpec
+              name: 'ToolBar1'
+              layout: (LayoutFrame 0 0.0 0 0 0 1.0 32 0)
+              level: 0
+              menu: searchMenu
+              textDefault: true
+            )
+           (ProgressIndicatorSpec
+              name: 'ProgressIndicator1'
+              layout: (LayoutFrame 125 0 11 0 231 0 21 0)
+              visibilityChannel: enableStop
+              backgroundColor: (Color 0.0 66.9993133440146 66.9993133440146)
+              showPercentage: false
+              isActivityIndicator: true
+            )
+           (ViewSpec
+              name: 'Box1'
+              layout: (LayoutFrame 0 0.0 32 0 0 1.0 130 0)
+              component: 
+             (SpecCollection
+                collection: (
+                 (LabelSpec
+                    label: 'Directory1:'
+                    name: 'DirectoryLabel'
+                    layout: (LayoutFrame 2 0 7 0 154 0 24 0)
+                    activeHelpKey: searchDirectory1
+                    translateLabel: true
+                    adjust: right
+                  )
+                 (FilenameInputFieldSpec
+                    name: 'DirectoryEntryField'
+                    layout: (LayoutFrame 156 0 4 0 0 1 24 0)
+                    activeHelpKey: searchDirectory1
+                    model: directory1Holder
+                    immediateAccept: true
+                    acceptOnPointerLeave: false
+                  )
+                 (LabelSpec
+                    label: 'Directory2:'
+                    name: 'Label2'
+                    layout: (LayoutFrame 2 0 31 0 154 0 48 0)
+                    activeHelpKey: searchDirectory2
+                    translateLabel: true
+                    adjust: right
+                  )
+                 (FilenameInputFieldSpec
+                    name: 'FilenameEntryField1'
+                    layout: (LayoutFrame 156 0 28 0 0 1 48 0)
+                    activeHelpKey: searchDirectory2
+                    model: directory2Holder
+                    immediateAccept: true
+                    acceptOnPointerLeave: false
+                  )
+                 (LabelSpec
+                    label: 'Compare Files Named:'
+                    name: 'FileNameLabel'
+                    layout: (LayoutFrame 2 0 55 0 154 0 72 0)
+                    activeHelpKey: namePattern
+                    translateLabel: true
+                    adjust: right
+                  )
+                 (InputFieldSpec
+                    name: 'FileNameEntryField'
+                    layout: (LayoutFrame 156 0 52 0 -315 1 72 0)
+                    activeHelpKey: namePattern
+                    tabable: true
+                    model: namePatternHolder
+                    immediateAccept: true
+                    acceptOnLeave: false
+                    acceptOnPointerLeave: false
+                  )
+                 (CheckBoxSpec
+                    label: 'Ignore Case'
+                    name: 'IgnoreCaseInNameCheckBox'
+                    layout: (LayoutFrame -169 1 53 0 -4 1 76 0)
+                    activeHelpKey: ignoreCase
+                    tabable: true
+                    model: ignoreCaseInName
+                    translateLabel: true
+                  )
+                 (LabelSpec
+                    label: 'But Not Named:'
+                    name: 'Label1'
+                    layout: (LayoutFrame 2 0 79 0 154 0 96 0)
+                    activeHelpKey: excludedNamePattern
+                    translateLabel: true
+                    adjust: right
+                  )
+                 (InputFieldSpec
+                    name: 'EntryField1'
+                    layout: (LayoutFrame 156 0 76 0 -315 1 96 0)
+                    activeHelpKey: excludedNamePattern
+                    tabable: true
+                    model: excludedNamePatternHolder
+                    immediateAccept: true
+                    acceptOnLeave: false
+                    acceptOnPointerLeave: false
+                  )
+                 (CheckBoxSpec
+                    label: 'Ignore Case'
+                    name: 'CheckBox1'
+                    layout: (LayoutFrame -169 1 77 0 -4 1 100 0)
+                    activeHelpKey: ignoreCase
+                    tabable: true
+                    model: ignoreCaseInExcludedName
+                    translateLabel: true
+                  )
+                 )
+               
+              )
+            )
+           (VariableVerticalPanelSpec
+              name: 'VariableVerticalPanel1'
+              layout: (LayoutFrame 0 0.0 140 0 0 1.0 0 1)
+              component: 
+             (SpecCollection
+                collection: (
+                 (DataSetSpec
+                    name: 'Table1'
+                    model: selectionHolder
+                    hasHorizontalScrollBar: true
+                    hasVerticalScrollBar: true
+                    dataList: matchedFilesList
+                    doubleClickSelector: fileDoubleClick:
+                    columnHolder: searchResultTable
+                    valueChangeSelector: fileSelected:
+                    multipleSelectOk: true
+                  )
+                 (ArbitraryComponentSpec
+                    name: 'DiffTextView'
+                    hasHorizontalScrollBar: true
+                    hasVerticalScrollBar: true
+                    component: DiffTextView
+                  )
+                 )
+               
+              )
+              handles: (Any 0.5 1.0)
+            )
+           )
+         
+        )
+      )
+
+    "Modified: / 13-01-2012 / 14:41:56 / cg"
+! !
+
+!DirectoryDifferenceViewApplication class methodsFor:'menu specs'!
+
+searchMenu
+    "This resource specification was automatically generated
+     by the MenuEditor of ST/X."
+
+    "Do not manually edit this!! If it is corrupted,
+     the MenuEditor may not be able to read the specification."
+
+
+    "
+     MenuEditor new openOnClass:FindFileApplication andSelector:#searchMenu
+     (Menu new fromLiteralArrayEncoding:(FindFileApplication searchMenu)) startUp
+    "
+
+    <resource: #menu>
+
+    ^ 
+     #(Menu
+        (
+         (MenuItem
+            label: 'Search'
+            itemValue: doSearch
+            translateLabel: true
+            isButton: true
+            labelImage: (ResourceRetriever ToolbarIconLibrary searchFileIcon)
+          )
+         (MenuItem
+            enabled: enableStop
+            label: 'Stop'
+            itemValue: stop
+            translateLabel: true
+            isButton: true
+            isVisible: enableStop
+            labelImage: (ResourceRetriever XPToolbarIconLibrary stop22x22Icon)
+          )
+         (MenuItem
+            label: 'Close'
+            itemValue: doClose
+            translateLabel: true
+            isButton: true
+            startGroup: right
+            isVisible: false
+            labelImage: (ResourceRetriever ToolbarIconLibrary removeTabIcon)
+          )
+         )
+        nil
+        nil
+      )
+! !
+
+!DirectoryDifferenceViewApplication class methodsFor:'tableColumns specs'!
+
+searchResultTable
+    "This resource specification was automatically generated
+     by the DataSetBuilder of ST/X."
+
+    "Do not manually edit this!! If it is corrupted,
+     the DataSetBuilder may not be able to read the specification."
+
+    "
+     DataSetBuilder new openOnClass:DirectoryDifferenceViewApplication andSelector:#searchResultTable
+    "
+
+    <resource: #tableColumns>
+
+    ^#(
+      (DataSetColumnSpec
+         label: 'Filename'
+         id: 'FileName'
+         labelButtonType: Button
+         model: at:
+         menuFromApplication: false
+         writeSelector: at:put:
+         showRowSeparator: false
+         showColSeparator: false
+       )
+      (DataSetColumnSpec
+         label: 'Diff'
+         id: 'Diff'
+         labelButtonType: Button
+         model: at:
+         menuFromApplication: false
+         writeSelector: at:put:
+         showRowSeparator: false
+         showColSeparator: false
+       )
+      )
+    
+! !
+
+!DirectoryDifferenceViewApplication methodsFor:'accessing'!
+
+directory1:directory1Arg directory2:directory2Arg 
+    self directory1Holder value:directory1Arg.
+    self directory2Holder value:directory2Arg.
+
+"/    self namePatternHolder value:newPattern.
+    self enableStop value:false.
+    self enableSearch value:true.
+    ^ true.
+
+    "Modified: / 12-01-2012 / 01:36:54 / cg"
+!
+
+directory1Holder
+    directory1Holder isNil ifTrue:[
+        directory1Holder := nil asValue
+    ].
+    ^ directory1Holder
+
+    "Created: / 12-01-2012 / 01:37:31 / cg"
+!
+
+directory2Holder
+    directory2Holder isNil ifTrue:[
+        directory2Holder := nil asValue
+    ].
+    ^ directory2Holder
+
+    "Created: / 12-01-2012 / 01:37:41 / cg"
+! !
+
+!DirectoryDifferenceViewApplication methodsFor:'actions'!
+
+fileSelected:entries
+    |entry file fn1 fn2 text1 text2 differ|
+
+    entries isEmptyOrNil ifTrue:[^ self].
+
+    entry := self shownList at:entries first.
+    file := entry first.
+
+    fn1 := self directory1Holder value asFilename construct:file.
+    fn2 := self directory2Holder value asFilename construct:file.
+    fn1 exists ifTrue:[
+        text1 := fn1 contentsOfEntireFile.
+    ].
+    fn2 exists ifTrue:[
+        text2 := fn2 contentsOfEntireFile.
+    ].
+    differ := builder componentAt:'DiffTextView'.
+    differ text1:(text1 ? '') text2:(text2 ? '').
+
+    "Created: / 12-01-2012 / 03:21:52 / cg"
+! !
+
+!DirectoryDifferenceViewApplication methodsFor:'aspects'!
+
+excludedNamePatternHolder
+    excludedNamePatternHolder isNil ifTrue:[
+        excludedNamePatternHolder := '' asValue.
+    ].
+    ^ excludedNamePatternHolder.
+
+    "Created: / 13-01-2012 / 14:42:47 / cg"
+!
+
+namePatternHolder
+
+    namePatternHolder isNil ifTrue:[
+        namePatternHolder := '*' asValue.
+    ].
+    ^ namePatternHolder.
+
+    "Created: / 13-01-2012 / 14:37:28 / cg"
+! !
+
+!DirectoryDifferenceViewApplication methodsFor:'comparing'!
+
+doSearch
+    |dir1 dir2 namePattern namePatterns excludedNamePattern excludedNamePatterns|
+
+    filesOnlyInDirectory1 := OrderedCollection new.
+    filesOnlyInDirectory2 := OrderedCollection new.
+    directoriesOnlyInDirectory1 := OrderedCollection new.
+    directoriesOnlyInDirectory2 := OrderedCollection new.
+    filesWhichAreDifferent := OrderedCollection new.
+
+    dir1 := self directory1Holder value.
+    dir1 isNil ifTrue:[^ self].
+
+    dir2 := self directory2Holder value.
+    dir2 isNil ifTrue:[^ self].
+
+    dir1 := dir1 asFilename.
+    dir2 := dir2 asFilename.
+
+    dir1 pathName = dir2 pathName ifTrue:[
+        self notify:('Same folder.' allBold).
+        ^ self.
+    ].
+
+    namePattern := self namePatternHolder value.
+    namePattern notEmptyOrNil ifTrue:[
+        namePatterns := namePattern asCollectionOfSubstringsSeparatedByAny:',;'.
+        namePatterns := namePatterns collect:[:p | p withoutSeparators ].
+    ].
+    excludedNamePattern := self excludedNamePatternHolder value.
+    excludedNamePattern notEmptyOrNil ifTrue:[
+        excludedNamePatterns := excludedNamePattern asCollectionOfSubstringsSeparatedByAny:',;'.
+        excludedNamePatterns := excludedNamePatterns collect:[:p | p withoutSeparators ].
+    ].
+
+    self 
+        startSearchTask:[
+            self changeInformationTo:'Directory Diff - searching ' toTab:true.
+
+            self shownListHolder valueHolder:(self matchedFilesList).
+
+            dir1 recursiveDirectoryContentsDo:[:relFn1 |
+                |fn1 fn2|
+
+                fn1 := dir1 construct:relFn1.
+                (namePatterns isNil or:[namePatterns contains:[:p | p match:fn1 baseName]]) ifTrue:[
+                    (excludedNamePatterns notNil and:[excludedNamePatterns contains:[:p | p match:fn1 baseName]]) ifFalse:[
+                        fn2 := dir2 construct:relFn1.
+                        fn1 isDirectory ifTrue:[
+                            self notify:('Comparing %1...' bindWith:relFn1 asString allBold).
+                            fn2 exists ifFalse:[
+                                directoriesOnlyInDirectory1 add:fn1.
+                                self matchedFilesList add:{ relFn1 . 'Directory only in directory1' }.
+                            ].
+                        ] ifFalse:[
+                            fn2 exists ifTrue:[
+                                (fn1 sameContentsAs:fn2) ifFalse:[
+                                    filesWhichAreDifferent add:fn1.
+                                    self matchedFilesList add:{ relFn1 . 'Different' }.
+                                ].
+                            ] ifFalse:[
+                                filesOnlyInDirectory1 add:fn1.
+                                self matchedFilesList add:{ relFn1 . 'File only in directory1' }.
+                            ].
+                        ].
+                    ]
+                ]
+            ].
+            dir2 recursiveDirectoryContentsDo:[:relFn2 |
+                |fn1 fn2|
+
+                fn2 := dir2 construct:relFn2.
+                (namePatterns isNil or:[namePatterns contains:[:p | p match:fn2 baseName]]) ifTrue:[
+                    (excludedNamePatterns notNil and:[excludedNamePatterns contains:[:p | p match:fn2 baseName]]) ifFalse:[
+                        fn1 := dir1 construct:relFn2.
+                        fn1 exists ifFalse:[
+                            fn1 isDirectory ifTrue:[
+                                directoriesOnlyInDirectory1 add:fn1.
+                                self matchedFilesList add:{ relFn2 . 'Directory only in directory2' }.
+                            ] ifFalse:[
+                                filesOnlyInDirectory2 add:fn2.
+                                self matchedFilesList add:{ relFn2 . 'File only in directory2' }.
+                            ]
+                        ].
+                    ].
+                ]
+            ].
+            filesOnlyInDirectory1 notEmpty ifTrue:[
+                Transcript showCR:('%1 files only in directory1' bindWith:filesOnlyInDirectory1 size).
+            ].
+            filesOnlyInDirectory2 notEmpty ifTrue:[
+                Transcript showCR:('%1 files only in directory2' bindWith:filesOnlyInDirectory2 size).
+            ].
+            directoriesOnlyInDirectory1 notEmpty ifTrue:[
+                Transcript showCR:('%1 directories only in directory1' bindWith:directoriesOnlyInDirectory1 size).
+            ].
+            directoriesOnlyInDirectory2 notEmpty ifTrue:[
+                Transcript showCR:('%1 directories only in directory2' bindWith:directoriesOnlyInDirectory2 size).
+            ].
+            filesWhichAreDifferent notEmpty ifTrue:[
+                Transcript showCR:('%1 files are different' bindWith:filesWhichAreDifferent size).
+            ]
+        ]
+        name:'Directory Diff'.
+
+    "Created: / 12-01-2012 / 01:07:20 / cg"
+! !
+
+!DirectoryDifferenceViewApplication methodsFor:'startup & release'!
+
+postOpenWith:aBuilder
+    super postOpenWith:aBuilder.
+    self doSearch
+
+    "Created: / 12-01-2012 / 01:41:18 / cg"
+! !
+
+!DirectoryDifferenceViewApplication class methodsFor:'documentation'!
+
+version
+    ^ '$Header: /cvs/stx/stx/libtool/DirectoryDifferenceViewApplication.st,v 1.4 2012/01/13 14:14:02 cg Exp $'
+!
+
+version_CVS
+    ^ '§Header: /cvs/stx/stx/libtool/DirectoryDifferenceViewApplication.st,v 1.4 2012/01/13 14:14:02 cg Exp §'
+! !
\ No newline at end of file