UIHelpTool.st
changeset 1669 e6ea33c843a0
parent 1665 f6427f12f173
child 1670 72af7609bb08
equal deleted inserted replaced
1668:3e83796a3e0e 1669:e6ea33c843a0
     1 "
     1 "
     2  COPYRIGHT (c) 1995 by eXept Software AG
     2  COPYRIGHT (c) 1995 by eXept Software AG
     3               All Rights Reserved
     3 	      All Rights Reserved
     4 
     4 
     5  This software is furnished under a license and may be used
     5  This software is furnished under a license and may be used
     6  only in accordance with the terms of that license and with the
     6  only in accordance with the terms of that license and with the
     7  inclusion of the above copyright notice.   This software may not
     7  inclusion of the above copyright notice.   This software may not
     8  be provided or otherwise made available to, or used by, any
     8  be provided or otherwise made available to, or used by, any
     9  other person.  No title to or ownership of the software is
     9  other person.  No title to or ownership of the software is
    10  hereby transferred.
    10  hereby transferred.
    11 "
    11 "
    12 
    12 
    13 
       
    14 
       
    15 "{ Package: 'stx:libtool2' }"
    13 "{ Package: 'stx:libtool2' }"
    16 
    14 
    17 ToolApplicationModel subclass:#UIHelpTool
    15 ToolApplicationModel subclass:#UIHelpTool
    18 	instanceVariableNames:'specClass specSelector dictionary dictionaries modifiedHolder
    16 	instanceVariableNames:'specClass specSelector classItemList classItemModel keyItemModel
    19 		modified listOfKeys listOfKeysModel listOfClasses
    17 		helpTextView modifiedHolder contentsModifiedChannel editModel'
    20 		listOfClassesModel contentsModifiedChannel editModel editTextView'
       
    21 	classVariableNames:''
    18 	classVariableNames:''
    22 	poolDictionaries:''
    19 	poolDictionaries:''
    23 	category:'Interface-UIPainter'
    20 	category:'Interface-UIPainter'
    24 !
    21 !
    25 
    22 
       
    23 HierarchicalItem subclass:#ClassItem
       
    24 	instanceVariableNames:'theClass list modified'
       
    25 	classVariableNames:''
       
    26 	poolDictionaries:''
       
    27 	privateIn:UIHelpTool
       
    28 !
       
    29 
       
    30 HierarchicalItem subclass:#KeyItem
       
    31 	instanceVariableNames:'helpKey helpText modified'
       
    32 	classVariableNames:''
       
    33 	poolDictionaries:''
       
    34 	privateIn:UIHelpTool
       
    35 !
       
    36 
    26 !UIHelpTool class methodsFor:'documentation'!
    37 !UIHelpTool class methodsFor:'documentation'!
    27 
    38 
    28 copyright
    39 copyright
    29 "
    40 "
    30  COPYRIGHT (c) 1995 by eXept Software AG
    41  COPYRIGHT (c) 1995 by eXept Software AG
    31               All Rights Reserved
    42 	      All Rights Reserved
    32 
    43 
    33  This software is furnished under a license and may be used
    44  This software is furnished under a license and may be used
    34  only in accordance with the terms of that license and with the
    45  only in accordance with the terms of that license and with the
    35  inclusion of the above copyright notice.   This software may not
    46  inclusion of the above copyright notice.   This software may not
    36  be provided or otherwise made available to, or used by, any
    47  be provided or otherwise made available to, or used by, any
    37  other person.  No title to or ownership of the software is
    48  other person.  No title to or ownership of the software is
    38  hereby transferred.
    49  hereby transferred.
    39 "
    50 "
    40 
       
    41 
       
    42 !
    51 !
    43 
    52 
    44 documentation
    53 documentation
    45 "
    54 "
    46     The Help Tool allows you to define help dictionaries for the widgets in
    55     The Help Tool allows you to define help dictionaries for the widgets in
    50     this selector is called by the widget's view when the mouse cursor moves over. 
    59     this selector is called by the widget's view when the mouse cursor moves over. 
    51     If the application does not responds to that selector, and the activeHelp mode
    60     If the application does not responds to that selector, and the activeHelp mode
    52     is enabled, an active help bubble is shown at the widget's view.
    61     is enabled, an active help bubble is shown at the widget's view.
    53 
    62 
    54     [instance variables:]
    63     [instance variables:]
    55         specClass       <Symbol>        class implementing the help spec
    64 	specClass       <Symbol>        class implementing the help spec
    56         specSelector    <Symbol>        selector returning the help spec
    65 	specSelector    <Symbol>        selector returning the help spec
    57         dictionary      <Dictionary>    dictionary containing pairs of help keys/texts
    66 	classItemList                   the list of classItems
    58         dictionaries    <Dictionary>    dictionary containing pairs of help spec classes/help dictionaries
    67 	classItemModel                  keeps the selected class
    59         listSelection   <String>        current selected help key
    68 	keyItemModel                    keeps the selected helpKey
    60         maxCharsPerLine <Integer>       maximum number of allowed characters per text line
    69 	modifiedHolder  <ValueHolder>   true if the editField or contents changed
    61         modifiedHolder  <ValueHolder>   value holder for setting as modified
    70 	editModel                       keeps the current helpKey
    62         modified        <Boolean>       flag whether the help spec was modified
    71 	helpTextView                    the view which shows the helpText
       
    72 	contentsModifiedChannel         true if the helpText is modified
    63 
    73 
    64     [author:]
    74     [author:]
    65         Claus Atzkern, eXept Software AG
    75 	Claus Atzkern, eXept Software AG
    66         Thomas Zwick, eXept Software AG
    76 	Thomas Zwick,  eXept Software AG
    67 "
    77 "
    68 ! !
    78 ! !
    69 
    79 
    70 !UIHelpTool class methodsFor:'instance creation'!
    80 !UIHelpTool class methodsFor:'instance creation'!
    71 
    81 
    72 open
    82 open
    73     ^ self openOnClass:nil.
    83     ^ self openOnClass:nil.
    74 
       
    75 "/    |className cls|
       
    76 "/
       
    77 "/    className := Dialog request:(ClassResources string:'Open on which class ?').
       
    78 "/    className size > 0 ifTrue:[
       
    79 "/        cls := Smalltalk at:className asSymbol.
       
    80 "/        cls notNil ifTrue:[
       
    81 "/            ^ self openOnClass:cls.
       
    82 "/        ].
       
    83 "/        self warn:(ClassResources string:'No such class').
       
    84 "/    ].
       
    85 "/
       
    86 "/    "Created: / 20.5.1998 / 00:55:05 / cg"
       
    87 "/
       
    88 
       
    89     "Modified: / 20.5.1998 / 01:06:07 / cg"
       
    90 !
    84 !
    91 
    85 
    92 openOnClass:aClass
    86 openOnClass:aClass
    93     "opens a Help Tool on aClass"
    87     "opens a Help Tool on aClass
    94 
    88     "
    95     ^ self openOnClass:aClass andSelector:#helpSpec
    89     ^ self openOnClass:aClass andSelector:#helpSpec
    96 
       
    97     "
       
    98      UIHelpTool openOnClass:self
       
    99     "
       
   100 
       
   101     "Modified: / 20.5.1998 / 01:06:14 / cg"
       
   102 !
    90 !
   103 
    91 
   104 openOnClass:aClass andSelector: aSelector
    92 openOnClass:aClass andSelector: aSelector
   105     "opens a Help Tool on aClass and aSelector"
    93     "opens a Help Tool on aClass and aSelector
   106 
    94     "
   107     ^self new openOnClass:aClass andSelector: aSelector
    95     ^ self new openOnClass:aClass andSelector:aSelector
   108   
       
   109 ! !
    96 ! !
   110 
    97 
   111 !UIHelpTool class methodsFor:'constants'!
    98 !UIHelpTool class methodsFor:'constants'!
   112 
    99 
   113 label
   100 label
   114     "returns the label; used if embedded as sub canvas in the GUI Painter or Menu Editor"
   101     "returns the label; used if embedded as sub canvas in the GUI Painter or Menu Editor
   115 
   102     "
   116     ^'Help'
   103     ^'Help'
   117 ! !
   104 ! !
   118 
   105 
   119 !UIHelpTool class methodsFor:'help specs'!
   106 !UIHelpTool class methodsFor:'help specs'!
   120 
   107 
   129      UIHelpTool openOnClass:UIHelpTool    
   116      UIHelpTool openOnClass:UIHelpTool    
   130     "
   117     "
   131 
   118 
   132     <resource: #help>
   119     <resource: #help>
   133 
   120 
   134     ^super helpSpec addPairsFrom:#(
   121     ^ super helpSpec addPairsFrom:#(
   135 
   122 
   136 #addHelpTextKey
   123 #addHelpTextKey
   137 'Adds the key to the help spec.'
   124 'Adds the key to the help spec.'
   138 
   125 
   139 #currentHelpTexts
   126 #currentHelpTexts
   186 
   173 
   187     <resource: #canvas>
   174     <resource: #canvas>
   188 
   175 
   189     ^ 
   176     ^ 
   190      #(#FullSpec
   177      #(#FullSpec
   191         #name: #windowSpec
   178 	#name: #windowSpec
   192         #window: 
   179 	#window: 
   193        #(#WindowSpec
   180        #(#WindowSpec
   194           #label: 'Help Tool'
   181 	  #label: 'UIHelpTool'
   195           #name: 'Help Tool'
   182 	  #name: 'UIHelpTool'
   196           #min: #(#Point 10 10)
   183 	  #min: #(#Point 10 10)
   197           #max: #(#Point 1160 870)
   184 	  #max: #(#Point 1024 768)
   198           #bounds: #(#Rectangle 31 306 317 577)
   185 	  #bounds: #(#Rectangle 30 292 491 585)
   199         )
   186 	)
   200         #component: 
   187 	#component: 
   201        #(#SpecCollection
   188        #(#SpecCollection
   202           #collection: #(
   189 	  #collection: #(
   203            #(#VariableVerticalPanelSpec
   190 	   #(#VariableVerticalPanelSpec
   204               #name: 'VariableVerticalPanel'
   191 	      #name: 'PanelVrt'
   205               #layout: #(#LayoutFrame 0 0.0 0 0.0 0 1.0 0 1.0)
   192 	      #layout: #(#LayoutFrame 0 0.0 0 0.0 0 1.0 0 1.0)
   206               #component: 
   193 	      #component: 
   207              #(#SpecCollection
   194 	     #(#SpecCollection
   208                 #collection: #(
   195 		#collection: #(
   209                  #(#VariableHorizontalPanelSpec
   196 		 #(#VariableHorizontalPanelSpec
   210                     #name: 'VariableHorizontalPanel'
   197 		    #name: 'PanelHrz'
   211                     #component: 
   198 		    #component: 
   212                    #(#SpecCollection
   199 		   #(#SpecCollection
   213                       #collection: #(
   200 		      #collection: #(
   214                        #(#SelectionInListModelViewSpec
   201 		       #(#HierarchicalListViewSpec
   215                           #name: 'listOfKeys'
   202 			  #name: 'keyItemModel'
   216                           #activeHelpKey: #listOfHelpTexts
   203 			  #model: #keyItemModel
   217                           #model: #listOfKeysModel
   204 			  #menu: #keyItemMenu
   218                           #menu: #listOfKeysMenu
   205 			  #hasHorizontalScrollBar: true
   219                           #hasHorizontalScrollBar: true
   206 			  #hasVerticalScrollBar: true
   220                           #hasVerticalScrollBar: true
   207 			  #miniScrollerHorizontal: true
   221                           #miniScrollerHorizontal: true
   208 			  #miniScrollerVertical: false
   222                           #listModel: #listOfKeys
   209 			  #listModel: #keyItemListHolder
   223                           #useIndex: false
   210 			  #useIndex: false
   224                           #highlightMode: #line
   211 			  #highlightMode: #label
   225                         )
   212 			  #showLines: false
   226                        #(#ViewSpec
   213 			  #showIndicators: false
   227                           #name: 'Box'
   214 			  #showLeftIndicators: false
   228                           #component: 
   215 			  #useDefaultIcons: false
   229                          #(#SpecCollection
   216 			  #autoScrollHorizontal: false
   230                             #collection: #(
   217 			)
   231                              #(#InputFieldSpec
   218 		       #(#ViewSpec
   232                                 #name: 'helpKeyInputField'
   219 			  #name: 'classItemList'
   233                                 #layout: #(#LayoutFrame 2 0.0 2 0 -2 1.0 25 0)
   220 			  #component: 
   234                                 #activeHelpKey: #currentHelpTexts
   221 			 #(#SpecCollection
   235                                 #tabable: true
   222 			    #collection: #(
   236                                 #model: #editModel
   223 			     #(#InputFieldSpec
   237                                 #immediateAccept: true
   224 				#name: 'editModel'
   238                                 #acceptOnReturn: false
   225 				#layout: #(#LayoutFrame 0 0.0 2 0 -1 1.0 25 0)
   239                                 #acceptOnTab: false
   226 				#activeHelpKey: #currentHelpTexts
   240                                 #acceptOnPointerLeave: false
   227 				#model: #editModel
   241                               )
   228 				#immediateAccept: true
   242                              #(#SelectionInListModelViewSpec
   229 				#acceptOnReturn: false
   243                                 #name: 'listOfClasses'
   230 				#acceptOnTab: false
   244                                 #layout: #(#LayoutFrame 0 0.0 27 0 0 1.0 0 1.0)
   231 				#acceptOnLostFocus: false
   245                                 #activeHelpKey: #listOfClasses
   232 				#acceptOnPointerLeave: false
   246                                 #model: #listOfClassesModel
   233 			      )
   247                                 #hasHorizontalScrollBar: true
   234 			     #(#SelectionInListModelViewSpec
   248                                 #hasVerticalScrollBar: true
   235 				#name: 'classItemModel'
   249                                 #miniScrollerHorizontal: true
   236 				#layout: #(#LayoutFrame 0 0.0 27 0.0 0 1.0 0 1.0)
   250                                 #miniScrollerVertical: true
   237 				#model: #classItemModel
   251                                 #listModel: #listOfClasses
   238 				#hasHorizontalScrollBar: true
   252                                 #useIndex: false
   239 				#hasVerticalScrollBar: true
   253                                 #highlightMode: #line
   240 				#miniScrollerHorizontal: true
   254                               )
   241 				#miniScrollerVertical: true
   255                              )
   242 				#autoHideScrollBars: false
       
   243 				#listModel: #classItemListHolder
       
   244 				#useIndex: false
       
   245 				#highlightMode: #label
       
   246 			      )
       
   247 			     )
   256                            
   248                            
   257                           )
   249 			  )
   258                         )
   250 			)
   259                        )
   251 		       )
   260                      
   252                      
   261                     )
   253 		    )
   262                     #handles: #(#Any 0.5 1.0)
   254 		    #handles: #(#Any 0.607375 1.0)
   263                   )
   255 		  )
   264                  #(#ViewSpec
   256 		 #(#ArbitraryComponentSpec
   265                     #name: 'Box1'
   257 		    #name: 'helpTextView'
   266                     #component: 
   258 		    #hasHorizontalScrollBar: true
   267                    #(#SpecCollection
   259 		    #hasVerticalScrollBar: true
   268                       #collection: #(
   260 		    #miniScrollerHorizontal: true
   269                        #(#MenuPanelSpec
   261 		    #miniScrollerVertical: true
   270                           #name: 'helpTextMenu'
   262 		    #hasBorder: false
   271                           #layout: #(#LayoutFrame 0 0.0 0 0 0 1.0 24 0)
   263 		    #component: #helpTextView
   272                           #menu: #helpTextMenu
   264 		  )
   273                           #textDefault: true
   265 		 )
   274                         )
       
   275                        #(#TextEditorSpec
       
   276                           #name: 'helpTextView'
       
   277                           #layout: #(#LayoutFrame 0 0.0 24 0.0 0 1.0 0 1.0)
       
   278                           #activeHelpKey: #helpTextView
       
   279                           #tabable: true
       
   280                           #hasHorizontalScrollBar: true
       
   281                           #hasVerticalScrollBar: true
       
   282                           #miniScrollerHorizontal: true
       
   283                           #miniScrollerVertical: true
       
   284                           #modifiedChannel: #contentsModifiedChannel
       
   285                           #postBuildCallback: #postBuildTextView:
       
   286                         )
       
   287                        )
       
   288                      
       
   289                     )
       
   290                   )
       
   291                  )
       
   292                
   266                
   293               )
   267 	      )
   294               #handles: #(#Any 0.5 1.0)
   268 	      #handles: #(#Any 0.679181 1.0)
   295             )
   269 	    )
   296            )
   270 	   )
   297          
   271          
   298         )
   272 	)
   299       )
   273       )
   300 !
   274 !
   301 
   275 
   302 windowSpecForStandAlone
   276 windowSpecForStandAlone
   303     "This resource specification was automatically generated
   277     "This resource specification was automatically generated
   313 
   287 
   314     <resource: #canvas>
   288     <resource: #canvas>
   315 
   289 
   316     ^ 
   290     ^ 
   317      #(#FullSpec
   291      #(#FullSpec
   318         #name: #windowSpecForStandAlone
   292 	#name: #windowSpecForStandAlone
   319         #window: 
   293 	#window: 
   320        #(#WindowSpec
   294        #(#WindowSpec
   321           #label: 'Help Tool'
   295 	  #label: 'Help Tool'
   322           #name: 'Help Tool'
   296 	  #name: 'Help Tool'
   323           #min: #(#Point 300 300)
   297 	  #min: #(#Point 300 300)
   324           #max: #(#Point 1152 900)
   298 	  #max: #(#Point 1152 900)
   325           #bounds: #(#Rectangle 83 333 796 896)
   299 	  #bounds: #(#Rectangle 11 332 509 761)
   326           #menu: #menu
   300 	  #menu: #menu
   327         )
   301 	)
   328         #component: 
   302 	#component: 
   329        #(#SpecCollection
   303        #(#SpecCollection
   330           #collection: #(
   304 	  #collection: #(
   331            #(#UISubSpecification
   305 	   #(#UISubSpecification
   332               #name: 'windowSpec'
   306 	      #name: 'windowSpec'
   333               #layout: #(#LayoutFrame 0 0.0 0 0.0 0 1.0 -26 1.0)
   307 	      #layout: #(#LayoutFrame 0 0.0 0 0.0 0 1.0 -50 1.0)
   334               #minorKey: #windowSpec
   308 	      #minorKey: #windowSpec
   335             )
   309 	    )
   336            #(#UISubSpecification
   310 	   #(#UISubSpecification
   337               #name: 'windowSpecForInfoBar'
   311 	      #name: 'windowSpecForCommit'
   338               #layout: #(#LayoutFrame 0 0 -24 1 0 1 0 1)
   312 	      #layout: #(#LayoutFrame 0 0.0 -50 1.0 0 1.0 -24 1.0)
   339               #majorKey: #ToolApplicationModel
   313 	      #majorKey: #ToolApplicationModel
   340               #minorKey: #windowSpecForInfoBar
   314 	      #minorKey: #windowSpecForCommit
   341             )
   315 	    )
   342            )
   316 	   #(#UISubSpecification
       
   317 	      #name: 'windowSpecForInfoBar'
       
   318 	      #layout: #(#LayoutFrame 0 0 -24 1 0 1 0 1)
       
   319 	      #majorKey: #ToolApplicationModel
       
   320 	      #minorKey: #windowSpecForInfoBar
       
   321 	    )
       
   322 	   )
   343          
   323          
   344         )
   324 	)
   345       )
   325       )
   346 ! !
   326 ! !
   347 
   327 
   348 !UIHelpTool class methodsFor:'menu specs'!
   328 !UIHelpTool class methodsFor:'menu specs'!
   349 
   329 
   361 
   341 
   362     <resource: #menu>
   342     <resource: #menu>
   363 
   343 
   364     ^ 
   344     ^ 
   365      #(#Menu
   345      #(#Menu
   366         #(
   346 	#(
   367          #(#MenuItem
   347 	 #(#MenuItem
   368             #activeHelpKey: #commitOK
   348 	    #activeHelpKey: #commitOK
   369             #enabled: #contentsModifiedChannel
   349 	    #enabled: #contentsModifiedChannel
   370             #label: 'Accept'
   350 	    #label: 'Accept'
   371             #itemValue: #accept
   351 	    #itemValue: #accept
   372             #translateLabel: true
   352 	    #translateLabel: true
   373           )
   353 	  )
   374          #(#MenuItem
   354 	 #(#MenuItem
   375             #activeHelpKey: #commitCancel
   355 	    #activeHelpKey: #commitCancel
   376             #enabled: #contentsModifiedChannel
   356 	    #enabled: #contentsModifiedChannel
   377             #label: 'Cancel'
   357 	    #label: 'Cancel'
   378             #itemValue: #cancel
   358 	    #itemValue: #cancel
   379             #translateLabel: true
   359 	    #translateLabel: true
   380           )
   360 	  )
   381          )
   361 	 )
   382         nil
   362 	nil
   383         nil
   363 	nil
       
   364       )
       
   365 !
       
   366 
       
   367 keyItemMenu
       
   368     "This resource specification was automatically generated
       
   369      by the MenuEditor of ST/X."
       
   370 
       
   371     "Do not manually edit this!! If it is corrupted,
       
   372      the MenuEditor may not be able to read the specification."
       
   373 
       
   374     "
       
   375      MenuEditor new openOnClass:UIHelpTool andSelector:#keyItemMenu
       
   376      (Menu new fromLiteralArrayEncoding:(UIHelpTool keyItemMenu)) startUp
       
   377     "
       
   378 
       
   379     <resource: #menu>
       
   380 
       
   381     ^ 
       
   382      #(#Menu
       
   383 	#(
       
   384 	 #(#MenuItem
       
   385 	    #activeHelpKey: #deleteHelpTextKey
       
   386 	    #label: 'Delete'
       
   387 	    #itemValue: #doDelete
       
   388 	    #translateLabel: true
       
   389 	  )
       
   390 	 )
       
   391 	nil
       
   392 	nil
   384       )
   393       )
   385 !
   394 !
   386 
   395 
   387 listOfKeysMenu
   396 listOfKeysMenu
   388     "This resource specification was automatically generated
   397     "This resource specification was automatically generated
   398 
   407 
   399     <resource: #menu>
   408     <resource: #menu>
   400 
   409 
   401     ^ 
   410     ^ 
   402      #(#Menu
   411      #(#Menu
   403         #(
   412 	#(
   404          #(#MenuItem
   413 	 #(#MenuItem
   405             #activeHelpKey: #deleteHelpTextKey
   414 	    #activeHelpKey: #deleteHelpTextKey
   406             #label: 'Delete'
   415 	    #label: 'Delete'
   407             #itemValue: #doDelete
   416 	    #itemValue: #doDelete
   408             #translateLabel: true
   417 	    #translateLabel: true
   409           )
   418 	  )
   410          )
   419 	 )
   411         nil
   420 	nil
   412         nil
   421 	nil
   413       )
   422       )
   414 !
   423 !
   415 
   424 
   416 menu
   425 menu
   417     "This resource specification was automatically generated
   426     "This resource specification was automatically generated
   427 
   436 
   428     <resource: #menu>
   437     <resource: #menu>
   429 
   438 
   430     ^ 
   439     ^ 
   431      #(#Menu
   440      #(#Menu
   432         #(
   441 	#(
   433          #(#MenuItem
   442 	 #(#MenuItem
   434             #label: 'File'
   443 	    #label: 'File'
   435             #translateLabel: true
   444 	    #translateLabel: true
   436             #submenu: 
   445 	    #submenu: 
   437            #(#Menu
   446 	   #(#Menu
   438               #(
   447 	      #(
   439                #(#MenuItem
   448 	       #(#MenuItem
   440                   #activeHelpKey: #fileLoad
   449 		  #activeHelpKey: #fileLoad
   441                   #label: 'Load...'
   450 		  #label: 'Load...'
   442                   #itemValue: #doLoad
   451 		  #itemValue: #doLoad
   443                   #translateLabel: true
   452 		  #translateLabel: true
   444                 )
   453 		)
   445                #(#MenuItem
   454 	       #(#MenuItem
   446                   #activeHelpKey: #fileSave
   455 		  #activeHelpKey: #fileSave
   447                   #label: 'Save'
   456 		  #label: 'Save'
   448                   #itemValue: #doSave
   457 		  #itemValue: #doSave
   449                   #translateLabel: true
   458 		  #translateLabel: true
   450                 )
   459 		)
   451                #(#MenuItem
   460 	       #(#MenuItem
   452                   #label: '-'
   461 		  #label: 'New'
   453                 )
   462 		  #itemValue: #doNew
   454                #(#MenuItem
   463 		  #translateLabel: true
   455                   #activeHelpKey: #fileExit
   464 		)
   456                   #label: 'Exit'
   465 	       #(#MenuItem
   457                   #itemValue: #closeRequest
   466 		  #label: '-'
   458                   #translateLabel: true
   467 		)
   459                 )
   468 	       #(#MenuItem
   460                )
   469 		  #activeHelpKey: #fileExit
   461               nil
   470 		  #label: 'Exit'
   462               nil
   471 		  #itemValue: #closeRequest
   463             )
   472 		  #translateLabel: true
   464           )
   473 		)
   465          #(#MenuItem
   474 	       )
   466             #label: 'Edit'
   475 	      nil
   467             #translateLabel: true
   476 	      nil
   468             #submenu: 
   477 	    )
   469            #(#Menu
   478 	  )
   470               #(
   479 	 #(#MenuItem
   471                #(#MenuItem
   480 	    #activeHelpKey: #history
   472                   #activeHelpKey: #deleteHelpTextKey
   481 	    #label: 'History'
   473                   #label: 'Delete'
   482 	    #translateLabel: true
   474                   #itemValue: #doDelete
   483 	    #submenuChannel: #menuHistory
   475                   #translateLabel: true
   484 	  )
   476                 )
   485 	 #(#MenuItem
   477                )
   486 	    #label: 'Edit'
   478               nil
   487 	    #translateLabel: true
   479               nil
   488 	    #submenuChannel: #keyItemMenu
   480             )
   489 	    #keepLinkedMenu: true
   481           )
   490 	  )
   482          #(#MenuItem
   491 	 #(#MenuItem
   483             #activeHelpKey: #help
   492 	    #activeHelpKey: #help
   484             #label: 'Help'
   493 	    #label: 'Help'
   485             #translateLabel: true
   494 	    #translateLabel: true
   486             #startGroup: #right
   495 	    #startGroup: #right
   487             #submenuChannel: #menuHelp
   496 	    #submenuChannel: #menuHelp
   488           )
   497 	  )
   489          )
   498 	 )
   490         nil
   499 	nil
   491         nil
   500 	nil
   492       )
   501       )
   493 ! !
   502 ! !
   494 
   503 
   495 !UIHelpTool methodsFor:'accessing'!
   504 !UIHelpTool methodsFor:'accessing'!
   496 
   505 
   497 dictionaries
       
   498     "returns the dictionary of the help dictionaries of the classes having help specs"
       
   499 
       
   500     ^dictionaries
       
   501 !
       
   502 
       
   503 dictionaries:aDictionaryOfDictionaries
       
   504     "sets a dictionary of the help dictionaries of the classes having help specs"
       
   505 
       
   506     (dictionaries := aDictionaryOfDictionaries) isNil ifTrue:[
       
   507         dictionaries := Dictionary new.
       
   508     ].
       
   509     self updateList.
       
   510 !
       
   511 
       
   512 dictionary
       
   513     "returns the dictionary of the selected class"
       
   514 
       
   515     ^dictionary
       
   516 !
       
   517 
       
   518 helpKey
   506 helpKey
   519     "returns the help key as symbol or nil
   507     "returns the helpKey as symbol or nil
   520     "
   508     "
   521     |value|
   509     |key|
   522 
   510 
   523     value := editModel value.
   511     key := editModel value.
   524 
   512 
   525     value notNil ifTrue:[
   513     key size ~~ 0 ifTrue:[
   526         value := value withoutSeparators.
   514 	key := key withoutSeparators.
   527         value notEmpty ifTrue:[ ^ value asSymbol ]
   515 	key notEmpty ifTrue:[ ^ key asSymbol ]
   528     ].
   516     ].
   529     ^ nil
   517     ^ nil
   530 !
   518 !
   531 
   519 
   532 helpKey:aKey
   520 helpKey:aKey
   533     "sets the help key into the selection channel in order to show the help text"
   521     "change the helpKey without any change notification (modifiedHolder).
   534 
   522     "
   535     |key|
   523     |key|
   536 
   524 
   537     aKey size ~~ 0 ifTrue:[
   525     self withoutModifyDo:[
   538         aKey isSymbol ifTrue:[
   526 	aKey size ~~ 0 ifTrue:[
   539             key := aKey
   527 	    key := aKey withoutSeparators.
   540         ] ifFalse:[
   528 	    key isEmpty ifTrue:[ key := nil ]
   541             key := aKey withoutSeparators.
   529 	] ifFalse:[
   542             key notEmpty ifTrue:[ key := key asSymbol ]
   530 	    key := nil
   543                         ifFalse:[ key := nil ].
   531 	].
   544         ]
   532 	editModel value:key.
   545     ] ifFalse:[
   533     ].
   546         key := nil
       
   547     ].
       
   548     editModel value:key.            
       
   549     self cancel.
   534     self cancel.
   550 !
   535 !
   551 
   536 
   552 modified
   537 modified
   553     "true if the helpSpec is modified, items are added, deleted or modified
   538     "true if any items are added, deleted or modified
   554     "
   539     "
   555     ^ modified
   540     classItemList do:[:aClassItem|
   556 !
   541 	aClassItem modified ifTrue:[^ true].
   557 
   542     ].
   558 modified: aBoolean
   543     ^ false
   559     "true if the helpSpec is modified, items are added, deleted or modified
   544 !
   560     "
   545 
   561     modified := aBoolean.
   546 modified:aBoolean
       
   547     "true if any items are added, deleted or modified
       
   548     "
       
   549     classItemList do:[:aClassItem| aClassItem modified:aBoolean ].
       
   550 !
       
   551 
       
   552 modifiedHolder
       
   553     "boolean holder which is set to true if the helpKey or contents changed
       
   554     "
       
   555     ^ modifiedHolder
   562 !
   556 !
   563 
   557 
   564 modifiedHolder:aValueHolder
   558 modifiedHolder:aValueHolder
   565     "sets the value holder to true in case of modifying attributes"
   559     "boolean holder which is set to true if the helpKey or contents changed
   566 
   560     "
   567     modifiedHolder notNil ifTrue:[
   561     modifiedHolder notNil ifTrue:[
   568         modifiedHolder removeDependent:self. 
   562 	modifiedHolder removeDependent:self. 
   569     ].
   563     ].
   570     modifiedHolder := aValueHolder.
   564     modifiedHolder := aValueHolder.
   571 
   565 
   572     modifiedHolder notNil ifTrue:[
   566     modifiedHolder notNil ifTrue:[
   573         modifiedHolder addDependent:self.
   567 	modifiedHolder addDependent:self.
   574     ]
   568     ].
   575 !
       
   576 
       
   577 setHelpKey:aKey
       
   578     "set the helpKey without notification
       
   579     "
       
   580     |model|
       
   581 
       
   582     model := modifiedHolder.
       
   583     modifiedHolder := nil.
       
   584     self helpKey:aKey.
       
   585     modifiedHolder := model.
       
   586 !
   569 !
   587 
   570 
   588 specClass
   571 specClass
   589     "returns the class on which the help tool works
   572     "returns the class on which the help tool works on
   590     "
   573     "
   591     ^ specClass
   574     ^ specClass
   592 !
   575 !
   593 
   576 
   594 specSelector
   577 specSelector
   597     ^ specSelector
   580     ^ specSelector
   598 ! !
   581 ! !
   599 
   582 
   600 !UIHelpTool methodsFor:'aspects'!
   583 !UIHelpTool methodsFor:'aspects'!
   601 
   584 
       
   585 classItemListHolder
       
   586     "returns the holder which keeps the class items
       
   587     "
       
   588     |holder|
       
   589 
       
   590     holder := builder bindingAt:#classItemListHolder.
       
   591 
       
   592     holder isNil ifTrue:[
       
   593 	holder := nil asValue.
       
   594 	holder value:classItemList.
       
   595 	builder aspectAt:#classItemListHolder put:holder.
       
   596     ].
       
   597     ^ holder
       
   598 !
       
   599 
       
   600 classItemModel
       
   601     "returns the holder which keeps the current selected class
       
   602     "
       
   603     ^ classItemModel
       
   604 !
       
   605 
   602 contentsModifiedChannel
   606 contentsModifiedChannel
   603     "returns the model which indicates whether the current helpText is modified
   607     "boolean holder, which is set to true if the contents assigned to the
       
   608      helpKey changed
   604     "
   609     "
   605     ^ contentsModifiedChannel
   610     ^ contentsModifiedChannel
   606 !
   611 !
   607 
   612 
   608 editModel
   613 editModel
   609     "returns the model which keeps the current editing key
   614     "string holder, which keeps the current editing helpKey as string
   610     "
   615     "
   611     ^ editModel
   616     ^ editModel.
   612 !
   617 !
   613 
   618 
   614 listOfClasses
   619 helpTextView
   615     "returns the list which keeps the classes
   620     "the editView which keeps the current help contents assigned to the key
   616     "
   621     "
   617     ^ listOfClasses
   622     ^ helpTextView
   618 !
   623 !
   619 
   624 
   620 listOfClassesModel
   625 keyItemListHolder
   621     "returns the model which keeps the current class selection
   626     "holder, which keeps the current hierarchical list
   622      or nil
   627      assigned to the selected class item
   623     "
   628     "
   624     ^ listOfClassesModel
   629     |holder|
   625 !
   630 
   626 
   631     holder := builder bindingAt:#keyItemListHolder.
   627 listOfKeys
   632 
   628     "returns the list which keeps the current keys
   633     holder isNil ifTrue:[
   629     "
   634 	holder := nil asValue.
   630     ^ listOfKeys
   635 	holder value:(classItemList last list).
   631 !
   636 	builder aspectAt:#keyItemListHolder put:holder.
   632 
   637     ].
   633 listOfKeysModel
   638     ^ holder
   634     "returns the model which keeps the current list selection
   639 !
   635      or nil
   640 
   636     "
   641 keyItemModel
   637     ^ listOfKeysModel
   642     "model which keeps the current selected helpKey or nil
       
   643     "
       
   644     ^ keyItemModel.
       
   645 !
       
   646 
       
   647 valueOfEnablingCommitButtons
       
   648     "returns the enabling of the commit of this tool as value holder
       
   649     "
       
   650     masterApplication notNil ifTrue:[
       
   651 	^ masterApplication valueOfEnablingCommitButtons
       
   652     ].
       
   653     ^ contentsModifiedChannel
   638 !
   654 !
   639 
   655 
   640 valueOfInfoLabel
   656 valueOfInfoLabel
   641 
   657     "returns the info label as value holder
       
   658     "
   642     masterApplication notNil ifTrue:[
   659     masterApplication notNil ifTrue:[
   643         ^ masterApplication valueOfInfoLabel
   660 	^ masterApplication valueOfInfoLabel
   644     ].
   661     ].
   645     ^ super valueOfInfoLabel
   662     ^ super valueOfInfoLabel
   646 ! !
   663 ! !
   647 
   664 
   648 !UIHelpTool methodsFor:'building'!
   665 !UIHelpTool methodsFor:'building'!
   649 
   666 
   650 buildAndMergeFromClass:aClass
   667 buildAndMergeFromClass:aClass
   651     "class and selector changed; merge old definitions
   668      "setup a new specClass, merge the current items into
   652      into definitions loaded from a class
   669      "
   653     "
   670      |root mergeItems|
   654     |saveDictionary saveHelpKey|
   671 
   655 
   672      root := classItemList first.
   656     saveDictionary := dictionary.
   673 
   657     saveHelpKey    := self helpKey.
   674      root isUnspecified ifTrue:[ mergeItems := root children ]
   658 
   675 		       ifFalse:[ mergeItems := nil ].
   659     self buildFromClass:aClass.
   676 
   660 
   677      self buildFromClass:aClass.
   661     saveDictionary notEmpty ifTrue:[
   678 
   662         dictionary declareAllFrom:saveDictionary.
   679      mergeItems size ~~ 0 ifTrue:[
   663         self updateList.
   680 	root := classItemList first.
   664     ].
   681 
   665     self helpKey:saveHelpKey.
   682 	mergeItems do:[:anItem| |item hkey|
   666     self modified:true.
   683 	    hkey := anItem helpKey.
       
   684 	    item := root detectItemWithKey:hkey.
       
   685 
       
   686 	    item isNil ifTrue:[
       
   687 		item := KeyItem helpKey:hkey helpText:(anItem helpText).
       
   688 		root add:item sortBlock:[:a :b| a label < b label ].
       
   689 	    ] ifFalse:[
       
   690 		item helpText:(anItem helpText).
       
   691 	    ]
       
   692 	]
       
   693     ].
   667 !
   694 !
   668 
   695 
   669 buildFromClass:aClass
   696 buildFromClass:aClass
   670     "reads the help dictionary from aClass and find remaining classes 
   697     "reads the help dictionary from aClass and find remaining classes 
   671      'between' aClass and ApplicationModel" 
   698      'between' aClass and ApplicationModel
   672 
   699     " 
   673     |list|
   700     |lastContents root list resource|
   674 
   701 
   675     modified  := false.
   702     specSelector isNil ifTrue:[ specSelector := #helpSpec ].
   676     specClass := self getHelpSpecClassFromClass:aClass.
   703     specClass := self getHelpSpecClassFromClass:aClass.
   677 
   704 
   678     specClass notNil ifTrue:[   
   705     list := OrderedCollection new.
   679         dictionary   := Dictionary new.
   706 
   680         dictionaries removeAll.
   707     (specClass isClass and:[specClass isLoaded]) ifTrue:[
   681     ].
   708 	lastContents := nil.
   682 
   709 	resource := specClass name, ' ', specSelector.
   683     (specClass isClass and:[specClass isLoaded]) ifFalse:[
   710 	self addToHistory:(Association key:resource value:#'loadFromMessage:').
   684         self updateList.
   711 
   685         ^ self
   712 	specClass withAllSuperclasses reverse do:[:aClass| |value name|
   686     ].
   713 	    lastContents isNil ifTrue:[
   687     (specClass class includesSelector:specSelector) ifFalse:[
   714 		aClass == ApplicationModel ifTrue:[ 
   688         dictionaries at:(specClass name) put:dictionary. 
   715 		    lastContents := IdentityDictionary new
   689     ].
   716 		].
   690     list := specClass withAllSuperclasses reverse collect:[:cls| cls name ].
   717 	    ] ifFalse:[
   691 
   718 		root := ClassItem onClass:aClass.
   692     (list includes: #ApplicationModel) ifTrue:[
   719 
   693         list := list asOrderedCollection.
   720 		(aClass class includesSelector:specSelector) ifTrue:[
   694         list removeAll:(ApplicationModel withAllSuperclasses collect:[:cls| cls name])
   721 		    value := aClass perform:specSelector.
   695     ].
   722 
   696     listOfClasses contents:list.
   723 		    value keysAndValuesDo:[:k :v| |cval|
   697     listOfClassesModel triggerValue:(specClass name).
   724 			cval := lastContents at:k ifAbsent:self.
       
   725 			cval = v ifFalse:[ root add:(KeyItem helpKey:k helpText:v) ].
       
   726 		    ].
       
   727 		    lastContents := value.
       
   728 		].
       
   729 		root sort:[:a :b| a label < b label ].
       
   730 		root modified:false.
       
   731 		list add:root.
       
   732 	    ]
       
   733 	]
       
   734     ].
       
   735     list isEmpty ifTrue:[
       
   736 	list add:(ClassItem onClass:nil)
       
   737     ].
       
   738 
       
   739     self withoutModifyDo:[
       
   740 	classItemList contents:list.
       
   741 	classItemModel value:(list last)
       
   742     ].
   698 !
   743 !
   699 
   744 
   700 buildFromClass: aClass andSelector: aSelector
   745 buildFromClass: aClass andSelector: aSelector
   701     "sets aSelector and reads the help dictionary from aClass"
   746     "sets aSelector and reads the help dictionary from aClass
   702 
   747     "
   703     specSelector := aSelector.
   748     specSelector := aSelector.
   704     self buildFromClass:aClass
   749     self buildFromClass:aClass
   705 
       
   706 !
   750 !
   707 
   751 
   708 buildFromHelpTool:aHelpTool
   752 buildFromHelpTool:aHelpTool
   709 
   753     "build from another helpTool
   710     self doNew.
   754     "
   711 
   755     specClass     := aHelpTool specClass.
   712     dictionaries := aHelpTool dictionaries.
   756     specSelector  := aHelpTool specSelector.
   713     dictionary   := aHelpTool dictionary.
   757     classItemList := aHelpTool classItemListHolder value.
   714 
   758 
   715     specSelector := aHelpTool specSelector.
   759     self classItemListHolder value:classItemList.
   716     specClass    := aHelpTool specClass.
   760 
   717 
   761     classItemModel triggerValue:(classItemList last).
   718     listOfClasses contents:(aHelpTool listOfClasses).
       
   719     listOfClassesModel triggerValue:(listOfClasses at:1 ifAbsent:nil).
       
   720 ! !
   762 ! !
   721 
   763 
   722 !UIHelpTool methodsFor:'change & update'!
   764 !UIHelpTool methodsFor:'change & update'!
   723 
   765 
   724 editModelChanged
   766 editModelChanged
   725     "called if the edit model changed
   767     "called if the editModel changed
   726     "
   768     "
   727     |key|
   769     |key|
   728 
   770 
   729     key := self helpKey.
   771     key := self helpKey.
   730     modifiedHolder notNil ifTrue:[ modifiedHolder value:true ].
   772 
   731 
   773     modifiedHolder notNil ifTrue:[
   732     (key notNil and:[(dictionary at:key ifAbsent:nil) isNil]) ifTrue:[
   774 	modifiedHolder value:true
   733         listOfClasses do:[:name| |dir|
   775     ].
   734             dir := self dictionaryForClassNamed:name.
   776 
   735 
   777     contentsModifiedChannel value:false.
   736             (dir includesKey:key) ifTrue:[
       
   737                 "/ setup new class
       
   738                 listOfKeysModel setValue:key.
       
   739                 listOfClassesModel value:name.
       
   740                 ^ self
       
   741             ].
       
   742         ].
       
   743         key := nil.
       
   744     ].
       
   745     listOfKeysModel value:key.
       
   746 !
       
   747 
       
   748 listOfClassesModelChanged
       
   749     "called if the class selection changed
       
   750     "
       
   751     |clsName|
       
   752 
       
   753     clsName := listOfClassesModel value.
       
   754     clsName isNil ifTrue:[^ self].
       
   755 
       
   756     dictionary := self dictionaryForClassNamed:clsName.
       
   757     self updateList.
       
   758 !
       
   759 
       
   760 listOfKeysModelChanged
       
   761     "called if the selection of the key list changed
       
   762     "
       
   763     |key txt|
       
   764 
       
   765     key := listOfKeysModel value.
       
   766 
   778 
   767     key notNil ifTrue:[
   779     key notNil ifTrue:[
   768         key := key asSymbol.
   780 	keyItemModel value = key ifTrue:[^ self].
   769         txt := dictionary at:key ifAbsent:nil.
   781 
   770 
   782 	classItemList reverseDo:[:root| |item|
   771         txt isNil ifTrue:[
   783 	    item := root detectItemWithKey:key.
   772             listOfKeysModel value:nil.
   784 
   773             ^ self
   785 	    item notNil ifTrue:[
   774         ].
   786 		classItemModel value:root.
   775         editModel value ~= key ifTrue:[
   787 		keyItemModel   value:item.
   776             editModel value:key withoutNotifying:self.
   788 		^ self.
   777             modifiedHolder notNil ifTrue:[ modifiedHolder value:true ].
   789 	    ].
   778         ].
   790 	].
   779     ].
   791 
   780 
   792 	masterApplication isNil ifTrue:[
   781     contentsModifiedChannel value ifFalse:[
   793 	    "entered a new helpKey
   782         self cancel
   794 	    "
   783     ].
   795 	    self valueOfEnablingCommitButtons value:true.
       
   796 	].
       
   797     ].
       
   798     keyItemModel value:nil.
   784 !
   799 !
   785 
   800 
   786 update:something with:aParameter from:changedObject
   801 update:something with:aParameter from:changedObject
   787     "Invoked when an object that I depend upon sends a change notification."
   802     "Invoked when an object that I depend upon sends a change notification.
   788 
   803     "
   789     editModel == changedObject ifTrue:[
   804     |root item list|
   790         self editModelChanged.
   805 
       
   806     changedObject == keyItemModel ifTrue:[
       
   807 	item := keyItemModel value.
       
   808 
       
   809 	item notNil ifTrue:[
       
   810 	    editModel value:(item helpKey).
       
   811 	].
       
   812 	self cancel.
       
   813 	^ self
       
   814     ].
       
   815 
       
   816     changedObject == classItemModel ifTrue:[
       
   817 	root := classItemModel value.
       
   818 
       
   819 	root notNil ifTrue:[
       
   820 	    item := root detectItemWithKey:(self helpKey).
       
   821 	    list := root list.
       
   822 	] ifFalse:[
       
   823 	    list := item := nil.
       
   824 	].
       
   825 
       
   826 	item notNil ifTrue:[
       
   827 	    keyItemModel value:nil withoutNotifying:self.
       
   828 	].
       
   829 	self keyItemListHolder value:list.
       
   830 	keyItemModel value:item.
       
   831 	^ self
       
   832     ].
       
   833 
       
   834     changedObject == editModel ifTrue:[
       
   835 	self editModelChanged.
       
   836 	^ self
       
   837     ].
       
   838 
       
   839     changedObject == contentsModifiedChannel ifTrue:[
       
   840 	modifiedHolder notNil ifTrue:[
       
   841 	    modifiedHolder value:true
       
   842 	].
       
   843 	^ self
       
   844     ].
       
   845     super update:something with:aParameter from:changedObject
       
   846 !
       
   847 
       
   848 withoutModifyDo:aBlock
       
   849     "discard modifications; trigger not the modifiedHolder during
       
   850      the action is active.
       
   851     "
       
   852     |holder|
       
   853 
       
   854     holder := modifiedHolder.
       
   855 
       
   856     holder isNil ifTrue:[
       
   857 	^ aBlock value
       
   858     ].
       
   859     ^ aBlock valueNowOrOnUnwindDo:[ modifiedHolder := holder ]
       
   860 ! !
       
   861 
       
   862 !UIHelpTool methodsFor:'private'!
       
   863 
       
   864 askForModification
       
   865     "asks for modification; launch a dialog if something is modified;
       
   866      returns true if the modifications are accepted by user otherwise
       
   867      false.
       
   868     "
       
   869     |dialog|
       
   870 
       
   871     self modified ifTrue:[
       
   872 	dialog := YesNoBox title:(resources string:'List was modified !!')
       
   873 			 yesText:(resources string:'Forget it and proceed')
       
   874 			  noText:(resources string:'Cancel').
       
   875 
       
   876 	dialog showAtPointer.
       
   877 	dialog accepted ifFalse:[^ false].
       
   878 	self modified:false.
       
   879     ].
       
   880     ^ true
       
   881 !
       
   882 
       
   883 extractResourceFrom:aString
       
   884     "extracts class and selector from a resource string. On success
       
   885      an association with the key a class and the selector as value
       
   886      is returned. Otherwise nil is returned
       
   887     "
       
   888     |words newClass newSel|
       
   889 
       
   890     aString size ~~ 0 ifTrue:[
       
   891 	words := aString asCollectionOfWords.
       
   892 
       
   893 	words size == 2 ifTrue:[
       
   894 	    newClass := self resolveName:(words first).
       
   895 
       
   896 	    (newClass isClass and:[newClass isLoaded]) ifTrue:[
       
   897 		newSel := words last asSymbol.
       
   898 
       
   899 		(newClass class includesSelector:newSel) ifTrue:[
       
   900 		    ^ Association key:newClass value:newSel            
       
   901 		].
       
   902 	    ].
       
   903 	].
       
   904     ].
       
   905     ^ nil
       
   906 !
       
   907 
       
   908 getHelpSpecClassFromClass:aClass
       
   909     "oops
       
   910     "
       
   911     |cls|
       
   912 
       
   913     aClass notNil ifTrue:[
       
   914 	cls := self resolveName:aClass.
       
   915 
       
   916 	cls notNil ifTrue:[
       
   917 	    cls := cls perform:#helpSpecClass ifNotUnderstood:cls.
       
   918 
       
   919 	    (cls isClass and:[cls isLoaded]) ifTrue:[
       
   920 		^ cls
       
   921 	    ].
       
   922 	].
       
   923     ].
       
   924     ^ nil
       
   925 !
       
   926 
       
   927 loadFromMessage:aString
       
   928     "Set and rebuild the specClass and specSelector from a resource string.
       
   929      On success true is returned otherwise false. If the current spec is
       
   930      modified, a dialog is launched.
       
   931     "
       
   932     |association|
       
   933 
       
   934     association := self extractResourceFrom:aString.
       
   935 
       
   936     association notNil ifTrue:[
       
   937 	self askForModification ifTrue:[
       
   938 	    self buildFromClass:(association key) andSelector:(association value).
       
   939 	    ^ true
       
   940 	].
       
   941     ].
       
   942     ^ false
       
   943 !
       
   944 
       
   945 resourceMessage:aString
       
   946     "Set the specClass and specSelector from a resource string. On
       
   947      success true is returned otherwise false.
       
   948     "
       
   949     |association|
       
   950 
       
   951     association := self extractResourceFrom:aString.
       
   952 
       
   953     association notNil ifTrue:[
       
   954 	specClass    := association key.
       
   955 	specSelector := association value.
       
   956 	^ true
       
   957     ].
       
   958     ^ false
       
   959 ! !
       
   960 
       
   961 !UIHelpTool methodsFor:'startup & release'!
       
   962 
       
   963 closeRequest
       
   964     "asks for permission before closing
       
   965     "
       
   966     (masterApplication isNil and:[self askForModification]) ifTrue:[
       
   967 	super closeRequest.
       
   968     ].
       
   969 !
       
   970 
       
   971 initialize
       
   972     "setup default attributes
       
   973     "
       
   974     super initialize.
       
   975     self createBuilder.
       
   976 
       
   977     specSelector   := #helpSpec.
       
   978 
       
   979     classItemList  := List new.
       
   980 
       
   981     classItemModel := nil asValue.
       
   982     classItemModel addDependent:self.
       
   983 
       
   984     keyItemModel := nil asValue.
       
   985     keyItemModel addDependent:self.
       
   986 
       
   987     contentsModifiedChannel := false asValue.
       
   988     contentsModifiedChannel addDependent:self.
       
   989 
       
   990     helpTextView := EditTextView new.
       
   991     helpTextView acceptAction:[:dummy| self accept ].
       
   992     helpTextView modifiedChannel:contentsModifiedChannel.
       
   993 
       
   994     editModel := nil asValue.
       
   995     editModel addDependent:self.
       
   996 
       
   997     self buildFromClass:nil.
       
   998 !
       
   999 
       
  1000 openInterface:aSymbol
       
  1001     "do not open as stand alone
       
  1002     "
       
  1003 !
       
  1004 
       
  1005 openOnClass:aClass
       
  1006     "opens the UIHelpTool on aClass
       
  1007     "
       
  1008     self openOnClass:aClass andSelector:nil
       
  1009 !
       
  1010 
       
  1011 openOnClass:aClass andSelector: aSelector
       
  1012     "opens the UIHelpTool on aClass and aSelector"
       
  1013 
       
  1014     super openInterface:#windowSpecForStandAlone.
       
  1015 
       
  1016     builder window label: 'Help Tool'.
       
  1017     self buildFromClass:aClass andSelector:aSelector
       
  1018 ! !
       
  1019 
       
  1020 !UIHelpTool methodsFor:'user actions'!
       
  1021 
       
  1022 accept
       
  1023     "accepts the help text
       
  1024     "
       
  1025     |helpKey helpItem root|
       
  1026 
       
  1027     helpKey := self helpKey.
       
  1028     helpKey isNil ifTrue:[^ self].
       
  1029 
       
  1030     root := classItemModel value.
       
  1031     root isNil ifTrue:[^ self].
       
  1032 
       
  1033     helpItem := root detectItemWithKey:helpKey.
       
  1034 
       
  1035     helpItem isNil ifTrue:[
       
  1036 	helpItem := KeyItem helpKey:helpKey helpText:(helpTextView contents).
       
  1037 	root add:helpItem sortBlock:[:a :b| a label < b label ].
       
  1038     ] ifFalse:[
       
  1039 	helpItem helpText:(helpTextView contents).
       
  1040     ].
       
  1041 
       
  1042     contentsModifiedChannel value:false.
       
  1043     keyItemModel triggerValue:helpItem.
       
  1044 !
       
  1045 
       
  1046 cancel
       
  1047     "cancel modifications, reload helpText
       
  1048     "
       
  1049     |item contents modified|
       
  1050 
       
  1051     item := keyItemModel value.
       
  1052     modified := false.
       
  1053 
       
  1054     item notNil ifTrue:[
       
  1055 	contents := item helpText.
       
  1056     ] ifFalse:[
       
  1057 	contents := nil.
       
  1058 
       
  1059 	modifiedHolder isNil ifTrue:[
       
  1060 	    modified := self helpKey notNil
       
  1061 	]
       
  1062     ].
       
  1063     helpTextView contents:contents.
       
  1064     contentsModifiedChannel value:modified.
       
  1065 !
       
  1066 
       
  1067 doDelete
       
  1068     "deletes the selected help key
       
  1069     "
       
  1070     |item|
       
  1071 
       
  1072     item := keyItemModel value.
       
  1073     item notNil ifTrue:[ item remove ].    
       
  1074     editModel value:nil.
       
  1075 !
       
  1076 
       
  1077 doLoad
       
  1078     "opens a Resource Selection Browser in order to get a resource message
       
  1079     "
       
  1080     self loadFromMessage: 
       
  1081 	(ResourceSelectionBrowser
       
  1082 	    request: 'Load Help Spec From Class'
       
  1083 	    onSuperclass: nil
       
  1084 	    andClass: specClass
       
  1085 	    andSelector: specSelector ? #help
       
  1086 	    withResourceTypes: (Array with: #help)).
       
  1087 
       
  1088     self updateInfoLabel
       
  1089 !
       
  1090 
       
  1091 doNew
       
  1092     "reset all to empty
       
  1093     "
       
  1094     contentsModifiedChannel value:false.
       
  1095     self helpKey:nil.
       
  1096     self buildFromClass:nil.
       
  1097 !
       
  1098 
       
  1099 doSave
       
  1100     "save the help spec to the spec-class(es)
       
  1101     "
       
  1102     specClass isNil ifTrue:[
       
  1103         self information:(resources string:'No class specified !!').
       
  1104         ^ nil
       
  1105     ].
       
  1106     (specClass isSubclassOf:ApplicationModel) ifFalse:[
       
  1107         self information:(resources string:'Cannot save help into none Application class').
       
  1108         ^ nil
       
  1109     ].
       
  1110 
       
  1111     classItemList do:[:aClassItem| aClassItem createHelpMethodNamed:specSelector ].
       
  1112 !
       
  1113 
       
  1114 openDocumentation
       
  1115     "opens the documentation file of the Help Tool
       
  1116     "
       
  1117     self openHTMLDocument: 'tools/uipainter/HelpTool.html'
       
  1118 ! !
       
  1119 
       
  1120 !UIHelpTool::ClassItem class methodsFor:'instance creation'!
       
  1121 
       
  1122 onClass:aClass
       
  1123     |root|
       
  1124 
       
  1125     root := self new.
       
  1126     root onClass:aClass.
       
  1127     ^ root
       
  1128 ! !
       
  1129 
       
  1130 !UIHelpTool::ClassItem methodsFor:'accessing'!
       
  1131 
       
  1132 list
       
  1133     "returns the hierarchical list assigned to the classItem; the
       
  1134      list contains the keyItems
       
  1135     "
       
  1136     list isNil ifTrue:[
       
  1137 	list := HierarchicalList new.
       
  1138 	list showRoot:false.
       
  1139 	list root:self.
       
  1140     ].
       
  1141     ^ list
       
  1142 !
       
  1143 
       
  1144 theClass
       
  1145     "returns the class or nil if unspecified
       
  1146     "
       
  1147     ^ theClass
       
  1148 ! !
       
  1149 
       
  1150 !UIHelpTool::ClassItem methodsFor:'change & update'!
       
  1151 
       
  1152 helpTextChangedFor:anItem
       
  1153     "called if an helpKey changed its contents
       
  1154     "
       
  1155     self model notNil ifTrue:[
       
  1156 	self   modified:true.
       
  1157 	anItem modified:true.
       
  1158     ].
       
  1159 ! !
       
  1160 
       
  1161 !UIHelpTool::ClassItem methodsFor:'code generation'!
       
  1162 
       
  1163 createHelpMethodNamed:aMethodName
       
  1164     |stream|
       
  1165 
       
  1166     (modified and:[theClass notNil]) ifFalse:[
   791         ^ self
  1167         ^ self
   792     ].
  1168     ].
   793 
  1169     stream := '' writeStream.
   794     listOfKeysModel == changedObject ifTrue:[
  1170 
   795         self listOfKeysModelChanged.
  1171     stream nextPutAll:
   796         ^ self
  1172         aMethodName, '\' withCRs,
   797     ].
  1173         (ResourceSpecEditor codeGenerationCommentForClass:UIHelpTool) withCRs,
   798 
       
   799     listOfClassesModel == changedObject ifTrue:[
       
   800         self listOfClassesModelChanged.
       
   801         ^ self
       
   802     ].
       
   803 
       
   804     contentsModifiedChannel == changedObject ifTrue:[
       
   805         contentsModifiedChannel value ifTrue:[
       
   806             modifiedHolder notNil ifTrue:[modifiedHolder value:true].
       
   807         ].
       
   808         ^ self
       
   809     ].
       
   810 
       
   811     super update:something with:aParameter from:changedObject
       
   812 ! !
       
   813 
       
   814 !UIHelpTool methodsFor:'help'!
       
   815 
       
   816 openDocumentation
       
   817     "opens the documentation file of the Help Tool"
       
   818 
       
   819     self openHTMLDocument: 'tools/uipainter/HelpTool.html'
       
   820 ! !
       
   821 
       
   822 !UIHelpTool methodsFor:'private'!
       
   823 
       
   824 askForModification
       
   825     "asks for modification"
       
   826 
       
   827     modified ifTrue:[
       
   828         ( (YesNoBox title: 'List was modified!!')        
       
   829                    noText:'Cancel';
       
   830                   yesText:'Waste it and proceed';
       
   831             showAtPointer;
       
   832             accepted
       
   833         ) ifFalse:[
       
   834             ^ false
       
   835         ].
       
   836         modified := false
       
   837     ].
       
   838     ^ true
       
   839 !
       
   840 
       
   841 dictionaryForClassNamed:clsName
       
   842     "returns the directory assigned to a class name
       
   843     "
       
   844     ^ dictionaries at:clsName
       
   845           ifAbsentPut:[ self extractHelpSpecForClass: (Smalltalk at:clsName) ].
       
   846 !
       
   847 
       
   848 extractHelpSpecForClass: aClass
       
   849     "extracts the help dictionary of aClass, it current and return it"
       
   850 
       
   851     |helpSpecSuperClass superHelpSpecKeys helpSpec|
       
   852 
       
   853     helpSpec := Dictionary new.
       
   854 
       
   855     ((aClass class includesSelector: specSelector)
       
   856     and: [(helpSpecSuperClass := aClass allSuperclasses detect: [:cls| cls class includesSelector: specSelector] ifNone: nil) notNil])
       
   857     ifTrue:[                  
       
   858         superHelpSpecKeys := (helpSpecSuperClass perform:specSelector) keys.
       
   859 
       
   860         (aClass perform:specSelector) keysAndValuesDo:[:key :value |
       
   861             (superHelpSpecKeys includes:key) ifFalse: [
       
   862                 helpSpec at:key put:value
       
   863             ]
       
   864         ].          
       
   865     ].
       
   866     ^ helpSpec 
       
   867 !
       
   868 
       
   869 getHelpSpecClassFromClass:aClass
       
   870     "returns application class keeping the associated help text or nil"
       
   871 
       
   872     |cls|
       
   873 
       
   874     ((cls := self resolveName:aClass) notNil and:[cls respondsTo: #helpSpecClass]) ifTrue:[
       
   875         ^cls helpSpecClass
       
   876     ].
       
   877     ^cls
       
   878 
       
   879 
       
   880 !
       
   881 
       
   882 getUnformattedHelpText: aHelpText
       
   883     "unformats aHelpText and returns it"
       
   884 
       
   885     |helpText|
       
   886 
       
   887     helpText := aHelpText asString copyReplaceAll:(Character cr) with:(Character space).
       
   888     (helpText endsWith:(Character space)) ifTrue:[
       
   889         helpText := helpText copyWithoutLast:1
       
   890     ].
       
   891     ^ helpText
       
   892 
       
   893     "Modified: / 20.7.1998 / 13:17:52 / cg"
       
   894 !
       
   895 
       
   896 installHelpSpecOnClass:aClass
       
   897     "saves the help dicts in aClass which is subclass of ApplicationModel"
       
   898 
       
   899     |cls src helpSpec|
       
   900 
       
   901     cls := self getHelpSpecClassFromClass: aClass.
       
   902 
       
   903     cls isNil ifTrue:[
       
   904         self information:'No application class defined!!'.
       
   905         ^nil
       
   906     ].
       
   907 
       
   908     (cls isSubclassOf: ApplicationModel) ifFalse:[
       
   909         self information: 'Cannot save help spec into class ', cls name asBoldText, ',\because it is not a subclass of ApplicationModel!!' withCRs.
       
   910         ^nil
       
   911     ].
       
   912 
       
   913     helpSpec := dictionaries 
       
   914         at: cls name 
       
   915         ifAbsent: [specClass notNil 
       
   916             ifTrue:  [dictionaries at: aClass put: (self extractHelpSpecForClass: (Smalltalk at: aClass))]
       
   917             ifFalse: [dictionary size > 0 ifTrue: [dictionary] ifFalse: [Dictionary new]]].
       
   918 
       
   919     helpSpec associationsDo:
       
   920     [:h|
       
   921         helpSpec at: h key put: (self getUnformattedHelpText: h value)
       
   922     ].
       
   923 
       
   924     (cls class includesSelector: specSelector) 
       
   925     ifTrue: 
       
   926     [
       
   927         |superclassHelpKeys implementedHelpSpec hasChanged|
       
   928         implementedHelpSpec := Dictionary new.
       
   929         superclassHelpKeys := (cls superclass respondsTo: specSelector)
       
   930             ifTrue:  [(cls superclass perform:specSelector) keys]
       
   931             ifFalse: [Array new].
       
   932 
       
   933         (cls perform:specSelector) associationsDo: [:h| (superclassHelpKeys includes: h key) 
       
   934             ifFalse: [implementedHelpSpec at: h key put: h value]].
       
   935 
       
   936         hasChanged := false.
       
   937         implementedHelpSpec associationsDo: [:h| (helpSpec            includesAssociation: h) ifFalse: [hasChanged := true]].
       
   938         helpSpec            associationsDo: [:h| (implementedHelpSpec includesAssociation: h) ifFalse: [hasChanged := true]].
       
   939 
       
   940         (implementedHelpSpec notEmpty and: [hasChanged and:
       
   941         [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 ']])
       
   942         ifTrue:
       
   943         [      
       
   944              implementedHelpSpec associationsDo: [:h| (helpSpec includesKey: h key) 
       
   945                 ifFalse: [helpSpec at: h key put: h value]].
       
   946         ]
       
   947     ].
       
   948 
       
   949     helpSpec isEmpty ifTrue:[
       
   950         ^(cls superclass respondsTo: specSelector) ifTrue: [cls class removeSelector: specSelector].
       
   951     ].
       
   952 
       
   953     src  := '' writeStream.
       
   954 
       
   955     src nextPutAll:
       
   956         specSelector, '\' withCRs,
       
   957         (ResourceSpecEditor codeGenerationCommentForClass: UIHelpTool) withCRs,
       
   958     '\\' withCRs,
  1174     '\\' withCRs,
   959     '    "\' withCRs,
  1175     '    "\' withCRs,
   960     '     UIHelpTool openOnClass:', cls name asString ,'    
  1176     '     UIHelpTool openOnClass:', theClass name asString ,'    
   961     "
  1177     "
   962 
  1178 
   963     <resource: #help>
  1179     <resource: #help>
   964 
  1180 
   965     ^super ', specSelector, ' addPairsFrom:#(
  1181     ^ super ', aMethodName, ' addPairsFrom:#(
   966 
  1182 
   967 '.
  1183 '.
   968 
  1184 
   969     helpSpec keys asSortedCollection do:
  1185     self do:[:aKeyItem| |helpText|
   970     [:key|
  1186         helpText := aKeyItem helpText.
   971         src nextPutLine: key storeString.
  1187         helpText isNil ifTrue:[ helpText := '' ].
   972         src nextPutLine: (helpSpec at: key) storeString; cr.
  1188 
   973     ].
  1189         stream nextPutLine:(aKeyItem helpKey storeString).
   974     src nextPutLine:')'.
  1190         stream nextPutLine:(helpText storeString); cr.
       
  1191     ].
       
  1192     stream nextPutLine:')'.
   975 
  1193 
   976     Compiler 
  1194     Compiler 
   977         compile:(src contents)
  1195         compile:(stream contents)
   978         forClass:cls class 
  1196         forClass:theClass class 
   979         inCategory:'help specs'.
  1197         inCategory:'help specs'.
   980 !
  1198 
   981 
  1199     self modified:false.
   982 installHelpSpecsOnClass:aClass
  1200 ! !
   983     "saves the help dicts on aClass and its superclasses which are subclasses of ApplicationModel"
  1201 
   984 
  1202 !UIHelpTool::ClassItem methodsFor:'displaying'!
   985     |cls helpSpecClasses|
  1203 
   986 
  1204 icon
   987     cls := self getHelpSpecClassFromClass:aClass.
  1205     "returns the display icon (always nil)
   988 
  1206     "
   989     cls isNil ifTrue: [
  1207     ^ nil
   990         self information:'No application class defined!!'.
  1208 !
   991         ^ self  
  1209 
   992     ].
  1210 label
   993 
  1211     "returns the display label
   994     modified ifFalse:[
  1212     "
   995         masterApplication isNil ifTrue: [self information:'Nothing was modified!!'].
  1213     |label|
   996         ^ self
  1214 
   997     ].
  1215     theClass notNil ifTrue:[ label := theClass name ]
   998     helpSpecClasses := listOfClasses copy.
  1216 		   ifFalse:[ label := '** not yet defined **' ].
   999 
  1217 
  1000     helpSpecClasses notEmpty ifTrue:[
  1218     modified ifTrue:[
  1001         (helpSpecClasses includes: cls name) ifFalse: [helpSpecClasses add: cls name].
  1219 	label := Text string:label color:(Color red).
  1002 
  1220     ].
  1003         helpSpecClasses do:[:clsName|
  1221     ^ label
  1004             (self installHelpSpecOnClass: clsName) isNil ifTrue:[
  1222 ! !
  1005                 modified := false.
  1223 
  1006                 ^ self
  1224 !UIHelpTool::ClassItem methodsFor:'instance creation'!
  1007             ]
  1225 
  1008         ].
  1226 initialize
  1009     ]
  1227     "setup defaults
  1010     ifFalse:
  1228     "
  1011     [      
  1229     super initialize.
  1012         self installHelpSpecOnClass: cls
  1230 
  1013     ].
  1231     children   := OrderedCollection new.
  1014 
  1232     isExpanded := true.
       
  1233     modified   := false.
       
  1234 !
       
  1235 
       
  1236 onClass:aClass
       
  1237     "the class the ys are assigned to; if the class is nil,
       
  1238      the class is not yet specified.
       
  1239     "
       
  1240     theClass := aClass.
       
  1241 ! !
       
  1242 
       
  1243 !UIHelpTool::ClassItem methodsFor:'private'!
       
  1244 
       
  1245 basicAdd:aChild sortBlock:aBlock
       
  1246     "catch low-level add to update the modification flag
       
  1247     "
       
  1248     self   modified:true.
       
  1249     aChild modified:true.
       
  1250 
       
  1251     ^ super basicAdd:aChild sortBlock:aBlock.
       
  1252 !
       
  1253 
       
  1254 basicAddAll:aList beforeIndex:anIndex
       
  1255     "catch low-level add to update the modification flag
       
  1256     "
       
  1257     self modified:true.
       
  1258 
       
  1259     aList do:[:el| el modified:true ].
       
  1260     ^ super basicAddAll:aList beforeIndex:anIndex.
       
  1261 !
       
  1262 
       
  1263 basicRemoveFromIndex:startIndex toIndex:stopIndex
       
  1264     "catch low-level remove to update the modification flag
       
  1265     "
       
  1266     self isUnspecified ifFalse:[
       
  1267 	self modified:true.
       
  1268     ].
       
  1269     ^ super basicRemoveFromIndex:startIndex toIndex:stopIndex
       
  1270 ! !
       
  1271 
       
  1272 !UIHelpTool::ClassItem methodsFor:'queries'!
       
  1273 
       
  1274 isUnspecified
       
  1275     "true if the class is unspecified
       
  1276     "
       
  1277     ^ theClass isNil
       
  1278 !
       
  1279 
       
  1280 modified
       
  1281     "true, if any item is modified, created or deleted
       
  1282     "
       
  1283     ^ modified
       
  1284 !
       
  1285 
       
  1286 modified:aBoolean
       
  1287     "true, if any item is modified, created or deleted
       
  1288     "
       
  1289     modified ~~ aBoolean ifTrue:[
       
  1290 	modified := aBoolean.
       
  1291 
       
  1292 	modified ifFalse:[
       
  1293 	    self do:[:el| el modified:false ].
       
  1294 	].
       
  1295     ].
       
  1296 ! !
       
  1297 
       
  1298 !UIHelpTool::ClassItem methodsFor:'searching'!
       
  1299 
       
  1300 detectItemWithKey:aKey
       
  1301     "returns the item assigned to a helpKey or nil
       
  1302     "
       
  1303     |key|
       
  1304 
       
  1305     aKey size ~~ 0 ifTrue:[
       
  1306 	key := aKey asSymbol.
       
  1307 
       
  1308 	self do:[:anItem|
       
  1309 	    anItem helpKey == key ifTrue:[ ^ anItem ].
       
  1310 	]
       
  1311     ].
       
  1312     ^ nil
       
  1313 ! !
       
  1314 
       
  1315 !UIHelpTool::KeyItem class methodsFor:'instance creation'!
       
  1316 
       
  1317 helpKey:aKey helpText:aText
       
  1318     |key|
       
  1319 
       
  1320     key := self new.
       
  1321     key helpKey:aKey helpText:aText.
       
  1322     ^ key
       
  1323 ! !
       
  1324 
       
  1325 !UIHelpTool::KeyItem methodsFor:'accessing'!
       
  1326 
       
  1327 helpKey
       
  1328     "returns the helpKey, a symbol
       
  1329     "
       
  1330     ^ helpKey
       
  1331 !
       
  1332 
       
  1333 helpText
       
  1334     "returns the contents assigned to the helpKey or nil
       
  1335     "
       
  1336     ^ helpText
       
  1337 !
       
  1338 
       
  1339 helpText:aText
       
  1340     "set the contents assigned to the helpKey; if the cxontents changed,
       
  1341      a notification is raised.
       
  1342     "
       
  1343     |text|
       
  1344 
       
  1345     text := self formatText:aText.
       
  1346 
       
  1347     text ~= helpText ifTrue:[
       
  1348 	helpText := text.
       
  1349 
       
  1350 	(modified or:[parent isNil]) ifFalse:[
       
  1351 	    parent helpTextChangedFor:self.
       
  1352 	]
       
  1353     ].
       
  1354 ! !
       
  1355 
       
  1356 !UIHelpTool::KeyItem methodsFor:'displaying'!
       
  1357 
       
  1358 icon
       
  1359     "returns the display icon (always nil)
       
  1360     "
       
  1361     ^ nil
       
  1362 !
       
  1363 
       
  1364 label
       
  1365     "returns the display label
       
  1366     "
       
  1367     modified ifTrue:[
       
  1368 	^ Text string:helpKey color:(Color red)
       
  1369     ].
       
  1370     ^ helpKey
       
  1371 ! !
       
  1372 
       
  1373 !UIHelpTool::KeyItem methodsFor:'instance creation'!
       
  1374 
       
  1375 helpKey:aKey helpText:aText
       
  1376     "set the key and contents without a change notification
       
  1377     "
       
  1378     helpKey  := aKey asSymbol.
       
  1379     helpText := self formatText:aText.
       
  1380 !
       
  1381 
       
  1382 initialize
       
  1383     "setup defaults
       
  1384     "
       
  1385     super initialize.
       
  1386     children := #().
  1015     modified := false.
  1387     modified := false.
  1016 !
  1388 ! !
  1017 
  1389 
  1018 resourceMessage: aString
  1390 !UIHelpTool::KeyItem methodsFor:'private'!
  1019     "extracts from aString the specClass and the specSelector"
  1391 
  1020 
  1392 formatText:aText
  1021     (aString notNil and: [self askForModification]) 
  1393     "format the text, replace carriage return by spaces and compress spaces
  1022     ifTrue:
  1394     "
  1023     [            
  1395     |text result|
  1024         |msg cls sel|
  1396 
  1025         msg := aString asCollectionOfWords.
  1397     aText size ~~ 0 ifTrue:[
  1026         (msg size == 2 and:
  1398 	text := aText asString asCollectionOfWords.
  1027         [(cls := self resolveName:(msg at:1)) notNil])
  1399 
  1028         ifTrue:
  1400 	text notEmpty ifTrue:[
  1029         [
  1401 	    result := text first.
  1030             specClass := cls name.
  1402 
  1031             specSelector := (msg at: 2) asSymbol.
  1403 	    text from:2 do:[:t| result := result, ' ', t ].
  1032             ^true
  1404 	    ^ result
  1033         ]
  1405        ].
  1034     ].
  1406     ].
  1035     ^false
  1407     ^ nil
  1036 
  1408 ! !
  1037 !
  1409 
  1038 
  1410 !UIHelpTool::KeyItem methodsFor:'queries'!
  1039 updateList
  1411 
  1040     "updates the list of keys
  1412 modified
  1041     "
  1413     "returns true if the helpText is modified
  1042     |key|
  1414     "
  1043 
  1415     ^ modified
  1044     listOfKeysModel setValue:nil.
  1416 !
  1045     listOfKeys contents:(dictionary keys asSortedCollection).
  1417 
  1046 
  1418 modified:aBoolean
  1047     key := self helpKey.
  1419     "set the modification flag
  1048 
  1420     "
  1049     (key notNil and:[listOfKeys includes:key]) ifFalse:[
  1421     aBoolean == modified ifFalse:[
  1050         key := nil.
  1422 	modified := aBoolean.
  1051     ].
  1423 	self changed:#redraw.
  1052     listOfKeysModel triggerValue:key
  1424     ].
  1053 ! !
       
  1054 
       
  1055 !UIHelpTool methodsFor:'startup / release'!
       
  1056 
       
  1057 closeRequest
       
  1058     "asks for permission before closing"
       
  1059 
       
  1060     (self masterApplication isNil and:[self askForModification]) ifTrue:[
       
  1061         super closeRequest
       
  1062     ]
       
  1063 !
       
  1064 
       
  1065 initialize
       
  1066     "initializes instance variables"
       
  1067 
       
  1068     super initialize.
       
  1069 
       
  1070     specSelector := #helpSpec.
       
  1071     dictionary   := Dictionary new.
       
  1072     dictionaries := Dictionary new.
       
  1073     modified     := false.
       
  1074 
       
  1075     editModel := nil asValue.
       
  1076     editModel addDependent:self.
       
  1077 
       
  1078     listOfKeys   := List new.
       
  1079     listOfKeysModel := nil asValue.
       
  1080     listOfKeysModel addDependent:self.
       
  1081 
       
  1082     listOfClasses := List new.
       
  1083     listOfClassesModel := nil asValue.
       
  1084     listOfClassesModel addDependent:self.
       
  1085 
       
  1086     contentsModifiedChannel := false asValue.
       
  1087     contentsModifiedChannel addDependent:self.
       
  1088 !
       
  1089 
       
  1090 loadFromMessage:aString
       
  1091     "loads a help spec by evaluating aString"
       
  1092 
       
  1093     (aString notNil and: [self askForModification]) 
       
  1094     ifTrue:
       
  1095     [            
       
  1096         |msg cls sel|
       
  1097         msg := aString asCollectionOfWords.
       
  1098         (msg size == 2 and:
       
  1099         [(cls := self resolveName:(msg at:1)) notNil and:
       
  1100         [cls class includesSelector: (sel := (msg at: 2) asSymbol)]])
       
  1101         ifTrue:
       
  1102         [               
       
  1103             self buildFromClass: (specClass := cls name) andSelector: (specSelector := sel).
       
  1104             ^true
       
  1105         ]
       
  1106     ].
       
  1107     ^false
       
  1108 !
       
  1109 
       
  1110 openInterface:aSymbol
       
  1111     "do not open as stand alone"
       
  1112 
       
  1113 
       
  1114    
       
  1115 !
       
  1116 
       
  1117 openOnClass:aClass
       
  1118     "opens the UIHelpTool on aClass"
       
  1119 
       
  1120     self openOnClass:aClass andSelector:nil
       
  1121 
       
  1122     "
       
  1123      self openOnClass:NewLauncher
       
  1124     "
       
  1125 !
       
  1126 
       
  1127 openOnClass:aClass andSelector: aSelector
       
  1128     "opens the UIHelpTool on aClass and aSelector"
       
  1129 
       
  1130     super openInterface: #windowSpecForStandAlone.
       
  1131 
       
  1132     builder window label: 'Help Tool'.
       
  1133     self buildFromClass:aClass andSelector:aSelector
       
  1134 !
       
  1135 
       
  1136 postBuildTextView:aView
       
  1137 
       
  1138     editTextView := aView scrolledView.
       
  1139     editTextView acceptAction:[:dummy| self accept ].
       
  1140 ! !
       
  1141 
       
  1142 !UIHelpTool methodsFor:'user actions'!
       
  1143 
       
  1144 accept
       
  1145     "accepts the help text"
       
  1146 
       
  1147     |key txt|   
       
  1148 
       
  1149     key := self helpKey.
       
  1150     key isNil ifTrue:[^ self].
       
  1151 
       
  1152     contentsModifiedChannel value ifFalse:[
       
  1153         (dictionary includes:key) ifTrue:[^ self].   
       
  1154     ].
       
  1155     contentsModifiedChannel value:false.
       
  1156 
       
  1157     txt := editTextView contents ? ''.
       
  1158     txt := txt asString.
       
  1159 
       
  1160     dictionary at:key put:txt.
       
  1161 
       
  1162     listOfKeys detect:[:el| el = key ] ifNone:[ |idx|
       
  1163         idx := listOfKeys findFirst:[:el| el > key ].
       
  1164         idx == 0 ifTrue:[ listOfKeys add:key ]
       
  1165                 ifFalse:[ listOfKeys add:key beforeIndex:idx]
       
  1166     ].
       
  1167 
       
  1168     listOfKeysModel value:key withoutNotifying:self.
       
  1169 
       
  1170     modified := true.
       
  1171     modifiedHolder notNil ifTrue:[ modifiedHolder value:true ].
       
  1172 !
       
  1173 
       
  1174 cancel
       
  1175     |key txt|
       
  1176 
       
  1177     editTextView notNil ifTrue:[
       
  1178         key := listOfKeysModel value.
       
  1179 
       
  1180         key notNil ifTrue:[
       
  1181             txt := dictionary at:key ifAbsent:nil.
       
  1182         ] ifFalse:[
       
  1183             txt := nil
       
  1184         ].
       
  1185         editTextView contents:txt.
       
  1186     ].
       
  1187     contentsModifiedChannel value:false.
       
  1188 !
       
  1189 
       
  1190 doDelete
       
  1191     "deletes the selected help key
       
  1192     "
       
  1193     |key|
       
  1194 
       
  1195     key := listOfKeysModel value.
       
  1196 
       
  1197     key isNil ifTrue:[
       
  1198         self warn:'No key selected !!'.
       
  1199         ^ self
       
  1200     ].
       
  1201 
       
  1202     listOfKeysModel value:nil.
       
  1203 
       
  1204     key := key asSymbol.
       
  1205     listOfKeys remove:key ifAbsent:nil.
       
  1206 
       
  1207     (dictionary removeKey:key ifAbsent:nil) notNil ifTrue:[
       
  1208         modified := true.
       
  1209         modifiedHolder notNil ifTrue: [modifiedHolder value:true].
       
  1210     ].
       
  1211 !
       
  1212 
       
  1213 doLoad
       
  1214     "opens a Resource Selection Browser in order to get a resource message"
       
  1215 
       
  1216     self loadFromMessage: 
       
  1217         (ResourceSelectionBrowser
       
  1218             request: 'Load Help Spec From Class'
       
  1219             onSuperclass: nil
       
  1220             andClass: specClass
       
  1221             andSelector: specSelector ? #help
       
  1222             withResourceTypes: (Array with: #help)).
       
  1223 
       
  1224     self updateInfoLabel
       
  1225 
       
  1226 !
       
  1227 
       
  1228 doNew
       
  1229     "resets the help tool"
       
  1230 
       
  1231     specClass := nil.
       
  1232 
       
  1233     editModel          value:nil withoutNotifying:self.
       
  1234     listOfKeysModel    value:nil.
       
  1235     listOfClassesModel value:nil.
       
  1236 
       
  1237     listOfKeys    removeAll.
       
  1238     listOfClasses removeAll.
       
  1239     dictionaries  removeAll.
       
  1240 
       
  1241     dictionary   := Dictionary new.
       
  1242     modified     := false.
       
  1243 !
       
  1244 
       
  1245 doSave
       
  1246     "saves the help dictionaries on specClass"
       
  1247 
       
  1248     self installHelpSpecsOnClass:specClass
       
  1249 ! !
  1425 ! !
  1250 
  1426 
  1251 !UIHelpTool class methodsFor:'documentation'!
  1427 !UIHelpTool class methodsFor:'documentation'!
  1252 
  1428 
  1253 version
  1429 version