UIHelpTool.st
changeset 740 e7362f3ab5e5
parent 722 a1bb632b1e00
child 750 9b705e31d38e
--- a/UIHelpTool.st	Fri Mar 20 19:11:50 1998 +0100
+++ b/UIHelpTool.st	Fri Mar 20 19:25:20 1998 +0100
@@ -13,8 +13,8 @@
 
 
 ApplicationModel subclass:#UIHelpTool
-	instanceVariableNames:'isModified specClass dictionary dictionaries listSelection
-		maxCharsPerLine modifiedHolder'
+	instanceVariableNames:'specClass dictionary dictionaries listSelection modified
+		modifiedHolder maxCharsPerLine'
 	classVariableNames:''
 	poolDictionaries:''
 	category:'Interface-UIPainter'
@@ -40,8 +40,13 @@
 
 documentation
 "
-    used by the UIPainter to add help text to any component which will be shown
-    during runing an application with enabled activeHelp mode.
+    The UIHelpTool allows you to define help dictionaries for the widgets in
+    applications. The tool are able to run stand alone or in other master 
+    applications like the GUI Painter and the Menu Editor.
+    If the application responds to the selector #showHelp:aHelpText for:aView,
+    this selector is called by the widget's view when the mouse cursor moves over. 
+    If the application does not responds to that selector, and the activeHelp mode
+    is enabled, an active help bubble is shown at the widget's view.
 
     [author:]
         Claus Atzkern
@@ -54,11 +59,8 @@
     "
      UIHelpTool openOnClass:UIPainter
     "
-    |helpTool|
 
-    helpTool := UIHelpTool open.
-    helpTool helpSpecFrom:aClass.
-    helpTool dictionary: aClass helpSpec.
+    UIHelpTool open helpSpecFrom:aClass
 
 ! !
 
@@ -72,14 +74,19 @@
 !UIHelpTool class methodsFor:'help specs'!
 
 helpSpec
-    "return a dictionary filled with helpKey -> helptext associations.
-     These are used by the activeHelp tool."
+    "This resource specification was automatically generated
+     by the UIHelpTool of ST/X."
+
+    "Do not manually edit this!! If it is corrupted,
+     the UIHelpTool may not be able to read the specification."
 
     "
-    UIHelpTool openOnClass:UIHelpTool    
+     UIHelpTool openOnClass:UIHelpTool    
     "
 
-  ^ super helpSpec addPairsFrom:#(
+    <resource: #help>
+
+    ^super helpSpec addPairsFrom:#(
 
 #addHelpTextKey
 'Adds help text key.'
@@ -108,16 +115,17 @@
 !UIHelpTool class methodsFor:'interface specs'!
 
 windowSpec
-    "this window spec was automatically generated by the ST/X UIPainter"
+    "This resource specification was automatically generated
+     by the UIPainter of ST/X."
 
-    "do not manually edit this - the painter/builder may not be able to
-     handle the specification if its corrupted."
+    "Do not manually edit this!! If it is corrupted,
+     the UIPainter may not be able to read the specification."
 
     "
      UIPainter new openOnClass:UIHelpTool andSelector:#windowSpec
      UIHelpTool new openInterface:#windowSpec
+     UIHelpTool open
     "
-    "UIHelpTool open"
 
     <resource: #canvas>
 
@@ -126,12 +134,12 @@
        #(#FullSpec
           #window: 
            #(#WindowSpec
-              #name: 'unnamed canvas'
-              #layout: #(#LayoutFrame 118 0 430 0 403 0 700 0)
-              #label: 'unnamed canvas'
+              #name: 'Help Tool'
+              #layout: #(#LayoutFrame 140 0 231 0 425 0 501 0)
+              #label: 'Help Tool'
               #min: #(#Point 10 10)
               #max: #(#Point 1160 870)
-              #bounds: #(#Rectangle 118 430 404 701)
+              #bounds: #(#Rectangle 140 231 426 502)
               #usePreferredExtent: false
           )
           #component: 
