MenuEditor.st
author Claus Gittinger <cg@exept.de>
Fri, 22 May 1998 11:57:38 +0200
changeset 847 15f688710007
parent 836 b44c0047291f
child 849 0001a9185d99
permissions -rw-r--r--
checkin from browser

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

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



ResourceSpecEditor subclass:#MenuEditor
	instanceVariableNames:'specCanvas helpCanvas slices'
	classVariableNames:''
	poolDictionaries:''
	category:'Interface-UIPainter'
!

Object subclass:#Item
	instanceVariableNames:'activeHelpKey enabled label value nameKey indication shortcutKey
		accessCharacterPos retriever icon iconAndLabel submenuChannel
		startGroup argument translateLabel isButton isVisible'
	classVariableNames:''
	poolDictionaries:''
	privateIn:MenuEditor
!

SelectionInTreeView subclass:#TreeView
	instanceVariableNames:''
	classVariableNames:''
	poolDictionaries:''
	privateIn:MenuEditor
!

!MenuEditor class methodsFor:'documentation'!

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

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


!

documentation
"
    The MenuEditor allows you to create, modify or just inspect
    hierarchical menus of menu bars, popup menu, or tool bar menus.

    [start with:]
        MenuEditor open
        MenuEditor openOnClass:MenuEditor andSelector:#menu

    [see also:]
        UIPainter

    [author:]
        Claus Atzkern, eXept Software AG
        Thomas Zwick, eXept Software AG
"

! !

!MenuEditor class methodsFor:'instance creation'!

openModalOnMenu: aMenu
    "Open a MenuEditor modal on aMenu"
    "self openModalOnMenu: (self perform: #menu) decodeAsLiteralArray"

    ^self new openModalOnMenu: aMenu
! !

!MenuEditor class methodsFor:'accessing'!

iconUnknown
    "returns an image used for picked items containing an image
    "

    <resource: #fileImage>

    "/ ^ Image fromFile:'brokenImage.xpm'
    ^ Icon constantNamed:'brokenImage.xpm'

    "Modified: / 22.4.1998 / 22:15:11 / ca"
!

resourceType
    "get the type of resource of the method generated by the MenuEditor"

    ^#menu




! !

!MenuEditor class methodsFor:'aspects'!

aspects
    "get the aspects for the attributes of the menu components"

    ^#(
        label
        accessCharacterPos
        argument
        submenuChannel
        enabled
        value
        nameKey
        indication
        translateLabel
        isButton
        shortcutKey
        startGroup
        retriever
        iconAndLabel
        icon
        isVisible
     )

! !

!MenuEditor class methodsFor:'help specs'!

helpSpec
    "This resource specification was automatically generated
     by the UIHelpTool of ST/X."

    "Do not manually edit this!! If it is corrupted,
     the UIHelpTool may not be able to read the specification."

    "
     UIHelpTool openOnClass:MenuEditor    
    "

    <resource: #help>

    ^super helpSpec addPairsFrom:#(

#addMenuItem
'Adds a new menu item.'

#addMenuSeparator
'Adds a new menu separator.'

#addSubMenu
'Adds a new sub menu.'

#addSubMenuLink
'Adds a new linked sub menu.'

#basicsAction
'An action selector with 0, 1 (the argument field), or 2 (the selected item) arguments.'

#basicsArgument
'An argument passed to above selector, if it is a 1 or a 2 argument selector.'

#basicsIndication
'A boolean value holder, a boolean evaluating block, or a boolean returning selector for specifying indication state.'

#basicsIsButton
'Turns on/off a button behavior.'

#basicsLabel
'Label of the item.'

#basicsMenu
'A value holder providing the sub menu to be opened if item is selected.'

#basicsMenuArgument
'An argument passes with menu selector.'

#basicsNameKey
'Unique identifier of the item (optional).'

#basicsSelector
'Selector under which the generated menu spec is saved.'

#basicsSeparatorType
'List of valid separators.'

#basicsTranslateLabel
'Turns on/off translation behavior of the label via class resource file.'

#detailsAccelerator
'Key to be pressed to select the menu item from the keyboard (accelerator key).'

#detailsAccessCharaterPosition
'Index of the access character position of the textual label (optional).'

#detailsEnabled
'A boolean value holder providing en- or disabling of the menu item.'

#detailsVisibility
'A boolean value holder providing visibility of the menu item.'

#fileLoad
'Opens a dialog for selecting and loading a menu spec from a class.'

#fileNew
'Creates a new menu spec.'

#filePickAMenu
'Select a menu from an open view and read its specification'

#fileSave
'Saves current menu spec and if modified the help spec.'

#fileSaveAs
'Opens a dialog to save current menu spec and if modified the help spec.'

#imageImageAndLabel
'Turns on/off displaying both image and textual label.'

#imageImageEditor
'Opens an Image Editor on retriever and selector.'

#imageRetriever
'Class implementing the image resource method. If no class is given, the current application class will be taken.'

#imageSelector
'Selector returning an image.'

)

    "Modified: / 20.5.1998 / 00:42:49 / cg"
! !

!MenuEditor class methodsFor:'image specs'!

