TabListEditor.st
author ca
Wed, 01 Apr 1998 11:35:57 +0200
changeset 759 f0c325edcc6c
parent 749 8f8767c6f32f
child 883 10afc79658a6
permissions -rw-r--r--
add scroller

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

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



ResourceSpecEditor subclass:#TabListEditor
	instanceVariableNames:'rebuildMode testView listOfTabs selectedIndex'
	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
    )

! !

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

#argument
'An argument not explicitly used by the tab item.'

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

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

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

#label
'Label of the tab item.'

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

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

)
! !

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

tabSpec
    "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:#tabSpec
     TabListEditor new openInterface:#tabSpec
    "

    <resource: #canvas>

    ^
     
       #(#FullSpec
          #window: 
           #(#WindowSpec
              #name: 'Tab Basic'
              #layout: #(#LayoutFrame 463 0 289 0 825 0 514 0)
              #label: 'Tab Basic'
              #min: #(#Point 10 10)
              #max: #(#Point 1280 1024)
              #bounds: #(#Rectangle 463 289 826 515)
              #usePreferredExtent: false
          )
          #component: 
           #(#SpecCollection
              #collection: 
               #(
                 #(#LabelSpec
                    #name: 'Label'
                    #layout: #(#AlignmentOrigin 98 0 26 0 1 0.5)
                    #label: 'Label:'
                    #resizeForLabel: true
                )
                 #(#InputFieldSpec
                    #name: 'LabelField'
                    #layout: #(#LayoutFrame 100 0 15 0 -5 1.0 37 0)
                    #activeHelpKey: #label
                    #model: #label
                )
                 #(#CheckBoxSpec
                    #name: 'TranslateLabel'
                    #layout: #(#LayoutFrame 100 0 40 0 -5 1 66 0)
                    #activeHelpKey: #labelDerivesFromApplication
                    #model: #translateLabel
                    #label: 'Label derives from Application'
                )
                 #(#LabelSpec
                    #name: 'ArgumentLabel'
                    #layout: #(#AlignmentOrigin 98 0 81 0 1 0.5)
                    #label: 'Argument:'
                    #resizeForLabel: true
                )
                 #(#InputFieldSpec
                    #name: 'ArgumentField'
                    #layout: #(#LayoutFrame 100 0 70 0 -5 1.0 92 0)
                    #activeHelpKey: #argument
                    #model: #editAgument
                )
                 #(#LabelSpec
                    #name: 'ForegroundLabel'
                    #layout: #(#AlignmentOrigin 98 0 115 0 1 0.5)
                    #label: 'Color:'
                    #adjust: #right
                    #resizeForLabel: true
                )
                 #(#ColorMenuSpec
                    #name: 'ForegroundColorMenu'
                    #layout: #(#LayoutFrame 100 0 103 0 -5 1.0 125 0)
                    #activeHelpKey: #color
                    #model: #labelForegroundColor
                    #labelsAreColored: false
                )
                 #(#CheckBoxSpec
                    #name: 'CanSelect'
                    #layout: #(#LayoutFrame 100 0 135 0 -5 1 157 0)
                    #activeHelpKey: #canSelect
                    #model: #enabled
                    #label: 'Can Select'
                )
              )
          )
      )
