1 # vim: foldmethod=marker foldmarker=<<<,>>> ts=4 shiftwidth=4 ft=tcl
4 inherit tlc::Mywidget tlc::Handlers tlc::Textvariable tlc::Signalsource
8 itk_option define -allow_add allowAdd AllowAdd 1 need_rerender
9 itk_option define -allow_remove allowRemove AllowRemove 1 need_rerender
10 itk_option define -allow_reorder allowReorder AllowReorder 1 need_rerender
13 variable schema {} need_rerender
16 method set_rows {args}
17 method set_tags {args}
22 method textvariable_changed {newvalue}
38 method need_rerender {}
40 method cannonize_type {intype}
41 method render_row {r arr}
42 method tableclick {row col idx wid}
43 method destroy_children {}
49 configbody tlc::Tablelist::state { #<<<1
50 log warning "$w -state not implemented yet"
54 body tlc::Tablelist::constructor {args} { #<<<1
57 # This requires tktable, and to ensure no conflict with blt::table
58 # the user must arrange to have the command 'tktable' refer to the
62 array set colschema {}
65 array set colvarname {}
68 itk_component add list {
74 -titlerows $titlerows \
75 -titlecols $titlecols \
76 -colstretch last -rowstretch none \
77 -variable [scope td] \
78 -yscrollcommand [list $w.vsb set] \
84 -browsecommand [code $this tableclick %r %c %s %W] \
92 bind $w.list <Return> {
93 set r [%W index active row]
94 set c [%W index active col]
95 set tc [%W cget -cols]
98 %W activate [incr r],1
100 %W activate $r,[incr c]
104 bind $w.list <KP_Enter> [bind $w.list <Return>]
105 bind $w.list <Tab> [bind $w.list <Return>]
107 itk_component add vsb {
108 tlc::myscrollbar_win32 $w.vsb -orient v -command [list $w.list yview] \
113 tlc::Signal #auto signals(item_selected) -name "$w item_selected"
114 tlc::Domino #auto dominos(need_rerender) -name "$w need_rerender"
115 tlc::Vardomino #auto dominos(td_changed) -name "$w td_changed" \
116 -textvariable [scope td]
118 $dominos(need_rerender) attach_output [code $this rerender]
119 $dominos(td_changed) attach_output [code $this td_changed]
122 $w.list tag configure lastrow \
123 -background #b2b2b2 \
128 eval itk_initialize $args
131 $w.list 1,1 -fill both \
133 blt::table configure $w c2 -resize none
135 $w.list configure -flashmode 1 -flashtime 2
137 $dominos(need_rerender) tip
141 body tlc::Tablelist::need_rerender {} { #<<<1
142 $dominos(need_rerender) tip
146 body tlc::Tablelist::rerender {} { #<<<1
147 if {[info exists oldschema] && $schema == $oldschema} return
148 set oldschema $schema
153 array unset colschema *
157 array set colwidths {}
158 array set colsettings {}
161 col_width_sticky default
172 if {$itk_option(-allow_remove)} {
173 set td(0,$colidx) "Del"
174 set colwidths($colidx) -25
178 if {$itk_option(-allow_reorder)} {
180 set colwidths($colidx) -35
185 foreach {label info} [tlc::decomment $schema] {
187 set layout(col_width) $layout(col_width_sticky)
188 set layout(col_args) $layout(col_args_sticky)
191 if {[string index $label 0] == "_"} {
194 switch -- [lindex $info 0] {
196 set layout(col_width) [lindex $info 1]
201 set layout(col_width_sticky) [lindex $info 1]
205 array set tmp $layout(col_args)
206 array set tmp [lrange $info 1 end]
207 set layout(col_args) [array get tmp]
212 array set tmp $layout(col_args_sticky)
213 array set tmp [lrange $info 1 end]
214 set layout(col_args_sticky) [array get tmp]
218 set layout(row_args) [lrange $info 1 end]
222 set layout(row_args_even) [lrange $info 1 end]
226 set layout(row_args_odd) [lrange $info 1 end]
230 array set tmp $layout(table_args)
231 array set tmp [lrange $info 1 end]
232 set layout(table_args) [array get tmp]
236 log error "Invalid layout type: ([lindex $info 0])"
242 log warning "Validation not implemented yet"
246 log error "Invalid schema directive: ($label)"
255 set varname [lindex $info 0]
256 set colschema($varname) [lrange $info 1 end]
258 set colmap($varname) $colidx
259 set colvarname($colidx) $varname
260 set td(0,$colidx) $label
261 set colwidths($colidx) $layout(col_width)
263 set colsettings($colidx) $layout(col_args)
269 log debug "Before:\n\t[join $arrdat \n\t]"
272 $w.list configure -cols $colidx
274 for {set i 0} {$i < $colidx} {incr i} {
275 if {![info exists colwidths($i)]} {
276 log error "Missing column width setting for column $i"
278 $w.list width $i $colwidths($i)
280 if {![info exists colsettings($i)]} {
281 log error "Missing column settings for column $i"
283 set settings [string map [list "\n" " "] $colsettings($i)]
284 log debug "Configuring col tags for $i ($colvarname($i)): ($settings)"
285 eval [list $w.list tag configure col$i] $settings
286 $w.list tag col col$i $i
291 array set tmp $layout(row_args)
292 array set tmp $layout(row_args_even)
293 set row_args(even) [array get tmp]
296 array set tmp $layout(row_args)
297 array set tmp $layout(row_args_odd)
298 set row_args(odd) [array get tmp]
301 if {[llength $layout(table_args)] > 0} {
302 eval [list $w.list configure] \
303 [string map [list "\n" " "] $layout(table_args)]
308 foreach {label info} [tlc::decomment $schema] {
309 if {$label == "_set_tags"} {
310 foreach {tag settings} $info {
311 set_tags $tag $settings
321 body tlc::Tablelist::set_rows {args} { #<<<1
322 $dominos(need_rerender) force_if_pending
323 log debug [tlc::stackdump]
324 $dominos(td_changed) lock
329 for {set r 0} {$r < $titlerows} {incr r} {
330 array set tmp [array get td $r,*]
333 array set td [array get tmp]
335 log debug "Setting arrdat to \$args"
338 set drows [expr {[llength $arrdat] + $titlerows}]
339 if {$itk_option(-allow_add)} {
342 $w.list config -rows $drows
344 log debug "rendering rows"
345 log debug "colschema:"
348 foreach row $arrdat {
356 log debug "releasing td_changed lock"
357 $dominos(td_changed) unlock
358 log debug "arrdat: ($arrdat)"
360 log debug "exiting set_rows"
364 body tlc::Tablelist::render_row {r arr} { #<<<1
366 foreach {varname value} $arr {
367 log debug "varname: ($varname)\[[info exists colschema($varname)]\], value: \"$value\""
368 if {![info exists colschema($varname)]} continue
369 set s $colschema($varname)
370 set c $colmap($varname)
372 set type [cannonize_type [lindex $s 0]]
373 set arglist [lrange $s 1 end]
374 log debug "setting td($r,$c) to \"$value\""
377 set scoped_varname [scope td($r,$c)]
378 set wn $w.list.$type,$r,$c
385 tlc::mycombobox $wn -textvariable $scoped_varname
389 tlc::Spinner $wn -textvariable $scoped_varname
393 error "Unknown type: ($type)" "" [list unknown_type $type]
397 if {[winfo exists $wn]} {
398 if {[llength $arglist] != 0} {
399 eval [list $wn configure] $arglist
401 log debug "Configuring $type in row $r with value \"$td($r,$c)\""
402 $w.list window config $r,$c -window $wn -sticky news
406 set tags $row_args(even)
408 set tags $row_args(odd)
410 eval [list $w.list tag configure row$r] [string map [list "\n" " "] $tags]
411 $w.list tag row row$r $r
415 body tlc::Tablelist::set_tags {args} { #<<<1
417 foreach {tag settings} $args {
418 set settings [string map [list "\n" " "] $settings]
419 eval [list $w.list tag configure $tag] $settings
424 body tlc::Tablelist::get_rows {} { #<<<1
426 # Ensure no pending updates of arrdat are in flight
427 $dominos(td_changed) force_if_pending
429 log debug "[llength $arrdat] items"
434 body tlc::Tablelist::cannonize_type {intype} { #<<<1
451 error "Unknown type: ($intype)" "" [list unknown_type $intype]
457 body tlc::Tablelist::tableclick {row col idx wid} { #<<<1
458 # Appending of new blank row to be handled by transcriber of td to arrdat
462 body tlc::Tablelist::destroy_children {} { #<<<1
463 foreach child [winfo children $w.list] {
465 if {[itcl::is object $child]} {
477 body tlc::Tablelist::td_changed {} { #<<<1
480 foreach {key value} [array get td] {
481 foreach {r c} [split $key ,] break
483 if {$r < $titlerows} continue
484 if {![info exists colvarname($c)]} continue
486 set varname $colvarname($c)
487 lappend rowinf($r) $varname $value
493 log debug "td to arrdat conversion, first stage:"
496 for {set r $titlerows} {$r <= $max_r} {incr r} {
497 if {![info exists rowinf($r)]} {
498 log warning "No data found for row $r"
501 lappend build $rowinf($r)
504 log debug "setting arrdat to \$build: [llength $build] items, from [tlc::stackdump]"
507 set_textvariable $arrdat
511 body tlc::Tablelist::textvariable_changed {newvalue} { #<<<1