MenuEditor.st
changeset 1244 fd44af858001
parent 1200 3d1b5aceaa49
child 1246 c5425b3c8f3e
--- a/MenuEditor.st	Mon Sep 27 13:48:04 1999 +0200
+++ b/MenuEditor.st	Mon Sep 27 14:04:03 1999 +0200
@@ -13,7 +13,8 @@
 
 
 ResourceSpecEditor subclass:#MenuEditor
-	instanceVariableNames:'specCanvas helpCanvas slices'
+	instanceVariableNames:'treeView typeOfCanvas listOfCanvas listOfSlices
+		lastImageRetriever slices'
 	classVariableNames:''
 	poolDictionaries:''
 	category:'Interface-UIPainter'
@@ -364,7 +365,7 @@
           #name: 'Basics Item'
           #min: #(#Point 10 10)
           #max: #(#Point 1160 870)
-          #bounds: #(#Rectangle 220 200 487 519)
+          #bounds: #(#Rectangle 273 266 540 585)
         )
         #component: 
        #(#SpecCollection
@@ -379,11 +380,11 @@
             )
            #(#InputFieldSpec
               #name: 'nameKeyField'
-              #layout: #(#LayoutFrame 110 0 15 0 -5 1.0 37 0)
+              #layout: #(#LayoutFrame 110 0 16 0 -5 1.0 38 0)
               #activeHelpKey: #basicsKey
               #tabable: true
               #model: #nameKey
-              #group: #inputGroup
+              #group: #inputGroup1
               #type: #symbolOrNil
               #acceptOnLeave: false
               #acceptOnReturn: true
@@ -407,7 +408,7 @@
               #activeHelpKey: #basicsLabel
               #tabable: true
               #model: #label
-              #group: #inputGroup
+              #group: #inputGroup1
               #acceptOnReturn: true
               #acceptOnTab: true
               #acceptOnLostFocus: false
@@ -429,7 +430,7 @@
               #activeHelpKey: #basicsAction
               #tabable: true
               #model: #value
-              #group: #inputGroup
+              #group: #inputGroup1
               #type: #symbolOrNil
               #acceptOnReturn: true
               #acceptOnTab: true
@@ -452,7 +453,7 @@
               #activeHelpKey: #basicsArgument
               #tabable: true
               #model: #argument
-              #group: #inputGroup
+              #group: #inputGroup1
               #type: #smalltalkObject
               #acceptOnReturn: true
               #acceptOnTab: true
@@ -476,7 +477,7 @@
               #enableChannel: #indicationEnabled
               #tabable: true
               #model: #indication
-              #group: #inputGroup
+              #group: #inputGroup1
               #type: #symbolOrNil
               #immediateAccept: true
               #acceptOnReturn: true
@@ -502,7 +503,7 @@
               #enableChannel: #choiceEnabled
               #tabable: true
               #model: #choice
-              #group: #inputGroup
+              #group: #inputGroup1
               #type: #symbolOrNil
               #immediateAccept: true
               #acceptOnReturn: true
@@ -528,7 +529,7 @@
               #enableChannel: #choiceValueEnabled
               #tabable: true
               #model: #choiceValue
-              #group: #inputGroup
+              #group: #inputGroup1
               #type: #smalltalkObject
               #acceptOnLeave: false
               #acceptOnReturn: true
@@ -581,14 +582,9 @@
        #(#WindowSpec
           #label: 'Basics Link'
           #name: 'Basics Link'
-          #layout: #(#LayoutFrame 8 0 143 0 274 0 461 0)
-          #level: 0
           #min: #(#Point 10 10)
           #max: #(#Point 1280 1024)
-          #bounds: #(#Rectangle 8 143 275 462)
-          #usePreferredExtent: false
-          #returnIsOKInDialog: true
-          #escapeIsCancelInDialog: true
+          #bounds: #(#Rectangle 94 229 361 548)
         )
         #component: 
        #(#SpecCollection
@@ -607,7 +603,7 @@
               #activeHelpKey: #basicsNameKey
               #tabable: true
               #model: #nameKey
-              #group: #inputGroup
+              #group: #inputGroup2
               #type: #symbolOrNil
               #acceptOnReturn: true
               #acceptOnTab: true
@@ -627,7 +623,7 @@
               #activeHelpKey: #basicsLabel
               #tabable: true
               #model: #label
-              #group: #inputGroup
+              #group: #inputGroup2
               #acceptOnReturn: true
               #acceptOnTab: true
               #acceptChannel: #acceptChannel
@@ -646,7 +642,7 @@
               #activeHelpKey: #basicsMenu
               #tabable: true
               #model: #submenuChannel
-              #group: #inputGroup
+              #group: #inputGroup2
               #type: #symbolOrNil
               #acceptOnReturn: true
               #acceptOnTab: true
@@ -666,7 +662,7 @@
               #activeHelpKey: #basicsMenuArgument
               #tabable: true
               #model: #argument
-              #group: #inputGroup
+              #group: #inputGroup2
               #acceptOnReturn: true
               #acceptOnTab: true
               #acceptChannel: #acceptChannel
@@ -708,14 +704,9 @@
        #(#WindowSpec
           #label: 'Basics Menu'
           #name: 'Basics Menu'
