DataSetBuilder.st
changeset 332 b895330fc7aa
child 333 a2e23dea36bf
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DataSetBuilder.st	Wed Oct 15 12:59:56 1997 +0200
@@ -0,0 +1,1529 @@
+"
+ COPYRIGHT (c) 1997 by eXept Software AG / Claus Gittinger
+              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.
+"
+
+
+
+
+
+ApplicationModel subclass:#DataSetBuilder
+	instanceVariableNames:'className superclassName hasChanged columnView columns
+		selectedColumnIndex tabSelectionIndex aspects isModified'
+	classVariableNames:'Number'
+	poolDictionaries:''
+	category:'Interface-UIPainter'
+!
+
+!DataSetBuilder class methodsFor:'documentation'!
+
+copyright
+"
+ COPYRIGHT (c) 1997 by eXept Software AG / Claus Gittinger
+              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 dataset columns; used by UIPainter (DataSetColumnSpec)
+
+    [see also:]
+        DataSetColumnSpec
+        DataSetSpec
+        DataSetView
+        DataSetColumn
+
+    [author:]
+        Claus Atzkern
+"
+
+! !
+
+!DataSetBuilder class methodsFor:'columns specs'!
+
+basicsEditSpec
+    "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:DataSetBuilder andSelector:#basicsEditSpec
+     DataSetBuilder new openInterface:#basicsEditSpec
+    "
+
+    <resource: #canvas>
+
+    ^
+     
+       #(#FullSpec
+          #'window:' 
+           #(#WindowSpec
+              #'name:' 'DataSet Basic'
+              #'layout:' #(#LayoutFrame 197 0 172 0 485 0 427 0)
+              #'label:' 'DataSet Basic'
+              #'min:' #(#Point 10 10)
+              #'max:' #(#Point 1280 1024)
+              #'bounds:' #(#Rectangle 197 172 486 428)
+          )
+          #'component:' 
+           #(#SpecCollection
+              #'collection:' 
+               #(
+                 #(#LabelSpec
+                    #'name:' 'labelLabel'
+                    #'layout:' #(#AlignmentOrigin 84 0 29 0 1 0.5)
+                    #'label:' 'Label:'
+                    #'adjust:' #right
+                    #'resizeForLabel:' true
+                )
+                 #(#InputFieldSpec
+                    #'name:' 'labelField'
+                    #'layout:' #(#LayoutFrame 86 0 20 0 -12 1.0 40 0)
+                    #'model:' #label
+                )
+                 #(#FramedBoxSpec
+                    #'name:' 'typesFrame'
+                    #'layout:' #(#LayoutFrame 0 0.0 51 0 0 1.0 131 0)
+                    #'component:' 
+                     #(#SpecCollection
+                        #'collection:' 
+                         #(
+                           #(#LabelSpec
+                              #'name:' 'rendererLabel'
+                              #'layout:' #(#AlignmentOrigin 84 0 26 0 1 0.5)
+                              #'label:' 'Renderer:'
+                              #'resizeForLabel:' true
+                          )
+                           #(#ComboListSpec
+                              #'name:' 'rendererField'
+                              #'layout:' #(#LayoutFrame 86 0 16 0 17 1.0 36 0)
+                              #'model:' #rendererType
+                              #'comboList:' #rendererTypeList
+                              #'useIndex:' false
+                          )
+                           #(#LabelSpec
+                              #'name:' 'editorLabel'
+                              #'layout:' #(#AlignmentOrigin 84 0 50 0 1 0.5)
+                              #'label:' 'Editor:'
+                              #'resizeForLabel:' true
+                          )
+                           #(#ComboBoxSpec
+                              #'name:' 'editorField'
+                              #'layout:' #(#LayoutFrame 86 0 41 0 17 1.0 61 0)
+                              #'model:' #editorType
+                              #'type:' #symbolOrNil
+                              #'comboList:' #editorTypeList
+                              #'useIndex:' false
+                          )
+                        )
+                    )
+                    #'label:' 'Types:'
+                    #'labelPosition:' #topLeft
+                )
+                 #(#FramedBoxSpec
+                    #'name:' 'selectorsFrame'
+                    #'layout:' #(#LayoutFrame 0 0.0 143 0 0 1.0 245 0)
+                    #'component:' 
+                     #(#SpecCollection
+                        #'collection:' 
+                         #(
+                           #(#LabelSpec
+                              #'name:' 'readLabel'
+                              #'layout:' #(#AlignmentOrigin 84 0 25 0 1 0.5)
+                              #'label:' 'Read:'
+                              #'adjust:' #right
+                              #'resizeForLabel:' true
+                          )
+                           #(#InputFieldSpec
+                              #'name:' 'readSelector'
+                              #'layout:' #(#LayoutFrame 86 0 16 0 17 1.0 36 0)
+                              #'model:' #readSelector
+                              #'type:' #symbolOrNil
+                          )
+                           #(#LabelSpec
+                              #'name:' 'menuLabel'
+                              #'layout:' #(#AlignmentOrigin 84 0 51 0 1 0.5)
+                              #'label:' 'Menu:'
+                              #'adjust:' #right
+                              #'resizeForLabel:' true
+                          )
+                           #(#InputFieldSpec
+                              #'name:' 'menuField'
+                              #'layout:' #(#LayoutFrame 86 0 41 0 17 1.0 61 0)
+                              #'model:' #menu
+                              #'type:' #symbolOrNil
+                          )
+                           #(#LabelSpec
+                              #'name:' 'printLabel'
+                              #'layout:' #(#AlignmentOrigin 84 0 75 0 1 0.5)
+                              #'label:' 'Print:'
+                              #'adjust:' #right
+                              #'resizeForLabel:' true
+                          )
+                           #(#InputFieldSpec
+                              #'name:' 'printSelector'
+                              #'layout:' #(#LayoutFrame 86 0 66 0 17 1.0 86 0)
+                              #'model:' #printSelector
+                              #'type:' #symbolOrNil
+                          )
+                        )
+                    )
+                    #'label:' 'Selectors:'
+                    #'labelPosition:' #topLeft
+                )
+              )
+          )
+      )
+!
+
+detailsEditSpec
+    "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:DataSetBuilder andSelector:#detailsEditSpec
+     DataSetBuilder new openInterface:#detailsEditSpec
+    "
+
+    <resource: #canvas>
+
+    ^
+     
+       #(#FullSpec
+          #'window:' 
+           #(#WindowSpec
+              #'name:' 'DataSet Details'
+              #'layout:' #(#LayoutFrame 197 0 172 0 487 0 385 0)
+              #'label:' 'DataSet Details'
+              #'min:' #(#Point 10 10)
+              #'max:' #(#Point 1280 1024)
+              #'bounds:' #(#Rectangle 197 172 488 386)
+          )
+          #'component:' 
+           #(#SpecCollection
+              #'collection:' 
+               #(
+                 #(#LabelSpec
+                    #'name:' 'textDescription'
+                    #'layout:' #(#Point 10 15)
+                    #'label:' 'Text Description:'
+                    #'resizeForLabel:' true
+                )
+                 #(#LabelSpec
+                    #'name:' 'formatLabel'
+                    #'layout:' #(#AlignmentOrigin 83 0 47 0 1 0.5)
+                    #'label:' 'Format:'
+                    #'resizeForLabel:' true
+                )
+                 #(#InputFieldSpec
+                    #'name:' 'formatField'
+                    #'layout:' #(#LayoutFrame 87 0 37 0 -19 1.0 59 0)
+                    #'model:' #formatString
+                )
+                 #(#LabelSpec
+                    #'name:' 'inpFieldDescription'
+                    #'layout:' #(#Point 10 80)
+                    #'label:' 'InputField Description:'
+                    #'resizeForLabel:' true
+                )
+                 #(#LabelSpec
+                    #'name:' 'typeLabel'
+                    #'layout:' #(#AlignmentOrigin 83 0 111 0 1 0.5)
+                    #'label:' 'Type:'
+                    #'resizeForLabel:' true
+                )
+                 #(#ComboListSpec
+                    #'name:' 'typeCombo'
+                    #'layout:' #(#LayoutFrame 87 0 102 0 289 0 122 0)
+                    #'model:' #type
+                    #'comboList:' #typeList
+                    #'useIndex:' false
+                )
+                 #(#LabelSpec
+                    #'name:' 'sizeLabel'
+                    #'layout:' #(#AlignmentOrigin 83 0 136 0 1 0.5)
+                    #'label:' 'Size:'
+                    #'resizeForLabel:' true
+                )
+                 #(#InputFieldSpec
+                    #'name:' 'sizeField'
+                    #'layout:' #(#LayoutFrame 87 0 126 0 -19 1.0 148 0)
+                    #'model:' #size
+                    #'type:' #numberOrNil
+                )
+                 #(#LabelSpec
+                    #'name:' 'choicesLabel'
+                    #'layout:' #(#Point 10 165)
+                    #'label:' 'Choices:'
+                    #'resizeForLabel:' true
+                )
+                 #(#LabelSpec
+                    #'name:' 'selectorLabel'
+                    #'layout:' #(#AlignmentOrigin 83 0 198 0 1 0.5)
+                    #'label:' 'Selector:'
+                    #'resizeForLabel:' true
+                )
+                 #(#InputFieldSpec
+                    #'name:' 'choiceField'
+                    #'layout:' #(#LayoutFrame 87 0 188 0 -19 1.0 210 0)
+                    #'model:' #choices
+                    #'type:' #symbolOrNil
+                )
+              )
+          )
+      )
+!
+
+dimensionEditSpec
+    "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:DataSetBuilder andSelector:#dimensionEditSpec
+     DataSetBuilder new openInterface:#dimensionEditSpec
+    "
+
+    <resource: #canvas>
+
+    ^
+     
+       #(#FullSpec
+          #'window:' 
+           #(#WindowSpec
+              #'name:' 'DataSet Dimension'
+              #'layout:' #(#LayoutFrame 197 0 172 0 487 0 385 0)
+              #'label:' 'DataSet Dimension'
+              #'min:' #(#Point 10 10)
+              #'max:' #(#Point 1280 1024)
+              #'bounds:' #(#Rectangle 197 172 488 386)
+          )
+          #'component:' 
+           #(#SpecCollection
+              #'collection:' 
+               #(
+                 #(#FramedBoxSpec
+                    #'name:' 'columnWidthFrame'
+                    #'layout:' #(#LayoutFrame 0 0.0 20 0 0 1.0 107 0)
+                    #'component:' 
+                     #(#SpecCollection
+                        #'collection:' 
+                         #(
+                           #(#LabelSpec
+                              #'name:' 'widthLabel'
+                              #'layout:' #(#AlignmentOrigin 68 0.0 27 0 1 0.5)
+                              #'label:' 'width:'
+                              #'resizeForLabel:' true
+                          )
+                           #(#InputFieldSpec
+                              #'name:' 'widthField'
+                              #'layout:' #(#LayoutFrame 70 0 17 0 0 1.0 39 0)
+                              #'model:' #width
+                              #'type:' #numberOrNil
+                          )
+                           #(#LabelSpec
+                              #'name:' 'minWidthLabel'
+                              #'layout:' #(#AlignmentOrigin 68 0.0 56 0 1 0.5)
+                              #'label:' 'minWidth:'
+                              #'resizeForLabel:' true
+                          )
+                           #(#InputFieldSpec
+                              #'name:' 'minWidthField'
+                              #'layout:' #(#LayoutFrame 70 0 46 0 0 1.0 68 0)
+                              #'model:' #minWidth
+                              #'type:' #numberOrNil
+                          )
+                        )
+                    )
+                    #'label:' 'Column Width:'
+                    #'labelPosition:' #topLeft
+                )
+                 #(#FramedBoxSpec
+                    #'name:' 'rowHeightFrame'
+                    #'layout:' #(#LayoutFrame 0 0.0 134 0 0 1.0 194 0)
+                    #'component:' 
+                     #(#SpecCollection
+                        #'collection:' 
+                         #(
+                           #(#LabelSpec
+                              #'name:' 'heightLabel'
+                              #'layout:' #(#AlignmentOrigin 68 0.0 29 0 1 0.5)
+                              #'label:' 'height:'
+                              #'resizeForLabel:' true
+                          )
+                           #(#InputFieldSpec
+                              #'name:' 'heightField'
+                              #'layout:' #(#LayoutFrame 70 0 19 0 0 1.0 41 0)
+                              #'model:' #height
+                              #'type:' #numberOrNil
+                          )
+                        )
+                    )
+                    #'label:' 'Row Height:'
+                    #'labelPosition:' #topLeft
+                )
+              )
+          )
+      )
+!
+
+miscEditSpec
+    "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:DataSetBuilder andSelector:#miscEditSpec
+     DataSetBuilder new openInterface:#miscEditSpec
+    "
+
+    <resource: #canvas>
+
+    ^
+     
+       #(#FullSpec
+          #'window:' 
+           #(#WindowSpec
+              #'name:' 'DataSet Misc'
+              #'layout:' #(#LayoutFrame 197 0 172 0 487 0 385 0)
+              #'label:' 'DataSet Misc'
+              #'min:' #(#Point 10 10)
+              #'max:' #(#Point 1280 1024)
+              #'bounds:' #(#Rectangle 197 172 488 386)
+          )
+          #'component:' 
+           #(#SpecCollection
+              #'collection:' 
+               #(
+                 #(#CheckBoxSpec
+                    #'name:' 'canSelect'
+                    #'layout:' #(#Point 17 21)
+                    #'model:' #canSelect
+                    #'label:' 'Is Selectable'
+                )
+                 #(#LabelSpec
+                    #'name:' 'separatorsLabel'
+                    #'layout:' #(#AlignmentOrigin 84 0 154 0 1 0.5)
+                    #'label:' 'Separators:'
+                    #'resizeForLabel:' true
+                )
+                 #(#CheckBoxSpec
+                    #'name:' 'showRowSeparator'
+                    #'layout:' #(#AlignmentOrigin 86 0 156 0 0 0.5)
+                    #'model:' #showRowSeparator
+                    #'label:' 'Show Row-Separator'
+                )
+                 #(#CheckBoxSpec
+                    #'name:' 'showColSeparator'
+                    #'layout:' #(#AlignmentOrigin 86 0 182 0 0 0.5)
+                    #'model:' #showColSeparator
+                    #'label:' 'Show Column-Separator'
+                )
+              )
+          )
+      )
+! !
+
+!DataSetBuilder class methodsFor:'images'!
+
+iconCreateItem
+    ^ MenuEditor iconCreateItem
+
+
+! !
+
+!DataSetBuilder class methodsFor:'interface specs'!
+
+defineClassNameSpec
+    "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:DataSetBuilder andSelector:#defineClassNameSpec
+     DataSetBuilder new openInterface:#defineClassNameSpec
+    "
+
+    <resource: #canvas>
+
+    ^
+     
+       #(#FullSpec
+          #'window:' 
+           #(#WindowSpec
+              #'name:' 'Class Definition'
+              #'layout:' #(#LayoutFrame 76 0 249 0 401 0 378 0)
+              #'label:' 'Class Definition'
+              #'min:' #(#Point 10 10)
+              #'max:' #(#Point 1152 900)
+              #'bounds:' #(#Rectangle 76 249 402 379)
+          )
+          #'component:' 
+           #(#SpecCollection
+              #'collection:' 
+               #(
+                 #(#LabelSpec
+                    #'name:' 'classLabel'
+                    #'layout:' #(#AlignmentOrigin 50 0.11 50 0 1 0.5)
+                    #'label:' 'class:'
+                    #'adjust:' #right
+                    #'resizeForLabel:' true
+                )
+                 #(#LabelSpec
+                    #'name:' 'superClassLabel'
+                    #'layout:' #(#AlignmentOrigin 50 0.11 77 0 1 0.5)
+                    #'label:' 'superclass:'
+                    #'adjust:' #right
+                    #'resizeForLabel:' true
+                )
+                 #(#LabelSpec
+                    #'name:' 'topLabel'
+                    #'layout:' #(#Point 2 10)
+                    #'label:' 'class for code:'
+                    #'adjust:' #left
+                    #'resizeForLabel:' true
+                )
+                 #(#InputFieldSpec
+                    #'name:' 'classNameField'
+                    #'layout:' #(#LayoutFrame 51 0.11 39 0 -2 1.0 61 0)
+                    #'tabable:' true
+                    #'model:' #classNameChannel
+                )
+                 #(#HorizontalPanelViewSpec
+                    #'name:' 'commitPanel'
+                    #'layout:' #(#LayoutFrame 2 0.0 -30 1.0 -2 1.0 -2 1.0)
+                    #'component:' 
+                     #(#SpecCollection
+                        #'collection:' 
+                         #(
+                           #(#ActionButtonSpec
+                              #'name:' 'button1'
+                              #'label:' 'cancel'
+                              #'tabable:' true
+                              #'model:' #cancel
+                              #'extent:' #(#Point 156 22)
+                          )
+                           #(#ActionButtonSpec
+                              #'name:' 'button2'
+                              #'label:' 'ok'
+                              #'tabable:' true
+                              #'isDefault:' true
+                              #'model:' #accept
+                              #'extent:' #(#Point 157 22)
+                          )
+                        )
+                    )
+                    #'horizontalLayout:' #fitSpace
+                    #'verticalLayout:' #fitSpace
+                    #'horizontalSpace:' 3
+                    #'verticalSpace:' 3
+                )
+                 #(#InputFieldSpec
+                    #'name:' 'inputField1'
+                    #'layout:' #(#LayoutFrame 51 0.11 67 0 -2 1.0 89 0)
+                    #'tabable:' true
+                    #'model:' #superclassNameChannel
+                )
+              )
+          )
+      )
+!
+
+slices
+    ^  #(       (Basics         basicsEditSpec)
+                (Details        detailsEditSpec)
+                (Misc           miscEditSpec)
+                (Dimension      dimensionEditSpec)
+        )
+!
+
+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:DataSetBuilder andSelector:#windowSpec
+     DataSetBuilder new openInterface:#windowSpec
+    "
+    "DataSetBuilder open"
+
+    <resource: #canvas>
+
+    ^
+     
+       #(#FullSpec
+          #'window:' 
+           #(#WindowSpec
+              #'name:' 'unnamed canvas'
+              #'layout:' #(#LayoutFrame 197 0 172 0 668 0 512 0)
+              #'label:' 'unnamed canvas'
+              #'min:' #(#Point 10 10)
+              #'max:' #(#Point 1152 900)
+              #'bounds:' #(#Rectangle 197 172 669 513)
+          )
+          #'component:' 
+           #(#SpecCollection
+              #'collection:' 
+               #(
+                 #(#MenuPanelSpec
+                    #'name:' 'mainMenu'
+                    #'layout:' #(#LayoutFrame 0 0.0 0 0.0 0 1.0 25 0)
+                    #'menu:' #mainMenu
+                )
+                 #(#VariableHorizontalPanelSpec
+                    #'name:' 'VariablePanel'
+                    #'layout:' #(#LayoutFrame 0 0.0 25 0.0 0 1.0 0 1.0)
+                    #'component:' 
+                     #(#SpecCollection
+                        #'collection:' 
+                         #(
+                           #(#ViewSpec
+                              #'name:' 'labelsView'
+                              #'component:' 
+                               #(#SpecCollection
+                                  #'collection:' 
+                                   #(
+                                     #(#MenuPanelSpec
+                                        #'name:' 'subMenu'
+                                        #'layout:' #(#LayoutFrame 0 0.0 0 0.0 0 1.0 35 0)
+                                        #'menu:' #subMenu
+                                    )
+                                     #(#SequenceViewSpec
+                                        #'name:' 'columnView'
+                                        #'layout:' #(#LayoutFrame 0 0.0 35 0.0 0 1.0 0 1.0)
+                                        #'model:' #selectedColumnModel
+                                        #'menu:' #columnMenu
+                                        #'hasVerticalScrollBar:' true
+                                        #'useIndex:' true
+                                        #'sequenceList:' #seqList
+                                    )
+                                  )
+                              )
+                          )
+                           #(#ViewSpec
+                              #'name:' 'specView'
+                              #'component:' 
+                               #(#SpecCollection
+                                  #'collection:' 
+                                   #(
+                                     #(#TabViewSpec
+                                        #'name:' 'tabView'
+                                        #'layout:' #(#LayoutFrame 0 0.0 0 0 0 1.0 35 0)
+                                        #'model:' #tabModel
+                                        #'menu:' #tabList
+                                        #'useIndex:' true
+                                    )
+                                     #(#SubCanvasSpec
+                                        #'name:' 'specCanvas'
+                                        #'layout:' #(#LayoutFrame 0 0.0 35 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 150 24)
+                                              )
+                                               #(#ActionButtonSpec
+                                                  #'name:' 'acceptButton'
+                                                  #'label:' 'ok'
+                                                  #'model:' #accept
+                                                  #'enableChannel:' #modifiedChannel
+                                                  #'extent:' #(#Point 151 24)
+                                              )
+                                            )
+                                        )
+                                        #'horizontalLayout:' #fitSpace
+                                        #'verticalLayout:' #fitSpace
+                                        #'horizontalSpace:' 3
+                                        #'verticalSpace:' 3
+                                    )
+                                  )
+                              )
+                              #'borderWidth:' 1
+                          )
+                        )
+                    )
+                    #'handles:' #(#Any 0.334746 1.0)
+                )
+              )
+          )
+      )
+! !
+
+!DataSetBuilder class methodsFor:'menu specs'!
+
+columnMenu
+    "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:DataSetBuilder andSelector:#columnMenu
+     (Menu new fromLiteralArrayEncoding:(DataSetBuilder columnMenu)) startUp
+    "
+
+    <resource: #menu>
+
+    ^
+     
+       #(#Menu
+          
+           #(
+             #(#MenuItem
+                #'label:' 'cut'
+                #'value:' #doCutColumn
+            )
+          ) nil
+          nil
+      )
+!
+
+mainMenu
+    "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:DataSetBuilder andSelector:#mainMenu
+     (Menu new fromLiteralArrayEncoding:(DataSetBuilder mainMenu)) startUp
+    "
+
+    <resource: #menu>
+
+    ^
+     
+       #(#Menu
+          
+           #(
+             #(#MenuItem
+                #'label:' 'file'
+                #'submenu:' 
+                 #(#Menu
+                    
+                     #(
+                       #(#MenuItem
+                          #'label:' 'close'
+                          #'value:' #closeRequest
+                      )
+                    ) nil
+                    nil
+                )
+            )
+             #(#MenuItem
+                #'label:' 'code'
+                #'submenu:' 
+                 #(#Menu
+                    
+                     #(
+                       #(#MenuItem
+                          #'label:' 'class'
+                          #'value:' #doDefineClass
+                      )
+                       #(#MenuItem
+                          #'label:' 'generate code'
+                          #'value:' #doGenerateCode
+                      )
+                       #(#MenuItem
+                          #'label:' '-'
+                      )
+                       #(#MenuItem
+                          #'label:' 'browse class'
+                          #'value:' #doBrowseClass
+                      )
+                    ) nil
+                    nil
+                )
+            )
+          ) nil
+          nil
+      )
+!
+
+subMenu
+    "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:DataSetBuilder andSelector:#subMenu
+     (Menu new fromLiteralArrayEncoding:(DataSetBuilder subMenu)) startUp
+    "
+
+    <resource: #menu>
+
+    ^
+     
+       #(#Menu
+          
+           #(
+             #(#MenuItem
+                #'label:' 'createColumn'
+                #'value:' #doCreateColumn
+                #'enabled:' #isNotModified
+                #'labelImage:' #(#ResourceRetriever #MenuEditor #iconCreateItem)
+            )
+             #(#MenuItem
+                #'label:' '-'
+            )
+             #(#MenuItem
+                #'label:' ''
+            )
+             #(#MenuItem
+                #'label:' '-'
+            )
+             #(#MenuItem
+                #'label:' 'stepUp'
+                #'value:' #'doMoveColumn:'
+                #'enabled:' #isNotModified
+                #'argument:' #up
+                #'labelImage:' #(#ResourceRetriever #UIPainter #iconStepUp)
+            )
+             #(#MenuItem
+                #'label:' '-'
+            )
+             #(#MenuItem
+                #'label:' 'stepDown'
+                #'value:' #'doMoveColumn:'
+                #'enabled:' #notModified
+                #'argument:' #down
+                #'labelImage:' #(#ResourceRetriever #UIPainter #iconStepDown)
+            )
+             #(#MenuItem
+                #'label:' '-'
+            )
+          ) nil
+          nil
+      )
+! !
+
+!DataSetBuilder methodsFor:'accessing'!
+
+className
+    ^ (Smalltalk resolveName:className inClass:self class) notNil ifTrue:[className] ifFalse:[nil]
+!
+
+className:aClassName
+    |cls|
+
+    superclassName := nil.
+
+    (className := aClassName) notNil ifTrue:[
+        (cls := self resolveClassNamed) notNil ifTrue:[
+            superclassName := cls superclass name asString.
+        ] ifFalse:[
+            superclassName := 'Object'
+        ]
+    ]
+!
+
+columns
+    "returns list of columns
+    "
+    ^ columns
+!
+
+columns:aListOfColumns fromView:aColumnView
+    "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:[:aCol|
+            columns add:(aCol copy).
+            aCol rendererType == #rowSelector ifFalse:[list add:(aCol label)]
+                                               ifTrue:[list add:'Row Selector'].
+        ]
+    ].
+! !
+
+!DataSetBuilder methodsFor:'accessing menu'!
+
+columnMenu
+    "this window spec was automatically generated by the UI Builder"
+
+    ^ self class columnMenu
+
+
+!
+
+doBrowseClass
+    |cls|
+
+    (cls := self resolveClassNamed) notNil ifTrue:[
+        SystemBrowser openInClass:cls
+    ] ifFalse:[
+        self information:'no class yet'.
+    ].
+
+
+
+!
+
+doCreateColumn
+    "create a new column after selected column or at left (nothing selected)
+    "
+    |label list|
+
+    list := self seqList.
+    label := 'column ', list size printString.
+    columns add:(DataSetColumnSpec label:label selector:#ToBeDefined) afterIndex:selectedColumnIndex.
+    self seqList add:label afterIndex:selectedColumnIndex.
+    hasChanged := true.
+
+    self modified ifFalse:[
+        self selectedColumnModel value:(selectedColumnIndex + 1)
+    ].
+    self updateColumnView.
+
+!
+
+doCutColumn
+    "remove selected column
+    "
+    |idx|
+
+    (idx := selectedColumnIndex) ~~ 0 ifTrue:[
+        self selectedColumnModel value:0.
+        self seqList removeIndex:idx.
+    ].
+!
+
+doDefineClass
+    "launch a dialog to define class and superclass
+    "
+    |aspects cls oldClass oldSuper|
+
+    aspects  := IdentityDictionary new.
+    oldClass := className.
+    oldSuper := superclassName.
+
+    [true] whileTrue:[
+        className notNil ifTrue:[
+            (cls := self resolveClassNamed) notNil ifTrue:[
+                superclassName := cls superclass name asString.
+            ].
+            aspects at:#classNameChannel put:className asValue
+        ] ifFalse:[
+            aspects at:#classNameChannel put:'DSVRow' asValue
+        ].
+
+        superclassName notNil ifTrue:[
+            aspects at:#superclassNameChannel put:superclassName asValue
+        ] ifFalse:[
+            aspects at:#superclassNameChannel put:'Object' asValue
+        ].
+
+        (self openDialogInterface:#defineClassNameSpec withBindings:aspects) ifFalse:[
+            className := oldClass.
+            superclassName := oldSuper.
+          ^ self
+        ].
+        className      := ((aspects at:#classNameChannel) value)      withoutSeparators.
+        superclassName := ((aspects at:#superclassNameChannel) value) withoutSeparators.
+
+        className size == 0 ifTrue:[
+            className := nil.
+            self information:'no valid className'.
+        ] ifFalse:[
+            cls := self resolveClassNamed.
+
+            cls notNil ifTrue:[
+                cls := cls superclass name asString
+            ].
+
+            superclassName size == 0 ifTrue:[        
+                cls notNil ifTrue:[
+                    superclassName := cls
+                ] ifFalse:[
+                    superclassName := '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, '.\\' ,
+                                  'Check and try again if that is not what you want.') withCRs.
+
+                superclassName := cls.
+            ]
+        ]
+    ]
+!
+
+doGenerateCode
+    |cls superclass|
+
+    className isNil ifTrue:[
+        ^ self information:'no class defined'
+    ].
+    cls := self resolveClassNamed.
+
+    cls isNil ifTrue:[
+        superclass := Smalltalk resolveName:superclassName inClass:self class.
+
+        superclass isNil ifTrue:[
+            ^ self information:'no superclass defined'
+        ].
+        (self confirm:'create ' , className , ' ?') ifFalse:[
+            ^ self
+        ].
+        cls := superclass subclass:(className asSymbol)
+                     instanceVariableNames:''
+                     classVariableNames:''
+                     poolDictionaries:''
+                     category:'Applications'.
+    ].
+
+    self generateChoicesIn:cls.
+    self generateMenuIn:cls.
+    self generatePrintSelectorIn:cls.
+    self generateReadSelectorIn:cls.
+    self generateWriteSelectorIn:cls.
+!
+
+doMoveColumn:upOrDown
+    "move selected column up or down
+    "
+    |idx list label col size|
+
+    (idx := selectedColumnIndex) == 0 ifTrue:[
+        ^ self
+    ].
+    list := self seqList.
+    size := list size.
+
+    size == 1 ifTrue:[
+        ^ self
+    ].
+    hasChanged := true.
+    selectedColumnIndex := 0.
+    label := list at:idx.
+    col   := columns at:idx.
+    list    removeIndex:idx.
+    columns removeIndex:idx.
+
+    upOrDown == #up ifTrue:[
+        idx == 1 ifTrue:[idx := size]
+                ifFalse:[idx := idx - 1]
+    ] ifFalse:[
+        idx == size ifTrue:[idx := 1]
+                   ifFalse:[idx := idx + 1]
+    ].
+    columns add:col   beforeIndex:idx.
+    list    add:label beforeIndex:idx.
+    self selectedColumnModel value:idx.
+    self updateColumnView.
+!
+
+mainMenu
+    "this window spec was automatically generated by the UI Builder"
+
+    ^ self class mainMenu
+
+
+!
+
+subMenu
+    "this window spec was automatically generated by the UI Builder"
+
+    ^ self class subMenu
+
+
+! !
+
+!DataSetBuilder methodsFor:'actions'!
+
+accept
+    "accept changes made
+    "
+    |column type|
+
+    self modifiedChannel value == false ifTrue:[
+        ^ self
+    ].
+    isModified := true.
+
+    (column := self selectedColumn) isNil ifTrue:[
+        ^ self cancel
+    ].
+
+    type := (aspects at:#rendererType) value.
+
+    type == #rowSelector ifTrue:[
+        #( label width minWidth editorType choices readSelector printSelector
+           formatString type size height canSelect
+         ) 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 updateColumnView.
+    self cancel
+!
+
+cancel
+    "remove all changes and reload selected column
+    "
+    |column|
+
+    isModified := true.
+    (column := self selectedColumn) isNil ifTrue:[
+        self tabModel value:0.
+    ] ifFalse:[
+        aspects keysAndValuesDo:[:aKey :aModel|
+            aModel value:(column perform:aKey)
+        ].
+        tabSelectionIndex == 0 ifTrue:[self tabModel value:1].
+    ].
+    self modifiedChannel value:false.
+    self isNotModified   value:true.
+    isModified := false.
+! !
+
+!DataSetBuilder methodsFor:'aspects'!
+
+aspectFor:aKey
+    "returns aspect for a key or nil
+    "
+  ^ aspects at:aKey ifAbsent:[ super aspectFor:aKey ]
+
+
+!
+
+editorTypeList
+    "generate list of supported editor types
+    "
+    |list|
+
+    (list := builder bindingAt:#editorTypeList) isNil ifTrue:[
+        list := OrderedCollection new.
+        DataSetColumnSpec slices do:[:aSlice||type|
+            type := aSlice at:1.
+            (list includes:type) ifFalse:[list add:type].
+        ].
+        builder aspectAt:#editorTypeList put:list.
+
+    ].
+    ^ list
+!
+
+isNotModified
+    "returns a boolean value holder which is set to true if something is modified
+     and not accepted
+    "
+    ^ builder valueAspectFor:#isNotModified initialValue:true
+
+
+
+!
+
+modifiedChannel
+    "returns a boolean value holder which is set to true if something is modified
+     and not accepted
+    "
+    ^ builder booleanValueAspectFor:#modifiedChannel
+
+
+
+!
+
+rendererTypeList
+    "generate list of supported renderer types
+    "
+    |list|
+
+    (list := builder bindingAt:#rendererTypeList) isNil ifTrue:[
+        list := OrderedCollection new.
+        DataSetColumnSpec slices do:[:aSlice||type|
+            type := aSlice at:2.
+            (list includes:type) ifFalse:[list add:type].
+        ].
+        builder aspectAt:#rendererTypeList put:list.
+
+    ].
+    ^ list
+!
+
+selectedColumnModel
+    "automatically generated by UIPainter ..."
+
+    |holder|
+
+    (holder := builder bindingAt:#selectedColumnModel) isNil ifTrue:[
+        holder := AspectAdaptor new subject:self; forAspect:#selectedColumnIndex.
+        builder aspectAt:#selectedColumnModel put:holder.
+    ].
+    ^ holder
+!
+
+seqList
+    "automatically generated by UIPainter ..."
+
+    |list|
+
+    (list := builder bindingAt:#seqList) isNil ifTrue:[
+        builder aspectAt:#seqList put:(list :=  List new).
+    ].
+    ^ list
+!
+
+specChannel
+    "automatically generated by UIPainter ..."
+
+    |holder|
+
+    (holder := builder bindingAt:#specChannel) isNil ifTrue:[
+        builder aspectAt:#specChannel put:(holder :=  ValueHolder new).
+    ].
+    ^ holder
+!
+
+tabList
+    "automatically generated by UIPainter ..."
+
+    ^ self class slices collect:[:aSlice| aSlice first ]
+
+!
+
+tabModel
+    "returns a value holder which keeps the index of the current selected tab or 0
+    "
+    |holder|
+
+    (holder := builder bindingAt:#tabModel) isNil ifTrue:[
+        holder := AspectAdaptor new subject:self; forAspect:#tabSelectionIndex.
+        builder aspectAt:#tabModel put:holder.
+    ].
+    ^ holder
+!
+
+typeList
+    "automatically generated by UIPainter ..."
+
+    ^ #( string password number numberOrNil symbolOrNil )
+! !
+
+!DataSetBuilder methodsFor:'change & update'!
+
+update:something with:aParameter from:someObject
+    "one of my aspects has changed; update modified channel
+    "
+    isModified ifFalse:[
+        isModified := hasChanged := true.
+        self modifiedChannel value:true.
+        self isNotModified   value:false.
+    ]
+! !
+
+!DataSetBuilder methodsFor:'code generation'!
+
+compile:aCode forClass:aClass inCategory:aCategory
+    "compile method for class in a category
+    "
+    ByteCodeCompiler compile:aCode withCRs forClass:aClass inCategory:aCategory
+!
+
+generateChoicesIn:aClass
+    "generate code for #choices
+    "
+    |sel catg code|
+
+    catg := 'accessing choices' asSymbol.
+    code :=   '\'
+            , '    "automatically generated by DataSetBuilder ..."\'
+            , '\'
+            , '    "get choices for visual editor; (a list of labels)\'
+            , '\'
+            , '    ^ nil'
+            .
+
+    columns do:[:aColumn|
+        (     aColumn canSelect
+         and:[aColumn rendererType ~~ #rowSelector
+         and:[(sel := aColumn choices) notNil
+         and:[(aClass implements:sel) not]]]
+        ) ifTrue:[
+            self compile:(sel asString, code) forClass:aClass inCategory:catg
+        ]
+    ]
+!
+
+generateMenuIn:aClass
+    "generate code for #menu
+    "
+    |sel catg code|
+
+    catg := 'accessing menus' asSymbol.
+    code :=   '\'
+            , '    "automatically generated by DataSetBuilder ..."\'
+            , '\'
+            , '    "get middleButton menu for selected cell in column"\'
+            , '\'
+            , '    ^ nil'
+            .
+
+    columns do:[:aColumn|
+        (     aColumn canSelect
+         and:[(sel := aColumn menu) notNil
+         and:[(aClass implements:sel) not]]
+        ) ifTrue:[
+            self compile:(sel asString, code) forClass:aClass inCategory:catg
+        ]
+    ]
+!
+
+generatePrintSelectorIn:aClass
+    "generate code for #printSelector
+    "
+    |sel catg code|
+
+    catg := 'accessing printSelector' asSymbol.
+    code :=   'aGC\'
+            , '    "automatically generated by DataSetBuilder ..."\'
+            , '\'
+            , '    "get drawable image or text on a gc"\'
+            , '\'
+            , '    ^ nil'
+            .
+
+    columns do:[:aColumn|
+        (     aColumn rendererType ~~ #rowSelector
+         and:[(sel := aColumn printSelector) notNil
+         and:[(aClass implements:sel) not]]
+        ) ifTrue:[
+            self compile:(sel asString, code) forClass:aClass inCategory:catg
+        ]
+    ]
+!
+
+generateReadSelectorIn:aClass
+    "generate code for #readSelector
+    "
+    |sel catg code bCode|
+
+    catg := 'accessing readSelector' asSymbol.
+    code :=   '\'
+            , '    "automatically generated by DataSetBuilder ..."\'
+            , '\'
+            , '    "get value"\'
+            , '\'
+            .
+
+    columns do:[:aColumn|
+        (     aColumn rendererType ~~ #rowSelector 
+         and:[(sel := aColumn readSelector) notNil
+         and:[(aClass implements:sel) not]]
+        ) ifTrue:[
+            (aColumn printSelector isNil or:[aColumn canSelect]) ifTrue:[
+                bCode := sel asString, code.
+                aColumn rendererType == #CheckToggle ifFalse:[
+                    bCode := bCode, '    ^ nil'
+                ] ifTrue:[
+                    bCode := bCode, '    ^ true'
+                ]. 
+                self compile:bCode forClass:aClass inCategory:catg
+            ]
+        ]
+    ]
+!
+
+generateWriteSelectorIn:aClass
+    "generate code for #writeSelector
+    "
+    |sel catg code|
+
+    catg := 'accessing writeSelector' asSymbol.
+    code :=   'aValue\'
+            , '    "automatically generated by DataSetBuilder ..."\'
+            , '\'
+            , '    "set value"\'
+            .
+
+    columns do:[:aColumn|
+        (     (sel := aColumn writeSelector) notNil 
+         and:[(aClass implements:sel) not]
+        ) ifTrue:[
+            self compile:(sel asString, code) forClass:aClass inCategory:catg
+        ]
+    ]
+! !
+
+!DataSetBuilder methodsFor:'initialization'!
+
+initialize
+    "setup aspects used by column description specifications
+    "
+    |holder|
+
+    super initialize.
+    selectedColumnIndex := 0.
+    tabSelectionIndex   := 0.
+    columns := OrderedCollection new.
+    aspects := IdentityDictionary new.
+    hasChanged := false.
+    isModified := false.
+
+    #(
+        label
+        canSelect
+        choices
+        editorType
+        formatString
+        size
+        type
+        width
+        minWidth
+        height
+        menu
+        printSelector
+        readSelector
+        rendererType
+        showColSeparator
+        showRowSeparator
+
+     ) do:[:aKey|
+        aspects at:aKey put:(holder := ValueHolder new).
+        holder addDependent:self.
+    ].
+
+! !
+
+!DataSetBuilder methodsFor:'private'!
+
+resolveClassNamed
+    "returns current class or nil
+    "
+    ^ Smalltalk resolveName:className inClass:self class.
+
+!
+
+updateColumnView
+    "update column view from column descriptions
+    "
+    columnView notNil ifTrue:[
+        columnView columnDescriptors:columns.
+    ].
+! !
+
+!DataSetBuilder methodsFor:'queries'!
+
+hasChanged
+    "returns true if changes are done to the original column description
+    "
+    ^ hasChanged
+!
+
+modified
+    "returns true if current specification is modified
+    "
+    ^ self modifiedChannel value
+! !
+
+!DataSetBuilder methodsFor:'selection'!
+
+selectedColumn
+    "returns selected column or nil
+    "
+    ^ selectedColumnIndex == 0 ifFalse:[columns at:selectedColumnIndex]
+                                ifTrue:[nil]
+!
+
+selectedColumnIndex
+    "returns selected column index or 0
+    "
+    ^ selectedColumnIndex
+!
+
+selectedColumnIndex:something
+    "change selected column and update specifications
+    "
+    something == selectedColumnIndex ifFalse:[
+        selectedColumnIndex := something ? 0.
+        self cancel.
+    ].
+
+!
+
+tabSelectionIndex
+    "returns selected tab index or 0
+    "
+    ^ tabSelectionIndex
+!
+
+tabSelectionIndex:something
+    "change selected tab and set corresponding specification
+    "
+    |specSelector|
+
+    something == tabSelectionIndex ifTrue:[
+        ^ self
+    ].
+    self selectedColumn isNil ifTrue:[
+        tabSelectionIndex == 0 ifTrue:[^ self ].
+        tabSelectionIndex := 0
+    ] ifFalse:[
+        (tabSelectionIndex := something) ~~ 0 ifTrue:[
+            specSelector := (self class slices at:tabSelectionIndex) last.
+        ]
+    ].
+    self specChannel value:specSelector
+
+
+! !
+
+!DataSetBuilder class methodsFor:'documentation'!
+
+version
+    ^ '$Header$'
+! !