MenuEditor.st
author tz
Thu, 05 Mar 1998 17:24:21 +0100
changeset 698 5bf234e0e451
parent 686 6eabad89ebf6
child 699 7746185a3621
permissions -rw-r--r--
redefine methods flag

"
 COPYRIGHT (c) 1997 by eXept Software AG / Claus Gittinger
              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.
"



ListSpecEditor 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 / Claus Gittinger
              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
"
    create and modify or inspect popup and pullDown menus of the
    new style( derives from Menu).

    [start with:]
        MenuEditor open
        MenuEditor new openOnClass:MenuEditor andSelector:#menuPullDown

    [see also:]
        UIPainter
        UIHelpTool
        UISpecificationTool
        SelectionInTreeView

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

! !

!MenuEditor class methodsFor:'initialization'!

initialize

    super initialize.

    TreeView initialize
! !

!MenuEditor class methodsFor:'instance creation'!

openModalOnClass:aClass andSelector:aSelector
    ^ self new openModalOnClass:aClass andSelector:aSelector


!

openOnClass:aClass andSelector:aSelector
    ^ self new openOnClass:aClass andSelector:aSelector


! !

!MenuEditor class methodsFor:'accessing'!

resourceType

    ^#menu




! !

!MenuEditor class methodsFor:'aspects'!

aspects

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

     )

! !

!MenuEditor class methodsFor:'code generation'!

sourceCategory
    "returns the category where to install the menu
    "
    ^ 'accessing menu'
! !

!MenuEditor class methodsFor:'help specs'!

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

    "
    UIHelpTool openOnClass:MenuEditor    
    "

  ^ 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
'Changes the cursor for moving it over another menu view to load its menu spec.'

#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.'

)
! !

!MenuEditor class methodsFor:'interface specs'!

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

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

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

    <resource: #canvas>

    ^
     
       #(#FullSpec
          #'window:' 
           #(#WindowSpec
              #'name:' 'unnamed canvas'
              #'layout:' #(#LayoutFrame 73 0 152 0 339 0 470 0)
              #'label:' 'unnamed canvas'
              #'min:' #(#Point 10 10)
              #'max:' #(#Point 1160 870)
              #'bounds:' #(#Rectangle 73 152 340 471)
              #'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
                )
                 #(#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 192)
                    #'activeHelpKey:' #basicsTranslateLabel
                    #'tabable:' true
                    #'model:' #translateLabel
                    #'label:' 'Translate Label'
                )
                 #(#CheckBoxSpec
                    #'name:' 'isButtonCheckBox'
                    #'layout:' #(#Point 20 221)
                    #'activeHelpKey:' #basicsIsButton
                    #'tabable:' true
                    #'model:' #isButton
                    #'label:' 'Is Button'
                )
              )
          )
      )
!

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

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

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

    <resource: #canvas>

    ^
     
       #(#FullSpec
          #'window:' 
           #(#WindowSpec
              #'name:' 'unnamed canvas'
              #'layout:' #(#LayoutFrame 73 0 152 0 339 0 470 0)
              #'label:' 'unnamed canvas'
              #'min:' #(#Point 10 10)
              #'max:' #(#Point 1280 1024)
              #'bounds:' #(#Rectangle 73 152 340 471)
              #'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 128)
                    #'activeHelpKey:' #basicsTranslateLabel
                    #'tabable:' true
                    #'model:' #translateLabel
                    #'label:' 'Translate Label'
                )
              )
          )
      )
!

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

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

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

    <resource: #canvas>

    ^
     
       #(#FullSpec
          #'window:' 
           #(#WindowSpec
              #'name:' 'unnamed canvas'
              #'layout:' #(#LayoutFrame 73 0 152 0 339 0 470 0)
              #'label:' 'unnamed canvas'
              #'min:' #(#Point 10 10)
              #'max:' #(#Point 1280 1024)
              #'bounds:' #(#Rectangle 73 152 340 471)
              #'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 100)
                    #'activeHelpKey:' #basicsTranslateLabel
                    #'tabable:' true
                    #'model:' #translateLabel
                    #'label:' 'Translate Label'
                )
              )
          )
      )
