110 subclassesAndPrivateClassesPerClass := IdentityDictionary new. |
110 subclassesAndPrivateClassesPerClass := IdentityDictionary new. |
111 |
111 |
112 Smalltalk allClassesDo:[:cls | |
112 Smalltalk allClassesDo:[:cls | |
113 |owner superclass info| |
113 |owner superclass info| |
114 |
114 |
115 (owner := cls owningClass) notNil ifTrue:[ |
115 "/ (owner := cls owningClass) notNil ifTrue:[ |
116 info := subclassesAndPrivateClassesPerClass at:owner ifAbsent:nil. |
116 "/ info := subclassesAndPrivateClassesPerClass at:owner ifAbsent:nil. |
117 info isNil ifTrue:[ |
117 "/ info isNil ifTrue:[ |
118 subclassesAndPrivateClassesPerClass at:owner put:(info := Array with:IdentitySet new |
118 "/ subclassesAndPrivateClassesPerClass at:owner put:(info := Array with:IdentitySet new |
119 with:IdentitySet new). |
119 "/ with:IdentitySet new). |
120 ]. |
120 "/ ]. |
121 (info at:2) add:cls |
121 "/ (info at:2) add:cls |
122 ] ifFalse:[ |
122 "/ ] ifFalse:[ |
123 superclass := cls superclass. |
123 superclass := cls superclass. |
124 superclass notNil ifTrue:[ |
124 superclass notNil ifTrue:[ |
125 info := subclassesAndPrivateClassesPerClass at:superclass ifAbsent:nil. |
125 info := subclassesAndPrivateClassesPerClass at:superclass ifAbsent:nil. |
126 info isNil ifTrue:[ |
126 info isNil ifTrue:[ |
127 subclassesAndPrivateClassesPerClass at:superclass put:(info := Array with:IdentitySet new |
127 subclassesAndPrivateClassesPerClass at:superclass put:(info := Array with:IdentitySet new |
128 with:IdentitySet new). |
128 with:IdentitySet new). |
129 ]. |
129 ]. |
130 (info at:1) add:cls |
130 (info at:1) add:cls |
131 ] |
131 ] |
132 ] |
132 "/ ] |
133 ]. |
133 ]. |
134 |
134 |
135 ^ [:aTreeItem| |
135 ^ [:aTreeItem| |
136 |classes itemClass info| |
136 |classes itemClass info| |
137 |
137 |
666 |cont children initialContents setOfCategories itemCategory setOfClasses| |
664 |cont children initialContents setOfCategories itemCategory setOfClasses| |
667 |
665 |
668 (cont := aTreeItem contents) isBehavior ifTrue:[ |
666 (cont := aTreeItem contents) isBehavior ifTrue:[ |
669 children := privateClasses select:[:cls | cls owningClass == aTreeItem contents]. |
667 children := privateClasses select:[:cls | cls owningClass == aTreeItem contents]. |
670 children := children asSortedCollection: [:c1 :c2| c1 name <= c2 name]. |
668 children := children asSortedCollection: [:c1 :c2| c1 name <= c2 name]. |
671 children := children collect: [:child| TreeItem name: child name , ' (', child superclass name, ')' contents: child] |
669 "/ children := children collect: [:child| TreeItem name: child name , ' (', child superclass name, ')' contents: child] |
|
670 children := children collect: [:child| TreeItem name:(child name) contents: child] |
672 ] ifFalse:[ |
671 ] ifFalse:[ |
673 cont size == 0 ifTrue:[ |
672 cont size == 0 ifTrue:[ |
674 setOfCategories := childrenPerCategory keys. |
673 setOfCategories := childrenPerCategory keys. |
675 children := setOfCategories asSortedCollection. |
674 children := setOfCategories asSortedCollection. |
676 children := children collect: [:nm | TreeItem name:nm contents:#Category] |
675 children := children collect: [:nm | TreeItem name:nm contents:#Category] |
728 !ResourceSelectionBrowser methodsFor:'callbacks-user'! |
725 !ResourceSelectionBrowser methodsFor:'callbacks-user'! |
729 |
726 |
730 classSelected |
727 classSelected |
731 "after a class selection, read the allowed resource methods of the selected class" |
728 "after a class selection, read the allowed resource methods of the selected class" |
732 |
729 |
733 ClassPresentation = #'Class Hierarchy' |
730 |sel| |
734 ifTrue: [self selectionOfClassHierarchy value isNil ifTrue: [^nil]] |
731 |
735 ifFalse: [self selectionOfClassCategories value isNil ifTrue: [^nil]]. |
732 "/ ClassPresentation = #'Class Hierarchy' |
|
733 "/ ifTrue: [sel := self selectionOfClassHierarchy value] |
|
734 "/ ifFalse: [sel := self selectionOfClassCategories value]. |
|
735 "/ |
|
736 "/ sel notNil ifTrue:[ |
|
737 "/ resourceClass := sel name. |
|
738 "/ ]. |
|
739 self updateResourceMethodList. |
|
740 ! |
|
741 |
|
742 classSelectionUpdate:clsPattern |
|
743 |foundClass classes| |
|
744 |
|
745 clsPattern notNil ifTrue:[ |
|
746 foundClass := Smalltalk at:(clsPattern printString asSymbol). |
|
747 ]. |
|
748 (foundClass isClass not or:[foundClass name ~= clsPattern]) |
|
749 ifTrue: [ |
|
750 classes := allClasses select: [:cls| cls name size >= clsPattern size]. |
|
751 1 to: clsPattern size do: [:i| |
|
752 classes := classes select: [:cls| (cls name at: i) == (clsPattern at: i)]. |
|
753 ]. |
|
754 foundClass := classes at: 1 ifAbsent: [nil] |
|
755 ]. |
|
756 |
|
757 foundClass notNil ifTrue: [ |
|
758 foundClass isLoaded ifFalse:[ |
|
759 foundClass autoload. |
|
760 foundClass := Smalltalk at:foundClass name. |
|
761 ]. |
|
762 |
|
763 ClassPresentation = #'Class Hierarchy' ifTrue: [ |
|
764 |searchArgs nonSuperclasses hierItem| |
|
765 |
|
766 false "foundClass isPrivate" |
|
767 ifFalse: [searchArgs := foundClass withAllSuperclasses reverse] |
|
768 ifTrue: [searchArgs := foundClass owningClass withAllSuperclasses reverse. searchArgs add: foundClass] |
|
769 . |
|
770 (nonSuperclasses := self treeViewClassHierarchyContents allSuperclasses) notNil |
|
771 ifTrue: [searchArgs := searchArgs reject: [:cls| nonSuperclasses includes: cls]]. |
|
772 |
|
773 hierItem := self rootOfClassHierarchy detectChild:[:child :arg| child contents == arg] arguments:searchArgs. |
|
774 hierItem notNil ifTrue:[ |
|
775 self selectionOfClassHierarchy value:hierItem. |
|
776 ]. |
|
777 ] |
|
778 ifFalse: [ |
|
779 |searchArgs hierItem| |
|
780 |
|
781 false "foundClass isPrivate" |
|
782 ifTrue: [searchArgs := Array with: 'Categories' with: foundClass category with: foundClass owningClass name with: foundClass name] |
|
783 ifFalse: [searchArgs := Array with: 'Categories' with: foundClass category with: foundClass name]. |
|
784 |
|
785 hierItem := self rootOfClassCategories detectChild:[:child :arg| (child name upTo: $ ) = arg] arguments:searchArgs. |
|
786 hierItem notNil ifTrue:[ |
|
787 self selectionOfClassCategories value: hierItem. |
|
788 ]. |
|
789 ]. |
|
790 ]. |
|
791 self valueOfClassName value: clsPattern |
|
792 ! |
|
793 |
|
794 resourceDoubleClicked |
|
795 "after a double click on resource method, accept it and close" |
|
796 |
|
797 accept value: true. |
|
798 self closeRequest |
|
799 ! |
|
800 |
|
801 resourceSelected |
|
802 "after a click on a resource method, set its selector into the field" |
|
803 |
|
804 self selectionOfResourceMethod value notNil |
|
805 ifTrue: [self valueOfResourceSelector value: self selectionOfResourceMethod value selector] |
|
806 ! |
|
807 |
|
808 updateResourceMethodList |
|
809 "read the allowed resource methods of the selected class" |
|
810 |
|
811 |class className item| |
|
812 |
|
813 resourceClass notNil ifTrue:[ |
|
814 class := Smalltalk at:resourceClass asSymbol. |
|
815 ]. |
|
816 class isNil ifTrue:[ |
|
817 ClassPresentation = #'Class Hierarchy' |
|
818 ifTrue: [item := self selectionOfClassHierarchy value ] |
|
819 ifFalse: [item := self selectionOfClassCategories value ]. |
|
820 item notNil ifTrue:[ |
|
821 className := item name. |
|
822 class := Smalltalk at:className asSymbol |
|
823 ]. |
|
824 ]. |
|
825 |
|
826 class isNil ifTrue: [^self]. |
|
827 |
|
828 className := class theNonMetaclass name. |
736 |
829 |
737 self withWaitCursorDo: |
830 self withWaitCursorDo: |
738 [ |
831 [ |
739 |clsName newContents class| |
832 |newContents| |
740 |
833 |
741 resourceTypes isNil ifTrue: [resourceTypes := Method resourceTypes]. |
834 resourceTypes isNil ifTrue: [resourceTypes := Method resourceTypes]. |
742 |
835 |
743 ClassPresentation = #'Class Hierarchy' |
836 self valueOfClassName value: className. |
744 ifTrue: [clsName := (self selectionOfClassHierarchy value name upTo: $ ) asSymbol] |
837 self class lastSelection: className. |
745 ifFalse: [clsName := (self selectionOfClassCategories value name upTo: $ ) asSymbol]. |
838 |
746 |
|
747 self valueOfClassName value: clsName. |
|
748 self class lastSelection: clsName. |
|
749 |
|
750 class := Smalltalk at: clsName. |
|
751 newContents := class class methodDictionary asOrderedCollection |
839 newContents := class class methodDictionary asOrderedCollection |
752 select: [:m | m resources notNil |
840 select: [:m | m resources notNil |
753 and: [resourceTypes includes: m resourceType] |
841 and: [resourceTypes includes: m resourceType] |
754 ]. |
842 ]. |
755 newContents := newContents sort:[:m1 :m2 | m1 selector < m2 selector]. |
843 newContents := newContents sort:[:m1 :m2 | m1 selector < m2 selector]. |
756 newContents := newContents collect:[:m| (ResourceMethod new method:m)]. |
844 newContents := newContents collect:[:m| (ResourceMethod new method:m)]. |
757 |
845 |
758 self listOfResourceMethods contents:newContents |
846 self listOfResourceMethods contents:newContents |
759 . |
847 . |
760 ] |
848 ] |
761 ! |
|
762 |
|
763 classSelectionUpdate:clsPattern |
|
764 |foundClass classes| |
|
765 |
|
766 clsPattern notNil ifTrue:[ |
|
767 foundClass := Smalltalk at:(clsPattern printString asSymbol). |
|
768 ]. |
|
769 (foundClass isClass not or:[foundClass name ~= clsPattern]) |
|
770 ifTrue: |
|
771 [ |
|
772 classes := allClasses select: [:cls| cls name size >= clsPattern size]. |
|
773 1 to: clsPattern size do: |
|
774 [:i| |
|
775 classes := classes select: [:cls| (cls name at: i) == (clsPattern at: i)]. |
|
776 ]. |
|
777 foundClass := classes at: 1 ifAbsent: [nil] |
|
778 ]. |
|
779 foundClass notNil |
|
780 ifTrue: |
|
781 [ |
|
782 ClassPresentation = #'Class Hierarchy' |
|
783 ifTrue: |
|
784 [ |
|
785 |searchArgs nonSuperclasses| |
|
786 foundClass isPrivate |
|
787 ifFalse: [searchArgs := foundClass withAllSuperclasses reverse] |
|
788 ifTrue: [searchArgs := foundClass owningClass withAllSuperclasses reverse. searchArgs add: foundClass] |
|
789 . |
|
790 (nonSuperclasses := self treeViewClassHierarchyContents allSuperclasses) notNil |
|
791 ifTrue: [searchArgs := searchArgs reject: [:cls| nonSuperclasses includes: cls]]. |
|
792 |
|
793 self selectionOfClassHierarchy value: (self rootOfClassHierarchy detectChild:[:child :arg| child contents == arg] arguments:searchArgs). |
|
794 ] |
|
795 ifFalse: |
|
796 [ |
|
797 |searchArgs| |
|
798 foundClass isPrivate |
|
799 ifTrue: [searchArgs := Array with: 'Categories' with: foundClass category with: foundClass owningClass name with: foundClass name] |
|
800 ifFalse: [searchArgs := Array with: 'Categories' with: foundClass category with: foundClass name]. |
|
801 |
|
802 self selectionOfClassCategories value: (self rootOfClassCategories detectChild:[:child :arg| (child name upTo: $ ) = arg] arguments:searchArgs). |
|
803 ]. |
|
804 ]. |
|
805 self valueOfClassName value: clsPattern |
|
806 |
|
807 |
|
808 ! |
|
809 |
|
810 resourceDoubleClicked |
|
811 "after a double click on resource method, accept it and close" |
|
812 |
|
813 accept value: true. |
|
814 self closeRequest |
|
815 ! |
|
816 |
|
817 resourceSelected |
|
818 "after a click on a resource method, set its selector into the field" |
|
819 |
|
820 self selectionOfResourceMethod value notNil |
|
821 ifTrue: [self valueOfResourceSelector value: self selectionOfResourceMethod value selector] |
|
822 ! ! |
849 ! ! |
823 |
850 |
824 !ResourceSelectionBrowser methodsFor:'instance creation'! |
851 !ResourceSelectionBrowser methodsFor:'instance creation'! |
825 |
852 |
826 openOnSuperclass: aSuperclassOrSymbol andClass: aClassOrSymbol andSelector: aSelector withResourceTypes: aResourceTypes |
853 openOnSuperclass: aSuperclassOrSymbol andClass: aClassOrSymbol andSelector: aSelector withResourceTypes: aResourceTypes |
828 aSuperclassOrSymbol, |
855 aSuperclassOrSymbol, |
829 and aClassOrSymbol, |
856 and aClassOrSymbol, |
830 and aSelector, |
857 and aSelector, |
831 with allowed aResourceTypes" |
858 with allowed aResourceTypes" |
832 |
859 |
833 |clsName clsNameString| |
860 |clsName clsNameString cls| |
834 |
861 |
835 resourceMethod := aSelector. |
862 resourceMethod := aSelector. |
836 resourceTypes := aResourceTypes. |
863 resourceTypes := aResourceTypes. |
837 resourceSuperclass := aSuperclassOrSymbol isClass ifTrue: [aSuperclassOrSymbol name] ifFalse: [aSuperclassOrSymbol]. |
864 resourceSuperclass := aSuperclassOrSymbol isClass ifTrue: [aSuperclassOrSymbol name] ifFalse: [aSuperclassOrSymbol]. |
838 resourceClass := nil. |
865 resourceClass := nil. |
839 |
866 |
840 aClassOrSymbol isClass |
867 aClassOrSymbol isClass |
841 ifTrue: [resourceClass := aClassOrSymbol name] |
868 ifTrue: [cls := aClassOrSymbol. resourceClass := aClassOrSymbol name] |
842 ifFalse: [ |
869 ifFalse: [ |
843 aClassOrSymbol size > 0 ifTrue:[ |
870 aClassOrSymbol size > 0 ifTrue:[ |
844 (Smalltalk at: aClassOrSymbol) notNil |
871 (cls := Smalltalk at: aClassOrSymbol) notNil |
845 ifTrue: [resourceClass := aClassOrSymbol] |
872 ifTrue: [resourceClass := aClassOrSymbol] |
846 ] |
873 ] |
847 ]. |
874 ]. |
848 self valueOfResourceSelector value:(aSelector ? ''). |
875 self valueOfResourceSelector value:(aSelector ? ''). |
849 |
876 cls notNil ifTrue:[ |
|
877 "/ TODO: update tree |
|
878 ]. |
850 self open. |
879 self open. |
851 |
880 |
852 (clsName := self selectionOfClassHierarchy value) isNil ifTrue:[ |
881 (clsName := self selectionOfClassHierarchy value) isNil ifTrue:[ |
853 (clsName := self selectionOfClassCategories value) isNil ifTrue:[ |
882 (clsName := self selectionOfClassCategories value) isNil ifTrue:[ |
854 (clsNameString := self valueOfClassName value) isNil ifTrue:[ |
883 (clsNameString := self valueOfClassName value) isNil ifTrue:[ |