linkSubmenuImage
    "This resource specification was automatically generated
     by the ImageEditor of ST/X."

    "Do not manually edit this!!!! If it is corrupted,
     the ImageEditor may not be able to read the specification."

    "
     ImageEditor openOnClass:self andSelector:#linkSubmenuImage
    "

    <resource: #image>

    ^Icon
        constantNamed:#'MenuEditor linkSubmenuImage'
        ifAbsentPut:[(Depth4Image new) width: 22; height: 22; photometric:(#palette); bitsPerSample:(#(4 )); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'@@@@@@@@@@@@@@@ADQDQDQDQDQDQH@D"H"H"H"H"H"K0@RH"H"H"H"H"H/@A????????????<@D@@@@@@@@@@@C0@PL3L0DQDQDQD_@A@3L3LBH"H"H"<@DCL3L3@"H"H"K0@PL3L3L0??????@A@@@@L3L@@@@@<@DQDQDCL3@PLAG0@RH"H"@3L0@3@/@AH"H"H L3L3L0<@G?????<CL3L3L@@P@@@@@@@3L3LO@ADQDQDQDP@CLA<@D"H"H"H"H LBK0@RH"H"H"H"@BH/@B????????????<@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@b') ; colorMapFromArray:#[0 0 0 255 255 255 170 170 170 255 0 0 0 255 0 0 0 255 0 255 255 255 255 0 255 0 255 127 0 0 0 127 0 0 0 127 0 127 127 127 127 0 127 0 127 127 127 127]; mask:((Depth1Image new) width: 22; height: 22; photometric:(#blackIs0); bitsPerSample:(#(1 )); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'???<???<???<???<???<???<???<???<???<???<???<???<???<???<???<???<???<???<???<???<???<@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@a') ; yourself); yourself]!

menuItemImage
    "This resource specification was automatically generated
     by the ImageEditor of ST/X."

    "Do not manually edit this!!!! If it is corrupted,
     the ImageEditor may not be able to read the specification."

    "
     ImageEditor openOnClass:self andSelector:#menuItemImage
    "

    <resource: #image>

    ^Icon
        constantNamed:#'MenuEditor menuItemImage'
        ifAbsentPut:[(Depth2Image new) width: 22; height: 22; photometric:(#palette); bitsPerSample:(#(2 )); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'UUUUUUUQUUUUUUUPUUUUUUU_UUUUUUUPUUUUUUUP@@@@@@@@EUUUUUVAF*****+HF:?+::;@F:.+*?;@F:.+::;@F:.+*:;@F:.+::;@F*****+DK??????A@@@@@@@@UUUUUUUPUUUUUUUXUUUUUUUPUUUUUUUPUUUUUUUPUUUUUUUX') ; colorMapFromArray:#[0 0 0 255 255 255 170 170 170 127 127 127]; mask:((Depth1Image new) width: 22; height: 22; photometric:(#blackIs0); bitsPerSample:(#(1 )); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'@@@@@@@@@@@@@@@@@@@@???<???<???<???<???<???<???<???<???<???<???<@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@a') ; yourself); yourself]!

menuSeparatorImage
    "This resource specification was automatically generated
     by the ImageEditor of ST/X."

    "Do not manually edit this!!!! If it is corrupted,
     the ImageEditor may not be able to read the specification."

    "
     ImageEditor openOnClass:self andSelector:#menuSeparatorImage
    "

    <resource: #image>

    ^Icon
        constantNamed:#'MenuEditor menuSeparatorImage'
        ifAbsentPut:[(Depth2Image new) width: 22; height: 22; photometric:(#palette); bitsPerSample:(#(2 )); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'UUUUUUURUUUUUUUPUUUUUUUPUUUUUUUPUUUUUUUP@@@@@@@@EUUUUUV@F*****+DF*****+CF?????+@F0@@@@[@F%UUUU[HF*****+@F*****+@K??????N@@@@@@@HUUUUUUUPUUUUUUUPUUUUUUUWUUUUUUUXUUUUUUUPUUUUUUUP') ; colorMapFromArray:#[0 0 0 255 255 255 170 170 170 127 127 127]; mask:((Depth1Image new) width: 22; height: 22; photometric:(#blackIs0); bitsPerSample:(#(1 )); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'@@@@@@@@@@@@@@@@@@@@???<???<???<???<???<???<???<???<???<???<???<@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@a') ; yourself); yourself]!

submenuImage
    "This resource specification was automatically generated
     by the ImageEditor of ST/X."

    "Do not manually edit this!!!! If it is corrupted,
     the ImageEditor may not be able to read the specification."

    "
     ImageEditor openOnClass:self andSelector:#submenuImage
    "

    <resource: #image>

    ^Icon
        constantNamed:#'MenuEditor submenuImage'
        ifAbsentPut:[(Depth2Image new) width: 22; height: 22; photometric:(#palette); bitsPerSample:(#(2 )); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'@@@@@@@@EUUUUUV@F*****+@F*****+@G??????GD@@@@@C@EUUUUUWLF*****+@F*****+@G??????HD@@@@@C@EUUUUUW@F*****+@F*****+OG??????@D@@@@@C@EUUUUUW@F*****+@F*****+@K??????@@@@@@@@@@@@@@@@@') ; colorMapFromArray:#[0 0 0 255 255 255 170 170 170 127 127 127]; mask:((Depth1Image new) width: 22; height: 22; photometric:(#blackIs0); bitsPerSample:(#(1 )); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'???<???<???<???<???<???<???<???<???<???<???<???<???<???<???<???<???<???<???<???<???<@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@a') ; yourself); yourself]! !

!MenuEditor class methodsFor:'interface specs'!

basicsItemSpec
    "This resource specification was automatically generated
     by the UIPainter of ST/X."

    "Do not manually edit this!! If it is corrupted,
     the UIPainter may not be able to read the specification."

    "
     UIPainter new openOnClass:MenuEditor andSelector:#basicsItemSpec
     MenuEditor new openInterface:#basicsItemSpec
    "

    <resource: #canvas>

    ^
     
       #(#FullSpec
          #window: 
           #(#WindowSpec
              #name: 'Basics Item'
              #layout: #(#LayoutFrame 473 0 301 0 739 0 619 0)
              #label: 'Basics Item'
              #min: #(#Point 10 10)
              #max: #(#Point 1160 870)
              #bounds: #(#Rectangle 473 301 740 620)
              #usePreferredExtent: false
          )
          #component: 
           #(#SpecCollection
              #collection: 
               #(
                 #(#LabelSpec
                    #name: 'nameKeyLabel'
                    #layout: #(#AlignmentOrigin 107 0 26 0 1 0.5)
                    #label: 'Name Key:'
                    #adjust: #right
                    #resizeForLabel: true
                )
                 #(#InputFieldSpec
                    #name: 'nameKeyField'
                    #layout: #(#LayoutFrame 110 0 15 0 -5 1.0 37 0)
                    #tabable: true
                    #model: #nameKey
                    #type: #symbolOrNil
                    #acceptOnReturn: false
                    #acceptOnTab: false
                )
                 #(#LabelSpec
                    #name: 'labelLabel'
                    #layout: #(#AlignmentOrigin 107 0 51 0 1 0.5)
                    #label: 'Label:'
                    #adjust: #right
                    #resizeForLabel: true
                )
                 #(#InputFieldSpec
                    #name: 'labelField'
                    #layout: #(#LayoutFrame 110 0 40 0 -5 1.0 62 0)
                    #activeHelpKey: #basicsLabel
                    #tabable: true
                    #model: #label
                    #acceptOnReturn: false
                    #acceptOnTab: false
                )
                 #(#LabelSpec
                    #name: 'valueLabel'
                    #layout: #(#AlignmentOrigin 107 0 90 0 1 0.5)
                    #label: 'Action:'
                    #adjust: #right
                    #resizeForLabel: true
                )
                 #(#InputFieldSpec
                    #name: 'valueField'
                    #layout: #(#LayoutFrame 110 0 79 0 -5 1.0 101 0)
                    #activeHelpKey: #basicsAction
                    #tabable: true
                    #model: #value
                    #type: #symbolOrNil
                    #acceptOnReturn: false
                    #acceptOnTab: false
                )
                 #(#LabelSpec
                    #name: 'argumentLabel'
                    #layout: #(#AlignmentOrigin 107 0 115 0 1 0.5)
                    #label: 'Argument:'
                    #adjust: #right
                    #resizeForLabel: true
                )
                 #(#InputFieldSpec
                    #name: 'argumentField'
                    #layout: #(#LayoutFrame 110 0 104 0 -5 1.0 126 0)
                    #activeHelpKey: #basicsArgument
                    #tabable: true
                    #model: #argument
                    #type: #string
                    #acceptOnReturn: false
                    #acceptOnTab: false
                )
                 #(#LabelSpec
                    #name: 'indicationLabel'
                    #layout: #(#AlignmentOrigin 107 0 155 0 1 0.5)
                    #label: 'Indication:'
                    #adjust: #right
                    #resizeForLabel: true
                )
                 #(#InputFieldSpec
                    #name: 'indicationField'
                    #layout: #(#LayoutFrame 110 0 144 0 -5 1.0 166 0)
                    #activeHelpKey: #basicsIndication
                    #tabable: true
                    #model: #indication
                    #type: #symbolOrNil
                    #acceptOnReturn: false
                    #acceptOnTab: false
                )
                 #(#CheckBoxSpec
                    #name: 'translateLabelCheckBox'
                    #layout: #(#Point 20 190)
                    #activeHelpKey: #basicsTranslateLabel
                    #tabable: true
                    #model: #translateLabel
                    #label: 'Translate Label'
                )
                 #(#CheckBoxSpec
                    #name: 'isButtonCheckBox'
                    #layout: #(#Point 20 219)
                    #activeHelpKey: #basicsIsButton
                    #tabable: true
                    #model: #isButton
                    #label: 'Is Button'
                )
              )
          )
      )
!

basicsLinkSpec
    "This resource specification was automatically generated
     by the UIPainter of ST/X."

    "Do not manually edit this!! If it is corrupted,
     the UIPainter may not be able to read the specification."

    "
     UIPainter new openOnClass:MenuEditor andSelector:#basicsLinkSpec
     MenuEditor new openInterface:#basicsLinkSpec
    "

    <resource: #canvas>

    ^
     
       #(#FullSpec
          #window: 
           #(#WindowSpec
              #name: 'Basics Link'
              #layout: #(#LayoutFrame 473 0 301 0 739 0 619 0)
              #label: 'Basics Link'
              #min: #(#Point 10 10)
              #max: #(#Point 1280 1024)
              #bounds: #(#Rectangle 473 301 740 620)
              #usePreferredExtent: false
          )
          #component: 
           #(#SpecCollection
              #collection: 
               #(
                 #(#LabelSpec
                    #name: 'nameKeyLabel'
                    #layout: #(#AlignmentOrigin 107 0 26 0 1 0.5)
                    #activeHelpKey: #nameKey
                    #label: 'Name Key:'
                    #adjust: #right
                    #resizeForLabel: true
                )
                 #(#InputFieldSpec
                    #name: 'nameKeyField'
                    #layout: #(#LayoutFrame 110 0 15 0 -5 1.0 37 0)
                    #activeHelpKey: #basicsNameKey
                    #tabable: true
                    #model: #nameKey
                    #type: #symbolOrNil
                    #acceptOnReturn: false
                    #acceptOnTab: false
                )
                 #(#LabelSpec
                    #name: 'labelLabel'
                    #layout: #(#AlignmentOrigin 107 0 51 0 1 0.5)
                    #label: 'Label:'
                    #resizeForLabel: true
                )
                 #(#InputFieldSpec
                    #name: 'labelField'
                    #layout: #(#LayoutFrame 110 0 40 0 -5 1.0 62 0)
                    #activeHelpKey: #basicsLabel
                    #tabable: true
                    #model: #label
                    #acceptOnReturn: false
                    #acceptOnTab: false
                )
                 #(#LabelSpec
                    #name: 'menuLabel'
                    #layout: #(#AlignmentOrigin 107 0 76 0 1 0.5)
                    #label: 'Menu:'
                    #resizeForLabel: true
                )
                 #(#InputFieldSpec
                    #name: 'menuField'
                    #layout: #(#LayoutFrame 110 0 65 0 -5 1.0 87 0)
                    #activeHelpKey: #basicsMenu
                    #tabable: true
                    #model: #submenuChannel
                    #type: #symbolOrNil
                    #acceptOnReturn: false
                    #acceptOnTab: false
                )
                 #(#LabelSpec
                    #name: 'ArgumentLabel'
                    #layout: #(#AlignmentOrigin 107 0 100 0 1 0.5)
                    #label: 'Argument:'
                    #resizeForLabel: true
                )
                 #(#InputFieldSpec
                    #name: 'argumentField'
                    #layout: #(#LayoutFrame 110 0 90 0 -5 1.0 112 0)
                    #activeHelpKey: #basicsMenuArgument
                    #tabable: true
                    #model: #argument
                    #acceptOnReturn: false
                    #acceptOnTab: false
                )
                 #(#CheckBoxSpec
                    #name: 'translateLabelCheckBox'
                    #layout: #(#Point 20 190)
                    #activeHelpKey: #basicsTranslateLabel
                    #tabable: true
                    #model: #translateLabel
                    #label: 'Translate Label'
                )
              )
          )
      )
