UIHelpTool.st
author ca
Wed, 15 Oct 1997 12:38:20 +0200
changeset 328 0e8a4296dec1
parent 319 f16aa0e8541e
child 331 aa1663b8c2ab
permissions -rw-r--r--
add DataSetBuilder

"
 COPYRIGHT (c) 1995 by eXept Software AG
              All Rights Reserved

 This software is furnished under a license and may be used
 only in accordance with the terms of that license and with the
 inclusion of the above copyright notice.   This software may not
 be provided or otherwise made available to, or used by, any
 other person.  No title to or ownership of the software is
 hereby transferred.
"



ApplicationModel subclass:#UIHelpTool
	instanceVariableNames:'specClass dictionary listSelection maxCharsPerLine modifiedHolder'
	classVariableNames:''
	poolDictionaries:''
	category:'Interface-UIPainter'
!

!UIHelpTool class methodsFor:'documentation'!

copyright
"
 COPYRIGHT (c) 1995 by eXept Software AG
              All Rights Reserved

 This software is furnished under a license and may be used
 only in accordance with the terms of that license and with the
 inclusion of the above copyright notice.   This software may not
 be provided or otherwise made available to, or used by, any
 other person.  No title to or ownership of the software is
 hereby transferred.
"


!

documentation
"
    used by the UIPainter to add help text to any component which will be shown
    during runing an application with enabled activeHelp mode.

    [author:]
        Claus Atzkern
"
! !

!UIHelpTool class methodsFor:'instance creation'!

openOnClass:aClass
    "
     UIHelpTool openOnClass:UIPainter
    "
    |helpTool|

    helpTool := UIHelpTool new.
    helpTool openInterface:#standAloneSpec.
    helpTool helpSpecFrom:aClass


! !

!UIHelpTool class methodsFor:'constants'!

label
    ^ 'Help'
! !

!UIHelpTool class methodsFor:'help specs'!

helpSpec
    "return a dictionary filled with helpKey -> helptext associations.
     These are used by the activeHelp tool."

    "
    UIHelpTool openOnClass:UIHelpTool    
    "

  ^ super helpSpec addPairsFrom:#(

#activeHelpAccessKey
'This ID is used to access an active help text for the selected component'

)
! !

!UIHelpTool class methodsFor:'interface specs'!

menuPanelStandAlone
    "this window spec was automatically generated by the ST/X MenuEditor"

    "do not manually edit this - the builder may not be able to
     handle the specification if its corrupted."

    "
     MenuEditor new openOnClass:UIHelpTool andSelector:#menuPanelStandAlone
     (Menu new fromLiteralArrayEncoding:(UIHelpTool menuPanelStandAlone)) startUp
    "

    <resource: #menu>

    ^
     
       #(#Menu
          
           #(
             #(#MenuItem
                #'label:' 'file'
                #'submenu:' 
                 #(#Menu
                    
                     #(
                       #(#MenuItem
                          #'label:' 'reload'
                          #'value:' #doReload
                      )
                       #(#MenuItem
                          #'label:' '-'
                      )
                       #(#MenuItem
                          #'label:' 'quit'
                          #'value:' #closeRequest
                      )
                    ) nil
                    nil
                )
            )
             #(#MenuItem
                #'label:' 'code'
                #'submenu:' 
                 #(#Menu
                    
                     #(
                       #(#MenuItem
                          #'label:' 'class'
                          #'value:' #doFromClass
                      )
                       #(#MenuItem
                          #'label:' '-'
                      )
                       #(#MenuItem
                          #'label:' 'install help spec.'
                          #'value:' #doInstallHelpSpec
                      )
                    ) nil
                    nil
                )
            )
          ) nil
          nil
      )
!

standAloneSpec
    "this window spec was automatically generated by the ST/X UIPainter"

    "do not manually edit this - the painter/builder may not be able to
     handle the specification if its corrupted."

    "
     UIPainter new openOnClass:UIHelpTool andSelector:#standAloneSpec
     UIHelpTool new openInterface:#standAloneSpec
    "

    <resource: #canvas>

    ^
     
       #(#FullSpec
          #'window:' 
           #(#WindowSpec
              #'name:' 'HelpTool'
              #'layout:' #(#LayoutFrame 199 0 167 0 794 0 664 0)
              #'label:' 'HelpTool'
              #'min:' #(#Point 10 10)
              #'max:' #(#Point 1160 870)
              #'bounds:' #(#Rectangle 199 167 795 665)
          )
          #'component:' 
           #(#SpecCollection
              #'collection:' 
               #(
                 #(#MenuPanelSpec
                    #'name:' 'menuPanelStandAlone'
                    #'layout:' #(#LayoutFrame 0 0.0 0 0.0 0 1.0 25 0)
                    #'menu:' #menuPanelStandAlone
                )
                 #(#VariableHorizontalPanelSpec
                    #'name:' 'variableHorizontalPanel1'
                    #'layout:' #(#LayoutFrame 0 0.0 25 0.0 0 1.0 0 1.0)
                    #'component:' 
                     #(#SpecCollection
                        #'collection:' 
                         #(
                           #(#TextEditorSpec
                              #'name:' 'textView'
                              #'hasHorizontalScrollBar:' true
                              #'hasVerticalScrollBar:' true
                              #'miniScrollerHorizontal:' true
                              #'miniScrollerVertical:' true
                          )
                           #(#SequenceViewSpec
                              #'name:' 'selectionList'
                              #'model:' #selectionListModel
                              #'hasHorizontalScrollBar:' true
                              #'hasVerticalScrollBar:' true
                              #'miniScrollerHorizontal:' true
                              #'miniScrollerVertical:' true
                          )
                        )
                    )
                )
              )
          )
      )
