137 'The first folder, to be compared against folder2' |
138 'The first folder, to be compared against folder2' |
138 |
139 |
139 #searchDirectory2 |
140 #searchDirectory2 |
140 'The second folder, to be compared against folder1' |
141 'The second folder, to be compared against folder1' |
141 |
142 |
|
143 #showAll |
|
144 'Show all differences in the result list' |
|
145 |
|
146 #showDifferent |
|
147 'Show only files in the result list\which are present in both, but different' |
|
148 |
|
149 #showOnlyIn1 |
|
150 'Show only files in the result list\which are present in the first directory,\but missing in the second' |
|
151 |
|
152 #showOnlyIn2 |
|
153 'Show only files in the result list\which are present in the second directory,\but missing in the first' |
|
154 |
142 ) |
155 ) |
|
156 ! ! |
|
157 |
|
158 !DirectoryDifferenceViewApplication class methodsFor:'image specs'! |
|
159 |
|
160 leftOnlyIcon |
|
161 "This resource specification was automatically generated |
|
162 by the ImageEditor of ST/X." |
|
163 |
|
164 "Do not manually edit this!! If it is corrupted, |
|
165 the ImageEditor may not be able to read the specification." |
|
166 |
|
167 " |
|
168 self leftOnlyIcon inspect |
|
169 ImageEditor openOnClass:self andSelector:#leftOnlyIcon |
|
170 Icon flushCachedIcons |
|
171 " |
|
172 |
|
173 <resource: #image> |
|
174 |
|
175 ^Icon |
|
176 constantNamed:'DirectoryDifferenceViewApplication class leftOnlyIcon' |
|
177 ifAbsentPut:[(Depth8Image width:24 height:24) bits:(ByteArray fromPackedString:' |
|
178 X6M#X6M#X6M#X6M#X&I"X&I"X&I"X&I"X6M#X6M#X6M#X6M#VE!!"X&I"X&I"X&I"X6M#X6M#X6M#X6MXA ]"X&I"X&I"X&I"X6M#X6M#X6M#X0(KC@5"X&I" |
|
179 X&I"X&I"X6M#X6M#X6M#A <PDP5"X&I"X&I"X&I"X6M#X6M#X1LSEADUE 5"X&I"X&I"X&I"X6M#X6M#D1LXE!!$ZD@5"X&I"X&I"X&I"X6M#X6MXA10]G!!<Z |
|
180 H@4MCP4MCP4MHRI"X6M#X0(#G"@$IRXZI2 (JATUEQTUBB%"X6M#A"(HER,%G20-K"<0LSD2L3P5M 5"X6L7NB 9G1<&KB4DAC(;OC0=O#=@PP5"X3\>P$L/ |
|
181 F!!(ZKPPDN#-DOA-EQ$\?R@5"X3]IR"XZKR4-A@P:N1 <O$-LST8TK 5"X6L!!S1H.ACD1L#(;Q@TCQ$YLQ48TT@5"X6M#TUH,P3(:N#P[T5QTUUYWQ$1WLP5" |
|
182 X6M#X5!!YL10;QDTCK3D1LSD1L#H;MB%"X6M#X6MXD38/U@MWL 4MCP4MCP4MJRM"X6M#X6M#VALON UFF@5"X&I"X&I"X&I"X6M#X6M#X5 SV30>W@5"X&I" |
|
183 X&I"X&I"X6M#X6M#X6MXTU5FU 5"X&I"X&I"X&I"X6M#X6M#X6M#X5!!_X@5"X&I"X&I"X&I"X6M#X6M#X6M#X6MXXP5"X&I"X&I"X&I"X6M#X6M#X6M#X6M# |
|
184 VE5"X&I"X&I"X&I"X6M#X6M#X6M#X6M#X&I"X&I"X&I"X&I"') |
|
185 colorMapFromArray:#[251 251 251 249 249 249 234 234 234 210 210 210 224 224 224 213 213 213 184 184 184 176 176 176 238 238 238 245 245 245 200 200 200 187 187 187 240 240 240 171 171 171 233 233 233 198 198 198 246 246 246 249 249 249 236 236 236 174 174 174 207 207 207 241 241 241 247 247 247 226 226 226 219 219 219 237 237 237 227 227 227 216 216 216 231 231 231 247 247 247 234 234 234 229 229 229 245 245 245 178 178 178 188 188 188 185 185 185 232 232 232 231 231 231 228 228 228 244 244 244 242 242 242 175 175 175 193 193 193 232 232 232 228 228 228 225 225 225 229 229 229 227 227 227 226 226 226 223 223 223 221 221 221 220 220 220 219 219 219 223 223 223 237 237 237 179 179 179 200 200 200 236 236 236 221 221 221 220 220 220 217 217 217 214 214 214 213 213 213 210 210 210 215 215 215 235 235 235 239 239 239 230 230 230 218 218 218 212 212 212 208 208 208 202 202 202 230 230 230 211 211 211 238 238 238 209 209 209 205 205 205 204 204 204 201 201 201 197 197 197 225 225 225 183 183 183 187 187 187 217 217 217 214 214 214 212 212 212 211 211 211 209 209 209 196 196 196 180 180 180 248 248 248 186 186 186 215 215 215 180 180 180 240 240 240 174 174 174 196 196 196 172 172 172 255 0 0 0 255 0] |
|
186 mask:((ImageMask width:24 height:24) bits:(ByteArray fromPackedString:'????????????????????????????????????????????????????????????????????????????????????????????????'); yourself); yourself] |
|
187 ! |
|
188 |
|
189 rightOnlyIcon |
|
190 "This resource specification was automatically generated |
|
191 by the ImageEditor of ST/X." |
|
192 |
|
193 "Do not manually edit this!! If it is corrupted, |
|
194 the ImageEditor may not be able to read the specification." |
|
195 |
|
196 " |
|
197 self rightOnlyIcon inspect |
|
198 ImageEditor openOnClass:self andSelector:#rightOnlyIcon |
|
199 Icon flushCachedIcons |
|
200 " |
|
201 |
|
202 <resource: #image> |
|
203 |
|
204 ^Icon |
|
205 constantNamed:'DirectoryDifferenceViewApplication class rightOnlyIcon' |
|
206 ifAbsentPut:[(Depth8Image width:24 height:24) bits:(ByteArray fromPackedString:' |
|
207 X&I"X&I"X&I"X&I"X6M#X6M#X6M#X6M#X&I"X&I"X&I"X%5XX6M#X6M#X6M#X6M#X&I"X&I"X&I"X 5!!VFM#X6M#X6M#X6M#X&I"X&I"X&I"X 5 W5!!#X6M# |
|
208 X6M#X6M#X&I"X&I"X&I"X 5VQ%5QVFM#X6M#X6M#X&I"X&I"X&I"X 5\O#1[D5!!#X6M#X6M#X&I"X&I"X&I"X 4XQ T:C1MXX6M#X6M#X"L)CP4MCP4MCP42 |
|
209 U0MTK38SVFM#X6M#X"$4N3H2LSD1LSD/@4UDN103VU!!#X6M#X 41U41FU5YUUEQSF3P:N#)CKEIQX6M#X 5PED9GSDYF@0UDN3(2LSDDK!!IOHVM#X 4.ED9M |
|
210 SD,>OA ;N PDKR4-F"YJRS]#X 5HO4]FQQ,<QC,:A@P-F!!(ZK4MBO#]#X 5APC<>OS0<N3(DAB4,I!!<_NR 8M6M#X 46MSP3L#D1LB<.KR0_IR,UBB(FX6M# |
|
211 X"$HEQTUEQT(JB ''F"X%IB@^H0)#X6M#X"H!!CP4MCP4MCP4 F!!<^GQ0GVFM#X6M#X&I"X&I"X&I"X 4PF!!$VFALSX6M#X6M#X&I"X&I"X&I"X 4VEQDTD1M# |
|
212 X6M#X6M#X&I"X&I"X&I"X 4QD@<FX6M#X6M#X6M#X&I"X&I"X&I"X 4LB0)#X6M#X6M#X6M#X&I"X&I"X&I"X \FVFM#X6M#X6M#X6M#X&I"X&I"X&I"X%!!X |
|
213 X6M#X6M#X6M#X6M#X&I"X&I"X&I"X&I"X6M#X6M#X6M#X6M#') |
|
214 colorMapFromArray:#[251 251 251 249 249 249 234 234 234 210 210 210 224 224 224 213 213 213 184 184 184 176 176 176 238 238 238 245 245 245 200 200 200 187 187 187 240 240 240 171 171 171 233 233 233 198 198 198 246 246 246 249 249 249 236 236 236 174 174 174 207 207 207 241 241 241 247 247 247 226 226 226 219 219 219 237 237 237 227 227 227 216 216 216 231 231 231 247 247 247 234 234 234 229 229 229 245 245 245 178 178 178 188 188 188 185 185 185 232 232 232 231 231 231 228 228 228 244 244 244 242 242 242 175 175 175 193 193 193 232 232 232 228 228 228 225 225 225 229 229 229 227 227 227 226 226 226 223 223 223 221 221 221 220 220 220 219 219 219 223 223 223 237 237 237 179 179 179 200 200 200 236 236 236 221 221 221 220 220 220 217 217 217 214 214 214 213 213 213 210 210 210 215 215 215 235 235 235 239 239 239 230 230 230 218 218 218 212 212 212 208 208 208 202 202 202 230 230 230 211 211 211 238 238 238 209 209 209 205 205 205 204 204 204 201 201 201 197 197 197 225 225 225 183 183 183 187 187 187 217 217 217 214 214 214 212 212 212 211 211 211 209 209 209 196 196 196 180 180 180 248 248 248 186 186 186 215 215 215 180 180 180 240 240 240 174 174 174 196 196 196 172 172 172 255 0 0 0 255 0] |
|
215 mask:((ImageMask width:24 height:24) bits:(ByteArray fromPackedString:'????????????????????????????????????????????????????????????????????????????????????????????????'); yourself); yourself] |
143 ! ! |
216 ! ! |
144 |
217 |
145 !DirectoryDifferenceViewApplication class methodsFor:'interface specs'! |
218 !DirectoryDifferenceViewApplication class methodsFor:'interface specs'! |
146 |
219 |
147 windowSpec |
220 windowSpec |
405 isButton: true |
478 isButton: true |
406 startGroup: right |
479 startGroup: right |
407 isVisible: false |
480 isVisible: false |
408 labelImage: (ResourceRetriever ToolbarIconLibrary removeTabIcon) |
481 labelImage: (ResourceRetriever ToolbarIconLibrary removeTabIcon) |
409 ) |
482 ) |
|
483 (MenuItem |
|
484 activeHelpKey: showOnlyIn1 |
|
485 label: 'Only in 1)' |
|
486 indication: showOnlyIn1Holder |
|
487 labelImage: (ResourceRetriever DirectoryDifferenceViewApplication leftOnlyIcon) |
|
488 isButton: true |
|
489 isVisible: hasResultListHolder |
|
490 ) |
|
491 (MenuItem |
|
492 activeHelpKey: showOnlyIn2 |
|
493 label: 'Only in 2)' |
|
494 indication: showOnlyIn2Holder |
|
495 labelImage: (ResourceRetriever DirectoryDifferenceViewApplication rightOnlyIcon) |
|
496 isButton: true |
|
497 isVisible: hasResultListHolder |
|
498 ) |
|
499 (MenuItem |
|
500 activeHelpKey: showDifferent |
|
501 label: 'Different Only' |
|
502 indication: showDifferentOnlyHolder |
|
503 labelImage: (ResourceRetriever ToolbarIconLibrary diff22x22Icon2) |
|
504 isButton: true |
|
505 isVisible: hasResultListHolder |
|
506 ) |
|
507 (MenuItem |
|
508 activeHelpKey: showAll |
|
509 label: 'Show All' |
|
510 indication: showAllHolder |
|
511 isButton: true |
|
512 isVisible: hasResultListHolder |
|
513 ) |
410 ) |
514 ) |
411 nil |
515 nil |
412 nil |
516 nil |
413 ) |
517 ) |
414 ! ! |
518 ! ! |
505 ]. |
609 ]. |
506 differ := builder componentAt:'DiffTextView'. |
610 differ := builder componentAt:'DiffTextView'. |
507 differ text1:(text1 ? '') text2:(text2 ? ''). |
611 differ text1:(text1 ? '') text2:(text2 ? ''). |
508 |
612 |
509 "Created: / 12-01-2012 / 03:21:52 / cg" |
613 "Created: / 12-01-2012 / 03:21:52 / cg" |
|
614 ! |
|
615 |
|
616 shouldShow:aListItem |
|
617 |showingWhat| |
|
618 |
|
619 showingWhat := self showWhatHolder value. |
|
620 showingWhat == #all ifTrue:[^ true]. |
|
621 |
|
622 "/ showing filtered |
|
623 ^ (aListItem at:3) == showingWhat |
|
624 ! |
|
625 |
|
626 shownFilesChanged |
|
627 |showingWhat| |
|
628 |
|
629 showingWhat := self showWhatHolder value. |
|
630 showingWhat == #all ifTrue:[ |
|
631 self matchedFilesList contents:unfilteredFilesList. |
|
632 "/ self shownListHolder valueHolder:unfilteredFilesList. |
|
633 "/ self shownListHolder valueHolder:unfilteredFilesList. |
|
634 ^ self. |
|
635 ]. |
|
636 |
|
637 "/ showing filtered |
|
638 |
|
639 filteredFilesList contents:(unfilteredFilesList select:[:entry | (entry at:3) == showingWhat]). |
|
640 self matchedFilesList contents:filteredFilesList. |
|
641 "/ self shownListHolder valueHolder:filteredFilesList. |
510 ! ! |
642 ! ! |
511 |
643 |
512 !DirectoryDifferenceViewApplication methodsFor:'aspects'! |
644 !DirectoryDifferenceViewApplication methodsFor:'aspects'! |
513 |
645 |
514 excludedDirectoryNamePatternHolder |
646 excludedDirectoryNamePatternHolder |
650 ] |
829 ] |
651 ]. |
830 ]. |
652 ]. |
831 ]. |
653 ]. |
832 ]. |
654 |
833 |
655 self matchedFilesList removeAll. |
834 self unfilteredFilesList removeAll. |
|
835 self filteredFilesList removeAll. |
|
836 self shownFilesChanged. "/ to set the filtered list |
|
837 |
656 self windowGroup repairDamage. |
838 self windowGroup repairDamage. |
|
839 |
|
840 itemsFoundQueue := SharedQueue new. |
657 |
841 |
658 self |
842 self |
659 startSearchTask:[ |
843 startSearchTask:[ |
660 self changeInformationTo:'Directory Diff - searching ' toTab:true. |
844 self changeInformationTo:'Directory Diff - searching ' toTab:true. |
661 |
845 |
662 self shownListHolder valueHolder:(self matchedFilesList). |
|
663 |
|
664 dir1 |
846 dir1 |
665 recursiveDirectoryContentsDo:[:relFn1 | |
847 recursiveDirectoryContentsDo:[:relFn1 | |
666 |fn1 fn2 fn1BaseName| |
848 |fn1 fn2 fn1BaseName newListItem| |
667 |
849 |
668 fn1 := dir1 construct:relFn1. |
850 fn1 := dir1 construct:relFn1. |
669 fn1BaseName := fn1 baseName. |
851 fn1BaseName := fn1 baseName. |
|
852 newListItem := nil. |
670 (namePattern isNil or:[namePattern compoundMatch:fn1BaseName caseSensitive:ignoreCaseInName not]) ifTrue:[ |
853 (namePattern isNil or:[namePattern compoundMatch:fn1BaseName caseSensitive:ignoreCaseInName not]) ifTrue:[ |
671 (fileExcludeFilterOrNil isNil or:[fileExcludeFilterOrNil value:fn1BaseName]) ifTrue:[ |
854 (fileExcludeFilterOrNil isNil or:[(fileExcludeFilterOrNil value:fn1BaseName) not]) ifTrue:[ |
672 fn2 := dir2 construct:relFn1. |
855 fn2 := dir2 construct:relFn1. |
673 fn1 isDirectory ifTrue:[ |
856 fn1 isDirectory ifTrue:[ |
674 self notify:('Comparing %1...' bindWith:relFn1 asString allBold). |
857 self notify:('Comparing %1...' bindWith:relFn1 asString allBold). |
675 fn2 exists ifFalse:[ |
858 fn2 exists ifFalse:[ |
676 directoriesOnlyInDirectory1 add:fn1. |
859 directoriesOnlyInDirectory1 add:fn1. |
677 self matchedFilesList add:{ relFn1 . 'Directory only in directory1' }. |
860 newListItem := { relFn1 . 'Directory only in directory1' . #onlyIn1}. |
678 ]. |
861 ]. |
679 ] ifFalse:[ |
862 ] ifFalse:[ |
680 fn2 exists ifTrue:[ |
863 fn2 exists ifTrue:[ |
681 filesSearchedCount := filesSearchedCount + 1. |
864 filesSearchedCount := filesSearchedCount + 1. |
682 (fn1 sameContentsAs:fn2) ifFalse:[ |
865 (fn1 sameContentsAs:fn2) ifFalse:[ |
683 filesWhichAreDifferent add:fn1. |
866 filesWhichAreDifferent add:fn1. |
684 self matchedFilesList add:{ relFn1 . 'Different' }. |
867 newListItem := { relFn1 . 'Different' . #different }. |
685 ]. |
868 ]. |
686 ] ifFalse:[ |
869 ] ifFalse:[ |
687 filesOnlyInDirectory1 add:fn1. |
870 filesOnlyInDirectory1 add:fn1. |
688 self matchedFilesList add:{ relFn1 . 'File only in directory1' }. |
871 newListItem := { relFn1 . 'File only in directory1' . #onlyIn1}. |
689 ]. |
872 ]. |
|
873 ]. |
|
874 newListItem notNil ifTrue:[ |
|
875 unfilteredFilesList add:newListItem. |
|
876 itemsFoundQueue add:newListItem. |
|
877 self enqueueMessage:#updateList for:self arguments:#(). |
690 ]. |
878 ]. |
691 ] ifFalse:[ |
879 ] ifFalse:[ |
692 filesSkippedCount := filesSkippedCount + 1. |
880 filesSkippedCount := filesSkippedCount + 1. |
693 ] |
881 ] |
694 ] |
882 ] |
695 ] |
883 ] |
696 filterForVisitingDirectories:directoryExcludeFilterOrNil. |
884 filterForVisitingDirectories:directoryExcludeFilterOrNil. |
697 |
885 |
698 dir2 |
886 dir2 |
699 recursiveDirectoryContentsDo:[:relFn2 | |
887 recursiveDirectoryContentsDo:[:relFn2 | |
700 |fn1 fn2 fn2BaseName| |
888 |fn1 fn2 fn2BaseName newListItem| |
701 |
889 |
702 fn2 := dir2 construct:relFn2. |
890 fn2 := dir2 construct:relFn2. |
703 fn2BaseName := fn2 baseName. |
891 fn2BaseName := fn2 baseName. |
704 (namePattern isNil or:[namePattern compoundMatch:fn2BaseName caseSensitive:ignoreCaseInName not]) ifTrue:[ |
892 (namePattern isNil or:[namePattern compoundMatch:fn2BaseName caseSensitive:ignoreCaseInName not]) ifTrue:[ |
705 (fileExcludeFilterOrNil isNil or:[fileExcludeFilterOrNil value:fn2BaseName]) ifFalse:[ |
893 (fileExcludeFilterOrNil isNil or:[(fileExcludeFilterOrNil value:fn2BaseName) not]) ifTrue:[ |
706 fn1 := dir1 construct:relFn2. |
894 fn1 := dir1 construct:relFn2. |
707 fn1 exists ifFalse:[ |
895 fn1 exists ifFalse:[ |
708 fn1 isDirectory ifTrue:[ |
896 fn2 isDirectory ifTrue:[ |
709 directoriesOnlyInDirectory1 add:fn1. |
897 directoriesOnlyInDirectory2 add:fn2. |
710 self matchedFilesList add:{ relFn2 . 'Directory only in directory2' }. |
898 newListItem := { relFn2 . 'Directory only in directory2' . #onlyIn2}. |
711 ] ifFalse:[ |
899 ] ifFalse:[ |
712 filesOnlyInDirectory2 add:fn2. |
900 filesOnlyInDirectory2 add:fn2. |
713 self matchedFilesList add:{ relFn2 . 'File only in directory2' }. |
901 newListItem := { relFn2 . 'File only in directory2' . #onlyIn2}. |
714 ] |
902 ]. |
|
903 newListItem notNil ifTrue:[ |
|
904 unfilteredFilesList add:newListItem. |
|
905 itemsFoundQueue add:newListItem. |
|
906 self enqueueMessage:#updateList for:self arguments:#(). |
|
907 ]. |
715 ]. |
908 ]. |
716 ]. |
909 ]. |
717 ] ifFalse:[ |
910 ] ifFalse:[ |
718 filesSkippedCount := filesSkippedCount + 1. |
911 filesSkippedCount := filesSkippedCount + 1. |
719 ] |
912 ] |
757 |
950 |
758 timeMillis := timeDuration asMilliseconds. |
951 timeMillis := timeDuration asMilliseconds. |
759 timeString := timeDuration printStringForApproximation. |
952 timeString := timeDuration printStringForApproximation. |
760 |
953 |
761 nIn1 := filesOnlyInDirectory1 size. |
954 nIn1 := filesOnlyInDirectory1 size. |
762 nIn2 := filesOnlyInDirectory1 size. |
955 nIn2 := filesOnlyInDirectory2 size. |
763 nDifferent := filesWhichAreDifferent size. |
956 nDifferent := filesWhichAreDifferent size. |
764 |
957 |
765 ^ resources |
958 ^ resources |
766 string:('different:%1, only in one:%2 / %3 (%4 files visited; %6 files/s).') |
959 string:('different:%1, only in 1: %2, only in 2: %3 (%4 files visited; %6 files/s).') |
767 with:nDifferent |
960 with:nDifferent |
768 with:nIn1 |
961 with:nIn1 |
769 with:nIn2 |
962 with:nIn2 |
770 with:filesSearchedCount |
963 with:filesSearchedCount |
771 with:(UnitConverter fileSizeSIStringFor:(bytesSearchedCount * 1000 / (timeMillis max:1))) |
964 with:(UnitConverter fileSizeSIStringFor:(bytesSearchedCount * 1000 / (timeMillis max:1))) |
772 with:((filesSearchedCount * 1000 / (timeMillis max:1)) asFixedPoint:1). |
965 with:((filesSearchedCount * 1000 / (timeMillis max:1)) asFixedPoint:1). |
|
966 ! |
|
967 |
|
968 updateList |
|
969 |next| |
|
970 |
|
971 [(next := itemsFoundQueue nextOrNil) notNil] whileTrue:[ |
|
972 (self shouldShow:next) ifTrue:[ |
|
973 filteredFilesList add:next. |
|
974 self matchedFilesList add:next |
|
975 ] |
|
976 ]. |
|
977 self windowGroup repairDamage. |
773 ! ! |
978 ! ! |
774 |
979 |
775 !DirectoryDifferenceViewApplication methodsFor:'startup & release'! |
980 !DirectoryDifferenceViewApplication methodsFor:'startup & release'! |
776 |
981 |
777 postOpenWith:aBuilder |
982 postOpenWith:aBuilder |