# HG changeset patch # User ca # Date 1042028165 -3600 # Node ID e6ea33c843a0937c0233f7e75b5590712863c4ec # Parent 3e83796a3e0ee71f1c269c117f0604054073df63 *** empty log message *** diff -r 3e83796a3e0e -r e6ea33c843a0 MenuEditor.st --- a/MenuEditor.st Sat Dec 21 14:11:41 2002 +0100 +++ b/MenuEditor.st Wed Jan 08 13:16:05 2003 +0100 @@ -1404,13 +1404,13 @@ helpTool "get the help tool application " - ^ wizards at:#help ifAbsentPut:[ |tool| - tool := UIHelpTool new createBuilder. - tool masterApplication:self. - tool modifiedHolder: self valueOfEnablingCommitButtons. - tool builder window:(ApplicationSubView new client:tool). - tool masterApplication:self. - tool + ^ wizards at:#help ifAbsentPut:[ |tool| + tool := UIHelpTool new. + tool masterApplication:self. + tool modifiedHolder: self valueOfEnablingCommitButtons. + tool builder window:(ApplicationSubView new client:tool). + tool masterApplication:self. + tool ] ! @@ -1460,6 +1460,7 @@ acceptChannel setValue:false. ok ifTrue:[ + helpTool accept. rscRetrHolder value:(imageTool resourceRetriever). helpKeyHolder value:(helpTool helpKey). selectedItem fromAspects:aspects. @@ -1471,7 +1472,7 @@ ]. ]. selectedItem toAspects:aspects. - helpTool setHelpKey:(helpKeyHolder value). + helpTool helpKey:(helpKeyHolder value). imageTool resourceRetriever:(rscRetrHolder value). ] ]. @@ -2401,7 +2402,9 @@ code := code withCRs. (ReadStream on:code) fileIn. - self isStandAlone ifTrue: [self helpTool installHelpSpecsOnClass:self specClass]. + self isStandAlone ifTrue:[ + self helpTool doSave + ]. self updateHistory. hasSaved := true. diff -r 3e83796a3e0e -r e6ea33c843a0 UIHelpTool.st --- a/UIHelpTool.st Sat Dec 21 14:11:41 2002 +0100 +++ b/UIHelpTool.st Wed Jan 08 13:16:05 2003 +0100 @@ -1,6 +1,6 @@ " COPYRIGHT (c) 1995 by eXept Software AG - All Rights Reserved + 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 @@ -10,25 +10,36 @@ hereby transferred. " - - "{ Package: 'stx:libtool2' }" ToolApplicationModel subclass:#UIHelpTool - instanceVariableNames:'specClass specSelector dictionary dictionaries modifiedHolder - modified listOfKeys listOfKeysModel listOfClasses - listOfClassesModel contentsModifiedChannel editModel editTextView' + instanceVariableNames:'specClass specSelector classItemList classItemModel keyItemModel + helpTextView modifiedHolder contentsModifiedChannel editModel' classVariableNames:'' poolDictionaries:'' category:'Interface-UIPainter' ! +HierarchicalItem subclass:#ClassItem + instanceVariableNames:'theClass list modified' + classVariableNames:'' + poolDictionaries:'' + privateIn:UIHelpTool +! + +HierarchicalItem subclass:#KeyItem + instanceVariableNames:'helpKey helpText modified' + classVariableNames:'' + poolDictionaries:'' + privateIn:UIHelpTool +! + !UIHelpTool class methodsFor:'documentation'! copyright " COPYRIGHT (c) 1995 by eXept Software AG - All Rights Reserved + 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 @@ -37,8 +48,6 @@ other person. No title to or ownership of the software is hereby transferred. " - - ! documentation @@ -52,18 +61,19 @@ is enabled, an active help bubble is shown at the widget's view. [instance variables:] - specClass class implementing the help spec - specSelector selector returning the help spec - dictionary dictionary containing pairs of help keys/texts - dictionaries dictionary containing pairs of help spec classes/help dictionaries - listSelection current selected help key - maxCharsPerLine maximum number of allowed characters per text line - modifiedHolder value holder for setting as modified - modified flag whether the help spec was modified + specClass class implementing the help spec + specSelector selector returning the help spec + classItemList the list of classItems + classItemModel keeps the selected class + keyItemModel keeps the selected helpKey + modifiedHolder true if the editField or contents changed + editModel keeps the current helpKey + helpTextView the view which shows the helpText + contentsModifiedChannel true if the helpText is modified [author:] - Claus Atzkern, eXept Software AG - Thomas Zwick, eXept Software AG + Claus Atzkern, eXept Software AG + Thomas Zwick, eXept Software AG " ! ! @@ -71,48 +81,25 @@ open ^ self openOnClass:nil. - -"/ |className cls| -"/ -"/ className := Dialog request:(ClassResources string:'Open on which class ?'). -"/ className size > 0 ifTrue:[ -"/ cls := Smalltalk at:className asSymbol. -"/ cls notNil ifTrue:[ -"/ ^ self openOnClass:cls. -"/ ]. -"/ self warn:(ClassResources string:'No such class'). -"/ ]. -"/ -"/ "Created: / 20.5.1998 / 00:55:05 / cg" -"/ - - "Modified: / 20.5.1998 / 01:06:07 / cg" ! openOnClass:aClass - "opens a Help Tool on aClass" - - ^ self openOnClass:aClass andSelector:#helpSpec - + "opens a Help Tool on aClass " - UIHelpTool openOnClass:self - " - - "Modified: / 20.5.1998 / 01:06:14 / cg" + ^ self openOnClass:aClass andSelector:#helpSpec ! openOnClass:aClass andSelector: aSelector - "opens a Help Tool on aClass and aSelector" - - ^self new openOnClass:aClass andSelector: aSelector - + "opens a Help Tool on aClass and aSelector + " + ^ self new openOnClass:aClass andSelector:aSelector ! ! !UIHelpTool class methodsFor:'constants'! label - "returns the label; used if embedded as sub canvas in the GUI Painter or Menu Editor" - + "returns the label; used if embedded as sub canvas in the GUI Painter or Menu Editor + " ^'Help' ! ! @@ -131,7 +118,7 @@ - ^super helpSpec addPairsFrom:#( + ^ super helpSpec addPairsFrom:#( #addHelpTextKey 'Adds the key to the help spec.' @@ -188,114 +175,101 @@ ^ #(#FullSpec - #name: #windowSpec - #window: + #name: #windowSpec + #window: #(#WindowSpec - #label: 'Help Tool' - #name: 'Help Tool' - #min: #(#Point 10 10) - #max: #(#Point 1160 870) - #bounds: #(#Rectangle 31 306 317 577) - ) - #component: + #label: 'UIHelpTool' + #name: 'UIHelpTool' + #min: #(#Point 10 10) + #max: #(#Point 1024 768) + #bounds: #(#Rectangle 30 292 491 585) + ) + #component: #(#SpecCollection - #collection: #( - #(#VariableVerticalPanelSpec - #name: 'VariableVerticalPanel' - #layout: #(#LayoutFrame 0 0.0 0 0.0 0 1.0 0 1.0) - #component: - #(#SpecCollection - #collection: #( - #(#VariableHorizontalPanelSpec - #name: 'VariableHorizontalPanel' - #component: - #(#SpecCollection - #collection: #( - #(#SelectionInListModelViewSpec - #name: 'listOfKeys' - #activeHelpKey: #listOfHelpTexts - #model: #listOfKeysModel - #menu: #listOfKeysMenu - #hasHorizontalScrollBar: true - #hasVerticalScrollBar: true - #miniScrollerHorizontal: true - #listModel: #listOfKeys - #useIndex: false - #highlightMode: #line - ) - #(#ViewSpec - #name: 'Box' - #component: - #(#SpecCollection - #collection: #( - #(#InputFieldSpec - #name: 'helpKeyInputField' - #layout: #(#LayoutFrame 2 0.0 2 0 -2 1.0 25 0) - #activeHelpKey: #currentHelpTexts - #tabable: true - #model: #editModel - #immediateAccept: true - #acceptOnReturn: false - #acceptOnTab: false - #acceptOnPointerLeave: false - ) - #(#SelectionInListModelViewSpec - #name: 'listOfClasses' - #layout: #(#LayoutFrame 0 0.0 27 0 0 1.0 0 1.0) - #activeHelpKey: #listOfClasses - #model: #listOfClassesModel - #hasHorizontalScrollBar: true - #hasVerticalScrollBar: true - #miniScrollerHorizontal: true - #miniScrollerVertical: true - #listModel: #listOfClasses - #useIndex: false - #highlightMode: #line - ) - ) + #collection: #( + #(#VariableVerticalPanelSpec + #name: 'PanelVrt' + #layout: #(#LayoutFrame 0 0.0 0 0.0 0 1.0 0 1.0) + #component: + #(#SpecCollection + #collection: #( + #(#VariableHorizontalPanelSpec + #name: 'PanelHrz' + #component: + #(#SpecCollection + #collection: #( + #(#HierarchicalListViewSpec + #name: 'keyItemModel' + #model: #keyItemModel + #menu: #keyItemMenu + #hasHorizontalScrollBar: true + #hasVerticalScrollBar: true + #miniScrollerHorizontal: true + #miniScrollerVertical: false + #listModel: #keyItemListHolder + #useIndex: false + #highlightMode: #label + #showLines: false + #showIndicators: false + #showLeftIndicators: false + #useDefaultIcons: false + #autoScrollHorizontal: false + ) + #(#ViewSpec + #name: 'classItemList' + #component: + #(#SpecCollection + #collection: #( + #(#InputFieldSpec + #name: 'editModel' + #layout: #(#LayoutFrame 0 0.0 2 0 -1 1.0 25 0) + #activeHelpKey: #currentHelpTexts + #model: #editModel + #immediateAccept: true + #acceptOnReturn: false + #acceptOnTab: false + #acceptOnLostFocus: false + #acceptOnPointerLeave: false + ) + #(#SelectionInListModelViewSpec + #name: 'classItemModel' + #layout: #(#LayoutFrame 0 0.0 27 0.0 0 1.0 0 1.0) + #model: #classItemModel + #hasHorizontalScrollBar: true + #hasVerticalScrollBar: true + #miniScrollerHorizontal: true + #miniScrollerVertical: true + #autoHideScrollBars: false + #listModel: #classItemListHolder + #useIndex: false + #highlightMode: #label + ) + ) - ) - ) - ) + ) + ) + ) - ) - #handles: #(#Any 0.5 1.0) - ) - #(#ViewSpec - #name: 'Box1' - #component: - #(#SpecCollection - #collection: #( - #(#MenuPanelSpec - #name: 'helpTextMenu' - #layout: #(#LayoutFrame 0 0.0 0 0 0 1.0 24 0) - #menu: #helpTextMenu - #textDefault: true - ) - #(#TextEditorSpec - #name: 'helpTextView' - #layout: #(#LayoutFrame 0 0.0 24 0.0 0 1.0 0 1.0) - #activeHelpKey: #helpTextView - #tabable: true - #hasHorizontalScrollBar: true - #hasVerticalScrollBar: true - #miniScrollerHorizontal: true - #miniScrollerVertical: true - #modifiedChannel: #contentsModifiedChannel - #postBuildCallback: #postBuildTextView: - ) - ) - - ) - ) - ) + ) + #handles: #(#Any 0.607375 1.0) + ) + #(#ArbitraryComponentSpec + #name: 'helpTextView' + #hasHorizontalScrollBar: true + #hasVerticalScrollBar: true + #miniScrollerHorizontal: true + #miniScrollerVertical: true + #hasBorder: false + #component: #helpTextView + ) + ) - ) - #handles: #(#Any 0.5 1.0) - ) - ) + ) + #handles: #(#Any 0.679181 1.0) + ) + ) - ) + ) ) ! @@ -315,33 +289,39 @@ ^ #(#FullSpec - #name: #windowSpecForStandAlone - #window: + #name: #windowSpecForStandAlone + #window: #(#WindowSpec - #label: 'Help Tool' - #name: 'Help Tool' - #min: #(#Point 300 300) - #max: #(#Point 1152 900) - #bounds: #(#Rectangle 83 333 796 896) - #menu: #menu - ) - #component: + #label: 'Help Tool' + #name: 'Help Tool' + #min: #(#Point 300 300) + #max: #(#Point 1152 900) + #bounds: #(#Rectangle 11 332 509 761) + #menu: #menu + ) + #component: #(#SpecCollection - #collection: #( - #(#UISubSpecification - #name: 'windowSpec' - #layout: #(#LayoutFrame 0 0.0 0 0.0 0 1.0 -26 1.0) - #minorKey: #windowSpec - ) - #(#UISubSpecification - #name: 'windowSpecForInfoBar' - #layout: #(#LayoutFrame 0 0 -24 1 0 1 0 1) - #majorKey: #ToolApplicationModel - #minorKey: #windowSpecForInfoBar - ) - ) + #collection: #( + #(#UISubSpecification + #name: 'windowSpec' + #layout: #(#LayoutFrame 0 0.0 0 0.0 0 1.0 -50 1.0) + #minorKey: #windowSpec + ) + #(#UISubSpecification + #name: 'windowSpecForCommit' + #layout: #(#LayoutFrame 0 0.0 -50 1.0 0 1.0 -24 1.0) + #majorKey: #ToolApplicationModel + #minorKey: #windowSpecForCommit + ) + #(#UISubSpecification + #name: 'windowSpecForInfoBar' + #layout: #(#LayoutFrame 0 0 -24 1 0 1 0 1) + #majorKey: #ToolApplicationModel + #minorKey: #windowSpecForInfoBar + ) + ) - ) + ) ) ! ! @@ -363,24 +343,53 @@ ^ #(#Menu - #( - #(#MenuItem - #activeHelpKey: #commitOK - #enabled: #contentsModifiedChannel - #label: 'Accept' - #itemValue: #accept - #translateLabel: true - ) - #(#MenuItem - #activeHelpKey: #commitCancel - #enabled: #contentsModifiedChannel - #label: 'Cancel' - #itemValue: #cancel - #translateLabel: true - ) - ) - nil - nil + #( + #(#MenuItem + #activeHelpKey: #commitOK + #enabled: #contentsModifiedChannel + #label: 'Accept' + #itemValue: #accept + #translateLabel: true + ) + #(#MenuItem + #activeHelpKey: #commitCancel + #enabled: #contentsModifiedChannel + #label: 'Cancel' + #itemValue: #cancel + #translateLabel: true + ) + ) + nil + nil + ) +! + +keyItemMenu + "This resource specification was automatically generated + by the MenuEditor of ST/X." + + "Do not manually edit this!! If it is corrupted, + the MenuEditor may not be able to read the specification." + + " + MenuEditor new openOnClass:UIHelpTool andSelector:#keyItemMenu + (Menu new fromLiteralArrayEncoding:(UIHelpTool keyItemMenu)) startUp + " + + + + ^ + #(#Menu + #( + #(#MenuItem + #activeHelpKey: #deleteHelpTextKey + #label: 'Delete' + #itemValue: #doDelete + #translateLabel: true + ) + ) + nil + nil ) ! @@ -400,16 +409,16 @@ ^ #(#Menu - #( - #(#MenuItem - #activeHelpKey: #deleteHelpTextKey - #label: 'Delete' - #itemValue: #doDelete - #translateLabel: true - ) - ) - nil - nil + #( + #(#MenuItem + #activeHelpKey: #deleteHelpTextKey + #label: 'Delete' + #itemValue: #doDelete + #translateLabel: true + ) + ) + nil + nil ) ! @@ -429,164 +438,138 @@ ^ #(#Menu - #( - #(#MenuItem - #label: 'File' - #translateLabel: true - #submenu: - #(#Menu - #( - #(#MenuItem - #activeHelpKey: #fileLoad - #label: 'Load...' - #itemValue: #doLoad - #translateLabel: true - ) - #(#MenuItem - #activeHelpKey: #fileSave - #label: 'Save' - #itemValue: #doSave - #translateLabel: true - ) - #(#MenuItem - #label: '-' - ) - #(#MenuItem - #activeHelpKey: #fileExit - #label: 'Exit' - #itemValue: #closeRequest - #translateLabel: true - ) - ) - nil - nil - ) - ) - #(#MenuItem - #label: 'Edit' - #translateLabel: true - #submenu: - #(#Menu - #( - #(#MenuItem - #activeHelpKey: #deleteHelpTextKey - #label: 'Delete' - #itemValue: #doDelete - #translateLabel: true - ) - ) - nil - nil - ) - ) - #(#MenuItem - #activeHelpKey: #help - #label: 'Help' - #translateLabel: true - #startGroup: #right - #submenuChannel: #menuHelp - ) - ) - nil - nil + #( + #(#MenuItem + #label: 'File' + #translateLabel: true + #submenu: + #(#Menu + #( + #(#MenuItem + #activeHelpKey: #fileLoad + #label: 'Load...' + #itemValue: #doLoad + #translateLabel: true + ) + #(#MenuItem + #activeHelpKey: #fileSave + #label: 'Save' + #itemValue: #doSave + #translateLabel: true + ) + #(#MenuItem + #label: 'New' + #itemValue: #doNew + #translateLabel: true + ) + #(#MenuItem + #label: '-' + ) + #(#MenuItem + #activeHelpKey: #fileExit + #label: 'Exit' + #itemValue: #closeRequest + #translateLabel: true + ) + ) + nil + nil + ) + ) + #(#MenuItem + #activeHelpKey: #history + #label: 'History' + #translateLabel: true + #submenuChannel: #menuHistory + ) + #(#MenuItem + #label: 'Edit' + #translateLabel: true + #submenuChannel: #keyItemMenu + #keepLinkedMenu: true + ) + #(#MenuItem + #activeHelpKey: #help + #label: 'Help' + #translateLabel: true + #startGroup: #right + #submenuChannel: #menuHelp + ) + ) + nil + nil ) ! ! !UIHelpTool methodsFor:'accessing'! -dictionaries - "returns the dictionary of the help dictionaries of the classes having help specs" - - ^dictionaries -! - -dictionaries:aDictionaryOfDictionaries - "sets a dictionary of the help dictionaries of the classes having help specs" - - (dictionaries := aDictionaryOfDictionaries) isNil ifTrue:[ - dictionaries := Dictionary new. - ]. - self updateList. -! +helpKey + "returns the helpKey as symbol or nil + " + |key| -dictionary - "returns the dictionary of the selected class" - - ^dictionary -! + key := editModel value. -helpKey - "returns the help key as symbol or nil - " - |value| - - value := editModel value. - - value notNil ifTrue:[ - value := value withoutSeparators. - value notEmpty ifTrue:[ ^ value asSymbol ] + key size ~~ 0 ifTrue:[ + key := key withoutSeparators. + key notEmpty ifTrue:[ ^ key asSymbol ] ]. ^ nil ! helpKey:aKey - "sets the help key into the selection channel in order to show the help text" - + "change the helpKey without any change notification (modifiedHolder). + " |key| - aKey size ~~ 0 ifTrue:[ - aKey isSymbol ifTrue:[ - key := aKey - ] ifFalse:[ - key := aKey withoutSeparators. - key notEmpty ifTrue:[ key := key asSymbol ] - ifFalse:[ key := nil ]. - ] - ] ifFalse:[ - key := nil + self withoutModifyDo:[ + aKey size ~~ 0 ifTrue:[ + key := aKey withoutSeparators. + key isEmpty ifTrue:[ key := nil ] + ] ifFalse:[ + key := nil + ]. + editModel value:key. ]. - editModel value:key. self cancel. ! modified - "true if the helpSpec is modified, items are added, deleted or modified + "true if any items are added, deleted or modified " - ^ modified + classItemList do:[:aClassItem| + aClassItem modified ifTrue:[^ true]. + ]. + ^ false ! -modified: aBoolean - "true if the helpSpec is modified, items are added, deleted or modified +modified:aBoolean + "true if any items are added, deleted or modified " - modified := aBoolean. + classItemList do:[:aClassItem| aClassItem modified:aBoolean ]. +! + +modifiedHolder + "boolean holder which is set to true if the helpKey or contents changed + " + ^ modifiedHolder ! modifiedHolder:aValueHolder - "sets the value holder to true in case of modifying attributes" - + "boolean holder which is set to true if the helpKey or contents changed + " modifiedHolder notNil ifTrue:[ - modifiedHolder removeDependent:self. + modifiedHolder removeDependent:self. ]. modifiedHolder := aValueHolder. modifiedHolder notNil ifTrue:[ - modifiedHolder addDependent:self. - ] -! - -setHelpKey:aKey - "set the helpKey without notification - " - |model| - - model := modifiedHolder. - modifiedHolder := nil. - self helpKey:aKey. - modifiedHolder := model. + modifiedHolder addDependent:self. + ]. ! specClass - "returns the class on which the help tool works + "returns the class on which the help tool works on " ^ specClass ! @@ -599,48 +582,82 @@ !UIHelpTool methodsFor:'aspects'! +classItemListHolder + "returns the holder which keeps the class items + " + |holder| + + holder := builder bindingAt:#classItemListHolder. + + holder isNil ifTrue:[ + holder := nil asValue. + holder value:classItemList. + builder aspectAt:#classItemListHolder put:holder. + ]. + ^ holder +! + +classItemModel + "returns the holder which keeps the current selected class + " + ^ classItemModel +! + contentsModifiedChannel - "returns the model which indicates whether the current helpText is modified + "boolean holder, which is set to true if the contents assigned to the + helpKey changed " ^ contentsModifiedChannel ! editModel - "returns the model which keeps the current editing key + "string holder, which keeps the current editing helpKey as string " - ^ editModel + ^ editModel. ! -listOfClasses - "returns the list which keeps the classes +helpTextView + "the editView which keeps the current help contents assigned to the key " - ^ listOfClasses + ^ helpTextView ! -listOfClassesModel - "returns the model which keeps the current class selection - or nil +keyItemListHolder + "holder, which keeps the current hierarchical list + assigned to the selected class item " - ^ listOfClassesModel + |holder| + + holder := builder bindingAt:#keyItemListHolder. + + holder isNil ifTrue:[ + holder := nil asValue. + holder value:(classItemList last list). + builder aspectAt:#keyItemListHolder put:holder. + ]. + ^ holder ! -listOfKeys - "returns the list which keeps the current keys +keyItemModel + "model which keeps the current selected helpKey or nil " - ^ listOfKeys + ^ keyItemModel. ! -listOfKeysModel - "returns the model which keeps the current list selection - or nil +valueOfEnablingCommitButtons + "returns the enabling of the commit of this tool as value holder " - ^ listOfKeysModel + masterApplication notNil ifTrue:[ + ^ masterApplication valueOfEnablingCommitButtons + ]. + ^ contentsModifiedChannel ! valueOfInfoLabel - + "returns the info label as value holder + " masterApplication notNil ifTrue:[ - ^ masterApplication valueOfInfoLabel + ^ masterApplication valueOfInfoLabel ]. ^ super valueOfInfoLabel ! ! @@ -648,604 +665,763 @@ !UIHelpTool methodsFor:'building'! buildAndMergeFromClass:aClass - "class and selector changed; merge old definitions - into definitions loaded from a class - " - |saveDictionary saveHelpKey| + "setup a new specClass, merge the current items into + " + |root mergeItems| - saveDictionary := dictionary. - saveHelpKey := self helpKey. + root := classItemList first. + + root isUnspecified ifTrue:[ mergeItems := root children ] + ifFalse:[ mergeItems := nil ]. + + self buildFromClass:aClass. - self buildFromClass:aClass. + mergeItems size ~~ 0 ifTrue:[ + root := classItemList first. + + mergeItems do:[:anItem| |item hkey| + hkey := anItem helpKey. + item := root detectItemWithKey:hkey. - saveDictionary notEmpty ifTrue:[ - dictionary declareAllFrom:saveDictionary. - self updateList. + item isNil ifTrue:[ + item := KeyItem helpKey:hkey helpText:(anItem helpText). + root add:item sortBlock:[:a :b| a label < b label ]. + ] ifFalse:[ + item helpText:(anItem helpText). + ] + ] ]. - self helpKey:saveHelpKey. - self modified:true. ! buildFromClass:aClass "reads the help dictionary from aClass and find remaining classes - 'between' aClass and ApplicationModel" + 'between' aClass and ApplicationModel + " + |lastContents root list resource| - |list| - - modified := false. + specSelector isNil ifTrue:[ specSelector := #helpSpec ]. specClass := self getHelpSpecClassFromClass:aClass. - specClass notNil ifTrue:[ - dictionary := Dictionary new. - dictionaries removeAll. + list := OrderedCollection new. + + (specClass isClass and:[specClass isLoaded]) ifTrue:[ + lastContents := nil. + resource := specClass name, ' ', specSelector. + self addToHistory:(Association key:resource value:#'loadFromMessage:'). + + specClass withAllSuperclasses reverse do:[:aClass| |value name| + lastContents isNil ifTrue:[ + aClass == ApplicationModel ifTrue:[ + lastContents := IdentityDictionary new + ]. + ] ifFalse:[ + root := ClassItem onClass:aClass. + + (aClass class includesSelector:specSelector) ifTrue:[ + value := aClass perform:specSelector. + + value keysAndValuesDo:[:k :v| |cval| + cval := lastContents at:k ifAbsent:self. + cval = v ifFalse:[ root add:(KeyItem helpKey:k helpText:v) ]. + ]. + lastContents := value. + ]. + root sort:[:a :b| a label < b label ]. + root modified:false. + list add:root. + ] + ] + ]. + list isEmpty ifTrue:[ + list add:(ClassItem onClass:nil) ]. - (specClass isClass and:[specClass isLoaded]) ifFalse:[ - self updateList. - ^ self - ]. - (specClass class includesSelector:specSelector) ifFalse:[ - dictionaries at:(specClass name) put:dictionary. + self withoutModifyDo:[ + classItemList contents:list. + classItemModel value:(list last) ]. - list := specClass withAllSuperclasses reverse collect:[:cls| cls name ]. - - (list includes: #ApplicationModel) ifTrue:[ - list := list asOrderedCollection. - list removeAll:(ApplicationModel withAllSuperclasses collect:[:cls| cls name]) - ]. - listOfClasses contents:list. - listOfClassesModel triggerValue:(specClass name). ! buildFromClass: aClass andSelector: aSelector - "sets aSelector and reads the help dictionary from aClass" - + "sets aSelector and reads the help dictionary from aClass + " specSelector := aSelector. self buildFromClass:aClass - ! buildFromHelpTool:aHelpTool - - self doNew. - - dictionaries := aHelpTool dictionaries. - dictionary := aHelpTool dictionary. + "build from another helpTool + " + specClass := aHelpTool specClass. + specSelector := aHelpTool specSelector. + classItemList := aHelpTool classItemListHolder value. - specSelector := aHelpTool specSelector. - specClass := aHelpTool specClass. + self classItemListHolder value:classItemList. - listOfClasses contents:(aHelpTool listOfClasses). - listOfClassesModel triggerValue:(listOfClasses at:1 ifAbsent:nil). + classItemModel triggerValue:(classItemList last). ! ! !UIHelpTool methodsFor:'change & update'! editModelChanged - "called if the edit model changed + "called if the editModel changed " |key| key := self helpKey. - modifiedHolder notNil ifTrue:[ modifiedHolder value:true ]. - - (key notNil and:[(dictionary at:key ifAbsent:nil) isNil]) ifTrue:[ - listOfClasses do:[:name| |dir| - dir := self dictionaryForClassNamed:name. - - (dir includesKey:key) ifTrue:[ - "/ setup new class - listOfKeysModel setValue:key. - listOfClassesModel value:name. - ^ self - ]. - ]. - key := nil. - ]. - listOfKeysModel value:key. -! -listOfClassesModelChanged - "called if the class selection changed - " - |clsName| - - clsName := listOfClassesModel value. - clsName isNil ifTrue:[^ self]. + modifiedHolder notNil ifTrue:[ + modifiedHolder value:true + ]. - dictionary := self dictionaryForClassNamed:clsName. - self updateList. -! - -listOfKeysModelChanged - "called if the selection of the key list changed - " - |key txt| - - key := listOfKeysModel value. + contentsModifiedChannel value:false. key notNil ifTrue:[ - key := key asSymbol. - txt := dictionary at:key ifAbsent:nil. + keyItemModel value = key ifTrue:[^ self]. + + classItemList reverseDo:[:root| |item| + item := root detectItemWithKey:key. - txt isNil ifTrue:[ - listOfKeysModel value:nil. - ^ self - ]. - editModel value ~= key ifTrue:[ - editModel value:key withoutNotifying:self. - modifiedHolder notNil ifTrue:[ modifiedHolder value:true ]. - ]. + item notNil ifTrue:[ + classItemModel value:root. + keyItemModel value:item. + ^ self. + ]. + ]. + + masterApplication isNil ifTrue:[ + "entered a new helpKey + " + self valueOfEnablingCommitButtons value:true. + ]. ]. - - contentsModifiedChannel value ifFalse:[ - self cancel - ]. + keyItemModel value:nil. ! update:something with:aParameter from:changedObject - "Invoked when an object that I depend upon sends a change notification." - - editModel == changedObject ifTrue:[ - self editModelChanged. - ^ self - ]. + "Invoked when an object that I depend upon sends a change notification. + " + |root item list| - listOfKeysModel == changedObject ifTrue:[ - self listOfKeysModelChanged. - ^ self - ]. + changedObject == keyItemModel ifTrue:[ + item := keyItemModel value. - listOfClassesModel == changedObject ifTrue:[ - self listOfClassesModelChanged. - ^ self + item notNil ifTrue:[ + editModel value:(item helpKey). + ]. + self cancel. + ^ self ]. - contentsModifiedChannel == changedObject ifTrue:[ - contentsModifiedChannel value ifTrue:[ - modifiedHolder notNil ifTrue:[modifiedHolder value:true]. - ]. - ^ self + changedObject == classItemModel ifTrue:[ + root := classItemModel value. + + root notNil ifTrue:[ + item := root detectItemWithKey:(self helpKey). + list := root list. + ] ifFalse:[ + list := item := nil. + ]. + + item notNil ifTrue:[ + keyItemModel value:nil withoutNotifying:self. + ]. + self keyItemListHolder value:list. + keyItemModel value:item. + ^ self ]. - super update:something with:aParameter from:changedObject -! ! - -!UIHelpTool methodsFor:'help'! + changedObject == editModel ifTrue:[ + self editModelChanged. + ^ self + ]. -openDocumentation - "opens the documentation file of the Help Tool" + changedObject == contentsModifiedChannel ifTrue:[ + modifiedHolder notNil ifTrue:[ + modifiedHolder value:true + ]. + ^ self + ]. + super update:something with:aParameter from:changedObject +! - self openHTMLDocument: 'tools/uipainter/HelpTool.html' +withoutModifyDo:aBlock + "discard modifications; trigger not the modifiedHolder during + the action is active. + " + |holder| + + holder := modifiedHolder. + + holder isNil ifTrue:[ + ^ aBlock value + ]. + ^ aBlock valueNowOrOnUnwindDo:[ modifiedHolder := holder ] ! ! !UIHelpTool methodsFor:'private'! askForModification - "asks for modification" + "asks for modification; launch a dialog if something is modified; + returns true if the modifications are accepted by user otherwise + false. + " + |dialog| - modified ifTrue:[ - ( (YesNoBox title: 'List was modified!!') - noText:'Cancel'; - yesText:'Waste it and proceed'; - showAtPointer; - accepted - ) ifFalse:[ - ^ false - ]. - modified := false + self modified ifTrue:[ + dialog := YesNoBox title:(resources string:'List was modified !!') + yesText:(resources string:'Forget it and proceed') + noText:(resources string:'Cancel'). + + dialog showAtPointer. + dialog accepted ifFalse:[^ false]. + self modified:false. ]. ^ true ! -dictionaryForClassNamed:clsName - "returns the directory assigned to a class name +extractResourceFrom:aString + "extracts class and selector from a resource string. On success + an association with the key a class and the selector as value + is returned. Otherwise nil is returned " - ^ dictionaries at:clsName - ifAbsentPut:[ self extractHelpSpecForClass: (Smalltalk at:clsName) ]. -! + |words newClass newSel| -extractHelpSpecForClass: aClass - "extracts the help dictionary of aClass, it current and return it" - - |helpSpecSuperClass superHelpSpecKeys helpSpec| + aString size ~~ 0 ifTrue:[ + words := aString asCollectionOfWords. - helpSpec := Dictionary new. + words size == 2 ifTrue:[ + newClass := self resolveName:(words first). - ((aClass class includesSelector: specSelector) - and: [(helpSpecSuperClass := aClass allSuperclasses detect: [:cls| cls class includesSelector: specSelector] ifNone: nil) notNil]) - ifTrue:[ - superHelpSpecKeys := (helpSpecSuperClass perform:specSelector) keys. + (newClass isClass and:[newClass isLoaded]) ifTrue:[ + newSel := words last asSymbol. - (aClass perform:specSelector) keysAndValuesDo:[:key :value | - (superHelpSpecKeys includes:key) ifFalse: [ - helpSpec at:key put:value - ] - ]. + (newClass class includesSelector:newSel) ifTrue:[ + ^ Association key:newClass value:newSel + ]. + ]. + ]. ]. - ^ helpSpec + ^ nil ! getHelpSpecClassFromClass:aClass - "returns application class keeping the associated help text or nil" - + "oops + " |cls| - ((cls := self resolveName:aClass) notNil and:[cls respondsTo: #helpSpecClass]) ifTrue:[ - ^cls helpSpecClass - ]. - ^cls + aClass notNil ifTrue:[ + cls := self resolveName:aClass. - -! + cls notNil ifTrue:[ + cls := cls perform:#helpSpecClass ifNotUnderstood:cls. -getUnformattedHelpText: aHelpText - "unformats aHelpText and returns it" - - |helpText| - - helpText := aHelpText asString copyReplaceAll:(Character cr) with:(Character space). - (helpText endsWith:(Character space)) ifTrue:[ - helpText := helpText copyWithoutLast:1 + (cls isClass and:[cls isLoaded]) ifTrue:[ + ^ cls + ]. + ]. ]. - ^ helpText - - "Modified: / 20.7.1998 / 13:17:52 / cg" + ^ nil ! -installHelpSpecOnClass:aClass - "saves the help dicts in aClass which is subclass of ApplicationModel" - - |cls src helpSpec| - - cls := self getHelpSpecClassFromClass: aClass. - - cls isNil ifTrue:[ - self information:'No application class defined!!'. - ^nil - ]. - - (cls isSubclassOf: ApplicationModel) ifFalse:[ - self information: 'Cannot save help spec into class ', cls name asBoldText, ',\because it is not a subclass of ApplicationModel!!' withCRs. - ^nil - ]. - - helpSpec := dictionaries - at: cls name - ifAbsent: [specClass notNil - ifTrue: [dictionaries at: aClass put: (self extractHelpSpecForClass: (Smalltalk at: aClass))] - ifFalse: [dictionary size > 0 ifTrue: [dictionary] ifFalse: [Dictionary new]]]. - - helpSpec associationsDo: - [:h| - helpSpec at: h key put: (self getUnformattedHelpText: h value) - ]. - - (cls class includesSelector: specSelector) - ifTrue: - [ - |superclassHelpKeys implementedHelpSpec hasChanged| - implementedHelpSpec := Dictionary new. - superclassHelpKeys := (cls superclass respondsTo: specSelector) - ifTrue: [(cls superclass perform:specSelector) keys] - ifFalse: [Array new]. - - (cls perform:specSelector) associationsDo: [:h| (superclassHelpKeys includes: h key) - ifFalse: [implementedHelpSpec at: h key put: h value]]. +loadFromMessage:aString + "Set and rebuild the specClass and specSelector from a resource string. + On success true is returned otherwise false. If the current spec is + modified, a dialog is launched. + " + |association| - hasChanged := false. - implementedHelpSpec associationsDo: [:h| (helpSpec includesAssociation: h) ifFalse: [hasChanged := true]]. - helpSpec associationsDo: [:h| (implementedHelpSpec includesAssociation: h) ifFalse: [hasChanged := true]]. - - (implementedHelpSpec notEmpty and: [hasChanged and: - [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 ']]) - ifTrue: - [ - implementedHelpSpec associationsDo: [:h| (helpSpec includesKey: h key) - ifFalse: [helpSpec at: h key put: h value]]. - ] - ]. - - helpSpec isEmpty ifTrue:[ - ^(cls superclass respondsTo: specSelector) ifTrue: [cls class removeSelector: specSelector]. - ]. - - src := '' writeStream. + association := self extractResourceFrom:aString. - src nextPutAll: - specSelector, '\' withCRs, - (ResourceSpecEditor codeGenerationCommentForClass: UIHelpTool) withCRs, - '\\' withCRs, - ' "\' withCRs, - ' UIHelpTool openOnClass:', cls name asString ,' - " - - - - ^super ', specSelector, ' addPairsFrom:#( - -'. - - helpSpec keys asSortedCollection do: - [:key| - src nextPutLine: key storeString. - src nextPutLine: (helpSpec at: key) storeString; cr. + association notNil ifTrue:[ + self askForModification ifTrue:[ + self buildFromClass:(association key) andSelector:(association value). + ^ true + ]. ]. - src nextPutLine:')'. - - Compiler - compile:(src contents) - forClass:cls class - inCategory:'help specs'. + ^ false ! -installHelpSpecsOnClass:aClass - "saves the help dicts on aClass and its superclasses which are subclasses of ApplicationModel" - - |cls helpSpecClasses| - - cls := self getHelpSpecClassFromClass:aClass. - - cls isNil ifTrue: [ - self information:'No application class defined!!'. - ^ self - ]. - - modified ifFalse:[ - masterApplication isNil ifTrue: [self information:'Nothing was modified!!']. - ^ self - ]. - helpSpecClasses := listOfClasses copy. - - helpSpecClasses notEmpty ifTrue:[ - (helpSpecClasses includes: cls name) ifFalse: [helpSpecClasses add: cls name]. - - helpSpecClasses do:[:clsName| - (self installHelpSpecOnClass: clsName) isNil ifTrue:[ - modified := false. - ^ self - ] - ]. - ] - ifFalse: - [ - self installHelpSpecOnClass: cls - ]. - - modified := false. -! +resourceMessage:aString + "Set the specClass and specSelector from a resource string. On + success true is returned otherwise false. + " + |association| -resourceMessage: aString - "extracts from aString the specClass and the specSelector" + association := self extractResourceFrom:aString. - (aString notNil and: [self askForModification]) - ifTrue: - [ - |msg cls sel| - msg := aString asCollectionOfWords. - (msg size == 2 and: - [(cls := self resolveName:(msg at:1)) notNil]) - ifTrue: - [ - specClass := cls name. - specSelector := (msg at: 2) asSymbol. - ^true - ] + association notNil ifTrue:[ + specClass := association key. + specSelector := association value. + ^ true ]. - ^false - -! - -updateList - "updates the list of keys - " - |key| - - listOfKeysModel setValue:nil. - listOfKeys contents:(dictionary keys asSortedCollection). - - key := self helpKey. - - (key notNil and:[listOfKeys includes:key]) ifFalse:[ - key := nil. - ]. - listOfKeysModel triggerValue:key + ^ false ! ! -!UIHelpTool methodsFor:'startup / release'! +!UIHelpTool methodsFor:'startup & release'! closeRequest - "asks for permission before closing" - - (self masterApplication isNil and:[self askForModification]) ifTrue:[ - super closeRequest - ] + "asks for permission before closing + " + (masterApplication isNil and:[self askForModification]) ifTrue:[ + super closeRequest. + ]. ! initialize - "initializes instance variables" + "setup default attributes + " + super initialize. + self createBuilder. - super initialize. + specSelector := #helpSpec. + + classItemList := List new. - specSelector := #helpSpec. - dictionary := Dictionary new. - dictionaries := Dictionary new. - modified := false. + classItemModel := nil asValue. + classItemModel addDependent:self. + + keyItemModel := nil asValue. + keyItemModel addDependent:self. + + contentsModifiedChannel := false asValue. + contentsModifiedChannel addDependent:self. + + helpTextView := EditTextView new. + helpTextView acceptAction:[:dummy| self accept ]. + helpTextView modifiedChannel:contentsModifiedChannel. editModel := nil asValue. editModel addDependent:self. - listOfKeys := List new. - listOfKeysModel := nil asValue. - listOfKeysModel addDependent:self. - - listOfClasses := List new. - listOfClassesModel := nil asValue. - listOfClassesModel addDependent:self. - - contentsModifiedChannel := false asValue. - contentsModifiedChannel addDependent:self. -! - -loadFromMessage:aString - "loads a help spec by evaluating aString" - - (aString notNil and: [self askForModification]) - ifTrue: - [ - |msg cls sel| - msg := aString asCollectionOfWords. - (msg size == 2 and: - [(cls := self resolveName:(msg at:1)) notNil and: - [cls class includesSelector: (sel := (msg at: 2) asSymbol)]]) - ifTrue: - [ - self buildFromClass: (specClass := cls name) andSelector: (specSelector := sel). - ^true - ] - ]. - ^false + self buildFromClass:nil. ! openInterface:aSymbol - "do not open as stand alone" - - - + "do not open as stand alone + " ! openOnClass:aClass - "opens the UIHelpTool on aClass" - + "opens the UIHelpTool on aClass + " self openOnClass:aClass andSelector:nil - - " - self openOnClass:NewLauncher - " ! openOnClass:aClass andSelector: aSelector "opens the UIHelpTool on aClass and aSelector" - super openInterface: #windowSpecForStandAlone. + super openInterface:#windowSpecForStandAlone. builder window label: 'Help Tool'. self buildFromClass:aClass andSelector:aSelector -! - -postBuildTextView:aView - - editTextView := aView scrolledView. - editTextView acceptAction:[:dummy| self accept ]. ! ! !UIHelpTool methodsFor:'user actions'! accept - "accepts the help text" + "accepts the help text + " + |helpKey helpItem root| - |key txt| - - key := self helpKey. - key isNil ifTrue:[^ self]. + helpKey := self helpKey. + helpKey isNil ifTrue:[^ self]. - contentsModifiedChannel value ifFalse:[ - (dictionary includes:key) ifTrue:[^ self]. - ]. - contentsModifiedChannel value:false. + root := classItemModel value. + root isNil ifTrue:[^ self]. + + helpItem := root detectItemWithKey:helpKey. - txt := editTextView contents ? ''. - txt := txt asString. - - dictionary at:key put:txt. - - listOfKeys detect:[:el| el = key ] ifNone:[ |idx| - idx := listOfKeys findFirst:[:el| el > key ]. - idx == 0 ifTrue:[ listOfKeys add:key ] - ifFalse:[ listOfKeys add:key beforeIndex:idx] + helpItem isNil ifTrue:[ + helpItem := KeyItem helpKey:helpKey helpText:(helpTextView contents). + root add:helpItem sortBlock:[:a :b| a label < b label ]. + ] ifFalse:[ + helpItem helpText:(helpTextView contents). ]. - listOfKeysModel value:key withoutNotifying:self. - - modified := true. - modifiedHolder notNil ifTrue:[ modifiedHolder value:true ]. + contentsModifiedChannel value:false. + keyItemModel triggerValue:helpItem. ! cancel - |key txt| + "cancel modifications, reload helpText + " + |item contents modified| - editTextView notNil ifTrue:[ - key := listOfKeysModel value. + item := keyItemModel value. + modified := false. - key notNil ifTrue:[ - txt := dictionary at:key ifAbsent:nil. - ] ifFalse:[ - txt := nil - ]. - editTextView contents:txt. + item notNil ifTrue:[ + contents := item helpText. + ] ifFalse:[ + contents := nil. + + modifiedHolder isNil ifTrue:[ + modified := self helpKey notNil + ] ]. - contentsModifiedChannel value:false. + helpTextView contents:contents. + contentsModifiedChannel value:modified. ! doDelete "deletes the selected help key " - |key| - - key := listOfKeysModel value. - - key isNil ifTrue:[ - self warn:'No key selected !!'. - ^ self - ]. + |item| - listOfKeysModel value:nil. - - key := key asSymbol. - listOfKeys remove:key ifAbsent:nil. - - (dictionary removeKey:key ifAbsent:nil) notNil ifTrue:[ - modified := true. - modifiedHolder notNil ifTrue: [modifiedHolder value:true]. - ]. + item := keyItemModel value. + item notNil ifTrue:[ item remove ]. + editModel value:nil. ! doLoad - "opens a Resource Selection Browser in order to get a resource message" - + "opens a Resource Selection Browser in order to get a resource message + " self loadFromMessage: - (ResourceSelectionBrowser - request: 'Load Help Spec From Class' - onSuperclass: nil - andClass: specClass - andSelector: specSelector ? #help - withResourceTypes: (Array with: #help)). + (ResourceSelectionBrowser + request: 'Load Help Spec From Class' + onSuperclass: nil + andClass: specClass + andSelector: specSelector ? #help + withResourceTypes: (Array with: #help)). self updateInfoLabel - ! doNew - "resets the help tool" - - specClass := nil. - - editModel value:nil withoutNotifying:self. - listOfKeysModel value:nil. - listOfClassesModel value:nil. - - listOfKeys removeAll. - listOfClasses removeAll. - dictionaries removeAll. - - dictionary := Dictionary new. - modified := false. + "reset all to empty + " + contentsModifiedChannel value:false. + self helpKey:nil. + self buildFromClass:nil. ! doSave - "saves the help dictionaries on specClass" + "save the help spec to the spec-class(es) + " + specClass isNil ifTrue:[ + self information:(resources string:'No class specified !!'). + ^ nil + ]. + (specClass isSubclassOf:ApplicationModel) ifFalse:[ + self information:(resources string:'Cannot save help into none Application class'). + ^ nil + ]. + + classItemList do:[:aClassItem| aClassItem createHelpMethodNamed:specSelector ]. +! + +openDocumentation + "opens the documentation file of the Help Tool + " + self openHTMLDocument: 'tools/uipainter/HelpTool.html' +! ! + +!UIHelpTool::ClassItem class methodsFor:'instance creation'! + +onClass:aClass + |root| + + root := self new. + root onClass:aClass. + ^ root +! ! + +!UIHelpTool::ClassItem methodsFor:'accessing'! + +list + "returns the hierarchical list assigned to the classItem; the + list contains the keyItems + " + list isNil ifTrue:[ + list := HierarchicalList new. + list showRoot:false. + list root:self. + ]. + ^ list +! + +theClass + "returns the class or nil if unspecified + " + ^ theClass +! ! + +!UIHelpTool::ClassItem methodsFor:'change & update'! + +helpTextChangedFor:anItem + "called if an helpKey changed its contents + " + self model notNil ifTrue:[ + self modified:true. + anItem modified:true. + ]. +! ! + +!UIHelpTool::ClassItem methodsFor:'code generation'! + +createHelpMethodNamed:aMethodName + |stream| + + (modified and:[theClass notNil]) ifFalse:[ + ^ self + ]. + stream := '' writeStream. + + stream nextPutAll: + aMethodName, '\' withCRs, + (ResourceSpecEditor codeGenerationCommentForClass:UIHelpTool) withCRs, + '\\' withCRs, + ' "\' withCRs, + ' UIHelpTool openOnClass:', theClass name asString ,' + " + + + + ^ super ', aMethodName, ' addPairsFrom:#( + +'. + + self do:[:aKeyItem| |helpText| + helpText := aKeyItem helpText. + helpText isNil ifTrue:[ helpText := '' ]. + + stream nextPutLine:(aKeyItem helpKey storeString). + stream nextPutLine:(helpText storeString); cr. + ]. + stream nextPutLine:')'. + + Compiler + compile:(stream contents) + forClass:theClass class + inCategory:'help specs'. + + self modified:false. +! ! + +!UIHelpTool::ClassItem methodsFor:'displaying'! + +icon + "returns the display icon (always nil) + " + ^ nil +! + +label + "returns the display label + " + |label| + + theClass notNil ifTrue:[ label := theClass name ] + ifFalse:[ label := '** not yet defined **' ]. + + modified ifTrue:[ + label := Text string:label color:(Color red). + ]. + ^ label +! ! + +!UIHelpTool::ClassItem methodsFor:'instance creation'! + +initialize + "setup defaults + " + super initialize. + + children := OrderedCollection new. + isExpanded := true. + modified := false. +! + +onClass:aClass + "the class the ys are assigned to; if the class is nil, + the class is not yet specified. + " + theClass := aClass. +! ! + +!UIHelpTool::ClassItem methodsFor:'private'! + +basicAdd:aChild sortBlock:aBlock + "catch low-level add to update the modification flag + " + self modified:true. + aChild modified:true. + + ^ super basicAdd:aChild sortBlock:aBlock. +! + +basicAddAll:aList beforeIndex:anIndex + "catch low-level add to update the modification flag + " + self modified:true. + + aList do:[:el| el modified:true ]. + ^ super basicAddAll:aList beforeIndex:anIndex. +! - self installHelpSpecsOnClass:specClass +basicRemoveFromIndex:startIndex toIndex:stopIndex + "catch low-level remove to update the modification flag + " + self isUnspecified ifFalse:[ + self modified:true. + ]. + ^ super basicRemoveFromIndex:startIndex toIndex:stopIndex +! ! + +!UIHelpTool::ClassItem methodsFor:'queries'! + +isUnspecified + "true if the class is unspecified + " + ^ theClass isNil +! + +modified + "true, if any item is modified, created or deleted + " + ^ modified +! + +modified:aBoolean + "true, if any item is modified, created or deleted + " + modified ~~ aBoolean ifTrue:[ + modified := aBoolean. + + modified ifFalse:[ + self do:[:el| el modified:false ]. + ]. + ]. +! ! + +!UIHelpTool::ClassItem methodsFor:'searching'! + +detectItemWithKey:aKey + "returns the item assigned to a helpKey or nil + " + |key| + + aKey size ~~ 0 ifTrue:[ + key := aKey asSymbol. + + self do:[:anItem| + anItem helpKey == key ifTrue:[ ^ anItem ]. + ] + ]. + ^ nil +! ! + +!UIHelpTool::KeyItem class methodsFor:'instance creation'! + +helpKey:aKey helpText:aText + |key| + + key := self new. + key helpKey:aKey helpText:aText. + ^ key +! ! + +!UIHelpTool::KeyItem methodsFor:'accessing'! + +helpKey + "returns the helpKey, a symbol + " + ^ helpKey +! + +helpText + "returns the contents assigned to the helpKey or nil + " + ^ helpText +! + +helpText:aText + "set the contents assigned to the helpKey; if the cxontents changed, + a notification is raised. + " + |text| + + text := self formatText:aText. + + text ~= helpText ifTrue:[ + helpText := text. + + (modified or:[parent isNil]) ifFalse:[ + parent helpTextChangedFor:self. + ] + ]. +! ! + +!UIHelpTool::KeyItem methodsFor:'displaying'! + +icon + "returns the display icon (always nil) + " + ^ nil +! + +label + "returns the display label + " + modified ifTrue:[ + ^ Text string:helpKey color:(Color red) + ]. + ^ helpKey +! ! + +!UIHelpTool::KeyItem methodsFor:'instance creation'! + +helpKey:aKey helpText:aText + "set the key and contents without a change notification + " + helpKey := aKey asSymbol. + helpText := self formatText:aText. +! + +initialize + "setup defaults + " + super initialize. + children := #(). + modified := false. +! ! + +!UIHelpTool::KeyItem methodsFor:'private'! + +formatText:aText + "format the text, replace carriage return by spaces and compress spaces + " + |text result| + + aText size ~~ 0 ifTrue:[ + text := aText asString asCollectionOfWords. + + text notEmpty ifTrue:[ + result := text first. + + text from:2 do:[:t| result := result, ' ', t ]. + ^ result + ]. + ]. + ^ nil +! ! + +!UIHelpTool::KeyItem methodsFor:'queries'! + +modified + "returns true if the helpText is modified + " + ^ modified +! + +modified:aBoolean + "set the modification flag + " + aBoolean == modified ifFalse:[ + modified := aBoolean. + self changed:#redraw. + ]. ! ! !UIHelpTool class methodsFor:'documentation'! diff -r 3e83796a3e0e -r e6ea33c843a0 UIPainter.st --- a/UIPainter.st Sat Dec 21 14:11:41 2002 +0100 +++ b/UIPainter.st Wed Jan 08 13:16:05 2003 +0100 @@ -2186,7 +2186,6 @@ layoutTool modifiedHolder:modifiedChannel. helpTool := UIHelpTool new. - helpTool createBuilder. applBuilder := helpTool builder. applWindow := ApplicationSubView origin:0.0@0.0 corner:1.0@1.0 in:noteBook. applWindow level:0. @@ -2363,19 +2362,17 @@ editor := MenuEditor new. editor masterApplication:self. editor specClass: cls. - editor useHelpTool: self helpTool. + editor useHelpTool:(self helpTool). selectorOrMenu class ~~ Menu ifTrue: [editor openModalOnClass:cls andSelector:selectorOrMenu] ifFalse: [editor openModalOnMenu:selectorOrMenu]. - self helpTool updateList. - editor hasSaved ifTrue:[ holder := self specTool aspectFor:#menuSelector. holder value:(editor specSelector). self accept. - ^ self + ^ self ]. ! @@ -2874,9 +2871,7 @@ ifFalse:[aClass]. self helpTool buildFromClass:specClass. - self helpTool updateList. self clearModifiedFlag. - ! ! !UIPainter methodsFor:'private tools'! @@ -3840,10 +3835,9 @@ (ReadStream on:code) fileIn. self doGenerateAspectSelectorsMethod. - - self helpTool installHelpSpecsOnClass:specClass. - + self helpTool doSave. self updateInfoLabel. + modified := false. painter resetModification. (cls class includesSelector: specSelector) ifTrue:[