!

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
          #window: 
           #(#WindowSpec
              #name: 'Tab List Editor'
              #layout: #(#LayoutFrame 117 0 340 0 586 0 669 0)
              #label: 'Tab List Editor'
              #min: #(#Point 440 280)
              #max: #(#Point 1152 900)
              #bounds: #(#Rectangle 117 340 587 670)
              #menu: #menu
              #usePreferredExtent: false
          )
          #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: 
                         #(
                           #(#SequenceViewSpec
                              #name: 'ColumnView'
                              #model: #selectionHolder
                              #menu: #menuEdit
                              #hasHorizontalScrollBar: true
                              #hasVerticalScrollBar: true
                              #miniScrollerHorizontal: true
                              #useIndex: true
                              #sequenceList: #listOfLabels
                          )
                           #(#ViewSpec
                              #name: 'SpecView'
                              #component: 
                               #(#SpecCollection
                                  #collection: 
                                   #(
                                     #(#ViewSpec
                                        #name: 'TestView'
                                        #layout: #(#LayoutFrame 1 0.0 0 0.0 0 1.0 0 1.0)
                                        #component: 
                                         #(#SpecCollection
                                            #collection: 
                                             #(
                                               #(#TabViewSpec
                                                  #name: 'TestTabsView'
                                                  #layout: #(#LayoutFrame 0 0.0 0 0.0 0 1.0 0 0.5)
                                              )
                                            )
                                        )
                                    )
                                     #(#SubCanvasSpec
                                        #name: 'specCanvas'
                                        #layout: #(#LayoutFrame 1 0.0 0 0.0 0 1.0 -30 1.0)
                                        #specHolder: #specChannel
                                    )
                                     #(#UISubSpecification
                                        #name: 'subSpec'
                                        #layout: #(#LayoutFrame 2 0.0 -26 1 -2 1.0 -2 1)
                                        #majorKey: #ToolApplicationModel
                                        #minorKey: #windowSpecForCommit
                                    )
                                  )
                              )
                              #level: -1
                          )
                        )
                    )
                    #handles: #(#Any 0.259875 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:'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: #doCreateTabItem
                          #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: #canShowTestMode
                          #indication: #testMode
                      )
                    ) nil
                    nil
                )
            )
             #(#MenuItem
                #label: 'Settings'
                #submenu: 
                 #(#Menu
                    
                     #(
                       #(#MenuItem
                          #label: 'Fonts'
                          #submenuChannel: #menuFont
                      )
                    ) 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: #valueOfCanCut
            )
             #(#MenuItem
                #label: 'Copy'
                #value: #doCopy
                #activeHelpKey: #editCopy
                #enabled: #valueOfCanCopy
            )
             #(#MenuItem
                #label: 'Paste'
                #value: #doPaste
                #activeHelpKey: #editPaste
                #enabled: #valueOfCanPaste
            )
             #(#MenuItem
                #label: 'Delete'
                #value: #doDelete
                #activeHelpKey: #editPaste
                #enabled: #valueOfCanCut
            )
             #(#MenuItem
                #label: '-'
            )
             #(#MenuItem
                #label: 'Move Up'
                #value: #doMoveTabUpOrDown:
                #activeHelpKey: #editMoveUp
                #enabled: #canMoveTabItemUpOrDown
                #argument: #up
                #labelImage: #(#ResourceRetriever #ToolApplicationModel #upIcon 'Move Up')
            )
             #(#MenuItem
                #label: 'Move Down'
                #value: #doMoveTabUpOrDown:
                #activeHelpKey: #editMoveDown
                #enabled: #canMoveTabItemUpOrDown
                #argument: #down
                #labelImage: #(#ResourceRetriever #ToolApplicationModel #downIcon 'Move Down')
            )
          ) 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
                #label: 'New'
                #isButton: true
                #value: #doNew
                #activeHelpKey: #fileNew
                #labelImage: #(#ResourceRetriever nil #newIcon)
            )
             #(#MenuItem
                #label: 'Load'
                #isButton: true
                #value: #doLoad
                #activeHelpKey: #fileLoad
                #labelImage: #(#ResourceRetriever nil #loadIcon)
            )
             #(#MenuItem
                #label: 'Save'
                #isButton: true
                #value: #doSave
                #activeHelpKey: #fileSave
                #labelImage: #(#ResourceRetriever nil #saveIcon)
            )
             #(#MenuItem
                #label: ''
            )
             #(#MenuItem
                #label: 'Cut'
                #isButton: true
                #value: #doCut
                #activeHelpKey: #editCut
                #enabled: #valueOfCanCut
                #labelImage: #(#ResourceRetriever nil #cutIcon)
            )
             #(#MenuItem
                #label: 'Copy'
                #isButton: true
                #value: #doCopy
                #activeHelpKey: #editCopy
                #enabled: #valueOfCanCopy
                #labelImage: #(#ResourceRetriever nil #copyIcon)
            )
             #(#MenuItem
                #label: 'Paste'
                #isButton: true
                #value: #doPaste
                #activeHelpKey: #editPaste
                #enabled: #valueOfCanPaste
                #labelImage: #(#ResourceRetriever nil #pasteIcon)
            )
             #(#MenuItem
                #label: 'Delete'
                #isButton: true
                #value: #doDelete
                #activeHelpKey: #editDelete
                #enabled: #valueOfCanCut
                #labelImage: #(#ResourceRetriever nil #deleteIcon)
            )
             #(#MenuItem
                #label: ''
            )
             #(#MenuItem
                #label: 'Add Tab Item'
                #isButton: true
                #value: #doCreateTabItem
                #activeHelpKey: #addTabItem
                #labelImage: #(#ResourceRetriever nil #newTabItemIcon)
            )
             #(#MenuItem
                #label: ''
            )
             #(#MenuItem
                #label: 'Move Tab Up'
                #isButton: true
                #value: #doMoveTabUpOrDown:
                #activeHelpKey: #editMoveUp
                #enabled: #canMoveTabItemUpOrDown
                #argument: #up
                #labelImage: #(#ResourceRetriever nil #upIcon)
            )
             #(#MenuItem
                #label: 'Move Tab Down'
                #isButton: true
                #value: #doMoveTabUpOrDown:
                #activeHelpKey: #editMoveDown
                #enabled: #canMoveTabItemUpOrDown
                #argument: #down
                #labelImage: #(#ResourceRetriever nil #downIcon)
            )
             #(#MenuItem
                #label: ''
            )
             #(#MenuItem
                #label: 'Preview'
                #activeHelpKey: #testPreview
                #enabled: #canShowTestMode
                #indication: #testMode
            )
          ) nil
          nil
      )
