DataSetBuilder.st
author tz
Thu, 05 Mar 1998 23:30:36 +0100
changeset 700 2aae4f3b6526
parent 687 363d54091c9e
child 799 22734b99f830
permissions -rw-r--r--
supports merging into existing help specs

"
 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.
"





ToolApplicationModel subclass:#DataSetBuilder
	instanceVariableNames:'className superclassName hasChanged columnView columns
		selectedColumnIndex tabSelectionIndex aspects'
	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, eXept Software AG
"

! !

!DataSetBuilder class methodsFor:'help specs'!

helpSpec
    "return a dictionary filled with helpKey -> helptext associations.
     These are used by the activeHelp tool."

    "
    UIHelpTool openOnClass:DataSetBuilder    
    "

  ^ super helpSpec addPairsFrom:#(

#addColumn
'Adds a new column.'

#basicsEditor
'Default widget type or a selector returning an instance of an user defined widget opened in the cell.'

#basicsFont
'Sets the font of the label text.'

#basicsJustification
'Aligns the label text to the left, right, or centered in the cell.'

#basicsLabel
'The label of the column or a selector returning a string an image.'

#basicsLabelIsImage
'Turns on/off image behavior of the label string; i.e. it is used as selector returning an image.'

#basicsRenderer
'Specifies displaying cell as Text, CheckToggle, ComboBox, ComboList or as a RowSelector.'

#colorsBackgroundCellColor
'Sets the background color of the column.'

#colorsBackgroundLabelColor
'Sets the background color of the label.'

#colorsBackgroundSelector
'Selector returning the background color for a cell (optional).'

#colorsForegroundCellColor
'Sets the foreground color of the column.'

#colorsForegroundLabelColor
'Sets the foreground color of the label.'

#colorsForegroundSelector
'Selector returning the foreground color for a cell (optional).'

#formatInputType
'A type converter symbol used by the input field.'

#formatMaxSize
'Maximum size of the string which can be typed in. 0 or nil means unlimited.'

#formatTextFormat
'Format string specifying the output format of the cell text. In this release, only numbers are supported (for example: 0.0000).'

#frameColumnWidth
'Width (fixed) of a column (optional).'

#frameMinWidth
'Minimum width of the column (optional).'

#frameRowHeight
'Height of the row (optional).'

#frameShowColumnSeparator
'Turns on/off displaying column separators.'

#frameShowRowSeparator
'Turns on/off displaying row separators.'

#selectionCellClickSelector
'A selector called if cell was selected. '

#selectionCellDoubleClickSelector
'A selector called if cell was double clicked.'

#selectionCellSelector
'An optional selector, which is used to test whether the cell in the column is selectable; the ''Is Selectable'' flag must be enabled.'

#selectionIsSelectable
'Turns on/off selection behavior of a column.'

#selectionLabelClickSelector
'A selector called if label cell was clicked.'

#selectionLabelSelectorArgument
'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.'

#valuesMenuSelector
'A selector returning a middle button menu.'

#valuesPrintSelector
'A key selector used to register images on a DSVColumnView (the arg). For more detailed info see #register... methods in DSVColumnView.'

#valuesReadSelector
'A selector used to get (string or a bitmap) or set (if the write selector is undefined) the contents of a cell.'

#valuesWriteSelector
'A selector used to set the value of a cell.'

)
! !

!DataSetBuilder class methodsFor:'interface 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 299 0 234 0 587 0 489 0)
              #label: 'DataSet Basic'
              #min: #(#Point 10 10)
              #max: #(#Point 1280 1024)
              #bounds: #(#Rectangle 299 234 588 490)
              #usePreferredExtent: false
          )
          #component: 
           #(#SpecCollection
              #collection: 
               #(
                 #(#FramedBoxSpec
                    #name: 'framedBox1'
                    #layout: #(#LayoutFrame 0 0.0 3 0 0 1.0 145 0)
                    #component: 
                     #(#SpecCollection
                        #collection: 
                         #(
                           #(#LabelSpec
                              #name: 'label1'
                              #layout: #(#AlignmentOrigin 107 0 32 0 1 0.5)
                              #label: 'Label:'
                              #resizeForLabel: true
                          )
                           #(#InputFieldSpec
                              #name: 'labelField'
                              #layout: #(#LayoutFrame 110 0 21 0 15 1.0 43 0)
                              #activeHelpKey: #basicsLabel
                              #tabable: true
                              #model: #label
                          )
                           #(#CheckBoxSpec
                              #name: 'labelIsImage'
                              #layout: #(#LayoutOrigin 107 0 103 0)
                              #activeHelpKey: #basicsLabelIsImage
                              #tabable: true
                              #model: #labelIsImage
                              #label: 'Label Is Image'
                          )
                           #(#UISubSpecification
                              #name: 'fontSubSpec'
                              #layout: #(#LayoutFrame 60 0.0 47 0 15 1.0 75 0)
                              #activeHelpKey: #basicsFont
                              #majorKey: #UISpecification
                              #minorKey: #fontSpec
                          )
                           #(#PopUpListSpec
                              #name: 'Alignment'
                              #layout: #(#LayoutFrame 110 0 78 0 15 1.0 100 0)
                              #activeHelpKey: #basicsJustification
                              #label: 'Alignment'
                              #model: #labelAlignment
                              #menu: 
                               #(#left
                                  #right #center
                              )
                              #useIndex: false
                          )
                           #(#LabelSpec
                              #name: 'JustificationLabel'
                              #layout: #(#AlignmentOrigin 107 0 89 0 1 0.5)
                              #label: 'Justification:'
                              #adjust: #left
                              #resizeForLabel: true
                          )
                        )
                    )
                    #label: 'Header:'
                    #labelPosition: #topLeft
                )
                 #(#FramedBoxSpec
                    #name: 'typesFrame'
                    #layout: #(#LayoutFrame 0 0.0 145 0 0 1.0 227 0)
                    #component: 
                     #(#SpecCollection
                        #collection: 
                         #(
                           #(#LabelSpec
                              #name: 'rendererLabel'
                              #layout: #(#AlignmentOrigin 107 0 29 0 1 0.5)
                              #label: 'Renderer:'
                              #resizeForLabel: true
                          )
                           #(#ComboListSpec
                              #name: 'rendererField'
                              #layout: #(#LayoutFrame 110 0 18 0 15 1.0 40 0)
                              #activeHelpKey: #basicsRenderer
                              #tabable: true
                              #model: #rendererType
                              #comboList: #rendererTypeList
                              #useIndex: false
                          )
                           #(#LabelSpec
                              #name: 'editorLabel'
                              #layout: #(#AlignmentOrigin 107 0 55 0 1 0.5)
                              #label: 'Editor:'
                              #resizeForLabel: true
                          )
                           #(#ComboBoxSpec
                              #name: 'editorField'
                              #layout: #(#LayoutFrame 110 0 44 0 15 1.0 66 0)
                              #activeHelpKey: #basicsEditor
                              #tabable: true
                              #model: #editorType
                              #type: #symbolOrNil
                              #comboList: #editorTypeList
                              #useIndex: false
                          )
                        )
                    )
                    #label: 'Cell Type:'
                    #labelPosition: #topLeft
                )
              )
          )
      )
