TabListEditor.st
author Claus Gittinger <cg@exept.de>
Fri, 04 Jul 2008 10:12:29 +0200
changeset 2371 233e1bda3570
parent 2346 d6fdeda319de
child 2383 e76cc686a293
permissions -rw-r--r--
mass operations: color selected-color

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

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

ResourceSpecEditor subclass:#TabListEditor
	instanceVariableNames:'listOfTabs'
	classVariableNames:''
	poolDictionaries:''
	category:'Interface-UIPainter'
!

!TabListEditor class methodsFor:'documentation'!

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

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


!

documentation
"
    The TabListEditor allows you to create, modify or just inspect
    tab lists for tab headers or note books.

    [start with:]
        TabItemEditor open

    [see also:]
        TabItem
        TabView
        NoteBookView
        UIPainter

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


! !

!TabListEditor class methodsFor:'instance creation'!

openModalOnTabList: aTabList
    "Open a TabListEditor modal on aTabList"
    "self openModalOnTabList: (Array with: (TabItem label: 'Tab Item 1'))"

    ^self new openModalOnTabList: aTabList

! !

!TabListEditor class methodsFor:'accessing'!

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

    ^#tabList






! !

!TabListEditor class methodsFor:'aspects'!

aspects
    "get the aspects for the attributes of the tab list components"

    ^#(
        label
        translateLabel
        labelForegroundColor
        enabled
        editAgument
        accessCharacterPosition
        shortcutKey
        activeHelpKey

        majorKey
        minorKey
        createNewBuilder

        hasHorizontalScrollBar
        hasVerticalScrollBar
        miniScrollerHorizontal
        miniScrollerVertical
    )

! !

!TabListEditor class methodsFor:'help specs'!

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

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

    "
     UIHelpTool openOnClass:TabListEditor    
    "

    <resource: #help>

    ^ super helpSpec addPairsFrom:#(

#addTabItem
'Adds a new tab item.'

#applicationProvidesLabel
'If on, the label''s string is a selector returning a string or bitmap image, which is used as logo in the tab item.'

#autoHideScrollBars
'ScrollBars should be made invisible dynamically, if there is nothing to scroll.'

#basicTab
'Define the basic attributes.'

#canSelect
'Turns on/off whether the tab item is selectable.'

#canvasTab
'Define an application, which is started if the tab is pressed the first time.'

#color
'Defines the foreground color of the label. The default color derives from the style sheet.'

#createNewBuilder
'Create a new builder for the application; the application use its own aspects.'

#detailTab
'Define the optional/specific attributes.'

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

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

#detailsArgument
'An optional argument stored with the tab item.'

#fileCreateAspectMethod
'Creates the aspect method for the tab list.'

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

#fileNew
'Creates a new tab list.'

#fileSave
'Saves current tab list.'

#horizontalMiniScroller
'Use a mini-scroller as horizontal scrollbar.'

#horizontalScroller
'Enable horizontal scrollability.'

#label
'Label of the tab item.'

#majorKey
'Name of the class to be started (application if empty); or app-selector returning application instance.'

#minorKey
'Message sent to the class which returns the window specification (default: #windowSpec).'

#testPreview
'Turns on/off preview of the tab list.'

#translateLabel
'If on, the label is translated using the applications language resources.'

#verticalMiniScroller
'Use a mini-scroller as vertical scrollbar.'

#verticalScroller
'Enable vertical scrollability.'

)
! !

