--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/TabItemEditor.st Wed Jan 28 15:05:27 1998 +0100
@@ -0,0 +1,1068 @@
+"
+ 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.
+"
+
+
+
+ToolApplicationModel subclass:#TabItemEditor
+ instanceVariableNames:'rebuildMode className selector aspects listOfTabs hasChanged
+ selectedIndex'
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Interface-UIPainter'
+!
+
+!TabItemEditor 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
+"
+ create and modify or inspect a list of tabs
+
+ [start with:]
+ TabItemEditor open
+
+ [see also:]
+ TabItem
+ TabView
+ NoteBookView
+ UIPainter
+
+ [author:]
+ Claus Atzkern
+"
+
+
+! !
+
+!TabItemEditor class methodsFor:'interface specs'!
+
+nameAndSelectorSpec
+ "this window spec was automatically generated by the ST/X UIPainter"
+
+ "do not manually edit this - the painter/builder may not be able to
+ handle the specification if its corrupted."
+
+ "
+ UIPainter new openOnClass:TabItemEditor andSelector:#nameAndSelectorSpec
+ TabItemEditor new openInterface:#nameAndSelectorSpec
+ "
+
+ <resource: #canvas>
+
+ ^
+
+ #(#FullSpec
+ #'window:'
+ #(#WindowSpec
+ #'name:' 'Class & Selector'
+ #'layout:' #(#LayoutFrame 219 0 193 0 584 0 319 0)
+ #'label:' 'Class & Selector'
+ #'min:' #(#Point 10 10)
+ #'max:' #(#Point 1152 900)
+ #'bounds:' #(#Rectangle 219 193 585 320)
+ #'usePreferredExtent:' false
+ )
+ #'component:'
+ #(#SpecCollection
+ #'collection:'
+ #(
+ #(#LabelSpec
+ #'name:' 'DefineClassAndSelector'
+ #'layout:' #(#Point 2 10)
+ #'label:' 'Define Class And Selector'
+ #'adjust:' #left
+ #'resizeForLabel:' true
+ )
+ #(#LabelSpec
+ #'name:' 'ClassLabel'
+ #'layout:' #(#AlignmentOrigin 50 0.11 51 0 1 0.5)
+ #'label:' 'Class:'
+ #'adjust:' #right
+ #'resizeForLabel:' true
+ )
+ #(#InputFieldSpec
+ #'name:' 'ClassField'
+ #'layout:' #(#LayoutFrame 51 0.11 39 0 -2 1.0 61 0)
+ #'tabable:' true
+ #'model:' #className
+ )
+ #(#LabelSpec
+ #'name:' 'SelectorLabel'
+ #'layout:' #(#AlignmentOrigin 50 0.11 74 0 1 0.5)
+ #'label:' 'Selector:'
+ #'adjust:' #right
+ #'resizeForLabel:' true
+ )
+ #(#InputFieldSpec
+ #'name:' 'SelectorField'
+ #'layout:' #(#LayoutFrame 51 0.11 64 0 -2 1.0 86 0)
+ #'tabable:' true
+ #'model:' #selector
+ )
+ #(#UISubSpecification
+ #'name:' 'CommitPanel'
+ #'layout:' #(#LayoutFrame 0 0.0 -29 1 0 1.0 -5 1)
+ #'majorKey:' #ToolApplicationModel
+ #'minorKey:' #windowSpecForCommitWithoutChannels
+ )
+ )
+ )
+ )
+!
+
+tabSpec
+ "this window spec was automatically generated by the ST/X UIPainter"
+
+ "do not manually edit this - the painter/builder may not be able to
+ handle the specification if its corrupted."
+
+ "
+ UIPainter new openOnClass:TabItemEditor andSelector:#tabSpec
+ TabItemEditor new openInterface:#tabSpec
+ "
+
+ <resource: #canvas>
+
+ ^
+
+ #(#FullSpec
+ #'window:'
+ #(#WindowSpec
+ #'name:' 'Tab Basic'
+ #'layout:' #(#LayoutFrame 219 0 193 0 506 0 397 0)
+ #'label:' 'Tab Basic'
+ #'min:' #(#Point 10 10)
+ #'max:' #(#Point 1280 1024)
+ #'bounds:' #(#Rectangle 219 193 507 398)
+ #'usePreferredExtent:' false
+ )
+ #'component:'
+ #(#SpecCollection
+ #'collection:'
+ #(
+ #(#LabelSpec
+ #'name:' 'Label'
+ #'layout:' #(#AlignmentOrigin 63 0 34 0 1 0.5)
+ #'label:' 'Label:'
+ #'resizeForLabel:' true
+ )
+ #(#InputFieldSpec
+ #'name:' 'LabelField'
+ #'layout:' #(#LayoutFrame 66 0 24 0 -4 1.0 46 0)
+ #'activeHelpKey:' #label
+ #'model:' #label
+ )
+ #(#CheckBoxSpec
+ #'name:' 'TranslateLabel'
+ #'layout:' #(#LayoutOrigin 63 0 49 0)
+ #'activeHelpKey:' #translateLabel
+ #'model:' #translateLabel
+ #'label:' 'Label derives from Application'
+ )
+ #(#ColorMenuSpec
+ #'name:' 'ForegroundColorMenu'
+ #'layout:' #(#LayoutFrame 94 0 104 0 -4 1.0 126 0)
+ #'activeHelpKey:' #foregroundColor
+ #'model:' #labelForegroundColor
+ #'labelsAreColored:' false
+ )
+ #(#LabelSpec
+ #'name:' 'ForegroundLabel'
+ #'layout:' #(#AlignmentOrigin 92 0 116 0 1 0.5)
+ #'label:' 'Foreground:'
+ #'adjust:' #right
+ #'resizeForLabel:' true
+ )
+ #(#CheckBoxSpec
+ #'name:' 'CanSelect'
+ #'layout:' #(#LayoutFrame 15 0 171 0 134 0 193 0)
+ #'model:' #enabled
+ #'label:' 'Can Select'
+ )
+ )
+ )
+ )
+!
+
+windowSpec
+ "this window spec was automatically generated by the ST/X UIPainter"
+
+ "do not manually edit this - the painter/builder may not be able to
+ handle the specification if its corrupted."
+
+ "
+ UIPainter new openOnClass:TabItemEditor andSelector:#windowSpec
+ TabItemEditor new openInterface:#windowSpec
+ "
+ "TabItemEditor open"
+
+ <resource: #canvas>
+
+ ^
+
+ #(#FullSpec
+ #'window:'
+ #(#WindowSpec
+ #'name:' 'TabItem Editor'
+ #'layout:' #(#LayoutFrame 219 0 193 0 687 0 521 0)
+ #'label:' 'TabItem Editor'
+ #'min:' #(#Point 10 10)
+ #'max:' #(#Point 1152 900)
+ #'bounds:' #(#Rectangle 219 193 688 522)
+ #'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
+ )
+ #(#VariableHorizontalPanelSpec
+ #'name:' 'VariablePanel'
+ #'layout:' #(#LayoutFrame 0 0.0 36 0.0 0 1.0 -22 1.0)
+ #'component:'
+ #(#SpecCollection
+ #'collection:'
+ #(
+ #(#SequenceViewSpec
+ #'name:' 'columnView'
+ #'enableChannel:' #isNotModified
+ #'model:' #selectionHolder
+ #'menu:' #menuEdit
+ #'hasHorizontalScrollBar:' true
+ #'hasVerticalScrollBar:' true
+ #'miniScrollerHorizontal:' true
+ #'useIndex:' true
+ #'sequenceList:' #listOfLabels
+ )
+ #(#ViewSpec
+ #'name:' 'specView'
+ #'component:'
+ #(#SpecCollection
+ #'collection:'
+ #(
+ #(#SubCanvasSpec
+ #'name:' 'specCanvas'
+ #'layout:' #(#LayoutFrame 0 0.0 0 0.0 0 1.0 -30 1.0)
+ #'specHolder:' #specChannel
+ )
+ #(#HorizontalPanelViewSpec
+ #'name:' 'modifyPanel'
+ #'layout:' #(#LayoutFrame 0 0.0 -30 1.0 0 1.0 0 1.0)
+ #'component:'
+ #(#SpecCollection
+ #'collection:'
+ #(
+ #(#ActionButtonSpec
+ #'name:' 'cancelButton'
+ #'label:' 'Cancel'
+ #'model:' #cancel
+ #'enableChannel:' #modifiedChannel
+ #'extent:' #(#Point 168 24)
+ )
+ #(#ActionButtonSpec
+ #'name:' 'acceptButton'
+ #'label:' 'OK'
+ #'model:' #accept
+ #'enableChannel:' #modifiedChannel
+ #'extent:' #(#Point 168 24)
+ )
+ )
+ )
+ #'horizontalLayout:' #fitSpace
+ #'verticalLayout:' #fitSpace
+ #'horizontalSpace:' 3
+ #'verticalSpace:' 3
+ )
+ )
+ )
+ #'borderWidth:' 1
+ )
+ )
+ )
+ #'handles:' #(#Any 0.259875 1.0)
+ )
+ #(#LabelSpec
+ #'name:' 'infoLabel'
+ #'layout:' #(#LayoutFrame 0 0.0 -22 1 -80 1.0 0 1.0)
+ #'labelChannel:' #valueOfInfoLabel
+ #'level:' 1
+ #'adjust:' #left
+ )
+ #(#LabelSpec
+ #'name:' 'timeLabel'
+ #'layout:' #(#LayoutFrame -80 1 -22 1 0 1.0 0 1.0)
+ #'labelChannel:' #valueOfTimeLabel
+ #'level:' 1
+ #'adjust:' #right
+ )
+ )
+ )
+ )
+! !
+
+!TabItemEditor class methodsFor:'menus'!
+
+menu
+ "this window spec was automatically generated by the ST/X MenuEditor"
+
+ "do not manually edit this - the builder may not be able to
+ handle the specification if its corrupted."
+
+ "
+ MenuEditor new openOnClass:TabItemEditor andSelector:#menu
+ (Menu new fromLiteralArrayEncoding:(TabItemEditor menu)) startUp
+ "
+
+ <resource: #menu>
+
+ ^
+
+ #(#Menu
+
+ #(
+ #(#MenuItem
+ #'label:' 'File'
+ #'submenu:'
+ #(#Menu
+
+ #(
+ #(#MenuItem
+ #'label:' 'New'
+ #'value:' #doNew
+ )
+ #(#MenuItem
+ #'label:' 'Reload'
+ #'value:' #doReload
+ #'enabled:' #hasClassAndSelector
+ )
+ #(#MenuItem
+ #'label:' '-'
+ )
+ #(#MenuItem
+ #'label:' 'Define Class And Selector...'
+ #'value:' #doDefineClassAndSelector
+ )
+ #(#MenuItem
+ #'label:' '-'
+ )
+ #(#MenuItem
+ #'label:' 'Create Aspect Method'
+ #'value:' #doInstallAspect
+ #'enabled:' #hasClassAndSelector
+ )
+ #(#MenuItem
+ #'label:' '-'
+ )
+ #(#MenuItem
+ #'label:' 'Exit'
+ #'value:' #closeRequest
+ #'enabled:' #isNotModified
+ )
+ ) nil
+ nil
+ )
+ )
+ ) nil
+ nil
+ )
+!
+
+menuEdit
+ "this window spec was automatically generated by the ST/X MenuEditor"
+
+ "do not manually edit this - the builder may not be able to
+ handle the specification if its corrupted."
+
+ "
+ MenuEditor new openOnClass:self andSelector:#menuEdit
+ (Menu new fromLiteralArrayEncoding:(self menuEdit)) startUp
+ "
+
+ <resource: #menu>
+
+ ^
+
+ #(#Menu
+
+ #(
+ #(#MenuItem
+ #'label:' 'Cut'
+ #'value:' #doCutTab
+ #'enabled:' #isColumnSelected
+ #'shortcutKeyCharacter:' #Cut
+ )
+ #(#MenuItem
+ #'label:' 'Copy'
+ #'value:' #doCopyTab
+ #'enabled:' #isColumnSelected
+ #'shortcutKeyCharacter:' #Copy
+ )
+ #(#MenuItem
+ #'label:' 'Paste'
+ #'value:' #doPasteTab
+ #'enabled:' #valueOfHavingClipboard
+ #'shortcutKeyCharacter:' #Paste
+ )
+ ) nil
+ nil
+ )
+
+!
+
+menuToolbar
+ "this window spec was automatically generated by the ST/X MenuEditor"
+
+ "do not manually edit this - the builder may not be able to
+ handle the specification if its corrupted."
+
+ "
+ MenuEditor new openOnClass:TabItemEditor andSelector:#menuToolbar
+ (Menu new fromLiteralArrayEncoding:(TabItemEditor menuToolbar)) startUp
+ "
+
+ <resource: #menu>
+
+ ^
+
+ #(#Menu
+
+ #(
+ #(#MenuItem
+ #'label:' 'Save'
+ #'isButton:' true
+ #'value:' #doInstallSpec
+ #'enabled:' #isNotModified
+ #'labelImage:' #(#ResourceRetriever nil #saveIcon)
+ )
+ #(#MenuItem
+ #'label:' ''
+ )
+ #(#MenuItem
+ #'label:' 'createLabel'
+ #'isButton:' true
+ #'value:' #doCreateTab
+ #'enabled:' #isNotModified
+ #'labelImage:' #(#ResourceRetriever #MenuEditor #menuItemImage)
+ )
+ #(#MenuItem
+ #'label:' ''
+ )
+ #(#MenuItem
+ #'label:' 'Move Tab Up'
+ #'isButton:' true
+ #'value:' #'doMoveTabUpOrDown:'
+ #'enabled:' #canMoveTabUpOrDown
+ #'argument:' #up
+ #'labelImage:' #(#ResourceRetriever nil #upIcon)
+ )
+ #(#MenuItem
+ #'label:' 'Move Tab Down'
+ #'isButton:' true
+ #'value:' #'doMoveTabUpOrDown:'
+ #'enabled:' #canMoveTabUpOrDown
+ #'argument:' #down
+ #'labelImage:' #(#ResourceRetriever nil #downIcon)
+ )
+ ) nil
+ nil
+ )
+! !
+
+!TabItemEditor class methodsFor:'resources'!
+
+newLabelIcon
+ "ImageEditor openOnClass:self andSelector:#newLabelIcon"
+
+ <resource: #image>
+ ^(Depth4Image new) width: 22; height: 22; photometric:(#palette); bitsPerSample:(#(4 )); samplesPerPixel:(1); bits:(#[17 17 16 0 0 0 0 0 0 17 17 17 17 16 17 17 17 17 17 32 17 17 17 17 16 18 34 34 34 34 48 17 17 17 17 16 18 32 2 32 34 48 17 17 17 17 16 18 2 34 2 2 48 17 17 17 17 16 18 2 34 2 2 48 17 17 17 17 16 18 32 2 32 34 48 17 17 16 17 16 18 34 34 34 34 48 17 17 17 17 16 18 2 34 2 2 48 17 17 17 17 16 18 2 34 2 2 48 17 17 17 17 16 18 2 34 2 2 48 17 17 17 17 16 18 0 2 0 2 48 17 17 17 17 16 18 34 34 34 34 48 17 17 17 17 16 18 34 34 34 34 48 17 17 17 17 16 18 2 2 2 2 48 17 17 17 17 16 18 0 2 0 2 48 17 17 17 17 16 18 2 2 0 2 48 17 17 17 17 16 18 2 2 2 2 48 17 17 17 17 16 18 34 34 34 34 48 17 17 17 17 16 18 34 34 34 34 48 17 17 17 17 16 35 51 51 51 51 48 17 17 17 17 16 0 0 0 0 0 0 17 17]) ; colorMap:((OrderedCollection new add:(Color black); add:(Color white); add:(Color grey:66.9978); add:(Color grey:49.9962); add:(Color red:100.0 green:0.0 blue:0.0); add:(Color red:0.0 green:100.0 blue:0.0); add:(Color red:0.0 green:0.0 blue:100.0); add:(Color red:0.0 green:100.0 blue:100.0); add:(Color red:100.0 green:100.0 blue:0.0); add:(Color red:100.0 green:0.0 blue:100.0); add:(Color red:49.9992 green:0.0 blue:0.0); add:(Color red:0.0 green:49.9992 blue:0.0); add:(Color red:0.0 green:0.0 blue:49.9992); add:(Color red:0.0 green:49.9992 blue:49.9992); add:(Color red:49.9992 green:49.9992 blue:0.0); add:(Color red:49.9992 green:0.0 blue:49.9992); yourself)); mask:((Depth1Image new) width: 22; height: 22; photometric:(#blackIs0); bitsPerSample:(#(1 )); samplesPerPixel:(1); bits:(#[7 255 192 7 255 192 7 255 192 7 255 192 7 255 192 7 255 192 7 255 192 7 255 192 7 255 195 7 255 192 7 255 192 7 255 192 7 255 192 7 255 195 7 255 193 7 255 192 7 255 195 7 255 192 7 255 195 7 255 192 7 255 192 7 255 193]) ; yourself); yourself
+
+
+! !
+
+!TabItemEditor methodsFor:'accessing'!
+
+className
+ ^ className
+!
+
+selector
+ ^ selector
+! !
+
+!TabItemEditor methodsFor:'actions'!
+
+accept
+ "accept changes
+ "
+ |label|
+
+ self modified ifTrue:[
+ selectedIndex ~~ 0 ifTrue:[
+ rebuildMode := true.
+ label := listOfTabs at:selectedIndex.
+ hasChanged := true.
+
+ aspects keysAndValuesDo:[:aKey :aModel|
+ label perform:(aKey , ':') asSymbol with:(aModel value).
+ ].
+ self listOfLabels at:selectedIndex put:(label label).
+
+ rebuildMode := false.
+ ].
+ self cancel
+ ]
+!
+
+cancel
+ "cancel all changes
+ "
+ |tab|
+
+ rebuildMode ifFalse:[
+ selectedIndex ~~ 0 ifTrue:[
+ tab := listOfTabs at:selectedIndex.
+
+ rebuildMode := true.
+
+ aspects keysAndValuesDo:[:aKey :aModel|
+ aModel value:(tab perform:aKey)
+ ].
+
+ rebuildMode := false.
+ ].
+ self modified:false.
+ ].
+ self canMoveTabUpOrDown value:(selectedIndex ~~ 0 and:[listOfTabs size > 1])
+
+
+
+
+!
+
+modified
+ "returns true if current tab is modified
+ "
+ ^ self modifiedChannel value
+!
+
+modified:aState
+ "change modification state
+ "
+ rebuildMode ifFalse:[
+ self modifiedChannel value:aState.
+ self isNotModified value:(aState not).
+ ]
+! !
+
+!TabItemEditor methodsFor:'aspects'!
+
+aspectFor:aKey
+ "returns aspect for a key or nil
+ "
+ ^ aspects at:aKey ifAbsent:[ super aspectFor:aKey ]
+
+
+!
+
+canMoveTabUpOrDown
+
+ |holder|
+
+ (holder := builder bindingAt:#canMoveTabUpOrDown) isNil ifTrue:[
+ builder aspectAt:#canMoveTabUpOrDown put:(holder := false asValue).
+ ].
+ ^ holder
+
+!
+
+hasClassAndSelector
+
+ |holder|
+
+ (holder := builder bindingAt:#hasClassAndSelector) isNil ifTrue:[
+ builder aspectAt:#hasClassAndSelector put:(holder := false asValue).
+ ].
+ ^ holder
+
+!
+
+isNotModified
+ "returns true if current tab spec is not modified
+ "
+ |holder|
+
+ (holder := builder bindingAt:#isNotModified) isNil ifTrue:[
+ builder aspectAt:#isNotModified put:(holder := true 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
+!
+
+modifiedChannel
+ "channel which is true if the current tab specification is modified
+ "
+ |holder|
+
+ (holder := builder bindingAt:#modifiedChannel) isNil ifTrue:[
+ builder aspectAt:#modifiedChannel put:(holder := false asValue).
+ ].
+ ^ holder
+!
+
+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
+! !
+
+!TabItemEditor methodsFor:'change & update'!
+
+update:something with:aParameter from:someObject
+ "one of my aspects has changed; update modified channel
+ "
+ self modified:true.
+
+
+! !
+
+!TabItemEditor methodsFor:'selection'!
+
+selectedIndex
+ ^ selectedIndex
+!
+
+selectedIndex:anIndex
+ |s oldSel|
+
+ 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.
+! !
+
+!TabItemEditor methodsFor:'startup / release'!
+
+buildFrom:aClass andSelector:aSelector
+ "build from class and selector
+ "
+ |spec list validClSl|
+
+ self doNew.
+
+ selector := nil.
+ className := self resolveName:aClass.
+ validClSl := false.
+
+ className notNil ifTrue:[
+ aSelector notNil ifTrue:[
+ validClSl := true.
+ selector := aSelector asSymbol.
+
+ (className respondsTo:selector) ifTrue:[
+ spec := className perform:selector.
+ list := self listOfLabels.
+
+ spec size ~~ 0 ifTrue:[
+
+ rebuildMode := true.
+
+ spec do:[:aTab|
+ list add:aTab label.
+ listOfTabs add:aTab.
+ ].
+ rebuildMode := false.
+ ]
+ ]
+ ]
+ ].
+
+ self hasClassAndSelector value:validClSl.
+ self modified:false.
+ hasChanged := false.
+
+ listOfTabs notEmpty ifTrue:[
+ self selectionHolder value:1
+ ].
+!
+
+closeRequest
+
+ hasChanged ifTrue:[
+ ( YesNoBox title:'tab description was modified!!'
+ yesText:'waste it and proceed'
+ noText:'cancel'
+ ) confirm ifFalse:[
+ ^ self
+ ].
+ hasChanged := false.
+ ].
+ super closeRequest.
+!
+
+initialize
+ "setup aspects used by column description specifications
+ "
+ |holder|
+
+ super initialize.
+
+ aspects := IdentityDictionary new.
+ listOfTabs := OrderedCollection new.
+ hasChanged := false.
+ selectedIndex := 0.
+ rebuildMode := false.
+
+ #(
+ label
+ translateLabel
+ labelForegroundColor
+ enabled
+
+ ) do:[:aKey|
+ aspects at:aKey put:(holder := ValueHolder new).
+ holder addDependent:self.
+ ].
+
+
+!
+
+openModalOnClass:aClass andSelector:aSelector
+
+ className := aClass.
+ selector := aSelector.
+
+ super openInterfaceModal.
+
+
+!
+
+openOnClass:aClass andSelector:aSelector
+
+ className := aClass.
+ selector := aSelector.
+
+ super openInterface.
+
+
+!
+
+postBuildWith:builder
+ self buildFrom:className andSelector:selector.
+! !
+
+!TabItemEditor methodsFor:'user interactions'!
+
+doCopyTab
+ "copy selected tab
+ "
+ selectedIndex ~~ 0 ifTrue:[
+ self clipboard:(listOfTabs at:selectedIndex) deepCopy
+ ]
+!
+
+doCreateTab
+ |tab|
+
+ tab := TabItem label:'label'.
+
+ listOfTabs add:tab afterIndex:selectedIndex.
+ self listOfLabels add:(tab label) afterIndex:selectedIndex.
+ hasChanged := true.
+
+ selectedIndex == 0 ifTrue:[
+ self selectionHolder value:1
+ ] ifFalse:[
+ self cancel.
+ ]
+!
+
+doCutTab
+ "cut selected tab
+ "
+ |list index|
+
+ (index := selectedIndex) ~~ 0 ifTrue:[
+ list := self listOfLabels.
+ self clipboard:(listOfTabs at:index) deepCopy.
+ self selectionHolder value:0.
+ listOfTabs removeIndex:index.
+ list removeIndex:index.
+ hasChanged := true.
+
+ index > list size ifTrue:[
+ index := index - 1
+ ].
+ self selectionHolder value:index
+ ]
+
+!
+
+doDefineClassAndSelector
+ "launch a dialog to define class and selector
+ "
+ |cls sel bindings|
+
+ bindings := IdentityDictionary new.
+
+ [true] whileTrue:[
+ cls := className notNil ifTrue:[className name] ifFalse:['NewApplication'].
+ sel := selector ? 'tabItemList'.
+
+ bindings at:#className put:cls asValue.
+ bindings at:#selector put:sel asValue.
+
+ (self openDialogInterface:#nameAndSelectorSpec withBindings:bindings)
+ ifFalse:[ ^ self ].
+
+ cls := (bindings at:#className) value withoutSeparators.
+ sel := (bindings at:#selector) value withoutSeparators.
+
+ (cls := self resolveName:cls) notNil ifTrue:[
+ className := cls.
+
+ sel notNil ifTrue:[
+ selector := sel asSymbol.
+ ^ self hasClassAndSelector value:true.
+ ]
+ ]
+ ]
+!
+
+doInstallAspect
+ "generate aspect method
+ "
+ |code|
+
+ className isNil ifTrue:[ ^ self information:'No valid class defined!!'].
+ selector isNil ifTrue:[ ^ self information:'No selector defined!!' ].
+
+ (className canUnderstand:selector) ifTrue:[
+ "/ method already exists, do not overwrite the method automaticaly
+
+ ( YesNoBox title:'method '
+ , (Text string:('#', selector) emphasis:#bold)
+ , ' already exists'
+ yesText:'overwrite'
+ noText:'cancel'
+ ) confirm ifFalse:[
+ ^ self
+ ]
+ ].
+
+ code := '!!' , className name , ' methodsFor:''aspects''!!\\' ,
+ selector , '\' ,
+ ' "automatically generated by TabItem Editor ..."\' ,
+ '\' ,
+ ' |list|\' ,
+ '\' ,
+ ' (list := builder bindingAt:#' , selector , ') isNil ifTrue:[\' ,
+ ' builder aspectAt:#' , selector, ' put:(list := self class ', selector, ').\' ,
+ ' ].\' ,
+ ' ^ list\' ,
+ '!! !!\\'.
+
+ (ReadStream on:(code withCRs)) fileIn
+
+
+!
+
+doInstallSpec
+ "generate code for class and instance
+ "
+ |code spec category mthd|
+
+ (className isNil or:[selector isNil]) ifTrue:[
+ self doDefineClassAndSelector
+ ].
+ className isNil ifTrue:[ ^ self information:'No valid class defined!!'].
+ selector isNil ifTrue:[ ^ self information:'No selector defined!!' ].
+ listOfTabs isEmpty ifTrue:[ ^ self information:'No valid tabs 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 := 'interface specs'.
+
+ (mthd := className class compiledMethodAt:selector) notNil ifTrue:[
+ category := mthd category.
+ ].
+
+ code := Character excla asString
+ , className name , ' class methodsFor:' , category storeString
+ , Character excla asString , '\\'
+
+ , selector , '\'
+ , ' "this window spec was automatically generated by the ST/X TabItemEditor"\\'
+ , ' "do not manually edit this - the builder may not be able to\'
+ , ' handle the specification if its corrupted."\\'
+ , ' "\'
+ , ' TabItemEditor new openOnClass:' , className name , ' andSelector:#' , selector , '\'
+ , ' "\'.
+
+ code := code
+ , '\'
+ , ' <resource: #tabItem>\\'
+ , ' ^\'
+ , ' ', spec, '\'
+ , ' collect:[:aTab| TabItem new fromLiteralArrayEncoding:aTab ]'
+ , '\'
+ , Character excla asString
+ , ' '
+ , Character excla asString
+ , '\\'.
+
+ code := code withCRs.
+ (ReadStream on:code) fileIn.
+ hasChanged := false.
+
+ (className canUnderstand:selector) ifFalse:[
+ (YesNoBox confirm:'install aspect method') ifTrue:[
+ self doInstallAspect
+ ]
+ ]
+
+
+!
+
+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.
+ hasChanged := true.
+
+ rebuildMode := true.
+ self selectionHolder value:index.
+ rebuildMode := false.
+
+
+!
+
+doNew
+
+ self modified:false.
+
+ rebuildMode := true.
+
+ self selectionHolder value:0.
+ self listOfLabels removeAll.
+ listOfTabs removeAll.
+
+ hasChanged := true.
+ rebuildMode := false.
+!
+
+doPasteTab
+ "paste a tab
+ "
+ |tab|
+
+ tab := self class clipboard deepCopy.
+ listOfTabs add:tab afterIndex:selectedIndex.
+ self listOfLabels add:(tab label) afterIndex:selectedIndex.
+ hasChanged := true.
+
+ selectedIndex == 0 ifTrue:[
+ self selectionHolder value:1
+ ]
+!
+
+doReload
+ "reload from class and selector
+ "
+ self buildFrom:className andSelector:selector
+! !
+
+!TabItemEditor class methodsFor:'documentation'!
+
+version
+ ^ '$Header$'
+! !