!

colorsEditSpec
    "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:#colorsEditSpec
     DataSetBuilder new openInterface:#colorsEditSpec
    "

    <resource: #canvas>

    ^
     
       #(#FullSpec
          #window: 
           #(#WindowSpec
              #name: 'DataSet Misc'
              #layout: #(#LayoutFrame 383 0 282 0 751 0 581 0)
              #label: 'DataSet Misc'
              #min: #(#Point 10 10)
              #max: #(#Point 1280 1024)
              #bounds: #(#Rectangle 383 282 752 582)
              #usePreferredExtent: false
          )
          #component: 
           #(#SpecCollection
              #collection: 
               #(
                 #(#FramedBoxSpec
                    #name: 'ColorsBox'
                    #layout: #(#LayoutFrame 0 0.0 3 0 0 1.0 88 0)
                    #component: 
                     #(#SpecCollection
                        #collection: 
                         #(
                           #(#LabelSpec
                              #name: 'label1'
                              #layout: #(#AlignmentOrigin 107 0 27 0 1 0.5)
                              #label: 'Foreground:'
                              #adjust: #right
                              #resizeForLabel: true
                          )
                           #(#ColorMenuSpec
                              #name: 'colorMenu1'
                              #layout: #(#LayoutFrame 110 0 15 0 12 1.0 37 0)
                              #activeHelpKey: #colorsForegroundLabelColor
                              #model: #labelForegroundColor
                              #labelsAreColored: true
                          )
                           #(#LabelSpec
                              #name: 'label2'
                              #layout: #(#AlignmentOrigin 107 0 55 0 1 0.5)
                              #label: 'Background:'
                              #adjust: #right
                              #resizeForLabel: true
                          )
                           #(#ColorMenuSpec
                              #name: 'colorMenu2'
                              #layout: #(#LayoutFrame 110 0 43 0 12 1.0 65 0)
                              #activeHelpKey: #colorsBackgroundLabelColor
                              #model: #labelBackgroundColor
                              #labelsAreColored: false
                          )
                        )
                    )
                    #label: 'Label Colors:'
                    #labelPosition: #topLeft
                )
                 #(#FramedBoxSpec
                    #name: 'defaultColorsBox'
                    #layout: #(#LayoutFrame 0 0.0 88 0 0 1.0 230 0)
                    #component: 
                     #(#SpecCollection
                        #collection: 
                         #(
                           #(#LabelSpec
                              #name: 'fgLabel'
                              #layout: #(#AlignmentOrigin 107 0 27 0 1 0.5)
                              #label: 'Foreground:'
                              #adjust: #right
                              #resizeForLabel: true
                          )
                           #(#ColorMenuSpec
                              #name: 'fgMenu'
                              #layout: #(#LayoutFrame 110 0 15 0 12 1.0 37 0)
                              #activeHelpKey: #colorsForegroundCellColor
                              #model: #foregroundColor
                              #labelsAreColored: true
                          )
                           #(#LabelSpec
                              #name: 'bgLabel'
                              #layout: #(#AlignmentOrigin 107 0 55 0 1 0.5)
                              #label: 'Background:'
                              #adjust: #right
                              #resizeForLabel: true
                          )
                           #(#ColorMenuSpec
                              #name: 'bgMenu'
                              #layout: #(#LayoutFrame 110 0 43 0 12 1.0 65 0)
                              #activeHelpKey: #colorsBackgroundCellColor
                              #model: #backgroundColor
                              #labelsAreColored: false
                          )
                           #(#LabelSpec
                              #name: 'fgSelLabel'
                              #layout: #(#AlignmentOrigin 107 0 89 0 1 0.5)
                              #label: 'FG-Selector:'
                              #adjust: #right
                              #resizeForLabel: true
                          )
                           #(#InputFieldSpec
                              #name: 'fgSelField'
                              #layout: #(#LayoutFrame 110 0 78 0 15 1.0 100 0)
                              #activeHelpKey: #colorsForegroundSelector
                              #tabable: true
                              #model: #foregroundSelector
                              #type: #symbolOrNil
                          )
                           #(#LabelSpec
                              #name: 'bgSelLabel'
                              #layout: #(#AlignmentOrigin 107 0 114 0 1 0.5)
                              #label: 'BG-Selector:'
                              #adjust: #right
                              #resizeForLabel: true
                          )
                           #(#InputFieldSpec
                              #name: 'bgSelField'
                              #layout: #(#LayoutFrame 110 0 103 0 15 1.0 125 0)
                              #activeHelpKey: #colorsBackgroundSelector
                              #tabable: true
                              #model: #backgroundSelector
                              #type: #symbolOrNil
                          )
                        )
                    )
                    #label: 'Cell Colors:'
                    #labelPosition: #topLeft
                )
              )
          )
      )
