--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/TabListEditor.st Fri Mar 20 19:11:50 1998 +0100
@@ -0,0 +1,1285 @@
+"
+ 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
+"
+
+
+! !
+
+!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 516 0 302 0 984 0 630 0)
+ #label: 'Tab List Editor'
+ #min: #(#Point 10 10)
+ #max: #(#Point 1152 900)
+ #bounds: #(#Rectangle 516 302 985 631)
+ #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: 'History'
+ #activeHelpKey: #history
+ #submenuChannel: #menuHistory
+ )
+ #(#MenuItem
+ #label: 'Settings'
+ #submenu:
+ #(#Menu
+
+ #(
+ #(#MenuItem
+ #label: 'Fonts'
+ #submenuChannel: #menuFont
+ )
+ ) nil
+ nil
+ )
+ )
+ #(#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
+ ]
+!
+
+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].
+ 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'
+! !