# HG changeset patch # User tz # Date 890417510 -3600 # Node ID cc3413fc1afb724569cfc77c1c1aba876f266de5 # Parent ebc4a399f4dc75b1b6c05aad5d92e56a5e03b3a9 initial checkin diff -r ebc4a399f4dc -r cc3413fc1afb TabListEditor.st --- /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 + " + + + + ^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 + " + + + + ^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?<@??? + + ^ + + #(#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 + " + + + + ^ + + #(#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 + " + + + + ^ + + #(#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 + " + + + + ^ + + #(#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 + " + + + + ^ + + #(#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 + , '\' + , ' \\' + , ' ^' + , ' ', 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' +! !