1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214
|
# copyright (C) 1997-2005 Jean-Luc Fontaine (mailto:jfontain@free.fr)
# this program is free software: please read the COPYRIGHT file enclosed in this package or use the Help Copyright menu
# $Id: viewtab.tcl,v 1.18 2005/01/02 00:45:07 jfontain Exp $
class viewTable {
if {$global::withGUI} {
set (monitorInstanceCellsMessage) [mc {in database history mode, can only monitor cells from a module instance data table}]
}
proc viewTable {this args} {
set ($this,nextRow) 0
}
proc ~viewTable {this} {
variable ${this}cellRow
catch {unset ${this}cellRow}
if {$global::withGUI} {
delete $($this,dataTable)
}
set dataName $($this,dataName)
incr ${dataName}(updates) ;# so related viewers can eventually show disappeared cells
unset $dataName
}
if {$global::withGUI} {
proc createTable {this dataName dragDataCommand} {
if {[info exists ($this,dataTable)]} { ;# useful in history mode
delete $($this,dataTable)
unset ($this,dataTable)
}
# wait till after completion before creating table since some options are not dynamically settable
set table [new dataTable $widget::($this,path)\
-data $dataName -draggable $composite::($this,-draggable) -background $viewer::(background)\
]
### hack: drag and drop code should be separated from dataTable which should provide a selected member procedure ###
# allow dropping of data cells ### use same path as drag path to avoid drops in table from table ###
viewer::setupDropSite $this $dataTable::($table,tablePath)
if {$composite::($this,-draggable)} {
# extend data table drag capabilities ### hack ### also eventually allow row selection only instead of cells ###
dragSite::provide $dataTable::($table,drag) OBJECTS $dragDataCommand
# intercept original data cells dragging
dragSite::provide $dataTable::($table,drag) DATACELLS $dragDataCommand
}
pack $widget::($table,path) -fill both -expand 1
set ($this,dataTable) $table
set ($this,dataName) $dataName
}
} else {
proc setDataName {this name} {
set ($this,dataName) $name
}
}
proc cells {this} { ;# return cells in creation (increasing row) order
variable ${this}cellRow
set lists {}
foreach {cell row} [array get ${this}cellRow] {
lappend lists [list $row $cell]
}
set cells {}
foreach list [lsort -integer -index 0 $lists] {
lappend cells [lindex $list end]
}
return $cells
}
proc setCellRows {this rows} { ;# restore cell to row mapping from a save file
set ($this,cellRows) $rows
set ($this,cellRowIndex) 0 ;# initialize cell row index in list of rows
}
proc row {this cell} {
variable ${this}cellRow
set row {}
catch {set row [set ${this}cellRow($cell)]}
return $row
}
proc register {this cell array} {
variable ${this}cellRow
viewer::registerTrace $this $array
if {[info exists ($this,cellRowIndex)]} { ;# restore cell row from recorded configuration
set row [lindex $($this,cellRows) $($this,cellRowIndex)]
if {[string length $row] == 0} { ;# rows list exhausted: we are done initializing from recorded data
unset ($this,cellRowIndex) ($this,cellRows)
set row $($this,nextRow)
} else {
incr ($this,cellRowIndex) ;# get ready for upcoming cell
if {$($this,nextRow) < $row} {set ($this,nextRow) $row} ;# make sure to eliminate potential conflicts
}
} else {
set row $($this,nextRow) ;# next row for this data table
}
set ${this}cellRow($cell) $row ;# remember cell row
incr ($this,nextRow)
return $row
}
proc cellsAndRows {this} {
variable ${this}cellRow
return [array get ${this}cellRow]
}
if {$global::withGUI} {
proc dragCells {this} {
variable ${this}cellRow
foreach {cell row} [array get ${this}cellRow] { ;# revert original cell / row mapping
set original($row) $cell
}
set cells {}
foreach cell [dataTable::dragData $($this,dataTable) DATACELLS] {
viewer::parse $cell array row column type
if {$column == 1} { ;# current value: replace with original cell to propagate color, for example
lappend cells $original($row)
} else {
lappend cells $cell
}
}
return $cells
}
proc deleteRow {this cell} {
variable ${this}cellRow
viewer::parse $cell array ignore ignore ignore
viewer::unregisterTrace $this $array
set row [set ${this}cellRow($cell)]
unset ${this}cellRow($cell)
return $row
}
# data index is needed so that data array that other eventual data viewers depend on is reused when initializing from save file
proc initializationConfiguration {this} {
variable ${this}cellRow
scan [namespace tail $($this,dataName)] %u index ;# retrieve index from data name
set list [list -dataindex $index]
foreach cell [cells $this] { ;# in creation order
lappend rows [set ${this}cellRow($cell)]
}
if {[info exists rows]} {
lappend list -cellrows $rows
}
return $list
}
proc numberOfRows {this} {
variable ${this}cellRow
return [array size ${this}cellRow]
}
proc monitored {this cell} {
variable ${this}cellRow
# either a current value cell or an internally generated cell:
return [expr {[info exists ${this}cellRow($cell)] || [dataTable::monitored $($this,dataTable) $cell]}]
}
proc setCellColor {this source color} { ;# useful for current value cell only, others are handled directly by data table
variable ${this}cellRow
foreach {cell row} [array get ${this}cellRow] {
if {[string equal $cell $source]} {
dataTable::setCellColor $($this,dataTable) $row 1 $color
return
}
}
}
proc selectedRows {this format} { ;# gather rows with at least 1 selected cell
foreach cell [dataTable::dragData $($this,dataTable) $format] {
regexp {\(([^,]+)} $cell dummy row
set selected($row) {}
}
return [array names selected]
}
proc update {this} {
dataTable::update $($this,dataTable)
}
proc updateLabels {this} {
variable ${this}cellRow
set dataName $($this,dataName)
foreach {cell row} [array get ${this}cellRow] {
viewer::parse $cell array cellRow cellColumn ignore
set ${dataName}($row,0) [lindex [viewer::label $array $cellRow $cellColumn] 0]
}
incr ${dataName}(updates) ;# let data table update itself
}
proc updateTitleLabels {this} {
dataTable::updateTitleLabels $($this,dataTable)
}
}
}
|