674 |root mergeItems| |
672 |root mergeItems| |
675 |
673 |
676 root := classItemList first. |
674 root := classItemList first. |
677 |
675 |
678 root isUnspecified ifTrue:[ mergeItems := root children ] |
676 root isUnspecified ifTrue:[ mergeItems := root children ] |
679 ifFalse:[ mergeItems := nil ]. |
677 ifFalse:[ mergeItems := nil ]. |
680 |
678 |
681 self buildFromClass:aClass. |
679 self loadFromClass:aClass. |
682 |
680 |
683 mergeItems size ~~ 0 ifTrue:[ |
681 mergeItems size ~~ 0 ifTrue:[ |
684 root := classItemList first. |
682 root := classItemList first. |
685 |
683 |
686 mergeItems do:[:anItem| |item hkey| |
684 mergeItems do:[:anItem| |item hkey| |
687 hkey := anItem helpKey. |
685 hkey := anItem helpKey. |
688 item := root detectItemWithKey:hkey. |
686 item := root detectItemWithKey:hkey. |
689 |
687 |
690 item isNil ifTrue:[ |
688 item isNil ifTrue:[ |
691 item := KeyItem helpKey:hkey helpText:(anItem helpText). |
689 item := KeyItem helpKey:hkey helpText:(anItem helpText). |
692 root add:item sortBlock:[:a :b| a label < b label ]. |
690 root add:item sortBlock:[:a :b| a label < b label ]. |
693 ] ifFalse:[ |
691 ] ifFalse:[ |
694 item helpText:(anItem helpText). |
692 item helpText:(anItem helpText). |
695 ] |
693 ] |
696 ] |
694 ] |
697 ]. |
695 ]. |
698 ! |
696 ! |
699 |
697 |
700 buildFromClass:aClass |
698 loadFromClass:aClass |
701 "reads the help dictionary from aClass and find remaining classes |
699 "reads the help dictionary from aClass and find remaining classes |
702 'between' aClass and ApplicationModel |
700 'between' aClass and ApplicationModel |
703 " |
701 " |
704 |lastContents root list resource helpSpecSelector| |
702 |lastContents root list helpSpecSelector| |
705 |
703 |
706 helpSpecSelector := self specSelector. |
704 helpSpecSelector := self specSelector. |
707 specClass := self getHelpSpecClassFromClass:aClass. |
705 specClass := self getHelpSpecClassFromClass:aClass. |
708 |
706 |
709 list := OrderedCollection new. |
707 list := OrderedCollection new. |
710 |
708 |
711 (specClass isClass and:[specClass isLoaded]) ifTrue:[ |
709 (specClass isClass and:[specClass isLoaded]) ifTrue:[ |
712 lastContents := nil. |
710 lastContents := nil. |
713 resource := specClass name, ' ', helpSpecSelector. |
711 |
714 self addToHistory:(Association key:resource value:#'loadFromMessage:'). |
712 self addHistoryEntryForClass:specClass selector:helpSpecSelector. |
715 |
713 |
716 specClass withAllSuperclasses reverse do:[:aClass| |value name| |
714 specClass withAllSuperclasses reverse do:[:aClass| |value name| |
717 lastContents isNil ifTrue:[ |
715 lastContents isNil ifTrue:[ |
718 aClass == ApplicationModel ifTrue:[ |
716 aClass == ApplicationModel ifTrue:[ |
719 lastContents := IdentityDictionary new |
717 lastContents := IdentityDictionary new |
720 ]. |
718 ]. |
721 ] ifFalse:[ |
719 ] ifFalse:[ |
722 root := ClassItem onClass:aClass. |
720 root := ClassItem onClass:aClass. |
723 |
721 |
724 (aClass class includesSelector:helpSpecSelector) ifTrue:[ |
722 (aClass respondsTo: helpSpecSelector) ifTrue:[ |
725 value := aClass perform:helpSpecSelector. |
723 value := aClass perform: helpSpecSelector. |
726 |
724 ]. |
|
725 |
|
726 value notNil ifTrue:[ |
727 value keysAndValuesDo:[:k :v| |cval| |
727 value keysAndValuesDo:[:k :v| |cval| |
728 cval := lastContents at:k ifAbsent:self. |
728 cval := lastContents at:k ifAbsent:self. |
729 cval = v ifFalse:[ root add:(KeyItem helpKey:k helpText:v) ]. |
729 cval = v ifFalse:[ root add:(KeyItem helpKey:k helpText:v) ]. |
730 ]. |
730 ]. |
731 lastContents := value. |
731 lastContents := value. |
745 self updateIcons. |
745 self updateIcons. |
746 classItemModel value:(list last) |
746 classItemModel value:(list last) |
747 ]. |
747 ]. |
748 ! |
748 ! |
749 |
749 |
750 buildFromClass: aClass andSelector: aSelector |
750 loadFromClass:aClass andSelector:aSelector |
751 "sets aSelector and reads the help dictionary from aClass |
751 "reads the help dictionary from aClass" |
752 " |
752 |
|
753 self assert:(aClass isNil or:[aClass isClass]). |
|
754 |
753 specSelector := aSelector. |
755 specSelector := aSelector. |
754 self buildFromClass:aClass |
756 self loadFromClass:aClass |
755 ! |
757 ! |
756 |
758 |
757 buildFromHelpTool:aHelpTool |
759 loadFromHelpTool:aHelpTool |
758 "build from another helpTool |
760 "build from another helpTool |
759 " |
761 " |
760 specClass := aHelpTool specClass. |
762 specClass := aHelpTool specClass. |
761 specSelector := aHelpTool specSelector. |
763 specSelector := aHelpTool specSelector. |
762 classItemList := aHelpTool classItemListHolder value. |
764 classItemList := aHelpTool classItemListHolder value. |
863 ^ aBlock ensure:[modifiedHolder := holder] |
865 ^ aBlock ensure:[modifiedHolder := holder] |
864 ! ! |
866 ! ! |
865 |
867 |
866 !UIHelpTool methodsFor:'private'! |
868 !UIHelpTool methodsFor:'private'! |
867 |
869 |
868 extractResourceFrom:aString |
870 getHelpSpecClassFromClass:aClass |
869 "extracts class and selector from a resource string. On success |
871 |cls| |
870 an association with the key a class and the selector as value |
872 |
871 is returned. Otherwise nil is returned |
873 aClass isNil ifTrue:[^ nil]. |
872 " |
874 |
873 |words newClass newSel| |
875 cls := self resolveName:aClass. |
874 |
876 cls isNil ifTrue:[ ^ nil ]. |
875 aString size ~~ 0 ifTrue:[ |
877 |
876 words := aString asCollectionOfWords. |
878 cls := cls perform:#helpSpecClass ifNotUnderstood:cls. |
877 |
879 |
878 words size == 2 ifTrue:[ |
880 (cls isBehavior and:[cls isLoaded]) ifTrue:[ |
879 newClass := self resolveName:(words first). |
881 ^ cls |
880 |
|
881 (newClass isClass and:[newClass isLoaded]) ifTrue:[ |
|
882 newSel := words last asSymbol. |
|
883 |
|
884 (newClass class includesSelector:newSel) ifTrue:[ |
|
885 ^ Association key:newClass value:newSel |
|
886 ]. |
|
887 ]. |
|
888 ]. |
|
889 ]. |
882 ]. |
890 ^ nil |
883 ^ nil |
891 ! |
884 ! |
892 |
885 |
893 getHelpSpecClassFromClass:aClass |
886 loadFromMessage:classAndSelector |
894 "oops |
|
895 " |
|
896 |cls| |
|
897 |
|
898 aClass notNil ifTrue:[ |
|
899 cls := self resolveName:aClass. |
|
900 |
|
901 cls notNil ifTrue:[ |
|
902 cls := cls perform:#helpSpecClass ifNotUnderstood:cls. |
|
903 |
|
904 (cls isClass and:[cls isLoaded]) ifTrue:[ |
|
905 ^ cls |
|
906 ]. |
|
907 ]. |
|
908 ]. |
|
909 ^ nil |
|
910 ! |
|
911 |
|
912 loadFromMessage:aString |
|
913 "Set and rebuild the specClass and specSelector from a resource string. |
887 "Set and rebuild the specClass and specSelector from a resource string. |
914 On success true is returned otherwise false. If the current spec is |
888 On success true is returned otherwise false. If the current spec is |
915 modified, a dialog is launched. |
889 modified, a dialog is launched." |
916 " |
890 |
917 |association| |
891 self askForModification ifFalse:[ ^ false]. |
918 |
892 |
919 association := self extractResourceFrom:aString. |
893 classAndSelector notNil ifTrue:[ |
920 |
894 self loadFromClass:(classAndSelector methodClass) andSelector:(classAndSelector methodSelector). |
921 association notNil ifTrue:[ |
895 ^ true |
922 self askForModification ifTrue:[ |
|
923 self buildFromClass:(association key) andSelector:(association value). |
|
924 ^ true |
|
925 ]. |
|
926 ]. |
|
927 ^ false |
|
928 ! |
|
929 |
|
930 resourceMessage:aString |
|
931 "Set the specClass and specSelector from a resource string. On |
|
932 success true is returned otherwise false. |
|
933 " |
|
934 |association| |
|
935 |
|
936 association := self extractResourceFrom:aString. |
|
937 |
|
938 association notNil ifTrue:[ |
|
939 specClass := association key. |
|
940 specSelector := association value. |
|
941 ^ true |
|
942 ]. |
896 ]. |
943 ^ false |
897 ^ false |
944 ! |
898 ! |
945 |
899 |
946 updateIcons |
900 updateIcons |