UIHelpTool.st
changeset 750 9b705e31d38e
parent 740 e7362f3ab5e5
child 761 91e524583390
equal deleted inserted replaced
749:8f8767c6f32f 750:9b705e31d38e
    10  hereby transferred.
    10  hereby transferred.
    11 "
    11 "
    12 
    12 
    13 
    13 
    14 
    14 
    15 ApplicationModel subclass:#UIHelpTool
    15 ToolApplicationModel subclass:#UIHelpTool
    16 	instanceVariableNames:'specClass dictionary dictionaries listSelection modified
    16 	instanceVariableNames:'specClass specSelector dictionary dictionaries listSelection
    17 		modifiedHolder maxCharsPerLine'
    17 		modifiedHolder maxCharsPerLine modified'
    18 	classVariableNames:''
    18 	classVariableNames:''
    19 	poolDictionaries:''
    19 	poolDictionaries:''
    20 	category:'Interface-UIPainter'
    20 	category:'Interface-UIPainter'
    21 !
    21 !
    22 
    22 
    47     this selector is called by the widget's view when the mouse cursor moves over. 
    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
    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.
    49     is enabled, an active help bubble is shown at the widget's view.
    50 
    50 
    51     [author:]
    51     [author:]
    52         Claus Atzkern
    52         Claus Atzkern, eXept Software AG
       
    53         Thomas Zwick, eXept Software AG
    53 "
    54 "
    54 ! !
    55 ! !
    55 
    56 
    56 !UIHelpTool class methodsFor:'instance creation'!
    57 !UIHelpTool class methodsFor:'instance creation'!
    57 
    58 
    58 openOnClass:aClass
    59 openOnClass:aClass
    59     "
    60     "
    60      UIHelpTool openOnClass:UIPainter
    61      UIHelpTool openOnClass:self
    61     "
    62     "
    62 
    63 
    63     UIHelpTool open helpSpecFrom:aClass
    64     UIHelpTool new openOnClass:aClass
       
    65 
       
    66 ! !
       
    67 
       
    68 !UIHelpTool class methodsFor:'accessing'!
       
    69 
       
    70 resourceType
       
    71     "get the type of resource of the method generated by the Help Tool"
       
    72 
       
    73     ^#help
       
    74 
    64 
    75 
    65 ! !
    76 ! !
    66 
    77 
    67 !UIHelpTool class methodsFor:'constants'!
    78 !UIHelpTool class methodsFor:'constants'!
    68 
    79 
    87     <resource: #help>
    98     <resource: #help>
    88 
    99 
    89     ^super helpSpec addPairsFrom:#(
   100     ^super helpSpec addPairsFrom:#(
    90 
   101 
    91 #addHelpTextKey
   102 #addHelpTextKey
    92 'Adds help text key.'
   103 'Adds the help text key to the help spec.'
    93 
   104 
    94 #currentHelpTexts
   105 #currentHelpTexts
    95 'Selected help text key.'
   106 'Selected help text key.'
    96 
   107 
    97 #deleteHelpTextKey
   108 #deleteHelpTextKey
    98 'Deletes the help text from the help spec.'
   109 'Deletes the help text key from the help spec.'
       
   110 
       
   111 #fileLoad
       
   112 'Opens a dialog for selecting and loading a help spec from a class.'
       
   113 
       
   114 #fileSave
       
   115 'Saves current help spec.'
    99 
   116 
   100 #helpTextView
   117 #helpTextView
   101 'Shows the help text.'
   118 'Shows the help text.'
   102 
   119 
   103 #listOfHelpSpecClasses
   120 #listOfHelpSpecClasses
   133      
   150      
   134        #(#FullSpec
   151        #(#FullSpec
   135           #window: 
   152           #window: 
   136            #(#WindowSpec
   153            #(#WindowSpec
   137               #name: 'Help Tool'
   154               #name: 'Help Tool'
   138               #layout: #(#LayoutFrame 140 0 231 0 425 0 501 0)
   155               #layout: #(#LayoutFrame 155 0 273 0 440 0 543 0)
   139               #label: 'Help Tool'
   156               #label: 'Help Tool'
   140               #min: #(#Point 10 10)
   157               #min: #(#Point 10 10)
   141               #max: #(#Point 1160 870)
   158               #max: #(#Point 1160 870)
   142               #bounds: #(#Rectangle 140 231 426 502)
   159               #bounds: #(#Rectangle 155 273 441 544)
   143               #usePreferredExtent: false
   160               #usePreferredExtent: false
   144           )
   161           )
   145           #component: 
   162           #component: 
   146            #(#SpecCollection
   163            #(#SpecCollection
   147               #collection: 
   164               #collection: 
   148                #(
   165                #(
   149                  #(#SequenceViewSpec
   166                  #(#VariableVerticalPanelSpec
   150                     #name: 'listOfHelpKeysView'
   167                     #name: 'VariableVerticalPanel'
   151                     #layout: #(#LayoutFrame 3 0 2 0 -1 0.5 -1 0.5)
   168                     #layout: #(#LayoutFrame 0 0.0 0 0.0 0 1.0 0 1.0)
   152                     #activeHelpKey: #listOfHelpTexts
   169                     #component: 
   153                     #tabable: true
   170                      #(#SpecCollection
   154                     #model: #listModel
   171                         #collection: 
   155                     #hasHorizontalScrollBar: true
   172                          #(
   156                     #hasVerticalScrollBar: true
   173                            #(#VariableHorizontalPanelSpec
   157                     #miniScrollerHorizontal: true
   174                               #name: 'VariableHorizontalPanel'
   158                     #useIndex: false
   175                               #component: 
   159                     #sequenceList: #listChannel
   176                                #(#SpecCollection
   160                 )
   177                                   #collection: 
   161                  #(#ActionButtonSpec
   178                                    #(
   162                     #name: 'AddButton'
   179                                      #(#SequenceViewSpec
   163                     #layout: #(#LayoutFrame 2 0.5 2 0 -1 0.67 26 0)
   180                                         #name: 'listOfHelpKeysView'
   164                     #activeHelpKey: #addHelpTextKey
   181                                         #activeHelpKey: #listOfHelpTexts
   165                     #label: 'Add'
   182                                         #tabable: true
   166                     #tabable: true
   183                                         #model: #listModel
   167                     #model: #add
   184                                         #hasHorizontalScrollBar: true
   168                 )
   185                                         #hasVerticalScrollBar: true
   169                  #(#ActionButtonSpec
   186                                         #miniScrollerHorizontal: true
   170                     #name: 'RemoveButton'
   187                                         #useIndex: false
   171                     #layout: #(#LayoutFrame 1 0.67 2 0 -1 0.83 26 0)
   188                                         #sequenceList: #listChannel
   172                     #activeHelpKey: #removeHelpTextKey
   189                                     )
   173                     #label: 'Remove'
   190                                      #(#ViewSpec
   174                     #tabable: true
   191                                         #name: 'Box'
   175                     #model: #remove
   192                                         #component: 
   176                 )
   193                                          #(#SpecCollection
   177                  #(#ActionButtonSpec
   194                                             #collection: 
   178                     #name: 'DeleteButton'
   195                                              #(
   179                     #layout: #(#LayoutFrame 1 0.83 2 0 -2 1 26 0)
   196                                                #(#InputFieldSpec
   180                     #activeHelpKey: #deleteHelpTextKey
   197                                                   #name: 'helpKeyInputField'
   181                     #label: 'Delete'
   198                                                   #layout: #(#LayoutFrame 0 0.0 29 0 0 1.0 51 0)
   182                     #tabable: true
   199                                                   #activeHelpKey: #currentHelpTexts
   183                     #model: #delete
   200                                                   #tabable: true
   184                 )
   201                                                   #model: #listModel
   185                  #(#InputFieldSpec
   202                                                   #immediateAccept: false
   186                     #name: 'helpKeyInputField'
   203                                               )
   187                     #layout: #(#LayoutFrame 1 0.5 29 0 -3 1 51 0)
   204                                                #(#SequenceViewSpec
   188                     #activeHelpKey: #currentHelpTexts
   205                                                   #name: 'listOfHelpSpecClassesView'
   189                     #tabable: true
   206                                                   #layout: #(#LayoutFrame 0 0.0 54 0 0 1.0 0 1.0)
   190                     #model: #listModel
   207                                                   #activeHelpKey: #listOfHelpSpecClasses
   191                     #immediateAccept: false
   208                                                   #tabable: true
   192                 )
   209                                                   #model: #selectionOfHelpSpecClass
   193                  #(#SequenceViewSpec
   210                                                   #hasHorizontalScrollBar: true
   194                     #name: 'listOfHelpSpecClassesView'
   211                                                   #hasVerticalScrollBar: true
   195                     #layout: #(#LayoutFrame 1 0.5 54 0 -3 1 -1 0.5)
   212                                                   #miniScrollerHorizontal: true
   196                     #activeHelpKey: #listOfHelpSpecClasses
   213                                                   #miniScrollerVertical: true
   197                     #tabable: true
   214                                                   #valueChangeSelector: #helpSpecClassSelected
   198                     #model: #selectionOfHelpSpecClass
   215                                                   #useIndex: false
   199                     #hasHorizontalScrollBar: true
   216                                                   #sequenceList: #listOfHelpSpecClasses
   200                     #hasVerticalScrollBar: true
   217                                               )
   201                     #miniScrollerHorizontal: true
   218                                                #(#HorizontalPanelViewSpec
   202                     #miniScrollerVertical: true
   219                                                   #name: 'HorizontalPanel1'
   203                     #valueChangeSelector: #helpSpecClassSelected
   220                                                   #layout: #(#LayoutFrame 0 0.0 2 0 0 1.0 26 0)
   204                     #useIndex: false
   221                                                   #component: 
   205                     #sequenceList: #listOfHelpSpecClasses
   222                                                    #(#SpecCollection
   206                 )
   223                                                       #collection: 
   207                  #(#TextEditorSpec
   224                                                        #(
   208                     #name: 'helpTextView'
   225                                                          #(#ActionButtonSpec
   209                     #layout: #(#LayoutFrame 3 0.0 1 0.5 -1 1.0 -3 1.0)
   226                                                             #name: 'AddButton'
   210                     #activeHelpKey: #helpTextView
   227                                                             #activeHelpKey: #addHelpTextKey
   211                     #tabable: true
   228                                                             #label: 'Add'
   212                     #hasHorizontalScrollBar: true
   229                                                             #tabable: true
   213                     #hasVerticalScrollBar: true
   230                                                             #model: #doAdd
   214                     #miniScrollerHorizontal: true
   231                                                             #extent: #(#Point 44 24)
   215                     #miniScrollerVertical: true
   232                                                         )
       
   233                                                          #(#ActionButtonSpec
       
   234                                                             #name: 'RemoveButton'
       
   235                                                             #activeHelpKey: #removeHelpTextKey
       
   236                                                             #label: 'Remove'
       
   237                                                             #tabable: true
       
   238                                                             #model: #doRemove
       
   239                                                             #extent: #(#Point 45 24)
       
   240                                                         )
       
   241                                                          #(#ActionButtonSpec
       
   242                                                             #name: 'DeleteButton'
       
   243                                                             #activeHelpKey: #deleteHelpTextKey
       
   244                                                             #label: 'Delete'
       
   245                                                             #tabable: true
       
   246                                                             #model: #doDelete
       
   247                                                             #extent: #(#Point 45 24)
       
   248                                                         )
       
   249                                                       )
       
   250                                                   )
       
   251                                                   #horizontalLayout: #fit
       
   252                                                   #verticalLayout: #fit
       
   253                                                   #horizontalSpace: 3
       
   254                                                   #verticalSpace: 3
       
   255                                               )
       
   256                                             )
       
   257                                         )
       
   258                                     )
       
   259                                   )
       
   260                               )
       
   261                               #handles: #(#Any 0.5 1.0)
       
   262                           )
       
   263                            #(#TextEditorSpec
       
   264                               #name: 'helpTextView'
       
   265                               #activeHelpKey: #helpTextView
       
   266                               #tabable: true
       
   267                               #hasHorizontalScrollBar: true
       
   268                               #hasVerticalScrollBar: true
       
   269                               #miniScrollerHorizontal: true
       
   270                               #miniScrollerVertical: true
       
   271                           )
       
   272                         )
       
   273                     )
       
   274                     #handles: #(#Any 0.5 1.0)
   216                 )
   275                 )
   217               )
   276               )
   218           )
   277           )
   219       )
   278       )
   220 !
   279 !
   237      
   296      
   238        #(#FullSpec
   297        #(#FullSpec
   239           #window: 
   298           #window: 
   240            #(#WindowSpec
   299            #(#WindowSpec
   241               #name: 'Help Tool'
   300               #name: 'Help Tool'
   242               #layout: #(#LayoutFrame 534 0 276 0 1033 0 675 0)
   301               #layout: #(#LayoutFrame 191 0 334 0 660 0 663 0)
   243               #label: 'Help Tool'
   302               #label: 'Help Tool'
   244               #min: #(#Point 10 10)
   303               #min: #(#Point 300 300)
   245               #max: #(#Point 1160 870)
   304               #max: #(#Point 1152 900)
   246               #bounds: #(#Rectangle 534 276 1034 676)
   305               #bounds: #(#Rectangle 191 334 661 664)
   247               #menu: #menu
   306               #menu: #menu
   248               #usePreferredExtent: false
   307               #usePreferredExtent: false
   249           )
   308           )
   250           #component: 
   309           #component: 
   251            #(#SpecCollection
   310            #(#SpecCollection
   252               #collection: 
   311               #collection: 
   253                #(
   312                #(
   254                  #(#UISubSpecification
   313                  #(#UISubSpecification
   255                     #name: 'UISubSpecification1'
   314                     #name: 'windowSpec'
   256                     #layout: #(#LayoutFrame 0 0.0 0 0.0 0 1.0 0 1.0)
   315                     #layout: #(#LayoutFrame 0 0.0 0 0.0 0 1.0 -26 1.0)
   257                     #minorKey: #windowSpec
   316                     #minorKey: #windowSpec
       
   317                 )
       
   318                  #(#UISubSpecification
       
   319                     #name: 'windowSpecForInfoBar'
       
   320                     #layout: #(#LayoutFrame 0 0 -24 1 0 1 0 1)
       
   321                     #majorKey: #ToolApplicationModel
       
   322                     #minorKey: #windowSpecForInfoBar
   258                 )
   323                 )
   259               )
   324               )
   260           )
   325           )
   261       )
   326       )
   262 ! !
   327 ! !
   287                 #submenu: 
   352                 #submenu: 
   288                  #(#Menu
   353                  #(#Menu
   289                     
   354                     
   290                      #(
   355                      #(
   291                        #(#MenuItem
   356                        #(#MenuItem
   292                           #label: 'Reload'
   357                           #label: 'Load'
   293                           #value: #doReload
   358                           #value: #doLoad
       
   359                           #activeHelpKey: #fileLoad
   294                       )
   360                       )
   295                        #(#MenuItem
   361                        #(#MenuItem
   296                           #label: '-'
   362                           #label: '-'
   297                       )
   363                       )
   298                        #(#MenuItem
   364                        #(#MenuItem
   299                           #label: 'Save'
   365                           #label: 'Save'
   300                           #value: #doSave
   366                           #value: #doSave
   301                       )
   367                           #activeHelpKey: #fileSave
   302                        #(#MenuItem
       
   303                           #label: '-'
       
   304                       )
       
   305                        #(#MenuItem
       
   306                           #label: 'Define Class...'
       
   307                           #value: #doFromClass
       
   308                       )
   368                       )
   309                        #(#MenuItem
   369                        #(#MenuItem
   310                           #label: '-'
   370                           #label: '-'
   311                       )
   371                       )
   312                        #(#MenuItem
   372                        #(#MenuItem
   313                           #label: 'Exit'
   373                           #label: 'Exit'
   314                           #value: #closeRequest
   374                           #value: #closeRequest
       
   375                           #activeHelpKey: #fileExit
       
   376                       )
       
   377                     ) nil
       
   378                     nil
       
   379                 )
       
   380             )
       
   381              #(#MenuItem
       
   382                 #label: 'Edit'
       
   383                 #submenu: 
       
   384                  #(#Menu
       
   385                     
       
   386                      #(
       
   387                        #(#MenuItem
       
   388                           #label: 'Add'
       
   389                           #value: #doAdd
       
   390                           #activeHelpKey: #addHelpTextKey
       
   391                       )
       
   392                        #(#MenuItem
       
   393                           #label: '-'
       
   394                       )
       
   395                        #(#MenuItem
       
   396                           #label: 'Delete'
       
   397                           #value: #doDelete
       
   398                           #activeHelpKey: #deleteHelpTextKey
       
   399                       )
       
   400                     ) nil
       
   401                     nil
       
   402                 )
       
   403             )
       
   404              #(#MenuItem
       
   405                 #label: 'Help'
       
   406                 #startGroup: #right
       
   407                 #submenu: 
       
   408                  #(#Menu
       
   409                     
       
   410                      #(
       
   411                        #(#MenuItem
       
   412                           #label: 'Documentation'
       
   413                           #value: #openHTMLDocument:
       
   414                           #activeHelpKey: #helpHelpTool
       
   415                           #argument: 'tools/uipainter/HelpTool.html'
       
   416                       )
       
   417                        #(#MenuItem
       
   418                           #label: '-'
       
   419                       )
       
   420                        #(#MenuItem
       
   421                           #label: 'Show Help Texts'
       
   422                           #activeHelpKey: #helpShowHelp
       
   423                           #indication: #showHelp:
   315                       )
   424                       )
   316                     ) nil
   425                     ) nil
   317                     nil
   426                     nil
   318                 )
   427                 )
   319             )
   428             )
   370     aKey size ~~ 0 ifTrue:[
   479     aKey size ~~ 0 ifTrue:[
   371         key := aKey asString
   480         key := aKey asString
   372     ].
   481     ].
   373     self listModel value:key
   482     self listModel value:key
   374 
   483 
   375 !
       
   376 
       
   377 helpSpecFrom:aClass
       
   378     "read the help dictionary from aClass and find remaining classes 
       
   379      'between' aClass and ApplicationModel 
       
   380     "
       
   381     |help|
       
   382 
       
   383     modified := false.
       
   384     specClass notNil
       
   385     ifTrue:
       
   386     [   
       
   387         dictionary   := Dictionary new.
       
   388         dictionaries := Dictionary new.
       
   389     ].
       
   390     specClass  := self applicationClassAssociatedWith:aClass.
       
   391     (specClass isClass and: [specClass isLoaded])
       
   392     ifTrue: 
       
   393     [                                               
       
   394         (specClass class implements:#helpSpec) ifFalse:[
       
   395             dictionaries at: specClass name put: dictionary 
       
   396         ].
       
   397         self listOfHelpSpecClasses contents:  (specClass withAllSuperclasses reverse collect: [:cls| cls name]).
       
   398         (self listOfHelpSpecClasses includes: #ApplicationModel)
       
   399             ifTrue: [self listOfHelpSpecClasses removeAll: (ApplicationModel withAllSuperclasses collect: [:cls| cls name])].
       
   400         self selectionOfHelpSpecClass value: specClass name. 
       
   401         (builder componentAt: #listOfHelpSpecClassesView) selection: 
       
   402                 (self listOfHelpSpecClasses value indexOf: specClass name).
       
   403         self helpSpecClassSelected.
       
   404     ].
       
   405 
       
   406     self updateList
       
   407 !
   484 !
   408 
   485 
   409 modified
   486 modified
   410     "answer whether the help tool was modified
   487     "answer whether the help tool was modified
   411     "
   488     "
   473 
   550 
   474 listOfHelpSpecClasses
   551 listOfHelpSpecClasses
   475     "get the value holder of the specClass and its superclasses 
   552     "get the value holder of the specClass and its superclasses 
   476      which are subclasses of ApplicationModel
   553      which are subclasses of ApplicationModel
   477     "
   554     "
   478     |holder|
   555     |holder|       
   479     (holder := builder bindingAt:#listOfHelpSpecClasses) isNil ifTrue:[
   556     (holder := builder bindingAt:#listOfHelpSpecClasses) isNil ifTrue:[
   480         builder aspectAt:#listOfHelpSpecClasses put: (holder := List new)
   557         builder aspectAt:#listOfHelpSpecClasses put: (holder := List new)
   481     ].
   558     ].
   482     ^ holder
   559     ^ holder
   483 
   560 
   489     |holder|
   566     |holder|
   490     (holder := builder bindingAt:#selectionOfHelpSpecClass) isNil ifTrue:[
   567     (holder := builder bindingAt:#selectionOfHelpSpecClass) isNil ifTrue:[
   491         builder aspectAt:#selectionOfHelpSpecClass put: (holder := ValueHolder new)
   568         builder aspectAt:#selectionOfHelpSpecClass put: (holder := ValueHolder new)
   492     ].
   569     ].
   493     ^ holder
   570     ^ holder
       
   571 
       
   572 ! !
       
   573 
       
   574 !UIHelpTool methodsFor:'building'!
       
   575 
       
   576 buildFromClass:aClass
       
   577     "read the help dictionary from aClass and find remaining classes 
       
   578      'between' aClass and ApplicationModel 
       
   579     "
       
   580     |help|
       
   581 
       
   582     modified := false.
       
   583     specClass notNil
       
   584     ifTrue:
       
   585     [   
       
   586         dictionary   := Dictionary new.
       
   587         dictionaries := Dictionary new.
       
   588     ].
       
   589     specClass  := self getHelpSpecClassFromClass:aClass.
       
   590     (specClass isClass and: [specClass isLoaded])
       
   591     ifTrue: 
       
   592     [                                               
       
   593         (specClass class implements:specSelector) ifFalse:[
       
   594             dictionaries at: specClass name put: dictionary 
       
   595         ].
       
   596         self listOfHelpSpecClasses contents:  (specClass withAllSuperclasses reverse collect: [:cls| cls name]).
       
   597         (self listOfHelpSpecClasses includes: #ApplicationModel)
       
   598             ifTrue: [self listOfHelpSpecClasses removeAll: (ApplicationModel withAllSuperclasses collect: [:cls| cls name])].
       
   599         self selectionOfHelpSpecClass value: specClass name.  
       
   600         (builder componentAt: #listOfHelpSpecClassesView) selection: 
       
   601                 (self listOfHelpSpecClasses value indexOf: specClass name).
       
   602         self helpSpecClassSelected.
       
   603     ].
       
   604 
       
   605     self updateList
       
   606 !
       
   607 
       
   608 buildFromClass: aClass andSelector: aSelector
       
   609 
       
   610     specSelector := aSelector.
       
   611     self buildFromClass:aClass
   494 
   612 
   495 ! !
   613 ! !
   496 
   614 
   497 !UIHelpTool methodsFor:'callbacks'!
   615 !UIHelpTool methodsFor:'callbacks'!
   498 
   616 
   526     ]
   644     ]
   527 
   645 
   528 
   646 
   529 ! !
   647 ! !
   530 
   648 
       
   649 !UIHelpTool methodsFor:'help'!
       
   650 
       
   651 defaultInfoLabel
       
   652     "get default label for the info bar"
       
   653 
       
   654     specClass isClass
       
   655     ifTrue:
       
   656     [
       
   657         (specClass class implements: specSelector)
       
   658         ifFalse: 
       
   659         [
       
   660             ^specSelector isNil 
       
   661                 ifTrue:  [specClass name, ' >> ? (no selector defined)']
       
   662                 ifFalse: [specClass name, ' >> ', specSelector, ' (not implemented)']
       
   663         ].
       
   664         ^specClass name, ' >> ', specSelector
       
   665     ].
       
   666     ^'No class and selector defined.'
       
   667 
       
   668 
       
   669 
       
   670 ! !
       
   671 
   531 !UIHelpTool methodsFor:'private'!
   672 !UIHelpTool methodsFor:'private'!
   532 
   673 
   533 applicationClassAssociatedWith:aClass
   674 askForModification
   534     "get application class keeping the associated help text or nil
   675     "ask for modification"
   535     "
   676 
   536     |cls|
   677     modified
   537 
   678     ifTrue:
   538     ((cls := self resolveName:aClass) notNil and:[cls includesBehavior:UISpecification]) ifTrue:[
   679     [
   539         ^UISpecificationTool
   680         ((YesNoBox title: 'List was modified!!')        
   540     ].
   681             noText:'Cancel';
   541     ^cls
   682             yesText:'Waste it and proceed';
       
   683             showAtPointer;
       
   684             accepted) ifFalse: [^false].
       
   685         modified := false
       
   686     ].
       
   687     ^true
       
   688 
   542 
   689 
   543 
   690 
   544 !
   691 !
   545 
   692 
   546 editTextView
   693 editTextView
   567 extractHelpSpecForClass: aClass
   714 extractHelpSpecForClass: aClass
   568     "extract the help dictionary of aClass, it current and return it
   715     "extract the help dictionary of aClass, it current and return it
   569     "
   716     "
   570     |helpSpecSuperClass superHelpSpecKeys helpSpec|
   717     |helpSpecSuperClass superHelpSpecKeys helpSpec|
   571 
   718 
   572     ((aClass class implements: #helpSpec)
   719     ((aClass class implements: specSelector)
   573     and: [(helpSpecSuperClass := aClass allSuperclasses detect: [:cls| cls class implements: #helpSpec] ifNone: nil) notNil])
   720     and: [(helpSpecSuperClass := aClass allSuperclasses detect: [:cls| cls class implements: specSelector] ifNone: nil) notNil])
   574     ifTrue:
   721     ifTrue:
   575     [                  
   722     [                  
   576         superHelpSpecKeys := helpSpecSuperClass helpSpec keys.
   723         superHelpSpecKeys := helpSpecSuperClass helpSpec keys.
   577         helpSpec := Dictionary new.
   724         helpSpec := Dictionary new.
   578         aClass helpSpec associationsDo:
   725         aClass helpSpec associationsDo:
   609     dictionary := dictTemp
   756     dictionary := dictTemp
   610 
   757 
   611 
   758 
   612 !
   759 !
   613 
   760 
       
   761 getHelpSpecClassFromClass:aClass
       
   762     "get application class keeping the associated help text or nil
       
   763     "
       
   764     |cls|
       
   765 
       
   766     ((cls := self resolveName:aClass) notNil and:[cls respondsTo: #helpSpecClass]) ifTrue:[
       
   767         ^cls helpSpecClass
       
   768     ].
       
   769     ^cls
       
   770 
       
   771 
       
   772 !
       
   773 
   614 installHelpSpecOnClass:aClass
   774 installHelpSpecOnClass:aClass
   615     "save the help dicts in aClass which is subclass of ApplicationModel"
   775     "save the help dicts in aClass which is subclass of ApplicationModel"
   616 
   776 
   617     |cls src helpSpec|
   777     |cls src helpSpec|
   618 
   778 
   619     cls := self applicationClassAssociatedWith:aClass.
   779     cls := self getHelpSpecClassFromClass: aClass.
   620 
   780 
   621     cls isNil ifTrue:[
   781     cls isNil ifTrue:[
   622         self information:'No application class defined!!'.
   782         self information:'No application class defined!!'.
   623         ^nil
   783         ^nil
   624     ].
   784     ].
   632         at: cls name 
   792         at: cls name 
   633         ifAbsent: [specClass notNil 
   793         ifAbsent: [specClass notNil 
   634             ifTrue:  [dictionaries at: aClass put: (self extractHelpSpecForClass: (Smalltalk at: aClass))]
   794             ifTrue:  [dictionaries at: aClass put: (self extractHelpSpecForClass: (Smalltalk at: aClass))]
   635             ifFalse: [dictionary size > 0 ifTrue: [dictionary] ifFalse: [Dictionary new]]].
   795             ifFalse: [dictionary size > 0 ifTrue: [dictionary] ifFalse: [Dictionary new]]].
   636 
   796 
   637     (cls class implements: #helpSpec) 
   797     (cls class implements: specSelector) 
   638     ifTrue: 
   798     ifTrue: 
   639     [
   799     [
   640         |superclassHelpKeys implementedHelpSpec hasChanged|
   800         |superclassHelpKeys implementedHelpSpec hasChanged|
   641         implementedHelpSpec := Dictionary new.
   801         implementedHelpSpec := Dictionary new.
   642         superclassHelpKeys := (cls superclass respondsTo: #helpSpec)
   802         superclassHelpKeys := (cls superclass respondsTo: specSelector)
   643             ifTrue:  [cls superclass helpSpec keys]
   803             ifTrue:  [cls superclass helpSpec keys]
   644             ifFalse: [Array new].
   804             ifFalse: [Array new].
   645 
   805 
   646         cls helpSpec associationsDo: [:h| (superclassHelpKeys includes: h key) 
   806         cls helpSpec associationsDo: [:h| (superclassHelpKeys includes: h key) 
   647             ifFalse: [implementedHelpSpec at: h key put: h value]].
   807             ifFalse: [implementedHelpSpec at: h key put: h value]].
   658                 ifFalse: [helpSpec at: h key put: h value]].
   818                 ifFalse: [helpSpec at: h key put: h value]].
   659         ]
   819         ]
   660     ].
   820     ].
   661 
   821 
   662     helpSpec isEmpty ifTrue:[
   822     helpSpec isEmpty ifTrue:[
   663         ^(cls superclass respondsTo: #helpSpec) ifTrue: [cls class removeSelector: #helpSpec].
   823         ^(cls superclass respondsTo: specSelector) ifTrue: [cls class removeSelector: specSelector].
   664     ].
   824     ].
   665 
   825 
   666     src  := '' writeStream.
   826     src  := '' writeStream.
   667 
   827 
   668     src nextPutAll:
   828     src nextPutAll:
   669         'helpSpec\' withCRs,
   829         specSelector, '\' withCRs,
   670         (ResourceSpecEditor codeGenerationCommentForClass: UIHelpTool) withCRs,
   830         (ResourceSpecEditor codeGenerationCommentForClass: UIHelpTool) withCRs,
   671     '\\' withCRs,
   831     '\\' withCRs,
   672     '    "\' withCRs,
   832     '    "\' withCRs,
   673     '     UIHelpTool openOnClass:', cls name asString ,'    
   833     '     UIHelpTool openOnClass:', cls name asString ,'    
   674     "
   834     "
   675 
   835 
   676     <resource: #help>
   836     <resource: #help>
   677 
   837 
   678     ^super helpSpec addPairsFrom:#(
   838     ^super ', specSelector, ' addPairsFrom:#(
   679 
   839 
   680 '.
   840 '.
   681 
   841 
   682     helpSpec keys asSortedCollection
   842     helpSpec keys asSortedCollection
   683     do:[:key |
   843     do:[:key |
   704 installHelpSpecsOnClass:aClass
   864 installHelpSpecsOnClass:aClass
   705     "save the help dicts on aClass and its superclasses which are subclasses of ApplicationModel
   865     "save the help dicts on aClass and its superclasses which are subclasses of ApplicationModel
   706     "
   866     "
   707     |cls helpSpecClasses|
   867     |cls helpSpecClasses|
   708 
   868 
       
   869     cls := self getHelpSpecClassFromClass:aClass.
       
   870     cls isNil ifTrue: [^self information:'No application class defined!!'].
       
   871 
   709     modified ifFalse:[
   872     modified ifFalse:[
       
   873         masterApplication isNil ifTrue: [self information:'Nothing was modified!!'].
   710         ^nil
   874         ^nil
   711     ].
   875     ].
   712 
       
   713     cls := aClass isClass ifTrue: [aClass name] ifFalse: [aClass].
       
   714 
   876 
   715     (helpSpecClasses := self listOfHelpSpecClasses value) notNil
   877     (helpSpecClasses := self listOfHelpSpecClasses value) notNil
   716     ifTrue:
   878     ifTrue:
   717     [     
   879     [        
   718         (helpSpecClasses includes: cls) ifFalse: [helpSpecClasses add: cls].
   880         (helpSpecClasses includes: cls name) ifFalse: [helpSpecClasses add: cls name].
   719         helpSpecClasses do: [:clsName| (self installHelpSpecOnClass: clsName) isNil ifTrue: [^modified := false]].
   881         helpSpecClasses do: [:clsName| (self installHelpSpecOnClass: clsName) isNil ifTrue: [^modified := false]].
   720     ]
   882     ]
   721     ifFalse:
   883     ifFalse:
   722     [
   884     [      
   723         self installHelpSpecOnClass: cls
   885         self installHelpSpecOnClass: cls
   724     ].
   886     ].
   725 
   887 
   726     modified := false.
   888     modified := false.
       
   889 
       
   890 !
       
   891 
       
   892 resourceMessage: aString
       
   893     "extract from aString the specClass and the specSelector"
       
   894 
       
   895     (aString notNil and: [self askForModification]) 
       
   896     ifTrue:
       
   897     [            
       
   898         |msg cls sel|
       
   899         msg := aString asCollectionOfWords.
       
   900         (msg size == 2 and:
       
   901         [(cls := self resolveName:(msg at:1)) notNil])
       
   902         ifTrue:
       
   903         [
       
   904             specClass := cls name.
       
   905             specSelector := (msg at: 2) asSymbol.
       
   906             ^true
       
   907         ]
       
   908     ].
       
   909     ^false
   727 
   910 
   728 !
   911 !
   729 
   912 
   730 updateList
   913 updateList
   731     "update the list channel from dictionary
   914     "update the list channel from dictionary
   788 !UIHelpTool methodsFor:'startup / release'!
   971 !UIHelpTool methodsFor:'startup / release'!
   789 
   972 
   790 closeRequest
   973 closeRequest
   791     "before closing the help tool, ask for permission
   974     "before closing the help tool, ask for permission
   792     "
   975     "
   793     (modified and:[self masterApplication isNil]) ifTrue:[
   976     (self masterApplication isNil and:[self askForModification]) ifTrue:[super closeRequest]
   794         (self confirm:'Exit without saving your modifications?') ifFalse:[
       
   795             ^ self
       
   796         ]
       
   797     ].
       
   798     ^super closeRequest
       
   799 !
   977 !
   800 
   978 
   801 initialize
   979 initialize
   802     "initialize instance variables
   980     "initialize instance variables
   803     "
   981     "
   804     super initialize.
   982     super initialize.
   805 
   983 
       
   984     specSelector := #helpSpec.
   806     dictionary   := Dictionary new.
   985     dictionary   := Dictionary new.
   807     dictionaries := Dictionary new.
   986     dictionaries := Dictionary new.
   808     modified   := false.
   987     modified   := false.
   809 
   988 
   810 !
   989 !
   811 
   990 
       
   991 loadFromMessage:aString
       
   992     "load a spec from class and selector"
       
   993 
       
   994     (aString notNil and: [self askForModification]) 
       
   995     ifTrue:
       
   996     [            
       
   997         |msg cls sel|
       
   998         msg := aString asCollectionOfWords.
       
   999         (msg size == 2 and:
       
  1000         [(cls := self resolveName:(msg at:1)) notNil and:
       
  1001         [cls class implements: (sel := (msg at: 2) asSymbol)]])
       
  1002         ifTrue:
       
  1003         [               
       
  1004             self buildFromClass: (specClass := cls name) andSelector: (specSelector := sel).
       
  1005             ^true
       
  1006         ]
       
  1007     ].
       
  1008     ^false
       
  1009 
       
  1010 !
       
  1011 
   812 openInterface:aSymbol
  1012 openInterface:aSymbol
   813     "open interface
  1013     "do not open as stand alone
   814     "
  1014     "
   815     super openInterface: #windowSpecForStandAlone
  1015 
       
  1016    
       
  1017 !
       
  1018 
       
  1019 openOnClass:aClass
       
  1020     "open the UIHelpTool on aClass
       
  1021     "
       
  1022 
       
  1023     super openInterface: #windowSpecForStandAlone.
       
  1024     self masterApplication isNil ifTrue: [(builder componentAt: #RemoveButton) beInvisible].
       
  1025     builder window label: 'Help Tool'.
       
  1026     self buildFromClass: aClass
   816 ! !
  1027 ! !
   817 
  1028 
   818 !UIHelpTool methodsFor:'user actions'!
  1029 !UIHelpTool methodsFor:'user actions'!
   819 
  1030 
   820 accept
  1031 accept
   840         modified := true.
  1051         modified := true.
   841         modifiedHolder notNil ifTrue: [modifiedHolder value:true]
  1052         modifiedHolder notNil ifTrue: [modifiedHolder value:true]
   842     ]
  1053     ]
   843 !
  1054 !
   844 
  1055 
   845 add
  1056 doAdd
   846     "add help key
  1057     "add help key
   847     "
  1058     "
   848     self listModel value: (builder componentAt: #helpKeyInputField asSymbol) contents.
  1059     |helpKey|
   849     self accept
  1060     (helpKey := (builder componentAt: #helpKeyInputField asSymbol) contents) size > 0
   850 !
  1061     ifTrue:
   851 
  1062     [
   852 delete
  1063         self listModel value: helpKey.
       
  1064         self accept
       
  1065     ]
       
  1066     ifFalse:
       
  1067     [
       
  1068         self warn: 'First define a help key!!'
       
  1069     ]
       
  1070 !
       
  1071 
       
  1072 doDelete
   853     "delete selected help key
  1073     "delete selected help key
   854     "
  1074     "    
   855     listSelection notNil
  1075     listSelection notNil
   856     ifTrue:
  1076     ifTrue:
   857     [
  1077     [
   858         dictionary removeKey: listSelection asSymbol ifAbsent: nil.
  1078         dictionary removeKey: listSelection asSymbol ifAbsent: nil.
   859         self remove.
  1079         self doRemove.
   860 
       
   861         self updateList.
  1080         self updateList.
   862 
       
   863         modified := true.
  1081         modified := true.
   864         modifiedHolder notNil ifTrue: [modifiedHolder value:true]
  1082         modifiedHolder notNil ifTrue: [modifiedHolder value:true]
   865     ]
  1083     ]
   866 !
  1084     ifFalse:
   867 
  1085     [
   868 doFromClass
  1086         self warn: 'First select a help key!!'
   869     "setup new specification from a class accessed through to a dialog
       
   870     "
       
   871     |cls cls2 accepted|
       
   872 
       
   873     specClass notNil ifTrue:[cls := specClass name asValue]
       
   874                     ifFalse:[cls := '' asValue].
       
   875 
       
   876     [true] whileTrue:[
       
   877         accepted :=
       
   878             (DialogBox new
       
   879                 addTextLabel:'Class name:';
       
   880                 addInputFieldOn:cls; 
       
   881                 addAbortButton; 
       
   882                 addOkButton; 
       
   883                 open
       
   884             ) accepted.
       
   885         accepted ifFalse:[^ self].
       
   886         cls2 := self applicationClassAssociatedWith:cls value.
       
   887 
       
   888         (cls2 notNil and: [cls2 respondsTo: #helpSpec]) ifTrue:[ 
       
   889             ^ self helpSpecFrom:cls2
       
   890         ].
       
   891         self warn:'No help spec found in class ', cls value asBoldText, '!!'.
       
   892     ]
  1087     ]
       
  1088 !
       
  1089 
       
  1090 doLoad
       
  1091     "open a Resource Selection Browser in order to get a resource message"
       
  1092 
       
  1093     self loadFromMessage: 
       
  1094         (ResourceSelectionBrowser
       
  1095             request: 'Load ', self class resourceType asUppercaseFirst, ' Spec From Class'
       
  1096             onSuperclass: nil
       
  1097             andClass: specClass
       
  1098             andSelector: specSelector ? self class resourceType
       
  1099             withResourceTypes: (Array with: self class resourceType))
       
  1100 
       
  1101 !
       
  1102 
       
  1103 doNew
       
  1104     "reset the help tool
       
  1105     "
       
  1106     specClass := listSelection := nil.
       
  1107     self dictionary: nil.
       
  1108     self dictionaries: nil.
       
  1109     self listOfHelpSpecClasses removeAll.
       
  1110     modified := false.
   893 !
  1111 !
   894 
  1112 
   895 doReload
  1113 doReload
   896     "reload the help dictionaries
  1114     "reload the help dictionaries
   897     "
  1115     "
   904     model value:oldSel.
  1122     model value:oldSel.
   905     modified := false.
  1123     modified := false.
   906 
  1124 
   907 !
  1125 !
   908 
  1126 
       
  1127 doRemove
       
  1128     "remove selected help key
       
  1129     "
       
  1130     listSelection notNil
       
  1131     ifTrue:
       
  1132     [
       
  1133         self listModel value: nil.
       
  1134         self updateList.
       
  1135         modifiedHolder notNil ifTrue: [modifiedHolder value:true]
       
  1136     ]
       
  1137     ifFalse:
       
  1138     [
       
  1139         self warn: 'First select a help key!!'
       
  1140     ]
       
  1141 !
       
  1142 
   909 doSave
  1143 doSave
   910     "save the help dictionaries
  1144     "save the help dictionaries
   911     "
  1145     "
   912     self installHelpSpecsOnClass:specClass
  1146     self installHelpSpecsOnClass:specClass
   913 !
       
   914 
       
   915 remove
       
   916     "remove selected help key
       
   917     "
       
   918     self listModel value: nil.
       
   919     self updateList.
       
   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.
       
   931 ! !
  1147 ! !
   932 
  1148 
   933 !UIHelpTool class methodsFor:'documentation'!
  1149 !UIHelpTool class methodsFor:'documentation'!
   934 
  1150 
   935 version
  1151 version