!

basicsMenuSpec
    "This resource specification was automatically generated
     by the UIPainter of ST/X."

    "Do not manually edit this!! If it is corrupted,
     the UIPainter may not be able to read the specification."

    "
     UIPainter new openOnClass:MenuEditor andSelector:#basicsMenuSpec
     MenuEditor new openInterface:#basicsMenuSpec
    "

    <resource: #canvas>

    ^
     
       #(#FullSpec
          #window: 
           #(#WindowSpec
              #name: 'Basics Menu'
              #layout: #(#LayoutFrame 473 0 301 0 739 0 619 0)
              #label: 'Basics Menu'
              #min: #(#Point 10 10)
              #max: #(#Point 1280 1024)
              #bounds: #(#Rectangle 473 301 740 620)
              #usePreferredExtent: false
          )
          #component: 
           #(#SpecCollection
              #collection: 
               #(
                 #(#LabelSpec
                    #name: 'nameKeyLabel'
                    #layout: #(#AlignmentOrigin 107 0 26 0 1 0.5)
                    #label: 'Name Key:'
                    #adjust: #right
                    #resizeForLabel: true
                )
                 #(#InputFieldSpec
                    #name: 'nameKeyField'
                    #layout: #(#LayoutFrame 110 0 15 0 -5 1.0 37 0)
                    #activeHelpKey: #basicsNameKey
                    #tabable: true
                    #model: #nameKey
                    #type: #symbolOrNil
                    #acceptOnReturn: false
                    #acceptOnTab: false
                )
                 #(#LabelSpec
                    #name: 'labelLabel'
                    #layout: #(#AlignmentOrigin 107 0 51 0 1 0.5)
                    #label: 'Label:'
                    #adjust: #right
                    #resizeForLabel: true
                )
                 #(#InputFieldSpec
                    #name: 'labelField'
                    #layout: #(#LayoutFrame 110 0 40 0 -5 1.0 62 0)
                    #activeHelpKey: #basicsLabel
                    #tabable: true
                    #model: #label
                    #acceptOnReturn: false
                    #acceptOnTab: false
                )
                 #(#CheckBoxSpec
                    #name: 'translateLabelCheckBox'
                    #layout: #(#Point 20 190)
                    #activeHelpKey: #basicsTranslateLabel
                    #tabable: true
                    #model: #translateLabel
                    #label: 'Translate Label'
                )
              )
          )
      )
!

basicsRootSpec
    "This resource specification was automatically generated
     by the UIPainter of ST/X."

    "Do not manually edit this!! If it is corrupted,
     the UIPainter may not be able to read the specification."

    "
     UIPainter new openOnClass:MenuEditor andSelector:#basicsRootSpec
     MenuEditor new openInterface:#basicsRootSpec
    "

    <resource: #canvas>

    ^
     
       #(#FullSpec
          #window: 
           #(#WindowSpec
              #name: 'Basics Root'
              #layout: #(#LayoutFrame 473 0 301 0 739 0 619 0)
              #label: 'Basics Root'
              #min: #(#Point 10 10)
              #max: #(#Point 1280 1024)
              #bounds: #(#Rectangle 473 301 740 620)
              #usePreferredExtent: false
          )
          #component: 
           #(#SpecCollection
              #collection: 
               #(
                 #(#LabelSpec
                    #name: 'selectorLabel'
                    #layout: #(#AlignmentOrigin 107 0 26 0 1 0.5)
                    #label: 'Selector:'
                    #adjust: #right
                    #resizeForLabel: true
                )
                 #(#InputFieldSpec
                    #name: 'selectorField'
                    #layout: #(#LayoutFrame 110 0 15 0 -5 1.0 37 0)
                    #activeHelpKey: #basicsSelector
                    #tabable: true
                    #model: #label
                    #acceptOnReturn: false
                    #acceptOnTab: false
                )
              )
          )
      )
!

basicsSeparatorSpec
    "This resource specification was automatically generated
     by the UIPainter of ST/X."

    "Do not manually edit this!! If it is corrupted,
     the UIPainter may not be able to read the specification."

    "
     UIPainter new openOnClass:MenuEditor andSelector:#basicsSeparatorSpec
     MenuEditor new openInterface:#basicsSeparatorSpec
    "

    <resource: #canvas>

    ^
     
       #(#FullSpec
          #window: 
           #(#WindowSpec
              #name: 'Basics Separator'
              #layout: #(#LayoutFrame 473 0 301 0 739 0 619 0)
              #label: 'Basics Separator'
              #min: #(#Point 10 10)
              #max: #(#Point 1160 870)
              #bounds: #(#Rectangle 473 301 740 620)
              #usePreferredExtent: false
          )
          #component: 
           #(#SpecCollection
              #collection: 
               #(
                 #(#LabelSpec
                    #name: 'separatorLabel'
                    #layout: #(#AlignmentOrigin 127 0 26 0 1 0.5)
                    #label: 'Separator Type:'
                    #adjust: #right
                    #resizeForLabel: true
                )
                 #(#ComboListSpec
                    #name: 'seperatorList'
                    #layout: #(#LayoutFrame 132 0 15 0 -5 1.0 37 0)
                    #activeHelpKey: #basicsSeparatorType
                    #tabable: true
                    #model: #seperatorSelection
                    #useIndex: true
                )
                 #(#LabelSpec
                    #name: 'visibilityLabel'
                    #layout: #(#AlignmentOrigin 127 0 76 0 1 0.5)
                    #label: 'Visibility:'
                    #adjust: #right
                    #resizeForLabel: true
                )
                 #(#InputFieldSpec
                    #name: 'visibilityInputField'
                    #layout: #(#LayoutFrame 132 0 65 0 -5 1.0 87 0)
                    #activeHelpKey: #detailsVisibility
                    #tabable: true
                    #model: #isVisible
                    #type: #symbolOrNil
                    #acceptOnReturn: false
                    #acceptOnTab: false
                )
              )
          )
      )
!