!

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: 'Data Set Builder'
              #layout: #(#LayoutFrame 425 0 253 0 751 0 388 0)
              #label: 'Data Set Builder'
              #min: #(#Point 10 10)
              #max: #(#Point 1152 900)
              #bounds: #(#Rectangle 425 253 752 389)
              #usePreferredExtent: false
          )
          #component: 
           #(#SpecCollection
              #collection: 
               #(
                 #(#FramedBoxSpec
                    #name: 'framedBox1'
                    #layout: #(#LayoutFrame 0 0.0 3 0.0 0 1.0 -34 1.0)
                    #label: 'Classes for code'
                    #labelPosition: #topLeft
                )
                 #(#LabelSpec
                    #name: 'classLabel'
                    #layout: #(#AlignmentOrigin 73 0.11 38 0 1 0.5)
                    #label: 'Class:'
                    #adjust: #right
                    #resizeForLabel: true
                )
                 #(#InputFieldSpec
                    #name: 'classNameInputField'
                    #layout: #(#LayoutFrame 77 0.11 27 0 -16 1.0 49 0)
                    #tabable: true
                    #model: #classNameChannel
                )
                 #(#LabelSpec
                    #name: 'superClassLabel'
                    #layout: #(#AlignmentOrigin 73 0.11 65 0 1 0.5)
                    #label: 'Superclass:'
                    #adjust: #right
                    #resizeForLabel: true
                )
                 #(#InputFieldSpec
                    #name: 'superclassNameInputField'
                    #layout: #(#LayoutFrame 76 0.11 55 0 -16 1.0 77 0)
                    #tabable: true
                    #model: #superclassNameChannel
                )
                 #(#UISubSpecification
                    #name: 'SubSpecification'
                    #layout: #(#LayoutFrame 0 0.0 -29 1 0 1.0 -5 1.0)
                    #majorKey: #ToolApplicationModel
                    #minorKey: #windowSpecForCommitWithoutChannels
                )
              )
          )
      )
!

formatEditSpec
    "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:#formatEditSpec
     DataSetBuilder new openInterface:#formatEditSpec
    "

    <resource: #canvas>

    ^
     
       #(#FullSpec
          #window: 
           #(#WindowSpec
              #name: 'DataSet Details'
              #layout: #(#LayoutFrame 415 0 266 0 802 0 557 0)
              #label: 'DataSet Details'
              #min: #(#Point 10 10)
              #max: #(#Point 1280 1024)
              #bounds: #(#Rectangle 415 266 803 558)
              #usePreferredExtent: false
          )
          #component: 
           #(#SpecCollection
              #collection: 
               #(
                 #(#FramedBoxSpec
                    #name: 'framedBox1'
                    #layout: #(#LayoutFrame 0 0.0 3 0 0 1.0 114 0)
                    #component: 
                     #(#SpecCollection
                        #collection: 
                         #(
                           #(#LabelSpec
                              #name: 'typeLabel'
                              #layout: #(#AlignmentOrigin 107 0 29 0 1 0.5)
                              #label: 'Input Type:'
                              #resizeForLabel: true
                          )
                           #(#ComboListSpec
                              #name: 'typeCombo'
                              #layout: #(#LayoutFrame 110 0 18 0 15 1.0 40 0)
                              #activeHelpKey: #formatInputType
                              #tabable: true
                              #model: #type
                              #comboList: 
                               #(#string
                                  #password #number
                                  #numberOrNil #symbolOrNil
                              )
                              #useIndex: false
                          )
                           #(#LabelSpec
                              #name: 'sizeLabel'
                              #layout: #(#AlignmentOrigin 107 0 55 0 1 0.5)
                              #label: 'Max Size:'
                              #resizeForLabel: true
                          )
                           #(#InputFieldSpec
                              #name: 'sizeField'
                              #layout: #(#LayoutFrame 110 0 44 0 15 1.0 66 0)
                              #activeHelpKey: #formatMaxSize
                              #tabable: true
                              #model: #size
                              #type: #numberOrNil
                          )
                           #(#LabelSpec
                              #name: 'formatLabel'
                              #layout: #(#AlignmentOrigin 107 0 80 0 1 0.5)
                              #label: 'Text Format:'
                              #resizeForLabel: true
                          )
                           #(#InputFieldSpec
                              #name: 'formatField'
                              #layout: #(#LayoutFrame 110 0 69 0 15 1.0 91 0)
                              #activeHelpKey: #formatTextFormat
                              #tabable: true
                              #model: #formatString
                          )
                        )
                    )
                    #label: 'Input Format'
                    #labelPosition: #topLeft
                )
              )
          )
      )
!