@@ -150,52 +158,43 @@
                     #useIndex: false
                     #sequenceList: #listChannel
                 )
-                 #(#HorizontalPanelViewSpec
-                    #name: 'HorizontalPanelView'
-                    #layout: #(#LayoutFrame 1 0.5 2 0 -3 1 26 0)
-                    #component: 
-                     #(#SpecCollection
-                        #collection: 
-                         #(
-                           #(#ActionButtonSpec
-                              #name: 'AddButton'
-                              #activeHelpKey: #addHelpTextKey
-                              #label: 'Add'
-                              #model: #add
-                              #extent: #(#Point 44 24)
-                          )
-                           #(#ActionButtonSpec
-                              #name: 'RemoveButton'
-                              #activeHelpKey: #removeHelpTextKey
-                              #label: 'Remove'
-                              #model: #remove
-                              #extent: #(#Point 44 24)
-                          )
-                           #(#ActionButtonSpec
-                              #name: 'DeleteButton'
-                              #activeHelpKey: #deleteHelpTextKey
-                              #label: 'Delete'
-                              #model: #delete
-                              #extent: #(#Point 45 24)
-                          )
-                        )
-                    )
-                    #horizontalLayout: #fit
-                    #verticalLayout: #fit
-                    #horizontalSpace: 3
-                    #verticalSpace: 3
+                 #(#ActionButtonSpec
+                    #name: 'AddButton'
+                    #layout: #(#LayoutFrame 2 0.5 2 0 -1 0.67 26 0)
+                    #activeHelpKey: #addHelpTextKey
+                    #label: 'Add'
+                    #tabable: true
+                    #model: #add
+                )
+                 #(#ActionButtonSpec
+                    #name: 'RemoveButton'
+                    #layout: #(#LayoutFrame 1 0.67 2 0 -1 0.83 26 0)
+                    #activeHelpKey: #removeHelpTextKey
+                    #label: 'Remove'
+                    #tabable: true
+                    #model: #remove
+                )
+                 #(#ActionButtonSpec
+                    #name: 'DeleteButton'
+                    #layout: #(#LayoutFrame 1 0.83 2 0 -2 1 26 0)
+                    #activeHelpKey: #deleteHelpTextKey
+                    #label: 'Delete'
+                    #tabable: true
+                    #model: #delete
                 )
                  #(#InputFieldSpec
                     #name: 'helpKeyInputField'
                     #layout: #(#LayoutFrame 1 0.5 29 0 -3 1 51 0)
                     #activeHelpKey: #currentHelpTexts
+                    #tabable: true
                     #model: #listModel
                     #immediateAccept: false
                 )
                  #(#SequenceViewSpec
                     #name: 'listOfHelpSpecClassesView'
-                    #layout: #(#LayoutFrame 1 0.5 53 0 -3 1 -1 0.5)
+                    #layout: #(#LayoutFrame 1 0.5 54 0 -3 1 -1 0.5)
                     #activeHelpKey: #listOfHelpSpecClasses
+                    #tabable: true
                     #model: #selectionOfHelpSpecClass
                     #hasHorizontalScrollBar: true
                     #hasVerticalScrollBar: true
@@ -209,6 +208,7 @@
                     #name: 'helpTextView'
                     #layout: #(#LayoutFrame 3 0.0 1 0.5 -1 1.0 -3 1.0)
                     #activeHelpKey: #helpTextView
+                    #tabable: true
                     #hasHorizontalScrollBar: true
                     #hasVerticalScrollBar: true
                     #miniScrollerHorizontal: true
@@ -220,10 +220,11 @@
 !
 
 windowSpecForStandAlone
-    "this window spec was automatically generated by the ST/X UIPainter"
+    "This resource specification was automatically generated
+     by the UIPainter of ST/X."
 
-    "do not manually edit this - the painter/builder may not be able to
-     handle the specification if its corrupted."
+    "Do not manually edit this!! If it is corrupted,
+     the UIPainter may not be able to read the specification."
 
     "
      UIPainter new openOnClass:UIHelpTool andSelector:#windowSpecForStandAlone