detailsEditSpec
    "This resource specification was automatically generated
     by the UIPainter of ST/X."

    "Do not manually edit this!! If it is corrupted,
     the UIPainter may not be able to read the specification."

    "
     UIPainter new openOnClass:MenuEditor andSelector:#detailsEditSpec
     MenuEditor new openInterface:#detailsEditSpec
    "

    <resource: #canvas>

    ^
     
       #(#FullSpec
          #window: 
           #(#WindowSpec
              #name: 'Details Edit'
              #layout: #(#LayoutFrame 332 0 374 0 590 0 661 0)
              #label: 'Details Edit'
              #min: #(#Point 10 10)
              #max: #(#Point 1280 1024)
              #bounds: #(#Rectangle 332 374 591 662)
              #usePreferredExtent: false
          )
          #component: 
           #(#SpecCollection
              #collection: 
               #(
                 #(#LabelSpec
                    #name: 'shortcutKeyLabel'
                    #layout: #(#AlignmentOrigin 107 0 26 0 1 0.5)
                    #label: 'Accelerator:'
                    #adjust: #right
                    #resizeForLabel: true
                )
                 #(#InputFieldSpec
                    #name: 'shortcutKeyField'
                    #layout: #(#LayoutFrame 110 0 15 0 -5 1.0 37 0)
                    #activeHelpKey: #detailsAccelerator
                    #tabable: true
                    #model: #shortcutKey
                    #type: #symbolOrNil
                    #acceptOnReturn: false
                    #acceptOnTab: false
                )
                 #(#LabelSpec
                    #name: 'enabledLabel'
                    #layout: #(#AlignmentOrigin 107 0 51 0 1 0.5)
                    #label: 'Enabled:'
                    #adjust: #right
                    #resizeForLabel: true
                )
                 #(#InputFieldSpec
                    #name: 'enabledField'
                    #layout: #(#LayoutFrame 110 0 40 0 -5 1.0 62 0)
                    #activeHelpKey: #detailsEnabled
                    #tabable: true
                    #model: #enabled
                    #type: #symbolOrNil
                    #acceptOnReturn: false
                    #acceptOnTab: false
                )
                 #(#LabelSpec
                    #name: 'visibilityLabel'
                    #layout: #(#AlignmentOrigin 107 0 76 0 1 0.5)
                    #label: 'Visibility:'
                    #adjust: #right
                    #resizeForLabel: true
                )
                 #(#InputFieldSpec
                    #name: 'isVisibleInputField'
                    #layout: #(#LayoutFrame 110 0 65 0 -5 1.0 87 0)
                    #activeHelpKey: #detailsVisibility
                    #tabable: true
                    #model: #isVisible
                    #type: #symbolOrNil
                    #acceptOnReturn: false
                    #acceptOnTab: false
                )
                 #(#LabelSpec
                    #name: 'StartGroupLabel'
                    #layout: #(#AlignmentOrigin 107 0 111 0 1 0.5)
                    #label: 'Start Group:'
                    #adjust: #right
                    #resizeForLabel: true
                )
                 #(#PopUpListSpec
                    #name: 'StartGroupPopUp'
                    #layout: #(#LayoutFrame 110 0 100 0 -5 1.0 122 0)
                    #label: 'PopUpList'
                    #tabable: true
                    #model: #startGroup
                    #menu: 
                     #(nil
                        #right
                    )
                    #useIndex: false
                )
                 #(#LabelSpec
                    #name: 'accessCharLabel'
                    #layout: #(#AlignmentOrigin 217 0 142 0 1 0.5)
                    #label: 'Access Character Position:'
                    #adjust: #right
                    #resizeForLabel: true
                )
                 #(#InputFieldSpec
                    #name: 'accessCharField'
                    #layout: #(#LayoutFrame 220 0 131 0 -5 1.0 153 0)
                    #activeHelpKey: #detailsAccessCharaterPosition
                    #tabable: true
                    #model: #accessCharacterPos
                    #type: #numberOrNil
                    #acceptOnReturn: false
                    #acceptOnTab: false
                )
              )
          )
      )
!

imageEditSpec
    "This resource specification was automatically generated
     by the UIPainter of ST/X."

    "Do not manually edit this!! If it is corrupted,
     the UIPainter may not be able to read the specification."

    "
     UIPainter new openOnClass:MenuEditor andSelector:#imageEditSpec
     MenuEditor new openInterface:#imageEditSpec
    "

    <resource: #canvas>

    ^
     
       #(#FullSpec
          #window: 
           #(#WindowSpec
              #name: 'Image Item'
              #layout: #(#LayoutFrame 473 0 301 0 717 0 442 0)
              #label: 'Image Item'
              #min: #(#Point 10 10)
              #max: #(#Point 1280 1024)
              #bounds: #(#Rectangle 473 301 718 443)
              #usePreferredExtent: false
          )
          #component: 
           #(#SpecCollection
              #collection: 
               #(
                 #(#LabelSpec
                    #name: 'retrieverLabel'
                    #layout: #(#AlignmentOrigin 107 0 26 0 1 0.5)
                    #label: 'Retriever:'
                    #adjust: #right
                    #resizeForLabel: true
                )
                 #(#InputFieldSpec
                    #name: 'retrieverField'
                    #layout: #(#LayoutFrame 110 0 15 0 -5 1.0 37 0)
                    #activeHelpKey: #imageRetriever
                    #tabable: true
                    #model: #retriever
                    #type: #symbolOrNil
                    #acceptOnReturn: false
                    #acceptOnTab: false
                )
                 #(#LabelSpec
                    #name: 'iconLabel'
                    #layout: #(#AlignmentOrigin 107 0 51 0 1 0.5)
                    #label: 'Selector:'
                    #adjust: #right
                    #resizeForLabel: true
                )
                 #(#InputFieldSpec
                    #name: 'iconField'
                    #layout: #(#LayoutFrame 110 0 40 0 -5 1.0 62 0)
                    #activeHelpKey: #imageSelector
                    #tabable: true
                    #model: #icon
                    #type: #symbolOrNil
                    #acceptOnReturn: false
                    #acceptOnTab: false
                )
                 #(#ActionButtonSpec
                    #name: 'imageEditorButton'
                    #layout: #(#LayoutFrame 110 0 66 0 -5 1 90 0)
                    #activeHelpKey: #imageImageEditor
                    #label: 'Image Editor'
                    #tabable: true
                    #model: #doEditImage
                )
                 #(#CheckBoxSpec
                    #name: 'iconAndLabel'
                    #layout: #(#LayoutOrigin 20 0 104 0)
                    #activeHelpKey: #imageImageAndLabel
                    #tabable: true
                    #model: #iconAndLabel
                    #label: 'Image & Label'
                )
              )
          )
      )
!

windowSpec
    "This resource specification was automatically generated
     by the UIPainter of ST/X."

    "Do not manually edit this!! If it is corrupted,
     the UIPainter may not be able to read the specification."

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

    <resource: #canvas>

    ^
     
       #(#FullSpec
          #window: 
           #(#WindowSpec
              #name: 'Menu Editor'
              #layout: #(#LayoutFrame 189 0 552 0 872 0 931 0)
              #label: 'Menu Editor'
              #min: #(#Point 510 390)
              #max: #(#Point 1152 900)
              #bounds: #(#Rectangle 189 552 873 932)
              #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)
                    #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
                          )
                        )
                    )
                    #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
                )
              )
          )
      )

    "Modified: / 20.5.1998 / 01:18:39 / cg"
! !

!MenuEditor class methodsFor:'menu specs'!

menu
    "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:MenuEditor andSelector:#menu
     (Menu new fromLiteralArrayEncoding:(MenuEditor menu)) startUp
    "

    <resource: #menu>

    ^
     
       #(#Menu
          
           #(
             #(#MenuItem
                #label: 'About'
                #translateLabel: true
                #accessCharacterPosition: 1
                #labelImage: #(#ResourceRetriever nil #menuIcon)
                #submenuChannel: #menuAbout
            )
             #(#MenuItem
                #label: 'File'
                #activeHelpKey: #file
                #translateLabel: true
                #submenu: 
                 #(#Menu
                    
                     #(
                       #(#MenuItem
                          #label: 'New'
                          #value: #doNew
                          #translateLabel: true
                          #activeHelpKey: #fileNew
                      )
                       #(#MenuItem
                          #label: '-'
                      )
                       #(#MenuItem
                          #label: 'Load...'
                          #translateLabel: true
                          #value: #doLoad
                          #activeHelpKey: #fileLoad
                      )
                       #(#MenuItem
                          #label: '-'
                      )
                       #(#MenuItem
                          #label: 'Save'
                          #translateLabel: true
                          #value: #doSave
                          #activeHelpKey: #fileSave
                      )
                       #(#MenuItem
                          #label: 'Save As...'
                          #translateLabel: true
                          #value: #doSaveAs
                          #activeHelpKey: #fileSaveAs
                      )
                       #(#MenuItem
                          #label: '-'
                      )
                       #(#MenuItem
                          #label: 'Pick A Menu...'
                          #translateLabel: true
                          #value: #doPickAMenu
                          #activeHelpKey: #filePickAMenu
                      )
                       #(#MenuItem
                          #label: '-'
                      )
                       #(#MenuItem
                          #label: 'Browse Class'
                          #translateLabel: true
                          #value: #doBrowseClass
                          #activeHelpKey: #fileBrowseClass
                      )
                       #(#MenuItem
                          #label: '-'
                      )
                       #(#MenuItem
                          #label: 'Exit'
                          #translateLabel: true
                          #value: #closeRequest
                          #activeHelpKey: #fileExit
                      )
                    ) nil
                    nil
                )
            )
             #(#MenuItem
                #label: 'Edit'
                #activeHelpKey: #edit
                #translateLabel: true
                #submenuChannel: #menuEdit
            )
             #(#MenuItem
                #label: 'Add'
                #activeHelpKey: #add
                #translateLabel: true
                #submenuChannel: #menuAdd
            )
             #(#MenuItem
                #label: 'Test'
                #activeHelpKey: #test
                #translateLabel: true
                #submenuChannel: #submenuTest
            )
             #(#MenuItem
                #label: 'Settings'
                #submenu: 
                 #(#Menu
                    
                     #(
                       #(#MenuItem
                          #label: 'Fonts'
                          #translateLabel: true
                          #submenuChannel: #menuFont
                      )
                    ) nil
                    nil
                )
            )
             #(#MenuItem
                #label: 'History'
                #activeHelpKey: #history
                #translateLabel: true
                #submenuChannel: #menuHistory
            )
             #(#MenuItem
                #label: 'Help'
                #translateLabel: true
                #startGroup: #right
                #submenu: 
                 #(#Menu
                    
                     #(
                       #(#MenuItem
                          #label: 'Documentation'
                          #value: #openHTMLDocument:
                          #translateLabel: true
                          #activeHelpKey: #helpTutorial
                          #argument: 'tools/uipainter/MenuEditor.html'
                      )
                       #(#MenuItem
                          #label: '-'
                      )
                       #(#MenuItem
                          #label: 'Help Tool'
                          #value: #openHTMLDocument:
                          #translateLabel: true
                          #activeHelpKey: #helpHelpTool
                          #argument: 'tools/uipainter/HelpTool.html'
                      )
                       #(#MenuItem
                          #label: '-'
                      )
                       #(#MenuItem
                          #label: 'Show Help Texts'
                          #translateLabel: true
                          #activeHelpKey: #helpShowHelp
                          #indication: #showHelp:
                      )
                    ) nil
                    nil
                )
            )
          ) nil
          nil
      )

    "Modified: / 20.5.1998 / 00:36:34 / cg"