frameEditSpec
    "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:#frameEditSpec
     DataSetBuilder new openInterface:#frameEditSpec
    "

    <resource: #canvas>

    ^
     
       #(#FullSpec
          #window: 
           #(#WindowSpec
              #name: 'DataSet Dimension'
              #layout: #(#LayoutFrame 354 0 262 0 644 0 475 0)
              #label: 'DataSet Dimension'
              #min: #(#Point 10 10)
              #max: #(#Point 1280 1024)
              #bounds: #(#Rectangle 354 262 645 476)
              #usePreferredExtent: false
          )
          #component: 
           #(#SpecCollection
              #collection: 
               #(
                 #(#FramedBoxSpec
                    #name: 'separatorBox'
                    #layout: #(#LayoutFrame 0 0.0 3 0 0 1.0 86 0)
                    #component: 
                     #(#SpecCollection
                        #collection: 
                         #(
                           #(#CheckBoxSpec
                              #name: 'showRowSeparator'
                              #layout: #(#LayoutFrame 18 0 19 0 194 0 42 0)
                              #activeHelpKey: #frameShowRowSeparator
                              #tabable: true
                              #model: #showRowSeparator
                              #label: 'Show Row-Separator'
                          )
                           #(#CheckBoxSpec
                              #name: 'showColSeparator'
                              #layout: #(#LayoutFrame 18 0 45 0 194 0 68 0)
                              #activeHelpKey: #frameShowColumnSeparator
                              #tabable: true
                              #model: #showColSeparator
                              #label: 'Show Column-Separator'
                          )
                        )
                    )
                    #label: 'Separators'
                    #labelPosition: #topLeft
                )
                 #(#FramedBoxSpec
                    #name: 'framedBox1'
                    #layout: #(#LayoutFrame 0 0.0 86 0 0 1.0 198 0)
                    #component: 
                     #(#SpecCollection
                        #collection: 
                         #(
                           #(#LabelSpec
                              #name: 'widthLabel'
                              #layout: #(#AlignmentOrigin 107 0.0 28 0 1 0.5)
                              #label: 'Column Width:'
                              #adjust: #right
                              #resizeForLabel: true
                          )
                           #(#InputFieldSpec
                              #name: 'widthField'
                              #layout: #(#LayoutFrame 110 0 17 0 15 1.0 39 0)
                              #activeHelpKey: #frameColumnWidth
                              #tabable: true
                              #model: #width
                              #type: #numberOrNil
                          )
                           #(#LabelSpec
                              #name: 'minWidthLabel'
                              #layout: #(#AlignmentOrigin 107 0.0 53 0 1 0.5)
                              #label: 'Min Width:'
                              #adjust: #right
                              #resizeForLabel: true
                          )
                           #(#InputFieldSpec
                              #name: 'minWidthField'
                              #layout: #(#LayoutFrame 110 0 42 0 15 1.0 64 0)
                              #activeHelpKey: #frameMinWidth
                              #tabable: true
                              #model: #minWidth
                              #type: #numberOrNil
                          )
                           #(#LabelSpec
                              #name: 'heightLabel'
                              #layout: #(#AlignmentOrigin 107 0.0 84 0 1 0.5)
                              #label: 'Row Height:'
                              #adjust: #right
                              #resizeForLabel: true
                          )
                           #(#InputFieldSpec
                              #name: 'heightField'
                              #layout: #(#LayoutFrame 110 0 73 0 15 1.0 95 0)
                              #activeHelpKey: #frameRowHeight
                              #tabable: true
                              #model: #height
                              #type: #numberOrNil
                          )
                        )
                    )
                    #label: 'Dimensions:'
                    #labelPosition: #topLeft
                )
              )
          )
      )
!

selectionEditSpec
    "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:#selectionEditSpec
     DataSetBuilder new openInterface:#selectionEditSpec
    "

    <resource: #canvas>

    ^
     
       #(#FullSpec
          #window: 
           #(#WindowSpec
              #name: 'DataSet Basic'
              #layout: #(#LayoutFrame 411 0 287 0 699 0 542 0)
              #label: 'DataSet Basic'
              #min: #(#Point 10 10)
              #max: #(#Point 1280 1024)
              #bounds: #(#Rectangle 411 287 700 543)
              #usePreferredExtent: false
          )
          #component: 
           #(#SpecCollection
              #collection: 
               #(
                 #(#FramedBoxSpec
                    #name: 'framedBox1'
                    #layout: #(#LayoutFrame 0 0.0 3 0 0 1.0 85 0)
                    #component: 
                     #(#SpecCollection
                        #collection: 
                         #(
                           #(#LabelSpec
                              #name: 'ActionLabel'
                              #layout: #(#AlignmentOrigin 107 0 28 0 1 0.5)
                              #label: 'Selector:'
                              #adjust: #left
                              #resizeForLabel: true
                          )
                           #(#InputFieldSpec
                              #name: 'ActionSelector'
                              #layout: #(#LayoutFrame 110 0 17 0 15 1.0 39 0)
                              #activeHelpKey: #selectionLabelClickSelector
                              #tabable: true
                              #model: #labelActionSelector
                              #type: #symbolOrNil
                          )
                           #(#LabelSpec
                              #name: 'ArgumentLabel'
                              #layout: #(#AlignmentOrigin 107 0 53 0 1 0.5)
                              #label: 'Argument:'
                              #adjust: #left
                              #resizeForLabel: true
                          )
                           #(#InputFieldSpec
                              #name: 'ArgumentValue'
                              #layout: #(#LayoutFrame 110 0 42 0 15 1.0 64 0)
                              #activeHelpKey: #selectionLabelSelectorArgument
                              #tabable: true
                              #model: #labelActionArgument
                              #type: #string
                          )
                        )
                    )
                    #label: 'Label Select Action:'
                    #labelPosition: #topLeft
                )
                 #(#FramedBoxSpec
                    #name: 'framedBox2'
                    #layout: #(#LayoutFrame 0 0.0 85 0 0 1.0 166 0)
                    #component: 
                     #(#SpecCollection
                        #collection: 
                         #(
                           #(#CheckBoxSpec
                              #name: 'canSelect'
                              #layout: #(#Point 107 17)
                              #activeHelpKey: #selectionIsSelectable
                              #tabable: true
                              #model: #canSelect
                              #label: 'Is Selectable'
                          )
                           #(#LabelSpec
                              #name: 'selectorLabel'
                              #layout: #(#AlignmentOrigin 107 0 53 0 1 0.5)
                              #label: 'Selector:'
                              #adjust: #right
                              #resizeForLabel: true
                          )
                           #(#InputFieldSpec
                              #name: 'selectSelector'
                              #layout: #(#LayoutFrame 110 0 42 0 15 1.0 64 0)
                              #activeHelpKey: #selectionCellClickSelector
                              #tabable: true
                              #model: #selectSelector
                              #type: #symbolOrNil
                          )
                        )
                    )
                    #label: 'Cell Selection:'
                    #labelPosition: #topLeft
                )
                 #(#FramedBoxSpec
                    #name: 'framedBox3'
                    #layout: #(#LayoutFrame 0 0.0 166 0 0 1.0 220 0)
                    #component: 
                     #(#SpecCollection
                        #collection: 
                         #(
                           #(#LabelSpec
                              #name: 'doubleLabel'
                              #layout: #(#AlignmentOrigin 107 0 27 0 1 0.5)
                              #label: 'Selector:'
                              #adjust: #right
                              #resizeForLabel: true
                          )
                           #(#InputFieldSpec
                              #name: 'doubleClicked'
                              #layout: #(#LayoutFrame 110 0 16 0 15 1.0 38 0)
                              #activeHelpKey: #selectionCellDoubleClickSelector
                              #tabable: true
                              #model: #doubleClickedSelector
                              #type: #symbolOrNil
                          )
                        )
                    )
                    #label: 'Cell Double Click:'
                    #labelPosition: #topLeft
                )
              )
          )
      )