!TabListEditor class methodsFor:'image specs'!

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

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

    "
     ImageEditor openOnClass:self andSelector:#newTabItemIcon
    "

    <resource: #image>

    ^Icon
        constantNamed:#'TabListEditor newTabItemIcon'
        ifAbsentPut:[(Depth2Image new) width: 22; height: 22; photometric:(#palette); bitsPerSample:(#(2 )); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'U@@@@EUPUEUUVEUPUF**+EUPUF**+EUPUF**+EUP@F**+@@@EV***UV@F*****+@F KNC*+NF(("H*+@F((BC +EF(("H*+@F(("C*+MF*****+@F"@ H*K@F"""(LK@F"" ("K@F"""(*K@F"" H*K@F*****+HK??????@@@@@@@@@') ; colorMapFromArray:#[0 0 0 255 255 255 170 170 170 127 127 127]; mask:((Depth1Image new) width: 22; height: 22; photometric:(#blackIs0); bitsPerSample:(#(1 )); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'G?<@G?<@G?<@G?<@G?<@???<???<???<???????<???<???<???<???????=???<???????<???????<???<???=') ; yourself); yourself]
! !

!TabListEditor class methodsFor:'interface specs'!

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

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

    "
     UIPainter new openOnClass:TabListEditor andSelector:#basicSpec
     TabListEditor new openInterface:#basicSpec
    "

    <resource: #canvas>

    ^ 
     #(FullSpec
        name: basicSpec
        window: 
       (WindowSpec
          label: 'Basic'
          name: 'Basic'
          min: (Point 10 10)
          max: (Point 1280 1024)
          bounds: (Rectangle 0 0 429 240)
        )
        component: 
       (SpecCollection
          collection: (
           (LabelSpec
              label: 'Label:'
              name: 'labelLabel'
              layout: (AlignmentOrigin 98 0 26 0 1 0.5)
              translateLabel: true
              resizeForLabel: true
            )
           (InputFieldSpec
              name: 'label'
              layout: (LayoutFrame 100 0 15 0 -5 1.0 37 0)
              activeHelpKey: label
              tabable: true
              model: label
              group: inputGroup
              immediateAccept: true
              acceptOnReturn: false
              acceptOnTab: false
              acceptOnLostFocus: false
              acceptChannel: acceptChannel
              modifiedChannel: modifiedChannel
              acceptOnPointerLeave: false
            )
           (LabelSpec
              label: 'Accelerator:'
              name: 'shortcutKeyLabel'
              layout: (AlignmentOrigin 98 0 55 0 1 0.5)
              translateLabel: true
              resizeForLabel: true
            )
           (InputFieldSpec
              name: 'shortcutKey'
              layout: (LayoutFrame 100 0 44 0 -5 1.0 66 0)
              activeHelpKey: detailsAccelerator
              tabable: true
              model: shortcutKey
              group: inputGroup
              type: symbolOrNil
              immediateAccept: true
              acceptOnReturn: false
              acceptOnTab: false
              acceptOnLostFocus: false
              acceptChannel: acceptChannel
              modifiedChannel: modifiedChannel
              acceptOnPointerLeave: false
            )
           (LabelSpec
              label: 'Argument:'
              name: 'editAgumentLabel'
              layout: (AlignmentOrigin 98 0 84 0 1 0.5)
              translateLabel: true
              resizeForLabel: true
            )
           (InputFieldSpec
              name: 'editAgument'
              layout: (LayoutFrame 100 0 73 0 -5 1.0 95 0)
              activeHelpKey: detailsArgument
              tabable: true
              model: editAgument
              group: inputGroup
              immediateAccept: true
              acceptOnReturn: false
              acceptOnTab: false
              acceptOnLostFocus: false
              acceptChannel: acceptChannel
              modifiedChannel: modifiedChannel
              acceptOnPointerLeave: false
            )
           (LabelSpec
              label: 'Access Character Position:'
              name: 'accessCharacterPositionLabel'
              layout: (AlignmentOrigin 275 0 113 0 1 0.5)
              translateLabel: true
              resizeForLabel: true
            )
           (InputFieldSpec
              name: 'accessCharacterPosition'
              layout: (LayoutFrame 278 0 103 0 -5 1.0 125 0)
              activeHelpKey: detailsAccessCharaterPosition
              tabable: true
              model: accessCharacterPosition
              group: inputGroup
              type: number
              immediateAccept: true
              acceptOnReturn: false
              acceptOnTab: false
              acceptOnLostFocus: false
              acceptChannel: acceptChannel
              modifiedChannel: modifiedChannel
              acceptOnPointerLeave: false
            )
           (CheckBoxSpec
              label: 'Translate Label '
              name: 'translateLabel'
              layout: (LayoutFrame 96 0 135 0 308 0 161 0)
              activeHelpKey: translateLabel
              tabable: true
              model: translateLabel
              translateLabel: true
            )
           (CheckBoxSpec
              label: 'Application Provides Label '
              name: 'CheckBox1'
              layout: (LayoutFrame 96 0 161 0 308 0 187 0)
              activeHelpKey: applicationProvidesLabel
              tabable: true
              model: applicationProvidesLabel
              translateLabel: true
            )
           (LabelSpec
              label: 'Help Key:'
              name: 'activeHelp'
              layout: (AlignmentOrigin 98 0 203 0 1 0.5)
              translateLabel: true
              resizeForLabel: true
            )
           (InputFieldSpec
              name: 'activeHelpKey'
              layout: (LayoutFrame 100 0 192 0 -5 1.0 214 0)
              activeHelpKey: label
              tabable: true
              model: activeHelpKey
              group: inputGroup
              type: symbolOrNil
              immediateAccept: true
              acceptOnReturn: false
              acceptOnTab: false
              acceptOnLostFocus: false
              acceptChannel: acceptChannel
              modifiedChannel: modifiedChannel
              acceptOnPointerLeave: false
            )
           )
         
        )
      )
!

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

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

    "
     UIPainter new openOnClass:TabListEditor andSelector:#canvasSpec
     TabListEditor new openInterface:#canvasSpec
    "

    <resource: #canvas>

    ^ 
     #(FullSpec
        name: canvasSpec
        window: 
       (WindowSpec
          label: 'Canvas'
          name: 'Canvas'
          min: (Point 10 10)
          max: (Point 1280 1024)
          bounds: (Rectangle 0 0 383 220)
        )
        component: 
       (SpecCollection
          collection: (
           (LabelSpec
              label: 'Class Name / Major Key:'
              name: 'majorKeyLabel'
              layout: (AlignmentOrigin 160 0 26 0 1 0.5)
              activeHelpKey: majorKey
              translateLabel: true
              resizeForLabel: true
            )
           (InputFieldSpec
              name: 'majorKeyField'
              layout: (LayoutFrame 161 0 15 0 -5 1.0 37 0)
              activeHelpKey: majorKey
              tabable: true
              model: majorKey
              group: inputGroup
              type: symbolOrNil
              immediateAccept: true
              acceptOnReturn: false
              acceptOnTab: false
              acceptOnLostFocus: false
              modifiedChannel: modifiedChannel
              acceptOnPointerLeave: false
            )
           (LabelSpec
              label: 'Selector / Minor Key:'
              name: 'minorKeyLabel'
              layout: (AlignmentOrigin 160 0 55 0 1 0.5)
              translateLabel: true
              resizeForLabel: true
            )
           (InputFieldSpec
              name: 'minorKeyField'
              layout: (LayoutFrame 161 0 44 0 -5 1.0 66 0)
              activeHelpKey: majorKey
              tabable: true
              model: minorKey
              group: inputGroup
              type: symbolOrNil
              immediateAccept: true
              acceptOnReturn: false
              acceptOnTab: false
              acceptOnLostFocus: false
              modifiedChannel: modifiedChannel
              acceptOnPointerLeave: false
            )
           (FramedBoxSpec
              label: 'Scroll Bars'
              name: 'FramedBox'
              layout: (LayoutFrame 0 0.0 119 0.0 0 1.0 218 0)
              labelPosition: topLeft
              translateLabel: true
              component: 
             (SpecCollection
                collection: (
                 (HorizontalPanelViewSpec
                    name: 'HorizontalPanel1'
                    layout: (LayoutFrame 0 0.0 0 0.0 0 1.0 0 1.0)
                    horizontalLayout: fitSpace
                    verticalLayout: fitSpace
                    horizontalSpace: 3
                    verticalSpace: 3
                    component: 
                   (SpecCollection
                      collection: (
                       (ViewSpec
                          name: 'Box1'
                          component: 
                         (SpecCollection
                            collection: (
                             (CheckBoxSpec
                                label: 'Vertical'
                                name: 'verticalScrollBarCheckBox'
                                layout: (LayoutFrame 0 0.0 3 0 0 1.0 27 0)
                                activeHelpKey: verticalScroller
                                tabable: true
                                model: hasVerticalScrollBar
                                translateLabel: true
                              )
                             (CheckBoxSpec
                                label: 'Mini'
                                name: 'miniScrollerVerticalCheckBox'
                                layout: (LayoutFrame 0 0.0 32 0 0 1.0 56 0)
                                activeHelpKey: verticalMiniScroller
                                tabable: true
                                model: miniScrollerVertical
                                translateLabel: true
                              )
                             )
                           
                          )
                          useDefaultExtent: true
                        )
                       (ViewSpec
                          name: 'Box2'
                          component: 
                         (SpecCollection
                            collection: (
                             (CheckBoxSpec
                                label: 'Horizontal'
                                name: 'horizontalScrollBarCheckBox'
                                layout: (LayoutFrame 0 0.0 3 0 0 1.0 27 0)
                                activeHelpKey: horizontalScroller
                                tabable: true
                                model: hasHorizontalScrollBar
                                translateLabel: true
                              )
                             (CheckBoxSpec
                                label: 'Mini'
                                name: 'miniScrollerHorizontalCheckBox'
                                layout: (LayoutFrame 0 0.0 32 0 0 1.0 56 0)
                                activeHelpKey: horizontalMiniScroller
                                tabable: true
                                model: miniScrollerHorizontal
                                translateLabel: true
                              )
                             )
                           
                          )
                          extent: (Point 113 61)
                        )
                       (ViewSpec
                          name: 'Box3'
                          component: 
                         (SpecCollection
                            collection: (
                             (LabelSpec
                                label: 'Auto Hide:'
                                name: 'Label1'
                                layout: (LayoutFrame 0 0.0 6 0 0 1.0 23 0)
                                translateLabel: true
                                resizeForLabel: true
                                adjust: left
                              )
                             (PopUpListSpec
                                label: 'Default'
                                name: 'PopUpList1'
                                layout: (LayoutFrame 0 0.0 32 0 0 1.0 54 0)
                                activeHelpKey: autoHideScrollBars
                                tabable: true
                                model: autoHideScrollBars
                                menu: 
                               (Default
                                  On Off
                                )
                                useIndex: true
                              )
                             )
                           
                          )
                          extent: (Point 113 61)
                        )
                       )
                     
                    )
                  )
                 )
               
              )
            )
           (CheckBoxSpec
              label: 'Create New Builder'
              name: 'createNewBuilder'
              layout: (Point 161 75)
              activeHelpKey: createNewBuilder
              model: createNewBuilder
              translateLabel: true
            )
           )
         
        )
      )