!

menuAdd
    "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:MenuEditor andSelector:#menuAdd
     (Menu new fromLiteralArrayEncoding:(MenuEditor menuAdd)) startUp
    "

    <resource: #menu>

    ^
     
       #(#Menu
          
           #(
             #(#MenuItem
                #label: 'Menu Item'
                #translateLabel: true
                #value: #doCreateItem
                #activeHelpKey: #addMenuItem
                #labelImage: #(#ResourceRetriever #MenuEditor #menuItemImage 'Menu Item')
            )
             #(#MenuItem
                #label: 'Menu Separator'
                #translateLabel: true
                #value: #doCreateSep
                #activeHelpKey: #addMenuSeparator
                #labelImage: #(#ResourceRetriever #MenuEditor #menuSeparatorImage 'Menu Separator')
            )
             #(#MenuItem
                #label: '-'
            )
             #(#MenuItem
                #label: 'Submenu'
                #translateLabel: true
                #value: #doCreateMenu
                #activeHelpKey: #addSubMenu
                #labelImage: #(#ResourceRetriever #MenuEditor #submenuImage 'Submenu')
            )
             #(#MenuItem
                #label: 'Submenu Link'
                #translateLabel: true
                #value: #doCreateLink
                #activeHelpKey: #addSubMenuLink
                #labelImage: #(#ResourceRetriever #MenuEditor #linkSubmenuImage 'Submenu Link')
            )
          ) nil
          nil
      )

    "Modified: / 20.5.1998 / 00:40:39 / cg"
!

menuDefaultLink
    "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:MenuEditor andSelector:#menuDefaultLink
     (Menu new fromLiteralArrayEncoding:(MenuEditor menuDefaultLink)) startUp
    "

    <resource: #menu>

    ^

       #(#Menu

           #(
             #(#MenuItem
                #'label:' '!!!! derives from application !!!!'
            )
          ) nil
          nil
      )
!

menuEdit
    "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:MenuEditor andSelector:#menuEdit
     (Menu new fromLiteralArrayEncoding:(MenuEditor menuEdit)) startUp
    "

    <resource: #menu>

    ^
     
       #(#Menu
          
           #(
             #(#MenuItem
                #label: 'Cut'
                #value: #doCut
                #translateLabel: true
                #activeHelpKey: #editCut
                #enabled: #hasValidSelection
                #shortcutKeyCharacter: #Cut
            )
             #(#MenuItem
                #label: 'Copy'
                #value: #doCopy
                #translateLabel: true
                #activeHelpKey: #editCopy
                #enabled: #hasValidSelection
                #shortcutKeyCharacter: #Copy
            )
             #(#MenuItem
                #label: 'Paste'
                #value: #doPaste
                #translateLabel: true
                #activeHelpKey: #editPaste
                #enabled: #valueOfCanPaste
                #shortcutKeyCharacter: #Paste
            )
             #(#MenuItem
                #label: 'Delete'
                #value: #doDelete
                #translateLabel: true
                #activeHelpKey: #editDelete
                #enabled: #hasValidSelection
                #shortcutKeyCharacter: #Delete
            )
             #(#MenuItem
                #label: '-'
            )
             #(#MenuItem
                #label: 'Move Up'
                #value: #doStepUp
                #translateLabel: true
                #activeHelpKey: #editMoveUp
                #enabled: #valueOfEnableMovingUpOrDown
            )
             #(#MenuItem
                #label: 'Move Down'
                #value: #doStepDown
                #translateLabel: true
                #activeHelpKey: #editMoveDown
                #enabled: #valueOfEnableMovingUpOrDown
            )
             #(#MenuItem
                #label: 'Move In'
                #value: #doStepIn
                #translateLabel: true
                #activeHelpKey: #editMoveIn
                #enabled: #valueOfEnableMovingIn
            )
             #(#MenuItem
                #label: 'Move Out'
                #value: #doStepOut
                #translateLabel: true
                #activeHelpKey: #editMoveOut
                #enabled: #valueOfEnableMovingOut
            )
          ) nil
          nil
      )

    "Modified: / 20.5.1998 / 00:37:16 / cg"
!

menuToolbar
    "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:MenuEditor andSelector:#menuToolbar
     (Menu new fromLiteralArrayEncoding:(MenuEditor menuToolbar)) startUp
    "

    <resource: #menu>

    ^
     
       #(#Menu
          
           #(
             #(#MenuItem
                #label: 'New'
                #isButton: true
                #value: #doNew
                #activeHelpKey: #fileNew
                #labelImage: #(#ResourceRetriever nil #newIcon)
            )
             #(#MenuItem
                #label: 'Load'
                #isButton: true
                #value: #doLoad
                #activeHelpKey: #fileLoad
                #labelImage: #(#ResourceRetriever nil #loadIcon)
            )
             #(#MenuItem
                #label: 'Save'
                #isButton: true
                #value: #doSave
                #activeHelpKey: #fileSave
                #labelImage: #(#ResourceRetriever nil #saveIcon)
            )
             #(#MenuItem
                #label: ''
            )
             #(#MenuItem
                #label: 'Cut'
                #isButton: true
                #value: #doCut
                #activeHelpKey: #editCut
                #enabled: #hasValidSelection
                #labelImage: #(#ResourceRetriever nil #cutIcon)
            )
             #(#MenuItem
                #label: 'Copy'
                #isButton: true
                #value: #doCopy
                #activeHelpKey: #editCopy
                #enabled: #hasValidSelection
                #labelImage: #(#ResourceRetriever nil #copyIcon)
            )
             #(#MenuItem
                #label: 'Paste'
                #isButton: true
                #value: #doPaste
                #activeHelpKey: #editPaste
                #enabled: #valueOfCanPaste
                #labelImage: #(#ResourceRetriever nil #pasteIcon)
            )
             #(#MenuItem
                #label: 'Delete'
                #isButton: true
                #value: #doDelete
                #activeHelpKey: #editDelete
                #enabled: #hasValidSelection
                #labelImage: #(#ResourceRetriever nil #deleteIcon)
            )
             #(#MenuItem
                #label: ''
            )
             #(#MenuItem
                #label: 'Add Item'
                #isButton: true
                #value: #doCreateItem
                #activeHelpKey: #addMenuItem
                #enabled: #hasAnySingleSelection
                #labelImage: #(#ResourceRetriever nil #menuItemImage)
            )
             #(#MenuItem
                #label: 'Add Separator'
                #isButton: true
                #value: #doCreateSep
                #activeHelpKey: #addMenuSeparator
                #enabled: #hasAnySingleSelection
                #labelImage: #(#ResourceRetriever nil #menuSeparatorImage)
            )
             #(#MenuItem
                #label: 'Add Submenu'
                #isButton: true
                #value: #doCreateMenu
                #activeHelpKey: #addSubMenu
                #enabled: #hasAnySingleSelection
                #labelImage: #(#ResourceRetriever nil #submenuImage)
            )
             #(#MenuItem
                #label: 'Add Linked Submenu'
                #isButton: true
                #value: #doCreateLink
                #activeHelpKey: #addSubMenuLink
                #enabled: #hasAnySingleSelection
                #labelImage: #(#ResourceRetriever nil #linkSubmenuImage)
            )
             #(#MenuItem
                #label: ''
            )
             #(#MenuItem
                #label: 'Move Up'
                #isButton: true
                #value: #doStepUp
                #activeHelpKey: #editMoveUp
                #enabled: #valueOfEnableMovingUpOrDown
                #labelImage: #(#ResourceRetriever nil #upIcon)
            )
             #(#MenuItem
                #label: 'Move Down'
                #isButton: true
                #value: #doStepDown
                #activeHelpKey: #editMoveDown
                #enabled: #valueOfEnableMovingUpOrDown
                #labelImage: #(#ResourceRetriever nil #downIcon)
            )
             #(#MenuItem
                #label: 'Move In'
                #isButton: true
                #value: #doStepIn
                #activeHelpKey: #editMoveIn
                #enabled: #valueOfEnableMovingIn
                #labelImage: #(#ResourceRetriever nil #downRightIcon)
            )
             #(#MenuItem
                #label: 'Move Out'
                #isButton: true
                #value: #doStepOut
                #activeHelpKey: #editMoveOut
                #enabled: #valueOfEnableMovingOut
                #labelImage: #(#ResourceRetriever nil #leftDownIcon)
            )
          ) nil
          nil
      )