!

windowSpec
    "this window spec was automatically generated by the ST/X UIPainter"

    "do not manually edit this - the painter/builder may not be able to
     handle the specification if its corrupted."

    "
     UIPainter new openOnClass:UIHelpTool andSelector:#windowSpec
     UIHelpTool new openInterface:#windowSpec
    "
    "UIHelpTool open"

    <resource: #canvas>

    ^
     
       #(#FullSpec
          #'window:' 
           #(#WindowSpec
              #'name:' 'HelpTool'
              #'layout:' #(#LayoutFrame 199 0 167 0 484 0 437 0)
              #'label:' 'unnamed canvas'
              #'min:' #(#Point 10 10)
              #'max:' #(#Point 1160 870)
              #'bounds:' #(#Rectangle 199 167 485 438)
          )
          #'component:' 
           #(#SpecCollection
              #'collection:' 
               #(
                 #(#LabelSpec
                    #'name:' 'keyLabel'
                    #'layout:' #(#AlignmentOrigin 3 0.0 42 0.0 0 1)
                    #'label:' 'Key:'
                    #'adjust:' #left
                    #'resizeForLabel:' true
                )
                 #(#ComboBoxSpec
                    #'name:' 'comboBox'
                    #'layout:' #(#LayoutFrame 48 0 22 0 -3 1.0 44 0)
                    #'activeHelpKey:' #activeHelpAccessKey
                    #'tabable:' true
                    #'model:' #listModel
                    #'type:' #symbolOrNil
                    #'comboList:' #listChannel
                )
                 #(#TextEditorSpec
                    #'name:' 'textView'
                    #'layout:' #(#LayoutFrame 3 0.0 45 0.0 -3 1.0 -3 1.0)
                    #'hasHorizontalScrollBar:' true
                    #'hasVerticalScrollBar:' true
                    #'miniScrollerHorizontal:' true
                    #'miniScrollerVertical:' true
                )
              )
          )
      )
! !

!UIHelpTool class methodsFor:'misc'!

applicationClassAssociatedWith:aClass
    "get application class keeping the associated help text or nil
    "
    |cls|

    aClass notNil ifTrue:[
        aClass isBehavior ifFalse:[cls := Smalltalk at:aClass asSymbol]
                           ifTrue:[cls := aClass].

        (cls notNil and:[cls includesBehavior:UISpecification]) ifTrue:[
            ^ UISpecificationTool
        ]
    ].
  ^ cls

! !

!UIHelpTool methodsFor:'accessing'!

dictionary
    "return the value of the instance variable 'dictionary' (automatically generated)"

    ^ dictionary!

dictionary:aDictionary
    "set the value of the instance variable 'dictionary' (automatically generated)"

    (dictionary := aDictionary) isNil ifTrue:[
        dictionary := IdentityDictionary new.
    ].
    self updateList
!

helpKey
    listSelection size ~~ 0 ifTrue:[
        ^ listSelection asSymbol
    ].
    ^ nil
!

helpKey:aKey
    |key|

    aKey size ~~ 0 ifTrue:[
        key := aKey asString
    ].
    self listModel value:key
!

helpSpecFrom:aClass
    "read help text from an application associated with the class
    "
    |help|

    specClass := self class applicationClassAssociatedWith:aClass.

    (specClass respondsTo:#helpSpec) ifTrue:[
        help := specClass helpSpec
    ] ifFalse:[
        specClass := nil
    ].
    self dictionary:help
!

modifiedHolder:aValueHolder
    "set the value holder set to true in case of modifying attributes
    "
    modifiedHolder notNil ifTrue:[
        modifiedHolder removeDependent:self. 
    ].

    (modifiedHolder := aValueHolder) notNil ifTrue:[
        modifiedHolder addDependent:self.
    ].


!

updateList
    "update list from dictionary
    "
    self listChannel value:(dictionary keys asSortedCollection)
! !

!UIHelpTool methodsFor:'actions'!

accept
    "accept the text
    "
    |view key txt list|

    (listSelection size == 0 or:[(view := self editTextView) isNil]) ifFalse:[
        txt  := view contents asString.
        key  := listSelection asSymbol.
        list := self listChannel value.

        (dictionary at:key ifAbsent:nil) isNil ifTrue:[
            list add:key.
        ].
        dictionary at:key put:txt
    ]
!