!

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

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

    "
     UIPainter new openOnClass:TabListEditor andSelector:#detailSpec
     TabListEditor new openInterface:#detailSpec
    "

    <resource: #canvas>

    ^ 
     #(FullSpec
        name: detailSpec
        window: 
       (WindowSpec
          label: 'Details'
          name: 'Details'
          min: (Point 10 10)
          max: (Point 1280 1024)
          bounds: (Rectangle 0 0 358 107)
        )
        component: 
       (SpecCollection
          collection: (
           (CheckBoxSpec
              label: 'Can Select'
              name: 'enabled'
              layout: (Point 46 14)
              activeHelpKey: canSelect
              tabable: true
              model: enabled
              translateLabel: true
            )
           (LabelSpec
              label: 'Color:'
              name: 'ForegroundLabel'
              layout: (AlignmentOrigin 46 0 62 0 1 0.5)
              translateLabel: true
              resizeForLabel: true
              adjust: right
            )
           (ColorMenuSpec
              name: 'ForegroundColorMenu'
              layout: (LayoutFrame 48 0 50 0 -10 1.0 72 0)
              activeHelpKey: color
              model: labelForegroundColor
              labelsAreColored: false
            )
           )
         
        )
      )
!

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

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

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

    <resource: #canvas>

    ^ 
     #(#FullSpec
        #name: #windowSpec
        #window: 
       #(#WindowSpec
          #label: 'Tab List Editor'
          #name: 'Tab List Editor'
          #min: #(#Point 440 280)
          #max: #(#Point 1152 900)
          #bounds: #(#Rectangle 596 292 1132 661)
          #menu: #menu
        )
        #component: 
       #(#SpecCollection
          #collection: #(
           #(#MenuPanelSpec
              #name: 'menuToolbarView'
              #layout: #(#LayoutFrame 0 0.0 0 0.0 0 1.0 34 0)
              #menu: #menuToolbar
              #showSeparatingLines: true
            )
           #(#VariableHorizontalPanelSpec
              #name: 'VariablePanel'
              #layout: #(#LayoutFrame 0 0.0 36 0.0 0 1.0 -26 1.0)
              #component: 
             #(#SpecCollection
                #collection: #(
                 #(#SelectionInListModelViewSpec
                    #attributes: 
                   #(#vpext
                      
                     #(#Array
                        #Array #Array
                        #Array #Array
                        #Array #Point
                        0.264414 1.0
                      )
                    )
                    #name: 'ListOfLabels'
                    #tabable: true
                    #model: #selectionHolder
                    #menu: #menuEdit
                    #hasHorizontalScrollBar: true
                    #hasVerticalScrollBar: true
                    #miniScrollerHorizontal: true
                    #listModel: #listOfTabs
                    #highlightMode: #line
                    #selectConditionSelector: #askForItemModification
                  )
                 #(#ViewSpec
                    #name: 'SpecView'
                    #level: -1
                    #component: 
                   #(#SpecCollection
                      #collection: #(
                       #(#NoteBookViewSpec
                          #name: 'NoteBook'
                          #layout: #(#LayoutFrame 1 0.0 0 0.0 0 1.0 -30 1.0)
                          #enableChannel: #hasSelectionHolder
                          #tabable: true
                          #model: #noteBookModel
                          #menu: #noteBookTabList
                          #useIndex: true
                          #keepCanvasAlive: true
                        )
                       #(#UISubSpecification
                          #name: 'subSpec'
                          #layout: #(#LayoutFrame 2 0.0 -26 1 -2 1.0 -2 1)
                          #majorKey: #ToolApplicationModel
                          #minorKey: #windowSpecForCommit
                        )
                       #(#NoteBookViewSpec
                          #name: 'TestNoteBook'
                          #layout: #(#LayoutFrame 0 0.0 0 0.0 0 1.0 0 1.0)
                          #visibilityChannel: #testMode
                          #tabable: true
                          #menu: #testItemList
                          #useIndex: true
                        )
                       )
                     
                    )
                  )
                 )
               
              )
              #handles: #(#Any 0.24053 1.0)
            )
           #(#UISubSpecification
              #name: 'infoBarSubSpec'
              #layout: #(#LayoutFrame 0 0.0 -24 1 0 1.0 0 1.0)
              #majorKey: #ToolApplicationModel
              #minorKey: #windowSpecForInfoBar
            )
           )
         
        )
      )
