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 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311
|
#! /usr/bin/env tclsh
#==============================================================================
# Demonstrates the interactive tablelist cell editing with the aid of some
# widgets from the tile package.
#
# Copyright (c) 2005-2024 Csaba Nemethi (E-mail: csaba.nemethi@t-online.de)
#==============================================================================
package require Tk
package require tablelist_tile
if {[tk windowingsystem] eq "x11" &&
($tk_version < 8.7 || [package vcompare $::tk_patchLevel "8.7a5"] <= 0)} {
#
# Patch the default theme's styles TCheckbutton and TRadiobutton
#
package require themepatch
themepatch::patch default
}
wm title . "Serial Line Configuration"
#
# Add some entries to the Tk option database
#
set dir [file dirname [info script]]
source [file join $dir option_tile.tcl]
option add *Tablelist*Spinbox.background white
option add *Tablelist*Spinbox.readonlyBackground white
#
# Create the images "checkedImg" and "uncheckedImg", as well as 16 images of
# names like "img#FF0000", displaying colors identified by names like "red"
#
source [file join $dir images.tcl]
#
# Improve the window's appearance by using a tile
# frame as a container for the other widgets
#
if {$::argc == 0} {
set f [ttk::frame .f]
} else {
set f [lindex $::argv 0] ;# provided by the awthemes script "demottk.tcl"
}
#
# Create a tablelist widget with editable columns (except the first one)
#
set tbl $f.tbl
tablelist::tablelist $tbl \
-columns {0 "No." right
0 "Available" center
0 "Name" left
0 "Baud Rate" right
0 "Data Bits" center
0 "Parity" left
0 "Stop Bits" center
0 "Handshake" left
0 "Activation Date" center
0 "Activation Time" center
0 "Cable Color" center} \
-editstartcommand editStartCmd -editendcommand editEndCmd \
-aftercopycommand afterCopyCmd -height 0 -width 0
if {$isAwTheme && ![regexp {^(aw)?(arc|breeze.*)$} $currentTheme]} {
$tbl configure -borderwidth 2
}
if {[$tbl cget -selectborderwidth] == 0} {
$tbl configure -spacing 1
}
$tbl columnconfigure 0 -sortmode integer
$tbl columnconfigure 1 -name available -editable yes \
-editwindow ttk::checkbutton -formatcommand emptyStr \
-labelwindow ttk::checkbutton
$tbl columnconfigure 2 -name lineName -editable yes -editwindow ttk::entry \
-allowduplicates 0 -sortmode dictionary
$tbl columnconfigure 3 -name baudRate -editable yes -editwindow ttk::combobox \
-sortmode integer
if {[info commands ttk::spinbox] eq ""} {
$tbl columnconfigure 4 -name dataBits -editable yes -editwindow spinbox
} else {
$tbl columnconfigure 4 -name dataBits -editable yes -editwindow ttk::spinbox
}
$tbl columnconfigure 5 -name parity -editable yes -editwindow ttk::combobox
$tbl columnconfigure 6 -name stopBits -editable yes -editwindow ttk::combobox
$tbl columnconfigure 7 -name handshake -editable yes -editwindow ttk::combobox
$tbl columnconfigure 8 -name actDate -editable yes -editwindow ttk::entry \
-formatcommand formatDate -sortmode integer
$tbl columnconfigure 9 -name actTime -editable yes -editwindow ttk::entry \
-formatcommand formatTime -sortmode integer
$tbl columnconfigure 10 -name color -editable yes \
-editwindow ttk::menubutton -formatcommand emptyStr
proc emptyStr val { return "" }
proc formatDate val { return [clock format $val -format "%Y-%m-%d"] }
proc formatTime val { return [clock format $val -format "%H:%M:%S"] }
#
# Populate the tablelist widget and configure the checkbutton
# embedded into the header label of the column "available"
#
source [file join $dir serialParams.tcl]
if {$::argc == 0} {
set btn [ttk::button $f.btn -text "Close" -command exit]
}
#
# Manage the widgets
#
if {$::argc == 0} {
pack $btn -side bottom -pady 7p
pack $tbl -side top -expand yes -fill both
pack $f -expand yes -fill both
} else {
$tbl configure -stretch all
foreach col {8 9} { $tbl columnconfigure $col -hide yes }
pack $tbl -side top -expand yes -fill both -padx 3p -pady {0 3p}
}
#------------------------------------------------------------------------------
# editStartCmd
#
# Applies some configuration options to the edit window; if the latter is a
# combobox, the procedure populates it.
#------------------------------------------------------------------------------
proc editStartCmd {tbl row col text} {
set w [$tbl editwinpath]
switch [$tbl columncget $col -name] {
lineName {
#
# Set an upper limit of 20 for the number of characters
#
$w configure -invalidcommand bell -validate key \
-validatecommand {expr {[string length %P] <= 20}}
}
baudRate {
#
# Populate the combobox and allow no more
# than 6 digits in its entry component
#
$w configure -values {50 75 110 300 1200 2400 4800 9600 19200 38400
57600 115200 230400 460800 921600}
$w configure -invalidcommand bell -validate key -validatecommand \
{expr {[string length %P] <= 6 && [regexp {^[0-9]*$} %S]}}
}
dataBits {
#
# Configure the spinbox
#
$w configure -from 5 -to 8 -state readonly
}
parity {
#
# Populate the combobox and make it non-editable
#
$w configure -values {None Even Odd Mark Space} -state readonly
}
stopBits {
#
# Populate the combobox and make it non-editable
#
$w configure -values {1 1.5 2} -state readonly
}
handshake {
#
# Populate the combobox and make it non-editable
#
$w configure -values {XON/XOFF RTS/CTS None} -state readonly
}
actDate {
#
# Set an upper limit of 10 for the number of characters
# and allow only digits and the "-" character in it
#
$w configure -invalidcommand bell -validate key -validatecommand \
{expr {[string length %P] <= 10 && [regexp {^[0-9-]*$} %S]}}
}
actTime {
#
# Set an upper limit of 8 for the number of characters
# and allow only digits and the ":" character in it
#
$w configure -invalidcommand bell -validate key -validatecommand \
{expr {[string length %P] <= 8 && [regexp {^[0-9:]*$} %S]}}
}
color {
#
# Populate the menu and make sure the menubutton will display the
# color name rather than $text, which is "", due to -formatcommand
#
set menu [$w cget -menu]
foreach name $::colorNames {
$menu add radiobutton -compound left \
-image img$::colors($name) -label $name
}
$menu entryconfigure 8 -columnbreak 1
return [$tbl cellcget $row,$col -text]
}
}
return $text
}
#------------------------------------------------------------------------------
# editEndCmd
#
# Performs a final validation of the text contained in the edit window and gets
# the cell's internal content.
#------------------------------------------------------------------------------
proc editEndCmd {tbl row col text} {
switch [$tbl columncget $col -name] {
available {
#
# Update the image contained in the cell and the checkbutton
# embedded into the header label of the column "available"
#
set img [expr {$text ? "checkedImg" : "uncheckedImg"}]
$tbl cellconfigure $row,$col -image $img
after idle [list updateCkbtn $tbl $row $col]
}
baudRate {
#
# Check whether the baud rate is an integer in the range 50..921600
#
if {![regexp {^[0-9]+$} $text] || $text < 50 || $text > 921600} {
bell
tk_messageBox -title "Error" -icon error -message \
"The baud rate must be an integer in the range 50..921600"
$tbl rejectinput
}
}
actDate {
#
# Get the activation date in seconds from the last argument
#
if {[catch {clock scan $text} actDate] != 0} {
bell
tk_messageBox -title "Error" -icon error -message "Invalid date"
$tbl rejectinput
return ""
}
#
# Check whether the activation clock value is later than the
# current one; if this is the case then make sure the cells
# "actDate" and "actTime" will have the same internal value
#
set actTime [$tbl cellcget $row,actTime -text]
set actClock [clock scan [formatTime $actTime] -base $actDate]
if {$actClock <= [clock seconds]} {
bell
tk_messageBox -title "Error" -icon error -message \
"The activation date & time must be in the future"
$tbl rejectinput
} else {
$tbl cellconfigure $row,actTime -text $actClock
return $actClock
}
}
actTime {
#
# Get the activation clock value in seconds from the last argument
#
set actDate [$tbl cellcget $row,actDate -text]
if {[catch {clock scan $text -base $actDate} actClock] != 0} {
bell
tk_messageBox -title "Error" -icon error -message "Invalid time"
$tbl rejectinput
return ""
}
#
# Check whether the activation clock value is later than the
# current one; if this is the case then make sure the cells
# "actDate" and "actTime" will have the same internal value
#
if {$actClock <= [clock seconds]} {
bell
tk_messageBox -title "Error" -icon error -message \
"The activation date & time must be in the future"
$tbl rejectinput
} else {
$tbl cellconfigure $row,actDate -text $actClock
return $actClock
}
}
color {
#
# Update the image contained in the cell
#
$tbl cellconfigure $row,$col -image img$::colors($text)
}
}
return $text
}
|