installHelpSpecInto:aClass
    "install help text
    "
    |cls src|

    cls := self class applicationClassAssociatedWith:aClass.

    cls isNil ifTrue:[
        ^ self information:'no application class defined'.
    ].
    dictionary isEmpty ifTrue:[
        ^ self information:'no help text defined'
    ].
    src  := '' writeStream.

    src nextPutAll:

'helpSpec
    "return a dictionary filled with helpKey -> helptext associations.
     These are used by the activeHelp tool."

    "
    UIHelpTool openOnClass:', cls name asString ,'    
    "

  ^ super helpSpec addPairsFrom:#(

'.

    dictionary keysAndValuesDo:[:key :txt|
        |t|
        src nextPutLine:key storeString.

        t := txt asString replaceAll:(Character cr) with:(Character space).

        (t endsWith:Character space) ifTrue:[
            t := t copyWithoutLast:1
        ].
        src nextPutLine:t storeString; cr.
    ].
    src nextPutLine:')'.

    Compiler compile:(src contents)
            forClass:cls class 
          inCategory:'help specs'

! !

!UIHelpTool methodsFor:'aspects'!

listChannel
    "automatically generated by UIPainter ..."

    |holder|

    (holder := builder bindingAt:#listChannel) isNil ifTrue:[
        builder aspectAt:#listChannel put:(holder :=  ValueHolder new).
        holder value:(OrderedCollection new).
    ].
    ^ holder
!

listModel
    "automatically generated by UIPainter ..."

    |holder|

    (holder := builder bindingAt:#listModel) isNil ifTrue:[
        holder := AspectAdaptor new subject:self; forAspect:#listSelection.
        builder aspectAt:#listModel put:holder.
    ].
    ^ holder
!

selectionListModel
    "automatically generated by UIPainter ..."

    |holder|

    (holder := builder bindingAt:#selectionListModel) isNil ifTrue:[
        builder aspectAt:#selectionListModel put:(holder :=  SelectionInList new).
        holder listHolder:(self listChannel).
        holder selectionIndexHolder:(self listModel).
    ].
    ^ holder
! !

!UIHelpTool methodsFor:'initialization'!

initialize
    "setup instance attributes
    "
    super initialize.
    dictionary := IdentityDictionary new.
! !

!UIHelpTool methodsFor:'private'!

editTextView
    "get the editTextView or nil.
    "
    |view|

    (view := builder componentAt:#textView) notNil ifTrue:[
        view := view scrolledView.

        view acceptAction isNil ifTrue:[
            view acceptAction:[:aList| self accept ].
        ].

        view left ~~ 0 ifTrue:[
            (maxCharsPerLine := view extent x // view font width) < 10 ifTrue:[
                maxCharsPerLine := nil
            ]
        ].
    ].
    ^ view
! !

!UIHelpTool methodsFor:'selection'!

listSelection
    "returns current selection
    "
    ^ listSelection
!

listSelection:aSelection
    "current selection changed
    "
    |txt view sel|

    aSelection isNumber ifTrue:[
        aSelection ~~ 0 ifTrue:[
            sel := self listChannel value at:aSelection
        ]
    ] ifFalse:[
        aSelection size ~~ 0 ifTrue:[
            sel := aSelection withoutSeparators.
            sel size == 0 ifTrue:[
                sel := nil
            ]
        ]
    ].

    listSelection = sel ifFalse:[
        listSelection := sel.

        modifiedHolder notNil ifTrue:[
            modifiedHolder value:true.
        ].

        (view := self editTextView) notNil ifTrue:[
            listSelection notNil ifTrue:[
                txt := dictionary at:(listSelection asSymbol) ifAbsent:nil.

                (txt isNil or:[maxCharsPerLine isNil]) ifFalse:[
                    txt := UIPainter convertString:(txt asString) maxLineSize:maxCharsPerLine.
                ]
            ].
            view contents:txt.    
        ]
    ]

! !

!UIHelpTool methodsFor:'user interactions'!

doFromClass
    "setup new specification from a class accessed through to a dialog
    "
    |cls accepted|

    specClass notNil ifTrue:[cls := specClass name asValue]
                    ifFalse:[cls := '' asValue].

    [true] whileTrue:[
        accepted :=
            (DialogBox new
                addTextLabel:'Classes name:';
                addInputFieldOn:cls; 
                addAbortButton; 
                addOkButton; 
                open
            ) accepted.

        accepted ifFalse:[^ self].
        cls := self class applicationClassAssociatedWith:cls value.

        cls notNil ifTrue:[
            ^ self helpSpecFrom:cls
        ].
        self warn:'no such class'.
    ]
!

doInstallHelpSpec
    "install help spec
    "
    self installHelpSpecInto:specClass
!

doReload
    "reload specification
    "
    |oldSel model|

    model  := self listModel.
    oldSel := model value.
    model value:nil.
    self helpSpecFrom:specClass.
    model value:oldSel.
! !

!UIHelpTool class methodsFor:'documentation'!

version
    ^ '$Header$'
! !