-          #layout: #(#LayoutFrame 50 0 134 0 316 0 452 0)
-          #level: 0
           #min: #(#Point 10 10)
           #max: #(#Point 1280 1024)
-          #bounds: #(#Rectangle 50 134 317 453)
-          #usePreferredExtent: false
-          #returnIsOKInDialog: true
-          #escapeIsCancelInDialog: true
+          #bounds: #(#Rectangle 93 223 360 542)
         )
         #component: 
        #(#SpecCollection
@@ -733,7 +724,7 @@
               #activeHelpKey: #basicsNameKey
               #tabable: true
               #model: #nameKey
-              #group: #inputGroup
+              #group: #inputGroup3
               #type: #symbolOrNil
               #acceptOnReturn: true
               #acceptOnTab: true
@@ -754,7 +745,7 @@
               #activeHelpKey: #basicsLabel
               #tabable: true
               #model: #label
-              #group: #inputGroup
+              #group: #inputGroup3
               #acceptOnReturn: true
               #acceptOnTab: true
               #acceptChannel: #acceptChannel
@@ -930,14 +921,9 @@
        #(#WindowSpec
           #label: 'Details Edit'
           #name: 'Details Edit'
-          #layout: #(#LayoutFrame 28 0 94 0 342 0 377 0)
-          #level: 0
           #min: #(#Point 10 10)
           #max: #(#Point 1280 1024)
-          #bounds: #(#Rectangle 28 94 343 378)
-          #usePreferredExtent: false
-          #returnIsOKInDialog: true
-          #escapeIsCancelInDialog: true
+          #bounds: #(#Rectangle 5 175 320 459)
         )
         #component: 
        #(#SpecCollection
@@ -956,12 +942,13 @@
               #activeHelpKey: #detailsAccelerator
               #tabable: true
               #model: #shortcutKey
-              #group: #inputGroup
+              #group: #inputGroup4
               #type: #symbolOrNil
               #acceptOnReturn: true
               #acceptOnTab: true
               #acceptChannel: #acceptChannel
               #modifiedChannel: #modifiedChannel
+              #acceptOnPointerLeave: false
             )
            #(#LabelSpec
               #label: 'Enabled:'
@@ -977,12 +964,13 @@
               #activeHelpKey: #detailsEnabled
               #tabable: true
               #model: #enabled
-              #group: #inputGroup
+              #group: #inputGroup4
               #type: #symbolOrNil
               #acceptOnReturn: true
               #acceptOnTab: true
               #acceptChannel: #acceptChannel
               #modifiedChannel: #modifiedChannel
+              #acceptOnPointerLeave: false
             )
            #(#LabelSpec
               #label: 'Visibility:'
@@ -998,12 +986,36 @@
               #activeHelpKey: #detailsVisibility
               #tabable: true
               #model: #isVisible
-              #group: #inputGroup
+              #group: #inputGroup4
               #type: #symbolOrNil
               #acceptOnReturn: true
               #acceptOnTab: true
               #acceptChannel: #acceptChannel
               #modifiedChannel: #modifiedChannel
+              #acceptOnPointerLeave: false
+            )
+           #(#LabelSpec
+              #label: 'Aux Value'
+              #name: 'auxLabel'
+              #layout: #(#AlignmentOrigin 107 0 101 0 1 0.5)
+              #activeHelpKey: #detailsAuxValue
+              #translateLabel: true
+              #resizeForLabel: true
+              #adjust: #right
+            )
+           #(#InputFieldSpec
+              #name: 'auxInputField'
+              #layout: #(#LayoutFrame 110 0 90 0 -5 1.0 112 0)
+              #activeHelpKey: #detailsAuxValue
+              #tabable: true
+              #model: #auxValue
+              #group: #inputGroup4
+              #type: #smalltalkObject
+              #acceptOnReturn: true
+              #acceptOnTab: true
+              #acceptChannel: #acceptChannel
+              #modifiedChannel: #modifiedChannel
+              #acceptOnPointerLeave: false
             )
            #(#LabelSpec
               #label: 'Start Group:'
@@ -1021,7 +1033,8 @@
               #tabable: true
               #model: #startGroup
               #menu: 
-             #(nil
+             #(#Array
+                #Array nil
                 #right
               )
               #useIndex: false
@@ -1040,35 +1053,14 @@
               #activeHelpKey: #detailsAccessCharaterPosition
               #tabable: true
               #model: #accessCharacterPos
-              #group: #inputGroup
+              #group: #inputGroup4
               #type: #numberOrNil
               #immediateAccept: false
               #acceptOnReturn: true
               #acceptOnTab: true
               #acceptChannel: #acceptChannel
               #modifiedChannel: #modifiedChannel
-            )
-           #(#LabelSpec
-              #label: 'Aux Value'
-              #name: 'auxLabel'
-              #layout: #(#AlignmentOrigin 107 0 101 0 1 0.5)
-              #activeHelpKey: #detailsAuxValue
-              #translateLabel: true
-              #resizeForLabel: true
-              #adjust: #right
-            )
-           #(#InputFieldSpec
-              #name: 'auxInputField'
-              #layout: #(#LayoutFrame 110 0 90 0 -5 1.0 112 0)
-              #activeHelpKey: #detailsAuxValue
-              #tabable: true
-              #model: #auxValue
-              #group: #inputGroup
-              #type: #smalltalkObject
-              #acceptOnReturn: true
-              #acceptOnTab: true
-              #acceptChannel: #acceptChannel
-              #modifiedChannel: #modifiedChannel
+              #acceptOnPointerLeave: false
             )
            )
          