!

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

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

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

    <resource: #canvas>

    ^
     
       #(#FullSpec
          #'window:' 
           #(#WindowSpec
              #'name:' 'unnamed canvas'
              #'layout:' #(#LayoutFrame 73 0 152 0 339 0 470 0)
              #'label:' 'unnamed canvas'
              #'min:' #(#Point 10 10)
              #'max:' #(#Point 1280 1024)
              #'bounds:' #(#Rectangle 73 152 340 471)
              #'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 window spec was automatically generated by the ST/X UIPainter"

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

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

    <resource: #canvas>

    ^
     
       #(#FullSpec
          #'window:' 
           #(#WindowSpec
              #'name:' 'unnamed canvas'
              #'layout:' #(#LayoutFrame 219 0 193 0 485 0 511 0)
              #'label:' 'unnamed canvas'
              #'min:' #(#Point 10 10)
              #'max:' #(#Point 1160 870)
              #'bounds:' #(#Rectangle 219 193 486 512)
              #'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:' 'isVisibleInputField'
                    #'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 window spec was automatically generated by the ST/X UIPainter"

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

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

    <resource: #canvas>

    ^
     
       #(#FullSpec
          #'window:' 
           #(#WindowSpec
              #'name:' 'unnamed canvas'
              #'layout:' #(#LayoutFrame 73 0 152 0 331 0 439 0)
              #'label:' 'unnamed canvas'
              #'min:' #(#Point 10 10)
              #'max:' #(#Point 1280 1024)
              #'bounds:' #(#Rectangle 73 152 332 440)
              #'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'
                    #'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 window spec was automatically generated by the ST/X UIPainter"

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

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

    <resource: #canvas>

    ^

       #(#FullSpec
          #'window:' 
           #(#WindowSpec
              #'name:' 'unnamed canvas'
              #'layout:' #(#LayoutFrame 238 0 321 0 482 0 462 0)
              #'label:' 'unnamed canvas'
              #'min:' #(#Point 10 10)
              #'max:' #(#Point 1280 1024)
              #'bounds:' #(#Rectangle 238 321 483 463)
              #'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 window spec was automatically generated by the ST/X UIPainter"

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

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

    <resource: #canvas>

    ^
     
       #(#FullSpec
          #'window:' 
           #(#WindowSpec
              #'name:' 'Menu Builder'
              #'layout:' #(#LayoutFrame 324 0 233 0 903 0 616 0)
              #'label:' 'Menu Builder'
              #'min:' #(#Point 10 10)
              #'max:' #(#Point 1152 900)
              #'bounds:' #(#Rectangle 324 233 904 617)
              #'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:' 'variableHorizontalPanel1'
                    #'layout:' #(#LayoutFrame 0 0.0 34 0.0 0 1.0 -26 1.0)
                    #'component:' 
                     #(#SpecCollection
                        #'collection:' 
                         #(
                           #(#ArbitraryComponentSpec
                              #'name:' 'painterView'
                              #'menu:' #menuEdit
                              #'hasHorizontalScrollBar:' true
                              #'hasVerticalScrollBar:' true
                              #'component:' #treeView
                              #'hasBorder:' false
                          )
                           #(#ViewSpec
                              #'name:' 'view1'
                              #'component:' 
                               #(#SpecCollection
                                  #'collection:' 
                                   #(
                                     #(#NoteBookViewSpec
                                        #'name:' 'specificationView'
                                        #'layout:' #(#LayoutFrame 1 0.0 0 0.0 1 1.0 -26 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.384483 1.0)
                )
                 #(#UISubSpecification
                    #'name:' 'infoBarSubSpec'
                    #'layout:' #(#LayoutFrame 0 0.0 -24 1 0 1.0 0 1.0)
                    #'majorKey:' #ToolApplicationModel
                    #'minorKey:' #windowSpecForInfoBar
                )
              )
          )
      )
! !

