UIHelpTool.st
changeset 740 e7362f3ab5e5
parent 722 a1bb632b1e00
child 750 9b705e31d38e
equal deleted inserted replaced
739:cc3413fc1afb 740:e7362f3ab5e5
    11 "
    11 "
    12 
    12 
    13 
    13 
    14 
    14 
    15 ApplicationModel subclass:#UIHelpTool
    15 ApplicationModel subclass:#UIHelpTool
    16 	instanceVariableNames:'isModified specClass dictionary dictionaries listSelection
    16 	instanceVariableNames:'specClass dictionary dictionaries listSelection modified
    17 		maxCharsPerLine modifiedHolder'
    17 		modifiedHolder maxCharsPerLine'
    18 	classVariableNames:''
    18 	classVariableNames:''
    19 	poolDictionaries:''
    19 	poolDictionaries:''
    20 	category:'Interface-UIPainter'
    20 	category:'Interface-UIPainter'
    21 !
    21 !
    22 
    22 
    38 
    38 
    39 !
    39 !
    40 
    40 
    41 documentation
    41 documentation
    42 "
    42 "
    43     used by the UIPainter to add help text to any component which will be shown
    43     The UIHelpTool allows you to define help dictionaries for the widgets in
    44     during runing an application with enabled activeHelp mode.
    44     applications. The tool are able to run stand alone or in other master 
       
    45     applications like the GUI Painter and the Menu Editor.
       
    46     If the application responds to the selector #showHelp:aHelpText for:aView,
       
    47     this selector is called by the widget's view when the mouse cursor moves over. 
       
    48     If the application does not responds to that selector, and the activeHelp mode
       
    49     is enabled, an active help bubble is shown at the widget's view.
    45 
    50 
    46     [author:]
    51     [author:]
    47         Claus Atzkern
    52         Claus Atzkern
    48 "
    53 "
    49 ! !
    54 ! !
    52 
    57 
    53 openOnClass:aClass
    58 openOnClass:aClass
    54     "
    59     "
    55      UIHelpTool openOnClass:UIPainter
    60      UIHelpTool openOnClass:UIPainter
    56     "
    61     "
    57     |helpTool|
    62 
    58 
    63     UIHelpTool open helpSpecFrom:aClass
    59     helpTool := UIHelpTool open.
       
    60     helpTool helpSpecFrom:aClass.
       
    61     helpTool dictionary: aClass helpSpec.
       
    62 
    64 
    63 ! !
    65 ! !
    64 
    66 
    65 !UIHelpTool class methodsFor:'constants'!
    67 !UIHelpTool class methodsFor:'constants'!
    66 
    68 
    70 ! !
    72 ! !
    71 
    73 
    72 !UIHelpTool class methodsFor:'help specs'!
    74 !UIHelpTool class methodsFor:'help specs'!
    73 
    75 
    74 helpSpec
    76 helpSpec
    75     "return a dictionary filled with helpKey -> helptext associations.
    77     "This resource specification was automatically generated
    76      These are used by the activeHelp tool."
    78      by the UIHelpTool of ST/X."
    77 
    79 
    78     "
    80     "Do not manually edit this!! If it is corrupted,
    79     UIHelpTool openOnClass:UIHelpTool    
    81      the UIHelpTool may not be able to read the specification."
    80     "
    82 
    81 
    83     "
    82   ^ super helpSpec addPairsFrom:#(
    84      UIHelpTool openOnClass:UIHelpTool    
       
    85     "
       
    86 
       
    87     <resource: #help>
       
    88 
       
    89     ^super helpSpec addPairsFrom:#(
    83 
    90 
    84 #addHelpTextKey
    91 #addHelpTextKey
    85 'Adds help text key.'
    92 'Adds help text key.'
    86 
    93 
    87 #currentHelpTexts
    94 #currentHelpTexts
   106 ! !
   113 ! !
   107 
   114 
   108 !UIHelpTool class methodsFor:'interface specs'!
   115 !UIHelpTool class methodsFor:'interface specs'!
   109 
   116 
   110 windowSpec
   117 windowSpec
   111     "this window spec was automatically generated by the ST/X UIPainter"
   118     "This resource specification was automatically generated
   112 
   119      by the UIPainter of ST/X."
   113     "do not manually edit this - the painter/builder may not be able to
   120 
   114      handle the specification if its corrupted."
   121     "Do not manually edit this!! If it is corrupted,
       
   122      the UIPainter may not be able to read the specification."
   115 
   123 
   116     "
   124     "
   117      UIPainter new openOnClass:UIHelpTool andSelector:#windowSpec
   125      UIPainter new openOnClass:UIHelpTool andSelector:#windowSpec
   118      UIHelpTool new openInterface:#windowSpec
   126      UIHelpTool new openInterface:#windowSpec
   119     "
   127      UIHelpTool open
   120     "UIHelpTool open"
   128     "
   121 
   129 
   122     <resource: #canvas>
   130     <resource: #canvas>
   123 
   131 
   124     ^
   132     ^
   125      
   133      
   126        #(#FullSpec
   134        #(#FullSpec
   127           #window: 
   135           #window: 
   128            #(#WindowSpec
   136            #(#WindowSpec
   129               #name: 'unnamed canvas'
   137               #name: 'Help Tool'
   130               #layout: #(#LayoutFrame 118 0 430 0 403 0 700 0)
   138               #layout: #(#LayoutFrame 140 0 231 0 425 0 501 0)
   131               #label: 'unnamed canvas'
   139               #label: 'Help Tool'
   132               #min: #(#Point 10 10)
   140               #min: #(#Point 10 10)
   133               #max: #(#Point 1160 870)
   141               #max: #(#Point 1160 870)
   134               #bounds: #(#Rectangle 118 430 404 701)
   142               #bounds: #(#Rectangle 140 231 426 502)
   135               #usePreferredExtent: false
   143               #usePreferredExtent: false
   136           )
   144           )
   137           #component: 
   145           #component: 
   138            #(#SpecCollection
   146            #(#SpecCollection
   139               #collection: 
   147               #collection: 
   148                     #hasVerticalScrollBar: true
   156                     #hasVerticalScrollBar: true
   149                     #miniScrollerHorizontal: true
   157                     #miniScrollerHorizontal: true
   150                     #useIndex: false
   158                     #useIndex: false
   151                     #sequenceList: #listChannel
   159                     #sequenceList: #listChannel
   152                 )
   160                 )
   153                  #(#HorizontalPanelViewSpec
   161                  #(#ActionButtonSpec
   154                     #name: 'HorizontalPanelView'
   162                     #name: 'AddButton'
   155                     #layout: #(#LayoutFrame 1 0.5 2 0 -3 1 26 0)
   163                     #layout: #(#LayoutFrame 2 0.5 2 0 -1 0.67 26 0)
   156                     #component: 
   164                     #activeHelpKey: #addHelpTextKey
   157                      #(#SpecCollection
   165                     #label: 'Add'
   158                         #collection: 
   166                     #tabable: true
   159                          #(
   167                     #model: #add
   160                            #(#ActionButtonSpec
   168                 )
   161                               #name: 'AddButton'
   169                  #(#ActionButtonSpec
   162                               #activeHelpKey: #addHelpTextKey
   170                     #name: 'RemoveButton'
   163                               #label: 'Add'
   171                     #layout: #(#LayoutFrame 1 0.67 2 0 -1 0.83 26 0)
   164                               #model: #add
   172                     #activeHelpKey: #removeHelpTextKey
   165                               #extent: #(#Point 44 24)
   173                     #label: 'Remove'
   166                           )
   174                     #tabable: true
   167                            #(#ActionButtonSpec
   175                     #model: #remove
   168                               #name: 'RemoveButton'
   176                 )
   169                               #activeHelpKey: #removeHelpTextKey
   177                  #(#ActionButtonSpec
   170                               #label: 'Remove'
   178                     #name: 'DeleteButton'
   171                               #model: #remove
   179                     #layout: #(#LayoutFrame 1 0.83 2 0 -2 1 26 0)
   172                               #extent: #(#Point 44 24)
   180                     #activeHelpKey: #deleteHelpTextKey
   173                           )
   181                     #label: 'Delete'
   174                            #(#ActionButtonSpec
   182                     #tabable: true
   175                               #name: 'DeleteButton'
   183                     #model: #delete
   176                               #activeHelpKey: #deleteHelpTextKey
       
   177                               #label: 'Delete'
       
   178                               #model: #delete
       
   179                               #extent: #(#Point 45 24)
       
   180                           )
       
   181                         )
       
   182                     )
       
   183                     #horizontalLayout: #fit
       
   184                     #verticalLayout: #fit
       
   185                     #horizontalSpace: 3
       
   186                     #verticalSpace: 3
       
   187                 )
   184                 )
   188                  #(#InputFieldSpec
   185                  #(#InputFieldSpec
   189                     #name: 'helpKeyInputField'
   186                     #name: 'helpKeyInputField'
   190                     #layout: #(#LayoutFrame 1 0.5 29 0 -3 1 51 0)
   187                     #layout: #(#LayoutFrame 1 0.5 29 0 -3 1 51 0)
   191                     #activeHelpKey: #currentHelpTexts
   188                     #activeHelpKey: #currentHelpTexts
       
   189                     #tabable: true
   192                     #model: #listModel
   190                     #model: #listModel
   193                     #immediateAccept: false
   191                     #immediateAccept: false
   194                 )
   192                 )
   195                  #(#SequenceViewSpec
   193                  #(#SequenceViewSpec
   196                     #name: 'listOfHelpSpecClassesView'
   194                     #name: 'listOfHelpSpecClassesView'
   197                     #layout: #(#LayoutFrame 1 0.5 53 0 -3 1 -1 0.5)
   195                     #layout: #(#LayoutFrame 1 0.5 54 0 -3 1 -1 0.5)
   198                     #activeHelpKey: #listOfHelpSpecClasses
   196                     #activeHelpKey: #listOfHelpSpecClasses
       
   197                     #tabable: true
   199                     #model: #selectionOfHelpSpecClass
   198                     #model: #selectionOfHelpSpecClass
   200                     #hasHorizontalScrollBar: true
   199                     #hasHorizontalScrollBar: true
   201                     #hasVerticalScrollBar: true
   200                     #hasVerticalScrollBar: true
   202                     #miniScrollerHorizontal: true
   201                     #miniScrollerHorizontal: true
   203                     #miniScrollerVertical: true
   202                     #miniScrollerVertical: true
   207                 )
   206                 )
   208                  #(#TextEditorSpec
   207                  #(#TextEditorSpec
   209                     #name: 'helpTextView'
   208                     #name: 'helpTextView'
   210                     #layout: #(#LayoutFrame 3 0.0 1 0.5 -1 1.0 -3 1.0)
   209                     #layout: #(#LayoutFrame 3 0.0 1 0.5 -1 1.0 -3 1.0)
   211                     #activeHelpKey: #helpTextView
   210                     #activeHelpKey: #helpTextView
       
   211                     #tabable: true
   212                     #hasHorizontalScrollBar: true
   212                     #hasHorizontalScrollBar: true
   213                     #hasVerticalScrollBar: true
   213                     #hasVerticalScrollBar: true
   214                     #miniScrollerHorizontal: true
   214                     #miniScrollerHorizontal: true
   215                     #miniScrollerVertical: true
   215                     #miniScrollerVertical: true
   216                 )
   216                 )
   218           )
   218           )
   219       )
   219       )
   220 !
   220 !
   221 
   221 
   222 windowSpecForStandAlone
   222 windowSpecForStandAlone
   223     "this window spec was automatically generated by the ST/X UIPainter"
   223     "This resource specification was automatically generated
   224 
   224      by the UIPainter of ST/X."
   225     "do not manually edit this - the painter/builder may not be able to
   225 
   226      handle the specification if its corrupted."
   226     "Do not manually edit this!! If it is corrupted,
       
   227      the UIPainter may not be able to read the specification."
   227 
   228 
   228     "
   229     "
   229      UIPainter new openOnClass:UIHelpTool andSelector:#windowSpecForStandAlone
   230      UIPainter new openOnClass:UIHelpTool andSelector:#windowSpecForStandAlone
   230      UIHelpTool new openInterface:#windowSpecForStandAlone
   231      UIHelpTool new openInterface:#windowSpecForStandAlone
   231     "
   232     "
   236      
   237      
   237        #(#FullSpec
   238        #(#FullSpec
   238           #window: 
   239           #window: 
   239            #(#WindowSpec
   240            #(#WindowSpec
   240               #name: 'Help Tool'
   241               #name: 'Help Tool'
   241               #layout: #(#LayoutFrame 195 0 352 0 694 0 751 0)
   242               #layout: #(#LayoutFrame 534 0 276 0 1033 0 675 0)
   242               #label: 'Help Tool'
   243               #label: 'Help Tool'
   243               #min: #(#Point 10 10)
   244               #min: #(#Point 10 10)
   244               #max: #(#Point 1160 870)
   245               #max: #(#Point 1160 870)
   245               #bounds: #(#Rectangle 195 352 695 752)
   246               #bounds: #(#Rectangle 534 276 1034 676)
   246               #menu: #menu
   247               #menu: #menu
   247               #usePreferredExtent: false
   248               #usePreferredExtent: false
   248           )
   249           )
   249           #component: 
   250           #component: 
   250            #(#SpecCollection
   251            #(#SpecCollection
   261 ! !
   262 ! !
   262 
   263 
   263 !UIHelpTool class methodsFor:'menu specs'!
   264 !UIHelpTool class methodsFor:'menu specs'!
   264 
   265 
   265 menu
   266 menu
   266     "this window spec was automatically generated by the ST/X MenuEditor"
   267     "This resource specification was automatically generated
   267 
   268      by the MenuEditor of ST/X."
   268     "do not manually edit this - the builder may not be able to
   269 
   269      handle the specification if its corrupted."
   270     "Do not manually edit this!! If it is corrupted,
       
   271      the MenuEditor may not be able to read the specification."
   270 
   272 
   271     "
   273     "
   272      MenuEditor new openOnClass:UIHelpTool andSelector:#menu
   274      MenuEditor new openOnClass:UIHelpTool andSelector:#menu
   273      (Menu new fromLiteralArrayEncoding:(UIHelpTool menu)) startUp
   275      (Menu new fromLiteralArrayEncoding:(UIHelpTool menu)) startUp
   274     "
   276     "
   376     "read the help dictionary from aClass and find remaining classes 
   378     "read the help dictionary from aClass and find remaining classes 
   377      'between' aClass and ApplicationModel 
   379      'between' aClass and ApplicationModel 
   378     "
   380     "
   379     |help|
   381     |help|
   380 
   382 
   381     isModified := false.
   383     modified := false.
   382     specClass notNil
   384     specClass notNil
   383     ifTrue:
   385     ifTrue:
   384     [   
   386     [   
   385         dictionary   := Dictionary new.
   387         dictionary   := Dictionary new.
   386         dictionaries := Dictionary new.
   388         dictionaries := Dictionary new.
   402     ].
   404     ].
   403 
   405 
   404     self updateList
   406     self updateList
   405 !
   407 !
   406 
   408 
   407 isModified
   409 modified
   408     "answer whether the help tool was modified
   410     "answer whether the help tool was modified
   409     "
   411     "
   410     ^isModified
   412     ^modified
   411 !
   413 !
   412 
   414 
   413 isModified: aBoolean
   415 modified: aBoolean
   414     "set the help tool as modified
   416     "set the help tool as modified
   415     "
   417     "
   416     isModified := aBoolean
   418     modified := aBoolean
   417 !
   419 !
   418 
   420 
   419 modifiedHolder:aValueHolder
   421 modifiedHolder:aValueHolder
   420     "set the value holder set to true in case of modifying attributes
   422     "set the value holder set to true in case of modifying attributes
   421     "
   423     "
   444     "get the class on which the help tool works
   446     "get the class on which the help tool works
   445     "
   447     "
   446     ^specClass
   448     ^specClass
   447 ! !
   449 ! !
   448 
   450 
   449 !UIHelpTool methodsFor:'actions'!
   451 !UIHelpTool methodsFor:'aspects'!
       
   452 
       
   453 listChannel
       
   454     "get the value holder of the help texts
       
   455     "
       
   456     |holder|
       
   457     (holder := builder bindingAt:#listChannel) isNil ifTrue:[
       
   458         builder aspectAt:#listChannel put:(holder :=  OrderedCollection new asValue).
       
   459     ].
       
   460     ^ holder
       
   461 !
       
   462 
       
   463 listModel
       
   464     "get the value holder of the help key
       
   465     "
       
   466     |holder|
       
   467     (holder := builder bindingAt:#listModel) isNil ifTrue:[
       
   468         holder := AspectAdaptor new subject:self; forAspect:#listSelection.
       
   469         builder aspectAt:#listModel put:holder.
       
   470     ].
       
   471     ^ holder
       
   472 !
       
   473 
       
   474 listOfHelpSpecClasses
       
   475     "get the value holder of the specClass and its superclasses 
       
   476      which are subclasses of ApplicationModel
       
   477     "
       
   478     |holder|
       
   479     (holder := builder bindingAt:#listOfHelpSpecClasses) isNil ifTrue:[
       
   480         builder aspectAt:#listOfHelpSpecClasses put: (holder := List new)
       
   481     ].
       
   482     ^ holder
       
   483 
       
   484 !
       
   485 
       
   486 selectionOfHelpSpecClass
       
   487     "get the value holder of the selected help spec class
       
   488     "
       
   489     |holder|
       
   490     (holder := builder bindingAt:#selectionOfHelpSpecClass) isNil ifTrue:[
       
   491         builder aspectAt:#selectionOfHelpSpecClass put: (holder := ValueHolder new)
       
   492     ].
       
   493     ^ holder
       
   494 
       
   495 ! !
       
   496 
       
   497 !UIHelpTool methodsFor:'callbacks'!
   450 
   498 
   451 helpSpecClassSelected
   499 helpSpecClassSelected
   452     "extract the help dictionary from the selected class and make it current
   500     "extract the help dictionary from the selected class and make it current
   453     "
   501     "
   454     |clsName|
   502     |clsName|
   476     [
   524     [
   477         self editTextView contents: (dictionary at: listSelection asSymbol ifAbsent: '')
   525         self editTextView contents: (dictionary at: listSelection asSymbol ifAbsent: '')
   478     ]
   526     ]
   479 
   527 
   480 
   528 
   481 !
       
   482 
       
   483 installHelpSpecOnClass:aClass
       
   484     "save the help dicts in aClass which is subclass of ApplicationModel"
       
   485 
       
   486     |cls src helpSpec|
       
   487 
       
   488     cls := self applicationClassAssociatedWith:aClass.
       
   489 
       
   490     cls isNil ifTrue:[
       
   491         self information:'No application class defined!!'.
       
   492         ^nil
       
   493     ].
       
   494 
       
   495     (cls isSubclassOf: ApplicationModel) ifFalse:[
       
   496         self information: 'Cannot save help spec into class ', cls name asBoldText, ',\because it is not a subclass of ApplicationModel!!' withCRs.
       
   497         ^nil
       
   498     ].
       
   499 
       
   500     helpSpec := dictionaries at: cls name 
       
   501         ifAbsent: [aClass = cls name asString ifTrue: [dictionary] ifFalse: [Dictionary new]].
       
   502 
       
   503     (cls class implements: #helpSpec) 
       
   504     ifTrue: 
       
   505     [
       
   506         |superclassHelpKeys implementedHelpSpec hasChanged|
       
   507         implementedHelpSpec := Dictionary new.
       
   508         superclassHelpKeys := (cls superclass respondsTo: #helpSpec)
       
   509             ifTrue:  [cls superclass helpSpec keys]
       
   510             ifFalse: [Array new].
       
   511 
       
   512         cls helpSpec associationsDo: [:h| (superclassHelpKeys includes: h key) 
       
   513             ifFalse: [implementedHelpSpec at: h key put: h value]].
       
   514 
       
   515         hasChanged := false.
       
   516         implementedHelpSpec associationsDo: [:h| (helpSpec            includesAssociation: h) ifFalse: [hasChanged := true]].
       
   517         helpSpec            associationsDo: [:h| (implementedHelpSpec includesAssociation: h) ifFalse: [hasChanged := true]].
       
   518 
       
   519         (implementedHelpSpec notEmpty and: [hasChanged and:
       
   520         [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 ']])
       
   521         ifTrue:
       
   522         [
       
   523              implementedHelpSpec associationsDo: [:h| (helpSpec includesKey: h key) 
       
   524                 ifFalse: [helpSpec at: h key put: h value]].
       
   525         ]
       
   526     ].
       
   527 
       
   528     helpSpec isEmpty ifTrue:[
       
   529         ^(cls superclass respondsTo: #helpSpec) ifTrue: [cls class removeSelector: #helpSpec].
       
   530     ].
       
   531 
       
   532     src  := '' writeStream.
       
   533 
       
   534     src nextPutAll:
       
   535 
       
   536 'helpSpec
       
   537     "return a dictionary filled with helpKey -> helptext associations.
       
   538      These are used by the activeHelp tool."
       
   539 
       
   540     "
       
   541     UIHelpTool openOnClass:', cls name asString ,'    
       
   542     "
       
   543 
       
   544   ^ super helpSpec addPairsFrom:#(
       
   545 
       
   546 '.
       
   547 
       
   548     helpSpec keys asSortedCollection
       
   549     do:[:key |
       
   550         |txt t|
       
   551 
       
   552         txt := helpSpec at:key.
       
   553         src nextPutLine:key storeString.
       
   554 
       
   555         t := txt asString replaceAll:(Character cr) with:(Character space).
       
   556 
       
   557         (t endsWith:Character space) ifTrue:[
       
   558             t := t copyWithoutLast:1
       
   559         ].
       
   560         src nextPutLine:t storeString; cr.
       
   561     ].
       
   562     src nextPutLine:')'.
       
   563 
       
   564     Compiler 
       
   565         compile:(src contents)
       
   566         forClass:cls class 
       
   567         inCategory:'help specs'.
       
   568 
       
   569 
       
   570 
       
   571 
       
   572 !
       
   573 
       
   574 installHelpSpecsOnClass:aClass
       
   575     "save the help dicts on aClass and its superclasses which are subclasses of ApplicationModel
       
   576     "
       
   577     |cls helpSpecClasses|
       
   578 
       
   579     isModified ifFalse:[
       
   580         ^nil
       
   581     ].
       
   582 
       
   583     cls := aClass isClass ifTrue: [aClass name] ifFalse: [aClass].
       
   584 
       
   585     (helpSpecClasses := self listOfHelpSpecClasses value) notNil
       
   586     ifTrue:
       
   587     [     
       
   588         (helpSpecClasses includes: cls) ifFalse: [helpSpecClasses add: cls].
       
   589         helpSpecClasses do: [:clsName| (self installHelpSpecOnClass: clsName) isNil ifTrue: [^isModified := false]].
       
   590     ]
       
   591     ifFalse:
       
   592     [
       
   593         self installHelpSpecOnClass: cls
       
   594     ].
       
   595 
       
   596     isModified := false.
       
   597 
       
   598 ! !
       
   599 
       
   600 !UIHelpTool methodsFor:'aspects'!
       
   601 
       
   602 listChannel
       
   603     "get the value holder of the help texts
       
   604     "
       
   605     |holder|
       
   606     (holder := builder bindingAt:#listChannel) isNil ifTrue:[
       
   607         builder aspectAt:#listChannel put:(holder :=  OrderedCollection new asValue).
       
   608     ].
       
   609     ^ holder
       
   610 !
       
   611 
       
   612 listModel
       
   613     "get the value holder of the help key
       
   614     "
       
   615     |holder|
       
   616     (holder := builder bindingAt:#listModel) isNil ifTrue:[
       
   617         holder := AspectAdaptor new subject:self; forAspect:#listSelection.
       
   618         builder aspectAt:#listModel put:holder.
       
   619     ].
       
   620     ^ holder
       
   621 !
       
   622 
       
   623 listOfHelpSpecClasses
       
   624     "get the value holder of the specClass and its superclasses 
       
   625      which are subclasses of ApplicationModel
       
   626     "
       
   627     |holder|
       
   628     (holder := builder bindingAt:#listOfHelpSpecClasses) isNil ifTrue:[
       
   629         builder aspectAt:#listOfHelpSpecClasses put: (holder := List new)
       
   630     ].
       
   631     ^ holder
       
   632 
       
   633 !
       
   634 
       
   635 selectionOfHelpSpecClass
       
   636     "get the value holder of the selected help spec class
       
   637     "
       
   638     |holder|
       
   639     (holder := builder bindingAt:#selectionOfHelpSpecClass) isNil ifTrue:[
       
   640         builder aspectAt:#selectionOfHelpSpecClass put: (holder := ValueHolder new)
       
   641     ].
       
   642     ^ holder
       
   643 
       
   644 ! !
       
   645 
       
   646 !UIHelpTool methodsFor:'initialization'!
       
   647 
       
   648 initialize
       
   649     "initialize instance variables
       
   650     "
       
   651     super initialize.
       
   652 
       
   653     dictionary   := Dictionary new.
       
   654     dictionaries := Dictionary new.
       
   655     isModified   := false.
       
   656 
       
   657 ! !
   529 ! !
   658 
   530 
   659 !UIHelpTool methodsFor:'private'!
   531 !UIHelpTool methodsFor:'private'!
       
   532 
       
   533 applicationClassAssociatedWith:aClass
       
   534     "get application class keeping the associated help text or nil
       
   535     "
       
   536     |cls|
       
   537 
       
   538     ((cls := self resolveName:aClass) notNil and:[cls includesBehavior:UISpecification]) ifTrue:[
       
   539         ^UISpecificationTool
       
   540     ].
       
   541     ^cls
       
   542 
       
   543 
       
   544 !
   660 
   545 
   661 editTextView
   546 editTextView
   662     "get the editTextView or nil.
   547     "get the editTextView or nil.
   663     "
   548     "
   664     |view|
   549     |view|
   724     dictionary := dictTemp
   609     dictionary := dictTemp
   725 
   610 
   726 
   611 
   727 !
   612 !
   728 
   613 
       
   614 installHelpSpecOnClass:aClass
       
   615     "save the help dicts in aClass which is subclass of ApplicationModel"
       
   616 
       
   617     |cls src helpSpec|
       
   618 
       
   619     cls := self applicationClassAssociatedWith:aClass.
       
   620 
       
   621     cls isNil ifTrue:[
       
   622         self information:'No application class defined!!'.
       
   623         ^nil
       
   624     ].
       
   625 
       
   626     (cls isSubclassOf: ApplicationModel) ifFalse:[
       
   627         self information: 'Cannot save help spec into class ', cls name asBoldText, ',\because it is not a subclass of ApplicationModel!!' withCRs.
       
   628         ^nil
       
   629     ].
       
   630 
       
   631     helpSpec := dictionaries 
       
   632         at: cls name 
       
   633         ifAbsent: [specClass notNil 
       
   634             ifTrue:  [dictionaries at: aClass put: (self extractHelpSpecForClass: (Smalltalk at: aClass))]
       
   635             ifFalse: [dictionary size > 0 ifTrue: [dictionary] ifFalse: [Dictionary new]]].
       
   636 
       
   637     (cls class implements: #helpSpec) 
       
   638     ifTrue: 
       
   639     [
       
   640         |superclassHelpKeys implementedHelpSpec hasChanged|
       
   641         implementedHelpSpec := Dictionary new.
       
   642         superclassHelpKeys := (cls superclass respondsTo: #helpSpec)
       
   643             ifTrue:  [cls superclass helpSpec keys]
       
   644             ifFalse: [Array new].
       
   645 
       
   646         cls helpSpec associationsDo: [:h| (superclassHelpKeys includes: h key) 
       
   647             ifFalse: [implementedHelpSpec at: h key put: h value]].
       
   648 
       
   649         hasChanged := false.
       
   650         implementedHelpSpec associationsDo: [:h| (helpSpec            includesAssociation: h) ifFalse: [hasChanged := true]].
       
   651         helpSpec            associationsDo: [:h| (implementedHelpSpec includesAssociation: h) ifFalse: [hasChanged := true]].
       
   652 
       
   653         (implementedHelpSpec notEmpty and: [hasChanged and:
       
   654         [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 ']])
       
   655         ifTrue:
       
   656         [      
       
   657              implementedHelpSpec associationsDo: [:h| (helpSpec includesKey: h key) 
       
   658                 ifFalse: [helpSpec at: h key put: h value]].
       
   659         ]
       
   660     ].
       
   661 
       
   662     helpSpec isEmpty ifTrue:[
       
   663         ^(cls superclass respondsTo: #helpSpec) ifTrue: [cls class removeSelector: #helpSpec].
       
   664     ].
       
   665 
       
   666     src  := '' writeStream.
       
   667 
       
   668     src nextPutAll:
       
   669         'helpSpec\' withCRs,
       
   670         (ResourceSpecEditor codeGenerationCommentForClass: UIHelpTool) withCRs,
       
   671     '\\' withCRs,
       
   672     '    "\' withCRs,
       
   673     '     UIHelpTool openOnClass:', cls name asString ,'    
       
   674     "
       
   675 
       
   676     <resource: #help>
       
   677 
       
   678     ^super helpSpec addPairsFrom:#(
       
   679 
       
   680 '.
       
   681 
       
   682     helpSpec keys asSortedCollection
       
   683     do:[:key |
       
   684         |txt t|
       
   685 
       
   686         txt := helpSpec at:key.
       
   687         src nextPutLine:key storeString.
       
   688 
       
   689         t := txt asString replaceAll:(Character cr) with:(Character space).
       
   690 
       
   691         (t endsWith:Character space) ifTrue:[
       
   692             t := t copyWithoutLast:1
       
   693         ].
       
   694         src nextPutLine:t storeString; cr.
       
   695     ].
       
   696     src nextPutLine:')'.
       
   697 
       
   698     Compiler 
       
   699         compile:(src contents)
       
   700         forClass:cls class 
       
   701         inCategory:'help specs'.
       
   702 !
       
   703 
       
   704 installHelpSpecsOnClass:aClass
       
   705     "save the help dicts on aClass and its superclasses which are subclasses of ApplicationModel
       
   706     "
       
   707     |cls helpSpecClasses|
       
   708 
       
   709     modified ifFalse:[
       
   710         ^nil
       
   711     ].
       
   712 
       
   713     cls := aClass isClass ifTrue: [aClass name] ifFalse: [aClass].
       
   714 
       
   715     (helpSpecClasses := self listOfHelpSpecClasses value) notNil
       
   716     ifTrue:
       
   717     [     
       
   718         (helpSpecClasses includes: cls) ifFalse: [helpSpecClasses add: cls].
       
   719         helpSpecClasses do: [:clsName| (self installHelpSpecOnClass: clsName) isNil ifTrue: [^modified := false]].
       
   720     ]
       
   721     ifFalse:
       
   722     [
       
   723         self installHelpSpecOnClass: cls
       
   724     ].
       
   725 
       
   726     modified := false.
       
   727 
       
   728 !
       
   729 
   729 updateList
   730 updateList
   730     "update the list channel from dictionary
   731     "update the list channel from dictionary
   731     "
   732     "
   732     self listChannel value: dictionary keys asSortedCollection
   733     self listChannel value: dictionary keys asSortedCollection
   733 ! !
       
   734 
       
   735 !UIHelpTool methodsFor:'queries'!
       
   736 
       
   737 applicationClassAssociatedWith:aClass
       
   738     "get application class keeping the associated help text or nil
       
   739     "
       
   740     |cls|
       
   741 
       
   742     ((cls := self resolveName:aClass) notNil and:[cls includesBehavior:UISpecification]) ifTrue:[
       
   743         ^UISpecificationTool
       
   744     ].
       
   745     ^cls
       
   746 
       
   747 
       
   748 ! !
   734 ! !
   749 
   735 
   750 !UIHelpTool methodsFor:'selection'!
   736 !UIHelpTool methodsFor:'selection'!
   751 
   737 
   752 listSelection
   738 listSelection
   802 !UIHelpTool methodsFor:'startup / release'!
   788 !UIHelpTool methodsFor:'startup / release'!
   803 
   789 
   804 closeRequest
   790 closeRequest
   805     "before closing the help tool, ask for permission
   791     "before closing the help tool, ask for permission
   806     "
   792     "
   807     (isModified and:[self masterApplication isNil]) ifTrue:[
   793     (modified and:[self masterApplication isNil]) ifTrue:[
   808         (self confirm:'Exit without saving your modifications?') ifFalse:[
   794         (self confirm:'Exit without saving your modifications?') ifFalse:[
   809             ^ self
   795             ^ self
   810         ]
   796         ]
   811     ].
   797     ].
   812     ^ super closeRequest.
   798     ^super closeRequest
       
   799 !
       
   800 
       
   801 initialize
       
   802     "initialize instance variables
       
   803     "
       
   804     super initialize.
       
   805 
       
   806     dictionary   := Dictionary new.
       
   807     dictionaries := Dictionary new.
       
   808     modified   := false.
       
   809 
   813 !
   810 !
   814 
   811 
   815 openInterface:aSymbol
   812 openInterface:aSymbol
   816     "open interface
   813     "open interface
   817     "
   814     "
   818     super openInterface: #windowSpecForStandAlone
   815     super openInterface: #windowSpecForStandAlone
   819 ! !
   816 ! !
   820 
   817 
   821 !UIHelpTool methodsFor:'user interactions'!
   818 !UIHelpTool methodsFor:'user actions'!
   822 
   819 
   823 accept
   820 accept
   824     "accept the help text
   821     "accept the help text
   825     "
   822     "
   826     |view key txt list listChgd|   
   823     |view key txt list listChgd|   
   838         listChgd ifTrue:[
   835         listChgd ifTrue:[
   839             self updateList.
   836             self updateList.
   840             (builder componentAt: #listOfHelpKeysView) selection: (list indexOf: key).
   837             (builder componentAt: #listOfHelpKeysView) selection: (list indexOf: key).
   841         ]. 
   838         ]. 
   842 
   839 
   843         isModified := true.
   840         modified := true.
   844         modifiedHolder notNil ifTrue: [modifiedHolder value:true]
   841         modifiedHolder notNil ifTrue: [modifiedHolder value:true]
   845     ]
   842     ]
   846 !
   843 !
   847 
   844 
   848 add
   845 add
   861         dictionary removeKey: listSelection asSymbol ifAbsent: nil.
   858         dictionary removeKey: listSelection asSymbol ifAbsent: nil.
   862         self remove.
   859         self remove.
   863 
   860 
   864         self updateList.
   861         self updateList.
   865 
   862 
   866         isModified := true.
   863         modified := true.
   867         modifiedHolder notNil ifTrue: [modifiedHolder value:true]
   864         modifiedHolder notNil ifTrue: [modifiedHolder value:true]
   868     ]
   865     ]
   869 !
   866 !
   870 
   867 
   871 doFromClass
   868 doFromClass
   903     model  := self listModel.
   900     model  := self listModel.
   904     oldSel := model value.
   901     oldSel := model value.
   905     model value:nil.
   902     model value:nil.
   906     self helpSpecFrom:specClass.
   903     self helpSpecFrom:specClass.
   907     model value:oldSel.
   904     model value:oldSel.
   908     isModified := false.
   905     modified := false.
   909 
   906 
   910 !
   907 !
   911 
   908 
   912 doSave
   909 doSave
   913     "save the help dictionaries
   910     "save the help dictionaries
   919     "remove selected help key
   916     "remove selected help key
   920     "
   917     "
   921     self listModel value: nil.
   918     self listModel value: nil.
   922     self updateList.
   919     self updateList.
   923     modifiedHolder notNil ifTrue: [modifiedHolder value:true]
   920     modifiedHolder notNil ifTrue: [modifiedHolder value:true]
       
   921 !
       
   922 
       
   923 reset
       
   924     "reset the help tool
       
   925     "
       
   926     specClass := listSelection := nil.
       
   927     self dictionary: nil.
       
   928     self dictionaries: nil.
       
   929     self listOfHelpSpecClasses removeAll.
       
   930     modified := false.
   924 ! !
   931 ! !
   925 
   932 
   926 !UIHelpTool class methodsFor:'documentation'!
   933 !UIHelpTool class methodsFor:'documentation'!
   927 
   934 
   928 version
   935 version