!

slices
    ^#(
        (Basics         basicsEditSpec)
        (Values         valuesEditSpec)
        (Format         formatEditSpec)
        (Selection      selectionEditSpec)
        (Frame          frameEditSpec)
        (Colors         colorsEditSpec)
    )
!

valuesEditSpec
    "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:#valuesEditSpec
     DataSetBuilder new openInterface:#valuesEditSpec
    "

    <resource: #canvas>

    ^
     
       #(#FullSpec
          #window: 
           #(#WindowSpec
              #name: 'DataSet Basic'
              #layout: #(#LayoutFrame 385 0 286 0 680 0 591 0)
              #label: 'DataSet Basic'
              #min: #(#Point 10 10)
              #max: #(#Point 1280 1024)
              #bounds: #(#Rectangle 385 286 681 592)
              #usePreferredExtent: false
          )
          #component: 
           #(#SpecCollection
              #collection: 
               #(
                 #(#FramedBoxSpec
                    #name: 'valuesBox'
                    #layout: #(#LayoutFrame 0 0.0 3 0 0 1.0 110 0)
                    #component: 
                     #(#SpecCollection
                        #collection: 
                         #(
                           #(#LabelSpec
                              #name: 'readLabel'
                              #layout: #(#AlignmentOrigin 107 0 29 0 1 0.5)
                              #label: 'Read:'
                              #adjust: #right
                              #resizeForLabel: true
                          )
                           #(#InputFieldSpec
                              #name: 'readSelector'
                              #layout: #(#LayoutFrame 110 0 18 0 15 1.0 40 0)
                              #activeHelpKey: #valuesReadSelector
                              #tabable: true
                              #model: #readSelector
                              #type: #symbolOrNil
                          )
                           #(#LabelSpec
                              #name: 'writeLabel'
                              #layout: #(#AlignmentOrigin 107 0 54 0 1 0.5)
                              #label: 'Write:'
                              #adjust: #right
                              #resizeForLabel: true
                          )
                           #(#InputFieldSpec
                              #name: 'writeSelector'
                              #layout: #(#LayoutFrame 110 0 43 0 15 1.0 65 0)
                              #activeHelpKey: #valuesWriteSelector
                              #tabable: true
                              #model: #writeSelector
                              #type: #symbolOrNil
                          )
                           #(#LabelSpec
                              #name: 'printLabel'
                              #layout: #(#AlignmentOrigin 107 0 79 0 1 0.5)
                              #label: 'Print:'
                              #adjust: #right
                              #resizeForLabel: true
                          )
                           #(#InputFieldSpec
                              #name: 'printSelector'
                              #layout: #(#LayoutFrame 110 0 68 0 15 1.0 90 0)
                              #activeHelpKey: #valuesPrintSelector
                              #tabable: true
                              #model: #printSelector
                              #type: #symbolOrNil
                          )
                        )
                    )
                    #label: 'Value Selectors:'
                    #labelPosition: #topLeft
                )
                 #(#FramedBoxSpec
                    #name: 'menusBox'
                    #layout: #(#LayoutFrame 0 0.0 110 0 0 1.0 167 0)
                    #component: 
                     #(#SpecCollection
                        #collection: 
                         #(
                           #(#LabelSpec
                              #name: 'menuLabel'
                              #layout: #(#AlignmentOrigin 107 0 29 0 1 0.5)
                              #label: 'Selector:'
                              #adjust: #right
                              #resizeForLabel: true
                          )
                           #(#InputFieldSpec
                              #name: 'menuSelector'
                              #layout: #(#LayoutFrame 110 0 18 0 15 1.0 40 0)
                              #activeHelpKey: #valuesMenuSelector
                              #tabable: true
                              #model: #menu
                              #type: #symbolOrNil
                          )
                        )
                    )
                    #label: 'Menu:'
                    #labelPosition: #topLeft
                )
                 #(#FramedBoxSpec
                    #name: 'framedBox1'
                    #layout: #(#LayoutFrame 1 0.0 167 0 1 1.0 225 0)
                    #component: 
                     #(#SpecCollection
                        #collection: 
                         #(
                           #(#LabelSpec
                              #name: 'label2'
                              #layout: #(#AlignmentOrigin 107 0 29 0 1 0.5)
                              #activeHelpKey: #valuesChoiceSelector
                              #label: 'Selector:'
                              #adjust: #right
                              #resizeForLabel: true
                          )
                           #(#InputFieldSpec
                              #name: 'inputField2'
                              #layout: #(#LayoutFrame 110 0 18 0 15 1.0 40 0)
                              #activeHelpKey: #valuesChoiceSelector
                              #tabable: true
                              #model: #choices
                              #type: #symbolOrNil
                          )
                        )
                    )
                    #label: 'List Choice:'
                    #labelPosition: #topLeft
                )
              )
          )
      )
!

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: 'Data Set Builder'
              #layout: #(#LayoutFrame 399 0 282 0 885 0 641 0)
              #label: 'Data Set Builder'
              #min: #(#Point 10 10)
              #max: #(#Point 1152 900)
              #bounds: #(#Rectangle 399 282 886 642)
              #menu: #menu
              #usePreferredExtent: false
          )
          #component: 
           #(#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)
                    #component: 
                     #(#SpecCollection
                        #collection: 
                         #(
                           #(#ViewSpec
                              #name: 'labelsView'
                              #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: '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.265905 1.0)
                )
                 #(#UISubSpecification
                    #name: 'infoBarSubSpec'
                    #layout: #(#LayoutFrame 0 0.0 -24 1 0 1.0 0 1.0)
                    #majorKey: #ToolApplicationModel
                    #minorKey: #windowSpecForInfoBar
                )
              )
          )
      )