!MenuEditor class methodsFor:'menu specs'!

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

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

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

    <resource: #menu>

    ^
     
       #(#Menu
          
           #(
             #(#MenuItem
                #label: 'About'
                #activeHelpKey: #about
                #accessCharacterPosition: 1
                #labelImage: #(#ResourceRetriever nil #menuIcon)
                #submenuChannel: #menuAbout
            )
             #(#MenuItem
                #label: 'File'
                #translateLabel: true
                #activeHelpKey: #file
                #submenu: 
                 #(#Menu
                    
                     #(
                       #(#MenuItem
                          #label: 'New'
                          #value: #doNew
                          #activeHelpKey: #fileNew
                      )
                       #(#MenuItem
                          #label: '-'
                      )
                       #(#MenuItem
                          #label: 'Load...'
                          #translateLabel: true
                          #value: #doLoad
                          #activeHelpKey: #fileLoad
                          #enabled: #isStandAlone
                      )
                       #(#MenuItem
                          #label: '-'
                      )
                       #(#MenuItem
                          #label: 'Save'
                          #value: #doSave
                          #activeHelpKey: #fileSave
                      )
                       #(#MenuItem
                          #label: 'Save As...'
                          #value: #doSaveAs
                          #activeHelpKey: #fileSaveAs
                      )
                       #(#MenuItem
                          #label: '-'
                      )
                       #(#MenuItem
                          #label: 'Pick A Menu...'
                          #value: #doPickAMenu
                          #activeHelpKey: #filePickAMenu
                          #enabled: #isStandAlone
                      )
                       #(#MenuItem
                          #label: '-'
                      )
                       #(#MenuItem
                          #label: 'Browse Class'
                          #value: #doBrowseClass
                          #activeHelpKey: #fileBrowseClass
                      )
                       #(#MenuItem
                          #label: '-'
                      )
                       #(#MenuItem
                          #label: 'Exit'
                          #translateLabel: true
                          #value: #closeRequest
                          #activeHelpKey: #fileExit
                      )
                    ) nil
                    nil
                )
            )
             #(#MenuItem
                #label: 'Edit'
                #activeHelpKey: #edit
                #submenuChannel: #menuEdit
            )
             #(#MenuItem
                #label: 'Add'
                #activeHelpKey: #add
                #submenuChannel: #menuAdd
            )
             #(#MenuItem
                #label: 'Test'
                #activeHelpKey: #test
                #submenuChannel: #submenuTest
            )
             #(#MenuItem
                #label: 'History'
                #activeHelpKey: #history
                #submenuChannel: #menuHistory
            )
             #(#MenuItem
                #label: 'Help'
                #startGroup: #right
                #activeHelpKey: #help
                #submenuChannel: #menuHelp
            )
          ) nil
          nil
      )
!

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

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

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

    <resource: #menu>

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

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

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

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

    <resource: #menu>

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

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

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

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

    <resource: #menu>

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

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

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

    "
     MenuEditor new openOnClass: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: #hasAnySingleSelection
                #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:'resources'!

linkSubmenuImage
    "Generated by the Image Editor"
    "
    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
    "Generated by the Image Editor"
    "
    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
    "Generated by the Image Editor"
    "
    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
    "Generated by the Image Editor"
    "
    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:'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
    "returns submenu assigned to item test"

    |menu|

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

useHelpDictionary:aDictionary

    self noteBookView.
    self helpTool dictionary:aDictionary
! !

!MenuEditor methodsFor:'aspects'!

hasAnySingleSelection

    ^builder booleanValueAspectFor: #hasAnySingleSelection
!

hasValidSelection

    ^builder booleanValueAspectFor: #hasValidSelection
!

hasValidSingleSelection

    ^builder booleanValueAspectFor: #hasValidSingleSelection
!

noteBookView

    |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

    |holder|
    (holder := builder bindingAt:#tabList) isNil ifTrue:[
        builder aspectAt:#tabList put:(holder := #('Properties') asValue).
    ].
    ^ holder


!

treeView
    "returns the tree view representing hierarchically all 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:'change & update'!

updateEnabledChannels
    "update enabled 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
        ]
    ]
    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.
! !

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

openTutorial

    self openTutorial: 'tools/MenuEditor/TOP.html'.

! !

!MenuEditor methodsFor:'initialization'!

initialize
    "initialize value holders for the menu item properties"

    |holder|

    super initialize.

    aspects at:#seperatorSelection put:(holder := SelectionInList new).
    holder list: Item separatorList.
    holder addDependent:self.