@@ -238,11 +239,11 @@
           #window: 
            #(#WindowSpec
               #name: 'Help Tool'
-              #layout: #(#LayoutFrame 195 0 352 0 694 0 751 0)
+              #layout: #(#LayoutFrame 534 0 276 0 1033 0 675 0)
               #label: 'Help Tool'
               #min: #(#Point 10 10)
               #max: #(#Point 1160 870)
-              #bounds: #(#Rectangle 195 352 695 752)
+              #bounds: #(#Rectangle 534 276 1034 676)
               #menu: #menu
               #usePreferredExtent: false
           )
@@ -263,10 +264,11 @@
 !UIHelpTool class methodsFor:'menu specs'!
 
 menu
-    "this window spec was automatically generated by the ST/X MenuEditor"
+    "This resource specification was automatically generated
+     by the MenuEditor of ST/X."
 
-    "do not manually edit this - the builder may not be able to
-     handle the specification if its corrupted."
+    "Do not manually edit this!! If it is corrupted,
+     the MenuEditor may not be able to read the specification."
 
     "
      MenuEditor new openOnClass:UIHelpTool andSelector:#menu
@@ -378,7 +380,7 @@
     "
     |help|
 
-    isModified := false.
+    modified := false.
     specClass notNil
     ifTrue:
     [   
@@ -404,16 +406,16 @@
     self updateList
 !
 
-isModified
+modified
     "answer whether the help tool was modified
     "
-    ^isModified
+    ^modified
 !
 
-isModified: aBoolean
+modified: aBoolean
     "set the help tool as modified
     "
-    isModified := aBoolean
+    modified := aBoolean
 !
 
 modifiedHolder:aValueHolder
@@ -446,157 +448,6 @@
     ^specClass
 ! !
 
-!UIHelpTool methodsFor:'actions'!
-
-helpSpecClassSelected
-    "extract the help dictionary from the selected class and make it current
-    "
-    |clsName|
-
-    clsName := self selectionOfHelpSpecClass value.
-
-    (dictionary := dictionaries at: clsName ifAbsent: nil) isNil
-    ifTrue:
-    [        
-        dictionary := dictionaries at: clsName put: (self extractHelpSpecForClass: (Smalltalk at: clsName))
-    ].
-
-    self updateList.
-
-    listSelection notNil
-    ifTrue: 
-    [
-        (dictionary keys includes: listSelection asSymbol)
-            ifTrue: [(builder componentAt: #listOfHelpKeysView) selection: 
-                     (self listChannel value indexOf: (builder componentAt: #helpKeyInputField) contents)]
-            ifFalse: [(builder componentAt: #listOfHelpKeysView) selection: nil].
-    ].
-    listSelection notNil
-    ifTrue: 
-    [
-        self editTextView contents: (dictionary at: listSelection asSymbol ifAbsent: '')
-    ]
-
-
-!
-
-installHelpSpecOnClass:aClass
-    "save the help dicts in aClass which is subclass of ApplicationModel"
-
-    |cls src helpSpec|
-
-    cls := self applicationClassAssociatedWith:aClass.
-
-    cls isNil ifTrue:[
-        self information:'No application class defined!!'.
-        ^nil
-    ].
-
-    (cls isSubclassOf: ApplicationModel) ifFalse:[
-        self information: 'Cannot save help spec into class ', cls name asBoldText, ',\because it is not a subclass of ApplicationModel!!' withCRs.
-        ^nil
-    ].
-
-    helpSpec := dictionaries at: cls name 
-        ifAbsent: [aClass = cls name asString ifTrue: [dictionary] ifFalse: [Dictionary new]].
-
-    (cls class implements: #helpSpec) 
-    ifTrue: 
-    [
-        |superclassHelpKeys implementedHelpSpec hasChanged|
-        implementedHelpSpec := Dictionary new.
-        superclassHelpKeys := (cls superclass respondsTo: #helpSpec)
-            ifTrue:  [cls superclass helpSpec keys]
-            ifFalse: [Array new].
-
-        cls helpSpec associationsDo: [:h| (superclassHelpKeys includes: h key) 
-            ifFalse: [implementedHelpSpec at: h key put: h value]].
-
-        hasChanged := false.
-        implementedHelpSpec associationsDo: [:h| (helpSpec            includesAssociation: h) ifFalse: [hasChanged := true]].
-        helpSpec            associationsDo: [:h| (implementedHelpSpec includesAssociation: h) ifFalse: [hasChanged := true]].
-
-        (implementedHelpSpec notEmpty and: [hasChanged and:
-        [DialogBox confirm: 'Class ', cls name asBoldText, ' already implements\a help spec!!\\Do only replace, if you have removed\help keys in an existing help spec.\' withCRs yesLabel: ' Merge ' noLabel: ' Replace ']])
-        ifTrue:
-        [
-             implementedHelpSpec associationsDo: [:h| (helpSpec includesKey: h key) 
-                ifFalse: [helpSpec at: h key put: h value]].
-        ]
-    ].
-
-    helpSpec isEmpty ifTrue:[
-        ^(cls superclass respondsTo: #helpSpec) ifTrue: [cls class removeSelector: #helpSpec].
-    ].
-
-    src  := '' writeStream.
-
-    src nextPutAll:
-
-'helpSpec
-    "return a dictionary filled with helpKey -> helptext associations.
-     These are used by the activeHelp tool."
-
-    "
-    UIHelpTool openOnClass:', cls name asString ,'    
-    "
-
-  ^ super helpSpec addPairsFrom:#(
-
-'.
-
-    helpSpec keys asSortedCollection
-    do:[:key |
-        |txt t|
-
-        txt := helpSpec at:key.
-        src nextPutLine:key storeString.
-
-        t := txt asString replaceAll:(Character cr) with:(Character space).
-
-        (t endsWith:Character space) ifTrue:[
-            t := t copyWithoutLast:1
-        ].
-        src nextPutLine:t storeString; cr.
-    ].
-    src nextPutLine:')'.
-
-    Compiler 
-        compile:(src contents)
-        forClass:cls class 
-        inCategory:'help specs'.
-
-
-
-
-!
-
-installHelpSpecsOnClass:aClass
-    "save the help dicts on aClass and its superclasses which are subclasses of ApplicationModel
-    "
-    |cls helpSpecClasses|
-
-    isModified ifFalse:[
-        ^nil
-    ].
-
-    cls := aClass isClass ifTrue: [aClass name] ifFalse: [aClass].
-
-    (helpSpecClasses := self listOfHelpSpecClasses value) notNil
-    ifTrue:
-    [     
-        (helpSpecClasses includes: cls) ifFalse: [helpSpecClasses add: cls].
-        helpSpecClasses do: [:clsName| (self installHelpSpecOnClass: clsName) isNil ifTrue: [^isModified := false]].
-    ]
-    ifFalse:
-    [
-        self installHelpSpecOnClass: cls
-    ].
-
-    isModified := false.
-
-! !
-
 !UIHelpTool methodsFor:'aspects'!
 
 listChannel
@@ -643,21 +494,55 @@
 
 ! !
 
-!UIHelpTool methodsFor:'initialization'!
+!UIHelpTool methodsFor:'callbacks'!
 
-initialize
-    "initialize instance variables
+helpSpecClassSelected
+    "extract the help dictionary from the selected class and make it current
     "
-    super initialize.
+    |clsName|
+
+    clsName := self selectionOfHelpSpecClass value.
+
+    (dictionary := dictionaries at: clsName ifAbsent: nil) isNil
+    ifTrue:
+    [        
+        dictionary := dictionaries at: clsName put: (self extractHelpSpecForClass: (Smalltalk at: clsName))
+    ].
+
+    self updateList.
 
-    dictionary   := Dictionary new.
-    dictionaries := Dictionary new.
-    isModified   := false.
+    listSelection notNil
+    ifTrue: 
+    [
+        (dictionary keys includes: listSelection asSymbol)
+            ifTrue: [(builder componentAt: #listOfHelpKeysView) selection: 
+                     (self listChannel value indexOf: (builder componentAt: #helpKeyInputField) contents)]
+            ifFalse: [(builder componentAt: #listOfHelpKeysView) selection: nil].
+    ].
+    listSelection notNil
+    ifTrue: 
+    [
+        self editTextView contents: (dictionary at: listSelection asSymbol ifAbsent: '')
+    ]
+
 
 ! !
 
 !UIHelpTool methodsFor:'private'!
 
+applicationClassAssociatedWith:aClass
+    "get application class keeping the associated help text or nil
+    "
+    |cls|
+
+    ((cls := self resolveName:aClass) notNil and:[cls includesBehavior:UISpecification]) ifTrue:[
+        ^UISpecificationTool
+    ].
+    ^cls
+
+
+!
+
 editTextView
     "get the editTextView or nil.
     "
@@ -726,27 +611,128 @@
 
 !
 
+installHelpSpecOnClass:aClass
+    "save the help dicts in aClass which is subclass of ApplicationModel"
+
+    |cls src helpSpec|
+
+    cls := self applicationClassAssociatedWith:aClass.
+
+    cls isNil ifTrue:[
+        self information:'No application class defined!!'.
+        ^nil
+    ].
+
+    (cls isSubclassOf: ApplicationModel) ifFalse:[
+        self information: 'Cannot save help spec into class ', cls name asBoldText, ',\because it is not a subclass of ApplicationModel!!' withCRs.
+        ^nil
+    ].
+
+    helpSpec := dictionaries 
+        at: cls name 
+        ifAbsent: [specClass notNil 
+            ifTrue:  [dictionaries at: aClass put: (self extractHelpSpecForClass: (Smalltalk at: aClass))]
+            ifFalse: [dictionary size > 0 ifTrue: [dictionary] ifFalse: [Dictionary new]]].
+
+    (cls class implements: #helpSpec) 
+    ifTrue: 
+    [
+        |superclassHelpKeys implementedHelpSpec hasChanged|
+        implementedHelpSpec := Dictionary new.
+        superclassHelpKeys := (cls superclass respondsTo: #helpSpec)
+            ifTrue:  [cls superclass helpSpec keys]
+            ifFalse: [Array new].
+
+        cls helpSpec associationsDo: [:h| (superclassHelpKeys includes: h key) 
+            ifFalse: [implementedHelpSpec at: h key put: h value]].
+
+        hasChanged := false.
+        implementedHelpSpec associationsDo: [:h| (helpSpec            includesAssociation: h) ifFalse: [hasChanged := true]].
+        helpSpec            associationsDo: [:h| (implementedHelpSpec includesAssociation: h) ifFalse: [hasChanged := true]].
+
+        (implementedHelpSpec notEmpty and: [hasChanged and:
+        [DialogBox confirm: 'Class ', cls name asBoldText, ' already implements\a help spec!!\\Do only replace, if you have removed\help keys in an existing help spec.\' withCRs yesLabel: ' Merge ' noLabel: ' Replace ']])
+        ifTrue:
+        [      
+             implementedHelpSpec associationsDo: [:h| (helpSpec includesKey: h key) 
+                ifFalse: [helpSpec at: h key put: h value]].
+        ]
+    ].
+
+    helpSpec isEmpty ifTrue:[
+        ^(cls superclass respondsTo: #helpSpec) ifTrue: [cls class removeSelector: #helpSpec].
+    ].
+
+    src  := '' writeStream.
+
+    src nextPutAll:
+        'helpSpec\' withCRs,
+        (ResourceSpecEditor codeGenerationCommentForClass: UIHelpTool) withCRs,
+    '\\' withCRs,
+    '    "\' withCRs,
+    '     UIHelpTool openOnClass:', cls name asString ,'    
+    "
+
+    <resource: #help>
+
+    ^super helpSpec addPairsFrom:#(
+
+'.
+
+    helpSpec keys asSortedCollection
+    do:[:key |
+        |txt t|
+
+        txt := helpSpec at:key.
+        src nextPutLine:key storeString.
+
+        t := txt asString replaceAll:(Character cr) with:(Character space).
+
+        (t endsWith:Character space) ifTrue:[
+            t := t copyWithoutLast:1
+        ].
+        src nextPutLine:t storeString; cr.
+    ].
+    src nextPutLine:')'.
+
+    Compiler 
+        compile:(src contents)
+        forClass:cls class 
+        inCategory:'help specs'.
+!
+
+installHelpSpecsOnClass:aClass
+    "save the help dicts on aClass and its superclasses which are subclasses of ApplicationModel
+    "
+    |cls helpSpecClasses|
+
+    modified ifFalse:[
+        ^nil
+    ].
+
+    cls := aClass isClass ifTrue: [aClass name] ifFalse: [aClass].
+
+    (helpSpecClasses := self listOfHelpSpecClasses value) notNil
+    ifTrue:
+    [     
+        (helpSpecClasses includes: cls) ifFalse: [helpSpecClasses add: cls].
+        helpSpecClasses do: [:clsName| (self installHelpSpecOnClass: clsName) isNil ifTrue: [^modified := false]].
+    ]
+    ifFalse:
+    [
+        self installHelpSpecOnClass: cls
+    ].
+
+    modified := false.
+
+!
+
 updateList
     "update the list channel from dictionary
     "
     self listChannel value: dictionary keys asSortedCollection
 ! !
 
-!UIHelpTool methodsFor:'queries'!
-
-applicationClassAssociatedWith:aClass
-    "get application class keeping the associated help text or nil
-    "
-    |cls|
-
-    ((cls := self resolveName:aClass) notNil and:[cls includesBehavior:UISpecification]) ifTrue:[
-        ^UISpecificationTool
-    ].
-    ^cls
-
-
-! !
-
 !UIHelpTool methodsFor:'selection'!
 
 listSelection
@@ -804,12 +790,23 @@
 closeRequest
     "before closing the help tool, ask for permission
     "
-    (isModified and:[self masterApplication isNil]) ifTrue:[
+    (modified and:[self masterApplication isNil]) ifTrue:[
         (self confirm:'Exit without saving your modifications?') ifFalse:[
             ^ self
         ]
     ].
-    ^ super closeRequest.
+    ^super closeRequest
+!
+
+initialize
+    "initialize instance variables
+    "
+    super initialize.
+
+    dictionary   := Dictionary new.
+    dictionaries := Dictionary new.
+    modified   := false.
+
 !
 
 openInterface:aSymbol
@@ -818,7 +815,7 @@
     super openInterface: #windowSpecForStandAlone
 ! !
 
-!UIHelpTool methodsFor:'user interactions'!
+!UIHelpTool methodsFor:'user actions'!
 
 accept
     "accept the help text
@@ -840,7 +837,7 @@
             (builder componentAt: #listOfHelpKeysView) selection: (list indexOf: key).
         ]. 
 
-        isModified := true.
+        modified := true.
         modifiedHolder notNil ifTrue: [modifiedHolder value:true]
     ]
 !
@@ -863,7 +860,7 @@
 
         self updateList.
 
-        isModified := true.
+        modified := true.
         modifiedHolder notNil ifTrue: [modifiedHolder value:true]
     ]
 !
@@ -905,7 +902,7 @@
     model value:nil.
     self helpSpecFrom:specClass.
     model value:oldSel.
-    isModified := false.
+    modified := false.
 
 !
 
@@ -921,6 +918,16 @@
     self listModel value: nil.
     self updateList.
     modifiedHolder notNil ifTrue: [modifiedHolder value:true]
+!
+
+reset
+    "reset the help tool
+    "
+    specClass := listSelection := nil.
+    self dictionary: nil.
+    self dictionaries: nil.
+    self listOfHelpSpecClasses removeAll.
+    modified := false.
 ! !
 
 !UIHelpTool class methodsFor:'documentation'!