MenuEditor.st
author Stefan Vogel <sv@exept.de>
Fri, 17 May 2019 16:59:23 +0200
changeset 3664 0d01da886d5a
parent 3636 197a2fbb8c5d
child 3751 5c7bb0559dc1
permissions -rw-r--r--
#REFACTORING by stefan
Sanitize BlockValues

class: MenuEditor
changed: #hasNonLinkedMenuSelectedHolder
     1 "{ Encoding: utf8 }"
     2 
     3 "
     4  COPYRIGHT (c) 1997 by eXept Software AG
     5 	      All Rights Reserved
     6 
     7  This software is furnished under a license and may be used
     8  only in accordance with the terms of that license and with the
     9  inclusion of the above copyright notice. This software may not
    10  be provided or otherwise made available to, or used by, any
    11  other person.  No title to or ownership of the software is
    12  hereby transferred.
    13 "
    14 "{ Package: 'stx:libtool2' }"
    15 
    16 "{ NameSpace: Smalltalk }"
    17 
    18 ResourceSpecEditor subclass:#MenuEditor
    19 	instanceVariableNames:'selectionHolder tabHolder listOfItems listOfTabs
    20 		selectedSuperItems notifyDisabledCounter wizards listOfItemsView
    21 		dropOverLine savedSpec'
    22 	classVariableNames:'ImageRetrieverClasses'
    23 	poolDictionaries:''
    24 	category:'Interface-UIPainter'
    25 !
    26 
    27 HierarchicalItem subclass:#Item
    28 	instanceVariableNames:'menuItem'
    29 	classVariableNames:''
    30 	poolDictionaries:''
    31 	privateIn:MenuEditor
    32 !
    33 
    34 ApplicationModel subclass:#ImageResourceEditor
    35 	instanceVariableNames:'selectorHolder iconAndLabelHolder retrieverHolder imageHolder
    36 		imageList selectorFilterHolder imageListView'
    37 	classVariableNames:''
    38 	poolDictionaries:''
    39 	privateIn:MenuEditor
    40 !
    41 
    42 HierarchicalItem subclass:#ImageResourceEditorItem
    43 	instanceVariableNames:'selector icon'
    44 	classVariableNames:''
    45 	poolDictionaries:''
    46 	privateIn:MenuEditor::ImageResourceEditor
    47 !
    48 
    49 MenuEditor::Item subclass:#ActionItem
    50 	instanceVariableNames:''
    51 	classVariableNames:''
    52 	poolDictionaries:''
    53 	privateIn:MenuEditor
    54 !
    55 
    56 MenuEditor::Item subclass:#LinkedMenuItem
    57 	instanceVariableNames:''
    58 	classVariableNames:''
    59 	poolDictionaries:''
    60 	privateIn:MenuEditor
    61 !
    62 
    63 MenuEditor::Item subclass:#MenuSliceItem
    64 	instanceVariableNames:''
    65 	classVariableNames:''
    66 	poolDictionaries:''
    67 	privateIn:MenuEditor
    68 !
    69 
    70 MenuEditor::Item subclass:#RegularMenuItem
    71 	instanceVariableNames:''
    72 	classVariableNames:''
    73 	poolDictionaries:''
    74 	privateIn:MenuEditor
    75 !
    76 
    77 MenuEditor::RegularMenuItem subclass:#RootItem
    78 	instanceVariableNames:''
    79 	classVariableNames:''
    80 	poolDictionaries:''
    81 	privateIn:MenuEditor
    82 !
    83 
    84 MenuEditor::Item subclass:#SeparatorItem
    85 	instanceVariableNames:''
    86 	classVariableNames:''
    87 	poolDictionaries:''
    88 	privateIn:MenuEditor
    89 !
    90 
    91 !MenuEditor class methodsFor:'documentation'!
    92 
    93 copyright
    94 "
    95  COPYRIGHT (c) 1997 by eXept Software AG
    96 	      All Rights Reserved
    97 
    98  This software is furnished under a license and may be used
    99  only in accordance with the terms of that license and with the
   100  inclusion of the above copyright notice. This software may not
   101  be provided or otherwise made available to, or used by, any
   102  other person.  No title to or ownership of the software is
   103  hereby transferred.
   104 "
   105 !
   106 
   107 documentation
   108 "
   109     The MenuEditor allows you to create, modify or just inspect
   110     menu specifications. Such specifications are returned by menu-spec methods
   111     of the application class. These methods are typically tagged with a menu-resource.
   112     The menu editor is able to retrieve such specifications and generate new menu-spec
   113     methods.
   114 
   115     The editor is typically opened by double-clicking on a menu-spec method in the browser.
   116 
   117     [Instance variables:]
   118 
   119 	listOfItemsView         <HierarcicalListView>  the view which shows the list of items
   120 	listOfItems             <HierarchicalList>     hierarchical list of menu items
   121 	listOfTabs              <List>                 list of current shown tab-labels
   122 
   123 	selectionHolder         <ValueHolder>          collection of current selected items
   124 	selectedSuperItems      <Collection>           collection of superItems derived from selection
   125 
   126 	tabHolder               <ValueHolder>          selected tab label holder
   127 	notifyDisabledCounter   <SmallInteger>         ~~ 0 than change notifications are discard
   128 	wizards                 <IdentityDictionary>   keeps all created wizard dialogs
   129 
   130 	dropOverLine            <nil or SmallInteger>  nil: drop context not dropabel.
   131 						       = 0: drop context dropable but no item specified
   132 						       ~ 0: drop context dropable for item at lineNumber
   133 						       used t6o restore drop indication drawings
   134 
   135     [Class variables:]
   136 	ImageRetrieverClasses   <Collection>        sorted collection of image receivers
   137 
   138     [start with:]
   139 	MenuEditor open
   140 	MenuEditor openOnClass:MenuEditor andSelector:#menu
   141 
   142     [author:]
   143 	Claus Atzkern, eXept Software AG
   144 	Thomas Zwick, eXept Software AG
   145 "
   146 ! !
   147 
   148 !MenuEditor class methodsFor:'initialization'!
   149 
   150 initialize
   151     ImageRetrieverClasses := #(
   152 				Icon
   153 				SystemBrowser
   154 				ToolbarIconLibrary
   155 			      ).
   156 
   157     "
   158      self initialize
   159     "
   160 ! !
   161 
   162 !MenuEditor class methodsFor:'instance creation'!
   163 
   164 openModalOnMenu: aMenu
   165     "Open a MenuEditor modal on aMenu
   166      self openModalOnMenu: (self perform: #menu) decodeAsLiteralArray
   167     "
   168     ^self new openModalOnMenu:aMenu
   169 ! !
   170 
   171 !MenuEditor class methodsFor:'accessing image retriever'!
   172 
   173 addNewImageRetriever:aSymbolOrClass
   174     "add a class to the imageRetriever list"
   175 
   176     |key|
   177 
   178     aSymbolOrClass isBehavior ifTrue:[
   179 	key := aSymbolOrClass nameWithNameSpacePrefix
   180     ] ifFalse:[
   181 	key := aSymbolOrClass
   182     ].
   183 
   184     key size ~~ 0 ifTrue:[
   185 	key := key asSymbol.
   186 
   187 	(ImageRetrieverClasses includes:key) ifFalse:[
   188 	    ImageRetrieverClasses := ImageRetrieverClasses asOrderedCollection.
   189 	    ImageRetrieverClasses add:key.
   190 	    ImageRetrieverClasses sort.
   191 	]
   192     ].
   193 !
   194 
   195 imageRetrieverClasses
   196     "returns a collection of image retrievers
   197     "
   198     ^ ImageRetrieverClasses
   199 ! !
   200 
   201 !MenuEditor class methodsFor:'aspects'!
   202 
   203 aspects
   204     "get the aspects for the attributes of the menu components"
   205 
   206     ^#(
   207         rawLabel
   208         accessCharacterPosition
   209         showBusyCursorWhilePerforming
   210         horizontalLayout
   211         triggerOnDown
   212         font
   213         argument
   214         submenuChannel
   215         keepLinkedMenu
   216         enabled
   217         itemValue
   218         nameKey
   219         indication
   220         choice
   221         choiceValue
   222         translateLabel
   223         isButton
   224         shortcutKeyCharacter
   225         startGroup
   226         isVisible
   227         hideMenuOnActivated
   228         auxValue
   229         activeHelpKey
   230         resourceRetriever
   231         sendToOriginator
   232         ignoreMnemonicKeys
   233         ignoreShortcutKeys
   234         isMenuSlice
   235         hasMenuIndicator
   236      )
   237 
   238     "Modified: / 09-08-2018 / 17:03:56 / Claus Gittinger"
   239 ! !
   240 
   241 !MenuEditor class methodsFor:'defaults'!
   242 
   243 resourceType
   244     "get the type of the resource of the method generated by the MenuEditor
   245     "
   246     ^ #menu
   247 ! !
   248 
   249 !MenuEditor class methodsFor:'help specs'!
   250 
   251 helpSpec
   252     ^super helpSpec addPairsFrom: #(
   253 
   254 #editCut
   255 'Cut Item'
   256 
   257 #editCopy
   258 'Copy Item'
   259 
   260 #editPaste
   261 'Paste Item'
   262 
   263 #fileSaveSpec
   264 'Save Menuspec'
   265 
   266 #addMenuSlice
   267 'Add Menuslice'
   268 
   269 #addDelayedMenu
   270 'Add a new delayed menu to item.'
   271 
   272 #addDelayedSubMenuLink
   273 'Add a new linked delayed menu to item.'
   274 
   275 #addMenuItem
   276 'Add a new menu item.'
   277 
   278 #addMenuSeparator
   279 'Add a new menu separator.'
   280 
   281 #addMenuSliceItem
   282 'Add a new menu slice.'
   283 
   284 #addSubMenu
   285 'Add a new sub menu.'
   286 
   287 #addSubMenuLink
   288 'Add a new linked sub menu.'
   289 
   290 #basicsAction
   291 'An action selector with 0, 1 (the argument field), or 2 (the selected item) arguments.'
   292 
   293 #browseMethod
   294 'Open a browser on this method in the application. Create the method, if it does not exist.'
   295 
   296 #basicsArgument
   297 'An optional arg passed with above selector, if it is a 1 or 2 arg selector (enter a Smalltalk literal).'
   298 
   299 #basicsChoice
   300 'Aspect for a boolean holder, block or method, specifying the choices state (RadioButton behavior).'
   301 
   302 #basicsChoiceValue
   303 'That choices value (typically number or symbol).'
   304 
   305 #basicsIndication
   306 'Aspect for boolean holder, block, or method, specifying the indication state (CheckToggle behavior).'
   307 
   308 #basicsIsButton
   309 'Button-like look and behavior.'
   310 
   311 #basicsKey
   312 'Internal key of the item (optional, for programmed accesses).'
   313 
   314 #basicsLabel
   315 'Label of the item.'
   316 
   317 #basicsMenu
   318 'Aspect providing the sub menu to be opened if item is selected (provide spec or valueHolder).'
   319 
   320 #basicsMenuArgument
   321 'An argument passed with the menu selector.'
   322 
   323 #basicsNameKey
   324 'Unique identifier of the item (optional).'
   325 
   326 #basicsSelector
   327 'Selector under which the generated menu spec is saved.'
   328 
   329 #basicsSeparatorType
   330 'List of valid separators.'
   331 
   332 #basicsTranslateLabel
   333 'Translate the label via the classes resource file (internationalization).'
   334 
   335 #browseResource
   336 'Search for methods with image resource.'
   337 
   338 #detailsAccelerator
   339 'Accelerator key to select the menu item from the keyboard (Cmdx or Ctrlx).'
   340 
   341 #detailsAccessCharaterPosition
   342 'Index of the access character position of the textual label (obsolete, VW compatibility).'
   343 
   344 #detailsAuxValue
   345 'Some additional value - for arbitrary use by the program.'
   346 
   347 #detailsEnabled
   348 'Aspect or binding providing a boolean value holder to enable/disable the menu item.'
   349 
   350 #detailsIgnoreAcceleratorKeys
   351 'Ignore accelerator keys in submenu(s).'
   352 
   353 #detailsIgnoreMnemonicKeys
   354 'Ignore mnemonic keys (access characters) in submenu(s).'
   355 
   356 #detailsStartGroup
   357 'Specify start of a specially aligned group.'
   358 
   359 #detailsVisibility
   360 'Boolean, or aspect or binding for a boolean holder controlling the visibility of the menu item.'
   361 
   362 #fileLoad
   363 'Load a menu spec from a class.'
   364 
   365 #fileNew
   366 'Create a new menu spec.'
   367 
   368 #filePickAMenu
   369 'Select a menu from an open view and read its specification'
   370 
   371 #fileChooseAMenu
   372 'Select a menu from an open view and edit its spec-method'
   373 
   374 #fileSave
   375 'Save the menu spec (and the help spec, if modified).'
   376 
   377 #fileSaveAs
   378 'Open a dialog to save the menu spec (and the help spec, if modified).'
   379 
   380 #fileShowMenuSpec
   381 'Opens a Workspace showing the current menu spec.'
   382 
   383 #forceMenuIndicator
   384 'Always show a menu indicator in horizontal menu (little down-arrow).'
   385 
   386 #generateAspectMethods
   387 'Generates aspect methods for defined aspect selectors of the menu.'
   388 
   389 #hideMenuOnActivated
   390 'If on, the menu hides itself after the item was activated (PopUp/PullDown-Menus only).'
   391 
   392 #horizontalLayout
   393 'If on, the submenu organizes its items horizontal instead of vertical (default).'
   394 
   395 #imageImageAndLabel
   396 'Toggle display of both image and textual label.'
   397 
   398 #imageImageEditor
   399 'Open an Image Editor on the resource method defined by retriever and selector.'
   400 
   401 #imageBrowseImageClass
   402 'Open a Browser on the resource retriever class.'
   403 
   404 #imageImageList
   405 'Currently existing image resources.'
   406 
   407 #imageRetriever
   408 'Class implementing the image resource method. If unspecified, the application instance / class are asked.'
   409 
   410 #imageSelector
   411 'Selector returning an image (sent to above or the application).'
   412 
   413 #keepLinkedMenu
   414 'Keep the linked menu after activation (do not destroy; if off, menu is rebuild for every activation).'
   415 
   416 #sendToOriginator
   417 'Send action-Message to widget (instead of application); only valid for PopUpMenus.'
   418 
   419 #settingsRedefineAspectMethods
   420 'Toggles the permission to overwrite existing aspect methods.'
   421 
   422 #showBusyCursorWhilePerforming
   423 'If on, a busy cursor is shown while the items action is performing.'
   424 
   425 #triggerOnDown
   426 'If on, the items action is performed on mouse-button press (default is: on button-release).'
   427 
   428 #selectorFilter
   429 'In the list below, only matching selectors are shown'
   430 )
   431 
   432     "Modified: / 09-08-2018 / 17:09:02 / Claus Gittinger"
   433 ! !
   434 
   435 !MenuEditor class methodsFor:'image specs'!
   436 
   437 browseActionImage
   438     <resource: #programImage>
   439 
   440     ^ UIPainter browseActionImage
   441 !
   442 
   443 defaultIcon
   444     <resource: #programImage>
   445 
   446     ^ ToolbarIconLibrary startMenuEditorIcon
   447 !
   448 
   449 iconUnknown
   450     "returns an image used for picked items containing an image
   451     "
   452     <resource: #programImage>
   453 
   454     ^ MenuPanelSpec icon
   455 ! !
   456 
   457 !MenuEditor class methodsFor:'interface specs'!
   458 
   459 windowSpec
   460     "This resource specification was automatically generated
   461      by the UIPainter of ST/X."
   462 
   463     "Do not manually edit this!! If it is corrupted,
   464      the UIPainter may not be able to read the specification."
   465 
   466     "
   467      UIPainter new openOnClass:MenuEditor andSelector:#windowSpec
   468      MenuEditor new openInterface:#windowSpec
   469      MenuEditor open
   470     "
   471 
   472     <resource: #canvas>
   473 
   474     ^ 
   475     #(FullSpec
   476        name: windowSpec
   477        uuid: '7d4bc1c6-2067-11b2-b33d-3065ec8abe8a'
   478        window: 
   479       (WindowSpec
   480          label: 'Menu Editor'
   481          name: 'Menu Editor'
   482          uuid: '7d4bc6f8-2067-11b2-b33d-3065ec8abe8a'
   483          min: (Point 550 385)
   484          bounds: (Rectangle 0 0 574 473)
   485          menu: menu
   486          icon: defaultIcon
   487          returnIsOKInDialog: false
   488          escapeIsCancelInDialog: false
   489        )
   490        component: 
   491       (SpecCollection
   492          collection: (
   493           (MenuPanelSpec
   494              name: 'toolbar'
   495              layout: (LayoutFrame 0 0.0 0 0 0 1.0 32 0)
   496              uuid: '7d4bcc98-2067-11b2-b33d-3065ec8abe8a'
   497              tabable: true
   498              menu: toolbar
   499              showSeparatingLines: true
   500            )
   501           (VariableHorizontalPanelSpec
   502              name: 'mainPanel'
   503              layout: (LayoutFrame 0 0.0 34 0.0 0 1.0 -26 1.0)
   504              uuid: '7d4bd2ba-2067-11b2-b33d-3065ec8abe8a'
   505              component: 
   506             (SpecCollection
   507                collection: (
   508                 (HierarchicalListViewSpec
   509                    name: 'ListOfItemsView'
   510                    uuid: '7d4bd7ba-2067-11b2-b33d-3065ec8abe8a'
   511                    model: selectionHolder
   512                    menu: editMenu
   513                    hasHorizontalScrollBar: true
   514                    hasVerticalScrollBar: true
   515                    miniScrollerHorizontal: true
   516                    miniScrollerVertical: true
   517                    listModel: listOfItems
   518                    multipleSelectOk: true
   519                    useIndex: false
   520                    highlightMode: label
   521                    doubleClickSelector: indicatorClickedAt:
   522                    selectConditionSelector: canSelect:
   523                    showLeftIndicators: false
   524                    indicatorSelector: indicatorClickedAt:
   525                    postBuildCallback: postBuildListOfItemsView:
   526                    properties: 
   527                   (PropertyListDictionary
   528                      dropSelector: doDrop:
   529                      dragArgument: nil
   530                      overSelector: dropOver:
   531                      canDropSelector: canDrop:
   532                      dropObjectSelector: dropObjects
   533                      enterSelector: dropEnter:
   534                      dropArgument: nil
   535                      leaveSelector: dropLeave:
   536                    )
   537                  )
   538                 (ViewSpec
   539                    name: 'Box'
   540                    uuid: '7d4be156-2067-11b2-b33d-3065ec8abe8a'
   541                    level: -1
   542                    component: 
   543                   (SpecCollection
   544                      collection: (
   545                       (NoteBookViewSpec
   546                          name: 'NoteBook'
   547                          layout: (LayoutFrame 1 0.0 0 0.0 1 1.0 -39 1.0)
   548                          uuid: '7d4be430-2067-11b2-b33d-3065ec8abe8a'
   549                          enableChannel: hasSingleSelectionChannel
   550                          tabable: true
   551                          model: tabHolder
   552                          menu: listOfTabs
   553                          fitLastRow: false
   554                          translateLabel: true
   555                          canvas: wizardHolder
   556                          keepCanvasAlive: true
   557                          postBuildCallback: postBuildNoteBook:
   558                        )
   559                       (UISubSpecification
   560                          name: 'SubSpecification'
   561                          layout: (LayoutFrame 2 0.0 -35 1.0 -2 1.0 -2 1.0)
   562                          uuid: '7d4beab6-2067-11b2-b33d-3065ec8abe8a'
   563                          majorKey: ToolApplicationModel
   564                          minorKey: windowSpecForCommit
   565                        )
   566                       )
   567                     
   568                    )
   569                  )
   570                 )
   571               
   572              )
   573              handles: (Any 0.29999999999999999 1.0)
   574            )
   575           (UISubSpecification
   576              name: 'infoBarSubSpec'
   577              layout: (LayoutFrame 0 0.0 -24 1 0 1.0 0 1.0)
   578              uuid: '7d4bee30-2067-11b2-b33d-3065ec8abe8a'
   579              majorKey: ToolApplicationModel
   580              minorKey: windowSpecForInfoBar
   581            )
   582           )
   583         
   584        )
   585      )
   586 ! !
   587 
   588 !MenuEditor class methodsFor:'menu specs'!
   589 
   590 addMenu
   591     "This resource specification was automatically generated
   592      by the MenuEditor of ST/X."
   593 
   594     "Do not manually edit this!! If it is corrupted,
   595      the MenuEditor may not be able to read the specification."
   596 
   597     "
   598      MenuEditor new openOnClass:MenuEditor andSelector:#addMenu
   599      (Menu new fromLiteralArrayEncoding:(MenuEditor addMenu)) startUp
   600     "
   601 
   602     <resource: #menu>
   603 
   604     ^
   605      #(Menu
   606 	(
   607 	 (MenuItem
   608 	    activeHelpKey: addMenuSeparator
   609 	    label: 'Separator'
   610 	    itemValue: doCreateSep
   611 	    translateLabel: true
   612 	    labelImage: (ResourceRetriever #'MenuEditor::Item' iconSeparator '')
   613 	  )
   614 	 (MenuItem
   615 	    activeHelpKey: addMenuItem
   616 	    label: 'Item'
   617 	    itemValue: doCreateItem
   618 	    translateLabel: true
   619 	    labelImage: (ResourceRetriever #'MenuEditor::Item' iconItem '')
   620 	  )
   621 	 (MenuItem
   622 	    activeHelpKey: addMenuSliceItem
   623 	    label: 'Menu Slice'
   624 	    itemValue: doCreateMenuSliceItem
   625 	    translateLabel: true
   626 	    labelImage: (ResourceRetriever #'MenuEditor::Item' iconSliceMenu '')
   627 	  )
   628 	 (MenuItem
   629 	    activeHelpKey: addMenuItem
   630 	    label: 'Menu'
   631 	    itemValue: doCreateMenu
   632 	    translateLabel: true
   633 	    labelImage: (ResourceRetriever #'MenuEditor::Item' iconMenu '')
   634 	  )
   635 	 (MenuItem
   636 	    activeHelpKey: addSubMenuLink
   637 	    label: 'Linked Menu'
   638 	    itemValue: doCreateLinkedMenu
   639 	    translateLabel: true
   640 	    labelImage: (ResourceRetriever #'MenuEditor::Item' iconLinkedMenu '')
   641 	  )
   642 	 (MenuItem
   643 	    label: '-'
   644 	  )
   645 	 (MenuItem
   646 	    activeHelpKey: addDelayedMenu
   647 	    enabled: canCreateDelayedMenuChannel
   648 	    label: 'Delayed Menu'
   649 	    itemValue: doCreateDelayedMenu:
   650 	    translateLabel: true
   651 	    labelImage: (ResourceRetriever #'MenuEditor::Item' iconDelayedMenu '')
   652 	    argument: menu
   653 	  )
   654 	 (MenuItem
   655 	    activeHelpKey: addDelayedSubMenuLink
   656 	    enabled: canCreateDelayedMenuChannel
   657 	    label: 'Delayed Linked Menu'
   658 	    itemValue: doCreateDelayedMenu:
   659 	    translateLabel: true
   660 	    labelImage: (ResourceRetriever #'MenuEditor::Item' iconDelayedLinkedMenu '')
   661 	    argument: linkedMenu
   662 	  )
   663 	 (MenuItem
   664 	    label: '-'
   665 	  )
   666 	 (MenuItem
   667 	    label: 'Standard Menus'
   668 	    translateLabel: true
   669 	    submenuChannel: standardMenus
   670 	    keepLinkedMenu: true
   671 	  )
   672 	 )
   673 "/        nil
   674 "/        nil
   675       )
   676 !
   677 
   678 editMenu
   679     "This resource specification was automatically generated
   680      by the MenuEditor of ST/X."
   681 
   682     "Do not manually edit this!! If it is corrupted,
   683      the MenuEditor may not be able to read the specification."
   684 
   685     "
   686      MenuEditor new openOnClass:MenuEditor andSelector:#editMenu
   687      (Menu new fromLiteralArrayEncoding:(MenuEditor editMenu)) startUp
   688     "
   689 
   690     <resource: #menu>
   691 
   692     ^
   693      #(Menu
   694         (
   695          (MenuItem
   696             activeHelpKey: editCut
   697             enabled: hasSelectionChannel
   698             label: 'Cut'
   699             itemValue: doCut
   700             translateLabel: true
   701             shortcutKey: Cut
   702           )
   703          (MenuItem
   704             activeHelpKey: editCopy
   705             enabled: hasSelectionChannel
   706             label: 'Copy'
   707             itemValue: doCopy
   708             translateLabel: true
   709             shortcutKey: Copy
   710           )
   711          (MenuItem
   712             activeHelpKey: editPaste
   713             enabled: canPasteHolder
   714             label: 'Paste'
   715             itemValue: doPaste
   716             translateLabel: true
   717             shortcutKey: Paste
   718           )
   719          (MenuItem
   720             activeHelpKey: editDelete
   721             enabled: hasSelectionChannel
   722             label: 'Delete'
   723             itemValue: doDelete
   724             translateLabel: true
   725             isVisible: false
   726           )
   727          (MenuItem
   728             label: '-'
   729           )
   730          (MenuItem
   731             activeHelpKey: makeLinkedMenu
   732             enabled: hasNonLinkedMenuSelectedHolder
   733             label: 'Make Linked Menu...'
   734             itemValue: doMakeLinkedMenu
   735             translateLabel: true
   736           )
   737          (MenuItem
   738             label: '-'
   739           )
   740          (MenuItem
   741             activeHelpKey: editMoveUp
   742             enabled: enableMovingUpOrDownHolder
   743             label: 'Move Up'
   744             itemValue: doMoveUpOrDown:
   745             translateLabel: true
   746             startGroup: right
   747             shortcutKey: CtrlCursorUp
   748             labelImage: (ResourceRetriever Icon upIcon 'Move Up')
   749             argument: up
   750           )
   751          (MenuItem
   752             activeHelpKey: editMoveDown
   753             enabled: enableMovingUpOrDownHolder
   754             label: 'Move Down'
   755             itemValue: doMoveUpOrDown:
   756             translateLabel: true
   757             shortcutKey: CtrlCursorDown
   758             labelImage: (ResourceRetriever Icon downIcon 'Move Down')
   759             argument: down
   760           )
   761          (MenuItem
   762             activeHelpKey: editMoveIn
   763             enabled: enableMovingInHolder
   764             label: 'Move Into Next'
   765             itemValue: doMoveIn:
   766             translateLabel: true
   767             shortcutKey: CtrlCursorRight
   768             labelImage: (ResourceRetriever Icon downRightIcon 'Move Into Next')
   769             argument: inNext
   770           )
   771          (MenuItem
   772             activeHelpKey: editMoveInAbove
   773             enabled: enableMovingInAboveHolder
   774             label: 'Move Into Previous'
   775             itemValue: doMoveIn:
   776             translateLabel: true
   777             labelImage: (ResourceRetriever Icon upRightIcon 'Move Into Previous' )
   778             argument: inPrev
   779           )
   780          (MenuItem
   781             activeHelpKey: editMoveOut
   782             enabled: enableMovingOutHolder
   783             label: 'Move Out'
   784             itemValue: doMoveOut
   785             translateLabel: true
   786             shortcutKey: CtrlCursorLeft
   787             labelImage: (ResourceRetriever Icon leftDownIcon 'Move Out' )
   788           )
   789          )
   790         nil
   791         nil
   792       )
   793 !
   794 
   795 editMenuForMainMenuWithoutAccelerators
   796     "This resource specification was automatically generated
   797      by the MenuEditor of ST/X."
   798 
   799     "Do not manually edit this!! If it is corrupted,
   800      the MenuEditor may not be able to read the specification."
   801 
   802     "
   803      MenuEditor new openOnClass:MenuEditor andSelector:#editMenuForMainMenuWithoutAccelerators
   804      (Menu new fromLiteralArrayEncoding:(MenuEditor editMenuForMainMenuWithoutAccelerators)) startUp
   805     "
   806 
   807     <resource: #menu>
   808 
   809     ^
   810      #(Menu
   811 	(
   812 	 (MenuItem
   813 	    activeHelpKey: editCut
   814 	    enabled: hasSelectionChannel
   815 	    label: 'Cut'
   816 	    itemValue: doCut
   817 	    translateLabel: true
   818 	  )
   819 	 (MenuItem
   820 	    activeHelpKey: editCopy
   821 	    enabled: hasSelectionChannel
   822 	    label: 'Copy'
   823 	    itemValue: doCopy
   824 	    translateLabel: true
   825 	  )
   826 	 (MenuItem
   827 	    activeHelpKey: editPaste
   828 	    enabled: canPasteHolder
   829 	    label: 'Paste'
   830 	    itemValue: doPaste
   831 	    translateLabel: true
   832 	  )
   833 	 (MenuItem
   834 	    activeHelpKey: editDelete
   835 	    enabled: hasSelectionChannel
   836 	    label: 'Delete'
   837 	    itemValue: doDelete
   838 	    translateLabel: true
   839 	    isVisible: false
   840 	  )
   841 	 (MenuItem
   842 	    label: '-'
   843 	  )
   844 	 (MenuItem
   845 	    activeHelpKey: editMoveUp
   846 	    enabled: enableMovingUpOrDownHolder
   847 	    label: 'Move Up'
   848 	    itemValue: doMoveUpOrDown:
   849 	    translateLabel: true
   850 	    startGroup: right
   851 	    labelImage: (ResourceRetriever Icon upIcon 'Move Up')
   852 	    argument: up
   853 	  )
   854 	 (MenuItem
   855 	    activeHelpKey: editMoveDown
   856 	    enabled: enableMovingUpOrDownHolder
   857 	    label: 'Move Down'
   858 	    itemValue: doMoveUpOrDown:
   859 	    translateLabel: true
   860 	    labelImage: (ResourceRetriever Icon downIcon 'Move Down')
   861 	    argument: down
   862 	  )
   863 	 (MenuItem
   864 	    activeHelpKey: editMoveIn
   865 	    enabled: enableMovingInHolder
   866 	    label: 'Move Into Next'
   867 	    itemValue: doMoveIn:
   868 	    translateLabel: true
   869 	    labelImage: (ResourceRetriever Icon downRightIcon 'Move Into Next')
   870 	    argument: inNext
   871 	  )
   872 	 (MenuItem
   873 	    activeHelpKey: editMoveInAbove
   874 	    enabled: enableMovingInAboveHolder
   875 	    label: 'Move Into Previous'
   876 	    itemValue: doMoveIn:
   877 	    translateLabel: true
   878 	    labelImage: (ResourceRetriever Icon upRightIcon 'Move Into Previous')
   879 	    argument: inPrev
   880 	  )
   881 	 (MenuItem
   882 	    activeHelpKey: editMoveOut
   883 	    enabled: enableMovingOutHolder
   884 	    label: 'Move Out'
   885 	    itemValue: doMoveOut
   886 	    translateLabel: true
   887 	    labelImage: (ResourceRetriever Icon leftDownIcon 'Move Out')
   888 	  )
   889 	 )
   890 	nil
   891 	nil
   892       )
   893 !
   894 
   895 fileMenu
   896     "This resource specification was automatically generated
   897      by the MenuEditor of ST/X."
   898 
   899     "Do not manually edit this!! If it is corrupted,
   900      the MenuEditor may not be able to read the specification."
   901 
   902     "
   903      MenuEditor new openOnClass:MenuEditor andSelector:#fileMenu
   904      (Menu new fromLiteralArrayEncoding:(MenuEditor fileMenu)) startUp
   905     "
   906 
   907     <resource: #menu>
   908 
   909     ^
   910      #(Menu
   911 	(
   912 	 (MenuItem
   913 	    isVisible: isNotEditingSpecOnlyAndNotEmbeddedInBrowser
   914 	    activeHelpKey: fileNew
   915 	    label: 'New'
   916 	    itemValue: doNew
   917 	    translateLabel: true
   918 	  )
   919 	 (MenuItem
   920 	    isVisible: isNotEditingSpecOnlyAndNotEmbeddedInBrowser
   921 	    label: '-'
   922 	  )
   923 	 (MenuItem
   924 	    isVisible: isNotEditingSpecOnlyAndNotEmbeddedInBrowser
   925 	    activeHelpKey: fileLoad
   926 	    label: 'Load...'
   927 	    itemValue: doLoad
   928 	    translateLabel: true
   929 	  )
   930 	 (MenuItem
   931 	    isVisible: isNotEditingSpecOnlyAndNotEmbeddedInBrowser
   932 	    label: '-'
   933 	  )
   934 	 (MenuItem
   935 	    isVisible: isEditingSpecOnly
   936 	    activeHelpKey: fileSaveSpec
   937 	    label: 'Save'
   938 	    itemValue: doSave
   939 	    translateLabel: true
   940 	  )
   941 	 (MenuItem
   942 	    isVisible: isNotEditingSpecOnly
   943 	    activeHelpKey: fileSave
   944 	    label: 'Save'
   945 	    itemValue: doSave
   946 	    translateLabel: true
   947 	  )
   948 	 (MenuItem
   949 	    isVisible: isNotEditingSpecOnlyAndNotEmbeddedInBrowser
   950 	    activeHelpKey: fileSaveAs
   951 	    label: 'Save As...'
   952 	    itemValue: doSaveAs
   953 	    translateLabel: true
   954 	  )
   955 	 (MenuItem
   956 	    label: '-'
   957 	  )
   958 	 (MenuItem
   959 	    activeHelpKey: filePickAMenu
   960 	    label: 'Pick a Menu...'
   961 	    itemValue: doPickAMenu
   962 	    translateLabel: true
   963 	  )
   964 	 (MenuItem
   965 	    activeHelpKey: fileChooseAMenu
   966 	    label: 'Choose a Menu...'
   967 	    itemValue: doChooseAMenu
   968 	    translateLabel: true
   969 	  )
   970 	 (MenuItem
   971 	    label: '-'
   972 	    isVisible: isStandAlone
   973 	  )
   974 	 (MenuItem
   975 	    activeHelpKey: fileBrowseClass
   976 	    enabled: hasValidSpecClass
   977 	    label: 'Browse Class'
   978 	    itemValue: doBrowseClass
   979 	    translateLabel: true
   980 	    isVisible: isStandAlone
   981 	  )
   982 	 (MenuItem
   983 	    activeHelpKey: fileShowMenuSpec
   984 	    label: 'Show Menu Spec'
   985 	    itemValue: doShowMenuSpec
   986 	    translateLabel: true
   987 	    isVisible: isStandAlone
   988 	  )
   989 	 (MenuItem
   990 	    label: '-'
   991 	    isVisible: isStandAlone
   992 	  )
   993 	 (MenuItem
   994 	    activeHelpKey: fileExit
   995 	    label: 'Exit'
   996 	    itemValue: closeRequest
   997 	    translateLabel: true
   998 	    isVisible: isStandAlone
   999 	  )
  1000 	 )
  1001 	nil
  1002 	nil
  1003       )
  1004 !
  1005 
  1006 generateMenu
  1007     "This resource specification was automatically generated
  1008      by the MenuEditor of ST/X."
  1009 
  1010     "Do not manually edit this!! If it is corrupted,
  1011      the MenuEditor may not be able to read the specification."
  1012 
  1013     "
  1014      MenuEditor new openOnClass:MenuEditor andSelector:#generateMenu
  1015      (Menu new fromLiteralArrayEncoding:(MenuEditor generateMenu)) startUp
  1016     "
  1017 
  1018     <resource: #menu>
  1019 
  1020     ^
  1021      #(#Menu
  1022 	#(
  1023 	 #(#MenuItem
  1024 	    #activeHelpKey: #generateAspectMethods
  1025 	    #enabled: #hasValidSpecClass
  1026 	    #label: 'Aspect Methods'
  1027 	    #itemValue: #doGenerateAspectMethods
  1028 	    #translateLabel: true
  1029 	  )
  1030 	 )
  1031 	nil
  1032 	nil
  1033       )
  1034 !
  1035 
  1036 helpMenu
  1037     "This resource specification was automatically generated
  1038      by the MenuEditor of ST/X."
  1039 
  1040     "Do not manually edit this!! If it is corrupted,
  1041      the MenuEditor may not be able to read the specification."
  1042 
  1043     "
  1044      MenuEditor new openOnClass:MenuEditor andSelector:#helpMenu
  1045      (Menu new fromLiteralArrayEncoding:(MenuEditor helpMenu)) startUp
  1046     "
  1047 
  1048     <resource: #menu>
  1049 
  1050     ^
  1051      #(#Menu
  1052 	#(
  1053 	 #(#MenuItem
  1054 	    #activeHelpKey: #helpTutorial
  1055 	    #label: 'Documentation'
  1056 	    #itemValue: #openHTMLDocument:
  1057 	    #translateLabel: true
  1058 	    #argument: 'tools/uipainter/MenuEditor.html'
  1059 	  )
  1060 	 #(#MenuItem
  1061 	    #label: '-'
  1062 	  )
  1063 	 #(#MenuItem
  1064 	    #activeHelpKey: #helpHelpTool
  1065 	    #label: 'Help Tool'
  1066 	    #itemValue: #openHTMLDocument:
  1067 	    #translateLabel: true
  1068 	    #argument: 'tools/uipainter/HelpTool.html'
  1069 	  )
  1070 	 #(#MenuItem
  1071 	    #label: '-'
  1072 	  )
  1073 	 #(#MenuItem
  1074 	    #activeHelpKey: #helpShowHelp
  1075 	    #label: 'Show Help Texts'
  1076 	    #translateLabel: true
  1077 	    #indication: #showingHelp:
  1078 	  )
  1079 	 #(#MenuItem
  1080 	    #label: '-'
  1081 	  )
  1082 	 #(#MenuItem
  1083 	    #activeHelpKey: #aboutThisAppliaction
  1084 	    #label: 'About MenuEditor...'
  1085 	    #itemValue: #openAboutThisApplication
  1086 	    #translateLabel: true
  1087 	  )
  1088 	 )
  1089 	nil
  1090 	nil
  1091       )
  1092 !
  1093 
  1094 menu
  1095     "This resource specification was automatically generated
  1096      by the MenuEditor of ST/X."
  1097 
  1098     "Do not manually edit this!! If it is corrupted,
  1099      the MenuEditor may not be able to read the specification."
  1100 
  1101     "
  1102      MenuEditor new openOnClass:MenuEditor andSelector:#menu
  1103      (Menu new fromLiteralArrayEncoding:(MenuEditor menu)) startUp
  1104     "
  1105 
  1106     <resource: #menu>
  1107 
  1108     ^
  1109      #(Menu
  1110 	(
  1111 	 (MenuItem
  1112 	    label: '&File'
  1113 	    translateLabel: true
  1114 	    submenuChannel: fileMenu
  1115 	    keepLinkedMenu: true
  1116 	    ignoreMnemonicKeys: true
  1117 	    ignoreShortcutKeys: true
  1118 	  )
  1119 	 (MenuItem
  1120 	    label: '&Edit'
  1121 	    translateLabel: true
  1122 	    submenuChannel: editMenuForMainMenuWithoutAccelerators
  1123 	    keepLinkedMenu: true
  1124 	  )
  1125 	 (MenuItem
  1126 	    enabled: hasSingleSelectionChannel
  1127 	    label: 'Item'
  1128 	    translateLabel: true
  1129 	    submenuChannel: addMenu
  1130 	    keepLinkedMenu: true
  1131 	    ignoreMnemonicKeys: true
  1132 	    ignoreShortcutKeys: true
  1133 	  )
  1134 	 (MenuItem
  1135 	    isVisible: isNotEditingSpecOnly
  1136 	    label: 'Generate'
  1137 	    translateLabel: true
  1138 	    submenuChannel: generateMenu
  1139 	    keepLinkedMenu: true
  1140 	    ignoreMnemonicKeys: true
  1141 	    ignoreShortcutKeys: true
  1142 	  )
  1143 	 (MenuItem
  1144 	    label: 'Test'
  1145 	    translateLabel: true
  1146 	    submenuChannel: submenuTest
  1147 	    ignoreMnemonicKeys: true
  1148 	    ignoreShortcutKeys: true
  1149 	  )
  1150 	 (MenuItem
  1151 	    label: 'Settings'
  1152 	    translateLabel: true
  1153 	    submenuChannel: settingsMenu
  1154 	    keepLinkedMenu: true
  1155 	    ignoreMnemonicKeys: true
  1156 	    ignoreShortcutKeys: true
  1157 	  )
  1158 	 (MenuItem
  1159 	    label: 'History'
  1160 	    translateLabel: true
  1161 	    isVisible: isStandAlone
  1162 	    submenuChannel: menuHistory
  1163 	    ignoreMnemonicKeys: true
  1164 	    ignoreShortcutKeys: true
  1165 	  )
  1166 	 (MenuItem
  1167 	    label: 'MENU_Help'
  1168 	    translateLabel: true
  1169 	    startGroup: conditionalRight
  1170 	    submenuChannel: helpMenu
  1171 	    keepLinkedMenu: true
  1172 	    ignoreMnemonicKeys: true
  1173 	    ignoreShortcutKeys: true
  1174 	  )
  1175 	 )
  1176 	nil
  1177 	nil
  1178       )
  1179 !
  1180 
  1181 settingsMenu
  1182     "This resource specification was automatically generated
  1183      by the MenuEditor of ST/X."
  1184 
  1185     "Do not manually edit this!! If it is corrupted,
  1186      the MenuEditor may not be able to read the specification."
  1187 
  1188     "
  1189      MenuEditor new openOnClass:MenuEditor andSelector:#settingsMenu
  1190      (Menu new fromLiteralArrayEncoding:(MenuEditor settingsMenu)) startUp
  1191     "
  1192 
  1193     <resource: #menu>
  1194 
  1195     ^
  1196      #(#Menu
  1197 	#(
  1198 	 #(#MenuItem
  1199 	    isVisible: isNotEditingSpecOnly
  1200 	    #activeHelpKey: #settingsRedefineAspectMethods
  1201 	    #enabled: #hasValidSpecClass
  1202 	    #label: 'Redefine Aspect Methods'
  1203 	    #translateLabel: true
  1204 	    #hideMenuOnActivated: false
  1205 	    #indication: #redefineAspectMethodsChannel
  1206 	  )
  1207 	 #(#MenuItem
  1208 	    #activeHelpKey: #settingsRedefineAspectMethods
  1209 	    #label: 'AutoAccept on Selection-Change'
  1210 	    #translateLabel: true
  1211 	    #hideMenuOnActivated: false
  1212 	    #indication: #autoAcceptOnSelectionChange
  1213 	  )
  1214 	 )
  1215 	nil
  1216 	nil
  1217       )
  1218 !
  1219 
  1220 standardMenus
  1221     "This resource specification was automatically generated
  1222      by the MenuEditor of ST/X."
  1223 
  1224     "Do not manually edit this!! If it is corrupted,
  1225      the MenuEditor may not be able to read the specification."
  1226 
  1227     "
  1228      MenuEditor new openOnClass:MenuEditor andSelector:#standardMenus
  1229      (Menu new fromLiteralArrayEncoding:(MenuEditor standardMenus)) startUp
  1230     "
  1231 
  1232     <resource: #menu>
  1233 
  1234     ^
  1235      #(#Menu
  1236 	#(
  1237 	 #(#MenuItem
  1238 	    #label: 'Standard Menu: File'
  1239 	    #itemValue: #doCreateStandardFileMenu
  1240 	    #translateLabel: true
  1241 	  )
  1242 	 #(#MenuItem
  1243 	    #label: 'Standard Menu: Edit'
  1244 	    #itemValue: #doCreateStandardEditMenu
  1245 	    #translateLabel: true
  1246 	  )
  1247 	 #(#MenuItem
  1248 	    #label: 'Standard Menu: Help'
  1249 	    #itemValue: #doCreateStandardHelpMenu
  1250 	    #translateLabel: true
  1251 	  )
  1252 	 )
  1253 	nil
  1254 	nil
  1255       )
  1256 !
  1257 
  1258 toolbar
  1259     "This resource specification was automatically generated
  1260      by the MenuEditor of ST/X."
  1261 
  1262     "Do not manually edit this!! If it is corrupted,
  1263      the MenuEditor may not be able to read the specification."
  1264 
  1265     "
  1266      MenuEditor new openOnClass:MenuEditor andSelector:#toolbar
  1267      (Menu new fromLiteralArrayEncoding:(MenuEditor toolbar)) startUp
  1268     "
  1269 
  1270     <resource: #menu>
  1271 
  1272     ^
  1273      #(Menu
  1274 	(
  1275 	 (MenuItem
  1276 	    activeHelpKey: fileNew
  1277 	    label: 'New'
  1278 	    itemValue: doNew
  1279 	    translateLabel: true
  1280 	    isButton: true
  1281 	    labelImage: (ResourceRetriever ToolbarIconLibrary newMenuIcon)
  1282 	  )
  1283 	 (MenuItem
  1284 	    label: '-'
  1285 	  )
  1286 	 (MenuItem
  1287 	    activeHelpKey: fileLoad
  1288 	    label: 'Load'
  1289 	    itemValue: doLoad
  1290 	    translateLabel: true
  1291 	    isButton: true
  1292 	    isVisible: isNotEditingSpecOnly
  1293 	    submenuChannel: menuHistory
  1294 	    labelImage: (ResourceRetriever ToolbarIconLibrary loadFromMethodIcon)
  1295 	    keepLinkedMenu: true
  1296 	  )
  1297 	 (MenuItem
  1298 	    activeHelpKey: fileSave
  1299 	    label: 'Save'
  1300 	    itemValue: doSave
  1301 	    translateLabel: true
  1302 	    isButton: true
  1303 	    isVisible: isNotEditingSpecOnly
  1304 	    labelImage: (ResourceRetriever ToolbarIconLibrary saveAsMethodIcon)
  1305 	  )
  1306 	 (MenuItem
  1307 	    activeHelpKey: fileSaveSpec
  1308 	    label: 'Save'
  1309 	    itemValue: doSave
  1310 	    translateLabel: true
  1311 	    isButton: true
  1312 	    isVisible: isEditingSpecOnly
  1313 	    labelImage: (ResourceRetriever XPToolbarIconLibrary saveImageIcon)
  1314 	  )
  1315 	 (MenuItem
  1316 	    label: '-'
  1317 	  )
  1318 	 (MenuItem
  1319 	    activeHelpKey: editCut
  1320 	    enabled: hasSelectionChannel
  1321 	    label: 'Cut'
  1322 	    itemValue: doCut
  1323 	    translateLabel: true
  1324 	    isButton: true
  1325 	    labelImage: (ResourceRetriever ToolbarIconLibrary cutMenuItemIcon)
  1326 	  )
  1327 	 (MenuItem
  1328 	    activeHelpKey: editCopy
  1329 	    enabled: hasSelectionChannel
  1330 	    label: 'Copy'
  1331 	    itemValue: doCopy
  1332 	    translateLabel: true
  1333 	    isButton: true
  1334 	    labelImage: (ResourceRetriever ToolbarIconLibrary copyMenuItemIcon)
  1335 	  )
  1336 	 (MenuItem
  1337 	    activeHelpKey: editPaste
  1338 	    enabled: canPasteHolder
  1339 	    label: 'Paste'
  1340 	    itemValue: doPaste
  1341 	    translateLabel: true
  1342 	    isButton: true
  1343 	    labelImage: (ResourceRetriever ToolbarIconLibrary pasteMenuItemIcon)
  1344 	  )
  1345 	 (MenuItem
  1346 	    label: '-'
  1347 	  )
  1348 	 (MenuItem
  1349 	    activeHelpKey: addMenuItem
  1350 	    enabled: hasSingleSelectionChannel
  1351 	    label: 'Add Item'
  1352 	    itemValue: doCreateItem
  1353 	    translateLabel: true
  1354 	    isButton: true
  1355 	    labelImage: (ResourceRetriever #'MenuEditor::Item' iconItem)
  1356 	  )
  1357 	 (MenuItem
  1358 	    activeHelpKey: addMenuSeparator
  1359 	    enabled: hasSingleSelectionChannel
  1360 	    label: 'Add Separator'
  1361 	    itemValue: doCreateSep
  1362 	    translateLabel: true
  1363 	    isButton: true
  1364 	    labelImage: (ResourceRetriever #'MenuEditor::Item' iconSeparator)
  1365 	  )
  1366 	 (MenuItem
  1367 	    activeHelpKey: addMenuSlice
  1368 	    enabled: hasSingleSelectionChannel
  1369 	    label: 'Menu Slice'
  1370 	    itemValue: doCreateMenuSliceItem
  1371 	    translateLabel: true
  1372 	    isButton: true
  1373 	    labelImage: (ResourceRetriever #'MenuEditor::Item' iconSliceMenu)
  1374 	  )
  1375 	 (MenuItem
  1376 	    activeHelpKey: addSubMenu
  1377 	    enabled: hasSingleSelectionChannel
  1378 	    label: 'Add Menu'
  1379 	    itemValue: doCreateMenu
  1380 	    translateLabel: true
  1381 	    isButton: true
  1382 	    submenuChannel: standardMenus
  1383 	    labelImage: (ResourceRetriever #'MenuEditor::Item' iconMenu)
  1384 	    keepLinkedMenu: true
  1385 	  )
  1386 	 (MenuItem
  1387 	    activeHelpKey: addSubMenuLink
  1388 	    enabled: hasSingleSelectionChannel
  1389 	    label: 'Add Linked Menu'
  1390 	    itemValue: doCreateLinkedMenu
  1391 	    translateLabel: true
  1392 	    isButton: true
  1393 	    labelImage: (ResourceRetriever #'MenuEditor::Item' iconLinkedMenu)
  1394 	  )
  1395 	 (MenuItem
  1396 	    activeHelpKey: addDelayedMenu
  1397 	    enabled: canCreateDelayedMenuChannel
  1398 	    label: 'Add Delayed Menu'
  1399 	    itemValue: doCreateDelayedMenu:
  1400 	    translateLabel: true
  1401 	    isButton: true
  1402 	    labelImage: (ResourceRetriever #'MenuEditor::Item' iconDelayedMenu)
  1403 	    argument: menu
  1404 	  )
  1405 	 (MenuItem
  1406 	    activeHelpKey: addDelayedSubMenuLink
  1407 	    enabled: canCreateDelayedMenuChannel
  1408 	    label: 'Add Delayed Linked Menu'
  1409 	    itemValue: doCreateDelayedMenu:
  1410 	    translateLabel: true
  1411 	    isButton: true
  1412 	    labelImage: (ResourceRetriever #'MenuEditor::Item' iconDelayedLinkedMenu)
  1413 	    argument: linkedMenu
  1414 	  )
  1415 	 (MenuItem
  1416 	    label: ''
  1417 	  )
  1418 	 (MenuItem
  1419 	    activeHelpKey: editMoveUp
  1420 	    enabled: enableMovingUpOrDownHolder
  1421 	    label: 'Move Up'
  1422 	    itemValue: doMoveUp
  1423 	    translateLabel: true
  1424 	    isButton: true
  1425 	    startGroup: right
  1426 	    labelImage: (ResourceRetriever Icon upIcon)
  1427 	  )
  1428 	 (MenuItem
  1429 	    activeHelpKey: editMoveDown
  1430 	    enabled: enableMovingUpOrDownHolder
  1431 	    label: 'Move Down'
  1432 	    itemValue: doMoveDown
  1433 	    translateLabel: true
  1434 	    isButton: true
  1435 	    labelImage: (ResourceRetriever Icon downIcon)
  1436 	  )
  1437 	 (MenuItem
  1438 	    activeHelpKey: editMoveIn
  1439 	    enabled: enableMovingInHolder
  1440 	    label: 'Move Into Next'
  1441 	    itemValue: doMoveInNext
  1442 	    translateLabel: true
  1443 	    isButton: true
  1444 	    labelImage: (ResourceRetriever Icon downRightIcon)
  1445 	  )
  1446 	 (MenuItem
  1447 	    activeHelpKey: editMoveInAbove
  1448 	    enabled: enableMovingInAboveHolder
  1449 	    label: 'Move Into Previous'
  1450 	    itemValue: doMoveInPrevious
  1451 	    translateLabel: true
  1452 	    isButton: true
  1453 	    labelImage: (ResourceRetriever Icon upRightIcon)
  1454 	  )
  1455 	 (MenuItem
  1456 	    activeHelpKey: editMoveOut
  1457 	    enabled: enableMovingOutHolder
  1458 	    label: 'Move Out'
  1459 	    itemValue: doMoveOut
  1460 	    translateLabel: true
  1461 	    isButton: true
  1462 	    labelImage: (ResourceRetriever Icon leftDownIcon)
  1463 	  )
  1464 	 )
  1465 	nil
  1466 	nil
  1467       )
  1468 ! !
  1469 
  1470 !MenuEditor class methodsFor:'menu specs-standard'!
  1471 
  1472 standardEditMenu
  1473     "This resource specification was automatically generated
  1474      by the MenuEditor of ST/X."
  1475 
  1476     "Do not manually edit this!! If it is corrupted,
  1477      the MenuEditor may not be able to read the specification."
  1478 
  1479     "
  1480      MenuEditor new openOnClass:MenuEditor andSelector:#standardEditMenu
  1481      (Menu new fromLiteralArrayEncoding:(MenuEditor standardEditMenu)) startUp
  1482     "
  1483 
  1484     <resource: #menu>
  1485 
  1486     ^
  1487      #(#Menu
  1488 	#(
  1489 	 #(#MenuItem
  1490 	    #label: 'Cut'
  1491 	    #translateLabel: true
  1492 	    #value: #cutSelection
  1493 	  )
  1494 	 #(#MenuItem
  1495 	    #label: 'Copy'
  1496 	    #translateLabel: true
  1497 	    #value: #copySelection
  1498 	  )
  1499 	 #(#MenuItem
  1500 	    #label: 'Paste'
  1501 	    #translateLabel: true
  1502 	    #value: #paste
  1503 	  )
  1504 	 )
  1505 	nil
  1506 	nil
  1507       )
  1508 !
  1509 
  1510 standardFileMenu
  1511     "This resource specification was automatically generated
  1512      by the MenuEditor of ST/X."
  1513 
  1514     "Do not manually edit this!! If it is corrupted,
  1515      the MenuEditor may not be able to read the specification."
  1516 
  1517     "
  1518      MenuEditor new openOnClass:MenuEditor andSelector:#standardFileMenu
  1519      (Menu new fromLiteralArrayEncoding:(MenuEditor standardFileMenu)) startUp
  1520     "
  1521 
  1522     <resource: #menu>
  1523 
  1524     ^
  1525      #(#Menu
  1526 	#(
  1527 	 #(#MenuItem
  1528 	    #label: 'New'
  1529 	    #translateLabel: true
  1530 	    #value: #menuNew
  1531 	  )
  1532 	 #(#MenuItem
  1533 	    #label: '-'
  1534 	  )
  1535 	 #(#MenuItem
  1536 	    #label: 'Open...'
  1537 	    #translateLabel: true
  1538 	    #value: #menuOpen
  1539 	  )
  1540 	 #(#MenuItem
  1541 	    #label: '-'
  1542 	  )
  1543 	 #(#MenuItem
  1544 	    #label: 'Save'
  1545 	    #translateLabel: true
  1546 	    #value: #menuSave
  1547 	  )
  1548 	 #(#MenuItem
  1549 	    #label: 'Save As...'
  1550 	    #translateLabel: true
  1551 	    #value: #menuSaveAs
  1552 	  )
  1553 	 #(#MenuItem
  1554 	    #label: '-'
  1555 	  )
  1556 	 #(#MenuItem
  1557 	    #label: 'Exit'
  1558 	    #translateLabel: true
  1559 	    #value: #closeRequest
  1560 	  )
  1561 	 )
  1562 	nil
  1563 	nil
  1564       )
  1565 !
  1566 
  1567 standardHelpMenu
  1568     "This resource specification was automatically generated
  1569      by the MenuEditor of ST/X."
  1570 
  1571     "Do not manually edit this!! If it is corrupted,
  1572      the MenuEditor may not be able to read the specification."
  1573 
  1574     "
  1575      MenuEditor new openOnClass:MenuEditor andSelector:#standardHelpMenu
  1576      (Menu new fromLiteralArrayEncoding:(MenuEditor standardHelpMenu)) startUp
  1577     "
  1578 
  1579     <resource: #menu>
  1580 
  1581     ^
  1582      #(#Menu
  1583 	#(
  1584 	 #(#MenuItem
  1585 	    #label: 'Documentation'
  1586 	    #translateLabel: true
  1587 	    #value: #openDocumentation
  1588 	  )
  1589 	 #(#MenuItem
  1590 	    #label: '-'
  1591 	  )
  1592 	 #(#MenuItem
  1593 	    #label: 'About this Application...'
  1594 	    #translateLabel: true
  1595 	    #value: #openAboutThisApplication
  1596 	  )
  1597 	 )
  1598 	nil
  1599 	nil
  1600       )
  1601 ! !
  1602 
  1603 !MenuEditor methodsFor:'accessing'!
  1604 
  1605 helpSpec
  1606     |spec t g|
  1607 
  1608     spec := super helpSpec.
  1609     t := spec at:#detailsStartGroup.
  1610     g := (aspects at:#startGroup ifAbsent:nil) value.
  1611     g == #conditionalRight ifTrue:[
  1612         t := t , ' #conditionalRight means: "right on non-win32 systems"'
  1613     ].
  1614     g == #right ifTrue:[
  1615         t := t , ' #right means: "right align from here"'
  1616     ].
  1617     g == #left ifTrue:[
  1618         t := t , ' #left means: "left align group"'
  1619     ].
  1620     spec at:#detailsStartGroup put:t.
  1621 
  1622     ^ spec.
  1623 "/ #detailsStartGroup
  1624 "/ 'Specify start of a right-aligned item group.'
  1625 
  1626     "Created: / 16-10-2006 / 13:19:14 / cg"
  1627 !
  1628 
  1629 helpTool
  1630     "get the help tool application
  1631     "
  1632     ^ wizards at:#help ifAbsentPut:[ |tool|
  1633 	tool := UIHelpTool new.
  1634 	tool masterApplication:self.
  1635 	tool modifiedHolder: self enablingCommitButtonsHolder.
  1636 	tool builder window:(ApplicationSubView new client:tool spec:#innerSpec).
  1637 	tool masterApplication:self.
  1638 	tool
  1639     ]
  1640 !
  1641 
  1642 imageTool
  1643     "get the image tool application"
  1644 
  1645     ^ wizards
  1646 	at:#image
  1647 	ifAbsentPut:[
  1648 	    |tool|
  1649 
  1650 	    tool := ImageResourceEditor new createBuilder.
  1651 	    tool masterApplication:self.
  1652 	    tool modifiedChannel: self enablingCommitButtonsHolder.
  1653 	    tool builder window:(ApplicationSubView new client:tool).
  1654 	    tool
  1655 	]
  1656 
  1657     "Modified: / 03-08-2011 / 10:03:08 / cg"
  1658 !
  1659 
  1660 savedSpec
  1661     ^ savedSpec
  1662 !
  1663 
  1664 useHelpTool:aHelpTool
  1665     "take the help dictionaries from aHelpTool into my helpTool
  1666     "
  1667     self helpTool loadFromHelpTool:aHelpTool.
  1668 ! !
  1669 
  1670 !MenuEditor methodsFor:'actions'!
  1671 
  1672 accept
  1673     "accept modifications
  1674     "
  1675     self accept:true.
  1676 !
  1677 
  1678 accept:ok
  1679     "if ok is true, the modifications are accepted.
  1680      then reload from item
  1681     "
  1682     |selectedItem rscRetrHolder helpKeyHolder helpTool imageTool acceptChannel|
  1683 
  1684     selectedItem := self selectedItem.
  1685 
  1686     selectedItem notNil ifTrue:[
  1687 	self withoutNotifyDo:[
  1688 	    rscRetrHolder := aspects at:#resourceRetriever.
  1689 	    helpKeyHolder := aspects at:#activeHelpKey.
  1690 	    imageTool     := self imageTool.
  1691 	    helpTool      := self helpTool.
  1692 	    acceptChannel := self acceptChannel.
  1693 
  1694 	    acceptChannel triggerValue:true.
  1695 	    acceptChannel setValue:false.
  1696 
  1697 	    ok ifTrue:[
  1698 		helpTool accept.
  1699 		rscRetrHolder value:(imageTool resourceRetriever).
  1700 		helpKeyHolder value:(helpTool helpKey).
  1701 		selectedItem  fromAspects:aspects.
  1702 		self setModified.
  1703 
  1704 		selectedItem isRootItem ifTrue:[
  1705 		    "/ update specSelector
  1706 		    specSelector := selectedItem rawLabel.
  1707 		].
  1708 	    ].
  1709 	    selectedItem toAspects:aspects.
  1710 	    helpTool     helpKey:(helpKeyHolder value).
  1711 	    imageTool    resourceRetriever:(rscRetrHolder value).
  1712 	]
  1713     ].
  1714     self updateChannels.
  1715 "/    self clearModified.
  1716     self clearModifiedFlag.
  1717 
  1718     self enablingCommitButtonsHolder value:false.
  1719 
  1720     "Modified: / 29-11-2011 / 11:28:02 / cg"
  1721 !
  1722 
  1723 cancel
  1724     "reload aspects from current selected item; reset modification flag"
  1725 
  1726     self accept:false.
  1727 
  1728     "Modified: / 29-08-2006 / 10:20:46 / cg"
  1729 !
  1730 
  1731 indicatorClickedAt:atLine
  1732     "indicator clicked at line number; toggle expand of item at line
  1733     "
  1734     |item|
  1735 
  1736     item := listOfItems at:atLine ifAbsent:nil.
  1737     item notNil ifTrue:[
  1738 	item toggleExpand.
  1739 	self hasSelection ifFalse:[
  1740 	    self selectedItem:item
  1741 	]
  1742     ].
  1743 
  1744     "Modified: / 29-11-2011 / 11:28:20 / cg"
  1745 ! !
  1746 
  1747 !MenuEditor methodsFor:'aspects'!
  1748 
  1749 canCreateDelayedMenuChannel
  1750     "boolean holder, true if the current selected item accepts a delayed menu
  1751     "
  1752     ^ builder booleanValueAspectFor:#canCreateDelayedMenuChannel
  1753 !
  1754 
  1755 hasItemValue
  1756     "boolean holder, true if any item is selected
  1757     "
  1758     ^ BlockValue
  1759 	with:[:holder | holder size > 0]
  1760 	argument:(self aspectFor:#itemValue)
  1761 
  1762     "Modified: / 08-03-2007 / 22:59:42 / cg"
  1763 !
  1764 
  1765 hasNonLinkedMenuSelectedHolder
  1766     "boolean holder, true if a single non linked menu item is selected"
  1767 
  1768     ^ BlockValue
  1769         with:[:selection | 
  1770                 (selection size == 1) 
  1771                  and:[selection first isKindOfNonLinkedMenu
  1772                  and:[selection first isRootItem not]]
  1773              ]
  1774         argument:(self selectionHolder)
  1775 
  1776     "Modified: / 17-05-2019 / 16:18:19 / Stefan Vogel"
  1777 !
  1778 
  1779 hasSelectionChannel
  1780     "boolean holder, true if any item is selected
  1781     "
  1782     ^ builder booleanValueAspectFor:#hasSelectionChannel
  1783 !
  1784 
  1785 hasSingleSelectionChannel
  1786     "boolean holder, true if one item is selected
  1787     "
  1788     ^ builder booleanValueAspectFor:#hasSingleSelectionChannel
  1789 !
  1790 
  1791 listOfItems
  1792     "returns the hierarchical list of menuItems
  1793     "
  1794     ^ listOfItems
  1795 !
  1796 
  1797 listOfTabs
  1798     "returns the list of current shown tab-labels retrieved
  1799      from the current selected item.
  1800     "
  1801     ^ listOfTabs
  1802 !
  1803 
  1804 redefineAspectMethodsChannel
  1805     "boolean holder, true if aspects should be generated in only implemented
  1806      in superClass by calling #super ...
  1807     "
  1808     ^ builder booleanValueAspectFor:#redefineAspectMethodsChannel
  1809 !
  1810 
  1811 selectionHolder
  1812     "value holder, which keeps the current selected items
  1813     "
  1814     ^ selectionHolder
  1815 !
  1816 
  1817 tabHolder
  1818     "value holder, which keeps the current selected tab label or nil
  1819     "
  1820     ^ tabHolder
  1821 !
  1822 
  1823 wizardHolder
  1824     "holder, which keeps the current wizard window
  1825     "
  1826     |holder|
  1827 
  1828     holder := builder bindingAt:#wizardHolder.
  1829 
  1830     holder isNil ifTrue:[
  1831 	holder := nil asValue.
  1832 	builder aspectAt:#wizardHolder put:holder.
  1833     ].
  1834     ^ holder
  1835 ! !
  1836 
  1837 !MenuEditor methodsFor:'building'!
  1838 
  1839 buildFromMenu:aMenu selector:aSelector
  1840     "rebuild menu from a Menu
  1841     "
  1842     |root menu|
  1843 
  1844     aMenu isCollection ifTrue:[menu := aMenu decodeAsLiteralArray]
  1845 		      ifFalse:[menu := aMenu].
  1846 
  1847     self enablingCommitButtonsHolder value:false.
  1848     root := listOfItems root.
  1849 
  1850     self withoutNotifyDo:[
  1851 	selectionHolder setValue:#().
  1852 	root menu:aMenu labeled:(aSelector ? specSelector).
  1853     ].
  1854     self selectedItem:root.
  1855     self updateHistory.
  1856 !
  1857 
  1858 buildFromResourceSpec:aResourceSpec
  1859     "rebuild the menu from a resource spec"
  1860 
  1861     self buildFromMenu:aResourceSpec selector:nil
  1862 !
  1863 
  1864 loadFromClass:aClass andSelector:aSelector
  1865     "rebuild menu from a class and selector"
  1866 
  1867     |cls menu|
  1868 
  1869     self assert:(aClass isNil or:[aClass isClass]).
  1870 
  1871     menu := nil.
  1872 
  1873     self isStandAlone ifTrue:[ self helpTool loadFromClass:aClass ].
  1874 
  1875     specClass := aClass.
  1876     specSelector := aSelector.
  1877 
  1878     aSelector notNil ifTrue:[
  1879 	aClass notNil ifTrue:[
  1880 	    cls := aClass isBehavior ifTrue:[ aClass ] ifFalse:[ self resolveName:aClass].
  1881 
  1882 	    (cls respondsTo:aSelector) ifTrue:[
  1883 		menu := cls perform: aSelector.
  1884 	    ].
  1885 	].
  1886     ].
  1887     self loadFromMenu:menu selector:aSelector.
  1888 !
  1889 
  1890 loadFromMenu:menuArg selector:selectorOrNil
  1891     "rebuild menu"
  1892 
  1893     |menu|
  1894 
  1895     menu := menuArg.
  1896     menu notNil ifTrue:[
  1897 	(menu isCollection) ifTrue:[
  1898 	    menu := Menu decodeFromLiteralArray:menu
  1899 	].
  1900     ].
  1901     self buildFromMenu:menu selector:selectorOrNil.
  1902     self clearModified.
  1903 
  1904     "Modified: / 27-03-2007 / 11:16:47 / cg"
  1905 ! !
  1906 
  1907 !MenuEditor methodsFor:'change & update'!
  1908 
  1909 selectedSuperItems
  1910     "returns collection of superItems derived from selection
  1911     "
  1912     |selection size root|
  1913 
  1914     selectedSuperItems notNil ifTrue:[ ^ selectedSuperItems ].
  1915 
  1916     selection := selectionHolder value.
  1917     size      := selection size.
  1918 
  1919     size <= 1 ifTrue:[
  1920 	selectedSuperItems := selection ? #().
  1921       ^ selectedSuperItems
  1922     ].
  1923 
  1924     root := listOfItems root.
  1925 
  1926     (selection includesIdentical:root) ifTrue:[
  1927 	selectedSuperItems := Array with:root.
  1928       ^ selectedSuperItems
  1929     ].
  1930     selectedSuperItems := OrderedCollection new.
  1931 
  1932     selection do:[:anItem|
  1933 	anItem parentsDetect:[:el| selection includesIdentical:el ]
  1934 		      ifNone:[ selectedSuperItems add:anItem ].
  1935     ].
  1936     ^ selectedSuperItems
  1937 
  1938     "Modified: / 29-11-2011 / 11:28:23 / cg"
  1939 !
  1940 
  1941 selectionChanged
  1942     "called if the selection has changed
  1943     "
  1944     |newTabList selection|
  1945 
  1946     selection := selectionHolder value.
  1947 
  1948     selection size == 1 ifTrue:[
  1949 	selectedSuperItems := selection.
  1950 
  1951 	newTabList := selection first slices collect:[:el| el first ].
  1952 	newTabList = listOfTabs ifFalse:[
  1953 	    listOfTabs contents:newTabList.
  1954 	].
  1955     ] ifFalse:[
  1956 	"must compute selected super items on request
  1957 	"
  1958 	selectedSuperItems := nil.
  1959     ].
  1960     self cancel.
  1961     self tabChanged.
  1962     self updateChannels.
  1963 !
  1964 
  1965 tabChanged
  1966     "called if the tab changed"
  1967 
  1968     |tab selector item canvas wizardHolder|
  1969 
  1970     wizardHolder := self wizardHolder.
  1971     item := self selectedItem.
  1972     item isNil ifTrue:[
  1973 	wizardHolder value:nil.
  1974 	^ self
  1975     ].
  1976 
  1977     tab := tabHolder value.
  1978 
  1979     tab notNil ifTrue:[
  1980 	tab := item slices detect:[:el| el first = tab ] ifNone:nil.
  1981     ].
  1982     tab isNil ifTrue:[
  1983 	tabHolder value:( listOfTabs at:1 ifAbsent:nil ).
  1984 	^ self.
  1985     ].
  1986     selector := tab last.
  1987 
  1988     selector == #help  ifTrue:[
  1989 	wizardHolder value:(self helpTool  window).
  1990 	^ self
  1991     ].
  1992     selector == #image ifTrue:[
  1993 	wizardHolder value:(self imageTool window).
  1994 	^ self
  1995     ].
  1996 
  1997     canvas := wizards
  1998 		at:(item class name, selector) asSymbol
  1999 		ifAbsentPut:[
  2000 		    SimpleView new
  2001 			client:self
  2002 			spec:(item class perform:selector)
  2003 			builder:(self builder)
  2004 		].
  2005 
  2006     wizardHolder value:canvas.
  2007 !
  2008 
  2009 update:something with:aParameter from:changedObject
  2010     |lbl|
  2011 
  2012     notifyDisabledCounter ~~ 0 ifTrue:[ ^ self ].
  2013 
  2014     changedObject == selectionHolder ifTrue:[ ^ self selectionChanged ].
  2015     changedObject == tabHolder       ifTrue:[ ^ self tabChanged ].
  2016 
  2017     changedObject == self autoAcceptOnSelectionChange ifTrue:[
  2018 	lbl := changedObject value ifTrue:['Apply'] ifFalse:['OK'].
  2019 	(builder componentAt:'okButton') label:(resources string:lbl).
  2020 	^ self
  2021     ].
  2022 
  2023     super update:something with:aParameter from:changedObject
  2024 !
  2025 
  2026 updateChannels
  2027     "update all channels"
  2028 
  2029     |selection sizeOfSel selectedItem hasSelection|
  2030 
  2031     super updateChannels.
  2032 
  2033     selection := selectionHolder value.
  2034     sizeOfSel := selection size.
  2035 
  2036     hasSelection := sizeOfSel ~~ 0.
  2037     sizeOfSel == 1 ifTrue:[selectedItem := selection at:1]
  2038 		  ifFalse:[selectedItem := nil].
  2039 
  2040     self hasSelectionChannel       value:hasSelection.
  2041     self hasSingleSelectionChannel value:(selectedItem notNil).
  2042 
  2043     selectedItem isNil ifTrue:[
  2044 "/        self enableMovingUpOrDownHolder  value:false.
  2045 	self enableMovingInHolder        value:false.
  2046 	self enableMovingOutHolder       value:false.
  2047 	self enableMovingInAboveHolder   value:false.
  2048 	self canCreateDelayedMenuChannel value:false.
  2049     ] ifFalse:[
  2050 "/        self enableMovingUpOrDownHolder  value:(selectedItem canMoveUpOrDown).
  2051 	self enableMovingInHolder        value:(selectedItem canMoveInNext).
  2052 	self enableMovingOutHolder       value:(selectedItem canMoveOut).
  2053 	self enableMovingInAboveHolder   value:(selectedItem canMoveInAbove).
  2054 	self canCreateDelayedMenuChannel value:(selectedItem canAddDelayedMenu).
  2055     ].
  2056     self enableMovingUpOrDownHolder value:(selection conform:[:i | i canMoveUpOrDown]).
  2057 
  2058     "Modified (comment): / 18-01-2012 / 11:24:07 / cg"
  2059 ! !
  2060 
  2061 !MenuEditor methodsFor:'drag & drop'!
  2062 
  2063 canDrop:aDropContext
  2064     "return true, if the DropContext can be dropped into the list of items.
  2065      The dropable objects are already validated by: #dropEnter:"
  2066 
  2067     ^ (dropOverLine notNil and:[dropOverLine ~~ 0])
  2068 
  2069     "Modified: / 13-10-2006 / 16:03:47 / cg"
  2070 !
  2071 
  2072 changeDropLineTo:aLineOrNil in:aContext
  2073     "the over dropLine changed; redraw drop indication stuff
  2074     "
  2075     |x0 x1 y0|
  2076 
  2077     aLineOrNil == dropOverLine ifTrue:[
  2078 	^ self. "/ nothing changed
  2079     ].
  2080     x0 := listOfItemsView margin + 2.
  2081     x1 := listOfItemsView width - x0.
  2082 
  2083     "/ inform the DragAndDrop handler that the draw contents will change
  2084     aContext contentsWillChange.
  2085 
  2086     (dropOverLine notNil and:[dropOverLine ~~ 0]) ifTrue:[
  2087 	"/ restore old draw
  2088 	y0 := listOfItemsView yVisibleOfLine:(dropOverLine + 1).
  2089 	y0 := y0 - 3.
  2090 
  2091 	listOfItemsView invalidate:(Rectangle left:x0 top:y0 width:(x1-x0+1) height:2)
  2092 			 repairNow:true.
  2093     ].
  2094 
  2095     dropOverLine := aLineOrNil.
  2096 
  2097     (dropOverLine notNil and:[dropOverLine ~~ 0]) ifTrue:[
  2098 	"/ highlight new drop target
  2099 	y0 := listOfItemsView yVisibleOfLine:(dropOverLine + 1).
  2100 	y0 := y0 - 3.
  2101 
  2102 	listOfItemsView paint:(Color white).
  2103 	listOfItemsView displayLineFromX:x0 y:y0 toX:x1 y:y0.
  2104 	y0 := y0 + 1.
  2105 	listOfItemsView paint:(Color black).
  2106 	listOfItemsView displayLineFromX:x0 y:y0 toX:x1 y:y0.
  2107     ].
  2108 !
  2109 
  2110 doDrop:aDropContext
  2111     "drop the dropContext into the hierachical list of items
  2112     "
  2113     |done item|
  2114 
  2115     dropOverLine isNil ifTrue:[^ false ].      "/ context not valid to me ...
  2116 
  2117     item := listOfItems at:dropOverLine ifAbsent:nil.
  2118     self dropLeave:aDropContext.
  2119     item isNil ifTrue:[^ false].
  2120 
  2121     selectionHolder setValue:(Array with:item).
  2122 
  2123     done := false.
  2124 
  2125     self addAndSelectValueOf:[
  2126 	done := true.
  2127 	aDropContext dropObjects collect:[:el| Item menuItem:(el theObject) ]
  2128     ].
  2129     ^ done
  2130 
  2131     "Modified: / 13-10-2006 / 16:03:54 / cg"
  2132 !
  2133 
  2134 dropEnter:aDropContext
  2135     "a drop operation enters my widget; validate dropable objects.
  2136      If the objects are not dropable, dropOverLine is set to nil,
  2137      otherwise to 0 (can drop the contents but not).
  2138     "
  2139     |objects|
  2140 
  2141     dropOverLine := nil.
  2142 
  2143     self enablingCommitButtonsHolder value ifTrue:[
  2144 	"/ current editing spec is modified (couldn't accept operation)
  2145 	^ self
  2146     ].
  2147     objects := aDropContext dropObjects.
  2148     objects isEmpty ifTrue:[ ^ self ].  "/ nothing to drop ???
  2149 
  2150     "/ test whether all objects are dropable (kind of MenuItem)
  2151     (objects conform:[:el | (el theObject askFor:#isMenuItem)]) ifTrue:[
  2152 	"/ ok, the contents is dropable
  2153 	dropOverLine := 0.
  2154     ]
  2155 
  2156     "Modified: / 13-10-2006 / 16:04:14 / cg"
  2157 !
  2158 
  2159 dropLeave:aDropContext
  2160     "restore drop indications drawn..."
  2161 
  2162     self changeDropLineTo:nil in:aDropContext.
  2163 
  2164     "Modified: / 13-10-2006 / 16:03:59 / cg"
  2165 !
  2166 
  2167 dropObjects
  2168     "returns list of DropObjects
  2169     "
  2170     |obj items|
  2171 
  2172     items := self selectedSuperItems.
  2173     items isEmpty ifTrue:[ ^ nil ].
  2174 
  2175   ^ items collect:[:el|
  2176 	obj := DropObject new:(el menuItem).
  2177 	obj displayObject:(el rawLabel).
  2178 	obj
  2179     ].
  2180 !
  2181 
  2182 dropOver:aDropContext
  2183     "called during drag & drop while moving over the widget."
  2184 
  2185     |lnNr item|
  2186 
  2187     dropOverLine isNil ifTrue:[^ self ].       "/ context not valid to me ...
  2188 
  2189     lnNr := listOfItemsView yVisibleToLineNr:(aDropContext targetPointInDeviceCoordinates y).
  2190     item := nil.
  2191 
  2192     lnNr notNil ifTrue:[
  2193         item := listOfItems at:lnNr ifAbsent:nil.
  2194         item notNil ifTrue:[
  2195             (item isAction and:[item hasDelayedMenu]) ifTrue:[
  2196                 item := nil
  2197             ]
  2198         ]
  2199     ].
  2200     item isNil ifTrue:[ lnNr := 0 ].   "/ not dropable for item
  2201 
  2202     "/ redraw drop indication
  2203     self changeDropLineTo:lnNr in:aDropContext.
  2204 
  2205     "Modified: / 29-11-2011 / 11:28:17 / cg"
  2206     "Modified: / 15-06-2018 / 02:27:44 / Claus Gittinger"
  2207 ! !
  2208 
  2209 !MenuEditor methodsFor:'event processing'!
  2210 
  2211 processEvent:anEvent
  2212     "filter keyboard edit-events typed into the listOfItemsView.
  2213      Return true, if I have eaten the event"
  2214 
  2215     <resource: #keyboard (#Delete #BackSpace #Cut #Copy #Paste #CtrlCursorUp #CtrlCursorDown
  2216                           #CtrlCursorLeft #CtrlCursorRight #Accept)>
  2217 
  2218     |evView rawKey key|
  2219 
  2220     anEvent isKeyPressEvent ifFalse:[^ false].
  2221 
  2222     key    := anEvent key.
  2223 
  2224     evView := anEvent targetView.
  2225     evView isNil ifTrue:[^ false ].
  2226 
  2227     "/ only handle keyboard events for the left item list
  2228     "/ (otherwise, copy-paste would not work in the editFields on the right)
  2229     (evView isSameOrComponentOf:listOfItemsView) ifFalse:[
  2230         key == #Accept ifTrue:[
  2231             self accept.
  2232         ].
  2233         ^ false
  2234     ].
  2235 
  2236     rawKey := anEvent rawKey.
  2237 
  2238     (    key == #Delete
  2239      or:[key == #BackSpace
  2240      or:[key == #Cut]]
  2241     ) ifTrue:[
  2242         self doCut.
  2243         ^ true.
  2244     ].
  2245 
  2246     key == #Copy  ifTrue:[ self doCopy.  ^ true ].
  2247     key == #Paste ifTrue:[ self doPaste. ^ true ].
  2248 
  2249     (rawKey == #CtrlCursorUp) ifTrue:[
  2250         self doMoveUp.
  2251         ^ true.
  2252     ].
  2253     (rawKey == #CtrlCursorDown) ifTrue:[
  2254         self doMoveDown.
  2255         ^ true.
  2256     ].
  2257     (rawKey == #CtrlCursorLeft) ifTrue:[
  2258         self doMoveOut.
  2259         ^ true.
  2260     ].
  2261     (rawKey == #CtrlCursorRight) ifTrue:[
  2262         self doMoveInNext.
  2263         ^ true.
  2264     ].
  2265 
  2266     ^ false.
  2267 
  2268     "Modified: / 12-02-2019 / 10:56:08 / Claus Gittinger"
  2269 ! !
  2270 
  2271 !MenuEditor methodsFor:'initialization & release'!
  2272 
  2273 closeRequest
  2274     "asks for permission before closing"
  2275 
  2276     self askForModification ifFalse:[^self].
  2277 
  2278 "/    self enablingCommitButtonsHolder value ifTrue:[
  2279 "/        self setModified.
  2280 "/        self askForListModification.
  2281 "/        modified ifTrue:[^ self].
  2282 "/        self clearModified.
  2283 "/    ].
  2284     super closeRequest
  2285 
  2286     "Modified: / 05-09-2006 / 18:44:15 / cg"
  2287 !
  2288 
  2289 commonPostBuild
  2290     self autoAcceptOnSelectionChange addDependent:self.
  2291     self autoAcceptOnSelectionChange value ifTrue:[
  2292         (builder componentAt:'okButton') label:(resources string:'Apply')
  2293     ].
  2294 
  2295     "/ using masters infoHolder ?
  2296     self useAlienInfoLabel ifTrue:[
  2297         (builder componentAt:#mainPanel) layout bottomOffset:0.
  2298         (builder componentAt:#infoBarSubSpec) beInvisible
  2299     ]
  2300 
  2301     "Modified: / 20-02-2018 / 13:05:21 / stefan"
  2302 !
  2303 
  2304 commonPostOpen
  2305     "reset keyboardProcessor for menuBar"
  2306 
  2307     super commonPostOpen.
  2308     builder keyboardProcessor menuBar:nil.
  2309     self windowGroup addPreEventHook:self.
  2310 !
  2311 
  2312 initialize
  2313     "setup aspects, ...
  2314     "
  2315     super initialize.
  2316     notifyDisabledCounter := 0.
  2317 
  2318     Item withAllSubclasses do:[:aClass|
  2319 	aClass addBindingsTo:aspects for:self.
  2320     ].
  2321 
  2322     selectionHolder    := #() asValue.
  2323     selectionHolder addDependent:self.
  2324 
  2325     listOfItems := HierarchicalList new.
  2326     listOfItems application:self.
  2327     listOfItems root:(RootItem new).
  2328 
  2329     tabHolder := nil asValue.
  2330     tabHolder addDependent:self.
  2331 
  2332     listOfTabs := List new.
  2333     wizards    := IdentityDictionary new.
  2334 !
  2335 
  2336 loadFromResourceSpec:aResourceSpec
  2337     self loadFromMenu:aResourceSpec selector:nil
  2338 !
  2339 
  2340 openModalOnMenu:aMenuOrNil
  2341     "build a tree from aMenu and open it modal"
  2342 
  2343     self openModalOnResourceSpec:aMenuOrNil
  2344 !
  2345 
  2346 postBuildListOfItemsView:aSrollableView
  2347     listOfItemsView := aSrollableView scrolledView.
  2348 !
  2349 
  2350 postBuildNoteBook:aNoteBook
  2351     aNoteBook tabLabelInset:16@4.
  2352 ! !
  2353 
  2354 !MenuEditor methodsFor:'menus-dynamic'!
  2355 
  2356 submenuTest
  2357     "returns a menu on the current editing menu
  2358     "
  2359     |menu indication choice submenu retriever|
  2360 
  2361     menu := listOfItems root submenu.
  2362     menu isNil ifTrue:[^ nil ].
  2363 
  2364     menu allItemsDo:[:anItem|
  2365         anItem ignoreShortcutKeys:true.
  2366         anItem isVisible:true.
  2367         anItem enabled:true.
  2368         anItem translateLabel:false.
  2369 
  2370         anItem itemValue notNil ifTrue:[
  2371             anItem itemValue:[ Transcript showCR:(anItem label) ].
  2372         ].
  2373         anItem indication notNil ifTrue:[
  2374             indication isNil ifTrue:[ indication := true asValue ].
  2375             anItem indication:indication
  2376         ].
  2377         anItem choice notNil ifTrue:[
  2378             choice isNil ifTrue:[ choice := anItem choiceValue asValue ].
  2379             anItem choice:choice
  2380         ].
  2381         anItem isMenuSlice ifTrue:[
  2382             anItem submenuChannel:nil.
  2383             anItem label:'... Slice Menu ...'.
  2384         ].
  2385         anItem submenuChannel notNil ifTrue:[
  2386             anItem submenuChannel:nil.
  2387             anItem submenu isNil ifTrue:[
  2388                 submenu isNil ifTrue:[
  2389                     submenu := Menu new.
  2390                     submenu addItem:(MenuItem label:'Linked Menu...').
  2391                 ].
  2392                 anItem submenu:submenu.
  2393             ].
  2394         ].
  2395         retriever := anItem resourceRetriever.
  2396         retriever notNil ifTrue:[
  2397             retriever labelText notNil ifTrue:[ retriever labelText:(anItem label) ]
  2398         ].
  2399     ].
  2400     menu findGuiResourcesIn:(self resolveName:specClass).
  2401     ^ menu
  2402 ! !
  2403 
  2404 !MenuEditor methodsFor:'private'!
  2405 
  2406 addAndSelectValueOf:aBlockOrItem
  2407     "add an item(s) derived from the block; test if add operation
  2408      is enabled. On success the new item(s) are returned otherwise nil.
  2409     "
  2410     |intoItem index newItem|
  2411 
  2412     intoItem := self selectedItem.
  2413     intoItem isNil ifTrue:[ ^ nil].
  2414 
  2415     self askForItemModification ifFalse:[ ^ nil ].
  2416 
  2417     index := 1.
  2418 
  2419     (intoItem canAddChildren and:[intoItem isExpanded]) ifFalse:[
  2420 	intoItem parent notNil ifTrue:[
  2421 	    [ intoItem parent canAddChildren ] whileFalse:[
  2422 		intoItem := intoItem parent.
  2423 	    ].
  2424 	    index := intoItem parent identityIndexOf:intoItem.
  2425 	    index := index + 1.
  2426 	    intoItem := intoItem parent.
  2427 	].
  2428     ].
  2429     newItem := aBlockOrItem value.
  2430 
  2431     newItem notNil ifTrue:[
  2432 	selectionHolder setValue:nil.
  2433 	intoItem expand.
  2434 
  2435 	newItem isCollection ifTrue:[
  2436 	    intoItem addAll:newItem beforeIndex:index.
  2437 	    selectionHolder value:newItem.
  2438 	] ifFalse:[
  2439 	    intoItem add:newItem beforeIndex:index.
  2440 	    selectionHolder value:(Array with:newItem).
  2441 	].
  2442 	self setModified.
  2443     ].
  2444     ^ newItem
  2445 
  2446     "Modified: / 29-11-2011 / 11:28:06 / cg"
  2447 !
  2448 
  2449 clearModified
  2450     "clear the modifiedChannel and the commitPanel"
  2451 
  2452     super clearModified.
  2453     self enablingCommitButtonsHolder value:false.
  2454     self clearModifiedFlag.
  2455 !
  2456 
  2457 generateMenuSpec
  2458     "generate and returns the current menu spec or nil"
  2459 
  2460     ^ self generateMenuSpecFor:listOfItems root
  2461 !
  2462 
  2463 generateMenuSpecFor:aMenuItem
  2464     "generate and returns a menu spec or nil"
  2465 
  2466     |menu|
  2467 
  2468     menu := aMenuItem submenu.
  2469     menu isNil ifTrue:[^ nil].
  2470 
  2471     ^ menu literalArrayEncoding.
  2472 !
  2473 
  2474 generateMenuSpecString
  2475     "generate and returns the current menu spec as string or nil"
  2476 
  2477     ^ self generateMenuSpecStringFor:listOfItems root 
  2478 !
  2479 
  2480 generateMenuSpecStringFor:aMenuItem
  2481     "generate and returns the current menu spec as string or nil"
  2482 
  2483     |menu specStream|
  2484 
  2485     menu := self generateMenuSpecFor:aMenuItem.
  2486     menu isNil ifTrue:[^ nil].
  2487 
  2488     specStream := WriteStream on:''.
  2489     UISpecification prettyPrintSpecArray:menu on:specStream indent:5.
  2490     ^ specStream contents.
  2491 !
  2492 
  2493 withoutNotifyDo:aBlock
  2494     "evaluate the block; all change notifications are
  2495      discard during the block is evaluated"
  2496 
  2497     |blockResult|
  2498 
  2499     [
  2500 	notifyDisabledCounter := notifyDisabledCounter + 1.
  2501 	blockResult := aBlock value.
  2502     ] ensure:[
  2503 	notifyDisabledCounter := notifyDisabledCounter - 1
  2504     ].
  2505     ^ blockResult
  2506 ! !
  2507 
  2508 !MenuEditor methodsFor:'queries'!
  2509 
  2510 hasValidSpecClass
  2511     "returns true if a valid specClass exists
  2512     "
  2513     specClass isNil ifTrue:[^ false].
  2514     ^ (self resolveName:specClass) notNil
  2515 
  2516     "Modified: / 19-11-2016 / 20:19:30 / cg"
  2517 !
  2518 
  2519 isEditingSpecOnly
  2520     ^ masterApplication notNil
  2521     and:[ masterApplication perform:#isEditingSpecOnly ifNotUnderstood:false]
  2522 !
  2523 
  2524 isNotEditingSpecOnly
  2525     ^ self isEditingSpecOnly not
  2526 !
  2527 
  2528 isNotEditingSpecOnlyAndNotEmbeddedInBrowser
  2529     ^ self isNotEditingSpecOnly and:[ self isEmbeddedInBrowser not ]
  2530 ! !
  2531 
  2532 !MenuEditor methodsFor:'selection'!
  2533 
  2534 canSelect:anIndex
  2535     "called whenever the selection changed; test whether
  2536      current item is not modified ....
  2537     "
  2538     |oldSelectedItem newSelectedItem anythingChanged|
  2539 
  2540     self enablingCommitButtonsHolder value ifFalse:[
  2541 	^ true
  2542     ].
  2543     oldSelectedItem := self selectedItem.
  2544     oldSelectedItem isNil ifTrue:[^ true].
  2545 
  2546     newSelectedItem := listOfItems at:anIndex ifAbsent:nil.
  2547     oldSelectedItem == newSelectedItem ifTrue:[
  2548 	^ true
  2549     ].
  2550 
  2551     anythingChanged := self enablingCommitButtonsHolder value.
  2552     anythingChanged ifTrue:[
  2553 	self autoAcceptOnSelectionChange value ifTrue:[
  2554 	    self accept.
  2555 	    ^ true
  2556 	].
  2557     ].
  2558 
  2559     ^ self askForItemModification
  2560 !
  2561 
  2562 hasSelection
  2563     "returns true if a selection exists
  2564     "
  2565     ^ selectionHolder value size ~~ 0
  2566 !
  2567 
  2568 selectedItem
  2569     "returns the selected item or nil (none or multiple selected)"
  2570 
  2571     |selection|
  2572 
  2573     selection := selectionHolder value.
  2574     selection size == 1 ifTrue:[ ^ selection first ].
  2575     ^ nil
  2576 
  2577     "Modified: / 18-01-2012 / 11:33:42 / cg"
  2578 !
  2579 
  2580 selectedItem:anItem
  2581     "change selection to an item
  2582     "
  2583     |selection|
  2584 
  2585     anItem notNil ifTrue:[ selection := Array with:anItem ]
  2586 		 ifFalse:[ selection := #() ].
  2587 
  2588     selectionHolder value:selection.
  2589 !
  2590 
  2591 selectedItems
  2592     "returns the selected items or an empty collection"
  2593 
  2594     ^ selectionHolder value.
  2595 
  2596     "Created: / 18-01-2012 / 11:32:20 / cg"
  2597 !
  2598 
  2599 selectedItems:aCollectionOfItems
  2600     "set the selected items"
  2601 
  2602     selectionHolder value:aCollectionOfItems.
  2603 
  2604     "Created: / 18-01-2012 / 11:32:37 / cg"
  2605 ! !
  2606 
  2607 !MenuEditor methodsFor:'user actions-aspects'!
  2608 
  2609 collectActionSelectors
  2610     |selectors|
  2611 
  2612     selectors := IdentitySet new.
  2613 
  2614     listOfItems root recursiveDo:[:el|
  2615 	el actionSelectors do:[:s| selectors add:s ].
  2616     ].
  2617     ^ selectors asOrderedCollection
  2618 !
  2619 
  2620 collectAspectSelectors
  2621     |selectors|
  2622 
  2623     selectors := IdentitySet new.
  2624 
  2625     listOfItems root recursiveDo:[:el|
  2626 	selectors addAll:(el aspectSelectors).
  2627     ].
  2628     ^ selectors asOrderedCollection
  2629 !
  2630 
  2631 doBrowseActionMethod
  2632     "open a browser on the action callback method (create if not yet existing)"
  2633 
  2634     self doBrowseApplicationMethodFor:#itemValue
  2635 
  2636     "Modified: / 21-10-2010 / 14:09:33 / cg"
  2637 !
  2638 
  2639 doBrowseApplicationMethodFor:aspect
  2640     |selector cls implClass browsedClass category|
  2641 
  2642     specClass isNil ifTrue:[
  2643         self warn:('Please define the application class first.').
  2644         ^ self
  2645     ].
  2646 
  2647     selector := (self aspectValueFor:aspect).
  2648     selector isEmptyOrNil ifTrue:[
  2649         Dialog information:(resources string:'Missing name for the action/aspect method.').
  2650         ^ self
  2651     ].
  2652     (selector = 'true' or:[selector = 'false']) ifTrue:[^ self].
  2653     (selector == true or:[selector == false]) ifTrue:[^ self].
  2654 
  2655     selector := selector asSymbol.
  2656 
  2657     cls := self resolveName:specClass.
  2658     cls isNil ifTrue:[
  2659         self warn:(resources string:'Class %1 does not exist!!' with:specClass asString).
  2660         ^ self
  2661     ].
  2662 
  2663     browsedClass := cls.
  2664     (cls includesSelector:selector) ifFalse:[
  2665         | generate |    
  2666         (implClass := cls whichClassImplements:selector) notNil ifTrue:[
  2667             generate := (Dialog 
  2668                 confirm:(resources 
  2669                             stringWithCRs:'The application does not directly implement %1.\However it inherits this from %2.\\Create a redefinition in %1?'
  2670                             with:cls name
  2671                             with:implClass name)
  2672                 initialAnswer:false)
  2673         ] ifFalse:[ 
  2674             generate := true.
  2675         ].
  2676         category := UserPreferences current categoryForMenuActionsMethods.
  2677 
  2678         SmalltalkCodeGeneratorTool
  2679             createActionMethodFor:selector in:cls
  2680             category:category
  2681             redefine:(self redefineAspectMethodsChannel value).
  2682     ].
  2683 
  2684     browsedClass browserClass openInClass:browsedClass selector:selector
  2685 
  2686     "Created: / 21-10-2010 / 14:07:32 / cg"
  2687     "Modified: / 31-01-2011 / 18:28:59 / cg"
  2688     "Modified: / 17-03-2014 / 12:25:37 / Jan Vrany <jan.vrany@fit.cvut.cz>"
  2689     "Modified: / 09-08-2018 / 15:31:11 / Claus Gittinger"
  2690 !
  2691 
  2692 doBrowseChoiceMethod
  2693     "open a browser on the choice aspect method (create if not yet existing)"
  2694 
  2695     self doBrowseApplicationMethodFor:#choice
  2696 !
  2697 
  2698 doBrowseEnabledMethod
  2699     "open a browser on the enabled method (create if not yet existing)"
  2700 
  2701     self doBrowseApplicationMethodFor:#enabled
  2702 
  2703     "Created: / 21-10-2010 / 14:09:41 / cg"
  2704 !
  2705 
  2706 doBrowseIndicationMethod
  2707     "open a browser on the indicator aspect method (create if not yet existing)"
  2708 
  2709     self doBrowseApplicationMethodFor:#indication
  2710 !
  2711 
  2712 doBrowseVisibilityMethod
  2713     "open a browser on the visibility method (create if not yet existing)"
  2714 
  2715     self doBrowseApplicationMethodFor:#isVisible
  2716 
  2717     "Created: / 21-10-2010 / 14:09:56 / cg"
  2718 !
  2719 
  2720 doGenerateAspectMethods
  2721     "compile aspect and action methods"
  2722 
  2723     |cls redefineAspectMethods category|
  2724 
  2725     specClass isNil ifTrue:[
  2726 	self warn:'Define the class first !!'.
  2727 	^ self
  2728     ].
  2729     redefineAspectMethods := self redefineAspectMethodsChannel value.
  2730 
  2731     cls := self resolveName:specClass.
  2732     cls isNil ifTrue:[
  2733 	self warn:'Class ', specClass asString, ' does not exist!!'.
  2734 	^ self
  2735     ].
  2736 
  2737     category := UserPreferences current categoryForMenuActionsMethods.
  2738 
  2739     self collectActionSelectors do:[:aSelector|
  2740 	SmalltalkCodeGeneratorTool
  2741 	    createActionMethodFor:aSelector in:cls
  2742 	    category:category
  2743 	    redefine:redefineAspectMethods.
  2744     ].
  2745 
  2746     self collectAspectSelectors do:[:anAspect|
  2747 	SmalltalkCodeGeneratorTool
  2748 	    createAspectMethodFor:anAspect in:cls
  2749 	    category:category
  2750 	    redefine:redefineAspectMethods
  2751     ].
  2752 
  2753     "Modified: / 31-01-2011 / 18:29:06 / cg"
  2754 ! !
  2755 
  2756 !MenuEditor methodsFor:'user actions-building'!
  2757 
  2758 compileSpecMethodFor:aMenuItem selector:specSelector
  2759     "save current editing menu to
  2760            class: specClass
  2761         selector: specSelector
  2762     "
  2763     |cls specCode mthd category s|
  2764 
  2765     specCode := self generateMenuSpecStringFor:aMenuItem.
  2766     specCode isNil ifTrue:[^ nil].
  2767 
  2768     cls  := self resolveName:specClass.
  2769 
  2770     "/ if that method already exists, do not overwrite the category
  2771 
  2772     category := 'menu specs'.
  2773     (mthd := cls theMetaclass compiledMethodAt:specSelector) notNil ifTrue:[
  2774         category := mthd category.
  2775     ].
  2776 
  2777     s := '' writeStream.
  2778 
  2779     s nextPutChunkSeparator;
  2780       nextPutAll:(cls name);
  2781       nextPutAll:' class methodsFor:';
  2782       nextPutAll:category storeString;
  2783       nextPutChunkSeparator;
  2784       cr; cr;
  2785       nextPutAll:specSelector;
  2786       cr;
  2787       nextPutAllAsChunk:(self class codeGenerationComment) withCRs;
  2788       cr; cr;
  2789       nextPutLine:'    "';
  2790       nextPutLine:('     MenuEditor new openOnClass:' , cls name , ' andSelector:#' , specSelector);
  2791       nextPutLine:('     (Menu new fromLiteralArrayEncoding:(' , cls name , ' ' , specSelector , ')) startUp');
  2792       nextPutLine:'    "';
  2793       cr;
  2794       nextPutLine:'    <resource: #menu>';
  2795       cr;
  2796       nextPutAll:'    ^ ';
  2797       nextChunkPut:specCode;
  2798       space;
  2799       nextPutChunkSeparator;
  2800       cr.
  2801 
  2802     Class packageQuerySignal answer:cls package do:[
  2803         (ReadStream on:s contents) fileIn.
  2804     ].
  2805 !
  2806 
  2807 doChooseAMenu
  2808     "pick a menu and edit its spec method"
  2809 
  2810     |view subSpec app bldr spec menuSelector1 menuSelector2 info|
  2811 
  2812     self askForModification ifTrue:[
  2813 	view := Screen current viewFromUser.
  2814 	(view isNil or:[view == Screen current rootView]) ifTrue:[
  2815 	    ^ self
  2816 	].
  2817 	view specClass == MenuPanelSpec ifTrue:[
  2818 	    (app := view application) isNil ifTrue:[
  2819 		info := 'Could not figure out the application class.'
  2820 	    ] ifFalse:[
  2821 		(bldr := app builder) isNil ifTrue:[
  2822 		    info := 'Application has no builder.'
  2823 		] ifFalse:[
  2824 		    menuSelector1 := bldr namedComponents keyAtValue:view ifAbsent:nil.
  2825 		    (spec := bldr spec) isNil ifTrue:[
  2826 			info := 'Cannot fetch spec from applications builder.'
  2827 		    ] ifFalse:[
  2828 			subSpec := spec findSpecForWhich:[:subSpec | subSpec name = view name].
  2829 			subSpec isNil ifTrue:[
  2830 			    info := 'Cannot find view-spec for ',view name asString,'.'
  2831 			] ifFalse:[
  2832 			    menuSelector2 := subSpec menu.
  2833 			]
  2834 		    ].
  2835 		    (menuSelector1 isNil and:[ menuSelector2 isNil ]) ifTrue:[
  2836 			info := 'menu is probably not provided by a menuSelector.'
  2837 		    ] ifFalse:[
  2838 			(app class respondsTo:menuSelector1) ifTrue:[
  2839 			    self loadFromClass:app class andSelector:menuSelector1.
  2840 			    ^ self.
  2841 			].
  2842 			(app class respondsTo:menuSelector2) ifTrue:[
  2843 			    self loadFromClass:app class andSelector:menuSelector2.
  2844 			    ^ self.
  2845 			].
  2846 			info := 'menu is probably not provided by a menuSelector.'
  2847 		    ].
  2848 		]
  2849 	    ].
  2850 	    info notNil ifTrue:[
  2851 		app notNil ifTrue:[
  2852 		    (Dialog confirm:(info,'\\Browse ?' withCRs)) ifTrue:[
  2853 			app browse.
  2854 		    ].
  2855 		] ifFalse:[
  2856 		    Dialog information:info.
  2857 		].
  2858 	    ].
  2859 	    ^ self.
  2860 	].
  2861     ].
  2862 !
  2863 
  2864 doNew
  2865     "clear editing menu; start from scratch
  2866     "
  2867     super doNew ifTrue:[ self helpTool doNew ].
  2868 !
  2869 
  2870 doPickAMenu
  2871     "let user pick a menu and create a new spec"
  2872 
  2873     |view|
  2874 
  2875     self askForModification ifTrue:[
  2876 	view := Screen current viewFromUser.
  2877 	(view isNil or:[view == Screen current rootView]) ifTrue:[
  2878 	    ^ self
  2879 	].
  2880 	view specClass == MenuPanelSpec ifTrue:[
  2881 	    specSelector := #pickedMenu.
  2882 	    self buildFromMenu:(view asMenu) selector:specSelector.
  2883 	].
  2884     ].
  2885 !
  2886 
  2887 doSave
  2888     "save current editing menu to
  2889            class: specClass
  2890         selector: specSelector
  2891     "
  2892     self isEditingSpecOnly ifTrue:[
  2893         savedSpec := self generateMenuSpec.
  2894         hasSaved := true.
  2895         self clearModified.
  2896         ^ self
  2897     ].
  2898 
  2899     super doSave ifFalse: [^nil].
  2900 
  2901     self compileSpecMethodFor:listOfItems root selector:specSelector.
  2902     self isStandAlone ifTrue:[
  2903         self helpTool doSave
  2904     ].
  2905 
  2906     self updateHistory.
  2907     hasSaved := true.
  2908     self clearModified.
  2909 
  2910     "Modified: / 28-01-2014 / 21:57:24 / cg"
  2911 !
  2912 
  2913 doSaveAs
  2914     "save current editing menu to class and selector
  2915      defined by the user.
  2916     "
  2917     super doSaveAs ifTrue:[
  2918 	listOfItems root rawLabel:specSelector
  2919     ].
  2920 !
  2921 
  2922 doShowMenuSpec
  2923     "opens a code view with the contents of the menu spec"
  2924 
  2925     |code|
  2926 
  2927     code := self generateMenuSpecString.
  2928 
  2929     code notNil ifTrue:[
  2930 	CodeView openWith:code title: 'Menu Spec'
  2931     ].
  2932 
  2933     "Modified: / 29-11-2011 / 11:28:12 / cg"
  2934 !
  2935 
  2936 save
  2937     self doSave
  2938 ! !
  2939 
  2940 !MenuEditor methodsFor:'user actions-creation'!
  2941 
  2942 doCreateDelayedMenu:what
  2943     |selectedItem delayedItem|
  2944 
  2945     selectedItem := self selectedItem.
  2946     selectedItem isNil ifTrue:[^ self].
  2947 
  2948     selectedItem canAddDelayedMenu      ifFalse:[ ^ self ].
  2949     self askForItemModification ifFalse:[ ^ self ].
  2950 
  2951     what == #menu ifTrue:[ delayedItem := RegularMenuItem new ]
  2952 		 ifFalse:[ delayedItem := LinkedMenuItem new ].
  2953 
  2954     delayedItem setExpanded:true.
  2955     delayedItem := selectedItem add:delayedItem.
  2956 
  2957     delayedItem notNil ifTrue:[
  2958 	self selectedItem:delayedItem.
  2959     ].
  2960 
  2961     "Modified: / 29-11-2011 / 11:28:09 / cg"
  2962 !
  2963 
  2964 doCreateItem
  2965     "create a new Item
  2966     "
  2967     self addAndSelectValueOf:[ ActionItem new translateLabel:true ].
  2968 !
  2969 
  2970 doCreateLinkedMenu
  2971     "create a new Linked Menu
  2972     "
  2973     self addAndSelectValueOf:[ LinkedMenuItem new ].
  2974 !
  2975 
  2976 doCreateMenu
  2977     "create a new Menu
  2978     "
  2979     self addAndSelectValueOf:
  2980 	[ |item|
  2981 	    item := RegularMenuItem new.
  2982 	    "/ --- do not add it expanded - because that makes it hard to add multipe menus
  2983 	    "/ item expand.
  2984 	    item
  2985 	].
  2986 !
  2987 
  2988 doCreateMenuSliceItem
  2989     "create a new MenuSlice Item
  2990     "
  2991     self addAndSelectValueOf:[ MenuSliceItem new ].
  2992 !
  2993 
  2994 doCreateSep
  2995     "create a new Separator Item
  2996     "
  2997     self addAndSelectValueOf:[ SeparatorItem new ].
  2998 !
  2999 
  3000 doCreateStandardEditMenu
  3001     "create a standard edit menu
  3002     "
  3003     self addAndSelectValueOf:[
  3004 	RegularMenuItem menu:(self class standardEditMenu) labeled:'Edit' translateLabel:true
  3005     ].
  3006 !
  3007 
  3008 doCreateStandardFileMenu
  3009     "create a standard file menu
  3010     "
  3011     self addAndSelectValueOf:[
  3012 	RegularMenuItem menu:(self class standardFileMenu) labeled:'File' translateLabel:true
  3013     ].
  3014 !
  3015 
  3016 doCreateStandardHelpMenu
  3017     "create a standard help menu
  3018     "
  3019     |item|
  3020 
  3021     self addAndSelectValueOf:[
  3022 	item := RegularMenuItem menu:(self class standardHelpMenu) labeled:'Help' translateLabel:true.
  3023 	item aspectAt:#startGroup put:#conditionalRight.
  3024 	item
  3025     ].
  3026 
  3027     "Modified: / 16-10-2006 / 12:49:27 / cg"
  3028 ! !
  3029 
  3030 !MenuEditor methodsFor:'user actions-editing'!
  3031 
  3032 doCopy
  3033     "copy selected menuItems to the clipboard
  3034     "
  3035     |clip items|
  3036 
  3037     items := self selectedSuperItems.
  3038     items isEmpty ifTrue:[ ^ self ].
  3039 
  3040     clip := OrderedCollection new.
  3041     items do:[:el| clip add:(el menuItem) ].
  3042 
  3043     self clipboard:clip.
  3044     self updateAllToolInstances.
  3045 !
  3046 
  3047 doCut
  3048     "copy selected menuItems to the clipboard and delete
  3049     "
  3050     self doCopy.
  3051     self doDelete.
  3052 !
  3053 
  3054 doDelete
  3055     "delete selected menuItems
  3056     "
  3057     |selectedItem parent toDelete behind nextItem prevItem|
  3058 
  3059     toDelete := self selectedSuperItems.
  3060     toDelete isEmpty ifTrue:[ ^ self ].
  3061 
  3062     self clearModified.
  3063 
  3064     selectedItem := toDelete first.
  3065 
  3066     selectedItem isRootItem ifTrue:[
  3067 	^ selectedItem removeAll.
  3068     ].
  3069     "/ compute the new selection
  3070 
  3071     prevItem := parent := selectedItem parent.
  3072     nextItem := nil.
  3073 
  3074     parent children size ~~ 1 ifTrue:[
  3075 	behind := false.
  3076 
  3077 	parent do:[:el|
  3078 	    behind ifTrue:[
  3079 		(nextItem notNil or:[toDelete includesIdentical:el]) ifFalse:[ nextItem := el ].
  3080 	    ] ifFalse:[
  3081 		behind := el == selectedItem.
  3082 		(behind or:[toDelete includesIdentical:el]) ifFalse:[ prevItem := el ].
  3083 	    ]
  3084 	]
  3085     ].
  3086     self withoutNotifyDo:[
  3087 	toDelete do:[:el| el remove ].
  3088     ].
  3089     self selectedItem:(nextItem ? prevItem).
  3090     self setModified.
  3091     self updateChannels.
  3092 !
  3093 
  3094 doPaste
  3095     "paste from clipboard
  3096     "
  3097     ^ self doPaste:(self clipboard)
  3098 !
  3099 
  3100 doPaste:aCollection
  3101     "paste collection of MenuItems
  3102     "
  3103     |item loMenuItems|
  3104 
  3105     aCollection size == 0 ifTrue:[ ^ self ].
  3106 
  3107     item := self selectedItem.
  3108     item isNil ifTrue:[ ^ self ].
  3109 
  3110     loMenuItems := OrderedCollection new.
  3111     aCollection do:[:el|
  3112 	(el askFor:#isMenuItem) ifTrue:[ loMenuItems add:el ].
  3113     ].
  3114     loMenuItems isEmpty ifTrue:[ ^ self ].
  3115 
  3116     self addAndSelectValueOf:[
  3117 	loMenuItems collect:[:el| Item menuItem:el ]
  3118     ].
  3119 ! !
  3120 
  3121 !MenuEditor methodsFor:'user actions-hierarchy'!
  3122 
  3123 doMakeLinkedMenu
  3124     "the selected item must be a regular submenu.
  3125      create a new menuspec for it,
  3126      and chenge the item to a linke menu item."
  3127 
  3128     |cls subSelector oldMenuItem newLinkedMenuItem index|
  3129 
  3130     oldMenuItem := self selectionHolder value first.
  3131 
  3132     subSelector := Dialog 
  3133                     request:'Name of spec method for submenu:'
  3134                     initialAnswer:((oldMenuItem label reject:[:ch | ch isLetterOrDigit not]),'MenuSpec') asLowercaseFirst.
  3135     subSelector isEmptyOrNil ifTrue:[^ self].
  3136     subSelector := subSelector asSymbol.
  3137 
  3138     cls  := self resolveName:specClass.
  3139     (cls theMetaclass compiledMethodAt:subSelector) notNil ifTrue:[
  3140         (Dialog confirm:'Overwrite existing spec?') ifFalse:[^ self].
  3141     ].
  3142 
  3143     self compileSpecMethodFor:oldMenuItem selector:subSelector.
  3144 
  3145     newLinkedMenuItem := LinkedMenuItem new.
  3146     newLinkedMenuItem submenuChannel:subSelector.
  3147     newLinkedMenuItem menuItem nameKey:(oldMenuItem menuItem nameKey).
  3148     newLinkedMenuItem menuItem label:oldMenuItem menuItem label.
  3149     newLinkedMenuItem menuItem rawLabel:oldMenuItem menuItem rawLabel.
  3150     newLinkedMenuItem menuItem translateLabel:(oldMenuItem menuItem translateLabel).
  3151     newLinkedMenuItem menuItem hasMenuIndicator:(oldMenuItem menuItem hasMenuIndicator).
  3152 
  3153     index := oldMenuItem parent identityIndexOf:oldMenuItem.
  3154     oldMenuItem parent at:index put:newLinkedMenuItem.
  3155 
  3156     self selectedItem:newLinkedMenuItem.
  3157 
  3158     "Modified: / 09-08-2018 / 17:09:40 / Claus Gittinger"
  3159 !
  3160 
  3161 doMoveDown
  3162     "move selected item down"
  3163 
  3164     self doMoveUpOrDown:#down
  3165 !
  3166 
  3167 doMoveIn:aDirection
  3168     "move selected item into the next (#inNext) or previous (#inPrev) item
  3169     "
  3170     |item idx parent toParent|
  3171 
  3172     item := self selectedItem.
  3173     item isNil ifTrue:[^ self].
  3174 
  3175     aDirection == #inNext ifTrue:[ item canMoveInNext  ifFalse:[^ self] ]
  3176 			 ifFalse:[ item canMoveInAbove ifFalse:[^ self] ].
  3177 
  3178     self askForItemModification ifFalse:[ ^ self ].
  3179 
  3180     parent := item parent.
  3181     idx    := parent identityIndexOf:item.
  3182 
  3183     aDirection == #inNext ifTrue:[ toParent := parent at:(idx + 1) ifAbsent:nil ]
  3184 			 ifFalse:[ toParent := parent at:(idx - 1) ifAbsent:nil ].
  3185 
  3186     self withoutNotifyDo:[
  3187 	selectionHolder setValue:#().
  3188 	parent removeIndex:idx.
  3189 
  3190 	aDirection == #inNext ifTrue:[ toParent addFirst:item ]
  3191 			     ifFalse:[ toParent  addLast:item ].
  3192 	item makeVisible.
  3193     ].
  3194     self selectedItem:item.
  3195     self setModified.
  3196 !
  3197 
  3198 doMoveInNext
  3199     "move selected item into the next item"
  3200 
  3201     self doMoveIn:#inNext.
  3202 !
  3203 
  3204 doMoveInPrevious
  3205     "move selected item into the previous item"
  3206 
  3207     self doMoveIn:#inPrev.
  3208 !
  3209 
  3210 doMoveOut
  3211     "move selected item out of current item
  3212     "
  3213     |item parent grandParent index|
  3214 
  3215     item := self selectedItem.
  3216     item isNil ifTrue:[^ self].
  3217     item canMoveOut ifFalse:[^ self].
  3218 
  3219     self askForItemModification ifFalse:[ ^ self ].
  3220 
  3221     parent      := item parent.
  3222     grandParent := parent parent.
  3223     index       := grandParent identityIndexOf:parent.
  3224 
  3225     self withoutNotifyDo:[
  3226 	selectionHolder setValue:#().
  3227 	parent remove:item.
  3228 	index > grandParent size ifTrue:[ grandParent add:item ]
  3229 				ifFalse:[ grandParent add:item afterIndex:index ]
  3230     ].
  3231     self selectedItem:item.
  3232     self setModified.
  3233 !
  3234 
  3235 doMoveUp
  3236     "move selected item up"
  3237 
  3238     self doMoveUpOrDown:#up
  3239 !
  3240 
  3241 doMoveUpOrDown:aDirectionSymbol
  3242     "move selected item up (#up) or down (#down)"
  3243 
  3244     |items itemsSortedByIndex index parent children|
  3245 
  3246     items := self selectedItems.
  3247     items isEmptyOrNil ifTrue:[^ self].
  3248     (items conform:[:i | i canMoveUpOrDown]) ifFalse:[^ self].
  3249 
  3250     self askForItemModification ifFalse:[ ^ self ].
  3251 
  3252     self withoutNotifyDo:[
  3253 	itemsSortedByIndex := items copy.
  3254 	(items collect:[:i | listOfItems identityIndexOf:i])
  3255 	    sortWith:itemsSortedByIndex.
  3256 
  3257 	aDirectionSymbol == #down ifTrue:[
  3258 	    itemsSortedByIndex := itemsSortedByIndex reversed
  3259 	].
  3260 	itemsSortedByIndex do:[:item |
  3261 	    parent   := item parent.
  3262 	    children := parent children.
  3263 	    index    := children identityIndexOf:item.
  3264 
  3265 	    selectionHolder setValue:#().
  3266 	    children removeIndex:index.
  3267 
  3268 	    aDirectionSymbol == #up ifTrue:[
  3269 		index == 1 ifTrue:[ children add:item ]
  3270 			ifFalse:[ children add:item beforeIndex:index - 1 ]
  3271 	    ] ifFalse:[
  3272 		index > children size ifTrue:[ children addFirst:item ]
  3273 				    ifFalse:[ children add:item afterIndex:index ]
  3274 	    ].
  3275 	    parent childrenOrderChanged.
  3276 	]
  3277     ].
  3278     self selectedItems:items.
  3279     self setModified.
  3280 
  3281     "Modified: / 18-01-2012 / 11:35:38 / cg"
  3282 ! !
  3283 
  3284 !MenuEditor::Item class methodsFor:'defaults'!
  3285 
  3286 defaultLabel
  3287     ^ self subclassResponsibility
  3288 ! !
  3289 
  3290 !MenuEditor::Item class methodsFor:'image specs'!
  3291 
  3292 iconDelayedLinkedMenu
  3293     "This resource specification was automatically generated
  3294      by the ImageEditor of ST/X."
  3295 
  3296     "Do not manually edit this!! If it is corrupted,
  3297      the ImageEditor may not be able to read the specification."
  3298 
  3299     "
  3300      self iconDelayedLinkedMenu inspect
  3301      ImageEditor openOnClass:self andSelector:#iconDelayedLinkedMenu
  3302      Icon flushCachedIcons
  3303     "
  3304 
  3305     <resource: #image>
  3306 
  3307     ^Icon
  3308         constantNamed:'MenuEditor::Item iconDelayedLinkedMenu'
  3309         ifAbsentPut:[(Depth4Image new) width:20; height:16; bits:(ByteArray fromPackedString:'
  3310 @@@@@@@@@@@@@@DQDQDQDQDQDR@AH"H"H"H"H"H0@@@BH"H"@@@BL@QDPBH"H"@@H#@DQDPBH@H"@"H0ADQDPBA@H"H"L@@@QDP@Q@@@@C@ADPQDQDQ@DQD:
  3311 @RH QDQDQ@H"L@D"H QDQD@"H#@A@@@@@DP@@@@0@QDQDQA@DQDQL@D"H"H @"H"H#@BL3L3L3L3L3L0@@@@@@@@@@@@@@@a') ; colorMapFromArray:#[0 0 0 255 255 255 170 170 170 127 127 127 255 0 0]; mask:((ImageMask new) width:20; height:16; bits:(ByteArray fromPackedString:'???0???0???0???0???0???0???0???0???0???0???0???0???0???0???0???0') ; yourself); yourself]
  3312 !
  3313 
  3314 iconDelayedMenu
  3315     <resource: #image>
  3316     "This resource specification was automatically generated
  3317      by the ImageEditor of ST/X."
  3318     "Do not manually edit this!! If it is corrupted,
  3319      the ImageEditor may not be able to read the specification."
  3320     "
  3321      self iconDelayedMenu inspect
  3322      ImageEditor openOnClass:self andSelector:#iconDelayedMenu
  3323      Icon flushCachedIcons"
  3324     
  3325     ^ Icon constantNamed:'MenuEditor::Item class iconDelayedMenu'
  3326         ifAbsentPut:[
  3327             (Depth2Image new)
  3328                 width:20;
  3329                 height:16;
  3330                 photometric:(#palette);
  3331                 bitsPerSample:(#( 2 ));
  3332                 samplesPerPixel:(1);
  3333                 bits:(ByteArray 
  3334                             fromPackedString:'@@@@@@@UUUUUVA*****,F***@B0Z***@+A****J,F*****0@@@@@@AUUUUUXF*****0Z****+A@@@@@LEUUUUU0Z****+B?????<@@@@@@@b');
  3335                 colorMapFromArray:#[ 0 0 0 255 255 255 170 170 170 127 127 127 ];
  3336                 mask:((ImageMask new)
  3337                             width:20;
  3338                             height:16;
  3339                             bits:(ByteArray 
  3340                                         fromPackedString:'???0???0???0???0???0???0???0???0???0???0???0???0???0???0???0???0');
  3341                             yourself);
  3342                 yourself
  3343         ]
  3344 !
  3345 
  3346 iconItem
  3347     <resource: #image>
  3348     "This resource specification was automatically generated
  3349      by the ImageEditor of ST/X."
  3350     "Do not manually edit this!! If it is corrupted,
  3351      the ImageEditor may not be able to read the specification."
  3352     "
  3353      self iconItem inspect
  3354      ImageEditor openOnClass:self andSelector:#iconItem
  3355      Icon flushCachedIcons"
  3356     
  3357     ^ Icon constantNamed:'MenuEditor::Item class iconItem'
  3358         ifAbsentPut:[
  3359             (Depth2Image new)
  3360                 width:20;
  3361                 height:16;
  3362                 photometric:(#palette);
  3363                 bitsPerSample:(#( 2 ));
  3364                 samplesPerPixel:(1);
  3365                 bits:(ByteArray 
  3366                             fromPackedString:'UUUUUUUUUUUUUP@@@@@@EUUUUU Z****+A.?/;+,F:::/>0[++>:;A...++,F::?..0Z****+B?????<@@@@@@@@@@@@@@@@@@@@@@@@@@@b');
  3367                 colorMapFromArray:#[ 0 0 0 255 255 255 170 170 170 127 127 127 ];
  3368                 mask:((ImageMask new)
  3369                             width:20;
  3370                             height:16;
  3371                             bits:(ByteArray 
  3372                                         fromPackedString:'@@@@@@@@???0???0???0???0???0???0???0???0???0???0???0@@@@@@@@@@@@');
  3373                             yourself);
  3374                 yourself
  3375         ]
  3376 !
  3377 
  3378 iconLinkedMenu
  3379     <resource: #image>
  3380     "This resource specification was automatically generated
  3381      by the ImageEditor of ST/X."
  3382     "Do not manually edit this!! If it is corrupted,
  3383      the ImageEditor may not be able to read the specification."
  3384     "
  3385      self iconLinkedMenu inspect
  3386      ImageEditor openOnClass:self andSelector:#iconLinkedMenu
  3387      Icon flushCachedIcons"
  3388     
  3389     ^ Icon constantNamed:'MenuEditor::Item class iconLinkedMenu'
  3390         ifAbsentPut:[
  3391             (Depth4Image new)
  3392                 width:20;
  3393                 height:16;
  3394                 photometric:(#palette);
  3395                 bitsPerSample:(#( 4 ));
  3396                 samplesPerPixel:(1);
  3397                 bits:(ByteArray 
  3398                             fromPackedString:'
  3399 @@@@@@@@@@@@@@QDQDQDQDQDQA@DH"H"H"H"H"HPABH@@@H"H"H"D@PQ@3L0DQDQDQ@D@@L3L0@@@@@PADPCL3L0PCADD@P"@@@3L0@3@!!@DH"H"@3L3L3@P
  3400 AADQDQ@3L3L3@@P@@@@@@3L3LA@DQDQDQD@@L0PPABH"H"H"HC@"D@P"H"H"H"@BH!!@BDQDQDQDQDQDP@@@@@@@@@@@@@@@a');
  3401                 colorMapFromArray:#[ 0 0 0 127 127 127 170 170 170 255 0 0 255 255 255 ];
  3402                 mask:((ImageMask new)
  3403                             width:20;
  3404                             height:16;
  3405                             bits:(ByteArray 
  3406                                         fromPackedString:'???0???0???0???0???0???0???0???0???0???0???0???0???0???0???0???0');
  3407                             yourself);
  3408                 yourself
  3409         ]
  3410 !
  3411 
  3412 iconMenu
  3413     <resource: #image>
  3414     "This resource specification was automatically generated
  3415      by the ImageEditor of ST/X."
  3416     "Do not manually edit this!! If it is corrupted,
  3417      the ImageEditor may not be able to read the specification."
  3418     "
  3419      self iconMenu inspect
  3420      ImageEditor openOnClass:self andSelector:#iconMenu
  3421      Icon flushCachedIcons"
  3422     
  3423     ^ Icon constantNamed:'MenuEditor::Item class iconMenu'
  3424         ifAbsentPut:[
  3425             (Depth2Image new)
  3426                 width:20;
  3427                 height:16;
  3428                 photometric:(#palette);
  3429                 bitsPerSample:(#( 2 ));
  3430                 samplesPerPixel:(1);
  3431                 bits:(ByteArray 
  3432                             fromPackedString:'@@@@@@@?????=C*****$N*****P5UUUUUC@@@@@DO?????P:****)C*****$MUUUUUP0@@@@AC?????4N*****P:****)BUUUUUT@@@@@@@b');
  3433                 colorMapFromArray:#[ 0 0 0 127 127 127 170 170 170 255 255 255 ];
  3434                 mask:((ImageMask new)
  3435                             width:20;
  3436                             height:16;
  3437                             bits:(ByteArray 
  3438                                         fromPackedString:'???0???0???0???0???0???0???0???0???0???0???0???0???0???0???0???0');
  3439                             yourself);
  3440                 yourself
  3441         ]
  3442 !
  3443 
  3444 iconSeparator
  3445     <resource: #image>
  3446     "This resource specification was automatically generated
  3447      by the ImageEditor of ST/X."
  3448     "Do not manually edit this!! If it is corrupted,
  3449      the ImageEditor may not be able to read the specification."
  3450     "
  3451      self iconSeparator inspect
  3452      ImageEditor openOnClass:self andSelector:#iconSeparator
  3453      Icon flushCachedIcons"
  3454     
  3455     ^ Icon constantNamed:'MenuEditor::Item class iconSeparator'
  3456         ifAbsentPut:[
  3457             (Depth2Image new)
  3458                 width:20;
  3459                 height:16;
  3460                 photometric:(#palette);
  3461                 bitsPerSample:(#( 2 ));
  3462                 samplesPerPixel:(1);
  3463                 bits:(ByteArray 
  3464                             fromPackedString:'UUUUUUUUUUUUUP@@@@@@EUUUUU Z****+A*****,F????:0[@@@@[A)UUUU,F*****0Z****+B?????<@@@@@@@@@@@@@@@@@@@@@@@@@@@b');
  3465                 colorMapFromArray:#[ 0 0 0 255 255 255 170 170 170 127 127 127 ];
  3466                 mask:((ImageMask new)
  3467                             width:20;
  3468                             height:16;
  3469                             bits:(ByteArray 
  3470                                         fromPackedString:'@@@@@@@@???0???0???0???0???0???0???0???0???0???0???0@@@@@@@@@@@@');
  3471                             yourself);
  3472                 yourself
  3473         ]
  3474 !
  3475 
  3476 iconSliceMenu
  3477     <resource: #image>
  3478     "This resource specification was automatically generated
  3479      by the ImageEditor of ST/X."
  3480     "Do not manually edit this!! If it is corrupted,
  3481      the ImageEditor may not be able to read the specification."
  3482     "
  3483      self iconSliceMenu inspect
  3484      ImageEditor openOnClass:self andSelector:#iconSliceMenu
  3485      Icon flushCachedIcons"
  3486     
  3487     ^ Icon constantNamed:'MenuEditor::Item class iconSliceMenu'
  3488         ifAbsentPut:[
  3489             (Depth2Image new)
  3490                 width:20;
  3491                 height:16;
  3492                 photometric:(#palette);
  3493                 bitsPerSample:(#( 2 ));
  3494                 samplesPerPixel:(1);
  3495                 bits:(ByteArray 
  3496                             fromPackedString:'@@@@@@@@@@@@@@@@@@@@O?????0:*****C/?6??XN:*[*) ;*).*&C.*&:*XN5U[UU :*****C*****(@@@@@@@@@@@@@@@@@@@@@@@@@@@b');
  3497                 colorMapFromArray:#[ 0 0 0 127 127 127 170 170 170 255 255 255 ];
  3498                 mask:((ImageMask new)
  3499                             width:20;
  3500                             height:16;
  3501                             bits:(ByteArray 
  3502                                         fromPackedString:'@@@@@@@@???0???0???0???0???0???0???0???0???0???0???0@@@@@@@@@@@@');
  3503                             yourself);
  3504                 yourself
  3505         ]
  3506 ! !
  3507 
  3508 !MenuEditor::Item class methodsFor:'instance creation'!
  3509 
  3510 classFor:aMenuItem
  3511 
  3512     aMenuItem isNil ifTrue:[ ^ nil ].
  3513 
  3514     aMenuItem itemValue isNil ifTrue:[
  3515 	aMenuItem isMenuSlice ifTrue:[ ^ MenuEditor::MenuSliceItem ].
  3516 	aMenuItem submenu notNil ifTrue:[ ^ MenuEditor::RegularMenuItem ].
  3517 	aMenuItem submenuChannel notNil ifTrue:[ ^ MenuEditor::LinkedMenuItem ].
  3518 
  3519 	(self separatorTypeOf:(aMenuItem rawLabel)) notNil ifTrue:[
  3520 	    ^ MenuEditor::SeparatorItem
  3521 	]
  3522     ].
  3523     ^ MenuEditor::ActionItem
  3524 !
  3525 
  3526 menuItem:aMenuItem
  3527     |item cls|
  3528 
  3529     cls := self classFor:aMenuItem.
  3530     cls isNil ifTrue:[^ nil].
  3531 
  3532     item := cls new.
  3533     item menuItem:aMenuItem.
  3534     ^ item
  3535 ! !
  3536 
  3537 !MenuEditor::Item class methodsFor:'interface specs'!
  3538 
  3539 detailsEditSpec
  3540     "This resource specification was automatically generated
  3541      by the UIPainter of ST/X."
  3542 
  3543     "Do not manually edit this!! If it is corrupted,
  3544      the UIPainter may not be able to read the specification."
  3545 
  3546     "
  3547      UIPainter new openOnClass:MenuEditor::Item andSelector:#detailsEditSpec
  3548     "
  3549 
  3550     <resource: #canvas>
  3551 
  3552     ^
  3553      #(FullSpec
  3554 	name: detailsEditSpec
  3555 	window:
  3556        (WindowSpec
  3557 	  label: 'Details Edit'
  3558 	  name: 'Details Edit'
  3559 	  min: (Point 10 10)
  3560 	  bounds: (Rectangle 0 0 407 291)
  3561 	)
  3562 	component:
  3563        (SpecCollection
  3564 	  collection: (
  3565 	   (LabelSpec
  3566 	      label: 'Accelerator:'
  3567 	      name: 'shortcutKeyLabel'
  3568 	      layout: (AlignmentOrigin 107 0 26 0 1 0.5)
  3569 	      activeHelpKey: detailsAccelerator
  3570 	      translateLabel: true
  3571 	      resizeForLabel: true
  3572 	      adjust: right
  3573 	    )
  3574 	   (InputFieldSpec
  3575 	      name: 'shortcutKeyField'
  3576 	      layout: (LayoutFrame 110 0 15 0 -5 1.0 37 0)
  3577 	      activeHelpKey: detailsAccelerator
  3578 	      tabable: true
  3579 	      model: shortcutKeyCharacter
  3580 	      group: inputGroup
  3581 	      type: symbolOrNil
  3582 	      immediateAccept: false
  3583 	      acceptOnReturn: true
  3584 	      acceptOnTab: true
  3585 	      acceptChannel: acceptChannel
  3586 	      modifiedChannel: modifiedChannel
  3587 	      acceptOnPointerLeave: false
  3588 	    )
  3589 	   (LabelSpec
  3590 	      label: 'Enabled:'
  3591 	      name: 'enabledLabel'
  3592 	      layout: (AlignmentOrigin 107 0 51 0 1 0.5)
  3593 	      activeHelpKey: detailsEnabled
  3594 	      translateLabel: true
  3595 	      resizeForLabel: true
  3596 	      adjust: right
  3597 	    )
  3598 	   (InputFieldSpec
  3599 	      name: 'enabledField'
  3600 	      layout: (LayoutFrame 110 0 40 0 -25 1.0 62 0)
  3601 	      activeHelpKey: detailsEnabled
  3602 	      tabable: true
  3603 	      model: enabled
  3604 	      group: inputGroup
  3605 	      type: symbolOrBooleanOrNil
  3606 	      immediateAccept: false
  3607 	      acceptOnReturn: true
  3608 	      acceptOnTab: true
  3609 	      acceptChannel: acceptChannel
  3610 	      modifiedChannel: modifiedChannel
  3611 	      acceptOnPointerLeave: false
  3612 	    )
  3613 	   (ActionButtonSpec
  3614 	      label: 'browseActionImage'
  3615 	      name: 'Button1'
  3616 	      layout: (LayoutFrame -25 1 40 0 -5 1 62 0)
  3617 	      activeHelpKey: browseMethod
  3618 	      hasCharacterOrientedLabel: false
  3619 	      translateLabel: true
  3620 	      resizeForLabel: true
  3621 	      tabable: true
  3622 	      model: doBrowseEnabledMethod
  3623 	    )
  3624 	   (LabelSpec
  3625 	      label: 'Visibility:'
  3626 	      name: 'visibilityLabel'
  3627 	      layout: (AlignmentOrigin 107 0 76 0 1 0.5)
  3628 	      activeHelpKey: detailsVisibility
  3629 	      translateLabel: true
  3630 	      resizeForLabel: true
  3631 	      adjust: right
  3632 	    )
  3633 	   (InputFieldSpec
  3634 	      name: 'isVisibleInputField'
  3635 	      layout: (LayoutFrame 110 0 65 0 -25 1.0 87 0)
  3636 	      activeHelpKey: detailsVisibility
  3637 	      tabable: true
  3638 	      model: isVisible
  3639 	      group: inputGroup
  3640 	      type: symbolOrBooleanOrNil
  3641 	      immediateAccept: false
  3642 	      acceptOnReturn: true
  3643 	      acceptOnTab: true
  3644 	      acceptChannel: acceptChannel
  3645 	      modifiedChannel: modifiedChannel
  3646 	      acceptOnPointerLeave: false
  3647 	    )
  3648 	   (ActionButtonSpec
  3649 	      label: 'browseActionImage'
  3650 	      name: 'Button2'
  3651 	      layout: (LayoutFrame -25 1 65 0 -5 1 87 0)
  3652 	      activeHelpKey: browseMethod
  3653 	      hasCharacterOrientedLabel: false
  3654 	      translateLabel: true
  3655 	      resizeForLabel: true
  3656 	      tabable: true
  3657 	      model: doBrowseVisibilityMethod
  3658 	    )
  3659 	   (LabelSpec
  3660 	      label: 'Aux Value'
  3661 	      name: 'auxLabel'
  3662 	      layout: (AlignmentOrigin 107 0 101 0 1 0.5)
  3663 	      activeHelpKey: detailsAuxValue
  3664 	      translateLabel: true
  3665 	      resizeForLabel: true
  3666 	      adjust: right
  3667 	    )
  3668 	   (InputFieldSpec
  3669 	      name: 'auxInputField'
  3670 	      layout: (LayoutFrame 110 0 90 0 -5 1.0 112 0)
  3671 	      activeHelpKey: detailsAuxValue
  3672 	      tabable: true
  3673 	      model: auxValue
  3674 	      group: inputGroup
  3675 	      type: smalltalkObjectOrNil
  3676 	      immediateAccept: false
  3677 	      acceptOnReturn: true
  3678 	      acceptOnTab: true
  3679 	      acceptChannel: acceptChannel
  3680 	      modifiedChannel: modifiedChannel
  3681 	      acceptOnPointerLeave: false
  3682 	    )
  3683 	   (LabelSpec
  3684 	      label: 'Start Group:'
  3685 	      name: 'StartGroupLabel'
  3686 	      layout: (AlignmentOrigin 107 0 139 0 1 0.5)
  3687 	      activeHelpKey: detailsStartGroup
  3688 	      translateLabel: true
  3689 	      resizeForLabel: true
  3690 	      adjust: right
  3691 	    )
  3692 	   (PopUpListSpec
  3693 	      label: 'left'
  3694 	      name: 'StartGroupPopUp'
  3695 	      layout: (LayoutFrame 110 0 128 0 -5 1.0 150 0)
  3696 	      activeHelpKey: detailsStartGroup
  3697 	      tabable: true
  3698 	      model: startGroup
  3699 	      menu:
  3700 	     (Array
  3701 		left right
  3702 		conditionalRight
  3703 	      )
  3704 	    )
  3705 	   (LabelSpec
  3706 	      label: 'Access Character Position:'
  3707 	      name: 'accessCharLabel'
  3708 	      layout: (AlignmentOrigin 217 0 170 0 1 0.5)
  3709 	      translateLabel: true
  3710 	      resizeForLabel: true
  3711 	      adjust: right
  3712 	    )
  3713 	   (InputFieldSpec
  3714 	      name: 'accessCharField'
  3715 	      layout: (LayoutFrame 220 0 159 0 -5 1.0 181 0)
  3716 	      activeHelpKey: detailsAccessCharaterPosition
  3717 	      tabable: true
  3718 	      model: accessCharacterPosition
  3719 	      group: inputGroup
  3720 	      type: numberOrNil
  3721 	      immediateAccept: false
  3722 	      acceptOnReturn: true
  3723 	      acceptOnTab: true
  3724 	      acceptChannel: acceptChannel
  3725 	      modifiedChannel: modifiedChannel
  3726 	      acceptOnPointerLeave: false
  3727 	    )
  3728 	   (CheckBoxSpec
  3729 	      label: 'Ignore Accelerator (i.e. Display Only)'
  3730 	      name: 'ignoreShortcutKeysInItem'
  3731 	      layout: (AlignmentOrigin 42 0 204 0 0 0.5)
  3732 	      activeHelpKey: detailsIgnoreAcceleratorKeys
  3733 	      visibilityChannel: hasNoSubmenu
  3734 	      model: ignoreShortcutKeys
  3735 	      translateLabel: true
  3736 	      resizeForLabel: true
  3737 	    )
  3738 	   (CheckBoxSpec
  3739 	      label: 'Ignore Accelerators in Submenu'
  3740 	      name: 'ignoreShortcutKeys'
  3741 	      layout: (AlignmentOrigin 42 0 204 0 0 0.5)
  3742 	      activeHelpKey: detailsIgnoreAcceleratorKeys
  3743 	      visibilityChannel: hasSubmenu
  3744 	      model: ignoreShortcutKeys
  3745 	      translateLabel: true
  3746 	      resizeForLabel: true
  3747 	    )
  3748 	   (CheckBoxSpec
  3749 	      label: 'Ignore Mnemonics in Submenu'
  3750 	      name: 'ignoreMnemonicKeys'
  3751 	      layout: (AlignmentOrigin 42 0 232 0 0 0.5)
  3752 	      activeHelpKey: detailsIgnoreMnemonicKeys
  3753 	      visibilityChannel: hasSubmenu
  3754 	      model: ignoreMnemonicKeys
  3755 	      translateLabel: true
  3756 	      resizeForLabel: true
  3757 	    )
  3758 	   (LabelSpec
  3759 	      label: 'Font:'
  3760 	      name: 'fontLabel'
  3761 	      layout: (AlignmentOrigin 107 0 271 0 1 0.5)
  3762 	      translateLabel: true
  3763 	      resizeForLabel: true
  3764 	      adjust: right
  3765 	    )
  3766 	   (FontMenuSpec
  3767 	      name: 'fontMenu'
  3768 	      layout: (LayoutFrame 110 0 260 0 -5 1.0 282 0)
  3769 	      activeHelpKey: fontMenu
  3770 	      model: font
  3771 	      allowSymbolicFonts: true
  3772 	    )
  3773 	   )
  3774 
  3775 	)
  3776       )
  3777 
  3778     "Modified: / 21-10-2010 / 14:15:09 / cg"
  3779 ! !
  3780 
  3781 !MenuEditor::Item class methodsFor:'interface-editor'!
  3782 
  3783 addBindingsTo:aspects for:aMenuEditor
  3784     "add additional bindings to the aspects
  3785     "
  3786     aspects at:#notDelayedMenu ifAbsentPut:[true asValue].
  3787     aspects at:#hasSubmenu ifAbsentPut:[false asValue].
  3788     aspects at:#hasNoSubmenu ifAbsentPut:[true asValue].
  3789 ! !
  3790 
  3791 !MenuEditor::Item class methodsFor:'testing'!
  3792 
  3793 separatorTypeOf:aString
  3794     |size first|
  3795 
  3796     size := aString size.
  3797 
  3798     size == 0 ifTrue:[ ^ #blank ].
  3799 
  3800     size == 1 ifTrue:[
  3801 	first := aString first.
  3802 	first == $-                ifTrue:[ ^ #single ].
  3803 	first == $=                ifTrue:[ ^ #double ].
  3804 	first == (Character space) ifTrue:[ ^ #blank  ].
  3805     ].
  3806     ^ nil
  3807 ! !
  3808 
  3809 !MenuEditor::Item methodsFor:'accessing'!
  3810 
  3811 children
  3812     "optimize access; do not ask the model for unspecified children
  3813     "
  3814     ^ children
  3815 !
  3816 
  3817 hasMenuIndicator:aBoolean
  3818     menuItem hasMenuIndicator:aBoolean
  3819 
  3820     "Created: / 09-08-2018 / 17:03:06 / Claus Gittinger"
  3821 !
  3822 
  3823 menuItem
  3824      "returns self as a MenuItem
  3825     "
  3826     ^ MenuItem decodeFromLiteralArray:(menuItem literalArrayEncoding).
  3827 
  3828     "Modified: / 27-03-2007 / 08:43:14 / cg"
  3829 !
  3830 
  3831 menuItem:aMenuItem
  3832     "rebuild self from a MenuItem
  3833     "
  3834     |value|
  3835 
  3836     menuItem := MenuItem label:(self rawLabel).
  3837 
  3838     MenuEditor aspects do:[:aKey|
  3839         value := self validateValue:(aMenuItem perform:aKey).
  3840 
  3841         value notNil ifTrue:[
  3842             self aspectAt:aKey put:value.
  3843         ].
  3844     ].
  3845 !
  3846 
  3847 rawLabel
  3848     "returns the label assigned to the item
  3849     "
  3850     ^ menuItem rawLabel
  3851 !
  3852 
  3853 rawLabel:aValue
  3854     "set the label assigned to the item
  3855     "
  3856     aValue isString ifTrue:[
  3857 	"/ KLUDGE alarm: '-' and '' indicate a separator
  3858 	"/ (there is no separate menuItem class for them)
  3859 
  3860 	(self isKindOfMenu or:[(self class separatorTypeOf:aValue) isNil]) ifTrue:[
  3861 	    menuItem rawLabel:aValue
  3862 	]
  3863     ].
  3864 !
  3865 
  3866 slices
  3867     "returns a sequence of supported slices
  3868     "
  3869     ^ self subclassResponsibility
  3870 !
  3871 
  3872 submenu
  3873     "returns the submenu (of class Menu) or nil
  3874     "
  3875     ^ nil
  3876 !
  3877 
  3878 translateLabel:aBoolean
  3879     menuItem translateLabel:aBoolean
  3880 ! !
  3881 
  3882 !MenuEditor::Item methodsFor:'aspects'!
  3883 
  3884 aspectAt:aKey put:aValue
  3885     "set a specific aspect named aKey to the aValue"
  3886 
  3887     aKey == #rawLabel       ifTrue:[ ^ self rawLabel:aValue ].
  3888     aKey == #submenuChannel ifTrue:[ ^ self ].
  3889     menuItem perform:(aKey asMutator) with:aValue.
  3890 
  3891     "Modified: / 05-09-2006 / 17:47:19 / cg"
  3892 !
  3893 
  3894 fromAspects:aspects
  3895     "read values from aspects
  3896     "
  3897     MenuEditor aspects do:[:aKey|
  3898 	self aspectAt:aKey put:((aspects at:aKey) value).
  3899     ].
  3900     self validateMenuItem.
  3901     self changed.
  3902 !
  3903 
  3904 toAspects:aspects
  3905     "write values to aspects
  3906     "
  3907     MenuEditor aspects do:[:aKey|
  3908 	(aspects at:aKey) value:(menuItem perform:aKey)
  3909     ].
  3910     (aspects at:#notDelayedMenu) value:(self isDelayedMenu not).
  3911     (aspects at:#hasSubmenu)     value:(self isKindOfMenu or:[self children size ~~ 0]).
  3912     (aspects at:#hasNoSubmenu)   value:(self isKindOfMenu not ).
  3913 !
  3914 
  3915 validateMenuItem
  3916     "validate the menuItem for correctness"
  3917 
  3918     menuItem isNil ifTrue:[^ self].
  3919 
  3920     menuItem choice isEmptyOrNil ifTrue:[
  3921 	menuItem choice:nil.
  3922 	menuItem choiceValue:nil.
  3923     ].
  3924 ! !
  3925 
  3926 !MenuEditor::Item methodsFor:'displaying'!
  3927 
  3928 displayLabel
  3929     "returns the label on default displayed on the screen
  3930     "
  3931     ^ menuItem rawLabel
  3932 !
  3933 
  3934 displayOn:aGC x:x y:y h:h isHighlightedAsSelected:isHighlightedAsSelected
  3935     "display the item in the graphicsContext, aGC"
  3936 
  3937     |label|
  3938 
  3939     label := self displayLabel.
  3940 
  3941     label notNil ifTrue:[
  3942         self displayLabel:label h:(self heightOn:aGC) on:aGC x:x y:y h:h isHighlightedAsSelected:isHighlightedAsSelected
  3943     ].
  3944 !
  3945 
  3946 heightOn:aGC
  3947     "returns the height of the label on a GC
  3948     "
  3949     height isNil ifTrue:[ height := parent heightOn:aGC ].
  3950     ^ height
  3951 !
  3952 
  3953 label
  3954     "get the rawLabel assigned to the item
  3955     "
  3956     ^ menuItem rawLabel
  3957 !
  3958 
  3959 label:aLabel
  3960     "set the rawLabel assigned to the item
  3961     "
  3962     self rawLabel:aLabel
  3963 !
  3964 
  3965 widthOn:aGC
  3966     "returns the height of the displayLabel on a GC
  3967     "
  3968     width isNil ifTrue:[ width := self widthOf:(self displayLabel) on:aGC ].
  3969     ^ width
  3970 ! !
  3971 
  3972 !MenuEditor::Item methodsFor:'initialization'!
  3973 
  3974 initialize
  3975     <modifier: #super> "must be called if redefined"
  3976 
  3977     super initialize.
  3978     menuItem := MenuItem label:(self class defaultLabel).
  3979 
  3980     "Modified: / 08-02-2017 / 00:28:44 / cg"
  3981 ! !
  3982 
  3983 !MenuEditor::Item methodsFor:'private'!
  3984 
  3985 validateValue:aValue
  3986     "if we pick a menupanel, the values of an item can be
  3987      a block model, ....
  3988     "
  3989     aValue notNil ifTrue:[
  3990 	aValue isBlock      ifTrue:[ ^ #block ].
  3991 	aValue isValueModel ifTrue:[ ^ #valueModel ].
  3992     ].
  3993     ^ aValue
  3994 ! !
  3995 
  3996 !MenuEditor::Item methodsFor:'queries'!
  3997 
  3998 isAction
  3999     "returns true if the item is an Action
  4000     "
  4001     ^ false
  4002 !
  4003 
  4004 isDelayedMenu
  4005     "returns true if the item is a Delayed (Linked) Menu
  4006     "
  4007     ^ parent isAction
  4008 !
  4009 
  4010 isKindOfLinkedMenu
  4011     "returns true if the item is a Linked Menu
  4012     "
  4013     ^ false
  4014 !
  4015 
  4016 isKindOfMenu
  4017     "returns true if the item is a Linked Menu or Menu
  4018     "
  4019     ^ false
  4020 !
  4021 
  4022 isKindOfNonLinkedMenu
  4023     "returns true if the item is a Linked Menu
  4024     "
  4025     ^ false
  4026 !
  4027 
  4028 isMenuEditItem
  4029     ^ true
  4030 !
  4031 
  4032 isRootItem
  4033     "returns true if the item is the root item
  4034     "
  4035     ^ false
  4036 ! !
  4037 
  4038 !MenuEditor::Item methodsFor:'queries-editor'!
  4039 
  4040 actionSelectors
  4041     "return my action selectors"
  4042 
  4043     |value|
  4044 
  4045     value := menuItem value.
  4046     value isSymbol ifTrue:[ ^ Array with:value ].
  4047     ^ #()
  4048 !
  4049 
  4050 aspectSelectors
  4051     "return my aspect selectors"
  4052 
  4053     |aspects|
  4054 
  4055     aspects := OrderedCollection new.
  4056 
  4057     #( indication choice enabled isVisible ) do:[:aKey| |sel|
  4058 	sel := menuItem perform:aKey.
  4059 	sel isSymbol ifTrue:[ aspects add:sel ]
  4060     ].
  4061     ^ aspects
  4062 ! !
  4063 
  4064 !MenuEditor::Item methodsFor:'queries-operation'!
  4065 
  4066 canAddChildren
  4067     "returns true if children can be added
  4068     "
  4069     ^ false
  4070 !
  4071 
  4072 canAddDelayedMenu
  4073     "returns true if a delayed menu can be added;
  4074      on default false is returned
  4075     "
  4076     ^ false
  4077 !
  4078 
  4079 canMoveInAbove
  4080     "returns true if the item can become a child of its previous sibling
  4081     "
  4082     |siblings index nextItem|
  4083 
  4084     siblings := parent children.
  4085     siblings size > 1 ifFalse:[ ^ false ].
  4086 
  4087     index    := siblings identityIndexOf:self.
  4088     nextItem := siblings at:(index - 1)  ifAbsent:nil.
  4089 
  4090     nextItem isNil ifTrue:[^ false].
  4091     ^ nextItem canAddChildren
  4092 !
  4093 
  4094 canMoveInNext
  4095     "returns true if the item can become a child of its next sibling
  4096     "
  4097     |siblings index nextItem|
  4098 
  4099     siblings := parent children.
  4100     siblings size > 1 ifFalse:[ ^ false ].
  4101 
  4102     index    := siblings identityIndexOf:self.
  4103     nextItem := siblings at:(index + 1)  ifAbsent:nil.
  4104 
  4105     nextItem isNil ifTrue:[^ false].
  4106     ^ nextItem canAddChildren
  4107 !
  4108 
  4109 canMoveOut
  4110     "returns true if the item can be moved out from its current parent
  4111     "
  4112     self   isDelayedMenu ifTrue:[^ false].
  4113     parent isDelayedMenu ifTrue:[^ false].
  4114 
  4115   ^ parent parent notNil
  4116 !
  4117 
  4118 canMoveUpOrDown
  4119     "returns true if the item can change its vertical order in its sibling
  4120     "
  4121     ^ parent children size > 1
  4122 ! !
  4123 
  4124 !MenuEditor::ImageResourceEditor class methodsFor:'interface specs'!
  4125 
  4126 windowSpec
  4127     "This resource specification was automatically generated
  4128      by the UIPainter of ST/X."
  4129 
  4130     "Do not manually edit this!! If it is corrupted,
  4131      the UIPainter may not be able to read the specification."
  4132 
  4133     "
  4134      UIPainter new openOnClass:MenuEditor::ImageResourceEditor andSelector:#windowSpec
  4135      MenuEditor::ImageResourceEditor new openInterface:#windowSpec
  4136      MenuEditor::ImageResourceEditor open
  4137     "
  4138 
  4139     <resource: #canvas>
  4140 
  4141     ^
  4142      #(FullSpec
  4143 	name: windowSpec
  4144 	window:
  4145        (WindowSpec
  4146 	  label: 'Image Item'
  4147 	  name: 'Image Item'
  4148 	  min: (Point 10 10)
  4149 	  bounds: (Rectangle 0 0 303 304)
  4150 	)
  4151 	component:
  4152        (SpecCollection
  4153 	  collection: (
  4154 	   (LabelSpec
  4155 	      label: 'Retriever:'
  4156 	      name: 'retrieverLabel'
  4157 	      layout: (AlignmentOrigin 107 0 26 0 1 0.5)
  4158 	      activeHelpKey: imageRetriever
  4159 	      translateLabel: true
  4160 	      resizeForLabel: true
  4161 	      adjust: right
  4162 	    )
  4163 	   (ComboBoxSpec
  4164 	      name: 'retrieverHolder'
  4165 	      layout: (LayoutFrame 110 0 15 0 -2 1.0 37 0)
  4166 	      activeHelpKey: imageRetriever
  4167 	      tabable: true
  4168 	      model: retrieverHolder
  4169 	      type: symbolOrNil
  4170 	      immediateAccept: true
  4171 	      acceptOnReturn: false
  4172 	      acceptOnTab: false
  4173 	      acceptOnPointerLeave: false
  4174 	      entryCompletionBlock: entryCompletionForRetriever
  4175 	      comboList: retrieverList
  4176 	      isFilenameBox: false
  4177 	    )
  4178 	   (LabelSpec
  4179 	      label: 'Selector:'
  4180 	      name: 'iconLabel'
  4181 	      layout: (AlignmentOrigin 107 0 51 0 1 0.5)
  4182 	      activeHelpKey: imageSelector
  4183 	      translateLabel: true
  4184 	      resizeForLabel: true
  4185 	      adjust: right
  4186 	    )
  4187 	   (InputFieldSpec
  4188 	      name: 'selectorHolder'
  4189 	      layout: (LayoutFrame 110 0 40 0 -24 1.0 62 0)
  4190 	      activeHelpKey: imageSelector
  4191 	      tabable: true
  4192 	      model: selectorHolder
  4193 	      group: inputGroup
  4194 	      type: symbolOrNil
  4195 	      immediateAccept: true
  4196 	      acceptOnReturn: false
  4197 	      acceptOnTab: false
  4198 	      modifiedChannel: modifiedChannel
  4199 	      acceptOnPointerLeave: false
  4200 	    )
  4201 	   (ActionButtonSpec
  4202 	      label: '...'
  4203 	      name: 'browseButton'
  4204 	      layout: (LayoutFrame -22 1 40 0 -2 1 62 0)
  4205 	      activeHelpKey: browseResource
  4206 	      tabable: true
  4207 	      model: doBrowseForImageResource
  4208 	    )
  4209 	   (DividerSpec
  4210 	      name: 'Separator1'
  4211 	      layout: (LayoutFrame 0 0.0 66 0 0 1.0 70 0)
  4212 	    )
  4213 	   (ViewSpec
  4214 	      name: 'SelectorFilterBox2'
  4215 	      layout: (LayoutFrame 0 0.0 74 0 0 1.0 96 0)
  4216 	      activeHelpKey: selectorFilter
  4217 	      component:
  4218 	     (SpecCollection
  4219 		collection: (
  4220 		 (LabelSpec
  4221 		    label: 'Filter:'
  4222 		    name: 'Label1'
  4223 		    layout: (AlignmentOrigin 107 0 11 0 1 0.5)
  4224 		    activeHelpKey: selectorFilter
  4225 		    translateLabel: true
  4226 		    resizeForLabel: true
  4227 		    adjust: right
  4228 		  )
  4229 		 (InputFieldSpec
  4230 		    name: 'EntryField1'
  4231 		    layout: (LayoutFrame 110 0 0 0 -2 1 22 0)
  4232 		    model: selectorFilterHolder
  4233 		    immediateAccept: true
  4234 		    acceptOnLeave: true
  4235 		    acceptOnReturn: false
  4236 		    acceptOnTab: false
  4237 		    acceptOnPointerLeave: false
  4238 		    activeHelpKey: selectorFilter
  4239 		  )
  4240 		 )
  4241 
  4242 	      )
  4243 	    )
  4244 	   (HierarchicalListViewSpec
  4245 	      name: 'imageList'
  4246 	      layout: (LayoutFrame 2 0.0 100 0 -2 1.0 -60 1.0)
  4247 	      activeHelpKey: imageImageList
  4248 	      model: imageHolder
  4249 	      menu: menuEditImage
  4250 	      hasHorizontalScrollBar: true
  4251 	      hasVerticalScrollBar: true
  4252 	      miniScrollerHorizontal: true
  4253 	      listModel: imageList
  4254 	      useIndex: false
  4255 	      highlightMode: label
  4256 	      postBuildCallback: postBuildImageViewer:
  4257 	    )
  4258 	   (ViewSpec
  4259 	      name: 'Box1'
  4260 	      layout: (LayoutFrame 20 0.0 -60 1.0 -20 1.0 0 1.0)
  4261 	      level: 0
  4262 	      component:
  4263 	     (SpecCollection
  4264 		collection: (
  4265 		 (CheckBoxSpec
  4266 		    label: 'Image & Label'
  4267 		    name: 'iconAndLabelCheckBox'
  4268 		    layout: (AlignmentOrigin 0 0 17 0 0 0.5)
  4269 		    activeHelpKey: imageImageAndLabel
  4270 		    tabable: true
  4271 		    model: iconAndLabelHolder
  4272 		    translateLabel: true
  4273 		  )
  4274 		 (ActionButtonSpec
  4275 		    label: 'Image Editor'
  4276 		    name: 'imageEditorButton'
  4277 		    layout: (AlignmentOrigin -69 1.0 17 0 0 0.5)
  4278 		    activeHelpKey: imageImageEditor
  4279 		    hasCharacterOrientedLabel: false
  4280 		    foregroundColor: (Color 0.0 0.0 66.9993133440146)
  4281 		    tabable: true
  4282 		    model: doEditImage
  4283 		  )
  4284 		 (ActionButtonSpec
  4285 		    label: 'Browse'
  4286 		    name: 'Button1'
  4287 		    layout: (AlignmentOrigin -69 1.0 41 0 0 0.5)
  4288 		    activeHelpKey: imageBrowseImageClass
  4289 		    hasCharacterOrientedLabel: false
  4290 		    foregroundColor: (Color 0.0 0.0 66.9993133440146)
  4291 		    tabable: true
  4292 		    model: doBrowseImageClass
  4293 		  )
  4294 		 )
  4295 
  4296 	      )
  4297 	    )
  4298 	   )
  4299 
  4300 	)
  4301       )
  4302 
  4303     "Modified: / 03-08-2011 / 10:16:13 / cg"
  4304 ! !
  4305 
  4306 !MenuEditor::ImageResourceEditor methodsFor:'accessing'!
  4307 
  4308 resourceRetriever
  4309     |rcv sel cls clsName|
  4310 
  4311     sel := selectorHolder value.
  4312     sel size == 0 ifTrue:[ ^ nil ].
  4313     cls := self retrieverClass.
  4314     cls notNil ifTrue:[
  4315 	clsName := retrieverHolder value.
  4316 	clsName isEmptyOrNil ifTrue:[
  4317 	    clsName := cls name.
  4318 	].
  4319 	clsName := clsName asSymbol.
  4320     ].
  4321 
  4322     rcv := ResourceRetriever new.
  4323     rcv className:clsName.
  4324     rcv selector:sel.
  4325 
  4326     iconAndLabelHolder value ifTrue:[ rcv labelText:'' ].
  4327     ^ rcv
  4328 !
  4329 
  4330 resourceRetriever:aResourceRetriever
  4331     |className sel isOn|
  4332 
  4333     aResourceRetriever notNil ifTrue:[
  4334 	className := aResourceRetriever className.
  4335 	className isBehavior ifTrue:[
  4336 	    className := className name asSymbol
  4337 	].
  4338 	sel  := aResourceRetriever selector.
  4339 	isOn := aResourceRetriever labelText notNil.
  4340     ] ifFalse:[
  4341 	className := sel := nil.
  4342 	isOn := false.
  4343     ].
  4344 
  4345     retrieverHolder value:className.
  4346     selectorHolder  value:sel.
  4347     iconAndLabelHolder value:isOn.
  4348 !
  4349 
  4350 retrieverClass
  4351     |clsName cls|
  4352 
  4353     clsName  := retrieverHolder value.
  4354     clsName notEmptyOrNil ifTrue:[
  4355 	cls := Smalltalk at:clsName ifAbsent:nil.
  4356 	(cls isBehavior) ifTrue:[
  4357 	    ^ cls
  4358 	].
  4359     ].
  4360     ^ nil
  4361 ! !
  4362 
  4363 !MenuEditor::ImageResourceEditor methodsFor:'actions'!
  4364 
  4365 doBrowseForImageResource
  4366     "opens a browser on image-resource methods"
  4367 
  4368     |classAndSelector|
  4369 
  4370     classAndSelector := ResourceSelectionBrowser
  4371 		request:'Use Image From Class'
  4372 		onSuperclass:nil
  4373 		andClass:(self retrieverClass)
  4374 		andSelector:(selectorHolder value)
  4375 		withResourceTypes:#(image fileImage programImage).
  4376 
  4377     classAndSelector isNil ifTrue:[ ^ self ].
  4378 
  4379     retrieverHolder value:(classAndSelector methodClass) name.
  4380     selectorHolder  value:(classAndSelector methodSelector).
  4381 !
  4382 
  4383 doBrowseImageClass
  4384     |cls sel image|
  4385 
  4386     (cls := retrieverHolder value) isNil ifTrue:[
  4387         Dialog warn:'No resource retriever is defined.'.
  4388     ] ifFalse:[
  4389         sel := selectorHolder value.
  4390 
  4391         cls := Smalltalk classNamed:cls.
  4392         cls isNil ifTrue:[
  4393             Dialog warn:'No such resource retriever class.'.
  4394         ] ifFalse:[
  4395             (cls respondsTo:#visualFor:) ifTrue:[
  4396                 Error handle:[:ex |
  4397                     self warn:'The class seems to not understand #',sel.
  4398                 ] do:[
  4399                     image := cls visualFor:sel.
  4400                 ].
  4401                 (image notNil and:[image ~~ (cls perform:sel ifNotUnderstood:nil)]) ifTrue:[
  4402                     self warn:'The image as returned by #visualFor: is probably provided by another class.\\Showing all implementors of #',sel.
  4403                     "/ sel := #visualFor:.
  4404                     SystemBrowser default browseImplementorsOf:sel.
  4405                     ^ self.
  4406                 ].
  4407             ].
  4408             SystemBrowser default openInClass:(cls class) selector:sel
  4409         ]
  4410     ]
  4411 
  4412     "Created: / 20-09-2010 / 13:27:34 / cg"
  4413     "Modified: / 01-09-2017 / 14:21:02 / cg"
  4414     "Modified: / 08-07-2018 / 15:41:37 / Claus Gittinger"
  4415 !
  4416 
  4417 doEditImage
  4418     |sel cls item image|
  4419 
  4420     item := imageHolder value.
  4421     item notNil ifTrue:[
  4422 	item doEdit.
  4423 	^ self.
  4424     ].
  4425 
  4426     sel := selectorHolder value.
  4427     sel isNil ifTrue:[
  4428 	Dialog warn:'No selector is defined.'.
  4429 	^ self.
  4430     ].
  4431     cls := retrieverHolder value.
  4432     cls isNil ifTrue:[
  4433 	Dialog warn:'No resource retriever is defined.'.
  4434 	^ self.
  4435     ].
  4436     cls := Smalltalk classNamed:cls.
  4437     cls isNil ifTrue:[
  4438 	Dialog warn:'No such resource retriever class.'.
  4439 	^ self.
  4440     ].
  4441     (cls respondsTo:#visualFor:) ifTrue:[
  4442 	image := cls visualFor:sel.
  4443 	image ~~ (cls perform:sel ifNotUnderstood:nil) ifTrue:[
  4444 	    self warn:'The image is resolved via #visualFor: from some unknown class'.
  4445 	    image notNil ifTrue:[
  4446 		ImageEditor openOnImage:image.
  4447 	    ].
  4448 	    ^ self.
  4449 	].
  4450     ].
  4451 
  4452     ImageEditor openOnClass:cls andSelector:sel
  4453 ! !
  4454 
  4455 !MenuEditor::ImageResourceEditor methodsFor:'aspects'!
  4456 
  4457 entryCompletionForRetriever
  4458     ^ DoWhatIMeanSupport classNameEntryCompletionBlock.
  4459 
  4460     "Modified: / 10-08-2006 / 12:55:22 / cg"
  4461 !
  4462 
  4463 iconAndLabelHolder
  4464     ^ iconAndLabelHolder
  4465 !
  4466 
  4467 imageHolder
  4468     ^ imageHolder.
  4469 !
  4470 
  4471 imageList
  4472     ^ imageList
  4473 !
  4474 
  4475 modifiedChannel
  4476     ^ builder booleanValueAspectFor: #modifiedChannel
  4477 !
  4478 
  4479 modifiedChannel:aChannel
  4480     builder aspectAt:#modifiedChannel put:aChannel.
  4481 !
  4482 
  4483 retrieverHolder
  4484     ^ retrieverHolder
  4485 !
  4486 
  4487 retrieverList
  4488     |listOfClassNames cls owner|
  4489 
  4490     listOfClassNames := builder bindingAt:#retrieverList.
  4491     listOfClassNames isNil ifTrue:[
  4492         listOfClassNames := MenuEditor imageRetrieverClasses asList.
  4493         builder aspectAt:#retrieverList put:listOfClassNames.
  4494     ].
  4495     (masterApplication notNil
  4496      and:[(cls := masterApplication specClass) notNil]) ifTrue:[
  4497         (listOfClassNames includes:cls name) ifFalse:[ listOfClassNames addFirst:cls name ].
  4498         cls isPrivate ifTrue:[
  4499             (owner := cls owningClass) notNil ifTrue:[
  4500                 (listOfClassNames includes:owner name) ifFalse:[ listOfClassNames addFirst:owner name ].   
  4501             ].
  4502         ].
  4503     ].
  4504     ^ listOfClassNames
  4505 !
  4506 
  4507 selectorFilterHolder
  4508     ^ selectorFilterHolder
  4509 
  4510     "Created: / 03-08-2011 / 10:01:05 / cg"
  4511 !
  4512 
  4513 selectorHolder
  4514     ^ selectorHolder.
  4515 ! !
  4516 
  4517 !MenuEditor::ImageResourceEditor methodsFor:'change & update'!
  4518 
  4519 retrieverChanged
  4520     |retriever list name|
  4521 
  4522     retriever := self retrieverClass.
  4523     imageHolder setValue:nil.
  4524 
  4525     self updateImageList.
  4526     self updateSelectedImage.
  4527 
  4528     (retriever notNil and:[imageList size ~~ 0]) ifTrue:[
  4529 	list := self retrieverList.
  4530 	name := retriever name.
  4531 
  4532 	(list includes:name) ifFalse:[
  4533 	    list add:(name asSymbol).
  4534 	]
  4535     ].
  4536 
  4537     "Modified: / 03-08-2011 / 10:56:58 / cg"
  4538 !
  4539 
  4540 selectorChanged
  4541     self updateSelectedImage.
  4542 
  4543     "Modified: / 03-08-2011 / 10:56:04 / cg"
  4544 !
  4545 
  4546 selectorFilterChanged
  4547     self updateImageList.
  4548     self updateSelectedImage.
  4549 
  4550     "Created: / 03-08-2011 / 10:58:47 / cg"
  4551 !
  4552 
  4553 update:what with:aPara from:aModel
  4554     |item|
  4555 
  4556     self modifiedChannel value:true.
  4557 
  4558     aModel == retrieverHolder ifTrue:[ self retrieverChanged. ^ self ].
  4559     aModel == selectorHolder ifTrue:[ self selectorChanged. ^ self  ].
  4560     aModel == selectorFilterHolder ifTrue:[ self selectorFilterChanged. ^ self  ].
  4561 
  4562     aModel == imageHolder ifTrue:[
  4563 	item := imageHolder value.
  4564 	item notNil ifTrue:[
  4565 	    selectorHolder value:(item label)
  4566 	].
  4567 	^ self
  4568     ].
  4569     super update:what with:aPara from:aModel
  4570 
  4571     "Modified: / 29-11-2011 / 11:28:26 / cg"
  4572 !
  4573 
  4574 updateImageList
  4575     |retriever selectorFilterString filter|
  4576 
  4577     retriever := self retrieverClass.
  4578 
  4579     filter := [:sel | true].
  4580     (selectorFilterString := selectorFilterHolder value) notEmptyOrNil ifTrue:[
  4581         selectorFilterString includesMatchCharacters ifTrue:[
  4582             filter := [:sel | selectorFilterString match:sel caseSensitive:false].
  4583         ] ifFalse:[
  4584             filter := [:sel | sel includesString:selectorFilterString caseSensitive:false].
  4585         ].
  4586     ].
  4587 
  4588     imageList root updateFromClass:retriever selectorFilter:filter.
  4589 
  4590     "Created: / 03-08-2011 / 10:56:41 / cg"
  4591     "Modified: / 27-03-2017 / 12:54:00 / stefan"
  4592 !
  4593 
  4594 updateSelectedImage
  4595     "provider or selector has changed; select it in the list"
  4596 
  4597     |item selector line|
  4598 
  4599     imageList isEmpty ifTrue:[^ self].
  4600 
  4601     selector := selectorHolder value.
  4602     selector isEmptyOrNil ifTrue:[
  4603 	imageHolder value:nil.
  4604 	^ self
  4605     ].
  4606 
  4607     item     := nil.
  4608     selector := selector asSymbol.
  4609 
  4610     imageList do:[:anItem|
  4611 	|sel|
  4612 
  4613 	sel := anItem selector.
  4614 	selector == sel ifTrue:[
  4615 	    imageHolder value:anItem.
  4616 	    ^ self
  4617 	].
  4618 	item isNil ifTrue:[
  4619 	    (sel startsWith:selector) ifTrue:[ item := anItem ]
  4620 	]
  4621     ].
  4622     imageHolder value:nil.
  4623 
  4624     item notNil ifTrue:[
  4625 	line := imageList identityIndexOf:item.
  4626 	line ~~ 0 ifTrue:[
  4627 	    "/ imageListView scrollToLine:line
  4628 	    imageListView makeLineVisible:line
  4629 	]
  4630     ].
  4631 
  4632     "Created: / 03-08-2011 / 10:55:45 / cg"
  4633 ! !
  4634 
  4635 !MenuEditor::ImageResourceEditor methodsFor:'initialization'!
  4636 
  4637 initialize
  4638     super initialize.
  4639 
  4640     iconAndLabelHolder := true asValue.
  4641     iconAndLabelHolder addDependent:self.
  4642 
  4643     imageHolder := nil asValue.
  4644 
  4645     selectorHolder := nil asValue.
  4646     selectorHolder addDependent:self.
  4647 
  4648     imageList := HierarchicalList new.
  4649     imageList application:self.
  4650     imageList root:(ImageResourceEditorItem new).
  4651     imageList showRoot:false.
  4652 
  4653     imageHolder := nil asValue.
  4654     imageHolder addDependent:self.
  4655 
  4656     retrieverHolder := nil asValue.
  4657     retrieverHolder addDependent:self.
  4658 
  4659     selectorFilterHolder := '' asValue.
  4660     selectorFilterHolder addDependent:self.
  4661 
  4662     "Modified: / 03-08-2011 / 10:18:46 / cg"
  4663 !
  4664 
  4665 postBuildImageViewer:aWidget
  4666     imageListView := aWidget.
  4667 ! !
  4668 
  4669 !MenuEditor::ImageResourceEditor::ImageResourceEditorItem methodsFor:'accessing'!
  4670 
  4671 icon
  4672     ^ icon
  4673 !
  4674 
  4675 label
  4676     ^ selector
  4677 !
  4678 
  4679 selector
  4680     ^ selector
  4681 ! !
  4682 
  4683 !MenuEditor::ImageResourceEditor::ImageResourceEditorItem methodsFor:'instance creation'!
  4684 
  4685 forClass:aClass selector:aSelector
  4686     |w h magnify iconOrSymbol|
  4687 
  4688     selector := aSelector asSymbol.
  4689     selector numArgs == 0 ifFalse:[^ self].
  4690 
  4691     "do what the ResourceRetriever will do"
  4692     (aClass respondsTo:#visualFor:) ifTrue:[
  4693 	iconOrSymbol := aClass visualFor:selector.
  4694     ].
  4695     iconOrSymbol isNil ifTrue:[
  4696 	iconOrSymbol := aClass perform:selector.
  4697     ].
  4698     iconOrSymbol isNil ifTrue:[^ self].
  4699 
  4700     iconOrSymbol isSymbol ifTrue:[
  4701 	icon := ToolbarIconLibrary perform:iconOrSymbol.
  4702     ] ifFalse:[
  4703 	icon := iconOrSymbol.
  4704     ].
  4705 
  4706     w := icon width.
  4707     h := icon height.
  4708 
  4709     w > 32 ifTrue:[
  4710 	magnify := 32 / w.
  4711 	h > 32 ifTrue:[ magnify := (32 / h) max:magnify ].
  4712     ] ifFalse:[
  4713 	h > 32 ifFalse:[^ self].
  4714 	magnify := 32 / h.
  4715     ].
  4716     icon := icon magnifiedBy: magnify.
  4717 
  4718     "Modified: / 13-04-2011 / 18:56:45 / cg"
  4719     "Created: / 03-08-2011 / 10:47:16 / cg"
  4720 !
  4721 
  4722 initialize
  4723     <modifier: #super> "must be called if redefined"
  4724 
  4725     super initialize.
  4726     children := #().
  4727 
  4728     "Modified: / 08-02-2017 / 00:28:37 / cg"
  4729 !
  4730 
  4731 updateFromClass:aClass selectorFilter:aFilterBlock
  4732     (aClass notNil and:[aClass isBehavior]) ifFalse:[
  4733         ^ self collapse.
  4734     ].
  4735 "/    aClass == selector ifTrue:[
  4736 "/        ^ self expand
  4737 "/    ].
  4738     self collapse.
  4739 
  4740     selector := aClass.
  4741 
  4742     self application withWaitCursorDo:[
  4743         |methods|
  4744         methods := aClass methodsWithAnyResource:#(image programImage).
  4745         children := methods 
  4746                         select:[:each| aFilterBlock value:each selector]
  4747                         thenCollect:[:each|
  4748                                 |item|
  4749                                 item := self class new forClass:aClass selector:each selector.
  4750                                 item parent:self.
  4751                         ].
  4752 
  4753         children sort:[:a :b | a label < b label ].
  4754         self expand
  4755     ].
  4756 
  4757     "Created: / 03-08-2011 / 10:48:10 / cg"
  4758 ! !
  4759 
  4760 !MenuEditor::ImageResourceEditor::ImageResourceEditorItem methodsFor:'user operations'!
  4761 
  4762 doEdit
  4763     "open image browser on self"
  4764 
  4765     |parent aClass image|
  4766 
  4767     parent := self parent.
  4768     parent notNil ifTrue:[
  4769 	aClass := parent selector.
  4770 	(aClass respondsTo:#visualFor:) ifTrue:[
  4771 	    image := aClass visualFor:selector.
  4772 	    image ~~ (aClass perform:selector) ifTrue:[
  4773 		self warn:'The image is resolved via #visualFor: from some unknown class'.
  4774 		ImageEditor openOnImage:image.
  4775 		^ self.
  4776 	    ].
  4777 	].
  4778 	ImageEditor openOnClass:aClass andSelector:selector.
  4779     ].
  4780 ! !
  4781 
  4782 !MenuEditor::ActionItem class methodsFor:'defaults'!
  4783 
  4784 defaultLabel
  4785     ^ 'Action'
  4786 ! !
  4787 
  4788 !MenuEditor::ActionItem class methodsFor:'interface specs'!
  4789 
  4790 basicsEditSpec
  4791     "This resource specification was automatically generated
  4792      by the UIPainter of ST/X."
  4793 
  4794     "Do not manually edit this!! If it is corrupted,
  4795      the UIPainter may not be able to read the specification."
  4796 
  4797     "
  4798      UIPainter new openOnClass:MenuEditor::ActionItem andSelector:#basicsEditSpec
  4799     "
  4800 
  4801     <resource: #canvas>
  4802 
  4803     ^ 
  4804      #(FullSpec
  4805         name: basicsEditSpec
  4806         window: 
  4807        (WindowSpec
  4808           label: 'basicsEditSpec'
  4809           name: 'basicsEditSpec'
  4810           min: (Point 10 10)
  4811           bounds: (Rectangle 0 0 340 340)
  4812         )
  4813         component: 
  4814        (SpecCollection
  4815           collection: (
  4816            (LabelSpec
  4817               label: 'Name Key:'
  4818               name: 'nameKeyLabel'
  4819               layout: (AlignmentOrigin 107 0 25 0 1 0.5)
  4820               activeHelpKey: basicsKey
  4821               translateLabel: true
  4822               resizeForLabel: true
  4823               adjust: right
  4824             )
  4825            (InputFieldSpec
  4826               name: 'nameKeyField'
  4827               layout: (LayoutFrame 110 0 15 0 -5 1.0 37 0)
  4828               activeHelpKey: basicsKey
  4829               tabable: true
  4830               model: nameKey
  4831               group: inputGroup
  4832               type: symbolOrNil
  4833               immediateAccept: false
  4834               acceptOnLeave: false
  4835               acceptOnReturn: true
  4836               acceptOnTab: true
  4837               acceptOnLostFocus: false
  4838               acceptChannel: acceptChannel
  4839               modifiedChannel: modifiedChannel
  4840               acceptOnPointerLeave: false
  4841             )
  4842            (LabelSpec
  4843               label: 'Label:'
  4844               name: 'labelLabel'
  4845               layout: (AlignmentOrigin 107 0 51 0 1 0.5)
  4846               activeHelpKey: basicsLabel
  4847               translateLabel: true
  4848               resizeForLabel: true
  4849               adjust: right
  4850             )
  4851            (InputFieldSpec
  4852               name: 'labelField'
  4853               layout: (LayoutFrame 110 0 40 0 -5 1.0 62 0)
  4854               activeHelpKey: basicsLabel
  4855               tabable: true
  4856               model: rawLabel
  4857               group: inputGroup
  4858               immediateAccept: false
  4859               acceptOnReturn: true
  4860               acceptOnTab: true
  4861               acceptOnLostFocus: false
  4862               acceptChannel: acceptChannel
  4863               modifiedChannel: modifiedChannel
  4864               acceptOnPointerLeave: false
  4865             )
  4866            (LabelSpec
  4867               label: 'Action:'
  4868               name: 'valueLabel'
  4869               layout: (AlignmentOrigin 107 0 82 0 1 0.5)
  4870               activeHelpKey: basicsAction
  4871               translateLabel: true
  4872               resizeForLabel: true
  4873               adjust: right
  4874             )
  4875            (InputFieldSpec
  4876               name: 'valueField'
  4877               layout: (LayoutFrame 110 0 71 0 -25 1.0 93 0)
  4878               activeHelpKey: basicsAction
  4879               tabable: true
  4880               model: itemValue
  4881               group: inputGroup
  4882               type: symbolOrNil
  4883               immediateAccept: false
  4884               acceptOnLeave: true
  4885               acceptOnReturn: true
  4886               acceptOnTab: true
  4887               acceptOnLostFocus: true
  4888               acceptChannel: acceptChannel
  4889               modifiedChannel: modifiedChannel
  4890               acceptOnPointerLeave: true
  4891             )
  4892            (ActionButtonSpec
  4893               label: 'browseActionImage'
  4894               name: 'Button1'
  4895               layout: (LayoutFrame -25 1 71 0 -5 1 93 0)
  4896               activeHelpKey: browseMethod
  4897               hasCharacterOrientedLabel: false
  4898               translateLabel: true
  4899               resizeForLabel: true
  4900               tabable: true
  4901               model: doBrowseActionMethod
  4902             )
  4903            (LabelSpec
  4904               label: 'Argument:'
  4905               name: 'argumentLabel'
  4906               layout: (AlignmentOrigin 107 0 107 0 1 0.5)
  4907               activeHelpKey: basicsArgument
  4908               translateLabel: true
  4909               resizeForLabel: true
  4910               adjust: right
  4911             )
  4912            (InputFieldSpec
  4913               name: 'argumentField'
  4914               layout: (LayoutFrame 110 0 96 0 -5 1.0 118 0)
  4915               activeHelpKey: basicsArgument
  4916               tabable: true
  4917               model: argument
  4918               group: inputGroup
  4919               type: smalltalkObjectOrNil
  4920               immediateAccept: false
  4921               acceptOnReturn: true
  4922               acceptOnTab: true
  4923               acceptOnLostFocus: false
  4924               acceptChannel: acceptChannel
  4925               modifiedChannel: modifiedChannel
  4926               acceptOnPointerLeave: false
  4927             )
  4928            (LabelSpec
  4929               label: 'Indication:'
  4930               name: 'indicationLabel'
  4931               layout: (AlignmentOrigin 107 0 138 0 1 0.5)
  4932               activeHelpKey: basicsIndication
  4933               translateLabel: true
  4934               resizeForLabel: true
  4935               adjust: right
  4936             )
  4937            (InputFieldSpec
  4938               name: 'indicationField'
  4939               layout: (LayoutFrame 110 0 127 0 -25 1.0 149 0)
  4940               activeHelpKey: basicsIndication
  4941               enableChannel: indicationEnabled
  4942               tabable: true
  4943               model: indication
  4944               group: inputGroup
  4945               type: symbolOrNil
  4946               immediateAccept: true
  4947               acceptOnReturn: false
  4948               acceptOnTab: false
  4949               acceptOnLostFocus: false
  4950               modifiedChannel: modifiedChannel
  4951               acceptOnPointerLeave: false
  4952             )
  4953            (ActionButtonSpec
  4954               label: 'browseActionImage'
  4955               name: 'Button2'
  4956               layout: (LayoutFrame -25 1 127 0 -5 1 149 0)
  4957               activeHelpKey: browseMethod
  4958               hasCharacterOrientedLabel: false
  4959               translateLabel: true
  4960               resizeForLabel: true
  4961               tabable: true
  4962               model: doBrowseIndicationMethod
  4963             )
  4964            (LabelSpec
  4965               label: 'Choice:'
  4966               name: 'choiceLabel'
  4967               layout: (AlignmentOrigin 107 0 163 0 1 0.5)
  4968               activeHelpKey: basicsChoice
  4969               translateLabel: true
  4970               resizeForLabel: true
  4971               adjust: right
  4972             )
  4973            (InputFieldSpec
  4974               name: 'choiceField'
  4975               layout: (LayoutFrame 110 0 152 0 -25 1.0 174 0)
  4976               activeHelpKey: basicsChoice
  4977               enableChannel: choiceEnabled
  4978               tabable: true
  4979               model: choice
  4980               group: inputGroup
  4981               type: symbolOrNil
  4982               immediateAccept: true
  4983               acceptOnReturn: false
  4984               acceptOnTab: false
  4985               acceptOnLostFocus: false
  4986               modifiedChannel: modifiedChannel
  4987               acceptOnPointerLeave: false
  4988             )
  4989            (ActionButtonSpec
  4990               label: 'browseActionImage'
  4991               name: 'Button3'
  4992               layout: (LayoutFrame -25 1 152 0 -5 1 174 0)
  4993               activeHelpKey: browseMethod
  4994               hasCharacterOrientedLabel: false
  4995               translateLabel: true
  4996               resizeForLabel: true
  4997               tabable: true
  4998               model: doBrowseChoiceMethod
  4999             )
  5000            (LabelSpec
  5001               label: 'Value:'
  5002               name: 'choiceValueLabel'
  5003               layout: (AlignmentOrigin 107 0 188 0 1 0.5)
  5004               activeHelpKey: basicsChoiceValue
  5005               translateLabel: true
  5006               resizeForLabel: true
  5007               adjust: right
  5008             )
  5009            (InputFieldSpec
  5010               name: 'choiceValueField'
  5011               layout: (LayoutFrame 110 0 177 0 -5 1.0 199 0)
  5012               activeHelpKey: basicsChoiceValue
  5013               enableChannel: choiceValueEnabled
  5014               tabable: true
  5015               model: choiceValue
  5016               group: inputGroup
  5017               type: smalltalkObjectOrNil
  5018               immediateAccept: false
  5019               acceptOnLeave: false
  5020               acceptOnReturn: true
  5021               acceptOnTab: true
  5022               acceptOnLostFocus: false
  5023               acceptChannel: acceptChannel
  5024               modifiedChannel: modifiedChannel
  5025               acceptOnPointerLeave: false
  5026             )
  5027            (CheckBoxSpec
  5028               label: 'Translate Label'
  5029               name: 'translateLabelCheckBox'
  5030               layout: (AlignmentOrigin 7 0 213 0 0 0)
  5031               activeHelpKey: basicsTranslateLabel
  5032               tabable: true
  5033               model: translateLabel
  5034               translateLabel: true
  5035             )
  5036            (CheckBoxSpec
  5037               label: 'Is Button'
  5038               name: 'isButtonCheckBox'
  5039               layout: (AlignmentOrigin 7 0 238 0 0 0)
  5040               activeHelpKey: basicsIsButton
  5041               tabable: true
  5042               model: isButton
  5043               translateLabel: true
  5044             )
  5045            (CheckBoxSpec
  5046               label: 'Hide Menu after Activation'
  5047               name: 'hideMenuOnActivated'
  5048               layout: (AlignmentOrigin 7 0 263 0 0 0)
  5049               activeHelpKey: hideMenuOnActivated
  5050               tabable: true
  5051               model: hideMenuOnActivated
  5052               translateLabel: true
  5053             )
  5054            (CheckBoxSpec
  5055               label: 'BusyCursor while Active'
  5056               name: 'showBusyCursorWhilePerforming'
  5057               layout: (AlignmentOrigin 7 0 288 0 0 0)
  5058               activeHelpKey: showBusyCursorWhilePerforming
  5059               tabable: true
  5060               model: showBusyCursorWhilePerforming
  5061               translateLabel: true
  5062             )
  5063            (CheckBoxSpec
  5064               label: 'Trigger on Down'
  5065               name: 'triggerOnDown'
  5066               layout: (AlignmentOrigin 25 0.5 238 0 0 0)
  5067               activeHelpKey: triggerOnDown
  5068               enableChannel: hasNoDelayedMenuValue
  5069               tabable: true
  5070               model: triggerOnDown
  5071               translateLabel: true
  5072             )
  5073            (CheckBoxSpec
  5074               label: 'Send to Originating Widget'
  5075               name: 'sendToOriginator'
  5076               layout: (AlignmentOrigin 7 0 313 0 0 0)
  5077               activeHelpKey: sendToOriginator
  5078               enableChannel: hasItemValue
  5079               tabable: true
  5080               model: sendToOriginator
  5081               translateLabel: true
  5082             )
  5083            )
  5084          
  5085         )
  5086       )
  5087 ! !
  5088 
  5089 !MenuEditor::ActionItem class methodsFor:'interface-editor'!
  5090 
  5091 addBindingsTo:aspects for:aMenuEditor
  5092     "add additional bindings to the aspects
  5093     "
  5094     aspects
  5095 	at:#indicationEnabled
  5096 	ifAbsentPut:[ BlockValue with:[:a | a size == 0 ] argument:(aspects at:#choice)].
  5097 
  5098     aspects
  5099 	at:#choiceEnabled
  5100 	ifAbsentPut:[ BlockValue with:[:a | a size == 0 ] argument:(aspects at:#indication)].
  5101 
  5102     aspects
  5103 	at:#choiceValueEnabled
  5104 	ifAbsentPut:[ BlockValue with:[:a | a size ~~ 0 ] argument:(aspects at:#choice)].
  5105 
  5106     aspects
  5107 	at:#hasNoDelayedMenuValue
  5108 	ifAbsentPut:[true asValue].
  5109 ! !
  5110 
  5111 !MenuEditor::ActionItem methodsFor:'accessing'!
  5112 
  5113 menuItem
  5114     |item|
  5115 
  5116     item := super menuItem.
  5117     self hasDelayedMenu ifTrue:[
  5118 	children first setDelayedAttributesTo:item.
  5119 
  5120 	menuItem value isNil ifTrue:[
  5121 	    menuItem value:#unspecified
  5122 	]
  5123     ].
  5124     ^ item
  5125 !
  5126 
  5127 menuItem:anItem
  5128     |submenu item|
  5129 
  5130     super menuItem:anItem.
  5131     submenu := anItem submenu.
  5132 
  5133     submenu notNil ifTrue:[
  5134 	item := MenuEditor::RegularMenuItem new
  5135     ] ifFalse:[
  5136 	anItem submenuChannel isNil ifTrue:[
  5137 	    ^ self
  5138 	].
  5139 	item := MenuEditor::LinkedMenuItem new
  5140     ].
  5141     item getDelayedAttributesFrom:anItem.
  5142     self add:item.
  5143 !
  5144 
  5145 slices
  5146     ^ #(
  5147 	    (Basics   basicsEditSpec )
  5148 	    (Details  detailsEditSpec)
  5149 	    (Image    image  )
  5150 	    (Help     help)
  5151        )
  5152 ! !
  5153 
  5154 !MenuEditor::ActionItem methodsFor:'adding & removing'!
  5155 
  5156 add:anItem
  5157     "add an item; test whether the item is a delayed menu and
  5158      not already a delayed menu exists."
  5159 
  5160     (anItem isKindOfMenu and:[ self canAddDelayedMenu ]) ifFalse:[
  5161 	^ nil
  5162     ].
  5163 
  5164     menuItem triggerOnDown:false.
  5165     anItem argument:(menuItem argument).
  5166     isExpanded := false.
  5167     anItem parent:self.
  5168     children := Array with:anItem.
  5169     self expand.
  5170     ^ anItem
  5171 
  5172     "Modified: / 05-09-2006 / 17:49:57 / cg"
  5173 ! !
  5174 
  5175 !MenuEditor::ActionItem methodsFor:'aspects'!
  5176 
  5177 aspectAt:aKey put:aValue
  5178     "set a specific aspect named aKey to the aValue"
  5179 
  5180     aKey == #argument ifTrue:[
  5181 	self hasDelayedMenu ifTrue:[
  5182 	    children first argument:aValue
  5183 	].
  5184 	menuItem argument:aValue.
  5185 	^ self
  5186     ].
  5187 
  5188     aKey == #triggerOnDown ifTrue:[
  5189 	|triggerOnDown|
  5190 
  5191 	self hasDelayedMenu ifTrue:[
  5192 	    triggerOnDown := false
  5193 	] ifFalse:[
  5194 	    triggerOnDown := aValue
  5195 	].
  5196 	menuItem triggerOnDown:triggerOnDown.
  5197 	^ self.
  5198     ].
  5199     super aspectAt:aKey put:aValue.
  5200 
  5201     "Modified: / 05-09-2006 / 17:47:24 / cg"
  5202 !
  5203 
  5204 toAspects:aspects
  5205     "write values to aspects
  5206     "
  5207     |hasDelayedMenu|
  5208 
  5209     super toAspects:aspects.
  5210 
  5211     hasDelayedMenu := self hasDelayedMenu.
  5212     (aspects at:#hasNoDelayedMenuValue) value:(hasDelayedMenu not).
  5213 
  5214     hasDelayedMenu ifTrue:[
  5215 	(aspects at:#triggerOnDown) value:false
  5216     ].
  5217 ! !
  5218 
  5219 !MenuEditor::ActionItem methodsFor:'displaying'!
  5220 
  5221 icon
  5222     ^ self class iconItem
  5223 ! !
  5224 
  5225 !MenuEditor::ActionItem methodsFor:'initialization'!
  5226 
  5227 initialize
  5228     <modifier: #super> "must be called if redefined"
  5229 
  5230     super initialize.
  5231     isExpanded := true.
  5232 
  5233     "Modified: / 08-02-2017 / 00:28:28 / cg"
  5234 ! !
  5235 
  5236 !MenuEditor::ActionItem methodsFor:'queries'!
  5237 
  5238 canCollapse
  5239     ^ false
  5240 !
  5241 
  5242 hasDelayedMenu
  5243     "returns true if a delayed menu exists
  5244     "
  5245     ^ children size ~~ 0
  5246 !
  5247 
  5248 hasIndicator
  5249     ^ false
  5250 !
  5251 
  5252 isAction
  5253     ^ true
  5254 ! !
  5255 
  5256 !MenuEditor::ActionItem methodsFor:'queries-operation'!
  5257 
  5258 canAddDelayedMenu
  5259     "returns true if a delayed menu can be added
  5260     "
  5261     ^ self hasDelayedMenu not
  5262 ! !
  5263 
  5264 !MenuEditor::LinkedMenuItem class methodsFor:'defaults'!
  5265 
  5266 defaultLabel
  5267     ^ 'Linked Menu'
  5268 ! !
  5269 
  5270 !MenuEditor::LinkedMenuItem class methodsFor:'interface specs'!
  5271 
  5272 basicsEditSpec
  5273     "This resource specification was automatically generated
  5274      by the UIPainter of ST/X."
  5275 
  5276     "Do not manually edit this!! If it is corrupted,
  5277      the UIPainter may not be able to read the specification."
  5278 
  5279     "
  5280      UIPainter new openOnClass:MenuEditor::LinkedMenuItem andSelector:#basicsEditSpec
  5281     "
  5282 
  5283     <resource: #canvas>
  5284 
  5285     ^
  5286      #(FullSpec
  5287 	name: basicsEditSpec
  5288 	window:
  5289        (WindowSpec
  5290 	  label: 'basicsEditSpec'
  5291 	  name: 'basicsEditSpec'
  5292 	  min: (Point 10 10)
  5293 	  bounds: (Rectangle 0 0 340 340)
  5294 	)
  5295 	component:
  5296        (SpecCollection
  5297 	  collection: (
  5298 	   (LabelSpec
  5299 	      label: 'Name Key:'
  5300 	      name: 'nameKeyLabel'
  5301 	      layout: (AlignmentOrigin 107 0 25 0 1 0.5)
  5302 	      activeHelpKey: basicsKey
  5303 	      visibilityChannel: notDelayedMenu
  5304 	      translateLabel: true
  5305 	      resizeForLabel: true
  5306 	      adjust: right
  5307 	    )
  5308 	   (InputFieldSpec
  5309 	      name: 'nameKeyField'
  5310 	      layout: (LayoutFrame 110 0 15 0 -5 1.0 37 0)
  5311 	      activeHelpKey: basicsKey
  5312 	      visibilityChannel: notDelayedMenu
  5313 	      tabable: true
  5314 	      model: nameKey
  5315 	      group: inputGroup
  5316 	      type: symbolOrNil
  5317 	      immediateAccept: false
  5318 	      acceptOnLeave: false
  5319 	      acceptOnReturn: true
  5320 	      acceptOnTab: true
  5321 	      acceptOnLostFocus: false
  5322 	      acceptChannel: acceptChannel
  5323 	      modifiedChannel: modifiedChannel
  5324 	      acceptOnPointerLeave: false
  5325 	    )
  5326 	   (LabelSpec
  5327 	      label: 'Label:'
  5328 	      name: 'labelLabel'
  5329 	      layout: (AlignmentOrigin 107 0 51 0 1 0.5)
  5330 	      activeHelpKey: basicsLabel
  5331 	      visibilityChannel: notDelayedMenu
  5332 	      translateLabel: true
  5333 	      resizeForLabel: true
  5334 	      adjust: right
  5335 	    )
  5336 	   (InputFieldSpec
  5337 	      name: 'labelField'
  5338 	      layout: (LayoutFrame 110 0 40 0 -5 1.0 62 0)
  5339 	      activeHelpKey: basicsLabel
  5340 	      visibilityChannel: notDelayedMenu
  5341 	      tabable: true
  5342 	      model: rawLabel
  5343 	      group: inputGroup
  5344 	      immediateAccept: false
  5345 	      acceptOnReturn: true
  5346 	      acceptOnTab: true
  5347 	      acceptOnLostFocus: false
  5348 	      acceptChannel: acceptChannel
  5349 	      modifiedChannel: modifiedChannel
  5350 	      acceptOnPointerLeave: false
  5351 	    )
  5352 	   (LabelSpec
  5353 	      label: 'Menu:'
  5354 	      name: 'menuLabel'
  5355 	      layout: (AlignmentOrigin 107 0 90 0 1 0.5)
  5356 	      activeHelpKey: basicsLabel
  5357 	      translateLabel: true
  5358 	      resizeForLabel: true
  5359 	      adjust: right
  5360 	    )
  5361 	   (InputFieldSpec
  5362 	      name: 'menuField'
  5363 	      layout: (LayoutFrame 110 0 79 0 -5 1.0 101 0)
  5364 	      activeHelpKey: basicsMenu
  5365 	      tabable: true
  5366 	      model: submenuChannel
  5367 	      group: inputGroup
  5368 	      type: symbolOrNil
  5369 	      immediateAccept: false
  5370 	      acceptOnReturn: true
  5371 	      acceptOnTab: true
  5372 	      acceptOnLostFocus: false
  5373 	      acceptChannel: acceptChannel
  5374 	      modifiedChannel: modifiedChannel
  5375 	      acceptOnPointerLeave: false
  5376 	    )
  5377 	   (LabelSpec
  5378 	      label: 'Argument:'
  5379 	      name: 'argumentLabel'
  5380 	      layout: (AlignmentOrigin 107 0 115 0 1 0.5)
  5381 	      activeHelpKey: basicsLabel
  5382 	      translateLabel: true
  5383 	      resizeForLabel: true
  5384 	      adjust: right
  5385 	    )
  5386 	   (InputFieldSpec
  5387 	      name: 'argumentField'
  5388 	      layout: (LayoutFrame 110 0 104 0 -5 1.0 126 0)
  5389 	      activeHelpKey: basicsMenuArgument
  5390 	      enableChannel: notDelayedMenu
  5391 	      tabable: true
  5392 	      model: argument
  5393 	      group: inputGroup
  5394 	      type: smalltalkObjectOrNil
  5395 	      immediateAccept: false
  5396 	      acceptOnReturn: true
  5397 	      acceptOnTab: true
  5398 	      acceptOnLostFocus: false
  5399 	      acceptChannel: acceptChannel
  5400 	      modifiedChannel: modifiedChannel
  5401 	      acceptOnPointerLeave: false
  5402 	    )
  5403 	   (CheckBoxSpec
  5404 	      label: 'Translate Label'
  5405 	      name: 'translateLabelCheckBox'
  5406 	      layout: (Point 20 213)
  5407 	      activeHelpKey: basicsTranslateLabel
  5408 	      visibilityChannel: notDelayedMenu
  5409 	      tabable: true
  5410 	      model: translateLabel
  5411 	      translateLabel: true
  5412 	    )
  5413 	   (CheckBoxSpec
  5414 	      label: 'Is Button'
  5415 	      name: 'isButtonCheckBox'
  5416 	      layout: (Point 20 238)
  5417 	      activeHelpKey: basicsIsButton
  5418 	      visibilityChannel: notDelayedMenu
  5419 	      tabable: true
  5420 	      model: isButton
  5421 	      translateLabel: true
  5422 	    )
  5423 	   (CheckBoxSpec
  5424 	      label: 'Horizontal Layout'
  5425 	      name: 'horizontalLayout'
  5426 	      layout: (Point 20 263)
  5427 	      activeHelpKey: horizontalLayout
  5428 	      tabable: true
  5429 	      model: horizontalLayout
  5430 	      translateLabel: true
  5431 	    )
  5432 	   (CheckBoxSpec
  5433 	      label: 'Do not Destroy Linked Menu'
  5434 	      name: 'keepLinkedMenu'
  5435 	      layout: (Point 20 288)
  5436 	      activeHelpKey: keepLinkedMenu
  5437 	      tabable: true
  5438 	      model: keepLinkedMenu
  5439 	      translateLabel: true
  5440 	    )
  5441 	   )
  5442 
  5443 	)
  5444       )
  5445 ! !
  5446 
  5447 !MenuEditor::LinkedMenuItem methodsFor:'accessing'!
  5448 
  5449 argument:aValue
  5450     menuItem argument:aValue.
  5451 !
  5452 
  5453 menuItem
  5454      "returns self as a MenuItem
  5455     "
  5456     |item|
  5457 
  5458     item := super menuItem.
  5459     item submenuChannel:(self submenuChannel).
  5460   ^ item
  5461 !
  5462 
  5463 slices
  5464     self isDelayedMenu ifTrue:[
  5465 	^ #(
  5466 		(Basics   basicsEditSpec )
  5467 	   )
  5468     ].
  5469 
  5470     ^ #(
  5471 	    (Basics   basicsEditSpec )
  5472 	    (Details  detailsEditSpec)
  5473 	    (Image    image  )
  5474 	    (Help     help)
  5475        )
  5476 ! !
  5477 
  5478 !MenuEditor::LinkedMenuItem methodsFor:'accessing-channels'!
  5479 
  5480 submenuChannel
  5481     ^ menuItem submenuChannel ? #unspecified
  5482 !
  5483 
  5484 submenuChannel:aValue
  5485     menuItem submenuChannel:aValue.
  5486 ! !
  5487 
  5488 !MenuEditor::LinkedMenuItem methodsFor:'aspects'!
  5489 
  5490 aspectAt:aKey put:aValue
  5491     "set a specific aspect named aKey to the aValue"
  5492 
  5493     aKey == #submenuChannel ifTrue:[ ^ self submenuChannel:aValue ].
  5494     super aspectAt:aKey put:aValue.
  5495 
  5496     "Modified: / 05-09-2006 / 17:47:39 / cg"
  5497 !
  5498 
  5499 getDelayedAttributesFrom:anItem
  5500 
  5501     menuItem rawLabel:'Delayed'.
  5502 
  5503     menuItem   submenuChannel:(self validateValue:(anItem submenuChannel)).
  5504     menuItem horizontalLayout:(self validateValue:(anItem horizontalLayout)).
  5505     menuItem   keepLinkedMenu:(self validateValue:(anItem keepLinkedMenu)).
  5506 !
  5507 
  5508 setDelayedAttributesTo:aMenuItem
  5509     aMenuItem   submenuChannel:(self submenuChannel).
  5510     aMenuItem horizontalLayout:(menuItem horizontalLayout).
  5511     aMenuItem   keepLinkedMenu:(menuItem keepLinkedMenu).
  5512 ! !
  5513 
  5514 !MenuEditor::LinkedMenuItem methodsFor:'displaying'!
  5515 
  5516 displayLabel
  5517     "returns the label dependent on is delayed or not
  5518     "
  5519     self isDelayedMenu ifTrue:[ ^ self submenuChannel ].
  5520   ^ menuItem rawLabel
  5521 !
  5522 
  5523 icon
  5524     self isDelayedMenu ifTrue:[ ^ self class iconDelayedLinkedMenu ].
  5525   ^ self class iconLinkedMenu
  5526 ! !
  5527 
  5528 !MenuEditor::LinkedMenuItem methodsFor:'initialization'!
  5529 
  5530 initialize
  5531     "setup default values on the item"
  5532 
  5533     <modifier: #super> "must be called if redefined"
  5534 
  5535     super initialize.
  5536 
  5537     "setting default values
  5538     "
  5539     "/ CG: Thu, 08 May 2008 11:16:54 GMT
  5540     "/     I think having keepLinkedMenu true by default
  5541     "/     will confuse newcomers (even me occasionally)
  5542     "/     (will search, why the menu is not updated...)
  5543 
  5544     "/ menuItem keepLinkedMenu:true.
  5545     menuItem keepLinkedMenu:false.
  5546 
  5547     "Modified (comment): / 08-02-2017 / 00:29:14 / cg"
  5548 ! !
  5549 
  5550 !MenuEditor::LinkedMenuItem methodsFor:'queries'!
  5551 
  5552 isKindOfLinkedMenu
  5553     ^ true
  5554 !
  5555 
  5556 isKindOfMenu
  5557     ^ true
  5558 ! !
  5559 
  5560 !MenuEditor::MenuSliceItem class methodsFor:'defaults'!
  5561 
  5562 defaultLabel
  5563     ^ 'Menu Slice'
  5564 ! !
  5565 
  5566 !MenuEditor::MenuSliceItem class methodsFor:'interface specs'!
  5567 
  5568 basicsEditSpec
  5569     "This resource specification was automatically generated
  5570      by the UIPainter of ST/X."
  5571 
  5572     "Do not manually edit this!! If it is corrupted,
  5573      the UIPainter may not be able to read the specification."
  5574 
  5575     "
  5576      UIPainter new openOnClass:MenuEditor::MenuSliceItem andSelector:#basicsEditSpec
  5577     "
  5578 
  5579     <resource: #canvas>
  5580 
  5581     ^
  5582      #(FullSpec
  5583 	name: basicsEditSpec
  5584 	window:
  5585        (WindowSpec
  5586 	  label: 'basicsEditSpec'
  5587 	  name: 'basicsEditSpec'
  5588 	  min: (Point 10 10)
  5589 	  bounds: (Rectangle 0 0 344 146)
  5590 	)
  5591 	component:
  5592        (SpecCollection
  5593 	  collection: (
  5594 	   (LabelSpec
  5595 	      label: 'Name Key:'
  5596 	      name: 'nameKeyLabel'
  5597 	      layout: (AlignmentOrigin 107 0 25 0 1 0.5)
  5598 	      activeHelpKey: basicsKey
  5599 	      visibilityChannel: notDelayedMenu
  5600 	      translateLabel: true
  5601 	      resizeForLabel: true
  5602 	      adjust: right
  5603 	    )
  5604 	   (InputFieldSpec
  5605 	      name: 'nameKeyField'
  5606 	      layout: (LayoutFrame 110 0 15 0 -5 1.0 37 0)
  5607 	      activeHelpKey: basicsKey
  5608 	      visibilityChannel: notDelayedMenu
  5609 	      tabable: true
  5610 	      model: nameKey
  5611 	      group: inputGroup
  5612 	      type: symbolOrNil
  5613 	      immediateAccept: false
  5614 	      acceptOnLeave: false
  5615 	      acceptOnReturn: true
  5616 	      acceptOnTab: true
  5617 	      acceptOnLostFocus: false
  5618 	      acceptChannel: acceptChannel
  5619 	      modifiedChannel: modifiedChannel
  5620 	      acceptOnPointerLeave: false
  5621 	    )
  5622 	   (LabelSpec
  5623 	      label: 'Label:'
  5624 	      name: 'labelLabel'
  5625 	      layout: (AlignmentOrigin 107 0 51 0 1 0.5)
  5626 	      activeHelpKey: basicsLabel
  5627 	      visibilityChannel: notDelayedMenu
  5628 	      translateLabel: true
  5629 	      resizeForLabel: true
  5630 	      adjust: right
  5631 	    )
  5632 	   (InputFieldSpec
  5633 	      name: 'labelField'
  5634 	      layout: (LayoutFrame 110 0 40 0 -5 1.0 62 0)
  5635 	      activeHelpKey: basicsLabel
  5636 	      visibilityChannel: notDelayedMenu
  5637 	      tabable: true
  5638 	      model: rawLabel
  5639 	      group: inputGroup
  5640 	      immediateAccept: false
  5641 	      acceptOnReturn: true
  5642 	      acceptOnTab: true
  5643 	      acceptOnLostFocus: false
  5644 	      acceptChannel: acceptChannel
  5645 	      modifiedChannel: modifiedChannel
  5646 	      acceptOnPointerLeave: false
  5647 	    )
  5648 	   (LabelSpec
  5649 	      label: 'Menu:'
  5650 	      name: 'menuLabel'
  5651 	      layout: (AlignmentOrigin 107 0 90 0 1 0.5)
  5652 	      activeHelpKey: basicsLabel
  5653 	      translateLabel: true
  5654 	      resizeForLabel: true
  5655 	      adjust: right
  5656 	    )
  5657 	   (InputFieldSpec
  5658 	      name: 'menuField'
  5659 	      layout: (LayoutFrame 110 0 79 0 -5 1.0 101 0)
  5660 	      activeHelpKey: basicsMenu
  5661 	      tabable: true
  5662 	      model: submenuChannel
  5663 	      group: inputGroup
  5664 	      type: symbolOrNil
  5665 	      immediateAccept: false
  5666 	      acceptOnReturn: true
  5667 	      acceptOnTab: true
  5668 	      acceptOnLostFocus: false
  5669 	      acceptChannel: acceptChannel
  5670 	      modifiedChannel: modifiedChannel
  5671 	      acceptOnPointerLeave: false
  5672 	    )
  5673 	   (LabelSpec
  5674 	      label: 'Argument:'
  5675 	      name: 'argumentLabel'
  5676 	      layout: (AlignmentOrigin 107 0 115 0 1 0.5)
  5677 	      activeHelpKey: basicsLabel
  5678 	      translateLabel: true
  5679 	      resizeForLabel: true
  5680 	      adjust: right
  5681 	    )
  5682 	   (InputFieldSpec
  5683 	      name: 'argumentField'
  5684 	      layout: (LayoutFrame 110 0 104 0 -5 1.0 126 0)
  5685 	      activeHelpKey: basicsMenuArgument
  5686 	      enableChannel: notDelayedMenu
  5687 	      tabable: true
  5688 	      model: argument
  5689 	      group: inputGroup
  5690 	      type: smalltalkObjectOrNil
  5691 	      immediateAccept: false
  5692 	      acceptOnReturn: true
  5693 	      acceptOnTab: true
  5694 	      acceptOnLostFocus: false
  5695 	      acceptChannel: acceptChannel
  5696 	      modifiedChannel: modifiedChannel
  5697 	      acceptOnPointerLeave: false
  5698 	    )
  5699 	   )
  5700 
  5701 	)
  5702       )
  5703 ! !
  5704 
  5705 !MenuEditor::MenuSliceItem methodsFor:'accessing'!
  5706 
  5707 icon
  5708     ^ self class iconSliceMenu
  5709 !
  5710 
  5711 menuItem
  5712      "returns self as a MenuItem
  5713     "
  5714     |item|
  5715 
  5716     item := super menuItem.
  5717     item submenuChannel:(self submenuChannel).
  5718     item isMenuSlice:true.
  5719   ^ item
  5720 !
  5721 
  5722 slices
  5723     ^ #(
  5724 	    (Basics   basicsEditSpec)
  5725        )
  5726 ! !
  5727 
  5728 !MenuEditor::MenuSliceItem methodsFor:'aspects'!
  5729 
  5730 argument:aValue
  5731     menuItem argument:aValue.
  5732 !
  5733 
  5734 aspectAt:aKey put:aValue
  5735     "set a specific aspect named aKey to the aValue"
  5736 
  5737     aKey == #submenuChannel ifTrue:[ ^ self submenuChannel:aValue ].
  5738     aKey == #isSliceMenu    ifTrue:[ ^ self ].
  5739 
  5740     super aspectAt:aKey put:aValue.
  5741 
  5742     "Modified: / 05-09-2006 / 17:47:42 / cg"
  5743 !
  5744 
  5745 submenuChannel
  5746     ^ menuItem submenuChannel ? #unspecified
  5747 !
  5748 
  5749 submenuChannel:aValue
  5750     menuItem submenuChannel:aValue.
  5751 ! !
  5752 
  5753 !MenuEditor::RegularMenuItem class methodsFor:'defaults'!
  5754 
  5755 defaultDelayedLabel
  5756     ^ 'delayed'
  5757 !
  5758 
  5759 defaultLabel
  5760     ^ 'Menu'
  5761 ! !
  5762 
  5763 !MenuEditor::RegularMenuItem class methodsFor:'instance creation'!
  5764 
  5765 menu:aMenu labeled:aString
  5766     |item|
  5767 
  5768     item := self new.
  5769     item menu:aMenu labeled:aString.
  5770     ^ item
  5771 !
  5772 
  5773 menu:aMenu labeled:aString translateLabel:translateLabel
  5774     |item|
  5775 
  5776     item := self new.
  5777     item menu:aMenu labeled:aString.
  5778     item translateLabel:translateLabel.
  5779     ^ item
  5780 ! !
  5781 
  5782 !MenuEditor::RegularMenuItem class methodsFor:'interface specs'!
  5783 
  5784 basicsEditSpec
  5785     "This resource specification was automatically generated
  5786      by the UIPainter of ST/X."
  5787 
  5788     "Do not manually edit this!! If it is corrupted,
  5789      the UIPainter may not be able to read the specification."
  5790 
  5791     "
  5792      UIPainter new openOnClass:MenuEditor::RegularMenuItem andSelector:#basicsEditSpec
  5793     "
  5794 
  5795     <resource: #canvas>
  5796 
  5797     ^ 
  5798     #(FullSpec
  5799        name: basicsEditSpec
  5800        uuid: '62cf58f0-9bea-11e8-8c6e-b8f6b1108e05'
  5801        window: 
  5802       (WindowSpec
  5803          label: 'basicsEditSpec'
  5804          name: 'basicsEditSpec'
  5805          uuid: 'd6768940-9be5-11e8-8c6e-b8f6b1108e05'
  5806          min: (Point 10 10)
  5807          bounds: (Rectangle 0 0 340 340)
  5808        )
  5809        component: 
  5810       (SpecCollection
  5811          collection: (
  5812           (LabelSpec
  5813              label: 'Name Key:'
  5814              name: 'nameKeyLabel'
  5815              layout: (AlignmentOrigin 107 0 25 0 1 0.5)
  5816              activeHelpKey: basicsKey
  5817              uuid: 'd676e930-9be5-11e8-8c6e-b8f6b1108e05'
  5818              visibilityChannel: notDelayedMenu
  5819              translateLabel: true
  5820              resizeForLabel: true
  5821              adjust: right
  5822            )
  5823           (InputFieldSpec
  5824              name: 'nameKeyField'
  5825              layout: (LayoutFrame 110 0 15 0 -5 1.0 37 0)
  5826              activeHelpKey: basicsKey
  5827              uuid: 'd676ec64-9be5-11e8-8c6e-b8f6b1108e05'
  5828              visibilityChannel: notDelayedMenu
  5829              tabable: true
  5830              model: nameKey
  5831              group: inputGroup
  5832              type: symbolOrNil
  5833              immediateAccept: false
  5834              acceptOnLeave: false
  5835              acceptOnReturn: true
  5836              acceptOnTab: true
  5837              acceptOnLostFocus: false
  5838              acceptChannel: acceptChannel
  5839              modifiedChannel: modifiedChannel
  5840              acceptOnPointerLeave: false
  5841            )
  5842           (LabelSpec
  5843              label: 'Label:'
  5844              name: 'labelLabel'
  5845              layout: (AlignmentOrigin 107 0 51 0 1 0.5)
  5846              activeHelpKey: basicsLabel
  5847              uuid: 'd676effc-9be5-11e8-8c6e-b8f6b1108e05'
  5848              visibilityChannel: notDelayedMenu
  5849              translateLabel: true
  5850              resizeForLabel: true
  5851              adjust: right
  5852            )
  5853           (InputFieldSpec
  5854              name: 'labelField'
  5855              layout: (LayoutFrame 110 0 40 0 -5 1.0 62 0)
  5856              activeHelpKey: basicsLabel
  5857              uuid: 'd676f150-9be5-11e8-8c6e-b8f6b1108e05'
  5858              visibilityChannel: notDelayedMenu
  5859              tabable: true
  5860              model: rawLabel
  5861              group: inputGroup
  5862              immediateAccept: false
  5863              acceptOnReturn: true
  5864              acceptOnTab: true
  5865              acceptOnLostFocus: false
  5866              acceptChannel: acceptChannel
  5867              modifiedChannel: modifiedChannel
  5868              acceptOnPointerLeave: false
  5869            )
  5870           (VerticalPanelViewSpec
  5871              name: 'VerticalPanel1'
  5872              layout: (LayoutFrame 6 0 188 0 0 1 323 0)
  5873              uuid: 'd676f326-9be5-11e8-8c6e-b8f6b1108e05'
  5874              horizontalLayout: fit
  5875              verticalLayout: top
  5876              horizontalSpace: 3
  5877              verticalSpace: 3
  5878              component: 
  5879             (SpecCollection
  5880                collection: (
  5881                 (CheckBoxSpec
  5882                    label: 'Translate Label'
  5883                    name: 'translateLabelCheckBox'
  5884                    activeHelpKey: basicsTranslateLabel
  5885                    uuid: 'd676f54c-9be5-11e8-8c6e-b8f6b1108e05'
  5886                    visibilityChannel: notDelayedMenu
  5887                    tabable: true
  5888                    model: translateLabel
  5889                    translateLabel: true
  5890                    extent: (Point 334 30)
  5891                  )
  5892                 (CheckBoxSpec
  5893                    label: 'Is Button'
  5894                    name: 'isButtonCheckBox'
  5895                    activeHelpKey: basicsIsButton
  5896                    uuid: 'd676f786-9be5-11e8-8c6e-b8f6b1108e05'
  5897                    visibilityChannel: notDelayedMenu
  5898                    tabable: true
  5899                    model: isButton
  5900                    translateLabel: true
  5901                    extent: (Point 334 30)
  5902                  )
  5903                 (CheckBoxSpec
  5904                    label: 'Horizontal Layout'
  5905                    name: 'horizontalLayout'
  5906                    activeHelpKey: horizontalLayout
  5907                    uuid: 'd676f8d0-9be5-11e8-8c6e-b8f6b1108e05'
  5908                    tabable: true
  5909                    model: horizontalLayout
  5910                    translateLabel: true
  5911                    extent: (Point 334 30)
  5912                  )
  5913                 (CheckBoxSpec
  5914                    label: 'Force Menu Indicator'
  5915                    name: 'CheckBox1'
  5916                    activeHelpKey: forceMenuIndicator
  5917                    uuid: 'd676fa06-9be5-11e8-8c6e-b8f6b1108e05'
  5918                    tabable: true
  5919                    model: hasMenuIndicator
  5920                    translateLabel: true
  5921                    extent: (Point 334 30)
  5922                  )
  5923                 )
  5924               
  5925              )
  5926            )
  5927           )
  5928         
  5929        )
  5930      )
  5931 ! !
  5932 
  5933 !MenuEditor::RegularMenuItem methodsFor:'accessing'!
  5934 
  5935 argument:aValue
  5936     "/ ignorred.
  5937 !
  5938 
  5939 menu:aMenu labeled:aString
  5940     |expanded item menu|
  5941 
  5942     self synchronized:[
  5943         self isRootItem ifTrue:[ expanded := true ]
  5944                        ifFalse:[ expanded := isExpanded ].
  5945 
  5946         self removeAll.
  5947         self rawLabel:aString.
  5948 
  5949         menu := aMenu value.
  5950 
  5951         (menu isNil or:[menu isString]) ifTrue:[
  5952             menu := nil
  5953         ] ifFalse:[
  5954             aMenu isCollection ifTrue:[ menu := Menu decodeFromLiteralArray:aMenu ]
  5955                               ifFalse:[ menu := aMenu ].
  5956 
  5957             menu hasItems ifFalse:[
  5958                 menu := nil
  5959             ].
  5960         ].
  5961         menu notNil ifTrue:[
  5962             isExpanded := false.        "/ discard change notifications
  5963             children   := OrderedCollection new.
  5964 
  5965             menu itemsDo:[:el|
  5966                 item := self class menuItem:el.
  5967                 item parent:self.
  5968                 children add:item.
  5969             ].
  5970             expanded ifTrue:[ self expand ].
  5971         ].
  5972         isExpanded := expanded.
  5973     ].
  5974     self changed
  5975 
  5976     "Modified: / 29-11-2011 / 11:28:33 / cg"
  5977     "Modified: / 28-07-2018 / 15:49:52 / Claus Gittinger"
  5978 !
  5979 
  5980 menuItem
  5981     "returns self as a MenuItem
  5982     "
  5983     |item|
  5984 
  5985     item := super menuItem.
  5986     item submenu:(self submenu).
  5987   ^ item
  5988 !
  5989 
  5990 menuItem:anItem
  5991 
  5992     super menuItem:anItem.
  5993     self  menu:(anItem submenu) labeled:nil.
  5994 !
  5995 
  5996 slices
  5997     self isDelayedMenu ifTrue:[
  5998 	^ #(
  5999 		(Basics   basicsEditSpec )
  6000 	   )
  6001     ].
  6002 
  6003     ^ #(
  6004 	    (Basics   basicsEditSpec )
  6005 	    (Details  detailsEditSpec)
  6006 	    (Image    image  )
  6007 	    (Help     help)
  6008        )
  6009 !
  6010 
  6011 submenu
  6012     |menu|
  6013 
  6014     menu := Menu new.
  6015 
  6016     children size ~~ 0 ifTrue:[
  6017 	children do:[:el| menu addItem:(el menuItem) ].
  6018     ].
  6019     ^ menu
  6020 ! !
  6021 
  6022 !MenuEditor::RegularMenuItem methodsFor:'aspects'!
  6023 
  6024 getDelayedAttributesFrom:aMenuItem
  6025 
  6026     |menu|
  6027 
  6028     menu := self validateValue:(aMenuItem submenu value).
  6029 
  6030     self menu:menu labeled:nil.
  6031     menuItem horizontalLayout:(aMenuItem horizontalLayout).
  6032 !
  6033 
  6034 setDelayedAttributesTo:aMenuItem
  6035     aMenuItem          submenu:(self submenu).
  6036     aMenuItem horizontalLayout:(menuItem horizontalLayout).
  6037 ! !
  6038 
  6039 !MenuEditor::RegularMenuItem methodsFor:'displaying'!
  6040 
  6041 displayLabel
  6042     "returns the label dependent on is delayed or not
  6043     "
  6044     self isDelayedMenu ifTrue:[ ^ self class defaultDelayedLabel ].
  6045   ^ menuItem rawLabel
  6046 !
  6047 
  6048 icon
  6049     self isDelayedMenu ifTrue:[ ^ self class iconDelayedMenu ].
  6050   ^ self class iconMenu
  6051 ! !
  6052 
  6053 !MenuEditor::RegularMenuItem methodsFor:'queries'!
  6054 
  6055 canAddChildren
  6056     "children can be added
  6057     "
  6058     ^ true
  6059 !
  6060 
  6061 canExpand
  6062     "returns true if the item is expandable
  6063     "
  6064     ^ isExpanded == false
  6065 !
  6066 
  6067 hasIndicator
  6068     ^ true
  6069 !
  6070 
  6071 isKindOfMenu
  6072     ^ true
  6073 !
  6074 
  6075 isKindOfNonLinkedMenu
  6076     ^ true
  6077 ! !
  6078 
  6079 !MenuEditor::RootItem class methodsFor:'defaults'!
  6080 
  6081 defaultLabel
  6082     ^ MenuEditor resourceType
  6083 ! !
  6084 
  6085 !MenuEditor::RootItem class methodsFor:'interface specs'!
  6086 
  6087 basicsEditSpec
  6088     "This resource specification was automatically generated
  6089      by the UIPainter of ST/X."
  6090 
  6091     "Do not manually edit this!! If it is corrupted,
  6092      the UIPainter may not be able to read the specification."
  6093 
  6094     "
  6095      UIPainter new openOnClass:MenuEditor::RootItem andSelector:#basicsEditSpec
  6096     "
  6097 
  6098     <resource: #canvas>
  6099 
  6100     ^
  6101      #(FullSpec
  6102 	name: basicsEditSpec
  6103 	window:
  6104        (WindowSpec
  6105 	  label: 'basicsEditSpec'
  6106 	  name: 'basicsEditSpec'
  6107 	  min: (Point 10 10)
  6108 	  bounds: (Rectangle 0 0 260 46)
  6109 	)
  6110 	component:
  6111        (SpecCollection
  6112 	  collection: (
  6113 	   (LabelSpec
  6114 	      label: 'Selector:'
  6115 	      name: 'selectorLabel'
  6116 	      layout: (AlignmentOrigin 107 0 26 0 1 0.5)
  6117 	      activeHelpKey: basicsSelector
  6118 	      translateLabel: true
  6119 	      resizeForLabel: true
  6120 	      adjust: right
  6121 	    )
  6122 	   (InputFieldSpec
  6123 	      name: 'selectorField'
  6124 	      layout: (LayoutFrame 110 0 15 0 -5 1.0 37 0)
  6125 	      activeHelpKey: basicsSelector
  6126 	      tabable: true
  6127 	      model: rawLabel
  6128 	      group: inputGroup
  6129 	      type: string
  6130 	      immediateAccept: false
  6131 	      acceptOnReturn: true
  6132 	      acceptOnTab: true
  6133 	      acceptChannel: acceptChannel
  6134 	      modifiedChannel: modifiedChannel
  6135 	      acceptOnPointerLeave: false
  6136 	    )
  6137 	   )
  6138 
  6139 	)
  6140       )
  6141 ! !
  6142 
  6143 !MenuEditor::RootItem class methodsFor:'interface-editor'!
  6144 
  6145 addBindingsTo:aspects for:aMenuEditor
  6146     "add additional bindings to the aspects
  6147     "
  6148 ! !
  6149 
  6150 !MenuEditor::RootItem methodsFor:'accessing'!
  6151 
  6152 menuItem:aMenuItem
  6153     "rebuild self from a MenuItem
  6154     "
  6155     |submenu selector|
  6156 
  6157     aMenuItem notNil ifTrue:[
  6158 	submenu  := aMenuItem submenu.
  6159 	selector := aMenuItem rawLabel.
  6160     ] ifFalse:[
  6161 	selector := submenu := nil.
  6162     ].
  6163     self menu:submenu labeled:selector.
  6164 !
  6165 
  6166 rawLabel:aValue
  6167     "set the label assigned to the item
  6168     "
  6169     |value|
  6170 
  6171     aValue isString ifTrue:[
  6172 	value := aValue withoutSeparators.
  6173 
  6174 	(value notEmpty and:[value first isLetter]) ifTrue:[
  6175 	    menuItem rawLabel:(value asSymbol)
  6176 	].
  6177     ].
  6178 !
  6179 
  6180 slices
  6181     ^ #(
  6182 	    (Basics   basicsEditSpec)
  6183        )
  6184 ! !
  6185 
  6186 !MenuEditor::RootItem methodsFor:'adding & removing'!
  6187 
  6188 remove
  6189     "cannot remove the root item; delete all my children
  6190     "
  6191     self removeAll.
  6192 ! !
  6193 
  6194 !MenuEditor::RootItem methodsFor:'aspects'!
  6195 
  6196 aspectAt:aKey put:aValue
  6197     "ignore all aspects other than the rawLabel"
  6198 
  6199     aKey == #rawLabel ifTrue:[ self rawLabel:aValue ].
  6200 
  6201     "Modified: / 05-09-2006 / 17:48:01 / cg"
  6202 ! !
  6203 
  6204 !MenuEditor::RootItem methodsFor:'displaying'!
  6205 
  6206 heightOn:aGC
  6207     height isNil ifTrue:[ height := aGC font heightOn:aGC device ].
  6208     ^ height
  6209 ! !
  6210 
  6211 !MenuEditor::RootItem methodsFor:'initialization'!
  6212 
  6213 initialize
  6214     <modifier: #super> "must be called if redefined"
  6215 
  6216     super initialize.
  6217     isExpanded := true.
  6218 
  6219     "Modified: / 08-02-2017 / 00:29:29 / cg"
  6220 ! !
  6221 
  6222 !MenuEditor::RootItem methodsFor:'queries'!
  6223 
  6224 canCollapse
  6225     ^ false
  6226 !
  6227 
  6228 hasIndicator
  6229     ^ false
  6230 !
  6231 
  6232 isDelayedMenu
  6233     ^ false
  6234 !
  6235 
  6236 isRootItem
  6237     ^ true
  6238 ! !
  6239 
  6240 !MenuEditor::RootItem methodsFor:'queries-editor'!
  6241 
  6242 actionSelectors
  6243     "return my action selectors"
  6244 
  6245     ^ #()
  6246 !
  6247 
  6248 aspectSelectors
  6249     "returns my aspect selectors
  6250     "
  6251     ^ #()
  6252 ! !
  6253 
  6254 !MenuEditor::RootItem methodsFor:'queries-operation'!
  6255 
  6256 canMoveInAbove
  6257     ^ false
  6258 !
  6259 
  6260 canMoveInNext
  6261     ^ false
  6262 !
  6263 
  6264 canMoveOut
  6265     ^ false
  6266 !
  6267 
  6268 canMoveUpOrDown
  6269    ^ false
  6270 ! !
  6271 
  6272 !MenuEditor::SeparatorItem class methodsFor:'interface specs'!
  6273 
  6274 basicsEditSpec
  6275     "This resource specification was automatically generated
  6276      by the UIPainter of ST/X."
  6277 
  6278     "Do not manually edit this!! If it is corrupted,
  6279      the UIPainter may not be able to read the specification."
  6280 
  6281     "
  6282      UIPainter new openOnClass:MenuEditor::SeparatorItem andSelector:#basicsEditSpec
  6283     "
  6284 
  6285     <resource: #canvas>
  6286 
  6287     ^
  6288      #(FullSpec
  6289 	name: basicsEditSpec
  6290 	window:
  6291        (WindowSpec
  6292 	  label: 'basicsEditSpec'
  6293 	  name: 'basicsEditSpec'
  6294 	  min: (Point 10 10)
  6295 	  bounds: (Rectangle 0 0 260 245)
  6296 	)
  6297 	component:
  6298        (SpecCollection
  6299 	  collection: (
  6300 	   (LabelSpec
  6301 	      label: 'Separator:'
  6302 	      name: 'separatorLabel'
  6303 	      layout: (AlignmentOrigin 107 0 26 0 1 0.5)
  6304 	      translateLabel: true
  6305 	      resizeForLabel: true
  6306 	      adjust: right
  6307 	    )
  6308 	   (ComboListSpec
  6309 	      name: 'seperatorList'
  6310 	      layout: (LayoutFrame 110 0 15 0 -5 1.0 37 0)
  6311 	      activeHelpKey: basicsSeparatorType
  6312 	      tabable: true
  6313 	      model: seperatorSelection
  6314 	      comboList: seperatorList
  6315 	      useIndex: true
  6316 	    )
  6317 	   (LabelSpec
  6318 	      label: 'Visibility:'
  6319 	      name: 'visibilityLabel'
  6320 	      layout: (AlignmentOrigin 107 0 51 0 1 0.5)
  6321 	      translateLabel: true
  6322 	      resizeForLabel: true
  6323 	      adjust: right
  6324 	    )
  6325 	   (InputFieldSpec
  6326 	      name: 'visibilityInputField'
  6327 	      layout: (LayoutFrame 110 0 40 0 -5 1.0 62 0)
  6328 	      activeHelpKey: detailsVisibility
  6329 	      tabable: true
  6330 	      model: isVisible
  6331 	      group: inputGroup
  6332 	      type: symbolOrBooleanOrNil
  6333 	      immediateAccept: false
  6334 	      acceptOnReturn: true
  6335 	      acceptOnTab: true
  6336 	      acceptChannel: acceptChannel
  6337 	      modifiedChannel: modifiedChannel
  6338 	      acceptOnPointerLeave: false
  6339 	    )
  6340 	   (LabelSpec
  6341 	      label: 'Start Group:'
  6342 	      name: 'startGroupLabel'
  6343 	      layout: (AlignmentOrigin 107 0 88 0 1 0.5)
  6344 	      translateLabel: true
  6345 	      resizeForLabel: true
  6346 	      adjust: right
  6347 	    )
  6348 	   (PopUpListSpec
  6349 	      label: 'left'
  6350 	      name: 'startGroupPopUp'
  6351 	      layout: (LayoutFrame 110 0 77 0 -5 1.0 99 0)
  6352 	      activeHelpKey: detailsStartGroup
  6353 	      tabable: true
  6354 	      model: startGroup
  6355 	      menu: (left right conditionalRight)
  6356 	    )
  6357 	   )
  6358 
  6359 	)
  6360       )
  6361 
  6362     "Modified: / 16-10-2006 / 12:48:30 / cg"
  6363 ! !
  6364 
  6365 !MenuEditor::SeparatorItem class methodsFor:'interface-editor'!
  6366 
  6367 addBindingsTo:aspects for:aMenuEditor
  6368     "add additional bindings to the aspects
  6369     "
  6370     |holder|
  6371 
  6372     aspects
  6373 	at:#seperatorList
  6374 	ifAbsentPut:
  6375 	    [
  6376 		|l|
  6377 
  6378 		l := self separatorSlices collect:[:el| el last ].
  6379 		l := l collect:[:s | self classResources string:s ].
  6380 		l
  6381 	    ].
  6382 
  6383     aspects at:#seperatorSelection ifAbsentPut:[
  6384 	holder := 0 asValue.
  6385 	holder addDependent:aMenuEditor.
  6386 	holder
  6387     ].
  6388 !
  6389 
  6390 defaultLabel
  6391     ^ '-'
  6392 !
  6393 
  6394 separatorSlices
  6395     "get the list of menu spec values of the corresponding separator types
  6396     "
  6397     ^ #(
  6398 	( #blank        ''      'blank' )
  6399 	( #single       '-'     'single line')
  6400 	( #double       '='     'double line')
  6401       )
  6402 ! !
  6403 
  6404 !MenuEditor::SeparatorItem methodsFor:'accessing'!
  6405 
  6406 icon
  6407     ^ self class iconSeparator
  6408 !
  6409 
  6410 rawLabel:aValue
  6411     |value|
  6412 
  6413     aValue isString ifTrue:[
  6414 	value := aValue withoutSeparators.
  6415 
  6416 	(self class separatorTypeOf:value) notNil ifTrue:[
  6417 	    menuItem rawLabel:value
  6418 	]
  6419     ].
  6420 
  6421     "Modified: / 29-11-2011 / 11:28:39 / cg"
  6422 !
  6423 
  6424 separatorType
  6425     ^ self class separatorTypeOf:(menuItem rawLabel).
  6426 !
  6427 
  6428 slices
  6429     ^ #(
  6430 	    (Basics   basicsEditSpec)
  6431        )
  6432 ! !
  6433 
  6434 !MenuEditor::SeparatorItem methodsFor:'aspects'!
  6435 
  6436 fromAspects:aspects
  6437     "put my values into the values of aspects
  6438     "
  6439     |index slice|
  6440 
  6441     index  := (aspects at:#seperatorSelection) value ? 0.
  6442     slice  := self class separatorSlices at:index ifAbsent:nil.
  6443 
  6444     slice notNil ifTrue:[ slice := slice at:2 ].
  6445 
  6446     (aspects at:#rawLabel) value:slice.
  6447   ^ super fromAspects:aspects.
  6448 
  6449     "Modified: / 29-11-2011 / 11:28:36 / cg"
  6450 !
  6451 
  6452 toAspects:aspects
  6453     "put my values into the values of aspects
  6454     "
  6455     |index type|
  6456 
  6457     type   := self separatorType.
  6458     index  := self class separatorSlices findFirst:[:el| el first == type ].
  6459 
  6460     (aspects at:#seperatorSelection) value:index.
  6461   ^ super  toAspects:aspects.
  6462 ! !
  6463 
  6464 !MenuEditor::SeparatorItem methodsFor:'displaying'!
  6465 
  6466 displayOn:aGC x:x y:y h:h isHighlightedAsSelected:isHighlightedAsSelected
  6467     "draw the receiver in the graphicsContext, aGC"
  6468 
  6469     |x1 y0 type|
  6470 
  6471     type := self separatorType.
  6472     type == #blank ifTrue:[ ^ self ].
  6473 
  6474     x1 := x + (self widthOn:aGC).
  6475     y0 := y + (h // 2) - 1.
  6476 
  6477     type == #double ifTrue:[
  6478         y0 := y0 + 1.
  6479         aGC displayLineFromX:x y:y0 toX:x1 y:y0.
  6480         y0 := y0 - 2
  6481     ].
  6482     aGC displayLineFromX:x y:y0 toX:x1 y:y0
  6483 !
  6484 
  6485 widthOn:aGC
  6486     width isNil ifTrue:[ width := 60 ].
  6487     ^ width
  6488 ! !
  6489 
  6490 !MenuEditor class methodsFor:'documentation'!
  6491 
  6492 version
  6493     ^ '$Header$'
  6494 !
  6495 
  6496 version_CVS
  6497     ^ '$Header$'
  6498 ! !
  6499 
  6500 
  6501 MenuEditor initialize!