! !

!DataSetBuilder class methodsFor:'menu specs'!

menu
    "this window spec was automatically generated by the ST/X MenuEditor"

    "do not manually edit this - the builder may not be able to
     handle the specification if its corrupted."

    "
     MenuEditor new openOnClass:DataSetBuilder andSelector:#menu
     (Menu new fromLiteralArrayEncoding:(DataSetBuilder menu)) startUp
    "

    <resource: #menu>

    ^
     
       #(#Menu
          
           #(
             #(#MenuItem
                #'label:' 'About'
                #'activeHelpKey:' #about
                #'labelImage:' #(#ResourceRetriever nil #menuIcon)
                #'submenuChannel:' #menuAbout
            )
             #(#MenuItem
                #'label:' 'File'
                #'activeHelpKey:' #file
                #'submenu:' 
                 #(#Menu
                    
                     #(
                       #(#MenuItem
                          #'label:' 'Generate Code'
                          #'value:' #doGenerateCode
                      )
                       #(#MenuItem
                          #'label:' '-'
                      )
                       #(#MenuItem
                          #'label:' 'Define Class...'
                          #'value:' #doDefineClass
                          #'activeHelpKey:' #fileDefineClass
                      )
                       #(#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:' 'Column'
                          #'value:' #doCreateColumn
                          #'activeHelpKey:' #addColumn
                          #'enabled:' #columnIsNotEditing
                          #'labelImage:' #(#ResourceRetriever nil #newColumnIcon 'Column')
                      )
                    ) nil
                    nil
                )
            )
             #(#MenuItem
                #'label:' 'Help'
                #'startGroup:' #right
                #'activeHelpKey:' #help
                #'submenuChannel:' #menuHelp
            )
          ) nil
          nil
      )
!

menuEdit
    "this window spec was automatically generated by the ST/X MenuEditor"

    "do not manually edit this - the builder may not be able to
     handle the specification if its corrupted."

    "
     MenuEditor new openOnClass:DataSetBuilder andSelector:#menuEdit
     (Menu new fromLiteralArrayEncoding:(DataSetBuilder menuEdit)) startUp
    "

    <resource: #menu>

    ^
     
       #(#Menu
          
           #(
             #(#MenuItem
                #'label:' 'Cut'
                #'value:' #doCutColumn
                #'activeHelpKey:' #editCut
                #'enabled:' #isColumnSelected
            )
             #(#MenuItem
                #'label:' 'Copy'
                #'value:' #doCopyColumn
                #'activeHelpKey:' #editCopy
                #'enabled:' #isColumnSelected
            )
             #(#MenuItem
                #'label:' 'Paste'
                #'value:' #doPasteColumn
                #'activeHelpKey:' #editPaste
                #'enabled:' #valueOfHavingClipboard
            )
             #(#MenuItem
                #'label:' '-'
            )
             #(#MenuItem
                #'label:' 'Move Up'
                #'value:' #'doMoveColumn:'
                #'activeHelpKey:' #editMoveUp
                #'enabled:' #isColumnSelected
                #'argument:' #up
                #'labelImage:' #(#ResourceRetriever #DataSetBuilder #upIcon 'Move Up')
            )
             #(#MenuItem
                #'label:' 'Move Down'
                #'value:' #'doMoveColumn:'
                #'activeHelpKey:' #editMoveDown
                #'enabled:' #isColumnSelected
                #'argument:' #down
                #'labelImage:' #(#ResourceRetriever #DataSetBuilder #downIcon 'Move Down')
            )
          ) nil
          nil
      )
!

menuToolbar
    "this window spec was automatically generated by the ST/X MenuEditor"

    "do not manually edit this - the builder may not be able to
     handle the specification if its corrupted."

    "
     MenuEditor new openOnClass:DataSetBuilder andSelector:#menuToolbar
     (Menu new fromLiteralArrayEncoding:(DataSetBuilder menuToolbar)) startUp
    "

    <resource: #menu>

    ^
     
       #(#Menu
          
           #(
             #(#MenuItem
                #'label:' 'Add Column'
                #'isButton:' true
                #'value:' #doCreateColumn
                #'activeHelpKey:' #addColumn
                #'enabled:' #columnIsNotEditing
                #'labelImage:' #(#ResourceRetriever nil #newColumnIcon)
            )
             #(#MenuItem
                #'label:' ''
            )
             #(#MenuItem
                #'label:' 'Move Up'
                #'isButton:' true
                #'value:' #'doMoveColumn:'
                #'activeHelpKey:' #editMoveUp
                #'enabled:' #isColumnSelected
                #'argument:' #up
                #'labelImage:' #(#ResourceRetriever nil #upIcon)
            )
             #(#MenuItem
                #'label:' 'Move Down'
                #'isButton:' true
                #'value:' #'doMoveColumn:'
                #'activeHelpKey:' #editMoveDown
                #'enabled:' #isColumnSelected
                #'argument:' #down
                #'labelImage:' #(#ResourceRetriever nil #downIcon)
            )
          ) nil
          nil
      )
! !

!DataSetBuilder class methodsFor:'resources'!