! !

!TabListEditor methodsFor:'aspects'!

canMoveTabItemUpOrDown

    |holder|

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

!

canShowTestMode

    |holder|

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

!

listOfLabels
    "returns a holder which keeps the list of tab labels
    "
    |list|

    (list := builder bindingAt:#listOfLabels) isNil ifTrue:[
        builder aspectAt:#listOfLabels put:(list :=  List new).
    ].
    ^ list
!

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

    (holder := builder bindingAt:#selectionHolder) isNil ifTrue:[
        holder := AspectAdaptor new subject:self; forAspect:#selectedIndex.
        builder aspectAt:#selectionHolder put:holder.
    ].
    ^ holder
!

specChannel
    "holder which keeps the current tab specification
    "
    |holder|

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

testMode

    |holder|

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

! !

!TabListEditor methodsFor:'building'!

buildFromClass:aClass andSelector:aSelector
    "build from class and selector
    "
    |cls spec list|

    self testMode value: false.
    self selectionHolder value:0.

    "if opened on a tab list"
    (aClass isNil and: [aSelector isNil and: [listOfTabs size > 0]]) 
    ifTrue: 
    [
        listOfTabs notEmpty ifTrue:[
            self selectionHolder value:1
        ].
        ^nil
    ].

    self listOfLabels removeAll.
    listOfTabs removeAll.

    testView notNil ifTrue:[
        testView lower
    ].

    rebuildMode := false.

    self canShowTestMode value: false.

    cls := self resolveName:aClass.
    specSelector := aSelector.

    cls notNil ifTrue:[
        specSelector notNil ifTrue:[

            (cls respondsTo:specSelector) ifTrue:[
                spec := cls perform:specSelector.
                list := self listOfLabels.

                spec size ~~ 0 ifTrue:[

                    rebuildMode := true.

                    spec do:[:aTab|
                        list add:aTab label.
                        listOfTabs add:aTab.
                    ].
                    rebuildMode := false.          
                    self addToHistory:(cls name, ' ', specSelector) -> #loadFromMessage:                        
                ]
            ]
        ]
    ].

    modified := false.

    listOfTabs notEmpty ifTrue:[
        self selectionHolder value:1
    ].

    self updateInfoLabel