@@ -1097,14 +1089,9 @@
        #(#WindowSpec
           #label: 'Image Item'
           #name: 'Image Item'
-          #layout: #(#LayoutFrame 21 0 108 0 416 0 384 0)
-          #level: 0
           #min: #(#Point 10 10)
           #max: #(#Point 1280 1024)
-          #bounds: #(#Rectangle 21 108 417 385)
-          #usePreferredExtent: false
-          #returnIsOKInDialog: true
-          #escapeIsCancelInDialog: true
+          #bounds: #(#Rectangle 11 177 407 454)
         )
         #component: 
        #(#SpecCollection
@@ -1152,7 +1139,7 @@
               #activeHelpKey: #imageSelector
               #tabable: true
               #model: #icon
-              #group: #inputGroup
+              #group: #inputGroup5
               #type: #symbolOrNil
               #acceptOnReturn: true
               #acceptOnTab: true
@@ -1210,82 +1197,82 @@
 
     <resource: #canvas>
 
-    ^
-     
-       #(#FullSpec
-          #window: 
-           #(#WindowSpec
-              #name: 'Menu Editor'
-              #layout: #(#LayoutFrame 53 0 403 0 609 0 810 0)
-              #label: 'Menu Editor'
-              #min: #(#Point 510 390)
-              #max: #(#Point 1152 900)
-              #bounds: #(#Rectangle 53 403 610 811)
-              #menu: #menu
-              #usePreferredExtent: false
-          )
-          #component: 
-           #(#SpecCollection
-              #collection: 
-               #(
-                 #(#MenuPanelSpec
-                    #name: 'menuToolbarView'
-                    #layout: #(#LayoutFrame 0 0.0 0 0 0 1.0 32 0)
-                    #menu: #menuToolbar
-                    #showSeparatingLines: true
-                )
-                 #(#VariableHorizontalPanelSpec
-                    #name: 'VariableHorizontalPanel'
-                    #layout: #(#LayoutFrame 0 0.0 34 0.0 0 1.0 -26 1.0)
+    ^ 
+     #(#FullSpec
+        #name: #windowSpec
+        #window: 
+       #(#WindowSpec
+          #label: 'Menu Editor'
+          #name: 'Menu Editor'
+          #min: #(#Point 550 440)
+          #max: #(#Point 1152 900)
+          #bounds: #(#Rectangle 162 299 719 739)
+          #menu: #menu
+        )
+        #component: 
+       #(#SpecCollection
+          #collection: #(
+           #(#MenuPanelSpec
+              #name: 'menuToolbarView'
+              #layout: #(#LayoutFrame 0 0.0 0 0 0 1.0 32 0)
+              #menu: #menuToolbar
+              #showSeparatingLines: true
+            )
+           #(#VariableHorizontalPanelSpec
+              #name: 'VariableHorizontalPanel'
+              #layout: #(#LayoutFrame 0 0.0 34 0.0 0 1.0 -26 1.0)
+              #component: 
+             #(#SpecCollection
+                #collection: #(
+                 #(#ArbitraryComponentSpec
+                    #name: 'TreeView'
+                    #menu: #menuEdit
+                    #hasHorizontalScrollBar: true
+                    #hasVerticalScrollBar: true
+                    #hasBorder: false
+                    #component: #treeView
+                  )
+                 #(#ViewSpec
+                    #name: 'Box'
+                    #level: -1
                     #component: 
-                     #(#SpecCollection
-                        #collection: 
-                         #(
-                           #(#ArbitraryComponentSpec
-                              #name: 'TreeView'
-                              #menu: #menuEdit
-                              #hasHorizontalScrollBar: true
-                              #hasVerticalScrollBar: true
-                              #component: #treeView
-                              #hasBorder: false
-                          )
-                           #(#ViewSpec
-                              #name: 'Box'
-                              #component: 
-                               #(#SpecCollection
-                                  #collection: 
-                                   #(
-                                     #(#NoteBookViewSpec
-                                        #name: 'NoteBook'
-                                        #layout: #(#LayoutFrame 1 0.0 0 0.0 1 1.0 -30 1.0)
-                                        #tabable: true
-                                        #model: #tabModel
-                                        #menu: #tabList
-                                        #useIndex: true
-                                        #canvas: #noteBookView
-                                    )
-                                     #(#UISubSpecification
-                                        #name: 'SubSpecification'
-                                        #layout: #(#LayoutFrame 2 0.0 -26 1 -2 1.0 -2 1.0)
-                                        #majorKey: #ToolApplicationModel
-                                        #minorKey: #windowSpecForCommit
-                                    )
-                                  )
-                              )
-                              #level: -1
-                          )
+                   #(#SpecCollection
+                      #collection: #(
+                       #(#NoteBookViewSpec
+                          #name: 'NoteBook'
+                          #layout: #(#LayoutFrame 1 0.0 0 0.0 1 1.0 -30 1.0)
+                          #enableChannel: #hasAnySingleSelection
+                          #tabable: true
+                          #model: #tabModel
+                          #menu: #tabList
+                          #useIndex: true
+                          #canvas: #tabCanvasHolder
+                          #keepCanvasAlive: true
+                        )
+                       #(#UISubSpecification
+                          #name: 'SubSpecification'
+                          #layout: #(#LayoutFrame 2 0.0 -26 1 -2 1.0 -2 1.0)
+                          #majorKey: #ToolApplicationModel
+                          #minorKey: #windowSpecForCommit
                         )
