# HG changeset patch # User ca # Date 894876094 -7200 # Node ID 5bd68980f09a6669745f79dd04517fd925090fbe # Parent d350f49ae74822b2cefde61a069326d02a42a515 support standAlone mode diff -r d350f49ae748 -r 5bd68980f09a DataSetBuilder.st --- a/DataSetBuilder.st Thu May 07 14:42:54 1998 +0200 +++ b/DataSetBuilder.st Mon May 11 10:41:34 1998 +0200 @@ -14,9 +14,9 @@ -ToolApplicationModel subclass:#DataSetBuilder - instanceVariableNames:'className superclassName hasChanged columnView columns - selectedColumnIndex tabSelectionIndex aspects' +ResourceSpecEditor subclass:#DataSetBuilder + instanceVariableNames:'rowClass rowSuperClass hasChanged columnView columns + selectedColumnIndex tabSelectionIndex' classVariableNames:'' poolDictionaries:'' category:'Interface-UIPainter' @@ -61,22 +61,36 @@ !DataSetBuilder class methodsFor:'instance creation'! openOnClass:aClass andSelector:aSelector - self information:'not yet implemented' + + ^ self new openOnClass:aClass andSelector:aSelector +! ! + +!DataSetBuilder class methodsFor:'constants'! - "Created: / 22.4.1998 / 10:21:03 / cg" +resourceType + "get the type of resource of the method generated by the MenuEditor" + + ^#dataset + + ! ! !DataSetBuilder class methodsFor:'help specs'! helpSpec - "return a dictionary filled with helpKey -> helptext associations. - These are used by the activeHelp tool." + "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:DataSetBuilder + UIHelpTool openOnClass:DataSetBuilder " - ^ super helpSpec addPairsFrom:#( + + + ^super helpSpec addPairsFrom:#( #addColumn 'Adds a new column.' @@ -142,7 +156,7 @@ 'Turns on/off displaying row separators.' #selectionCellClickSelector -'A selector called if cell was selected. ' +'A selector called if cell was selected.' #selectionCellDoubleClickSelector 'A selector called if cell was double clicked.' @@ -157,7 +171,7 @@ 'A selector called if label cell was clicked.' #selectionLabelSelectorArgument -'An argument passed to label selection selector. ' +'An argument passed to label selection selector.' #valuesChoiceSelector 'A selector returning a collection of choices for a cell having a ComboBox or a ComboList widget.' @@ -1091,11 +1105,11 @@ #window: #(#WindowSpec #name: 'Data Set Builder' - #layout: #(#LayoutFrame 662 0 70 0 1132 0 446 0) + #layout: #(#LayoutFrame 487 0 189 0 1031 0 690 0) #label: 'Data Set Builder' #min: #(#Point 10 10) #max: #(#Point 1152 900) - #bounds: #(#Rectangle 662 70 1133 447) + #bounds: #(#Rectangle 487 189 1032 691) #menu: #menu #usePreferredExtent: false ) @@ -1103,75 +1117,107 @@ #(#SpecCollection #collection: #( - #(#MenuPanelSpec - #name: 'menuToolbarView' - #layout: #(#LayoutFrame 0 0.0 0 0.0 0 1.0 32 0) - #menu: #menuToolbar - ) - #(#VariableHorizontalPanelSpec - #name: 'VariablePanel' - #layout: #(#LayoutFrame 0 0.0 34 0.0 0 1.0 -26 1.0) + #(#ViewSpec + #name: 'Box1' + #layout: #(#LayoutFrame 0 0.0 100 0.0 0 1.0 0 1.0) #component: #(#SpecCollection #collection: #( - #(#ViewSpec - #name: 'labelsView' + #(#MenuPanelSpec + #name: 'menuToolbarView' + #layout: #(#LayoutFrame 0 0.0 0 0.0 0 1.0 32 0) + #menu: #menuToolbar + ) + #(#VariableHorizontalPanelSpec + #name: 'VariablePanel' + #layout: #(#LayoutFrame 0 0.0 34 0.0 0 1.0 -26 1.0) #component: #(#SpecCollection #collection: #( - #(#SequenceViewSpec - #name: 'columnView' - #layout: #(#LayoutFrame 0 0.0 0 0.0 0 1.0 0 1.0) - #model: #selectedColumnModel - #menu: #menuEdit - #hasHorizontalScrollBar: true - #hasVerticalScrollBar: true - #miniScrollerHorizontal: true - #useIndex: true - #sequenceList: #seqList + #(#ViewSpec + #name: 'labelsView' + #component: + #(#SpecCollection + #collection: + #( + #(#SequenceViewSpec + #name: 'labelAndColumns' + #layout: #(#LayoutFrame 0 0.0 0 0.0 0 1.0 0 1.0) + #model: #selectedColumnModel + #menu: #menuEdit + #hasHorizontalScrollBar: true + #hasVerticalScrollBar: true + #miniScrollerHorizontal: true + #useIndex: true + #sequenceList: #seqList + ) + ) + ) + ) + #(#ViewSpec + #name: 'specView' + #component: + #(#SpecCollection + #collection: + #( + #(#TabViewSpec + #name: 'tabView' + #layout: #(#LayoutFrame 1 0.0 0 0 0 1.0 35 0) + #model: #tabModel + #menu: #tabList + #useIndex: true + ) + #(#SubCanvasSpec + #name: 'specCanvas' + #layout: #(#LayoutFrame 1 0.0 35 0.0 0 1.0 -30 1.0) + #specHolder: #specChannel + ) + #(#UISubSpecification + #name: 'SubSpecification' + #layout: #(#LayoutFrame 2 0.0 -26 1 -2 1.0 -2 1.0) + #majorKey: #ToolApplicationModel + #minorKey: #windowSpecForCommit + ) + ) + ) + #level: -1 ) ) ) + #handles: #(#Any 0.346072 1.0) ) - #(#ViewSpec - #name: 'specView' - #component: - #(#SpecCollection - #collection: - #( - #(#TabViewSpec - #name: 'tabView' - #layout: #(#LayoutFrame 1 0.0 0 0 0 1.0 35 0) - #model: #tabModel - #menu: #tabList - #useIndex: true - ) - #(#SubCanvasSpec - #name: 'specCanvas' - #layout: #(#LayoutFrame 1 0.0 35 0.0 0 1.0 -30 1.0) - #specHolder: #specChannel - ) - #(#UISubSpecification - #name: 'SubSpecification' - #layout: #(#LayoutFrame 2 0.0 -26 1 -2 1.0 -2 1.0) - #majorKey: #ToolApplicationModel - #minorKey: #windowSpecForCommit - ) - ) - ) - #level: -1 + #(#UISubSpecification + #name: 'infoBarSubSpec' + #layout: #(#LayoutFrame 0 0.0 -24 1 0 1.0 0 1.0) + #majorKey: #ToolApplicationModel + #minorKey: #windowSpecForInfoBar ) ) ) - #handles: #(#Any 0.265905 1.0) ) - #(#UISubSpecification - #name: 'infoBarSubSpec' - #layout: #(#LayoutFrame 0 0.0 -24 1 0 1.0 0 1.0) - #majorKey: #ToolApplicationModel - #minorKey: #windowSpecForInfoBar + #(#FramedBoxSpec + #name: 'ColumnFrame' + #layout: #(#LayoutFrame 0 0.0 5 0.0 0 1.0 100 0) + #component: + #(#SpecCollection + #collection: + #( + #(#DataSetSpec + #name: 'columnView' + #layout: #(#LayoutFrame 14 0.0 18 0.0 14 1.0 14 1.0) + #hasHorizontalScrollBar: true + #hasVerticalScrollBar: false + #miniScrollerHorizontal: true + #rowClassName: 'CodingExamples_GUI::GUIDemoDataSetView::Row' + #useIndex: false + #has3Dsepartors: true + ) + ) + ) + #label: 'Table Columns' + #labelPosition: #topLeft ) ) ) @@ -1181,10 +1227,11 @@ !DataSetBuilder class methodsFor:'menu specs'! menu - "this window spec was automatically generated by the ST/X MenuEditor" + "This resource specification was automatically generated + by the MenuEditor of ST/X." - "do not manually edit this - the builder may not be able to - handle the specification if its corrupted." + "Do not manually edit this!! If it is corrupted, + the MenuEditor may not be able to read the specification." " MenuEditor new openOnClass:DataSetBuilder andSelector:#menu @@ -1199,75 +1246,160 @@ #( #(#MenuItem - #'label:' 'About' - #'activeHelpKey:' #about - #'labelImage:' #(#ResourceRetriever nil #menuIcon) - #'submenuChannel:' #menuAbout + #label: 'About' + #accessCharacterPosition: 1 + #labelImage: #(#ResourceRetriever nil #menuIcon) + #submenuChannel: #menuAbout ) #(#MenuItem - #'label:' 'File' - #'activeHelpKey:' #file - #'submenu:' + #label: 'File' + #activeHelpKey: #file + #submenu: #(#Menu #( #(#MenuItem - #'label:' 'Generate Code' - #'value:' #doGenerateCode + #label: 'New' + #value: #doNew + #activeHelpKey: #fileNew + ) + #(#MenuItem + #label: '-' ) #(#MenuItem - #'label:' '-' + #label: 'Load...' + #translateLabel: true + #value: #doLoad + #activeHelpKey: #fileLoad ) #(#MenuItem - #'label:' 'Define Class...' - #'value:' #doDefineClass - #'activeHelpKey:' #fileDefineClass + #label: '-' + ) + #(#MenuItem + #label: 'Save' + #value: #doSave + #activeHelpKey: #fileSave ) #(#MenuItem - #'label:' 'Browse Class' - #'value:' #doBrowseClass - #'activeHelpKey:' #fileBrowseClass + #label: 'Save As...' + #value: #doSaveAs + #activeHelpKey: #fileSaveAs + ) + #(#MenuItem + #label: '-' + ) + #(#MenuItem + #label: 'Pick Columns...' + #value: #doPickColumns ) #(#MenuItem - #'label:' '-' + #label: '-' + ) + #(#MenuItem + #label: 'Browse Class' + #value: #doBrowseClass + #activeHelpKey: #fileBrowseClass ) #(#MenuItem - #'label:' 'Exit' - #'value:' #closeRequest - #'activeHelpKey:' #fileExit + #label: '-' + ) + #(#MenuItem + #label: 'Exit' + #translateLabel: true + #value: #closeRequest + #activeHelpKey: #fileExit ) ) nil nil ) ) #(#MenuItem - #'label:' 'Edit' - #'activeHelpKey:' #edit - #'submenuChannel:' #menuEdit + #label: 'Edit' + #activeHelpKey: #edit + #submenuChannel: #menuEdit ) #(#MenuItem - #'label:' 'Add' - #'activeHelpKey:' #add - #'submenu:' + #label: 'Add' + #submenu: #(#Menu #( #(#MenuItem - #'label:' 'Column' - #'value:' #doCreateColumn - #'activeHelpKey:' #addColumn - #'enabled:' #columnIsNotEditing - #'labelImage:' #(#ResourceRetriever nil #newColumnIcon 'Column') + #label: 'Column' + #value: #doCreateColumn + #activeHelpKey: #addColumn + #enabled: #columnIsNotEditing + #labelImage: #(#ResourceRetriever nil #newColumnIcon) ) ) nil nil ) ) #(#MenuItem - #'label:' 'Help' - #'startGroup:' #right - #'activeHelpKey:' #help - #'submenuChannel:' #menuHelp + #label: 'Generate' + #activeHelpKey: #file + #submenu: + #(#Menu + + #( + #(#MenuItem + #label: 'Define Row Class...' + #value: #doDefineRowClass + #activeHelpKey: #fileDefineClass + ) + #(#MenuItem + #label: 'Browse Row Class' + #value: #doBrowseRowClass + ) + #(#MenuItem + #label: '-' + ) + #(#MenuItem + #label: 'Generate Code' + #value: #doGenerateCode + ) + ) nil + nil + ) + ) + #(#MenuItem + #label: 'History' + #activeHelpKey: #history + #submenuChannel: #menuHistory + ) + #(#MenuItem + #label: 'Help' + #startGroup: #right + #submenu: + #(#Menu + + #( + #(#MenuItem + #label: 'Documentation' + #value: #openHTMLDocument: + #activeHelpKey: #helpTutorial + #argument: 'tools/uipainter/DataSetBuilder.html' + ) + #(#MenuItem + #label: '-' + ) + #(#MenuItem + #label: 'Help Tool' + #value: #openHTMLDocument: + #activeHelpKey: #helpHelpTool + #argument: 'tools/uipainter/HelpTool.html' + ) + #(#MenuItem + #label: '-' + ) + #(#MenuItem + #label: 'Show Help Texts' + #activeHelpKey: #helpShowHelp + #indication: #showHelp: + ) + ) nil + nil + ) ) ) nil nil @@ -1405,51 +1537,50 @@ columns "returns list of columns" - ^columns + ^ columns ! -columns:aListOfColumns fromView:aColumnView +columns:aListOfColumns "setup columns from a column view" |list| - columnView := aColumnView. columns := OrderedCollection new. list := self seqList. hasChanged := false. list removeAll. - aListOfColumns size ~~ 0 - ifTrue: - [ - aListOfColumns do: - [:aColumn| - columns add: aColumn copy. - aColumn rendererType == #rowSelector - ifFalse:[list add: aColumn label] - ifTrue: [list add:'Row Selector'] + aListOfColumns size ~~ 0 ifTrue:[ + aListOfColumns do:[:aColumn||column| + (column := aColumn) isSequenceable ifTrue:[ + column := DataSetColumnSpec new fromLiteralArrayEncoding:aColumn + ] ifFalse:[ + column := aColumn copy + ]. + columns add:column. + list add:(self labelFromColumn:column). ] - ] + ]. + self updateColumnView. + ! rowClassName - ^(Smalltalk resolveName:className inClass:self class) notNil ifTrue:[className] ifFalse:[nil] + ^(Smalltalk resolveName:rowClass inClass:self class) notNil ifTrue:[rowClass] ifFalse:[nil] ! rowClassName:aClassName |cls| - superclassName := nil. + rowSuperClass := nil. - (className := aClassName) notNil - ifTrue: - [ - (cls := self resolveClassNamed) notNil - ifTrue: [superclassName := cls superclass name asString] - ifFalse:[superclassName := 'Object'] + (rowClass := aClassName) notNil ifTrue:[ + (cls := self resolveRowClassNamed) notNil + ifTrue: [rowSuperClass := cls superclass name asString] + ifFalse:[rowSuperClass := 'Object'] ] ! ! @@ -1586,6 +1717,33 @@ ^ holder ! ! +!DataSetBuilder methodsFor:'building'! + +buildFromClass:aClass andSelector:aSelector + |cls list| + + list := nil. + + (aClass notNil or:[self isStandAlone or:[self window shown]]) ifTrue:[ + + (aClass notNil and:[aSelector notNil]) ifTrue:[ + cls := self resolveName:aClass. + + (cls respondsTo:aSelector) ifTrue:[ + list := cls perform:aSelector + ] + ] + ] ifFalse:[ + list := columns + ]. + self columns:list +! + +buildFromResourceSpec:aResourceSpec + + self columns:aResourceSpec +! ! + !DataSetBuilder methodsFor:'change & update'! update:something with:aParameter from:someObject @@ -1874,7 +2032,6 @@ selectedColumnIndex := 0. tabSelectionIndex := 0. columns := OrderedCollection new. - aspects := IdentityDictionary new. hasChanged := false. #( @@ -1935,16 +2092,20 @@ ! -resolveClassNamed +labelFromColumn:aColumn + ^ aColumn rendererType == #rowSelector ifFalse:[aColumn label] + ifTrue:['Row Selector']. +! + +resolveRowClassNamed "returns current class or nil" - ^Smalltalk resolveName:className inClass:self class. + ^Smalltalk resolveName:rowClass inClass:self class. ! updateColumnView "update column view from column descriptions" - columnView notNil ifTrue:[columnView columnDescriptors:columns] ! @@ -2039,13 +2200,15 @@ postBuildWith:builder + columnView := self builder componentAt:#columnView. + columnView labelView enabled:false. + super postBuildWith:builder. - (builder componentAt: #columnView) + (builder componentAt: #labelAndColumns) selectConditionBlock: [:i|self checkMenuItemModified]; action: [:i|self cancel]; - selection: 1 - + selection: 1. ! ! @@ -2064,15 +2227,15 @@ type := (aspects at:#rendererType) value. - type == #rowSelector - ifTrue: - [ + type == #rowSelector ifTrue:[ #(label width minWidth editorType choices readSelector writeSelector printSelector - formatString type size height canSelect selectSelector) do:[:aKey|(aspects at:aKey) value:nil] + formatString type size height canSelect selectSelector + ) do:[:aKey| + (aspects at:aKey) value:nil + ] ]. - aspects keysAndValuesDo:[:aKey :aModel| column perform:(aKey , ':') asSymbol with: aModel value]. - self seqList at:selectedColumnIndex put: (aspects at:#label) value. + self seqList at:selectedColumnIndex put:(self labelFromColumn:column). self updateColumnView. self cancel ! @@ -2085,12 +2248,12 @@ self columnIsNotEditing value: true. ! -doBrowseClass +doBrowseRowClass "browse class of columns spec" |cls| - (cls := self resolveClassNamed) notNil + (cls := self resolveRowClassNamed) notNil ifTrue: [SystemBrowser openInClass:cls] ifFalse:[self information:'No class defined!!'] @@ -2121,7 +2284,8 @@ self seqList add:label afterIndex:selectedColumnIndex. hasChanged := true. self valueOfEnablingCommitButtons value ifFalse:[self selectedColumnModel value:selectedColumnIndex + 1]. - self cancel + self cancel. + self updateColumnView ! @@ -2146,77 +2310,77 @@ ] ! -doDefineClass +doDefineRowClass "launch a dialog to define class and superclass" |aspects cls oldClass oldSuper| aspects := IdentityDictionary new. - oldClass := className. - oldSuper := superclassName. + oldClass := rowClass. + oldSuper := rowSuperClass. [true] whileTrue: [ - className notNil + rowClass notNil ifTrue: [ - (cls := self resolveClassNamed) notNil + (cls := self resolveRowClassNamed) notNil ifTrue: [ - superclassName := cls superclass name asString + rowSuperClass := cls superclass name asString ]. - aspects at:#classNameChannel put:className asValue + aspects at:#classNameChannel put:rowClass asValue ] ifFalse: [ aspects at:#classNameChannel put:'DSVRow' asValue ]. - superclassName notNil - ifTrue: [aspects at:#superclassNameChannel put:superclassName asValue] + rowSuperClass notNil + ifTrue: [aspects at:#superclassNameChannel put:rowSuperClass asValue] ifFalse:[aspects at:#superclassNameChannel put:'Object' asValue]. (self openDialogInterface:#defineClassNameSpec withBindings:aspects) ifFalse: [ - className := oldClass. - superclassName := oldSuper. + rowClass := oldClass. + rowSuperClass := oldSuper. ^self ]. - className := ((aspects at:#classNameChannel) value) withoutSeparators. - superclassName := ((aspects at:#superclassNameChannel) value) withoutSeparators. + rowClass := ((aspects at:#classNameChannel) value) withoutSeparators. + rowSuperClass := ((aspects at:#superclassNameChannel) value) withoutSeparators. - className size == 0 + rowClass size == 0 ifTrue: [ - className := nil. + rowClass := nil. self information:'no valid className' ] ifFalse: [ - cls := self resolveClassNamed. + cls := self resolveRowClassNamed. cls notNil ifTrue:[cls := cls superclass name asString]. - superclassName size == 0 + rowSuperClass size == 0 ifTrue: [ cls notNil ifTrue:[ - superclassName := cls + rowSuperClass := cls ] ifFalse:[ - superclassName := 'Object' + rowSuperClass := 'Object' ]. self information: 'set superclassName' ] ifFalse: [ - (cls isNil or:[superclassName = cls]) ifTrue:[hasChanged := true. ^self]. - self information:('A global named ' , className , ' exists,\' , - 'but is not a subclass of ' , superclassName, '.\\' , + (cls isNil or:[rowSuperClass = cls]) ifTrue:[hasChanged := true. ^self]. + self information:('A global named ' , rowClass , ' exists,\' , + 'but is not a subclass of ' , rowSuperClass, '.\\' , 'Check and try again if that is not what you want.') withCRs. - superclassName := cls + rowSuperClass := cls ] ] ] @@ -2227,17 +2391,17 @@ |cls superclass| - className isNil ifTrue:[^self information:'No class defined!!']. - cls := self resolveClassNamed. + rowClass isNil ifTrue:[^self information:'No class defined!!']. + cls := self resolveRowClassNamed. cls isNil ifTrue: [ - superclass := Smalltalk resolveName:superclassName inClass:self class. + superclass := Smalltalk resolveName:rowSuperClass inClass:self class. superclass isNil ifTrue:[^self information:'No superclass defined!!']. - (self confirm:'create ' , className , ' ?') ifFalse:[^self]. - cls := superclass subclass:className asSymbol + (self confirm:'create ' , rowClass , ' ?') ifFalse:[^self]. + cls := superclass subclass:rowClass asSymbol instanceVariableNames:'' classVariableNames:'' poolDictionaries:'' @@ -2292,18 +2456,90 @@ doPasteColumn "paste clipboard copy column after selected column or at left (nothing selected)" - |label list| + |col lbl| self checkMenuItemModified ifFalse: [^nil]. - list := self seqList. - label := self class clipboard label. - columns add: self class clipboard deepCopy afterIndex:selectedColumnIndex. - self seqList add: label afterIndex:selectedColumnIndex. + col := self class clipboard deepCopy. + lbl := self labelFromColumn:col. + + columns add:col afterIndex:selectedColumnIndex. + self seqList add:lbl afterIndex:selectedColumnIndex. hasChanged := true. - self valueOfEnablingCommitButtons value ifFalse:[self selectedColumnModel value:selectedColumnIndex + 1]. + self valueOfEnablingCommitButtons value ifFalse:[ + self selectedColumnModel value:selectedColumnIndex + 1 + ]. self updateColumnView. self updateInputFields. +! + +doPickColumns + + |view cls| + + view := Screen current viewFromUser. + cls := view class. + + (cls == DSVColumnView or:[cls == DataSetView or:[cls == DSVLabelView]]) ifTrue:[ + self columns:(view columnView columnDescriptors) + ] +! + +doSave + |cls dst spc idx category mthd excla code resourceType| + + (columns size ~~ 0 and:[super doSave]) ifFalse:[ + ^ nil + ]. + cls := self resolveName:specClass. + dst := columns collect:[:aCol| aCol literalArrayEncoding ]. + spc := WriteStream on:String new. + UISpecification prettyPrintSpecArray:dst asArray on:spc indent:4. + spc := spc contents. + idx := (spc indexOfNonSeparatorStartingAt:1) - 2. + + spc at:idx put:$^. + + "/ if that method already exists, do not overwrite the category + + resourceType := self class resourceType. + category := resourceType, ' specs'. + + (mthd := cls class compiledMethodAt:specSelector) notNil ifTrue:[ + category := mthd category. + ]. + + excla := Character excla asString. + + code := excla + , (cls name , ' class methodsFor:' , category storeString) + , excla , '\\' + + , specSelector , '\' + , (self class codeGenerationComment replChar:$!! withString:'!!!!') + , '\\ "\' + , (' DataSetBuilder new openOnClass:' , cls name , ' andSelector:#' , specSelector , '\') + , ' "\'. + + code := code + , '\' + , ' \\' + , spc + , '\' + , (excla , ' ' , excla) + , '\\'. + + code := code withCRs. + (ReadStream on:code) fileIn. + +"/ self isStandAlone ifTrue: [self helpTool installHelpSpecsOnClass:self specClass]. + + self updateHistory. + self updateInfoLabel. + + hasSaved := true. + modified := false. + ! ! !DataSetBuilder class methodsFor:'documentation'!