* nemethi <
csaba....@t-online.de>
| While IMHO this is actually a bug in Itcl 3.4, Tablelist should behave
| the same, regardless of whether Itk 3.4 or 4.1.0 is being used (your
| sample script works as expected when using Itk 4.1.0).
This is due to the internal representation of variable scope in the two
underlying Itcl versions, as can be seen in this simpler example using
only Itcl, not Itk:
package require Itcl
package require Tablelist 6.3
itcl::class foo {
public {
method connect_listvar {w} {
$w configure -listvariable [itcl::scope myvar_]
puts stderr "$w configure -listvariable [itcl::scope myvar_]"
}
}
private {
variable myvar_ ""
}
}
set tbl [tablelist::tablelist .t -columns {0 one 0 two}]
set obj [foo \#auto]
$obj connect_listvar $tbl
With Itcl 3.4, it prints
.t configure -listvariable @itcl ::foo0 ::foo::myvar_
With Itcl 4.1.0, it prints
.t configure -listvariable ::itcl::internal::variables::oo::Obj34::foo::myvar_
And this 4.1 version of the itcl variable representation is an
'ordinary' namespace, as opposed to the 'old' Itcl 3.4 representation.
With that, simply prefixing it with another "::" just works.
| I think, the right solution to this problem is to use [uplevel #0
| [list info exists $data(-listvariable)]], as proposed in your 3rd
| posting within this thread.
I don't know what those [info exist...] code passages were meant to
achieve, since usually all other widgets simply create the global
variables they are connected to if they don't exist:
entry .e
info exist foo
=> 0
.e configure -textvariable foo
info exist foo
=> 1
And in fact looking at the code in tablelistConfig.tcl, proc
tablelist::makeListVar (which is called in the process of
"configure -listvariable"), there is no way how the variable could not
exist: it is set there if it does not exist:
proc tablelist::makeListVar {win varName} {
...
upvar #0 $varName var
...
if {[info exists var]} {
#
# Invoke the trace procedure associated with the new list variable
#
listVarTrace $win $name1 $name2 w
} else {
#
# Set $varName according to the value of data(itemList)
#
set var {}
foreach item $data(itemList) {
lappend var [lrange $item 0 $data(lastCol)]
}
}
And a trace for 'unset' is added which recreates the variable should it
ever become unset...
However the solution, in addition to your proposed changes involving
uplevel, IMHO the following procs also need attention with this:
- proc tablelist::listVarTrace
- in the 'unset' branch, it uses to recreate the variable:
set ::$varName {}
lappend ::$varName
trace variable ::$varName wu $data(listVarTraceCmd)
(should better use code similar to makeListVar involving upvar and
accessing the upvar'd variable)
- proc tablelist::makeListVar
- uses
if {[array exists ::$varName]} {
to detect if the variable is an array
(also should use 'upvar' and array exists on the upvar'd name)
And last but not least: many thanks for Tablelist, it is a very valuable
package!
R'