! !

!TabListEditor class methodsFor:'list specs'!

noteBookTabList
    "This resource specification was automatically generated
     by the TabListEditor of ST/X."

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

    "
     TabListEditor new openOnClass:TabListEditor andSelector:#noteBookTabList
    "

    <resource: #tabList>

    ^     #(
       #(#TabItem
          #label: 'Basic'
          #activeHelpKey: #basicTab
          #minorKey: #basicSpec
        )
       #(#TabItem
          #label: 'Details'
          #activeHelpKey: #detailTab
          #minorKey: #detailSpec
        )
       #(#TabItem
          #label: 'Canvas'
          #activeHelpKey: #canvasTab
          #minorKey: #canvasSpec
        )
       )
     
      collect:[:aTab| TabItem new fromLiteralArrayEncoding:aTab ]
! !

!TabListEditor class methodsFor:'menu specs'!

menu
    "This resource specification was automatically generated
     by the MenuEditor of ST/X."

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

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

    <resource: #menu>

    ^
     
       #(#Menu
          
           #(
             #(#MenuItem
                #label: 'About'
                #activeHelpKey: #about
                #labelImage: #(#ResourceRetriever nil #menuIcon)
                #submenuChannel: #menuAbout
            )
             #(#MenuItem
                #label: 'File'
                #activeHelpKey: #file
                #submenu: 
                 #(#Menu
                    
                     #(
                       #(#MenuItem
                          #label: 'New'
                          #value: #doNew
                          #activeHelpKey: #fileNew
                      )
                       #(#MenuItem
                          #label: '-'
                      )
                       #(#MenuItem
                          #label: 'Load...'
                          #translateLabel: true
                          #value: #doLoad
                          #activeHelpKey: #fileLoad
                      )
                       #(#MenuItem
                          #label: '-'
                      )
                       #(#MenuItem
                          #label: 'Save'
                          #value: #doSave
                          #activeHelpKey: #fileSave
                      )
                       #(#MenuItem
                          #label: 'Save As...'
                          #value: #doSaveAs
                          #activeHelpKey: #fileSave
                      )
                       #(#MenuItem
                          #label: '-'
                      )
                       #(#MenuItem
                          #label: 'Browse Class'
                          #value: #doBrowseClass
                          #activeHelpKey: #fileBrowseClass
                      )
                       #(#MenuItem
                          #label: '-'
                      )
                       #(#MenuItem
                          #label: 'Exit'
                          #value: #closeRequest
                          #activeHelpKey: #fileExit
                      )
                    ) nil
                    nil
                )
            )
             #(#MenuItem
                #label: 'Edit'
                #activeHelpKey: #edit
                #submenuChannel: #menuEdit
            )
             #(#MenuItem
                #label: 'Add'
                #activeHelpKey: #add
                #submenu: 
                 #(#Menu
                    
                     #(
                       #(#MenuItem
                          #label: 'Tab Item'
                          #value: #doCreate
                          #activeHelpKey: #addTabItem
                          #labelImage: #(#ResourceRetriever nil #newTabItemIcon 'Tab Item')
                      )
                    ) nil
                    nil
                )
            )
             #(#MenuItem
                #label: 'Generate'
                #activeHelpKey: #add
                #submenu: 
                 #(#Menu
                    
                     #(
                       #(#MenuItem
                          #label: 'Aspect Method'
                          #value: #doGenerateAspectMethod
                          #activeHelpKey: #fileCreateAspectMethod
                          #enabled: #hasClassAndSelector
                      )
                    ) nil
                    nil
                )
            )
             #(#MenuItem
                #label: 'Test'
                #activeHelpKey: #test
                #submenu: 
                 #(#Menu
                    
                     #(
                       #(#MenuItem
                          #label: 'Preview'
                          #activeHelpKey: #testPreview
                          #enabled: #canToggleTestMode
                          #indication: #testMode
                      )
                    ) nil
                    nil
                )
            )
             #(#MenuItem
                #label: 'History'
                #activeHelpKey: #history
                #submenuChannel: #menuHistory
            )
             #(#MenuItem
                #label: 'Help'
                #startGroup: #right
                #activeHelpKey: #help
                #submenuChannel: #menuHelp
            )
          ) nil
          nil
      )
