FindFileApplication.st
changeset 4518 85b13890d7b1
parent 4336 b4228ddf2183
child 4638 79734f7bdfc4
equal deleted inserted replaced
4517:832acdc7a34d 4518:85b13890d7b1
     1 "{ Package: 'stx:libtool' }"
     1 "{ Package: 'stx:libtool' }"
     2 
     2 
     3 AbstractFileApplicationNoteBookComponent subclass:#FindFileApplication
     3 AbstractFileApplicationNoteBookComponent subclass:#FindFileApplication
     4 	instanceVariableNames:'contentsPatternHolder ignoreCaseInName notSearchForSameContents
     4 	instanceVariableNames:'contentsPatternHolder searchDirectories ignoreCaseInName
     5 		namePatternHolder ignoreCaseInContents searchDirectoryHolder
     5 		notSearchForSameContents namePatternHolder ignoreCaseInContents
     6 		findFileView searchResultTable resultList enableStop enableSearch
     6 		searchDirectoryHolder findFileView searchResultTable resultList
     7 		stopSignal accessLock searchTask expanded searchRecursively
     7 		enableStop enableSearch stopSignal accessLock searchTask expanded
     8 		selectionHolder hasListEntries targetApplication'
     8 		searchRecursively selectionHolder hasListEntries
       
     9 		targetApplication'
     9 	classVariableNames:''
    10 	classVariableNames:''
    10 	poolDictionaries:''
    11 	poolDictionaries:''
    11 	category:'Interface-Tools-File'
    12 	category:'Interface-Tools-File'
    12 !
    13 !
    13 
    14 
    71        #(#WindowSpec
    72        #(#WindowSpec
    72           #label: 'File Search'
    73           #label: 'File Search'
    73           #name: 'File Search'
    74           #name: 'File Search'
    74           #min: #(#Point 377 131)
    75           #min: #(#Point 377 131)
    75           #max: #(#Point 1280 1024)
    76           #max: #(#Point 1280 1024)
    76           #bounds: #(#Rectangle 16 42 681 374)
    77           #bounds: #(#Rectangle 16 46 681 378)
    77         )
    78         )
    78         #component: 
    79         #component: 
    79        #(#SpecCollection
    80        #(#SpecCollection
    80           #collection: #(
    81           #collection: #(
    81            #(#MenuPanelSpec
    82            #(#MenuPanelSpec
    90               #layout: #(#LayoutFrame 0 0.0 32 0 0 1.0 126 0)
    91               #layout: #(#LayoutFrame 0 0.0 32 0 0 1.0 126 0)
    91               #component: 
    92               #component: 
    92              #(#SpecCollection
    93              #(#SpecCollection
    93                 #collection: #(
    94                 #collection: #(
    94                  #(#LabelSpec
    95                  #(#LabelSpec
       
    96                     #label: 'Directory:'
       
    97                     #name: 'DirectoryLabel'
       
    98                     #layout: #(#LayoutFrame 4 0 7 0 136 0 24 0)
       
    99                     #translateLabel: true
       
   100                     #adjust: #left
       
   101                   )
       
   102                  #(#FilenameInputFieldSpec
       
   103                     #name: 'DirectoryEntryField'
       
   104                     #layout: #(#LayoutFrame 140 0 4 0 -115 1 24 0)
       
   105                     #model: #searchDirectoryHolder
       
   106                     #immediateAccept: true
       
   107                     #acceptOnPointerLeave: false
       
   108                   )
       
   109                  #(#CheckBoxSpec
       
   110                     #label: 'Recursively'
       
   111                     #name: 'RecursiveSearchCheckBox'
       
   112                     #layout: #(#LayoutFrame -97 1 5 0 0 1 28 0)
       
   113                     #tabable: true
       
   114                     #model: #searchRecursively
       
   115                     #translateLabel: true
       
   116                   )
       
   117                  #(#LabelSpec
    95                     #label: 'Search files named:'
   118                     #label: 'Search files named:'
    96                     #name: 'Label1'
   119                     #name: 'FileNameLabel'
    97                     #layout: #(#LayoutFrame 3 0 7 0 148 0 24 0)
   120                     #layout: #(#LayoutFrame 4 0 31 0 136 0 48 0)
    98                     #translateLabel: true
   121                     #translateLabel: true
    99                     #adjust: #left
   122                     #adjust: #left
   100                   )
   123                   )
   101                  #(#InputFieldSpec
   124                  #(#InputFieldSpec
   102                     #name: 'EntryField1'
   125                     #name: 'FileNameEntryField'
   103                     #layout: #(#LayoutFrame 140 0 4 0 -115 1 24 0)
   126                     #layout: #(#LayoutFrame 140 0 29 0 -228 1 49 0)
   104                     #tabable: true
   127                     #tabable: true
   105                     #model: #namePatternHolder
   128                     #model: #namePatternHolder
   106                     #immediateAccept: true
   129                     #immediateAccept: true
   107                     #acceptOnLeave: false
   130                     #acceptOnLeave: false
   108                     #acceptOnPointerLeave: false
   131                     #acceptOnPointerLeave: false
   109                   )
   132                   )
   110                  #(#CheckBoxSpec
   133                  #(#CheckBoxSpec
       
   134                     #label: 'Directories'
       
   135                     #name: 'SearchDirectoriesCheckBox'
       
   136                     #layout: #(#LayoutFrame -211 1 30 0 -114 1 50 0)
       
   137                     #tabable: true
       
   138                     #model: #searchDirectories
       
   139                     #translateLabel: true
       
   140                   )
       
   141                  #(#CheckBoxSpec
   111                     #label: 'Ignore case'
   142                     #label: 'Ignore case'
   112                     #name: 'CheckBox1'
   143                     #name: 'IgnoreCaseInNameCheckBox'
   113                     #layout: #(#LayoutFrame -97 1 5 0 1 1 28 0)
   144                     #layout: #(#LayoutFrame -97 1 30 0 0 1 50 0)
   114                     #tabable: true
   145                     #tabable: true
   115                     #model: #ignoreCaseInName
   146                     #model: #ignoreCaseInName
   116                     #translateLabel: true
   147                     #translateLabel: true
   117                   )
   148                   )
   118                  #(#LabelSpec
   149                  #(#LabelSpec
   119                     #label: 'Containing the string:'
   150                     #label: 'Containing the string:'
   120                     #name: 'Label2'
   151                     #name: 'ContentsLabel'
   121                     #layout: #(#LayoutFrame 4 0 31 0 136 0 48 0)
   152                     #layout: #(#LayoutFrame 4 0 57 0 136 0 74 0)
   122                     #translateLabel: true
   153                     #translateLabel: true
   123                     #adjust: #left
   154                     #adjust: #left
   124                   )
   155                   )
   125                  #(#InputFieldSpec
   156                  #(#InputFieldSpec
   126                     #name: 'EntryField2'
   157                     #name: 'ContentsEntryField'
   127                     #layout: #(#LayoutFrame 140 0 29 0 -115 1 49 0)
   158                     #layout: #(#LayoutFrame 140 0 54 0 -115 1 74 0)
   128                     #enableChannel: #notSearchForSameContents
   159                     #enableChannel: #notSearchForSameContents
   129                     #tabable: true
   160                     #tabable: true
   130                     #model: #contentsPatternHolder
   161                     #model: #contentsPatternHolder
   131                     #immediateAccept: true
   162                     #immediateAccept: true
   132                     #acceptOnPointerLeave: false
   163                     #acceptOnPointerLeave: false
   133                   )
   164                   )
   134                  #(#CheckBoxSpec
   165                  #(#CheckBoxSpec
   135                     #label: 'Ignore case'
   166                     #label: 'Ignore case'
   136                     #name: 'CheckBox2'
   167                     #name: 'IgnoreCaseInContentsCheckBox'
   137                     #layout: #(#LayoutFrame -97 1 30 0 4 1 50 0)
   168                     #layout: #(#LayoutFrame -97 1 54 0 0 1 77 0)
   138                     #enableChannel: #notSearchForSameContents
   169                     #enableChannel: #notSearchForSameContents
   139                     #tabable: true
   170                     #tabable: true
   140                     #model: #ignoreCaseInContents
   171                     #model: #ignoreCaseInContents
   141                     #translateLabel: true
       
   142                   )
       
   143                  #(#LabelSpec
       
   144                     #label: 'Directory:'
       
   145                     #name: 'Directory'
       
   146                     #layout: #(#LayoutFrame 4 0 57 0 136 0 74 0)
       
   147                     #translateLabel: true
       
   148                     #adjust: #left
       
   149                   )
       
   150                  #(#FilenameInputFieldSpec
       
   151                     #name: 'FilenameEntryField1'
       
   152                     #layout: #(#LayoutFrame 140 0 54 0 -115 1 74 0)
       
   153                     #model: #searchDirectoryHolder
       
   154                     #immediateAccept: true
       
   155                     #acceptOnPointerLeave: false
       
   156                   )
       
   157                  #(#CheckBoxSpec
       
   158                     #label: 'Recursively'
       
   159                     #name: 'CheckBox3'
       
   160                     #layout: #(#LayoutFrame -97 1 54 0 1 1 77 0)
       
   161                     #tabable: true
       
   162                     #model: #searchRecursively
       
   163                     #translateLabel: true
   172                     #translateLabel: true
   164                   )
   173                   )
   165                  )
   174                  )
   166                
   175                
   167               )
   176               )
   395 
   404 
   396 "/    self changeExtentToSeeSearchResult.
   405 "/    self changeExtentToSeeSearchResult.
   397 
   406 
   398     dir := self searchDirectoryHolder value.
   407     dir := self searchDirectoryHolder value.
   399     dir isNil ifTrue:[
   408     dir isNil ifTrue:[
   400         Dialog warn:'please type in a Directory first'.
   409         Dialog warn:'Missing directory name'.
   401         ^ self.
   410         ^ self.
   402     ].
   411     ].
   403     dir asFilename exists not ifTrue:[
   412     dir asFilename exists not ifTrue:[
   404         Dialog warn:dir, 'not exists'.
   413         Dialog warn:('No such directory: %1' bindWith:dir asString allBold).
   405         ^ self.
   414         ^ self.
   406     ].
   415     ].
   407     
   416     
   408     searchTask notNil ifTrue:[
   417     searchTask notNil ifTrue:[
   409         (Dialog 
   418         (Dialog 
   410             confirm:(resources string:'there is already a find file running !!') withCRs
   419             confirm:(resources string:'There is already another find-file task running !!') withCRs
   411             yesLabel:(resources at:'Stop and continue')
   420             yesLabel:(resources at:'Stop other Task and Proceed')
   412             noLabel:(resources at:'Cancel'))
   421             noLabel:(resources at:'Cancel'))
   413         ifFalse:[^ self].
   422         ifFalse:[^ self].
   414         self stop.
   423         self stop.
   415     ].
   424     ].
   416 
   425 
   437                 self enableStop value:true.
   446                 self enableStop value:true.
   438                 self resultList removeAll.
   447                 self resultList removeAll.
   439                 self changeInformationTo:'Find File ' , '- search started ' toTab:true.
   448                 self changeInformationTo:'Find File ' , '- search started ' toTab:true.
   440                 self 
   449                 self 
   441                     doFindFileNamed:namePatterns
   450                     doFindFileNamed:namePatterns
   442                     ignoreCase:self ignoreCaseInName value
   451                     directories:(self searchDirectories value)
       
   452                     ignoreCase:(self ignoreCaseInName value)
   443                     containingString:contentsPattern
   453                     containingString:contentsPattern
   444                     ignoreCaseInContents:self ignoreCaseInContents value
   454                     ignoreCaseInContents:(self ignoreCaseInContents value)
   445                     sameContentsAsFile:nil 
   455                     sameContentsAsFile:nil 
   446                     sameContentsAs:nil 
   456                     sameContentsAs:nil 
   447                     in:self searchDirectoryHolder value.
   457                     in:(self searchDirectoryHolder value).
       
   458 
   448                 self enableStop value:false.
   459                 self enableStop value:false.
   449                 self enableSearch value:true.
   460                 self enableSearch value:true.
   450                 self changeInformationTo:'Find File ' , '- search finished' toTab:true.
   461                 self changeInformationTo:'Find File ' , '- search finished' toTab:true.
   451             ].
   462             ].
   452         ] valueNowOrOnUnwindDo:[
   463         ] valueNowOrOnUnwindDo:[
   598     resultList isNil ifTrue:[
   609     resultList isNil ifTrue:[
   599         resultList := List new.
   610         resultList := List new.
   600         resultList addDependent:self.
   611         resultList addDependent:self.
   601     ].
   612     ].
   602     ^ resultList.
   613     ^ resultList.
       
   614 !
       
   615 
       
   616 searchDirectories
       
   617     searchDirectories isNil ifTrue:[
       
   618         searchDirectories := false asValue.
       
   619     ].
       
   620     ^ searchDirectories.
   603 !
   621 !
   604 
   622 
   605 searchDirectoryHolder
   623 searchDirectoryHolder
   606 
   624 
   607     searchDirectoryHolder isNil ifTrue:[
   625     searchDirectoryHolder isNil ifTrue:[
   724     ].
   742     ].
   725 ! !
   743 ! !
   726 
   744 
   727 !FindFileApplication methodsFor:'private - file stuff'!
   745 !FindFileApplication methodsFor:'private - file stuff'!
   728 
   746 
   729 doFindFileNamed:namePatterns ignoreCase:ignCaseInName containingString:contentsString ignoreCaseInContents:ignCaseInString sameContentsAsFile:filenameToCompareContentsOrNil sameContentsAs:bytesToCompareContentsOrNil in:aDirectory
   747 doFindFileNamed:namePatterns directories:searchDirectories ignoreCase:ignCaseInName containingString:contentsString ignoreCaseInContents:ignCaseInString sameContentsAsFile:filenameToCompareContentsOrNil sameContentsAs:bytesToCompareContentsOrNil in:aDirectory
   730 
   748 
   731     |dir subDirs nameMatches contentsMatches lines contentsToCompare list|
   749     |dir subDirs nameMatches contentsMatches lines contentsToCompare list|
   732 
   750 
   733     list := self resultList.
   751     list := self resultList.
   734     bytesToCompareContentsOrNil notNil ifTrue:[
   752     bytesToCompareContentsOrNil notNil ifTrue:[
   738     subDirs := OrderedCollection new.
   756     subDirs := OrderedCollection new.
   739 
   757 
   740     dir := aDirectory asFilename.
   758     dir := aDirectory asFilename.
   741     self changeInformationTo:'Find File ' , '- searching .' , ((dir name) copyFrom:(self searchDirectoryHolder value asString size + 1)) toTab:false.
   759     self changeInformationTo:'Find File ' , '- searching .' , ((dir name) copyFrom:(self searchDirectoryHolder value asString size + 1)) toTab:false.
   742     (dir directoryContents ? #()) sort do:[:fn |
   760     (dir directoryContents ? #()) sort do:[:fn |
   743         |f|
   761         |f isDirectory|
   744 
   762 
   745         f := dir construct:fn.
   763         f := dir construct:fn.
   746         f isDirectory ifTrue:[
   764         isDirectory := f isDirectory.
       
   765         isDirectory ifTrue:[
   747             f isSymbolicLink ifFalse:[
   766             f isSymbolicLink ifFalse:[
   748                 subDirs add:f
   767                 subDirs add:f
   749             ]
   768             ]
   750         ] ifFalse:[
   769         ].
       
   770         (searchDirectories or:[isDirectory not]) ifTrue:[
   751             (nameMatches := namePatterns isNil) ifFalse:[
   771             (nameMatches := namePatterns isNil) ifFalse:[
   752                 ignCaseInName ifTrue:[
   772                 ignCaseInName ifTrue:[
   753                     nameMatches := namePatterns contains:[:aPattern | aPattern match:(fn asLowercase)]
   773                     nameMatches := namePatterns contains:[:aPattern | aPattern match:(fn asLowercase)]
   754                 ] ifFalse:[
   774                 ] ifFalse:[
   755                     nameMatches := namePatterns contains:[:aPattern | aPattern  match:fn]
   775                     nameMatches := namePatterns contains:[:aPattern | aPattern match:fn]
   756                 ]
   776                 ]
   757             ].
   777             ].
   758             nameMatches ifTrue:[
   778             nameMatches ifTrue:[
   759                 filenameToCompareContentsOrNil notNil ifTrue:[
   779                 isDirectory ifTrue:[
   760                     "/ contents compare ...
   780                     contentsMatches := true.
   761                     contentsMatches := false.
   781                 ] ifFalse:[
   762                     f pathName ~= filenameToCompareContentsOrNil pathName ifTrue:[
   782                     filenameToCompareContentsOrNil notNil ifTrue:[
   763                         f fileSize == filenameToCompareContentsOrNil fileSize ifTrue:[
   783                         "/ contents compare ...
   764                             contentsToCompare isNil ifTrue:[
   784                         contentsMatches := false.
   765                                 filenameToCompareContentsOrNil fileSize < (512*1024) ifTrue:[
   785                         f pathName ~= filenameToCompareContentsOrNil pathName ifTrue:[
   766                                     contentsToCompare := filenameToCompareContentsOrNil binaryContentsOfEntireFile
   786                             f fileSize == filenameToCompareContentsOrNil fileSize ifTrue:[
       
   787                                 contentsToCompare isNil ifTrue:[
       
   788                                     filenameToCompareContentsOrNil fileSize < (512*1024) ifTrue:[
       
   789                                         contentsToCompare := filenameToCompareContentsOrNil binaryContentsOfEntireFile
       
   790                                     ]
       
   791                                 ].
       
   792                                 contentsToCompare isNil ifTrue:[
       
   793                                     "/ too large - compare block-wise ...
       
   794                                     contentsMatches := (filenameToCompareContentsOrNil sameContentsAs:f).
       
   795                                 ] ifFalse:[
       
   796                                     contentsMatches := contentsToCompare = (f binaryContentsOfEntireFile).
   767                                 ]
   797                                 ]
   768                             ].
   798                             ].
   769                             contentsToCompare isNil ifTrue:[
   799                         ] ifFalse:[
   770                                 "/ too large - compare block-wise ...
   800                             f isSymbolicLink ifTrue:[
   771                                 contentsMatches := (filenameToCompareContentsOrNil sameContentsAs:f).
   801                                 list add: (f name , ' is a symbolic link to ' , f pathName).
   772                             ] ifFalse:[
       
   773                                 contentsMatches := contentsToCompare = (f binaryContentsOfEntireFile).
       
   774                             ]
   802                             ]
   775                         ].
   803                         ]
   776                     ] ifFalse:[
   804                     ] ifFalse:[
   777                         f isSymbolicLink ifTrue:[
   805                         "/ string search ...
   778                             list add: (f name , ' is a symbolic link to ' , f pathName).
   806                         (contentsMatches := contentsString isNil) ifFalse:[
   779                         ]
   807                             (f exists and:[f isReadable]) ifFalse:[
   780                     ]
   808                                 list add: (('*** ' , f pathName , ' skipped - unreadable or bad symbolic link ***') asText colorizeAllWith:(Color red darkened)).
   781                 ] ifFalse:[
   809                             ] ifTrue:[
   782                     "/ string search ...
   810                                 f fileSize > (4024*1024) ifTrue:[
   783                     (contentsMatches := contentsString isNil) ifFalse:[
   811                                     list add: (('*** ' , f pathName , ' skipped - too large ***') asText colorizeAllWith:(Color red darkened)).
   784                         (f exists and:[f isReadable]) ifFalse:[
   812                                 ] ifFalse:[
   785                             list add: (('*** ' , f pathName , ' skipped - unreadable or bad symbolic link ***') asText colorizeAllWith:(Color red darkened)).
   813                                     Stream lineTooLongErrorSignal handle:[:ex |
   786                         ] ifTrue:[
   814                                         |cont|
   787                             f fileSize > (4024*1024) ifTrue:[
   815 
   788                                 list add: (('*** ' , f pathName , ' skipped - too large ***') asText colorizeAllWith:(Color red darkened)).
   816                                         "/ this typically happens, when a binary file is read linewise ...
   789                             ] ifFalse:[
   817                                         cont := f readStream binary contentsOfEntireFile asString.
   790                                 Stream lineTooLongErrorSignal handle:[:ex |
   818                                         ignCaseInString ifTrue:[
   791                                     |cont|
   819                                             contentsMatches := cont asLowercase includesString:contentsString asLowercase
   792 
   820                                         ] ifFalse:[
   793                                     "/ this typically happens, when a binary file is read linewise ...
   821                                             contentsMatches := cont includesString:contentsString
   794                                     cont := f readStream binary contentsOfEntireFile asString.
   822                                         ].
   795                                     ignCaseInString ifTrue:[
   823                                     ] do:[    
   796                                         contentsMatches := cont asLowercase includesString:contentsString asLowercase
   824                                         lines := f contents ? #().
   797                                     ] ifFalse:[
   825                                         ignCaseInString ifTrue:[
   798                                         contentsMatches := cont includesString:contentsString
   826                                             contentsMatches := (lines findFirst:[:l | l asLowercase includesString:contentsString asLowercase]) ~~ 0
   799                                     ].
   827                                         ] ifFalse:[
   800                                 ] do:[    
   828                                             contentsMatches := (lines findFirst:[:l | l includesString:contentsString]) ~~ 0
   801                                     lines := f contents ? #().
   829                                         ].
   802                                     ignCaseInString ifTrue:[
       
   803                                         contentsMatches := (lines findFirst:[:l | l asLowercase includesString:contentsString asLowercase]) ~~ 0
       
   804                                     ] ifFalse:[
       
   805                                         contentsMatches := (lines findFirst:[:l | l includesString:contentsString]) ~~ 0
       
   806                                     ].
   830                                     ].
   807                                 ].
   831                                 ].
   808                             ].
   832                             ].
   809                         ].
   833                         ].
   810                     ].
   834                     ].
   818 
   842 
   819     self searchRecursively value ifTrue:[
   843     self searchRecursively value ifTrue:[
   820         subDirs do:[:dir |
   844         subDirs do:[:dir |
   821             self
   845             self
   822                 doFindFileNamed:namePatterns 
   846                 doFindFileNamed:namePatterns 
       
   847                 directories:searchDirectories
   823                 ignoreCase:ignCaseInName 
   848                 ignoreCase:ignCaseInName 
   824                 containingString:contentsString 
   849                 containingString:contentsString 
   825                 ignoreCaseInContents:ignCaseInString 
   850                 ignoreCaseInContents:ignCaseInString 
   826                 sameContentsAsFile:filenameToCompareContentsOrNil 
   851                 sameContentsAsFile:filenameToCompareContentsOrNil 
   827                 sameContentsAs:contentsToCompare
   852                 sameContentsAs:contentsToCompare
   887 ! !
   912 ! !
   888 
   913 
   889 !FindFileApplication class methodsFor:'documentation'!
   914 !FindFileApplication class methodsFor:'documentation'!
   890 
   915 
   891 version
   916 version
   892     ^ '$Header: /cvs/stx/stx/libtool/FindFileApplication.st,v 1.8 2002-11-29 09:47:01 penk Exp $'
   917     ^ '$Header: /cvs/stx/stx/libtool/FindFileApplication.st,v 1.9 2003-02-02 15:51:29 cg Exp $'
   893 ! !
   918 ! !