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 ) |
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:[ |
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 ]. |