!

menuEdit
    "This resource specification was automatically generated
     by the MenuEditor of ST/X."

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

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

    <resource: #menu>

    ^ 
     #(#Menu
        #(
         #(#MenuItem
            #label: 'Cut'
            #value: #doCut
            #activeHelpKey: #editCut
            #enabled: #hasSelectionHolder
          )
         #(#MenuItem
            #label: 'Copy'
            #value: #doCopy
            #activeHelpKey: #editCopy
            #enabled: #hasSelectionHolder
          )
         #(#MenuItem
            #label: 'Paste'
            #value: #doPaste
            #activeHelpKey: #editPaste
            #enabled: #valueOfCanPaste
          )
         #(#MenuItem
            #label: 'Delete'
            #value: #doDelete
            #activeHelpKey: #editPaste
            #enabled: #hasSelectionHolder
          )
         #(#MenuItem
            #label: '-'
          )
         #(#MenuItem
            #label: 'Move Up'
            #value: #doMoveTabUpOrDown:
            #activeHelpKey: #editMoveUp
            #enabled: #canMoveTabItemUpOrDown
            #argument: #up
            #labelImage: #(#ResourceRetriever #Icon #upIcon 'Move Up')
          )
         #(#MenuItem
            #label: 'Move Down'
            #value: #doMoveTabUpOrDown:
            #activeHelpKey: #editMoveDown
            #enabled: #canMoveTabItemUpOrDown
            #argument: #down
            #labelImage: #(#ResourceRetriever #Icon #downIcon 'Move Down')
          )
         #(#MenuItem
            #label: '-'
            #isVisible: #hiddenAccelerator
          )
         #(#MenuItem
            #label: 'Accept'
            #translateLabel: true
            #isVisible: #hiddenAccelerator
            #value: #accept
            #enabled: #valueOfEnablingCommitButtons
          )
         )
        nil
        nil
      )
!

