# HG changeset patch # User ca # Date 885996327 -3600 # Node ID c18c7621f8e95e44a98963d373029c0340bdfdf8 # Parent da5c2e271d1ab35e4ee46f7f4310a92c5328ab3e initial checkin diff -r da5c2e271d1a -r c18c7621f8e9 TabItemEditor.st --- /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 + " + + + + ^ + + #(#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 + " + + + + ^ + + #(#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" + + + + ^ + + #(#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 + " + + + + ^ + + #(#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 + " + + + + ^ + + #(#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 + " + + + + ^ + + #(#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" + + + ^(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 + , '\' + , ' \\' + , ' ^\' + , ' ', 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$' +! !