newColumnIcon
    "Generated by the Image Editor"
    "
    ImageEditor openOnClass:self andSelector:#newColumnIcon
    "

    <resource: #image>

    ^Icon
        constantNamed:#'DataSetBuilder newColumnIcon'
        ifAbsentPut:[(Depth2Image new) width: 22; height: 22; photometric:(#palette); bitsPerSample:(#(2 )); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'UT@@@@UPUTUUUXUPUTZ**,UPUTZB",UPUTX*H,UYUTX*H,UPUTZB",UPQTZ**,UPUTX*H,UPUTX*H,UPUTX*H,UPUTXB@,UPUTZ**,UPUTZ**,UPUTX"H,UYUTXB@,UPUTX"@,UPUTX"H,UPUTZ**,UPUTZ**,UPUT/??<UPUT@@@@UP'); colorMap:(((Array new:4) at:1 put:((Color black)); at:2 put:((Color white)); at:3 put:((Color grey:66.9978)); at:4 put:((Color grey:49.9962)); yourself)); mask:((Depth1Image new) width: 22; height: 22; photometric:(#blackIs0); bitsPerSample:(#(1 )); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'A??@A??@A??@A??@A??@A??@A??@A??@A??CA??@A??@A??@A??@A??CA??AA??@A??CA??@A??CA??@A??@A??A'); yourself); yourself]! !

!DataSetBuilder methodsFor:'accessing'!

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:
        [:aColumn|
            columns add: aColumn copy.
            aColumn rendererType == #rowSelector 
                ifFalse:[list add: aColumn label]
                ifTrue: [list add:'Row Selector']
        ]
    ]
!

rowClassName

    ^(Smalltalk resolveName:className inClass:self class) notNil ifTrue:[className] ifFalse:[nil]
!

rowClassName:aClassName

    |cls|

    superclassName := nil.

    (className := aClassName) notNil 
    ifTrue:
    [
        (cls := self resolveClassNamed) notNil 
            ifTrue: [superclassName := cls superclass name asString] 
            ifFalse:[superclassName := 'Object']
    ]

! !

!DataSetBuilder methodsFor:'aspects'!

aspectFor:aKey
    "returns aspect for a key or nil"

    ^aspects at:aKey ifAbsent:[super aspectFor:aKey]


!

columnIsNotEditing
    "returns a boolean value holder which is set to true if column is not editing"

    ^builder valueAspectFor:#columnIsNotEditing initialValue: true



!

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
!

isColumnSelected
    "returns a boolean value holder which is set to true if something is modified
     and not accepted"

    ^builder valueAspectFor:#isColumnSelected initialValue: false



!

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
    "returns a value holder which keeps selected column"

    |holder|

    (holder := builder bindingAt:#selectedColumnModel) isNil ifTrue:[
        holder := AspectAdaptor new subject:self; forAspect:#selectedColumnIndex.
        builder aspectAt:#selectedColumnModel put:holder.
    ].
    ^ holder
!

seqList

    |list|

    (list := builder bindingAt:#seqList) isNil ifTrue:[
        builder aspectAt:#seqList put:(list :=  List new).
    ].
    ^ list
!

specChannel

    |holder|

    (holder := builder bindingAt:#specChannel) isNil ifTrue:[
        builder aspectAt:#specChannel put:(holder :=  ValueHolder new).
    ].
    ^ holder
!

style

    ^self aspectFor:#labelFont
!

tabList

    ^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
! !

!DataSetBuilder methodsFor:'change & update'!

update:something with:aParameter from:someObject
    "one of my aspects has changed; update modified channel"

    self valueOfEnablingCommitButtons value: true.
    self columnIsNotEditing 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
!

generateBackgroundSelectorIn:aClass
    "generate code for #backgroundSelector"

    |sel catg code bCode|

    catg := 'accessing look' asSymbol.
    code :=   '\'
            , '    "automatically generated by DataSetBuilder ..."\'
            , '\'
            , '    "specific background color for a cell"\'
            , '\'
            .

    columns do:
    [:aColumn|
        ((sel := aColumn backgroundSelector) notNil and:[(aClass implements:sel) not]) 
        ifTrue:
        [
            bCode := sel asString, code, '    ^nil'.
            self compile:bCode forClass:aClass inCategory:catg
        ]
    ]


!

generateChoicesIn:aClass
    "generate code for #choices"

    |sel catg code|

    catg := 'accessing menu' 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
        ]
    ]
!

generateDoubleClickSelectorIn:aClass
    "generate code for #foregroundSelector"

    |sel catg code bCode|

    catg := 'accessing action' asSymbol.
    code :=   '\'
            , '    "automatically generated by DataSetBuilder ..."\'
            , '\'
            , '    "specific selector to be called on double click"\'
            , '\'
            .

    columns do:
    [:aColumn|
        ((sel := aColumn doubleClickedSelector) notNil 
        and:[(aClass implements:sel) not]) 
        ifTrue:
        [
            bCode := sel asString, code.
            self compile:bCode forClass:aClass inCategory:catg
        ]
    ]


!

generateForegroundSelectorIn:aClass
    "generate code for #foregroundSelector
    "
    |sel catg code bCode|

    catg := 'accessing look' asSymbol.
    code :=   '\'
            , '    "automatically generated by DataSetBuilder ..."\'
            , '\'
            , '    "specific foreground color for a cell"\'
            , '\'
            .

    columns do:
    [:aColumn|
        ((sel := aColumn foregroundSelector) notNil 
        and:[(aClass implements:sel) not]) 
        ifTrue:
        [
            bCode := sel asString, code, '    ^nil'.
            self compile:bCode forClass:aClass inCategory:catg
        ]
    ]


!

generateMenuIn:aClass
    "generate code for #menu"

    |sel catg code|

    catg := 'accessing menu' 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' 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' 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:
            [
                sel numArgs == 0 
                    ifTrue: [bCode := sel asString, code] 
                    ifFalse:[bCode := sel asString, 'anIndex\', code].
                aColumn rendererType == #CheckToggle 
                    ifFalse:[bCode := bCode, '    ^nil'] 
                    ifTrue: [bCode := bCode, '    ^true']. 
                self compile:bCode forClass:aClass inCategory:catg
            ]
        ]
    ]
!

generateSelectSelectorIn:aClass
    "generate code for #selectSelector
    "
    |sel catg code bCode|

    catg := 'accessing selection' asSymbol.
    code :=   '\'
            , '    "automatically generated by DataSetBuilder ..."\'
            , '\'
            , '    "can select cell in column"\'
            , '\'
            .

    columns do:
    [:aColumn|
        (aColumn rendererType ~~ #rowSelector 
         and:[(sel := aColumn selectSelector) notNil
         and:[(aClass implements:sel) not]]) 
         ifTrue:
         [
            aColumn canSelect 
            ifTrue:
            [
                bCode := sel asString, code, '    ^true'.
                self compile:bCode forClass:aClass inCategory:catg
            ]
        ]
    ]