! !

!MenuEditor class methodsFor:'slices'!

slicesItem
    ^#(
            (Basics     basicsItemSpec)
            (Details    detailsEditSpec)
            (Image      imageEditSpec)
      )

!

slicesLink
    ^#(
            (Basics     basicsLinkSpec)
            (Details    detailsEditSpec)
            (Image      imageEditSpec)
      )

!

slicesMenu
    ^#(
            (Basics     basicsMenuSpec)
            (Details    detailsEditSpec)
            (Image      imageEditSpec)
      )

!

slicesRootMenu
    ^#(
            (Basics   basicsRootSpec)
      )

!

slicesSeparatorMenu
    ^#(
            (Basics   basicsSeparatorSpec)
      )

! !

!MenuEditor methodsFor:'accessing'!

submenuTest
    "return submenu assigned to item test"

    |menu|

    (menu := self treeView asMenu) allItemsDo:
    [:anItem|
        anItem value:nil.
        anItem enabled:true.
    ].
    ^menu
!

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'!

hasAnySingleSelection

    ^builder booleanValueAspectFor: #hasAnySingleSelection
!

hasValidSelection

    ^builder booleanValueAspectFor: #hasValidSelection
!

hasValidSingleSelection

    ^builder booleanValueAspectFor: #hasValidSingleSelection
!

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
!

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).
    ].
    ^ holder


!

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
! !

!MenuEditor methodsFor:'building'!

buildFromClass:aClass andSelector:aSelector

    self isStandAlone ifTrue:[
        self helpTool buildFromClass:specClass
    ].              
    self 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])
! !

!MenuEditor methodsFor:'change & update'!