menuToolbar
    "This resource specification was automatically generated
     by the MenuEditor of ST/X."

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

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

    <resource: #menu>

    ^ 
     #(Menu
        (
         (MenuItem
            activeHelpKey: fileNew
            label: 'New'
            itemValue: doNew
            translateLabel: true
            isButton: true
            labelImage: (ResourceRetriever ToolbarIconLibrary new22x22Icon)
          )
         (MenuItem
            activeHelpKey: fileLoad
            label: 'Load'
            itemValue: doLoad
            translateLabel: true
            isButton: true
            labelImage: (ResourceRetriever ToolbarIconLibrary loadFromMethodIcon)
          )
         (MenuItem
            activeHelpKey: fileSave
            label: 'Save'
            itemValue: doSave
            translateLabel: true
            isButton: true
            labelImage: (ResourceRetriever ToolbarIconLibrary saveAsMethodIcon)
          )
         (MenuItem
            label: '-'
          )
         (MenuItem
            activeHelpKey: editCut
            enabled: hasSelectionHolder
            label: 'Cut'
            itemValue: doCut
            translateLabel: true
            isButton: true
            labelImage: (ResourceRetriever ToolbarIconLibrary cutWidgetIcon)
          )
         (MenuItem
            activeHelpKey: editCopy
            enabled: hasSelectionHolder
            label: 'Copy'
            itemValue: doCopy
            translateLabel: true
            isButton: true
            labelImage: (ResourceRetriever ToolbarIconLibrary copyWidgetIcon)
          )
         (MenuItem
            activeHelpKey: editPaste
            enabled: valueOfCanPaste
            label: 'Paste'
            itemValue: doPaste
            translateLabel: true
            isButton: true
            labelImage: (ResourceRetriever ToolbarIconLibrary pasteWidgetIcon)
          )
         (MenuItem
            activeHelpKey: editDelete
            enabled: hasSelectionHolder
            label: 'Delete'
            itemValue: doDelete
            translateLabel: true
            isButton: true
            isVisible: false
            labelImage: (ResourceRetriever ToolbarIconLibrary delete22x22Icon)
          )
         (MenuItem
            label: '-'
          )
         (MenuItem
            activeHelpKey: addTabItem
            label: 'Add Tab Item'
            itemValue: doCreate
            translateLabel: true
            isButton: true
            labelImage: (ResourceRetriever nil newTabItemIcon)
          )
         (MenuItem
            label: ''
          )
         (MenuItem
            activeHelpKey: editMoveUp
            enabled: canMoveTabItemUpOrDown
            label: 'Move Tab Up'
            itemValue: doMoveTabUpOrDown:
            translateLabel: true
            isButton: true
            startGroup: right
            labelImage: (ResourceRetriever XPToolbarIconLibrary up22x22Icon)
            argument: up
          )
         (MenuItem
            activeHelpKey: editMoveDown
            enabled: canMoveTabItemUpOrDown
            label: 'Move Tab Down'
            itemValue: doMoveTabUpOrDown:
            translateLabel: true
            isButton: true
            startGroup: right
            labelImage: (ResourceRetriever XPToolbarIconLibrary down22x22Icon)
            argument: down
          )
         )
        nil
        nil
      )
! !

!TabListEditor methodsFor:'aspects'!

autoHideScrollBars
    |holder|

    (holder := builder bindingAt:#autoHideScrollBars) isNil ifTrue:[
        builder aspectAt:#autoHideScrollBars put:(holder := 1 asValue).
        holder addDependent: self
    ].
    ^ holder.
!

canMoveTabItemUpOrDown
    ^ builder booleanValueAspectFor:#canMoveTabItemUpOrDown
!

hasSelectionHolder
    ^ builder booleanValueAspectFor:#hasSelectionHolder
!

hiddenAccelerator
    "used to set menu entries with an accelerator not visible to the operator
    "
    ^ false
!

inputGroup

    |holder|

    (holder := builder bindingAt:#inputGroup) isNil ifTrue:[
        builder aspectAt:#inputGroup put:(holder := EnterFieldGroup new)
    ].
    ^ holder.


!

listOfTabs
    ^ listOfTabs
!

noteBookModel
    |holder|

    (holder := builder bindingAt:#noteBookModel) isNil ifTrue:[
        holder := 0 asValue.
        builder aspectAt:#noteBookModel put:holder.
    ].
    ^ holder.
!

noteBookTabList
    "Generated by the TabListEditor"

    |list|

    (list := builder bindingAt:#noteBookTabList) isNil ifTrue:[
        builder aspectAt:#noteBookTabList put:(list := self class noteBookTabList).
    ].
    ^ list
!

selectionHolder
    "holder which keeps the current selection
    "
    |holder|

    (holder := builder bindingAt:#selectionHolder) isNil ifTrue:[
        holder := 0 asValue.
        builder aspectAt:#selectionHolder put:holder.
        holder addDependent:self.
    ].
    ^ holder
!

testItemList
    |holder|

    (holder := builder bindingAt:#testItemList) isNil ifTrue:[
        holder := ValueHolder new.
        builder aspectAt:#testItemList put:holder.
    ].
    ^ holder.
!

testMode

    |holder|

    (holder := builder bindingAt:#testMode) isNil ifTrue:[
        builder aspectAt:#testMode put:(holder := false asValue).
        holder addDependent: self
    ].
    ^ holder

! !

!TabListEditor methodsFor:'building'!