!

generateWriteSelectorIn:aClass
    "generate code for #writeSelector"

    |sel catg code bCode sz|

    catg := 'accessing' asSymbol.
    code :=   'aValue\'
            , '    "automatically generated by DataSetBuilder ..."\'
            , '\'
            , '    "set value"\'
            .

    columns do:
    [:aColumn|
        ((sel := aColumn writeSelector) notNil
         and:[aColumn canSelect
         and:[(aClass implements:sel) not]]) 
        ifTrue:
        [
            sel numArgs == 1 
            ifTrue:
            [
                bCode := sel asString
            ] 
            ifFalse:
            [
                sz := sel indexOf:$:.
                bCode := sel copyTo:sz.
                bCode := bCode, 'anIndex ', (sel copyFrom:sz + 1)
            ].
            self compile:(bCode, 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.

    #(
        label
        canSelect
        choices
        editorType
        formatString
        labelIsImage
        size
        type
        width
        minWidth
        height
        menu
        foregroundSelector
        backgroundSelector
        doubleClickedSelector
        selectSelector
        printSelector
        readSelector
        writeSelector
        rendererType
        showColSeparator
        showRowSeparator
        backgroundColor
        foregroundColor
        labelForegroundColor
        labelBackgroundColor
        labelFont
        labelActionSelector
        labelActionArgument
        labelAlignment
     ) do:[:aKey|
        aspects at:aKey put:(holder := ValueHolder new).
        holder addDependent:self
    ]

! !

!DataSetBuilder methodsFor:'private'!

checkMenuItemModified
    "check column modification"

    self valueOfEnablingCommitButtons value
    ifTrue:
    [
        ((YesNoBox title:'Column was modified!!\Save it?\' withCRs)        
            noText:'No';
            yesText:'Yes';
            showAtPointer;
            accepted) ifFalse: [self valueOfEnablingCommitButtons value: false. ^true].
        self accept
    ].
    ^true

!

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]
!

updateInputFields
    "reload item value into input fields"

    |column|

    (column := self selectedColumn) isNil 
    ifTrue:
    [
        self tabModel value:0.
    ] 
    ifFalse:
    [
        aspects keysAndValuesDo:[:aKey :aModel|aModel value:(column perform:aKey) withoutNotifying: self].
        tabSelectionIndex == 0 ifTrue:[self tabModel value:1]
    ]
! !

!DataSetBuilder methodsFor:'queries'!

hasChanged
    "returns true if changes are done to the original column description"

    ^hasChanged
! !

!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 isColumnSelected value: true
    ]

!

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 methodsFor:'startup / release'!

closeRequest
    "close request"

    self checkMenuItemModified ifTrue: [super closeRequest]
!

postBuildWith:builder

    super postBuildWith:builder.

    (builder componentAt: #columnView) 
        selectConditionBlock: [:i|self checkMenuItemModified];
        action: [:i|self cancel];
        selection: 1



! !

!DataSetBuilder methodsFor:'user actions'!

accept
    "accept changes made"

    |column type|

    self valueOfEnablingCommitButtons value == false ifTrue: [^self].
    hasChanged := true.

    (column := self selectedColumn) isNil ifTrue: [^self cancel].

    type := (aspects at:#rendererType) value.

    type == #rowSelector 
    ifTrue:
    [
        #(label width minWidth editorType choices readSelector writeSelector printSelector
          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 updateColumnView.
    self cancel
!

cancel
    "remove all changes and reload selected column values"

    |column|

    self updateInputFields.
    self valueOfEnablingCommitButtons value:false.
    self columnIsNotEditing value: true.
!

doBrowseClass
    "browse class of columns spec"

    |cls|

    (cls := self resolveClassNamed) notNil 
        ifTrue: [SystemBrowser openInClass:cls] 
        ifFalse:[self information:'No class defined!!']



!

doCopyColumn
    "copy selected column to the clipboard"

    |idx|

    (idx := selectedColumnIndex) ~~ 0 
    ifTrue:
    [
        self clipboard: (columns at: idx) deepCopy
    ]
!

doCreateColumn
    "create a new column after selected column or at left (nothing selected)"

    |label list|

    list := self seqList.
    label := 'Column ', (list size + 1) printString.
    columns add:(DataSetColumnSpec label:label selector:nil) afterIndex:selectedColumnIndex.
    self seqList add:label afterIndex:selectedColumnIndex.
    hasChanged := true.
    self valueOfEnablingCommitButtons value ifFalse:[self selectedColumnModel value:selectedColumnIndex + 1].
    self cancel

!

doCutColumn
    "remove selected column and put it to the clipboard"

    |idx|

    ((idx := selectedColumnIndex) ~~ 0 and: [self checkMenuItemModified]) 
    ifTrue:
    [
        self selectedColumnModel value:0.
        self clipboard: (columns at: idx).
        columns removeIndex:idx.
        self seqList removeIndex:idx.
        columns size > 0 ifTrue: [self selectedColumnModel value: ((idx - 1) max: 1)].
        self updateColumnView.
        self updateInputFields.
        columns isEmpty ifTrue: [self isColumnSelected value: false].
        self cancel.
        hasChanged := true.
    ]
!

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
    "generate code for column values"

    |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 generateBackgroundSelectorIn:cls.
    self generateForegroundSelectorIn:cls.
    self generateSelectSelectorIn:cls.
    self generateWriteSelectorIn:cls.
    self generateDoubleClickSelectorIn: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.
!

doPasteColumn
    "paste clipboard copy column after selected column or at left (nothing selected)"

    |label list|

    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.
    hasChanged := true.

    self valueOfEnablingCommitButtons value ifFalse:[self selectedColumnModel value:selectedColumnIndex + 1].
    self updateColumnView.
    self updateInputFields.
! !

!DataSetBuilder class methodsFor:'documentation'!

version
    ^ '$Header$'
! !