updateChannels
    "update channels"

    |node parent next state|

    state := false.   

    (node  := self treeView selectedNode) notNil
    ifTrue:
    [
        self hasAnySingleSelection value:true.
        (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 hasAnySingleSelection value:false.
        self treeView numberOfSelections ~~ 0 ifTrue:[
            state := (self 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. 
! !

!MenuEditor methodsFor:'event handling'!

doesNotUnderstand: aMessage
    "detour incoming messages to the tree view"

    (self treeView respondsTo: aMessage selector)
    ifTrue:
    [
        ^aMessage sendTo: self treeView
    ].
    super doesNotUnderstand:aMessage


! !

!MenuEditor methodsFor:'private'!

helpKey
    "get the help key of the selected menu item"

    |node|
    (node := self treeView selectedNode) notNil ifTrue:[
        ^ node contents activeHelpKey
    ].
    ^ nil
!

helpTool
    "get the help tool"

    ^helpCanvas application
! !

!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
!

preferredExtent

    ^super preferredExtent max: (Screen current width//3)@(Screen current height//2.5)


! !

!MenuEditor methodsFor:'selection'!

menuChanged

    |node item slc sel old|

    aspects do: [:holder| holder removeDependent:self].
    (node := self treeView selectedNode) notNil ifTrue:[
        aspects do:[:anAspect| anAspect value:nil ].
        item := node contents.
        item toAspects:aspects.

        item isSeparator ifFalse:[
            node parent isNil ifFalse:[
                node hasChildren ifTrue:[
                    slc := #slicesMenu
                ] ifFalse:[
                    item submenuChannel isNil ifTrue:[slc := #slicesItem]
                                             ifFalse:[slc := #slicesLink]
                ].
                slc := (self class perform:slc) copyWith:#( 'Help' #dummy ).
            ] ifTrue:[
                slc := self class perform:#slicesRootMenu
            ].
        ] ifTrue:[
            slc := self class 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.

    slc ~= slices  ifTrue:[
        tabSelection ~~ 0 ifTrue:[
            old := (slices at:tabSelection) first
        ].

        (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
            ].
            self tabModel value:sel
        ] ifFalse:[
            self tabList value:nil.
            self tabSelection:0.
        ]
    ].
    self updateChannels.
    aspects do: [:holder| holder addDependent:self].
!

tabSelection: aSelection
    "put the section aSelection into the note book"

    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
    ].

    self isHelpToolSelected ifTrue:[  
        self helpTool helpKey:(self helpKey).
        helpCanvas raise.
    ] ifFalse:[       
        aspects do: [:holder| holder release].
        specCanvas client:self spec:(self class perform:(slices at:tabSelection) last) builder:builder.
        aspects do: [:holder| holder addDependent:self].
        self updateFonts.
        specCanvas raise.
    ]    

! !

!MenuEditor methodsFor:'startup / release'!

initialize
    "initialize value holders for the attributes of the menu components"

    |holder|

    super initialize.

    aspects at:#seperatorSelection put:(holder := SelectionInList new).
    holder list: Item separatorList.
    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'!

accept
    "invoked by button 'OK' and by save requests of menu item changes"

    |node|

    super accept.

    (node := self treeView selectedNode) notNil
    ifTrue:
    [
        self isHelpToolSelected
        ifTrue:
        [
            self helpTool accept.
            node contents activeHelpKey: self helpTool helpKey.
            self valueOfEnablingCommitButtons value: false.
        ]
        ifFalse:
        [
            node contents buildFromAspects: aspects.
            node changed.
            specSelector := self treeView selectorName.
        ]
    ].   
    self updateInfoLabel
!

cancel
    "invoked by button 'Cancel'"

    |node|
    (node := self treeView selectedNode) notNil
    ifTrue:
    [          
        self helpTool helpKey:(self helpKey).
        aspects do:[:anAspect| anAspect value:nil].
        node contents toAspects:aspects
    ].
    self valueOfEnablingCommitButtons value: false.
    modified := false
!

doNew

    super doNew ifTrue: [self helpTool doNew]
!

doPickAMenu

    |view|

    ((view := Screen current viewFromUser) isNil or:
    [view == Screen current rootView]) ifTrue:[
        ^ self
    ].
    view specClass == MenuPanelSpec ifTrue:[
        ^ self treeView buildFromMenu: view asMenu
    ].
    ^ nil
!

doSave
    |cls treeView menu spec mthd category code excla|

    super doSave ifFalse: [^nil].

    cls := self resolveName: specClass.
    treeView := self treeView.
    menu     := treeView asMenu.
    menu := menu literalArrayEncoding.
    spec := WriteStream on:String new.
    UISpecification prettyPrintSpecArray:menu on:spec indent:5.
    spec := spec contents.

    "/ if that method already exists, do not overwrite the category

    category := 'menu specs'.
    (mthd := cls class compiledMethodAt:specSelector) notNil ifTrue:[
        category := mthd category.
    ].

    excla := Character excla asString.

    code := excla
            , (cls name , ' class methodsFor:' , category storeString)
            , excla , '\\'

            , specSelector , '\'
            , (self class codeGenerationComment replChar:$!! withString:'!!!!')
            , '\\    "\'
            , ('     MenuEditor new openOnClass:' , cls name , ' andSelector:#' , specSelector , '\')
            , ('     (Menu new fromLiteralArrayEncoding:(' , cls name , ' ' , specSelector , ')) startUp\')
            , '    "\'.

    code := code 
            , '\'
            , '    <resource: #menu>\\'
            , '    ^\' 
            , '     ', spec
            , '\'
            , (excla , ' ' , excla)
            , '\\'.

    code := code withCRs.
    (ReadStream on:code) fileIn.

    self isStandAlone ifTrue: [self helpTool installHelpSpecsOnClass:self specClass].

    self updateHistory.
    self updateInfoLabel.

    hasSaved := true.
    modified := false.

!

doSaveAs

    super doSaveAs ifTrue: [self treeView selectorName: specSelector]
!

doStepDown
    "shift selected menu item one step down"

    self treeView selectedNodeChangeSequenceOrder:1.
    modified := true.




!

doStepIn
    "move selected menu item into next submenu"

    self treeView selectedNodeBecomeChildOfNext.
    modified := true.





!

doStepOut
    "move selected menu item out from parent submenu"

    self treeView selectedNodeBecomeSisterOfParent.
    modified := true.
!

doStepUp
    "shift selected menu item one step up"

    self treeView selectedNodeChangeSequenceOrder:-1.
    modified := true.
! !

!MenuEditor::Item class methodsFor:'constants'!

separatorList
    "get the list of available separator types"

    ^#('blank' 'single line' 'double line')
!

separatorSlices
    "get the list of menu spec values of the corresponding separator types"

   ^ #(
        ( #blank        ''  )
        ( #single       '-' )
        ( #double       '=' )
      )
! !

!MenuEditor::Item class methodsFor:'documentation'!

documentation
"
    implements the contents assigned to a TreeItem. An instance
    is associated with one item and keeps all its information

    [see also:]
        TreeItem
        MenuEditor

    [author:]
        Claus Atzkern
"


! !

!MenuEditor::Item methodsFor:'accessing'!

activeHelpKey
    "get the help key of the menu item"

    ^activeHelpKey
!

activeHelpKey:aKey
    "set the help key of the menu item"

    activeHelpKey := aKey
!

label
    "get the value of the menu item"

    ^label
!

label:something
    "set the value of the menu item"

    label := something ? '-'
!

separatorType
    "get the separator type assigned to item or nil"

    label size > 1 
    ifFalse:
    [
        label size  == 0  ifTrue:[^#blank].
        label first == $- ifTrue:[^#single].
        label first == $= ifTrue:[^#double].
    ].    
    ^nil

!

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

    ^submenuChannel
!

submenuChannel:aChannel
    "get the submenuChannel"

    submenuChannel := aChannel
! !

!MenuEditor::Item methodsFor:'conversion'!

asMenuItem
    "converts self to a menu item"

    |item rcv|

    item := MenuItem labeled:label.
    item isVisible:isVisible.

    self isSeparator ifFalse:[    
        item activeHelpKey:activeHelpKey.
        item enabled:enabled.
        item accessCharacterPosition:accessCharacterPos.
        item argument:argument.
        item submenuChannel:submenuChannel.
        item nameKey:nameKey.
        item shortcutKeyCharacter:shortcutKey.
        item startGroup:startGroup.
        item value:value.
        item indication:indication.
        item translateLabel: translateLabel.
        item isButton: isButton.

        icon notNil ifTrue:[
            rcv := ResourceRetriever new.
            rcv className:retriever.
            rcv selector:icon.
            iconAndLabel == true ifTrue:[
                rcv labelText:label
            ].
            item labelImage:rcv
        ]
    ].
    ^item
!

buildFromAspects:aspects
    "read the values of the aspects into my values"

    |name|
    self isSeparator 
    ifFalse:
    [
        name  := label.
        label := (aspects at:#label) value.

        (label isNil or:[self isSeparator]) ifTrue:[
            (aspects at:#label) value:(label := name)
        ].

        enabled            := (aspects at:#enabled) value.
        value              := (aspects at:#value) value.
        nameKey            := (aspects at:#nameKey) value.
        indication         := (aspects at:#indication) value.
        shortcutKey        := (aspects at:#shortcutKey) value.
        startGroup         := (aspects at:#startGroup) value.
        accessCharacterPos := (aspects at:#accessCharacterPos) value.
        argument           := (aspects at:#argument) value.
        translateLabel     := (aspects at:#translateLabel) value.
        isButton           := (aspects at:#isButton) value.

        argument isString ifTrue:[
            argument size > 1 ifTrue:[
                (argument at:1) == $# ifTrue:[
                    argument := (argument copyFrom:2) asSymbol
                ]
            ]
        ].
        submenuChannel    := (aspects at:#submenuChannel) value.
        retriever         := (aspects at:#retriever) value.
        icon              := (aspects at:#icon) value.
        iconAndLabel      := (aspects at:#iconAndLabel) value.
    ]
    ifTrue:
    [
        name  := (aspects at:#seperatorSelection) selectionIndex.
        label := (self class separatorSlices at:name) last.
    ].
    isVisible := (aspects at:#isVisible) value.

!

buildFromMenuItem:anItem
    "read the attributes of anItem into my values"

    |rtv|

    self label:(anItem label).
    activeHelpKey := anItem activeHelpKey.

    (enabled := anItem enabled) isSymbol ifFalse:[
        enabled := nil
    ].

    (value := anItem value) isSymbol ifFalse:[
        value := nil.
    ].

    (indication := anItem indication) isSymbol ifFalse:[
        indication := nil
    ].

    nameKey            := anItem nameKey.
    shortcutKey        := anItem shortcutKeyCharacter.
    startGroup         := anItem startGroup.
    accessCharacterPos := anItem accessCharacterPosition.
    argument           := anItem argument.

    submenuChannel     := anItem submenuChannel.
    translateLabel     := anItem translateLabel.
    isButton           := anItem isButton.
    isVisible          := anItem isVisible.

    (((rtv := anItem adornment) notNil)
    and:[(rtv := rtv labelImage) isKindOf:ResourceRetriever])
    ifTrue:
    [
        retriever := rtv className.
        icon      := rtv selector.
        (iconAndLabel := rtv labelText notNil) ifTrue:[
            label := rtv labelText.
        ]
    ]
!

toAspects:aspects
    "put my values into the values of aspects"

    |type|
    (type := self separatorType) notNil
    ifTrue:
    [
        type := self class separatorSlices findFirst:[:el| el first == type ].
        (aspects at:#seperatorSelection) selectionIndex:type.
    ] 
    ifFalse:
    [
        (aspects at:#label)                value:label.
        (aspects at:#enabled)              value:enabled.
        (aspects at:#value)                value:value.
        (aspects at:#nameKey)              value:nameKey.
        (aspects at:#indication)           value:indication.
        (aspects at:#shortcutKey)          value:shortcutKey.
        (aspects at:#startGroup)           value:startGroup.
        (aspects at:#accessCharacterPos)   value:accessCharacterPos.
        (aspects at:#translateLabel)       value:translateLabel.
        (aspects at:#submenuChannel)       value:submenuChannel.
        (aspects at:#retriever)            value:retriever.
        (aspects at:#icon)                 value:icon.
        (aspects at:#iconAndLabel)         value:iconAndLabel.
        (aspects at:#isButton)             value:isButton.

        argument isSymbol
            ifTrue: [(aspects at:#argument)value:'#', argument] 
            ifFalse:[(aspects at:#argument)value:argument].
    ].
    (aspects at:#isVisible) value:isVisible.

! !

!MenuEditor::Item methodsFor:'queries'!

iconFor: aNode
    "get the icon of the menu item for the tree view"

    (aNode hasChildren or: [aNode parent isNil])
    ifTrue:
    [
        ^MenuEditor submenuImage
    ]
    ifFalse:
    [
        submenuChannel notNil 
        ifTrue:
        [
            ^MenuEditor linkSubmenuImage
        ]
        ifFalse:
        [
            self isSeparator 
                ifTrue:  [^MenuEditor menuSeparatorImage]
                ifFalse: [^MenuEditor menuItemImage]
        ]
    ]
!

isSeparator
    "return true if item is a seperator"

    ^self separatorType notNil
!

treeViewLabel
    "get the label of the menu item for the tree view"

    ^label asBoldText, 
        (value notNil ifTrue: [': [', 
                value ,
                (argument notNil ifTrue: [' ', (Text string: argument emphasis: #italic)] ifFalse: ['']),
                 ']'] ifFalse: [''])
! !

!MenuEditor::TreeView class methodsFor:'documentation'!

documentation
"
    This tree view class provides a hierarchical representation
    of the components of a menu.

    [see also:]
        SelectionInTreeView
        SelectionInTree
        TreeItem

    [author:]
        Claus Atzkern
"
! !

!MenuEditor::TreeView methodsFor:'accessing'!

selectorName
    "get the selector of the menu spec"

    ^(listOfNodes first contents label) asSymbol
!

selectorName: aSymbol
    "set the selector for the menu spec"

    listOfNodes first contents label: aSymbol
! !

!MenuEditor::TreeView methodsFor:'building'!

buildFromClass:aClass andSelector:aSelector
    "read a menu spec from aClass and aSelector and put 
     the encoded menu into the tree view"

    |spec cls menu firstNode firstNodeLabel|

    "if opened on a menu"
    (aClass isNil and: [aSelector isNil and: [listOfNodes size > 0]]) ifTrue: [^nil].

    (aClass notNil and:[aSelector notNil]) ifTrue:[
        cls := self application resolveName:aClass.

        (cls respondsTo:aSelector) ifTrue:[
            spec := cls perform:aSelector
        ]
    ].

    spec isNil ifFalse:[
        (spec isMemberOf:Menu) ifFalse:[
            menu := Menu new fromLiteralArrayEncoding:spec.
        ] ifTrue:[
            menu := spec.
        ].
        firstNode := self nodeLabel:(aSelector asString).
        self subMenu:menu parent:firstNode.
    ] ifTrue:[
        (aClass notNil and: [aSelector isNil and: [listOfNodes size > 0]])
        ifTrue:
        [
            firstNode := listOfNodes first
        ]
        ifFalse:
        [
            aSelector notNil ifTrue:[firstNodeLabel := aSelector asString]
                        ifFalse:[firstNodeLabel := 'menu'].
            firstNode := self nodeLabel:firstNodeLabel.
        ]
    ].

    firstNode expand.
    model root: firstNode.

    firstNode hasChildren ifFalse:[
        model add:(self nodeLabel:'Item 1') below:firstNode
    ].


!

buildFromMenu:aMenu
    "put aMenu into the tree view"

    |node|

    node := self nodeLabel:'menu'.
    self subMenu:aMenu parent:node.

    node hasChildren ifFalse:[
        node add:(self nodeLabel:'Item 1')
    ].
    node expand.
    model root:node.
!

menuItem:anItem

    |node|

    node := self nodeLabel: anItem label.
    node contents buildFromMenuItem:anItem.
    self subMenu: anItem submenu parent:node.
    ^node.


!

subMenu:aMenu parent:aParent

    |idx grp|

    aMenu isNil ifFalse:[
        grp := aMenu groupSizes.
        aMenu itemsDo:[:i| aParent add:(self menuItem:i)].

        grp notNil ifTrue:[
            idx := 0.

            grp do:[:i|
                idx := idx + i + 1.
                aParent add:(self nodeLabel:nil) beforeIndex:idx.
            ]
        ]
    ]
! !

!MenuEditor::TreeView methodsFor:'conversion'!

asMenu
    |menu root|

    root := self root.

    root hasChildren ifTrue:[
        menu := Menu new.
        root children do:[:aChild| menu addItem:(self asMenuItem:aChild)].
    ].
  ^ menu
!

asMenuItem:aNode

    |menu item|

    item := aNode contents asMenuItem.

    aNode hasChildren ifTrue:[
        menu := Menu new.
        aNode children do:[:aChild| menu addItem:(self asMenuItem:aChild)].
        item submenu:menu
    ].
  ^ item

! !

!MenuEditor::TreeView methodsFor:'drawing basics'!

drawLabelIndex:anIndex atX:x y:yCenter
    "draw text label assigned to a node at x y( center)"

    |y x2 type item|

    item := (listOfNodes at:anIndex) contents.
    type := item separatorType.

    type isNil ifTrue:[
        super drawLabelIndex:anIndex atX:x y:yCenter
    ] ifFalse:[
        type == #blank ifFalse:[
            x2 := x + 80.

            self displayLineFromX:x y:yCenter toX:x2 y:yCenter.

            type == #double ifTrue:[
                y := yCenter + 2.
                self displayLineFromX:x y:y toX:x2 y:y.
            ]    
        ]
    ]
! !

!MenuEditor::TreeView methodsFor:'event handling'!

keyPress:key x:x y:y
    "invoked if any key was pressed"

    <resource: #keyboard (#Delete #BackSpace #Cut #Copy #Paste)>

    (key == #Delete or:[key == #BackSpace]) ifTrue: [^self doDelete].
    key == #Cut   ifTrue:[^self doCut].
    key == #Copy  ifTrue:[^self doCopy].
    key == #Paste ifTrue:[^self doPaste].

    super keyPress:key x:x y:y

! !

!MenuEditor::TreeView methodsFor:'initialization'!

initialize
    "initialize the tree view of the menu components"

    super initialize.

    self multipleSelectOk:true.
    self showDirectoryIndicator: true.
    self showDirectoryIndicatorForRoot: false.
    self selectConditionBlock: [:i|self application askForItemModification]. 
    self validateDoubleClickBlock: [:node| node ~~ listOfNodes first].
    self model iconAction: [:aNode| aNode contents iconFor: aNode].
    self model labelAction: [:aNode| aNode contents treeViewLabel]
! !

!MenuEditor::TreeView methodsFor:'menus'!

doCopy

    self hasSelection ifTrue:[
        self application clipboard: OrderedCollection new.
        self selectionDo:[:i| self application clipboard add:((listOfNodes at:i) copy)].
        self topView application updateAllToolInstances.
    ]
!

doCreateItem

    self addElement: (self nodeLabel:'Item')
!

doCreateLink

    |node item|

    node := self nodeLabel:'Submenu Link'.
    item := node contents.
    item submenuChannel:#menuDefaultLink.
    self addElement:node.
    self setModified.


!

doCreateMenu

    |node|
    node := self nodeLabel:'Submenu'.
    node parent: self selectedNode.        
    node add:(self nodeLabel:'Item 1').
    self addElement:node
!

doCreateSep

    self addElement:(self nodeLabel:nil)
!

doCut

    (self topView application hasValidSelection value and: [self askForItemModification])
    ifTrue:
    [
        |selectedNodes|
        self doCopy.
        selectedNodes := self selection asSortedCollection.
        self selectedNodesRemove.
        self selection: selectedNodes first - 1.
        self setModified.
        self topView application updateAllToolInstances.
    ]

!

doDelete

    (self topView application hasValidSelection value and: [self askForItemModification])
    ifTrue:
    [
        |selectedNodes|
        selectedNodes := self selection asSortedCollection.
        self selectedNodesRemove.
        self selection: selectedNodes first - 1.
        self setModified.
    ]

!

doPaste

    (self application clipboard notNil and:[self selectedNode notNil]) ifTrue:[
        self addElement:(self application clipboard collect:[:el| el copy])
    ].
! !

!MenuEditor::TreeView methodsFor:'private'!

addElement: aNode
    "add something after selection"

    self askForItemModification
    ifTrue:
    [   
        self selectedNodeAdd: aNode.
        (aNode isCollection not and: [aNode name = 'Item']) 
        ifTrue: 
        [
            |label|     
            label := aNode name, ' ',
                (self selectedNode parent notNil 
                ifTrue:
                [
                    (((self selectedNode children size = 0 
                        ifTrue: [self selectedNode parent children] 
                        ifFalse: [self selectedNode children]) select: 
                            [:node| 
                                |lab| 
                                lab := node contents label. 
                                ((node children size = 0) & 
                                node contents submenuChannel isNil &
                                (lab ~= '-') & (lab ~= '=') & (lab ~= ''))
                            ]) size) printString] 
                ifFalse: ['1']).  

            aNode name: label string asBoldText.
            aNode contents label: label string.
        ].    
        aNode isCollection ifFalse: [self selectNode: aNode] ifTrue: [self selection: (aNode collect: [:node| self indexOfNode: node])].
        self setModified.
    ]
!

askForItemModification

    ^self topView application askForItemModification
!

nodeLabel:aLabel

    ^TreeItem new contents: (MenuEditor::Item new label:aLabel)
!

selectedNodeAdd:something

    |node|

    something notNil ifTrue:[
        (node := self selectedNode) notNil ifTrue:[
            node parent notNil ifTrue:[
                node isCollapsable ifTrue:[
                    model add:something afterIndex:node children size below:node
                ] ifFalse:[
                    model add:something after:node
                ]
            ] ifFalse:[
                model add:something afterIndex:node children size below:(self root)
            ]
        ]
    ]


!

setModified 

    self topView application modified: true.

    self topView application updateChannels
! !

!MenuEditor class methodsFor:'documentation'!

version
    ^ '$Header$'
! !