buildFromResourceSpec:aListSpec
    self buildFromTabList:aListSpec
!

buildFromTabList: aTabList
    "build from a aTabList"

    self selection:0.
    listOfTabs removeAll.

    aTabList do:[:aTabItem| listOfTabs add: aTabItem ].
    self clearModified.
    listOfTabs notEmpty ifTrue:[ self selection:1 ].
!

loadFromClass:aClass andSelector:aSelector
    "build from class and selector"

    |cls spec|

    self assert:(aClass isNil or:[aClass isClass]).

    self testMode value: false.
    self selection:0.

    "if opened on a tab list"
    (aClass isNil and: [aSelector isNil and: [listOfTabs size > 0]]) ifFalse:[
        listOfTabs removeAll.

        cls := aClass isBehavior ifTrue:[ aClass ] ifFalse:[ self resolveName:aClass].
        specSelector := aSelector.

        cls notNil ifTrue:[
            specSelector notNil ifTrue:[

                (cls respondsTo: aSelector) ifTrue:[ 
                    spec := cls perform: aSelector.
                ].
                spec size ~~ 0 ifTrue:[
                    spec do:[:aTab|
                        listOfTabs add:aTab.
                    ].
                    self addHistoryEntryForClass:cls selector:specSelector.
                ]
            ]
        ].

        self clearModified.
    ].
    listOfTabs notEmpty ifTrue:[ self selection:1 ].
! !

!TabListEditor methodsFor:'change & update'!

update:something with:aParameter from:someObject
    "one of my aspects has changed; update modified channel
    "
    |list|

    someObject = self selectionHolder ifTrue:[
        ^ self selectionChanged
    ].

    someObject = self testMode ifFalse:[              
        ^ super update:something with:aParameter from:someObject.
    ].

    someObject value ifTrue:[
        self noteBookModel value:0.

        listOfTabs notEmpty ifTrue:[
            list := listOfTabs collect:[:aTab| |tab|
                tab := aTab copy.
                tab setAttributesFromClass:specClass.
                tab
            ]
        ].
        self selection:0.
    ].
    self testItemList value:list.
    self updateInfoLabel.

! !

!TabListEditor methodsFor:'queries'!

canToggleTestMode
    "checks whether testMode button is enabled"

    self testMode value ifTrue:[
        ^ true
    ].

    self enablingCommitButtonsHolder value ifFalse:[
        ^ listOfTabs notEmpty
    ].
    ^ false
! !

!TabListEditor methodsFor:'selection'!

selectedElement
    |idx tab|

    idx := self selection.

    idx ~~ 0 ifTrue:[
        (tab := listOfTabs at:idx ifAbsent:nil) notNil ifTrue:[
            ^ tab
        ].
        self selection:0
    ].
    ^ nil
!

selection
    ^ self selectionHolder value ? 0
!

selection:anIndex
    self selectionHolder value:(anIndex ? 0).
!

selectionChanged
    |noteBookModel hasSelection|

    hasSelection  := self selection ~~ 0.
    noteBookModel := self noteBookModel.

    hasSelection ifTrue:[
        self testMode value:false.
        noteBookModel value == 0 ifTrue:[noteBookModel value:1]
    ] ifFalse:[
        noteBookModel value:0
    ].
    self cancel.
    self hasSelectionHolder value:hasSelection.
    self canPasteHolder.
!

setSelection:anIndex
    |index|

    index := anIndex ? 0.
    self selectionHolder value:index withoutNotifying:self
! !

!TabListEditor methodsFor:'startup / release'!

initialize
    "setup aspects used by column description specifications
    "
    super initialize.
    listOfTabs := List new.
!

openModalOnTabList: aTabList
    "build a tab list from aTabList and open it modal"

    super openModalOnResourceSpec: aTabList

! !

!TabListEditor methodsFor:'user actions'!

accept
    "accept changes
    "
    |tab idx asb|

    (tab := self selectedElement) notNil ifTrue:[
        super accept.
        aspects keysAndValuesDo:[:k :m| tab perform:(k , ':') asSymbol with:(m value) ].

        asb := self autoHideScrollBars value.
        asb := asb ~~ 1 ifTrue:[asb == 2] ifFalse:[nil].
        tab autoHideScrollBars:asb.
    ].
    self cancel.
!

addTab:aTab
    |idx|

    aTab notNil ifTrue:[
        self testMode value: false.

        (idx := self selection) == 0 ifTrue:[
            listOfTabs add:aTab.
            self selection:(listOfTabs size).
        ] ifFalse:[
            listOfTabs add:aTab afterIndex:idx
        ].
        self setModified.
    ].
!

cancel
    "cancel all changes"

    |tab idx asb|

    (     (idx := self selection) ~~ 0
     and:[(tab := self selectedElement) notNil]
    ) ifTrue:[
        aspects keysAndValuesDo:[:k :m| m value:(tab perform:k) ].
        listOfTabs at:idx put:tab.

        asb := tab autoHideScrollBars.
        asb notNil ifTrue:[asb := asb == true ifTrue:[2] ifFalse:[3]]
                  ifFalse:[asb := 1].

        self autoHideScrollBars value:asb.
    ].
    self canMoveTabItemUpOrDown value:(listOfTabs size > 1 and:[idx ~~ 0]).
    self enablingCommitButtonsHolder value: false
