diff -r d80b3c6a4373 -r 23712b1d3f3d UIHelpTool.st --- a/UIHelpTool.st Mon Aug 18 13:09:23 1997 +0200 +++ b/UIHelpTool.st Wed Aug 20 17:55:38 1997 +0200 @@ -13,7 +13,7 @@ ApplicationModel subclass:#UIHelpTool - instanceVariableNames:'dictionary list model' + instanceVariableNames:'specClass dictionary listSelection maxCharsPerLine modifiedHolder' classVariableNames:'' poolDictionaries:'' category:'Interface-UIPainter' @@ -47,6 +47,27 @@ " ! ! +!UIHelpTool class methodsFor:'instance creation'! + +openOnClass:aClass + " + UIHelpTool openOnClass:UIPainter + " + |helpTool| + + helpTool := UIHelpTool new. + helpTool openInterface:#standAloneSpec. + helpTool helpSpecFrom:UIPainter + + +! ! + +!UIHelpTool class methodsFor:'constants'! + +label + ^ 'Help' +! ! + !UIHelpTool class methodsFor:'help specs'! helpSpec @@ -56,8 +77,7 @@ ^ super helpSpec addPairsFrom:#( #activeHelpAccessKey -'This ID is used to access an active -help text for the selected component' +'This ID is used to access an active help text for the selected component' ) @@ -65,6 +85,135 @@ !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 + " + + + + ^ + + #(#Menu + + #( + #(#MenuItem + #'label:' 'file' + #'submenu:' + #(#Menu + + #( + #(#MenuItem + #'label:' 'reload' + #'value:' #doReload + ) + #(#MenuItem + #'label:' '-' + ) + #(#MenuItem + #'label:' 'close' + #'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 + " + + + + ^ + + #(#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" @@ -84,50 +233,44 @@ #(#FullSpec #'window:' #(#WindowSpec - #'name:' 'uIPainterView' - #'layout:' #(#LayoutFrame 0 0.0 0 0.0 0 1.0 0 1.0) + #'name:' 'HelpTool' + #'layout:' #(#LayoutFrame 199 0 167 0 484 0 437 0) #'label:' 'unnamed canvas' - #'bounds:' #(#Rectangle 0 0 286 272) + #'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 46 0 25 0.0 0 1.0 0 1.0) - #'model:' #textChannel + #'layout:' #(#LayoutFrame 3 0.0 45 0.0 -3 1.0 -3 1.0) #'hasHorizontalScrollBar:' true #'hasVerticalScrollBar:' true #'miniScrollerHorizontal:' true #'miniScrollerVertical:' true ) - #(#LabelSpec - #'name:' 'keyLabel' - #'layout:' #(#LayoutFrame 0 0.0 1 0.0 41 0 21 0) - #'label:' 'Key:' - #'adjust:' #left - #'resizeForLabel:' false - ) - #(#ComboBoxSpec - #'name:' 'comboBox' - #'layout:' #(#LayoutFrame 48 0 1 0 0 1.0 23 0) - #'activeHelpKey:' #activeHelpAccessKey - #'tabable:' true - #'comboList:' #listChannel - ) - #(#LabelSpec - #'name:' 'textLabel' - #'layout:' #(#LayoutFrame 0 0.0 25 0.0 41 0 45 0) - #'label:' 'Text:' - #'adjust:' #left - #'resizeForLabel:' false - ) ) ) ) - - "Modified: 28.7.1997 / 14:15:27 / cg" ! ! !UIHelpTool class methodsFor:'misc'! @@ -159,54 +302,61 @@ dictionary:aDictionary "set the value of the instance variable 'dictionary' (automatically generated)" - (dictionary := aDictionary) notNil ifTrue:[ - list := dictionary keys asOrderedCollection - ] ifFalse:[ + (dictionary := aDictionary) isNil ifTrue:[ dictionary := IdentityDictionary new. - list := nil + ]. + 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 cls| + |help| + + specClass := self class applicationClassAssociatedWith:aClass. - cls := self class applicationClassAssociatedWith:aClass. - - (cls respondsTo:#helpSpec) ifTrue:[ - help := cls helpSpec + (specClass respondsTo:#helpSpec) ifTrue:[ + help := specClass helpSpec + ] ifFalse:[ + specClass := nil ]. self dictionary:help ! -key - "get the key from the edit field as symbol or nil +modifiedHolder:aValueHolder + "set the value holder set to true in case of modifying attributes " - |key| - - key := model value. + modifiedHolder notNil ifTrue:[ + modifiedHolder removeDependent:self. + ]. - ( key size ~~ 0 - and:[(key indexOfSeparatorStartingAt:1) == 0 - or:[(key := key withoutSeparators) notEmpty]] - ) ifTrue:[ - ^ key asSymbol + (modifiedHolder := aValueHolder) notNil ifTrue:[ + modifiedHolder addDependent:self. ]. - ^ nil + + ! -model:aKeyHolder - "set the model on the edit field +updateList + "update list from dictionary " - model notNil ifTrue:[ - model removeDependent:self - ]. - (model := aKeyHolder) notNil ifTrue:[ - model addDependent:self - ]. - (builder componentAt:#comboBox) model:model. - self update:nil with:#model from:model. + self listChannel value:(dictionary keys asSortedCollection) ! ! !UIHelpTool methodsFor:'actions'! @@ -214,26 +364,17 @@ accept "accept the text " - |key txt| + |view key txt list| - key := self key. - txt := self textChannel. - - key notNil ifTrue:[ - txt dependentsDo:[:edt| edt accept]. + (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. - self listChannel value:list ]. - dictionary at:key put:(txt value) - ] ifFalse:[ - key := nil. - txt value:nil. - ]. - - model notNil ifTrue:[ - model value:key + dictionary at:key put:txt ] ! @@ -266,8 +407,9 @@ |t| src nextPutLine:key storeString. - t := txt asString. - (t endsWith:Character cr) ifTrue:[ + t := txt asString replaceAll:(Character cr) by:(Character space). + + (t endsWith:Character space) ifTrue:[ t := t copyWithoutLast:1 ]. src nextPutLine:t storeString; cr. @@ -289,34 +431,34 @@ (holder := builder bindingAt:#listChannel) isNil ifTrue:[ builder aspectAt:#listChannel put:(holder := ValueHolder new). - holder value:list. + holder value:(OrderedCollection new). ]. ^ holder ! -textChannel +listModel "automatically generated by UIPainter ..." |holder| - (holder := builder bindingAt:#textChannel) isNil ifTrue:[ - builder aspectAt:#textChannel put:(holder := ValueHolder new). + (holder := builder bindingAt:#listModel) isNil ifTrue:[ + holder := AspectAdaptor new subject:self; forAspect:#listSelection. + builder aspectAt:#listModel put:holder. ]. ^ holder -! ! +! -!UIHelpTool methodsFor:'change & update'! +selectionListModel + "automatically generated by UIPainter ..." + + |holder| -update:something with:aParameter from:someObject - "model might change - " - |text key| - - (key := self key) notNil ifTrue:[ - (text := dictionary at:key ifAbsent:nil) notNil ifTrue:[ - self textChannel value:text - ] - ] + (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'! @@ -325,8 +467,145 @@ "setup instance attributes " super initialize. - dictionary := IdentityDictionary new. - list := OrderedCollection new. + 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 col line 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 ifTrue:[ + ^ self + ]. + listSelection := sel. + + modifiedHolder notNil ifTrue:[ + modifiedHolder value:true. + ]. + + (view := self editTextView) isNil ifTrue:[ + ^ self + ]. + + listSelection notNil ifTrue:[ + txt := dictionary at:(listSelection asSymbol) ifAbsent:nil. + ]. + + (txt isNil or:[maxCharsPerLine isNil]) ifTrue:[ + col := txt. + ] ifFalse:[ + col := OrderedCollection new. + + txt asString asCollectionOfWords do:[:aWord| + line isNil ifTrue:[ + line := aWord + ] ifFalse:[ + (line size + aWord size) >= maxCharsPerLine ifTrue:[ + col add:line. + line := aWord + ] ifFalse:[ + line := line, ' ', aWord + ] + ]. + ]. + line notNil ifTrue:[col add:line]. + ]. + view contents:col. + + +! ! + +!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'!