+                       )
+                     
                     )
-                    #handles: #(#Any 0.30117 1.0)
-                )
-                 #(#UISubSpecification
-                    #name: 'InfoBarSubSpec'
-                    #layout: #(#LayoutFrame 0 0.0 -24 1 0 1.0 0 1.0)
-                    #majorKey: #ToolApplicationModel
-                    #minorKey: #windowSpecForInfoBar
-                )
+                  )
+                 )
+               
               )
-          )
+              #handles: #(#Any 0.346499 1.0)
+            )
+           #(#UISubSpecification
+              #name: 'InfoBarSubSpec'
+              #layout: #(#LayoutFrame 0 0.0 -24 1 0 1.0 0 1.0)
+              #majorKey: #ToolApplicationModel
+              #minorKey: #windowSpecForInfoBar
+            )
+           )
+         
+        )
       )
 ! !
 
@@ -1951,8 +1938,7 @@
 
     |menu cls|
 
-    (menu := self treeView asMenu) allItemsDo:
-    [:anItem|
+    (menu := treeView asMenu) allItemsDo:[:anItem|
         anItem value:nil.
         anItem enabled:true.
     ].
@@ -1965,11 +1951,11 @@
 useHelpTool: aHelpTool
     "take the help dictionaries from aHelpTool into my helpTool"
 
-    self noteBookView.
-
     self helpTool buildFromClass: aHelpTool specClass.
     self helpTool dictionaries:   aHelpTool dictionaries.
     self helpTool dictionary:     aHelpTool dictionary
+
+
 ! !
 
 !MenuEditor methodsFor:'aspects'!
@@ -1984,44 +1970,17 @@
     ^builder booleanValueAspectFor: #hasValidSelection
 !
 
-hasValidSingleSelection
-
-    ^builder booleanValueAspectFor: #hasValidSingleSelection
-!
-
 listOfImages
-    "get a list of the images"
-
-    |holder|
-    (holder := builder bindingAt:#listOfImages) isNil ifTrue:[
-        builder aspectAt:#listOfImages put: (holder := List new).
-        self updateListOfImages    
+    "get a list of the images
+    "
+    |list|
+
+    (list := builder bindingAt:#listOfImages) isNil ifTrue:[
+        builder aspectAt:#listOfImages put: (list := List new).
     ].
-    ^ holder
-
-
-!
-
-noteBookView
-    "create the note book view containing the attibute sections and the help tool"
-
-    |noteBook helpTool|
-
-    (noteBook := builder bindingAt:#noteBookView) isNil ifTrue:[
-        noteBook := View new.
-        helpTool := UIHelpTool new.
-
-        helpTool masterApplication:self.
-        helpCanvas := SubCanvas origin:0.0@0.0 corner:1.0@1.0 in:noteBook.
-        specCanvas := SubCanvas origin:0.0@0.0 corner:1.0@1.0 in:noteBook.
-
-        helpCanvas client:helpTool.
-        helpTool masterApplication:self.      
-        helpTool modifiedHolder: self valueOfEnablingCommitButtons.
-
-        builder aspectAt:#noteBookView put:noteBook.
-    ].
-    ^ noteBook
+    ^ list
+
+
 !
 
 selectionOfImage
@@ -2036,12 +1995,26 @@
 
 !
 
+tabCanvasHolder
+    "keep the canvas for the current selected item or nil
+    "
+    |holder|
+
+    (holder := builder bindingAt:#tabCanvasHolder) isNil ifTrue:[
+        builder aspectAt:#tabCanvasHolder put: (holder := nil asValue).
+    ].
+    ^ holder
+
+
+!
+
 tabList
     "get a value holder with the list of the attribute sections (slices)"
 
     |holder|
+
     (holder := builder bindingAt:#tabList) isNil ifTrue:[
-        builder aspectAt:#tabList put:(holder := #(Basics Details Image Help) asValue).
+        builder aspectAt:#tabList put:(holder := nil asValue).
     ].
     ^ holder
 
@@ -2051,13 +2024,7 @@
 treeView
     "get a tree view representing hierarchically the menu items"
 
-    |treeView|
-    (treeView := builder bindingAt:#treeView) isNil ifTrue:[
-        treeView := TreeView new.
-        treeView action:[:dummy|self menuChanged].
-        builder aspectAt: #treeView put: treeView
-    ].
-    ^treeView
+    ^ treeView
 ! !
 
 !MenuEditor methodsFor:'building'!
@@ -2067,19 +2034,20 @@
     self isStandAlone ifTrue:[
         self helpTool buildFromClass:specClass
     ].              
-    self treeView buildFromClass: aClass andSelector: aSelector.
+    treeView buildFromClass: aClass andSelector: aSelector.
 
     self updateHistory.
     self updateInfoLabel.
-    self treeView selection: 2.
-    self menuChanged
 
 !
 
-buildFromResourceSpec: aResourceSpec
-
-    self buildFromMenu:  
-        (aResourceSpec class == Menu ifTrue: [aResourceSpec] ifFalse: [aResourceSpec decodeAsLiteralArray])
+buildFromResourceSpec:aResourceSpec
+    |spec|
+
+    spec := aResourceSpec isCollection ifTrue:[aResourceSpec decodeAsLiteralArray]
+                                      ifFalse:[aResourceSpec].
+
+    self buildFromMenu:spec  
 ! !
 
 !MenuEditor methodsFor:'change & update'!
@@ -2088,8 +2056,7 @@
     super update:something with:aParameter from:changedObject.
 
     changedObject == (aspects at:#retriever) ifTrue:[
-        "/ self updateListOfImages.
-        self updateSelectionOfImage
+        self updateImageView.
     ].
 
     "Modified: / 24.8.1998 / 21:47:48 / cg"
@@ -2098,82 +2065,79 @@
 updateChannels
     "update channels"
 
-    |node parent next state|
-
-    self clearModifiedFlag.
+    |node parent next state canPaste|
+
     state := false.   
-    self updateSelectionOfImage.
-
-    (node  := self treeView selectedNode) notNil
-    ifTrue:
-    [
+    node  := treeView selectedNode.
+
+    node notNil ifTrue:[
         self hasAnySingleSelection value:true.
-        (parent := node parent) notNil
-        ifTrue:
-        [
+        canPaste := self valueOfCanPaste value.
+
+        (parent := node parent) notNil ifTrue:[
             next := parent childAt:((parent indexOfChild:node) + 1).
             self valueOfEnableMovingIn       value:(next notNil and:[next hasChildren]).
             self valueOfEnableMovingUpOrDown value:(parent children size > 1).
             self valueOfEnableMovingOut      value:parent parent notNil.
-            self hasValidSingleSelection     value:true.
             self hasValidSelection           value:true.  
-            self valueOfCanPaste             value:true & self valueOfCanPaste value. 
-            ^self
-        ]
-    ]
-    ifFalse:
-    [
+            self valueOfCanPaste             value:canPaste. 
+          ^ self
+        ].
+    ] ifFalse:[
+        canPaste := false.
+
         self hasAnySingleSelection value:false.
-        self treeView numberOfSelections ~~ 0 ifTrue:[
-            state := (self treeView isInSelection:1) not
+
+        treeView numberOfSelections ~~ 0 ifTrue:[
+            canPaste := false.
+            state    := (treeView isInSelection:1) not
         ]
     ].          
     self valueOfEnableMovingUpOrDown value:false.
     self valueOfEnableMovingIn       value:false.
     self valueOfEnableMovingOut      value:false.
-    self hasValidSingleSelection     value:false.
     self hasValidSelection           value:state.     
-    self valueOfCanPaste             value:(self hasValidSingleSelection value or: [node == self treeView root]) & self valueOfCanPaste value. 
+    self valueOfCanPaste             value:canPaste. 
 
 !
 
-updateListAndSelectionOfImage
-    "updates the list and selection of image"
-
-    self updateListOfImages.
-    self updateSelectionOfImage
-!
-
-updateListOfImages
-    "updates the list of images"
-
-    |iconClass|      
-
-    (iconClass := (aspects at: #retriever) value ? specClass) notNil ifTrue: 
-    [
-        iconClass := Smalltalk at: iconClass
+updateImageView
+    "update the image view
+    "
+    |cls newList icon|
+
+    self isImageViewSelected ifFalse:[
+        ^ self
     ].
-
-    self listOfImages contents:
-        ((self class getAllImageSelectorsFrom: iconClass)
-            collect: [:sel| |image| 
-                        image := iconClass perform: sel. 
-                        image height > 22 ifTrue:[
-                            image := image magnifiedBy: 22/image extent y
-                        ].
-                        LabelAndIcon 
-                            icon:image 
-                            string:sel
-                     ]).
-
-!
-
-updateSelectionOfImage
-    "updates the selection of image"
-
-    self selectionOfImage value: nil.
-    self updateListOfImages.
-    self selectionOfImage value: (self listOfImages detect: [:im| im string == (aspects at: #icon) value] ifNone: nil).
+    cls := self currentImageRetrieverClass.
+
+    lastImageRetriever == cls ifTrue:[
+        newList := self listOfImages
+    ] ifFalse:[
+        cls notNil ifTrue:[
+            lastImageRetriever := cls.
+
+            newList := self class getAllImageSelectorsFrom:cls.
+            newList := newList collect: [:sel| |img| 
+                            img := cls perform: sel. 
+                            img height > 22 ifTrue:[
+                                img := img magnifiedBy: 22 / img extent y
+                            ].
+                            LabelAndIcon icon:img string:sel
+                       ].
+        ] ifFalse:[
+            newList := #()
+        ].
+        self listOfImages contents:newList.
+    ].
+
+    icon := (aspects at:#icon) value.
+
+    icon notNil ifTrue:[
+        icon := newList detect:[:el| el string == icon] ifNone:nil.
+    ].
+    self selectionOfImage value:icon.
+
 
 ! !
 
@@ -2194,43 +2158,70 @@
 doesNotUnderstand: aMessage
     "detour incoming messages to the tree view"
 
-    (self treeView respondsTo: aMessage selector)
-    ifTrue:
-    [
-        ^aMessage sendTo: self treeView
-    ].
-    super doesNotUnderstand:aMessage
-
-
+    ^ aMessage sendTo:treeView
 ! !
 
 !MenuEditor methodsFor:'private'!
 
+currentImageRetrieverClass
+    "returns the current class which provides the images dependent on
+     the retriver or the current spec.
+    "
+    |clsName|
+
+    clsName := (aspects at: #retriever) value.
+
+    clsName size == 0 ifTrue:[
+        clsName := specClass
+    ].
+    ^ Smalltalk at:clsName ifAbsent:nil
+!
+
 helpKey
     "get the help key of the selected menu item"
 
     |node|
-    (node := self treeView selectedNode) notNil ifTrue:[
+
+    (node := treeView selectedNode) notNil ifTrue:[
         ^ node contents activeHelpKey
     ].
     ^ nil
 !
 
 helpTool
-    "get the help tool"
-
-    ^helpCanvas application
+    "get the help tool application
+    "
+    |helpView helpTool|
+
+    helpTool := listOfCanvas at:#help ifAbsent:nil.
+
+    helpTool isNil ifTrue:[
+        helpTool := UIHelpTool new createBuilder.
+        helpTool masterApplication:self.
+        helpTool modifiedHolder: self valueOfEnablingCommitButtons.
+        helpView := View new client:helpTool.
+        helpTool builder window:helpView.
+        listOfCanvas at:#help put:helpTool.
+    ].
+    ^ helpTool
+
+
 ! !
 
 !MenuEditor methodsFor:'queries'!
 
 isHelpToolSelected
-    "return true if current selection is help tool"
-
-    (tabSelection ~~ 0 and:[slices notNil]) ifTrue:[
-        ^(slices at:tabSelection) first = UIHelpTool label
-    ].
-    ^false
+    "return true if current selection is help tool
+    "
+    ^ typeOfCanvas == #help
+
+!
+
+isImageViewSelected
+    "return true if current selection is help tool
+    "
+    ^ typeOfCanvas == #imageEditSpec
+
 !
 
 preferredExtent
@@ -2242,6 +2233,11 @@
 
 !MenuEditor methodsFor:'selection'!
 
+clearSelection
+    tabSelection := 0.
+    typeOfCanvas := nil.
+!
+
 imageSelected
     |imgSel|
 
@@ -2253,103 +2249,80 @@
 
 menuChanged
 
-    |node item slc sel old myClass|
-
-    aspects do: [:holder| holder removeDependent:self].
-    (node := self treeView selectedNode) notNil ifTrue:[
-        "/ cg: this is rubbish - should only clear
-        "/ item-specific aspects (if at all)
-        "/ (added a q&d kludge for #retrieverClassList - no time to investigate)
-
-        aspects do:[:anAspect| 
-                        anAspect isBlock ifFalse:[
-                            anAspect == (aspects at:#retrieverClassList) ifFalse:[
-                                anAspect value:nil
-                            ]
-                        ]
-                   ].
-        item := node contents.
-        item toAspects:aspects.
-
-        myClass := self class.
+    |node item myClass oldLabel oldSlices newList index|
+
+    node := treeView selectedNode.
+
+    node isNil ifTrue:[
+        slices := nil.
+        index  := 0.
+    ] ifFalse:[
+        oldSlices := slices.
+        myClass   := self class.
+        item      := node contents.
+
         item isSeparator ifFalse:[
             node parent isNil ifFalse:[
                 node hasChildren ifTrue:[
-                    slc := #slicesMenu
+                    slices := #slicesMenu
                 ] ifFalse:[
-                    item submenuChannel isNil ifTrue:[slc := #slicesItem]
-                                             ifFalse:[slc := #slicesLink]
+                    item submenuChannel isNil ifTrue:[slices := #slicesItem]
+                                             ifFalse:[slices := #slicesLink]
                 ].
-                slc := (myClass perform:slc) copyWith:#( 'Help' #dummy ).
+                slices := listOfSlices at:slices
+                              ifAbsentPut:[(myClass perform:slices) copyWith:#('Help' #help)].
             ] ifTrue:[
-                slc := myClass perform:#slicesRootMenu
+                slices := listOfSlices at:#slicesRootMenu
+                              ifAbsentPut:[myClass perform:#slicesRootMenu].
             ].
         ] ifTrue:[
-            slc := myClass perform:#slicesSeparatorMenu.
-        ]
-    ].
-
-    self helpTool helpKey: self helpKey.
-    "Next line helps me to preserve myself against unnecessary settings of
-     valueOfEnablingCommitButtons to true in the help tool."
-
-    self valueOfEnablingCommitButtons value: false.
-    self modifiedChannel value: false.
-
-    slc ~= slices  ifTrue:[
-        tabSelection ~~ 0 ifTrue:[
-            old := (slices at:tabSelection) first
+            slices := myClass perform:#slicesSeparatorMenu.
         ].
-
-        (slices := slc) notNil ifTrue:[
-            sel := slices collect:[:s| s first].
-            tabSelection := 0.     
-            self tabList value:sel.
-
-            (old notNil and:[(sel := sel findFirst:[:n|n = old]) ~~ 0]) ifFalse:[
-                sel := 1
+        index := tabSelection ? 0.
+        self clearSelection.
+
+        slices ~~ oldSlices ifTrue:[
+            newList := slices collect:[:el| el first].
+
+            index ~~ 0 ifTrue:[
+                oldLabel := self tabList value at:index ifAbsent:nil.
+
+                oldLabel notNil ifTrue:[
+                    index := newList indexOf:oldLabel.
+                ]
             ].
-            self tabModel value:sel
-        ] ifFalse:[
-            self tabList value:nil.
-            self tabSelection:0.
-        ]
+            self tabList value:newList.
+        ].
+        index := index max:1.
     ].
+    self tabModel value:index.
     self updateChannels.
-    aspects do: [:holder| holder addDependent:self].
-
-    "Modified: / 4.2.1999 / 17:37:54 / cg"
+    self cancel.
+
 !
 
 tabSelection: aSelection
-    "put the section aSelection into the note book"
+    "put the section aSelection into the note book
+    "
+    |view|
 
     tabSelection = aSelection ifTrue:[
         ^ self
     ].
-    (aSelection ~~ 0 and:[slices isNil]) ifTrue:[
-        ^ self
-    ].
-    (tabSelection := aSelection) == 0 ifTrue:[
-        slices isNil ifTrue:[
-            specCanvas client:nil.
-            ^ specCanvas raise.
-        ].
-        tabSelection == 1 ifTrue:[^ self].
-        tabSelection := 1
+    typeOfCanvas := nil.
+
+    (tabSelection := aSelection) ~~ 0 ifTrue:[
+        typeOfCanvas := (slices at:tabSelection) last.
+
+        self isHelpToolSelected ifTrue:[
+            view := self helpTool window.
+        ] ifFalse:[
+            self updateImageView.
+            view := listOfCanvas at:typeOfCanvas ifAbsentPut:[View new client:self spec:typeOfCanvas].
+        ]
     ].
-
-    self isHelpToolSelected ifTrue:[  
-        self helpTool helpKey:(self helpKey).
-        helpCanvas raise.
-    ] ifFalse:[       
-        aspects do: [:holder| holder removeDependent:self].
-        specCanvas client:self spec:(self class perform:(slices at:tabSelection) last) builder:builder.
-        aspects do: [:holder| holder addDependent:self].
-        specCanvas raise.
-    ]
-
-    "Modified: / 14.8.1998 / 15:07:06 / cg"
+    self tabCanvasHolder value:view
+
 ! !
 
 !MenuEditor methodsFor:'startup / release'!
@@ -2365,6 +2338,12 @@
     holder list: Item separatorList.
     holder addDependent:self.
 
+    listOfCanvas := IdentityDictionary new.
+    listOfSlices := IdentityDictionary new.
+
+    treeView := TreeView new.
+    treeView action:[:dummy| self menuChanged ].
+
     aspects at:#indicationEnabled  put:(BlockValue 
                                             with:[:a | a size == 0]
                                             argument:(aspects at:#choice)).
@@ -2377,23 +2356,14 @@
 
     aspects at:#retrieverClassList put:self class defaultRetrieverClassList asValue.
 
-    "Modified: / 14.8.1998 / 15:07:58 / cg"
+    aspects do: [:holder| holder addDependent:self].
+
 !
 
 openModalOnMenu: aMenu
     "build a tree from aMenu and open it modal"
 
     super openModalOnResourceSpec: aMenu
-!
-
-postOpenWith:aBuilder
-
-    super postOpenWith:aBuilder.
-
-    self isHelpToolSelected 
-        ifTrue:  [helpCanvas raise] 
-        ifFalse: [specCanvas raise]
-
 ! !
 
 !MenuEditor methodsFor:'user actions'!
@@ -2401,40 +2371,49 @@
 accept
     "invoked by button 'OK' and by save requests of menu item changes"
 
-    |node|
+    |node item|
 
     super accept.
 
-    (node := self treeView selectedNode) notNil ifTrue:[
+    (node := treeView selectedNode) notNil ifTrue:[
+        item := node contents.
+
         self isHelpToolSelected ifTrue:[
             self helpTool accept.
-            node contents activeHelpKey: self helpTool helpKey.
+            item activeHelpKey: self helpTool helpKey.
             self valueOfEnablingCommitButtons value: false.
             self clearModifiedFlag.
         ] ifFalse:[
-            node contents buildFromAspects: aspects.
+            item buildFromAspects:aspects.
             node changed.
-            specSelector := self treeView selectorName.
+            specSelector := treeView selectorName.
         ]
     ].   
     self updateInfoLabel.
-    self updateListAndSelectionOfImage.
 
 !
 
 cancel
     "invoked by button 'Cancel'"
-
-    |node|
-
-    (node := self treeView selectedNode) notNil ifTrue:[          
-        self helpTool helpKey:(self helpKey).
-        aspects do:[:anAspect| anAspect value:'' ].
-        node contents toAspects:aspects
+    |node item|
+
+    node := treeView selectedNode.
+
+    aspects keysAndValuesDo:[:aKey :anAspect|
+        aKey ~~ #retrieverClassList ifTrue:[
+            anAspect setValue:''.  "/ to clear the field.
+            anAspect value:''
+        ]
     ].
-    self valueOfEnablingCommitButtons value: false.
+
+    node notNil ifTrue:[
+        item := node contents.
+        item toAspects:aspects.
+        self helpTool helpKey:(item activeHelpKey).
+    ].
+    self updateImageView.
+    self valueOfEnablingCommitButtons value:false.
     self clearModifiedFlag.
-    modified := false
 !
 
 doBrowseForImageResource
@@ -2442,7 +2421,7 @@
 
     |msg currClass w cls sel|
 
-    currClass := (Smalltalk at: (aspects at: #retriever) value ? specClass).
+    currClass := self currentImageRetrieverClass.
     msg := 
         (ResourceSelectionBrowser
             request: 'Use Image From Class'
@@ -2461,7 +2440,7 @@
             sel ~= (aspects at:#icon) ifTrue:[
                 (aspects at: #icon) value:sel asSymbol.
             ].
-            self updateSelectionOfImage
+            self updateImageView.
         ].
     ].
 
@@ -2473,8 +2452,8 @@
      then updates the list of images and select the line of the image"
 
     super doEditImage.
-
-    self updateListAndSelectionOfImage
+    lastImageRetriever := nil.
+    self updateImageView.
 !
 
 doNew
@@ -2486,39 +2465,42 @@
 
     |view|
 
-    ((view := Screen current viewFromUser) isNil or:
-    [view == Screen current rootView]) ifTrue:[
-        ^ self
-    ].
-    view specClass == MenuPanelSpec ifTrue:[
-        ^ self treeView buildFromMenu: view asMenu
+    self askForModification ifTrue:[
+        ((view := Screen current viewFromUser) isNil or:
+        [view == Screen current rootView]) ifTrue:[
+            ^ self
+        ].
+        view specClass == MenuPanelSpec ifTrue:[
+            ^ treeView buildFromMenu: view asMenu
+        ].
     ].
     ^ nil
 !
 
 doRemoveImage
     "removes the image of the selected line"
-
-    self selectionOfImage value notNil
-    ifTrue:
-    [
-        (Smalltalk at: (aspects at: #retriever) value ? specClass) class removeSelector:
-            self selectionOfImage value string.
-
-        self updateListAndSelectionOfImage.
-        (aspects at:#icon) value: nil
+    |cls sel|
+
+    sel := self selectionOfImage value.
+
+    sel size ~~ 0 ifTrue:[
+        cls := self currentImageRetrieverClass.
+        cls notNil ifTrue:[
+            cls class removeSelector:(sel string)
+        ].
+        (aspects at:#icon) value:nil.
+        lastImageRetriever := nil.
+        self updateImageView.
     ] 
 !
 
 doSave
-    |cls treeView menu spec mthd category code excla|
+    |cls menu spec mthd category code excla|
 
     super doSave ifFalse: [^nil].
 
-    cls := self resolveName: specClass.
-    treeView := self treeView.
-    menu     := treeView asMenu.
-    menu := menu literalArrayEncoding.
+    cls  := self resolveName: specClass.
+    menu := treeView asMenu literalArrayEncoding.
     spec := WriteStream on:String new.
     UISpecification prettyPrintSpecArray:menu on:spec indent:5.
     spec := spec contents.
@@ -2566,13 +2548,13 @@
 
 doSaveAs
 
-    super doSaveAs ifTrue: [self treeView selectorName: specSelector]
+    super doSaveAs ifTrue: [treeView selectorName:specSelector]
 !
 
 doStepDown
     "shift selected menu item one step down"
 
-    self treeView selectedNodeChangeSequenceOrder:1.
+    treeView selectedNodeChangeSequenceOrder:1.
     modified := true.
 
 
@@ -2583,7 +2565,7 @@
 doStepIn
     "move selected menu item into next submenu"
 
-    self treeView selectedNodeBecomeChildOfNext.
+    treeView selectedNodeBecomeChildOfNext.
     modified := true.
 
 
@@ -2595,14 +2577,14 @@
 doStepOut
     "move selected menu item out from parent submenu"
 
-    self treeView selectedNodeBecomeSisterOfParent.
+    treeView selectedNodeBecomeSisterOfParent.
     modified := true.
 !
 
 doStepUp
     "shift selected menu item one step up"
 
-    self treeView selectedNodeChangeSequenceOrder:-1.
+    treeView selectedNodeChangeSequenceOrder:-1.
     modified := true.
 ! !
 
@@ -2931,11 +2913,15 @@
 treeViewLabel
     "get the label of the menu item for the tree view"
 
-    ^label asBoldText, 
+    ^label
+" asBoldText, 
         (value notNil ifTrue: [': [', 
                 value ,
                 (argument isString ifTrue: [' ', (Text string: argument emphasis: #italic)] ifFalse: ['']),
                  ']'] ifFalse: [''])
+
+
+"
 ! !
 
 !MenuEditor::TreeView class methodsFor:'documentation'!
@@ -2980,6 +2966,8 @@
     "if opened on a menu"
     (aClass isNil and: [aSelector isNil and: [listOfNodes size > 0]]) ifTrue: [^nil].
 
+    self selection:nil.
+
     (aClass notNil and:[aSelector notNil]) ifTrue:[
         cls := self application resolveName:aClass.
 
@@ -3025,6 +3013,8 @@
 
     |node|
 
+    self selection:nil.
+
     node := self nodeLabel:'menu'.
     self subMenu:aMenu parent:node.