!

buildFromResourceSpec: aListSpec

    self buildFromTabList: aListSpec
!

buildFromTabList: aTabList
    "build from a aTabList"

    rebuildMode := true.

    self selectionHolder value: nil.
    self listOfLabels removeAll.
    listOfTabs removeAll.

    aTabList do:[:aTabItem|
        listOfTabs add: aTabItem.
        self listOfLabels add: aTabItem label
    ].
    rebuildMode := false.          

    modified := false.

    listOfTabs notEmpty ifTrue:[
        self selectionHolder value:1
    ].

    self updateInfoLabel
! !

!TabListEditor methodsFor:'change & update'!

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

    someObject = self testMode
    ifTrue:
    [              
        someObject value
            ifTrue: [self doTest]
            ifFalse:[testView lower. self selectionHolder value:1].

        self updateInfoLabel
    ]
! !

!TabListEditor methodsFor:'help'!

defaultInfoLabel

    ^self testMode value
        ifTrue:  ['Test mode']
        ifFalse: [super defaultInfoLabel]
! !

!TabListEditor methodsFor:'selection'!

selectedIndex
    ^ selectedIndex
!

selectedIndex:anIndex
    |s oldSel|

    self listOfLabels notEmpty ifTrue: [self canShowTestMode value: true].
    anIndex notNil ifTrue: [self testMode value: false].

    oldSel := selectedIndex.
    selectedIndex := anIndex ? 0.

    selectedIndex == oldSel ifTrue:[^ self].

    oldSel == 0 ifTrue:[
        self specChannel value:(self class tabSpec)
    ] ifFalse:[
        selectedIndex == 0 ifTrue:[
            self specChannel value:nil
        ]
    ].
    self cancel.

    testView notNil ifTrue:[
        testView lower.
    ].

    self valueOfCanCut value: (anIndex ~~ 0).
    self valueOfCanCopy value: (anIndex ~~ 0).
    self valueOfCanPaste.

    self updateFonts
! !

!TabListEditor methodsFor:'startup / release'!

initialize
    "setup aspects used by column description specifications
    "
    |holder|

    super initialize.

    listOfTabs    := OrderedCollection new.
    selectedIndex := 0.
    rebuildMode   := false.


!

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

    super openModalOnResourceSpec: aTabList

!