!

doCopy
    "copy selected tab
    "
    |tab|

    (tab := self selectedElement) notNil ifTrue:[
        self clipboard:tab.
        self updateAllToolInstances.
    ]
!

doCreate
    self addTab:(TabItem label:'TAB').
!

doCut
    "cut the selected tab; put to pasteBuffer
    "
    |tab|

    (tab := self selectedElement) notNil ifTrue:[
        self clipboard:tab.
        self doDelete.
    ].

!

doDelete
    "delete selected tab
    "
    |index size|

    (index := self selection) ~~ 0 ifTrue:[
        self testMode value: false.

        (size := listOfTabs size) == 1 ifTrue:[
            self selection:0
        ] ifFalse:[
            self setSelection:0
        ].
        listOfTabs removeIndex:index.
        index < size ifFalse:[
            index := index - 1
        ].
        self selection:index.
        self updateAllToolInstances.
        self setModified.
    ].       
!

doGenerateAspectMethod
    "generate aspect method
    "
    |cls code|

    (specClass notNil and:[specSelector notNil])
    ifFalse:
    [
        ^self information:'No class and selector defined!!'   
    ].

    cls := self resolveName: specClass.

    (cls canUnderstand:specSelector) ifTrue:[
        "/ method already exists, do not overwrite the method automaticaly

        ( YesNoBox title:'method '
                         , (Text string:('#', specSelector) emphasis:#bold)
                         , ' already exists!!'
                 yesText:'overwrite'
                  noText:'cancel'
        ) confirm ifFalse:[
            ^ self
        ]
    ].

    code := '!!' , cls name , ' methodsFor:''aspects''!!\\' ,
            specSelector , '\' ,
            '    "Generated by the TabListEditor"\' ,
            '\' ,
            '    |list|\' ,
            '\' ,
            '    (list := builder bindingAt:#' , specSelector , ') isNil ifTrue:[\' ,
            '        builder aspectAt:#' , specSelector, ' put:(list := self class ', specSelector, ').\' ,
            '    ].\' ,
            '    ^ list\' ,
            '!! !!\\'.

    (ReadStream on:(code withCRs)) fileIn


!

doMoveTabUpOrDown:what
    "step up or down
    "
    |tab idx sz|

    (listOfTabs size > 1 and:[(idx := self selection) ~~ 0]) ifFalse:[
        ^ self
    ].

    (tab := listOfTabs at:idx ifAbsent:nil) isNil ifTrue:[
        ^ self selection:0
    ].

    self setSelection:0.
    listOfTabs removeIndex:idx.

    sz := listOfTabs size.

    what == #down ifTrue:[
        idx := idx > sz ifTrue:[1] ifFalse:[idx + 1]
    ] ifFalse:[
        idx := idx == 1 ifTrue:[sz + 1] ifFalse:[idx - 1]
    ].

    listOfTabs add:tab beforeIndex:idx.
    self setSelection:idx.
    self setModified.
!

doPaste
    "paste a tab
    "
    |tab|

    ((tab := self class clipboard) notNil and:[tab isKindOf:TabItem]) ifTrue:[
        self addTab:(tab deepCopy).
    ]
!

doSave
    "generate code for class and instance"

    |cls code spec category mthd list|

    (specClass notNil and:[specSelector notNil])
    ifFalse:
    [
        ^self doSaveAs
    ].

    cls := self resolveName: specClass.

    listOfTabs isEmpty ifTrue:[^self information:'No tab list defined!!'].

    spec  := WriteStream on:String new.
    list := Array new:(listOfTabs size).
    listOfTabs keysAndValuesDo:[:i :el|list at:i put:(el literalArrayEncoding)].

    UISpecification prettyPrintSpecArray:list on:spec indent:5.
    spec := spec contents.

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

    category := 'list specs'.

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

    code := Character excla asString 
            , cls name , ' class methodsFor:' , category storeString
            , Character excla asString , '\\'

            , specSelector , '\'
            , (self class codeGenerationComment replChar:$!! withString:'!!!!')
            , '\\    "\'
            , '     TabListEditor new openOnClass: self andSelector:#' , specSelector , '\'
            , '    "\'.

    code := code 
            , '\'
            , '    <resource: #tabList>\\'
            , '    ^' 
            , '     ', spec, '\'
            , '      collect:[:aTab| TabItem new fromLiteralArrayEncoding:aTab ]'
            , '\'
            , Character excla asString
            , ' '
            , Character excla asString
            , '\'.

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

    (cls canUnderstand:specSelector) ifFalse:[
        (YesNoBox confirm:'Generate aspect method?') ifTrue:[
            self doGenerateAspectMethod
        ]
    ].

    self addHistoryEntryForClass:cls selector:specSelector.
    self clearModified.
    hasSaved  := true.
!

openDocumentation
   self openHTMLDocument:'tools/uipainter/TabListEditor.html'.
! !

!TabListEditor class methodsFor:'documentation'!

version
    ^ '$Header$'
! !