! !

!MenuEditor methodsFor:'private'!

helpKey

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

helpTool

    ^helpCanvas application
! !

!MenuEditor methodsFor:'queries'!

isHelpToolSelected
    "returns true if current selection is help tool"

    (tabSelection ~~ 0 and:[slices notNil]) ifTrue:[
        ^(slices at:tabSelection) first = UIHelpTool label
    ].
    ^false
!

isStandAlone
    "returns true in case of owner of the helptool"

    ^self masterApplication isNil
!

preferredExtent

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


! !

!MenuEditor methodsFor:'selection'!

menuChanged

    |node item slc sel old dep|

    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 updateEnabledChannels.
    aspects do: [:holder| holder addDependent:self].
!

tabSelection: aSelection

    |sel|                   
    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:[                       
        sel := (slices at:tabSelection) last.   
        aspects do: [:holder| holder release].
        specCanvas client:self spec:(self class perform:sel) builder:builder.
        aspects do: [:holder| holder addDependent:self].
        specCanvas raise.  
    ]    

! !

!MenuEditor methodsFor:'startup / release'!

buildFromClass:aClass andSelector:aSelector

    self isStandAlone ifTrue:[
        self helpTool helpSpecFrom:specClass
    ].              
    self treeView buildFromClass: aClass andSelector: specSelector.

    self updateHistory.
    self updateInfoLabel.
    self treeView selection: 2.
    self menuChanged

!

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

!

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

    self askForModification
    ifTrue: 
    [
        specClass := specSelector := nil.
        self buildFromClass: nil andSelector: #menu
    ]
!

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

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

    BANG := Character excla asString.

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

            , specSelector , '\'
            , '    "this window spec was automatically generated by the ST/X MenuEditor"\\'
            , '    "do not manually edit this - the builder may not be able to\'
            , '     handle the specification if its corrupted."\\'
            , '    "\'
            , ('     MenuEditor new openOnClass:' , cls name , ' andSelector:#' , specSelector , '\')
            , ('     (Menu new fromLiteralArrayEncoding:(' , cls name , ' ' , specSelector , ')) startUp\')
            , '    "\'.

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

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

    self isStandAlone ifTrue:[
        self helpTool installHelpSpecInto:(self specClass)
    ].
    self updateHistory.
    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

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

separatorSlices
   ^ #(
        ( #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

    ^activeHelpKey
!

activeHelpKey:aKey

    activeHelpKey := aKey
!

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

    ^label
!

label:something
    "set the value of the instance variable 'label' (automatically generated)"

    label := something ? '-'
!

separatorType
    "returns 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
    "return the value of the instance variable 'submenuChannel' (automatically generated)"

    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

    |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

    |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

    |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

    (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
    "returns true if item is a seperator"

    ^self separatorType notNil
!

treeViewLabel

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

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

documentation
"
    menu selection list

    [see also:]
        SelectionInTreeView
        SelectionInTree
        TreeItem

    [author:]
        Claus Atzkern
"


! !

!MenuEditor::TreeView methodsFor:'accessing'!

selectorName

    ^(listOfNodes first contents label) asSymbol
!

selectorName: aSymbol

    listOfNodes first contents label: aSymbol
! !

!MenuEditor::TreeView methodsFor:'building'!

buildFromClass:aClass andSelector:aSelector

    |spec cls menu node|

    (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.
        ].
        node := self nodeLabel:(aSelector asString).
        self subMenu:menu parent:node.
    ] ifTrue:[
        aSelector notNil ifTrue:[cls := aSelector asString]
                        ifFalse:[cls := 'menu'].

        node := self nodeLabel:cls.
    ].
    node expand.
    model root:node.

    node hasChildren ifFalse:[
        |n|              
        n := self nodeLabel:'Item 1'.   
        n parent: node.
        node add: n.
        model recomputeList
    ].


!

buildFromMenu:aMenu

    |node|

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

    node hasChildren ifFalse:[
        node add:(self nodeLabel:'Item')
    ].
    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

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

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

!

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

!MenuEditor class methodsFor:'documentation'!

version
    ^ '$Header$'
! !
MenuEditor initialize!