postBuildWith:builder

    super postBuildWith:builder.

    testView := builder componentAt:#TestView.
    (builder componentAt:#ColumnView) selectConditionBlock: [:i|self askForItemModification].
! !

!TabListEditor methodsFor:'user actions'!

accept
    "accept changes
    "
    |label|

    selectedIndex ~~ 0 ifTrue:[
        rebuildMode := true.
        label := listOfTabs at:selectedIndex.

        aspects keysAndValuesDo:[:aKey :aModel|
            label perform:(aKey , ':') asSymbol with:(aModel value).
        ].
        self listOfLabels at:selectedIndex put:(label label).

        rebuildMode := false.
    ].
    self cancel.
    modified := true.
    self valueOfEnablingCommitButtons value: false
!

cancel
    "cancel all changes
    "
    |tab|

    selectedIndex ~~ 0 ifTrue:[
        tab := listOfTabs at:selectedIndex.

        rebuildMode := true.

        aspects keysAndValuesDo:[:aKey :aModel|
            aModel value:(tab perform:aKey)    
        ].

        rebuildMode := false.
    ].
    self canMoveTabItemUpOrDown value:(selectedIndex ~~ 0 and:[listOfTabs size > 1]).
    self valueOfEnablingCommitButtons value: false



!

doCopy
    "copy selected tab
    "
    selectedIndex ~~ 0 ifTrue:[
        self clipboard:(listOfTabs at:selectedIndex) deepCopy.
        self updateAllToolInstances.
    ]
!

doCreateTabItem

    |tab|
    self testMode value: false.
    tab := TabItem label:'Tab Item ', (listOfTabs size + 1) printString.

    listOfTabs add:tab afterIndex:selectedIndex.
    self listOfLabels add:(tab label) afterIndex:selectedIndex.

    selectedIndex == 0 ifTrue:[
        self selectionHolder value:1
    ] ifFalse:[    
        self selectionHolder value:selectedIndex + 1.
        self cancel.
    ].

    modified := true.
!

doCut
    "cut selected tab
    "
    |list index|

    (index := selectedIndex) ~~ 0 ifTrue:[
        self testMode value: false.
        list := self listOfLabels.
        self clipboard:(listOfTabs at:index) deepCopy.
        self selectionHolder value:0.
        listOfTabs removeIndex:index.
        list removeIndex:index.
        index > list size ifTrue:[
            index := index - 1
        ].
        self selectionHolder value:index.
        self listOfLabels isEmpty ifTrue: [self canShowTestMode value: false].
        self updateAllToolInstances.
        modified := true.
    ].

!

doDelete
    "delete selected tab
    "
    |list index|

    (index := selectedIndex) ~~ 0 ifTrue:[
        self testMode value: false.
        list := self listOfLabels.
        self selectionHolder value:0.
        listOfTabs removeIndex:index.
        list removeIndex:index.
        index > list size ifTrue:[index := index - 1].
        self selectionHolder value:index.
        self listOfLabels isEmpty ifTrue: [self canShowTestMode value: false].
        modified := true.
    ].       
!

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 list index|

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

    list := self listOfLabels.
    tab  := listOfTabs at:selectedIndex.

    list removeIndex:selectedIndex.
    listOfTabs removeIndex:selectedIndex.

    what == #down ifTrue:[
        index := selectedIndex > list size ifTrue:[1]
                                          ifFalse:[selectedIndex + 1]
    ] ifFalse:[
        index := selectedIndex == 1 ifTrue:[list size + 1]
                                   ifFalse:[selectedIndex - 1]
    ].

    list add:(tab label) beforeIndex:index.
    listOfTabs add:tab beforeIndex:index.

    rebuildMode := true.
    self selectionHolder value:index.
    rebuildMode := false.

    modified := true.

!

doPaste
    "paste a tab
    "
    |tab|

    self testMode value: false.
    (tab := self class clipboard deepCopy) isNil ifTrue: [^nil].
    listOfTabs add:tab afterIndex:selectedIndex.
    self listOfLabels add:(tab label) afterIndex:selectedIndex.

    selectedIndex == 0 ifTrue:[
        self selectionHolder value:1
    ] ifFalse:[    
        self selectionHolder value:selectedIndex + 1.
        self cancel.
    ].
      
    modified  := true.

!

doSave
    "generate code for class and instance
    "
    |cls code spec category mthd|

    (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.
    UISpecification prettyPrintSpecArray:(listOfTabs literalArrayEncoding) 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:' , cls name , ' 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 addToHistory:(cls name, ' ', specSelector) -> #loadFromMessage:.
    modified  := false.
    hasSaved  := true.
!

doTest
    "run a test
    "
    |tabView list|

    self selectionHolder value:nil.

    listOfTabs size ~~ 0 ifTrue:[
        list := listOfTabs collect:[:aTab||t|
            t := aTab copy.
            t setAttributesFromClass:specClass.
            t
        ]
    ] ifFalse:[
        list := nil
    ].
    tabView  := builder componentAt:#TestTabsView.
    tabView list:list.
    testView raise.

    self valueOfCanCut value: false.
    self valueOfCanCopy value: false.
    self valueOfCanPaste value: false.

! !

!TabListEditor class methodsFor:'documentation'!

version
    ^ '$Header: /files/CVS/stx/libtool2/TabListEditor.st,v'
! !